aboutsummaryrefslogtreecommitdiff
path: root/src/NeoRuntimeManager/IPC.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/NeoRuntimeManager/IPC.js')
-rw-r--r--src/NeoRuntimeManager/IPC.js199
1 files changed, 0 insertions, 199 deletions
diff --git a/src/NeoRuntimeManager/IPC.js b/src/NeoRuntimeManager/IPC.js
deleted file mode 100644
index 56c8b5d..0000000
--- a/src/NeoRuntimeManager/IPC.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * This module is used to communicate with a python NeoRuntime instance.
- *
- * @author jakobst1n.
- * @since 3.10.2021
- */
-
-const net = require("net");
-let logger = require(__appdir + "/src/Logger");
-
-/** @type {int} How long wait between each reconnection attempt */
-const RECONNECT_INTERVAL = 1000;
-/** @type {Object} ENUM-ish for command that can be sent to neoruntime */
-const COMMAND = Object.freeze({SET_GLOB : 0,
- SET_VAR : 1,
- SET_SEND_STRIP_BUF: 2});
-/** @type {Object} ENUM-ish for globvars */
-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,
- MATRIX: 3});
-
-/**
- * class that will keep a active connection to a socket if possible, and
- * automatically reconnect. It will emit events when data is received,
- * and it will send commands to the process. */
-class IPC {
-
- constructor(_socketFile, _eventEmitter) {
- this.socketFile = _socketFile;
- this.eventEmitter = _eventEmitter;
-
- this.client;
- this.connected = false;
- this.reconnectInterval = false;
-
- this.globvars = {};
- this.variables = {};
-
- this.reconnect();
- }
-
- /**
- * If we are not already attempting to reconnect, this will start a
- * interval that tries to reconnect. */
- reconnect() {
- if (this.reconnectInterval === false) {
- this.reconnectInterval = setInterval(this.tryOpenSocketConnection.bind(this), RECONNECT_INTERVAL);
- }
- }
-
- /**
- * This will attempt to connect to the socket, and then setup all listeners
- * if it succedes. */
- tryOpenSocketConnection() {
- // logger.info("Attempting to start IPC");
-
- this.client = net.createConnection(this.socketFile)
- .on('connect', () => {
- clearInterval(this.reconnectInterval);
- this.reconnectInterval = false;
- logger.info("IPC Connected.");
- })
- .on("ready", () => {
- this.connected = true;
- })
- .on('data', (data) => {
- let json_data;
- switch (data[0]) {
- case DATATYPE.STATES:
- try {
- json_data = JSON.parse(data.toString("ascii", 1));
- } catch (e) {
- logger.warning("Could not parse json data from neoruntime");
- return;
- }
-
- if (json_data.hasOwnProperty("globvars")) {
- forEachDiff(json_data["globvars"], this.globvars, (key, newVal) => {
- this.eventEmitter.emit("change", key, newVal);
- });
- this.globvars = json_data["globvars"];
- }
- if (json_data.hasOwnProperty("variables")) {
- forEachDiff(json_data["variables"], this.variables, (key, newVal) => {
- this.eventEmitter.emit("change", `variable/${key}`, newVal);
- });
- 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);
- }
-
- })
- .on("timeout", () => {
- logger.info("IPC Timeout");
- })
- .on("close", (hadError) => {
- logger.info("IPC Close, hadError: ", hadError);
- this.connected = false;
- this.reconnect();
- })
- .on("end", () => {
- logger.info("IPC End");
- this.connected = false;
- })
- .on('error', (data) => {
- logger.info('IPC Server not active.');
- this.connected = false;
- this.reconnect();
- })
- ;
- }
-
- /**
- * Will send a command to the socket if we have a active connection,
- * if not it will just drop the command. there is no queue implemented
- * for such events. */
- sendCommand(commandType, name, value) {
- if (this.connected) {
- let buf;
-
- switch (commandType) {
- case (COMMAND.SET_GLOB):
- buf = Buffer.allocUnsafe(3);
- buf[1] = name;
- buf[2] = value;
- break;
-
- case (COMMAND.SET_VAR):
- if (name.length > 32) { return {success: false, reason: "name too long", detail: "max size of name is 32 bytes"}; }
- if (value.length > 93) { return {success: false, reason: "value too long", detail: "max size of value is 93 bytes"}; }
- buf = Buffer.allocUnsafe(3 + name.length + value.length);
- buf[1] = name.length;
- buf[2] = value.length;
- buf.write(name, 3, name.length, "ascii");
- buf.write(value, 3+name.length, value.length, "ascii");
- break;
-
- case (COMMAND.SET_SEND_STRIP_BUF):
- buf = Buffer.allocUnsafe(2);
- buf[1] = (name) ? 1 : 0;
- break;
-
- default:
- logger.warning(`IPC UNKNOWN COMMANDTYPE ${commandType}`)
- return {success: false, reason: "ipc command unknown", detail: commandType};
- }
-
- buf[0] = commandType;
- this.client.write(buf);
- return {success: true}
- }
- return {success: false, reason: "socket not connected", detail: "This usually means the python script is not running"};
- }
-
-}
-
-const isObject = v => v && typeof v === 'object';
-
-/**
- * Will call callback on all the differences between the dicts
- */
-function forEachDiff(dict1, dict2, callback) {
- for (const key of new Set([...Object.keys(dict1), ...Object.keys(dict2)])) {
- if (isObject(dict1[key]) && isObject(dict2[key])) {
- if (dict1[key].value !== dict2[key].value) {
- callback(key, dict1[key]);
- }
- } else if (dict1[key] !== dict2[key]) {
- if (isObject(dict2[key]) && (dict1[key] == null)) {
- dict2[key].value = null;
- callback(key, dict2[key])
- } else {
- callback(key, dict1[key]);
- }
- }
- }
-}
-
-module.exports = {IPC, COMMAND, GLOBVAR};