From 6e53fd0dfd830d6d96206419c530c71fa4b3f4e6 Mon Sep 17 00:00:00 2001 From: Jakob Stendahl Date: Thu, 21 Oct 2021 19:28:20 +0200 Subject: :sparkles: Add attempt at the "simulation" --- NeoRuntime/Runtime/luxcena_neo/strip.py | 2 + NeoRuntime/Runtime/neo_runtime.py | 21 ++++++ src/NeoRuntimeManager/IPC.js | 19 +++++- src/NeoRuntimeManager/index.js | 17 ++++- src/SocketIO/index.js | 11 ++++ src_frontend/Components/Editor/Controls.svelte | 2 - src_frontend/Components/Editor/Editor.svelte | 3 +- src_frontend/Components/Editor/Simulation.svelte | 82 ++++++++++++++++++++++++ 8 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 src_frontend/Components/Editor/Simulation.svelte diff --git a/NeoRuntime/Runtime/luxcena_neo/strip.py b/NeoRuntime/Runtime/luxcena_neo/strip.py index bc2e2be..9a12969 100644 --- a/NeoRuntime/Runtime/luxcena_neo/strip.py +++ b/NeoRuntime/Runtime/luxcena_neo/strip.py @@ -119,6 +119,7 @@ class Strip: def set_pixel_color(self, n, *color): """Set LED at position n to the provided 24-bit color value (in RGB order). """ + if n >= self.LED_COUNT: return c = detect_format_convert_color(*color) self.TMPCOLORSTATE[n] = c self.strip.setPixelColor(n, c) @@ -132,6 +133,7 @@ class Strip: """Set a whole segment to the provided red, green and blue color. Each color component should be a value from 0 to 255 (where 0 is the lowest intensity and 255 is the highest intensity).""" + if segment >= len(self.SEGMENTS): return for n in get_segment_range(self.SEGMENTS, segment): self.set_pixel_color(n, *color) diff --git a/NeoRuntime/Runtime/neo_runtime.py b/NeoRuntime/Runtime/neo_runtime.py index b028530..3057f3c 100644 --- a/NeoRuntime/Runtime/neo_runtime.py +++ b/NeoRuntime/Runtime/neo_runtime.py @@ -116,11 +116,32 @@ class NeoRuntime: ws.close() last_send = time.perf_counter() + + if self.__send_strip_buffer: + time.sleep(0.001) + buffer = [2] + for p in self.__strip.COLORSTATE: + buffer.append((p & 0x00FF0000) >> 16) + buffer.append((p & 0x0000FF00) >> 8) + buffer.append((p & 0x000000FF)) + buffer = bytes(buffer) + for ws in w: + try: + ws.send(buffer) + except BrokenPipeError: + self.__s_clients.remove(ws) + ws.close() + time.sleep(0.001) for rs in r: if rs is self.__s: c, a = self.__s.accept() self.__s_clients.append(c) + try: + buf = bytes([3]) + bytes(json.dumps(self.__strip.pixelMatrix.matrix), "ascii") + c.send(buf) + except Exception as e: + print(e) else: data = rs.recv(128) if not data: diff --git a/src/NeoRuntimeManager/IPC.js b/src/NeoRuntimeManager/IPC.js index 79ce7ea..6428a13 100644 --- a/src/NeoRuntimeManager/IPC.js +++ b/src/NeoRuntimeManager/IPC.js @@ -19,7 +19,8 @@ const GLOBVAR = Object.freeze({POWER_ON : 0, BRIGHTNESS: 1}); /** @type {Object} ENUM-ish for what type of data neoruntime sends */ const DATATYPE = Object.freeze({STATES : 1, - STRIP_BUF: 2}); + STRIP_BUF: 2, + MATRIX: 3}); /** * class that will keep a active connection to a socket if possible, and @@ -66,9 +67,9 @@ class IPC { this.connected = true; }) .on('data', (data) => { + let json_data; switch (data[0]) { case DATATYPE.STATES: - let json_data; try { json_data = JSON.parse(data.toString("ascii", 1)); } catch (e) { @@ -89,6 +90,20 @@ class IPC { this.variables = json_data["variables"]; } break; + + case DATATYPE.MATRIX: + try { + json_data = JSON.parse(data.toString("ascii", 1)); + } catch (e) { + logger.warning("Could not parse json data from neoruntime"); + console.log(e); + } + this.eventEmitter.emit("matrix", json_data); + break; + + case DATATYPE.STRIP_BUF: + this.eventEmitter.emit("strip_buffer", Array.from(data.values()).slice(1)); + break; default: logger.info(data); diff --git a/src/NeoRuntimeManager/index.js b/src/NeoRuntimeManager/index.js index 4377b8a..7fc117a 100644 --- a/src/NeoRuntimeManager/index.js +++ b/src/NeoRuntimeManager/index.js @@ -29,8 +29,13 @@ const eventEmitter = new EventEmitter(); let modeDebuggerActive = false; /** @type {string} Should be the modeId the debugger is attached to */ let modeDebuggerId = null; +/** @type {object} Handler for proc:start when debugger is active */ +let modeDebuggerProcStartHandler; +/** @type {object} The last received matrix setup */ +let matrix = null; eventEmitter.on("proc:exit", (code) => modeExitCode = code); +eventEmitter.on("matrix", (_matrix) => matrix = _matrix); /** * Check if a path id actually a mode (if it is a folder with a script.py file) @@ -248,6 +253,13 @@ function startDebugger(debuggerModeId) { if (!isMode(getModePath(debuggerModeId))) { return {success: false, reason: "unknown modeId"}; } if (modeDebuggerActive) { return {success: false, reason: "debugger already active"}; } logger.info(`Starting debugger for ${debuggerModeId}`); + + modeDebuggerProcStartHandler = eventEmitter.on("proc:start", () => { + setTimeout(() => { + ipc.sendCommand(IPC.COMMAND.SET_SEND_STRIP_BUF, true); + }, 500); + }); + modeDebuggerActive = true; modeDebuggerId = debuggerModeId; if (debuggerModeId != modeId) { @@ -277,6 +289,8 @@ function stopDebugger() { if (!modeDebuggerActive) { return {success: true, detail: "No debugger active"} } logger.info(`Stopping debugger`); modeDebuggerActive = false; + eventEmitter.removeAllListeners("proc:start", modeDebuggerProcStartHandler); + ipc.sendCommand(IPC.COMMAND.SET_SEND_STRIP_BUF, false); return {success: true} } @@ -306,6 +320,7 @@ module.exports = (_neoModules) => { isMode, modeRunning, startDebugger, stopDebugger, saveModeCode, - startMode, stopMode, restartMode + startMode, stopMode, restartMode, + matrix } }; diff --git a/src/SocketIO/index.js b/src/SocketIO/index.js index da140bb..88b5459 100644 --- a/src/SocketIO/index.js +++ b/src/SocketIO/index.js @@ -310,6 +310,11 @@ function createAuthorizedNamespace(io) { logger.info("Stopped debugger"); }); + /* Matrix and strip buffer */ + socket.on("matrix:get", () => { + socket.emit("matrix", neoModules.neoRuntimeManager.matrix); + }); + socket.on("disconnect", () => { logger.access(`SOCKET:authed Client (${socket.id}@${socket.handshake.headers.host}) disconnected.`); if (debuggerOpen) { @@ -319,6 +324,12 @@ function createAuthorizedNamespace(io) { }); }); + neoModules.neoRuntimeManager.event.on("matrix", (matrix) => { + authorizedNamespace.emit("matrix", matrix); + }); + neoModules.neoRuntimeManager.event.on("strip_buffer", (strip_buffer) => { + authorizedNamespace.emit("strip_buffer", strip_buffer); + }); neoModules.selfUpdater.updater.event.on("step", (step) => { authorizedNamespace.emit("updater:step", step); }); diff --git a/src_frontend/Components/Editor/Controls.svelte b/src_frontend/Components/Editor/Controls.svelte index 4b5c8b6..85450a5 100644 --- a/src_frontend/Components/Editor/Controls.svelte +++ b/src_frontend/Components/Editor/Controls.svelte @@ -23,7 +23,6 @@ openSocket.on("power", (power) => power_on = power); openSocket.on("brightness", (value) => brightnessValue = value); openSocket.on("vars", (vars) => variables = vars); - openSocket.on("vars", (vars) => console.log(vars)); openSocket.on("var", (name, value) => { name = name.replace("variable/", ""); if (value.value == null) { @@ -32,7 +31,6 @@ variables[name] = value; } variables = variables; - console.log(variables); }); onMount(() => { diff --git a/src_frontend/Components/Editor/Editor.svelte b/src_frontend/Components/Editor/Editor.svelte index b63ee9b..1876bf6 100644 --- a/src_frontend/Components/Editor/Editor.svelte +++ b/src_frontend/Components/Editor/Editor.svelte @@ -13,6 +13,7 @@ import ControlComponents from "../MainControls/ControlComponents.svelte"; import Controls from "./Controls.svelte"; import Output from "./Output.svelte"; + import Simulation from "./Simulation.svelte"; import { authorizedSocket, authorizedSocketNeeded } from "../../stores/socketStore"; authorizedSocketNeeded.set(true); @@ -276,12 +277,12 @@
+
-
diff --git a/src_frontend/Components/Editor/Simulation.svelte b/src_frontend/Components/Editor/Simulation.svelte new file mode 100644 index 0000000..aba5cdd --- /dev/null +++ b/src_frontend/Components/Editor/Simulation.svelte @@ -0,0 +1,82 @@ + + + + +

(still quite buggy, especially for very fast changing pixels, if nothing is happening, try to restart the script)

+
+ {#each pixels as pixel} + {#if pixel > -1} +
+ {:else} +
+ {/if} + {/each} +
\ No newline at end of file -- cgit v1.2.3