UNPKG

@pickdata/node-red-contrib-emod-simulator

Version:

eManager is an IoT controller designed with eMOD tech for monitoring, control and automation applications. The following nodes are pre-installed in all eMOD devices, although here we present a simulator to practice & test our modular industrial solution.

155 lines (133 loc) 6.29 kB
/** Copyright (c) 2020,2021 PickData SL (https://www.pickdata.net/) All rights reserved. node-red-contrib-emod-simulator - The BSD 3-Clause License **/ module.exports = function(RED) { const di10_simulator = require('@pickdata/emod-js-simulator').DI10; function EMOD10DI_S(config) { RED.nodes.createNode(this,config); var node = this; node.configNode = RED.nodes.getNode(config.modConfig); node.modNumEnabled = config.modNumEnabled; node.modNum = parseInt(config.modNum); if (!node.modNumEnabled) { node.modNum = 1; } node.config_error = false; if (node.configNode == null) { node.status({fill:"red",shape:"ring",text:"Config error"}); node.error("Node has no configuration"); node.config_error = true; return; } var compareModConfig = node.configNode.event_mode == "poll" ? ( function (node, other_node) { // Ambos nodos deberían tener la misma configuración, ya que corresponden al mismo módulo físico. if (!other_node.config_error && other_node.configNode.id != node.configNode.id) { throw new Error("Configuration mismatch between nodes "+node.id+" and "+other_node.id); } } ) : ( function (node, other_node) { // En modo "event" sólo puede haber un único nodo por módulo físico. throw new Error("Only a single node can be configured in event mode"); } ); try { RED.nodes.eachNode(function(n) { //Si node-red aún no ha instanciado el nodo n o está presente en un flow deshabilitado, esta función devuelve null y puede ser ignorado. var other_node = RED.nodes.getNode(n.id); if (other_node != null && other_node.id != node.id) { if (other_node.type == node.type && other_node.modNum == node.modNum) { // Esta función se llama con "other_node" para todos los nodos instanciados que sean del mismo tipo y número (mismo módulo físico) que "node" compareModConfig(node, other_node); } } }); } catch (e) { node.error(e.message); node.status({fill:"red",shape:"ring",text:"Config error"}); node.config_error = true; return; } node.simulator = di10_simulator.getInstance(node.modNum); node.simulator.setPulseFilterTime(node.configNode.pulse_filter_ms); switch (node.configNode.event_mode) { case "poll": node.simulator.setStatusChangeCallback(null); node.simulator.setPulseCounterCallback(null); break; case "status": node.simulator.setStatusChangeCallback(function(new_status) { node.send({payload: {all_status: new_status}}); }); node.simulator.setPulseCounterCallback(null); break; case "pulse-count": node.simulator.setStatusChangeCallback(null); node.simulator.setThreshold(node.configNode.pulse_count_threshold); node.simulator.setPulseCounterCallback(function(index, counter_value) { node.send({payload: {counter: {index: index, value: counter_value}}}); }); break; } node.on('input', function(msg) { if ("reset_pulse_count" in msg.payload) { if (Number.isInteger(msg.payload.reset_pulse_count)) { if (msg.payload.reset_pulse_count < 0 || msg.payload.reset_pulse_count > 9 ) { node.warn("Input index out of range"); return; } node.simulator.resetPulseCounter(msg.payload.reset_pulse_count); } else { node.simulator.resetAllPulseCounter(); } } else if ("get_all" in msg.payload) { if (node.configNode.event_mode != "poll") { node.warn("Polling request made in non-polling mode"); return; } switch (msg.payload.get_all) { case "status": var status = node.simulator.getAllStatus(); node.send({payload: {all_status: status}}); break; case "pulse_count": var counts = node.simulator.getAllCounters(); node.send({payload: {all_counters: counts}}); break; } } else if ("get_one" in msg.payload && typeof msg.payload.get_one === 'object' && msg.payload.get_one !== null) { if (node.configNode.event_mode != "poll") { node.warn("Polling request made in non-polling mode"); return; } var input_index = msg.payload.get_one.index; var input_mode = msg.payload.get_one.mode; if (!Number.isInteger(input_index) || input_index < 0 || input_index > 9) { node.warn("Input index out of range"); return; } switch (input_mode) { case "status": var status = node.simulator.getOneStatus(input_index); node.send({payload: {status: {index: input_index, value: status}}}); break; case "pulse_count": var count = node.simulator.getOneCounter(input_index); node.send({payload: {counter: {index: input_index, value: count}}}); break; } } else { node.error("unknown method call."); } }); node.simulator.startSimulation(); node.status({}); } RED.nodes.registerType("10DI-S",EMOD10DI_S); }