aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stendahl <jakobste@uio.no>2021-10-21 19:28:20 +0200
committerJakob Stendahl <jakobste@uio.no>2021-10-21 19:28:20 +0200
commit6e53fd0dfd830d6d96206419c530c71fa4b3f4e6 (patch)
tree9034a4c9adf3a41c6eb492f2fe6ac06e434275dd
parentf243dc8d7527cde3d5b5a4f6e659cf7604f5ae2a (diff)
downloadLuxcena-Neo-6e53fd0dfd830d6d96206419c530c71fa4b3f4e6.tar.gz
Luxcena-Neo-6e53fd0dfd830d6d96206419c530c71fa4b3f4e6.zip
:sparkles: Add attempt at the "simulation"
-rw-r--r--NeoRuntime/Runtime/luxcena_neo/strip.py2
-rw-r--r--NeoRuntime/Runtime/neo_runtime.py21
-rw-r--r--src/NeoRuntimeManager/IPC.js19
-rw-r--r--src/NeoRuntimeManager/index.js17
-rw-r--r--src/SocketIO/index.js11
-rw-r--r--src_frontend/Components/Editor/Controls.svelte2
-rw-r--r--src_frontend/Components/Editor/Editor.svelte3
-rw-r--r--src_frontend/Components/Editor/Simulation.svelte82
8 files changed, 151 insertions, 6 deletions
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 @@
<main use:initDebugger>
<div class="simulation">
<Pane header="simulation">
+ <Simulation />
</Pane>
</div>
<div class="controls">
<Pane header="Controls">
- <!-- <ControlComponents /> -->
<Controls />
</Pane>
</div>
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 @@
+<script>
+ import { onMount } from "svelte";
+ import { authorizedSocket, authorizedSocketNeeded } from "../../stores/socketStore";
+ authorizedSocketNeeded.set(true);
+
+ let pixels = [];
+ let strip_buffer = [];
+
+ let gridTemplateColumns = "1fr";
+ let gridTemplateRows = "1fr";
+
+ function updateMatrix(matrix) {
+ if (matrix == null) { return; }
+ pixels = [];
+ let columnN = 0;
+ for (let y = 0; y < matrix.length; y++) {
+ if (matrix[y].length > columnN) {
+ columnN = matrix[y].length;
+ }
+ }
+
+ for (let y = 0; y < matrix.length; y++) {
+ for (let x = 0; x < matrix[y].length; x++) {
+ pixels.push(matrix[y][x]);
+ }
+ for (let x = 0; x < (columnN - matrix[y].length); x++) {
+ pixels.push(-1);
+ }
+ }
+ gridTemplateColumns = `repeat(${columnN}, 1fr)`;
+ gridTemplateRows = `repeat(${matrix.length}, 1fr)`;
+ pixels = pixels;
+ }
+
+ async function updateColors(colors) {
+ for (let i = 0; i+2 < colors.length; i+=3) {
+ try {
+ document.querySelector("#sim-pixel-"+(i/3)).style.setProperty("--color", `rgb(${colors[i]}, ${colors[i+1]}, ${colors[i+2]})`);
+ } catch(e) {}
+ }
+ }
+
+ authorizedSocket.on("matrix", updateMatrix);
+ authorizedSocket.on("strip_buffer", updateColors);
+
+ onMount(() => {
+ authorizedSocket.emit("matrix:get");
+ });
+
+</script>
+
+<style>
+ .matrix {
+ display: grid;
+ width: 100%;
+ gap: 10px 10px;
+ }
+ .pixel {
+ display: inline-block;
+ width: 100%;
+ height: 5px;
+ background-color: var(--color);
+ box-shadow: 0 0 10px var(--color);
+ }
+ p {
+ margin: 0;
+ margin-bottom: 5px;
+ font-size: 10px;
+ color: var(--grey-500);
+ }
+</style>
+
+<p>(still quite buggy, especially for very fast changing pixels, if nothing is happening, try to restart the script)</p>
+<div class="matrix" style="grid-template-columns: {gridTemplateColumns}; grid-template-rows: {gridTemplateRows};">
+ {#each pixels as pixel}
+ {#if pixel > -1}
+ <div id="sim-pixel-{pixel}" style="--color:rgb(255, 255, 255)" class="pixel"></div>
+ {:else}
+ <div style="--color:none" class="pixel"></div>
+ {/if}
+ {/each}
+</div> \ No newline at end of file