node-red-contrib-omron-fins
Advanced tools
Comparing version 0.5.0-beta.0 to 0.5.0-beta.1
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": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
286821
1558
0
+ Addedomron-fins@0.5.0-beta.1(transitive)
- Removedomron-fins@0.5.0-beta.0(transitive)
Updatedomron-fins@0.5.0-beta.1