Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-red-contrib-omron-fins

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-red-contrib-omron-fins - npm Package Compare versions

Comparing version 0.5.0-beta.0 to 0.5.0-beta.1

21

.eslintrc.js
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true,
"node": true
env: {
browser: true,
commonjs: true,
es2021: true,
node: true,
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12
extends: 'eslint:recommended',
parserOptions: {
ecmaVersion: 12,
},
"rules": {
}
rules: {
indent: ['error', 4],
},
};

@@ -22,190 +22,188 @@ /*

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
*/
const clients = {};
function convertPayloadToDataArray(payload) {
let array = [];
let str = '';
let array = [];
let str = '';
if (Array.isArray(payload)) {
return payload;
} else if (typeof payload === "string") {
str = "" + payload;
} else if (typeof payload === "number") {
return [payload];
} else if (typeof payload === "boolean") {
return [payload];
}
if (Array.isArray(payload)) {
return payload;
} if (typeof payload === 'string') {
str = `${payload}`;
} else if (typeof payload === 'number') {
return [payload];
} else if (typeof payload === 'boolean') {
return [payload];
}
if (str.length === 0) {
return null;
} else {
if (str.length === 0) {
return null;
}
array = str.split(/\s*,\s*/);
}
return array;
return array;
}
module.exports = {
get: function (node, port, host, opts) {
const fins = require('./omron-fins.js');
const id = `FinsClient:{host:'${host || ""}', port:'${port || ""}', protocol:'${opts.protocol || "udp"}', MODE:'${opts.MODE}', ICF:'${opts.ICF}', DNA:'${opts.DNA}', DA1:'${opts.DA1}', DA2:'${opts.DA2}', SNA:'${opts.SNA}', SA1:'${opts.SA1}', SA2:'${opts.SA2}'}`;
get(node, port, host, opts) {
const fins = require('./omron-fins');
const id = `FinsClient:{host:'${host || ''}', port:'${port || ''}', protocol:'${opts.protocol || 'udp'}', MODE:'${opts.MODE}', ICF:'${opts.ICF}', DNA:'${opts.DNA}', DA1:'${opts.DA1}', DA2:'${opts.DA2}', SNA:'${opts.SNA}', SA1:'${opts.SA1}', SA2:'${opts.SA2}'}`;
if (!clients[id]) {
clients[id] = function () {
const options = opts || {};
const h = host || options.host;
const p = port || options.port;
if (!clients[id]) {
clients[id] = (function () {
const options = opts || {};
const h = host || options.host;
const p = port || options.port;
node.log(`[FINS] adding new connection to pool ~ ${id}`);
let client = fins.FinsClient(parseInt(p), h, options);
let connecting = false;
node.log(`[FINS] adding new connection to pool ~ ${id}`);
let client = fins.FinsClient(parseInt(p), h, options);
let connecting = false;
options.autoConnect = options.autoConnect == undefined ? true : options.autoConnect;
options.preventAutoReconnect = false;
options.autoConnect = options.autoConnect == undefined ? true : options.autoConnect;
options.preventAutoReconnect = false;
const finsClientConnection = {
const finsClientConnection = {
_instances: 0,
write: function (address, data, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const _data = convertPayloadToDataArray(data);
if (!Array.isArray(_data)) {
throw new Error('data is not valid');
}
const sid = client.write(address, _data, opts, tag);
return sid;
},
read: function (address, len, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.read(address, parseInt(len), opts, tag);
return sid;
},
readMultiple: function (addresses, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.readMultiple(addresses, opts, tag);
return sid;
},
fill: function (address, value, count, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.fill(address, value, parseInt(count), opts, tag);
return sid;
},
transfer: function (srcAddress, dstAddress, count, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.transfer(srcAddress, dstAddress, parseInt(count), opts, tag);
return sid;
},
status: function (opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.status(opts, tag);
return sid;
},
run: function (opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.run(opts, tag);
return sid;
},
stop: function (opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.stop(opts, tag);
return sid;
},
cpuUnitDataRead: function (opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error("Not connected!")
}
const sid = client.cpuUnitDataRead(opts, tag);
return sid;
},
getAutoConnect: function () {
return (options.autoConnect == true);
},
setAutoConnect: function (b) {
options.autoConnect = (b == true);
},
on: function (a, b) {
client.on(a, b);
},
connect: function () {
options.preventAutoReconnect = false;
if (client && !client.connected && !connecting) {
connecting = true;
client.reconnect();
}
},
closeConnection: function () {
options.preventAutoReconnect = true;
if (client){
client.close();
}
connecting = false;
},
stringToFinsAddress: function (addressString) {
return client.stringToFinsAddress(addressString);
},
_instances: 0,
write(address, data, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const _data = convertPayloadToDataArray(data);
if (!Array.isArray(_data)) {
throw new Error('data is not valid');
}
const sid = client.write(address, _data, opts, tag);
return sid;
},
read(address, len, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.read(address, parseInt(len), opts, tag);
return sid;
},
readMultiple(addresses, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.readMultiple(addresses, opts, tag);
return sid;
},
fill(address, value, count, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.fill(address, value, parseInt(count), opts, tag);
return sid;
},
transfer(srcAddress, dstAddress, count, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.transfer(srcAddress, dstAddress, parseInt(count), opts, tag);
return sid;
},
status(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.status(opts, tag);
return sid;
},
run(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.run(opts, tag);
return sid;
},
stop(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.stop(opts, tag);
return sid;
},
cpuUnitDataRead(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.cpuUnitDataRead(opts, tag);
return sid;
},
getAutoConnect() {
return (options.autoConnect == true);
},
setAutoConnect(b) {
options.autoConnect = (b == true);
},
on(a, b) {
client.on(a, b);
},
connect() {
options.preventAutoReconnect = false;
if (client && !client.connected && !connecting) {
connecting = true;
client.reconnect();
}
},
closeConnection() {
options.preventAutoReconnect = true;
if (client) {
client.close();
}
connecting = false;
},
stringToFinsAddress(addressString) {
return client.stringToFinsAddress(addressString);
},
FinsAddressToString: function (decodedAddress, offsetWD, offsetBit) {
return client.FinsAddressToString(decodedAddress, offsetWD, offsetBit);
},
FinsAddressToString(decodedAddress, offsetWD, offsetBit) {
return client.FinsAddressToString(decodedAddress, offsetWD, offsetBit);
},
disconnect: function () {
this._instances -= 1;
if (this._instances <= 0) {
node.log(`[FINS] closing connection ~ ${id}`);
client.close();
client = null;
node.log(`[FINS] deleting connection from pool ~ ${id}`);
delete clients[id];
}
}
};
disconnect() {
this._instances -= 1;
if (this._instances <= 0) {
node.log(`[FINS] closing connection ~ ${id}`);
client.close();
client = null;
node.log(`[FINS] deleting connection from pool ~ ${id}`);
delete clients[id];
}
},
};
client.on('open', function () {
if (client) {
node.log(`[FINS] connected ~ ${id}`);
connecting = false;
}
});
// eslint-disable-next-line no-unused-vars
client.on('close', function (err) {
node.log(`[FINS] connection closed ~ ${id}`);
connecting = false;
client.on('open', () => {
if (client) {
node.log(`[FINS] connected ~ ${id}`);
connecting = false;
}
});
// eslint-disable-next-line no-unused-vars
client.on('close', (err) => {
node.log(`[FINS] connection closed ~ ${id}`);
connecting = false;
if(options.autoConnect && !options.preventAutoReconnect){
setTimeout(function () {
if(options.autoConnect && !options.preventAutoReconnect){
node.log(`[FINS] autoConnect call from error handler ~ ${id}`);
finsClientConnection.connect();
}
}, 5000); //TODO: Parametrise
}
});
if (options.autoConnect && !options.preventAutoReconnect) {
setTimeout(() => {
if (options.autoConnect && !options.preventAutoReconnect) {
node.log(`[FINS] autoConnect call from error handler ~ ${id}`);
finsClientConnection.connect();
}
}, 5000); // TODO: Parametrise
}
});
return finsClientConnection
}();
}
clients[id]._instances += 1;
return clients[id];
}
};
return finsClientConnection;
}());
}
clients[id]._instances += 1;
return clients[id];
},
};

@@ -27,188 +27,187 @@ /* eslint-disable no-inner-declarations */

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const connection_pool = require('../connection_pool.js');
const controlTypes = ['status', 'cpu-unit-data-read', 'stop', 'run'];
function omronControl(config) {
RED.nodes.createNode(this, config);
const node = this;
node.name = config.name;
node.topic = config.topic;
node.connection = config.connection;
node.address = config.address || "topic";
node.addressType = config.addressType || "msg";
node.count = config.count || 1;
node.countType = config.countType || "num";
node.control = config.control || "status";
node.controlType = config.controlType || "status";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.connectionConfig = RED.nodes.getNode(node.connection);
if (this.connectionConfig) {
const options = Object.assign({}, node.connectionConfig.options);
node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);
node.status({ fill: "yellow", shape: "ring", text: "initialising" });
this.client.on('error', function (error, seq) {
node.status({ fill: "red", shape: "ring", text: "error" });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.status({ fill: "red", shape: "dot", text: "queue full" });
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
});
/* **************** Node status **************** */
function nodeStatusError (err, msg, statusText) {
if (err) {
node.error(err, msg);
} else {
node.error(statusText, msg);
}
node.status({ fill: "red", shape: "dot", text: statusText });
}
function finsReply(err, sequence) {
if(!err && !sequence) {
return;
}
var origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, "error")
return;
RED.nodes.createNode(this, config);
const node = this;
node.name = config.name;
node.topic = config.topic;
node.connection = config.connection;
node.address = config.address || 'topic';
node.addressType = config.addressType || 'msg';
node.count = config.count || 1;
node.countType = config.countType || 'num';
node.control = config.control || 'status';
node.controlType = config.controlType || 'status';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);
if (this.connectionConfig) {
const options = Object.assign({}, node.connectionConfig.options);
node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
this.client.on('error', function (error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.throttleUntil = Date.now() + 1000;
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});
/* **************** Node status **************** */
function nodeStatusError(err, msg, statusText) {
if (err) {
node.error(err, msg);
} else {
node.error(statusText, msg);
}
node.status({ fill: 'red', shape: 'dot', text: statusText });
}
if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
return;
function finsReply(err, sequence) {
if (!err && !sequence) {
return;
}
var origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
}
if (sequence.timeout) {
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID')
return;
}
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== sequence.request.command.commandCode) {
var ecd = 'bad response';
if (sequence.response.command.commandCode !== sequence.request.command.commandCode)
ecd = `Unexpected response. Expected command '${sequence.request.command.commandCode}' but received '${sequence.request.command.commandCode}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;
}
//set the output property
RED.util.setObjectProperty(origInputMsg, node.msgProperty, sequence.response, true);
//include additional detail in msg.fins
origInputMsg.fins = {};
origInputMsg.fins.name = node.name; //node name for user logging / routing
origInputMsg.fins.request = {
command: sequence.request.command,
options: sequence.request.options,
sid: sequence.request.sid,
};
origInputMsg.fins.response = sequence.response;
origInputMsg.fins.stats = sequence.stats;
origInputMsg.fins.createTime = sequence.createTime;
origInputMsg.fins.replyTime = sequence.replyTime;
origInputMsg.fins.timeTaken = sequence.timeTaken;
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, 'error');
}
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID")
return;
}
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command.commandCode !== sequence.request.command.commandCode) {
var ecd = "bad response";
if (sequence.response.command.commandCode !== sequence.request.command.commandCode)
ecd = `Unexpected response. Expected command '${sequence.request.command.commandCode}' but received '${sequence.request.command.commandCode}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
return;
}
//set the output property
RED.util.setObjectProperty(origInputMsg, node.msgProperty, sequence.response, true);
//include additional detail in msg.fins
origInputMsg.fins = {};
origInputMsg.fins.name = node.name; //node name for user logging / routing
origInputMsg.fins.request = {
command: sequence.request.command,
options: sequence.request.options,
sid: sequence.request.sid,
};
origInputMsg.fins.response = sequence.response;
origInputMsg.fins.stats = sequence.stats;
origInputMsg.fins.createTime = sequence.createTime;
origInputMsg.fins.replyTime = sequence.replyTime;
origInputMsg.fins.timeTaken = sequence.timeTaken;
node.status({ fill: "green", shape: "dot", text: "done" });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
}
this.on('close', function (done) {
if (done) done();
});
this.on('input', function (msg) {
if (node.throttleUntil) {
if (node.throttleUntil > Date.now()) return; //throttled
node.throttleUntil = null; //throttle time over
}
node.status({});//clear status
if (msg.disconnect === true || msg.topic === 'disconnect') {
node.client.closeConnection();
return;
} else if (msg.connect === true || msg.topic === 'connect') {
node.client.connect();
return;
}
let control = 'status';
if (controlTypes.indexOf(node.controlType + '') > 0) {
control = node.controlType;
} else {
control = RED.util.evaluateNodeProperty(node.control, node.controlType, node, msg);
}
if (controlTypes.indexOf(control) < 0) {
nodeStatusError(null, msg, `control command ${control} is not valid`);
return;
}
let clientFn;
switch (control) {
case 'status':
case 'stop':
case 'run':
clientFn = node.client[control];
break;
case 'cpu-unit-data-read':
clientFn = node.client.cpuUnitDataRead;
break;
}
const opts = msg.finsOptions || {};
let sid;
try {
opts.callback = finsReply;
sid = clientFn(opts, msg);
if (sid > 0) {
node.status({ fill: 'yellow', shape: 'ring', text: 'reading' });
}
} catch (error) {
node.sid = null;
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "control.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
opts: opts,
};
node.debug(debugMsg);
return;
}
});
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
this.on('close', function (done) {
if (done) done();
});
this.on('input', function (msg) {
if (node.throttleUntil) {
if (node.throttleUntil > Date.now()) return; //throttled
node.throttleUntil = null; //throttle time over
}
node.status({});//clear status
if (msg.disconnect === true || msg.topic === 'disconnect') {
node.client.closeConnection();
return;
} else if (msg.connect === true || msg.topic === 'connect') {
node.client.connect();
return;
}
let control = "status";
if(controlTypes.indexOf(node.controlType+'') > 0) {
control = node.controlType;
} else {
control = RED.util.evaluateNodeProperty(node.control, node.controlType, node, msg);
}
if(controlTypes.indexOf(control) < 0) {
nodeStatusError(null, msg, `control command ${control} is not valid`);
return;
}
let clientFn;
switch (control) {
case "status":
case "stop":
case "run":
clientFn = node.client[control];
break;
case "cpu-unit-data-read":
clientFn = node.client.cpuUnitDataRead;
break;
}
const opts = msg.finsOptions || {};
let sid;
try {
opts.callback = finsReply;
sid = clientFn(opts, msg);
if (sid > 0) {
node.status({ fill: "yellow", shape: "ring", text: "reading" });
}
} catch (error) {
node.sid = null;
nodeStatusError(error, msg, "error");
const debugMsg = {
info: "control.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
opts: opts,
};
node.debug(debugMsg);
return;
}
});
node.status({ fill: "green", shape: "ring", text: "ready" });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
}
}
RED.nodes.registerType("FINS Control", omronControl);
RED.nodes.registerType('FINS Control', omronControl);
omronControl.prototype.close = function () {
if (this.client) {
this.client.disconnect();
}
if (this.client) {
this.client.disconnect();
}
};
};
};

@@ -26,16 +26,17 @@ /*

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const connection_pool = require('../connection_pool.js');
function omronFill(config) {
RED.nodes.createNode(this, config);
const node = this;
const cmdExpected = '0103';
node.name = config.name;
node.connection = config.connection;
node.address = config.address || "";
node.addressType = config.addressType || "str";
node.count = config.count || "1";
node.countType = config.countType || "num";
node.value = config.value || "0";
node.valueType = config.valueType || "num";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.address = config.address || '';
node.addressType = config.addressType || 'str';
node.count = config.count || '1';
node.countType = config.countType || 'num';
node.value = config.value || '0';
node.valueType = config.valueType || 'num';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);

@@ -52,3 +53,3 @@

}
node.status({ fill: "red", shape: "dot", text: statusText });
node.status({ fill: 'red', shape: 'dot', text: statusText });
}

@@ -59,3 +60,3 @@

node.status({ fill: "yellow", shape: "ring", text: "initialising" });
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
const options = Object.assign({}, node.connectionConfig.options);

@@ -65,20 +66,20 @@ this.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);

this.client.on('error', function (error, seq) {
console.log("Error: ", error);
node.status({ fill: "red", shape: "ring", text: "error" });
console.log('Error: ', error);
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.status({ fill: "red", shape: "dot", text: "queue full" });
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
this.client.on('initialised', function () {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});

@@ -91,7 +92,7 @@

}
var origInputMsg = (sequence && sequence.tag) || {};
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
node.status({ fill: "red", shape: "ring", text: "error" });
nodeStatusError(err || sequence.error, origInputMsg, "error");
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');

@@ -101,18 +102,18 @@ return;

if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID");
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID');
return;
}
var cmdExpected = "0103";
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command !== cmdExpected) {
var ecd = "bad response";
if (sequence.response && sequence.response.command !== cmdExpected)
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== cmdExpected) {
let ecd = 'bad response';
if (sequence.response && sequence.response.command.commandCode !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;

@@ -128,4 +129,6 @@ }

origInputMsg.fins.request = {
command: sequence.request.command,
options: sequence.request.options,
address: sequence.request.address,
dataToBeWritten: sequence.request.dataToBeWritten,
count: sequence.request.count,
sid: sequence.request.sid,

@@ -139,6 +142,6 @@ };

node.status({ fill: "green", shape: "dot", text: "done" });
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
nodeStatusError(error, origInputMsg, 'error');

@@ -169,4 +172,4 @@ }

const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg);
if (!address || typeof address != "string") {
nodeStatusError(null, msg, "address is not valid");
if (!address || typeof address != 'string') {
nodeStatusError(null, msg, 'address is not valid');
return;

@@ -197,6 +200,6 @@ }

sid = node.client.fill(address, fillValue, fillCount, opts, msg);
if (sid > 0) node.status({ fill: "yellow", shape: "ring", text: "fill" });
if (sid > 0) node.status({ fill: 'yellow', shape: 'ring', text: 'fill' });
} catch (error) {
nodeStatusError(error, msg, "error");
nodeStatusError(error, msg, 'error');
const debugMsg = {

@@ -217,10 +220,10 @@ info: "fill.js-->on 'input' - try this.client.fill(address, fillValue, fillCount, opts, msg)",

});
node.status({ fill: "green", shape: "ring", text: "ready" });
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
}
RED.nodes.registerType("FINS Fill", omronFill);
RED.nodes.registerType('FINS Fill', omronFill);
omronFill.prototype.close = function () {

@@ -227,0 +230,0 @@ if (this.client) {

@@ -27,235 +27,236 @@ /* eslint-disable no-inner-declarations */

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const dataParser = require("./_parser");
const connection_pool = require('../connection_pool.js');
const dataParser = require('./_parser');
function omronRead(config) {
RED.nodes.createNode(this, config);
const node = this;
node.name = config.name;
node.topic = config.topic;
node.connection = config.connection;
node.address = config.address || "topic";
node.addressType = config.addressType || "msg";
node.count = config.count || 1;
node.countType = config.countType || "num";
node.outputFormat = config.outputFormat || "buffer";
node.outputFormatType = config.outputFormatType || "list";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.connectionConfig = RED.nodes.getNode(node.connection);
function omronRead(config) {
RED.nodes.createNode(this, config);
const node = this;
const cmdExpected = '0101';
node.name = config.name;
node.topic = config.topic;
node.connection = config.connection;
node.address = config.address || 'topic';
node.addressType = config.addressType || 'msg';
node.count = config.count || 1;
node.countType = config.countType || 'num';
node.outputFormat = config.outputFormat || 'buffer';
node.outputFormatType = config.outputFormatType || 'list';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);
if (this.connectionConfig) {
const options = Object.assign({}, node.connectionConfig.options);
node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);
node.status({ fill: "yellow", shape: "ring", text: "initialising" });
if (this.connectionConfig) {
const options = Object.assign({}, node.connectionConfig.options);
node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
this.client.on('error', function (error, seq) {
node.status({ fill: "red", shape: "ring", text: "error" });
node.error(error, (seq && seq.tag ? seq.tag : seq) );
});
this.client.on('full', function () {
node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.status({ fill: "red", shape: "dot", text: "queue full" });
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
});
this.client.on('error', function (error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.throttleUntil = Date.now() + 1000;
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});
/* **************** Node status **************** */
function nodeStatusError (err, msg, statusText) {
if (err) {
node.error(err, msg);
} else {
node.error(statusText, msg);
}
node.status({ fill: "red", shape: "dot", text: statusText });
}
/* **************** Node status **************** */
function nodeStatusError(err, msg, statusText) {
if (err) {
node.error(err, msg);
} else {
node.error(statusText, msg);
}
node.status({ fill: 'red', shape: 'dot', text: statusText });
}
const cmdExpected = "0101";
function finsReply(err, sequence) {
if(!err && !sequence) {
return;
}
var origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, "error")
return;
}
if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID")
return;
}
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command !== cmdExpected) {
var ecd = "bad response";
if (sequence.response && sequence.response.command !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
return;
}
function finsReply(err, sequence) {
if (!err && !sequence) {
return;
}
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
}
if (sequence.timeout) {
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID')
return;
}
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== cmdExpected) {
let ecd = 'bad response';
if (sequence.response && sequence.response.command.commandCode !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;
}
//backwards compatibility, try to upgrade users current setting
//the output type was originally a sub option 'list'
let outputFormat = "buffer";
const builtInReturnTypes = ['buffer', 'signed', 'unsigned', 'signedkv', 'unsignedkv'];
if(node.outputFormatType == "list" && builtInReturnTypes.indexOf(node.outputFormat+'') >= 0) {
outputFormat = node.outputFormat;
} else if(builtInReturnTypes.indexOf(node.outputFormatType+'') > 0) {
outputFormat = node.outputFormatType;
} else {
outputFormat = RED.util.evaluateNodeProperty(node.outputFormat, node.outputFormatType, node, origInputMsg);
}
//backwards compatibility, try to upgrade users current setting
//the output type was originally a sub option 'list'
let outputFormat = 'buffer';
const builtInReturnTypes = ['buffer', 'signed', 'unsigned', 'signedkv', 'unsignedkv'];
if (node.outputFormatType == 'list' && builtInReturnTypes.indexOf(node.outputFormat + '') >= 0) {
outputFormat = node.outputFormat;
} else if (builtInReturnTypes.indexOf(node.outputFormatType + '') > 0) {
outputFormat = node.outputFormatType;
} else {
outputFormat = RED.util.evaluateNodeProperty(node.outputFormat, node.outputFormatType, node, origInputMsg);
}
let value;
switch (outputFormat) {
case "signed":
if(sequence.request.address.isBitAddress) {
value = sequence.response.values.map(e => !!e);
} else {
value = sequence.response.values;
}
break;
case "unsigned":
if(sequence.request.address.isBitAddress) {
value = sequence.response.values;
} else {
sequence.response.values = Uint16Array.from(sequence.response.values);
value = sequence.response.values;
}
break;
case "signedkv":
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
if(sequence.request.address.isBitAddress) {
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, true);
} else {
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
}
break;
case "unsignedkv":
if(sequence.request.address.isBitAddress) {
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, false);
} else {
sequence.response.values = Uint16Array.from(sequence.response.values);
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
}
break;
default: //buffer
value = sequence.response.buffer;
break;
}
let value;
switch (outputFormat) {
case 'signed':
if (sequence.request.address.isBitAddress) {
value = sequence.response.values.map(e => !!e);
} else {
value = sequence.response.values;
}
break;
case 'unsigned':
if (sequence.request.address.isBitAddress) {
value = sequence.response.values;
} else {
sequence.response.values = Uint16Array.from(sequence.response.values);
value = sequence.response.values;
}
break;
case 'signedkv':
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
if (sequence.request.address.isBitAddress) {
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, true);
} else {
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
}
break;
case 'unsignedkv':
if (sequence.request.address.isBitAddress) {
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, false);
} else {
sequence.response.values = Uint16Array.from(sequence.response.values);
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values);
}
break;
default: //buffer
value = sequence.response.buffer;
break;
}
//set the output property
RED.util.setObjectProperty(origInputMsg, node.msgProperty, value, true);
//set the output property
RED.util.setObjectProperty(origInputMsg, node.msgProperty, value, true);
//include additional detail in msg.fins
origInputMsg.fins = {};
origInputMsg.fins.name = node.name; //node name for user logging / routing
origInputMsg.fins.request = {
address: sequence.request.address,
count: sequence.request.count,
sid: sequence.request.sid,
};
//include additional detail in msg.fins
origInputMsg.fins = {};
origInputMsg.fins.name = node.name; //node name for user logging / routing
origInputMsg.fins.request = {
command: sequence.request.command,
options: sequence.request.options,
address: sequence.request.address,
count: sequence.request.count,
sid: sequence.request.sid,
};
origInputMsg.fins.response = sequence.response;
origInputMsg.fins.stats = sequence.stats;
origInputMsg.fins.createTime = sequence.createTime;
origInputMsg.fins.replyTime = sequence.replyTime;
origInputMsg.fins.timeTaken = sequence.timeTaken;
origInputMsg.fins.response = sequence.response;
origInputMsg.fins.stats = sequence.stats;
origInputMsg.fins.createTime = sequence.createTime;
origInputMsg.fins.replyTime = sequence.replyTime;
origInputMsg.fins.timeTaken = sequence.timeTaken;
node.status({ fill: "green", shape: "dot", text: "done" });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
}
}
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, 'error');
}
}
this.on('close', function (done) {
if (done) done();
});
this.on('close', function (done) {
if (done) done();
});
this.on('input', function (msg) {
if (node.throttleUntil) {
if (node.throttleUntil > Date.now()) return; //throttled
node.throttleUntil = null; //throttle time over
}
node.status({});//clear status
this.on('input', function (msg) {
if (node.throttleUntil) {
if (node.throttleUntil > Date.now()) return; //throttled
node.throttleUntil = null; //throttle time over
}
node.status({});//clear status
if (msg.disconnect === true || msg.topic === 'disconnect') {
node.client.closeConnection();
return;
} else if (msg.connect === true || msg.topic === 'connect') {
node.client.connect();
return;
}
if (msg.disconnect === true || msg.topic === 'disconnect') {
node.client.closeConnection();
return;
} else if (msg.connect === true || msg.topic === 'connect') {
node.client.connect();
return;
}
/* **************** Get address Parameter **************** */
const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg);
/* **************** Get address Parameter **************** */
const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg);
/* **************** Get count Parameter **************** */
let count = RED.util.evaluateNodeProperty(node.count, node.countType, node, msg);
/* **************** Get count Parameter **************** */
let count = RED.util.evaluateNodeProperty(node.count, node.countType, node, msg);
if (!address || typeof address != "string") {
nodeStatusError(null, msg, "address is not valid");
return;
}
count = parseInt(count);
if (Number.isNaN(count) || count <= 0) {
nodeStatusError(null, msg, "count is not valid");
return;
}
if (!address || typeof address != 'string') {
nodeStatusError(null, msg, 'address is not valid');
return;
}
count = parseInt(count);
if (Number.isNaN(count) || count <= 0) {
nodeStatusError(null, msg, 'count is not valid');
return;
}
const opts = msg.finsOptions || {};
let sid;
try {
opts.callback = finsReply;
sid = node.client.read(address, count, opts, msg);
if (sid > 0) {
node.status({ fill: "yellow", shape: "ring", text: "reading" });
}
} catch (error) {
node.sid = null;
nodeStatusError(error, msg, "error");
const debugMsg = {
info: "read.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
count: count,
opts: opts,
};
node.debug(debugMsg);
return;
}
const opts = msg.finsOptions || {};
let sid;
try {
opts.callback = finsReply;
sid = node.client.read(address, count, opts, msg);
if (sid > 0) {
node.status({ fill: 'yellow', shape: 'ring', text: 'reading' });
}
} catch (error) {
node.sid = null;
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "read.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
count: count,
opts: opts,
};
node.debug(debugMsg);
return;
}
});
node.status({ fill: "green", shape: "ring", text: "ready" });
});
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
}
}
RED.nodes.registerType("FINS Read", omronRead);
omronRead.prototype.close = function () {
if (this.client) {
this.client.disconnect();
}
};
RED.nodes.registerType('FINS Read', omronRead);
omronRead.prototype.close = function () {
if (this.client) {
this.client.disconnect();
}
};
};

@@ -27,3 +27,3 @@ /* eslint-disable no-inner-declarations */

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const connection_pool = require('../connection_pool.js');
// const dataParser = require("./_parser");

@@ -34,11 +34,12 @@

const node = this;
const cmdExpected = '0104';
node.name = config.name;
node.topic = config.topic;
node.connection = config.connection;
node.address = config.address || "";
node.addressType = config.addressType || "str";
node.outputFormat = config.outputFormat || "buffer";
node.outputFormatType = config.outputFormatType || "list";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.address = config.address || '';
node.addressType = config.addressType || 'str';
node.outputFormat = config.outputFormat || 'buffer';
node.outputFormatType = config.outputFormatType || 'list';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);

@@ -49,6 +50,6 @@

node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);
node.status({ fill: "yellow", shape: "ring", text: "initialising" });
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
this.client.on('error', function (error, seq) {
node.status({ fill: "red", shape: "ring", text: "error" });
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));

@@ -58,15 +59,15 @@ });

node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.status({ fill: "red", shape: "dot", text: "queue full" });
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});

@@ -80,7 +81,5 @@ /* **************** Node status **************** */

}
node.status({ fill: "red", shape: "dot", text: statusText });
node.status({ fill: 'red', shape: 'dot', text: statusText });
}
const cmdExpected = "0104";
function finsReply(err, sequence) {

@@ -90,27 +89,27 @@ if (!err && !sequence) {

}
var origInputMsg = (sequence && sequence.tag) || {};
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, "error")
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
}
if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID")
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID')
return;
}
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command !== cmdExpected) {
var ecd = "bad response";
if (sequence.response && sequence.response.command !== cmdExpected)
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== cmdExpected) {
let ecd = 'bad response';
if (sequence.response && sequence.response.command.commandCode !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;
}
let outputFormat = "unsignedkv";
let outputFormat = 'unsignedkv';
const builtInReturnTypes = ['signed', 'unsigned', 'signedkv', 'unsignedkv'];

@@ -124,3 +123,3 @@ if (builtInReturnTypes.indexOf(node.outputFormatType + '') > 0) {

if (sequence.response.values.length != sequence.request.address.length) {
nodeStatusError(`Requested count '${sequence.request.address.length}' different to returned count '${sequence.response.values.length}`, origInputMsg, "error");
nodeStatusError(`Requested count '${sequence.request.address.length}' different to returned count '${sequence.response.values.length}`, origInputMsg, 'error');
return;

@@ -138,30 +137,30 @@ }

switch (outputFormat) {
case "signed":
if (addr.isBitAddress) {
arrValues.push(!!val);
} else {
arrValues.push(val);
}
break;
case "unsigned":
if (addr.isBitAddress) {
arrValues.push(val);
} else {
arrValues.push(Uint16Array.from([val])[0]);
}
break;
case "signedkv":
if (addr.isBitAddress) {
objValues[addrString] = (val == 1 || val == true) ? 1 : 0;
} else {
objValues[addrString] = val;
}
break;
default: //case "unsignedkv": //default
if (addr.isBitAddress) {
objValues[addrString] = (val == 1 || val == true) ? 1 : 0;
} else {
objValues[addrString] = Uint16Array.from([val])[0];
}
break;
case 'signed':
if (addr.isBitAddress) {
arrValues.push(!!val);
} else {
arrValues.push(val);
}
break;
case 'unsigned':
if (addr.isBitAddress) {
arrValues.push(val);
} else {
arrValues.push(Uint16Array.from([val])[0]);
}
break;
case 'signedkv':
if (addr.isBitAddress) {
objValues[addrString] = (val == 1 || val == true) ? 1 : 0;
} else {
objValues[addrString] = val;
}
break;
default: //case "unsignedkv": //default
if (addr.isBitAddress) {
objValues[addrString] = (val == 1 || val == true) ? 1 : 0;
} else {
objValues[addrString] = Uint16Array.from([val])[0];
}
break;
}

@@ -188,6 +187,6 @@ }

node.status({ fill: "green", shape: "dot", text: "done" });
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
nodeStatusError(error, origInputMsg, 'error');
}

@@ -218,4 +217,4 @@ }

const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg);
if (!address || typeof address != "string") {
nodeStatusError(null, msg, "Address is not valid");
if (!address || typeof address != 'string') {
nodeStatusError(null, msg, 'Address is not valid');
return;

@@ -230,7 +229,7 @@ }

if (sid > 0) {
node.status({ fill: "yellow", shape: "ring", text: "reading" });
node.status({ fill: 'yellow', shape: 'ring', text: 'reading' });
}
} catch (error) {
node.sid = null;
nodeStatusError(error, msg, "error");
nodeStatusError(error, msg, 'error');
const debugMsg = {

@@ -248,9 +247,9 @@ info: "readMultiple.js-->on 'input'",

});
node.status({ fill: "green", shape: "ring", text: "ready" });
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
}
RED.nodes.registerType("FINS Read Multiple", omronReadMultiple);
RED.nodes.registerType('FINS Read Multiple', omronReadMultiple);
omronReadMultiple.prototype.close = function () {

@@ -257,0 +256,0 @@ if (this.client) {

@@ -27,16 +27,17 @@ /* eslint-disable no-inner-declarations */

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const connection_pool = require('../connection_pool.js');
function omronTransfer(config) {
RED.nodes.createNode(this, config);
const node = this;
const cmdExpected = '0105';
node.name = config.name;
node.connection = config.connection;
node.address = config.address || "";
node.addressType = config.addressType || "str";
node.address2 = config.address2 || "";
node.address2Type = config.addressType || "str";
node.count = config.count || "1";
node.countType = config.countType || "num";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.address = config.address || '';
node.addressType = config.addressType || 'str';
node.address2 = config.address2 || '';
node.address2Type = config.addressType || 'str';
node.count = config.count || '1';
node.countType = config.countType || 'num';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);

@@ -53,3 +54,3 @@

}
node.status({ fill: "red", shape: "dot", text: statusText });
node.status({ fill: 'red', shape: 'dot', text: statusText });
}

@@ -63,3 +64,3 @@

node.status({ fill: "yellow", shape: "ring", text: "initialising" });
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
const options = Object.assign({}, node.connectionConfig.options);

@@ -69,21 +70,21 @@ this.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);

this.client.on('error', function (error, seq) {
console.log("Error: ", error);
node.status({ fill: "red", shape: "ring", text: "error" });
console.log('Error: ', error);
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.status({ fill: "red", shape: "dot", text: "queue full" });
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});

@@ -95,7 +96,7 @@

}
var origInputMsg = (sequence && sequence.tag) || {};
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
node.status({ fill: "red", shape: "ring", text: "error" });
nodeStatusError(err || sequence.error, origInputMsg, "error");
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');

@@ -105,18 +106,18 @@ return;

if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID");
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID');
return;
}
var cmdExpected = "0105";
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command !== cmdExpected) {
var ecd = "bad response";
if (sequence.response && sequence.response.command !== cmdExpected)
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== cmdExpected) {
let ecd = 'bad response';
if (sequence.response && sequence.response.command.commandCode !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;

@@ -132,4 +133,7 @@ }

origInputMsg.fins.request = {
address: sequence.request.address,
dataToBeWritten: sequence.request.dataToBeWritten,
command: sequence.request.command,
options: sequence.request.options,
srcAddress: sequence.request.srcAddress,
dstAddress: sequence.request.dstAddress,
count: sequence.request.count,
sid: sequence.request.sid,

@@ -143,6 +147,6 @@ };

node.status({ fill: "green", shape: "dot", text: "done" });
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
nodeStatusError(error, origInputMsg, 'error');

@@ -173,4 +177,4 @@ }

const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg);
if (!address || typeof address != "string") {
nodeStatusError(null, msg, "Source address is not valid");
if (!address || typeof address != 'string') {
nodeStatusError(null, msg, 'Source address is not valid');
return;

@@ -180,4 +184,4 @@ }

const address2 = RED.util.evaluateNodeProperty(node.address2, node.address2Type, node, msg);
if (!address2 || typeof address2 != "string") {
nodeStatusError(null, msg, "Destination address is not valid");
if (!address2 || typeof address2 != 'string') {
nodeStatusError(null, msg, 'Destination address is not valid');
return;

@@ -200,6 +204,6 @@ }

sid = node.client.transfer(address, address2, count, opts, msg);
if (sid > 0) node.status({ fill: "yellow", shape: "ring", text: "transfer" });
if (sid > 0) node.status({ fill: 'yellow', shape: 'ring', text: 'transfer' });
} catch (error) {
nodeStatusError(error, msg, "error");
nodeStatusError(error, msg, 'error');
const debugMsg = {

@@ -220,10 +224,10 @@ info: "transfer.js-->on 'input' - try this.client.transfer(address, address2, count, opts, msg)",

});
node.status({ fill: "green", shape: "ring", text: "ready" });
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
}
RED.nodes.registerType("FINS Transfer", omronTransfer);
RED.nodes.registerType('FINS Transfer', omronTransfer);
omronTransfer.prototype.close = function () {

@@ -230,0 +234,0 @@ if (this.client) {

@@ -27,14 +27,15 @@ /* eslint-disable no-inner-declarations */

module.exports = function (RED) {
const connection_pool = require("../connection_pool.js");
const connection_pool = require('../connection_pool.js');
function omronWrite(config) {
RED.nodes.createNode(this, config);
const node = this;
const cmdExpected = '0102';
node.name = config.name;
node.connection = config.connection;
node.address = config.address || "topic";
node.addressType = config.addressType || "msg";
node.data = config.data || "payload";
node.dataType = config.dataType || "msg";
node.msgProperty = config.msgProperty || "payload";
node.msgPropertyType = config.msgPropertyType || "str";
node.address = config.address || 'topic';
node.addressType = config.addressType || 'msg';
node.data = config.data || 'payload';
node.dataType = config.dataType || 'msg';
node.msgProperty = config.msgProperty || 'payload';
node.msgPropertyType = config.msgPropertyType || 'str';
node.connectionConfig = RED.nodes.getNode(node.connection);

@@ -51,3 +52,3 @@

}
node.status({ fill: "red", shape: "dot", text: statusText });
node.status({ fill: 'red', shape: 'dot', text: statusText });
}

@@ -61,3 +62,3 @@

node.status({ fill: "yellow", shape: "ring", text: "initialising" });
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
const options = Object.assign({}, node.connectionConfig.options);

@@ -67,21 +68,21 @@ this.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options);

this.client.on('error', function (error, seq) {
console.log("Error: ", error);
node.status({ fill: "red", shape: "ring", text: "error" });
console.log('Error: ', error);
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
});
this.client.on('full', function () {
node.status({ fill: "red", shape: "dot", text: "queue full" });
node.status({ fill: 'red', shape: 'dot', text: 'queue full' });
node.throttleUntil = Date.now() + 1000;
node.warn("Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.");
node.warn('Client buffer is saturated. Requests for the next 1000ms will be ignored. Consider reducing poll rate of operations to this connection.');
});
// eslint-disable-next-line no-unused-vars
this.client.on('open', function (remoteInfo) {
node.status({ fill: "green", shape: "dot", text: "connected" });
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
});
this.client.on('close', function () {
node.status({ fill: "red", shape: "dot", text: "not connected" });
node.status({ fill: 'red', shape: 'dot', text: 'not connected' });
});
// eslint-disable-next-line no-unused-vars
this.client.on('initialised', function (options) {
node.status({ fill: "yellow", shape: "dot", text: "initialised" });
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});

@@ -93,7 +94,7 @@

}
var origInputMsg = (sequence && sequence.tag) || {};
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
node.status({ fill: "red", shape: "ring", text: "error" });
nodeStatusError(err || sequence.error, origInputMsg, "error");
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');

@@ -103,18 +104,18 @@ return;

if (sequence.timeout) {
nodeStatusError("timeout", origInputMsg, "timeout");
nodeStatusError('timeout', origInputMsg, 'timeout');
return;
}
if (sequence.response && sequence.sid != sequence.response.sid) {
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID");
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, 'Incorrect SID');
return;
}
var cmdExpected = "0102";
if (!sequence || !sequence.response || sequence.response.endCode !== "0000" || sequence.response.command !== cmdExpected) {
var ecd = "bad response";
if (sequence.response && sequence.response.command !== cmdExpected)
if (!sequence || !sequence.response || sequence.response.endCode !== '0000' || sequence.response.command.commandCode !== cmdExpected) {
let ecd = 'bad response';
if (sequence.response && sequence.response.command.commandCode !== cmdExpected)
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`;
else if (sequence.response && sequence.response.endCodeDescription)
ecd = sequence.response.endCodeDescription;
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd);
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : '????'}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ''}`, origInputMsg, ecd);
return;

@@ -130,2 +131,4 @@ }

origInputMsg.fins.request = {
command: sequence.request.command,
options: sequence.request.options,
address: sequence.request.address,

@@ -141,6 +144,6 @@ dataToBeWritten: sequence.request.dataToBeWritten,

node.status({ fill: "green", shape: "dot", text: "done" });
node.status({ fill: 'green', shape: 'dot', text: 'done' });
node.send(origInputMsg);
} catch (error) {
nodeStatusError(error, origInputMsg, "error");
nodeStatusError(error, origInputMsg, 'error');

@@ -176,3 +179,3 @@ }

if (err) {
nodeStatusParameterError(err, msg, "data");
nodeStatusParameterError(err, msg, 'data');
return;//halt flow!

@@ -184,8 +187,8 @@ } else {

if (!address || typeof address != "string") {
nodeStatusError(null, msg, "address is not valid");
if (!address || typeof address != 'string') {
nodeStatusError(null, msg, 'address is not valid');
return;
}
if (data == null) {
nodeStatusError(null, msg, "data is not valid");
nodeStatusError(null, msg, 'data is not valid');
return;

@@ -199,6 +202,6 @@ }

sid = node.client.write(address, data, opts, msg);
if (sid > 0) node.status({ fill: "yellow", shape: "ring", text: "write" });
if (sid > 0) node.status({ fill: 'yellow', shape: 'ring', text: 'write' });
} catch (error) {
nodeStatusError(error, msg, "error");
nodeStatusError(error, msg, 'error');
const debugMsg = {

@@ -217,10 +220,10 @@ info: "write.js-->on 'input' - try this.client.write(address, data, finsReply)",

});
node.status({ fill: "green", shape: "ring", text: "ready" });
node.status({ fill: 'green', shape: 'ring', text: 'ready' });
} else {
node.status({ fill: "red", shape: "dot", text: "configuration not setup" });
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
}
}
RED.nodes.registerType("FINS Write", omronWrite);
RED.nodes.registerType('FINS Write', omronWrite);
omronWrite.prototype.close = function () {

@@ -227,0 +230,0 @@ if (this.client) {

{
"name": "node-red-contrib-omron-fins",
"version": "0.5.0-beta.0",
"version": "0.5.0-beta.1",
"author": {

@@ -28,3 +28,3 @@ "name": "Steve-Mcl",

"dependencies": {
"omron-fins": "0.5.0-beta.0"
"omron-fins": "0.5.0-beta.1"
},

@@ -31,0 +31,0 @@ "devDependencies": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc