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.3 to 0.5.0-beta.4

examples/control node demo.json

262

connection_pool.js

@@ -60,23 +60,19 @@ /*

const id = connectionConfig.id;
let options = connectionConfig.options || {};
let port = parseInt(connectionConfig.port || options.port);
let host = connectionConfig.host || options.host;
let connect = connectionConfig.autoConnect == null ? true : connectionConfig.autoConnect;
let _options = { ...(connectionConfig.options || {}) };
let _port = parseInt(connectionConfig.port || _options.port);
let _host = connectionConfig.host || _options.host;
let _connect = connectionConfig.autoConnect == null ? true : connectionConfig.autoConnect;
if (!clients[id]) {
clients[id] = (function () {
clients[id] = (function (port, host, options, connect) {
node.log(`Create new FinsClient. id:${id}, config: ${describe(host, port, options)}`);
let fins_client = fins.FinsClient(port, host, options, false);
options.autoConnect = options.autoConnect == null ? true : options.autoConnect;
let connecting = false;
let client = fins.FinsClient(port, host, options, connect);
let preventAutoReconnect = true;
options.autoConnect = options.autoConnect == null ? true : options.autoConnect;
options.preventAutoReconnect = false;
const finsClientConnection = {
const finsClientWrapper = {
write(address, data, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
checkConnection();
const _data = convertPayloadToDataArray(data);

@@ -86,98 +82,81 @@ if (!Array.isArray(_data)) {

}
const sid = client.write(address, _data, opts, tag);
return sid;
return fins_client.write(address, _data, opts, tag);
},
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;
checkConnection();
return fins_client.read(address, parseInt(len), opts, tag);
},
readMultiple(addresses, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.readMultiple(addresses, opts, tag);
return sid;
checkConnection();
return fins_client.readMultiple(addresses, opts, tag);
},
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;
checkConnection();
return fins_client.fill(address, value, parseInt(count), opts, tag);
},
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;
checkConnection();
return fins_client.transfer(srcAddress, dstAddress, parseInt(count), opts, tag);
},
status(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.status(opts, tag);
return sid;
checkConnection();
return fins_client.status(opts, tag);
},
run(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.run(opts, tag);
return sid;
checkConnection();
return fins_client.run(opts, tag);
},
stop(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.stop(opts, tag);
return sid;
checkConnection();
return fins_client.stop(opts, tag);
},
cpuUnitDataRead(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.cpuUnitDataRead(opts, tag);
return sid;
checkConnection();
return fins_client.cpuUnitDataRead(opts, tag);
},
clockRead(opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.clockRead(opts, tag);
return sid;
checkConnection();
return fins_client.clockRead(opts, tag);
},
clockWrite(clock, opts, tag) {
if (!client.connected && options.preventAutoReconnect) {
throw new Error('Not connected!');
}
const sid = client.clockWrite(clock, opts, tag);
return sid;
checkConnection();
return fins_client.clockWrite(clock, opts, tag);
},
getAutoConnect() {
return (options.autoConnect == true);
on(a, b) {
try {
fins_client.on(a, b);
// eslint-disable-next-line no-empty
} catch (error) { }
},
setAutoConnect(b) {
options.autoConnect = (b == true);
off(a, b) {
try {
fins_client.off(a, b);
// eslint-disable-next-line no-empty
} catch (error) { }
},
on(a, b) {
client.on(a, b);
removeAllListeners() {
try {
fins_client.removeAllListeners();
// eslint-disable-next-line no-empty
} catch (error) { }
},
connect(host, port, opts) {
options.preventAutoReconnect = false;
if (client && !client.connected && !connecting) {
preventAutoReconnect = false;
finsClientWrapper.reconnect(host, port, opts);
},
reconnect(host, port, opts) {
if (!fins_client.connected && !connecting) {
try {
node.log(`Connecting id:${id}, config: ${describe(this.connectionInfo.host, this.connectionInfo.port, this.connectionInfo.options)}`);
node.log(`Connecting id:${id}, config: ${describe(finsClientWrapper.connectionInfo.host, finsClientWrapper.connectionInfo.port, finsClientWrapper.connectionInfo.options)}`);
// eslint-disable-next-line no-empty
} catch (error) { }
connecting = true;
try {
if(arguments.length == 0) {
client.reconnect();
} else {
client.connect(host, port, opts);
}
fins_client.connect(host, port, opts);
connecting = true;
finsClientWrapper.reconnectTimeOver = setTimeout(() => {
connecting = false;
finsClientWrapper.reconnectTimeOver = null;
}, 8000);
// eslint-disable-next-line no-empty

@@ -190,5 +169,5 @@ } catch (error) {

disconnect() {
options.preventAutoReconnect = true;
if (client) {
client.disconnect();
preventAutoReconnect = true;
if (fins_client) {
fins_client.disconnect();
}

@@ -198,31 +177,31 @@ connecting = false;

stringToFinsAddress(addressString) {
return client.stringToFinsAddress(addressString);
return fins_client.stringToFinsAddress(addressString);
},
FinsAddressToString(decodedAddress, offsetWD, offsetBit) {
return client.FinsAddressToString(decodedAddress, offsetWD, offsetBit);
return fins_client.FinsAddressToString(decodedAddress, offsetWD, offsetBit);
},
close() {
if (client && client.connected) {
connecting = false;
if (fins_client && fins_client.connected) {
node.log(`closing connection ~ ${id}`);
client.disconnect();
fins_client.disconnect();
}
connecting = false;
},
get connected() {
return client && client.connected;
return fins_client && fins_client.connected;
},
get connectionInfo() {
if(client) {
if(fins_client) {
const info = {
port: client.port,
host: client.host,
options: {...client.options},
port: fins_client.port,
host: fins_client.host,
options: {...fins_client.options},
}
delete info.options.preventAutoReconnect;//not of interest
if(client.protocol == "tcp") {
info.options.tcp_server_node_no = client.server_node_no;//DA1
info.options.tcp_client_node_no = client.client_node_no;//SA1
if(fins_client.protocol == "tcp") {
info.options.tcp_server_node_no = fins_client.server_node_no;//DA1
info.options.tcp_client_node_no = fins_client.client_node_no;//SA1
}

@@ -235,44 +214,71 @@ return info;

client.on('open', () => {
if (client) {
fins_client.on('open', () => {
try {
connecting = false;
if (finsClientWrapper.reconnectTimer) {
clearTimeout(finsClientWrapper.reconnectTimer);
finsClientWrapper.reconnectTimer = null;
}
node.log(`connected ~ ${id}`);
// eslint-disable-next-line no-empty
} catch (error) { }
});
// eslint-disable-next-line no-unused-vars
fins_client.on('close', (err) => {
try {
connecting = false;
}
node.log(`connection closed ~ ${id}`);
scheduleReconnect();
// eslint-disable-next-line no-empty
} catch (error) { }
});
// eslint-disable-next-line no-unused-vars
client.on('close', (err) => {
node.log(`connection closed ~ ${id}`);
connecting = false;
if (options.autoConnect && !options.preventAutoReconnect) {
finsClientConnection.reconnectTimer = setTimeout(() => {
if (finsClientConnection.reconnectTimer && options.autoConnect && !options.preventAutoReconnect) {
node.log(`autoConnect call from close handler ~ ${id}`);
finsClientConnection.connect();
}
}, 5000); // TODO: Parametrise
function checkConnection() {
if (!finsClientWrapper.connected) {
if (!preventAutoReconnect && !finsClientWrapper.reconnectTimer) {
scheduleReconnect();
}
throw new Error('not connected');
}
});
}
return finsClientConnection;
}());
function scheduleReconnect() {
if(!connecting) {
if (!finsClientWrapper.reconnectTimer && options.autoConnect && !preventAutoReconnect) {
finsClientWrapper.reconnectTimer = setTimeout(() => {
if (finsClientWrapper.reconnectTimer && options.autoConnect && !preventAutoReconnect) {
finsClientWrapper.reconnectTimer = null;
node.log(`Scheduled reconnect ~ ${id}`);
finsClientWrapper.reconnect();
}
}, 2000); // TODO: Parametrise
}
}
}
if(connect) {
finsClientWrapper.connect();
}
return finsClientWrapper;
}(_port, _host, _options, _connect));
}
return clients[id];
},
close(connectionConfig) {
const c = this.get(null, connectionConfig);
if(c && c.connected) {
c.close();
const cli = this.get(null, connectionConfig);
if(cli) {
if(cli.reconnectTimer) {
clearTimeout(cli.reconnectTimer);
cli.reconnectTimer = null;
}
cli.removeAllListeners();
if(cli.connected) {
cli.close();
}
}
c.close();
if(c && c.reconnectTimer) {
clearTimeout(c.reconnectTimer);
c.reconnectTimer = null;
}
if(c) {
const id = connectionConfig.id;
delete clients[id];
}
const id = connectionConfig.id;
delete clients[id];
}
};

@@ -45,37 +45,56 @@ /* eslint-disable no-inner-declarations */

if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
node.client = connection_pool.get(this, node.connectionConfig);
/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', 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' });
});
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** 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 });
}
if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
if(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);
function finsReply(err, sequence) {

@@ -85,16 +104,18 @@ if (!err && !sequence) {

}
var origInputMsg = (sequence && sequence.tag) || {};
const origInputMsg = (sequence && sequence.tag) || {};
try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -150,2 +171,3 @@ var ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -205,9 +227,13 @@ });

case 'clock-write':
clockWriteData = RED.util.evaluateNodeProperty(node.clock, node.clockType, node, msg);
if(!clockWriteData || typeof clockWriteData != "object") {
nodeStatusError("Cannot set clock. msg.clock is missing or invalid.", msg, "error");
try {
clockWriteData = RED.util.evaluateNodeProperty(node.clock, node.clockType, node, msg);
if(!clockWriteData || typeof clockWriteData != "object") {
throw new Error();
}
clientFn = node.client.clockWrite;
params.push(clockWriteData);
} catch (error) {
nodeStatusError("Cannot set clock. Clock Value is missing or invalid.", msg, "Clock Value is missing or invalid");
return;
}
clientFn = node.client.clockWrite;
params.push(clockWriteData);
break;

@@ -230,10 +256,14 @@ }

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);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
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;

@@ -250,3 +280,3 @@ }

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -253,0 +283,0 @@ }

@@ -0,1 +1,2 @@

/* eslint-disable no-inner-declarations */
/*

@@ -43,2 +44,34 @@ MIT License

/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', shape: 'dot', text: 'initialised' });
}
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** Node status **************** */

@@ -54,29 +87,14 @@ function nodeStatusError(err, msg, statusText) {

if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
node.client = connection_pool.get(this, node.connectionConfig);
if(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);
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.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.');
});
// 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' });
});
this.client.on('initialised', function () {
node.status({ fill: 'yellow', shape: 'dot', text: 'initialised' });
});
// eslint-disable-next-line no-inner-declarations
function finsReply(err, sequence) {

@@ -88,18 +106,16 @@ if (!err && !sequence) {

try {
if (err || sequence.error) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -143,2 +159,3 @@ let ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -193,15 +210,18 @@ });

} catch (error) {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "fill.js-->on 'input' - try this.client.fill(address, fillValue, fillCount, opts, msg)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
fillValue: fillValue,
fillCount: fillCount,
opts: opts,
error: error
};
node.debug(debugMsg);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "fill.js-->on 'input' - try this.client.fill(address, fillValue, fillCount, opts, msg)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
fillValue: fillValue,
fillCount: fillCount,
opts: opts,
error: error
};
node.debug(debugMsg);
}
return;

@@ -218,3 +238,3 @@ }

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -221,0 +241,0 @@

@@ -47,37 +47,56 @@ /* eslint-disable no-inner-declarations */

if (this.connectionConfig) {
node.client = connection_pool.get(this, node.connectionConfig);
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', 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' });
});
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** 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 });
}
if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
if(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);
function finsReply(err, sequence) {

@@ -89,14 +108,16 @@ if (!err && !sequence) {

try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -190,2 +211,3 @@ let ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -235,13 +257,16 @@ });

} 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);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
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;

@@ -258,3 +283,3 @@ }

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -261,0 +286,0 @@ }

@@ -45,35 +45,55 @@ /* eslint-disable no-inner-declarations */

/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', shape: 'dot', text: 'initialised' });
}
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** 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 (this.connectionConfig) {
node.client = connection_pool.get(this, node.connectionConfig);
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(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);

@@ -86,14 +106,16 @@ function finsReply(err, sequence) {

try {
if (err || sequence.error) {
nodeStatusError(err || sequence.error, origInputMsg, 'error')
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -188,2 +210,3 @@ let ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -224,12 +247,15 @@ });

} catch (error) {
node.sid = null;
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "readMultiple.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
addresses: address,
opts: opts,
};
node.debug(debugMsg);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "readMultiple.js-->on 'input'",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
addresses: address,
opts: opts,
};
node.debug(debugMsg);
}
return;

@@ -246,3 +272,3 @@ }

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -249,0 +275,0 @@ }

@@ -44,2 +44,34 @@ /* eslint-disable no-inner-declarations */

/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', shape: 'dot', text: 'initialised' });
}
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** Node status **************** */

@@ -56,27 +88,13 @@ function nodeStatusError(err, msg, statusText) {

if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
node.client = connection_pool.get(this, node.connectionConfig);
if(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);
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.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.');
});
// 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' });
});
function finsReply(err, sequence) {

@@ -88,18 +106,16 @@ if (!err && !sequence) {

try {
if (err || sequence.error) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -144,2 +160,3 @@ let ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -192,18 +209,20 @@ });

} catch (error) {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "transfer.js-->on 'input' - try this.client.transfer(address, address2, count, opts, msg)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
address2: address2,
count: count,
opts: opts,
error: error
};
node.debug(debugMsg);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "transfer.js-->on 'input' - try this.client.transfer(address, address2, count, opts, msg)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
address2: address2,
count: count,
opts: opts,
error: error
};
node.debug(debugMsg);
}
return;
}
});

@@ -217,3 +236,3 @@ if(node.client && node.client.connected) {

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -220,0 +239,0 @@

@@ -42,2 +42,34 @@ /* eslint-disable no-inner-declarations */

/* **************** Listeners **************** */
function onClientError(error, seq) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
node.error(error, (seq && seq.tag ? seq.tag : seq));
}
function onClientFull() {
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
function onClientOpen(remoteInfo) {
node.status({ fill: 'green', shape: 'dot', text: 'connected' });
}
function onClientClose() {
node.status({ fill: 'yellow', shape: 'dot', text: 'not connected' });
}
// eslint-disable-next-line no-unused-vars
function onClientInit(options) {
node.status({ fill: 'grey', shape: 'dot', text: 'initialised' });
}
function removeAllListeners() {
if(node.client) {
node.client.off('error', onClientError);
node.client.off('full', onClientFull);
node.client.off('open', onClientOpen);
node.client.off('close', onClientClose);
node.client.off('initialised', onClientInit);
}
}
/* **************** Node status **************** */

@@ -53,32 +85,14 @@ function nodeStatusError(err, msg, statusText) {

function nodeStatusParameterError(err, msg, propName) {
nodeStatusError(err, msg, "Unable to evaluate property '" + propName + "' value");
}
if (this.connectionConfig) {
node.status({ fill: 'yellow', shape: 'ring', text: 'initialising' });
node.client = connection_pool.get(this, node.connectionConfig);
if(node.client) {
node.client.removeAllListeners();
}
node.client = connection_pool.get(node, node.connectionConfig);
this.client.on('error', onClientError);
this.client.on('full', onClientFull);
this.client.on('open', onClientOpen);
this.client.on('close', onClientClose);
this.client.on('initialised', onClientInit);
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.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.');
});
// 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' });
});
function finsReply(err, sequence) {

@@ -90,18 +104,16 @@ if (!err && !sequence) {

try {
if (err || sequence.error) {
node.status({ fill: 'red', shape: 'ring', text: 'error' });
nodeStatusError(err || sequence.error, origInputMsg, 'error');
return;
if(sequence) {
if (err || sequence.error) {
nodeStatusError(((err && err.message) || "error"), origInputMsg, ((err && err.message) || "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.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) {

@@ -145,2 +157,3 @@ let ecd = 'bad response';

this.on('close', function (done) {
removeAllListeners();
if (done) done();

@@ -171,3 +184,3 @@ });

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

@@ -195,16 +208,18 @@ } else {

} catch (error) {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "write.js-->on 'input' - try this.client.write(address, data, finsReply)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
data: data,
error: error
};
node.debug(debugMsg);
if(error.message == "not connected") {
node.status({ fill: 'yellow', shape: 'dot', text: error.message });
} else {
nodeStatusError(error, msg, 'error');
const debugMsg = {
info: "write.js-->on 'input' - try this.client.write(address, data, finsReply)",
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`,
sid: sid,
address: address,
data: data,
error: error
};
node.debug(debugMsg);
}
return;
}
});

@@ -218,3 +233,3 @@ if(node.client && node.client.connected) {

} else {
node.status({ fill: 'red', shape: 'dot', text: 'configuration not setup' });
node.status({ fill: 'red', shape: 'dot', text: 'Connection config missing' });
}

@@ -221,0 +236,0 @@

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

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

"dependencies": {
"omron-fins": "0.5.0-beta.3"
"omron-fins": "0.5.0-beta.4"
},

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

@@ -6,5 +6,7 @@ node-red-contrib-omron-fins

This is a Node-RED node module to directly interface with OMRON PLCs over FINS Ethernet protocol.
For now it only supports READ and WRITE of WORD or BIT addresses over FINS UDP.
Tested on CV, CP, CS, CJ, NJ and NX PLCs (the ones with FINS support)
Example flows have been included to help you get started.
In the node-red editor, click the hamburger menu, select <b>import</b> then <b>examples</b> (or press <kbd>ctrl+i</kbd>)
### NODES

@@ -14,5 +16,7 @@ * read - read 1 or more WORDs or bits

* fill - fill 1 or more consecutive addresses with a value
* read-multiple - read several disparate address values
* read-multiple - read several disparate WORD or BIT address values
* transfer - copy 1 or more data values from one memory area to another
* control - this has the following functions...
* Connect PLC
* Disconnect PLC
* Get PLC Status

@@ -55,3 +59,3 @@ * Get PLC Unit Data

npm node-red-contrib-omron-fins
npm install node-red-contrib-omron-fins

@@ -58,0 +62,0 @@ Or, install direct from github

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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