node-red-contrib-omron-fins
Advanced tools
Comparing version 0.4.1 to 0.5.0-beta.0
@@ -25,9 +25,8 @@ /* | ||
var util = require("util"); | ||
var clients = {}; | ||
const clients = {}; | ||
function convertPayloadToDataArray(payload) { | ||
var array = []; | ||
var str = ''; | ||
let array = []; | ||
let str = ''; | ||
@@ -56,14 +55,14 @@ if (Array.isArray(payload)) { | ||
get: function (node, port, host, opts) { | ||
var fins = require('./omron-fins.js'); | ||
var id = "FinsClient:{host:'" + (host || "") + "', port:" + (port || "''") + ", MODE:" + opts.MODE + ", ICF:" + opts.ICF + ", DNA:" + opts.DNA + ", DA1:" + opts.DA1 + ", DA2:" + opts.DA2 + ", SNA:" + opts.SNA + ", SA1:" + opts.SA1 + ", SA2:" + opts.SA2 + "}"; | ||
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}'}`; | ||
if (!clients[id]) { | ||
clients[id] = function () { | ||
var options = opts || {}; | ||
var h = host || options.host; | ||
var p = port || options.port; | ||
const options = opts || {}; | ||
const h = host || options.host; | ||
const p = port || options.port; | ||
node.log(`[FINS] adding new connection to pool ~ ${id}`); | ||
var client = fins.FinsClient(parseInt(p), h, options); | ||
var connecting = false; | ||
let client = fins.FinsClient(parseInt(p), h, options); | ||
let connecting = false; | ||
@@ -73,23 +72,72 @@ options.autoConnect = options.autoConnect == undefined ? true : options.autoConnect; | ||
var obj = { | ||
const finsClientConnection = { | ||
_instances: 0, | ||
write: function (addr, data, callback, msg) { | ||
write: function (address, data, opts, tag) { | ||
if (!client.connected && options.preventAutoReconnect) { | ||
throw new Error("Not connected!") | ||
} | ||
var data = convertPayloadToDataArray(data); | ||
if (!Array.isArray(data)) { | ||
const _data = convertPayloadToDataArray(data); | ||
if (!Array.isArray(_data)) { | ||
throw new Error('data is not valid'); | ||
} | ||
var sid = client.write(addr, data, callback, msg); | ||
const sid = client.write(address, _data, opts, tag); | ||
return sid; | ||
}, | ||
read: function (addr, len, callback, msg) { | ||
read: function (address, len, opts, tag) { | ||
if (!client.connected && options.preventAutoReconnect) { | ||
throw new Error("Not connected!") | ||
} | ||
var sid = client.read(addr, parseInt(len), callback, msg); | ||
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 () { | ||
@@ -144,2 +192,3 @@ return (options.autoConnect == true); | ||
}); | ||
// eslint-disable-next-line no-unused-vars | ||
client.on('close', function (err) { | ||
@@ -153,9 +202,9 @@ node.log(`[FINS] connection closed ~ ${id}`); | ||
node.log(`[FINS] autoConnect call from error handler ~ ${id}`); | ||
obj.connect(); | ||
finsClientConnection.connect(); | ||
} | ||
}, 5000); //TODO: Parameterise | ||
}, 5000); //TODO: Parametrise | ||
} | ||
}); | ||
return obj | ||
return finsClientConnection | ||
}(); | ||
@@ -162,0 +211,0 @@ } |
@@ -89,2 +89,7 @@ /* | ||
this.options = {}; | ||
if(config.protocolType == "env") { | ||
this.options.protocol = resolveSetting(config.protocol, RED); | ||
} else { | ||
this.options.protocol = config.protocolType || "udp"; | ||
} | ||
this.options.MODE = config.MODE ? config.MODE : "CSCJ"; | ||
@@ -91,0 +96,0 @@ this.options.ICF = isInt(resolveSetting(config.ICF, RED), constants.DefaultFinsHeader.ICF); |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable no-inner-declarations */ | ||
/* | ||
@@ -26,7 +27,8 @@ MIT License | ||
module.exports = function (RED) { | ||
var connection_pool = require("../connection_pool.js"); | ||
const connection_pool = require("../connection_pool.js"); | ||
const dataParser = require("./_parser"); | ||
function omronRead(config) { | ||
RED.nodes.createNode(this, config); | ||
var node = this; | ||
const node = this; | ||
node.name = config.name; | ||
@@ -46,3 +48,3 @@ node.topic = config.topic; | ||
if (this.connectionConfig) { | ||
var options = Object.assign({}, node.connectionConfig.options); | ||
const options = Object.assign({}, node.connectionConfig.options); | ||
node.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options); | ||
@@ -53,19 +55,33 @@ node.status({ fill: "yellow", shape: "ring", text: "initialising" }); | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(error, (seq && seq.tag ? tag : seq) ); | ||
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 reads and writes 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."); | ||
node.status({ fill: "red", shape: "dot", text: "queue full" }); | ||
}); | ||
this.client.on('open', function (error) { | ||
// 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 (error) { | ||
this.client.on('close', function () { | ||
node.status({ fill: "red", shape: "dot", text: "not connected" }); | ||
}); | ||
this.client.on('initialised', function (error) { | ||
// 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 }); | ||
} | ||
const cmdExpected = "0101"; | ||
function finsReply(err, sequence) { | ||
@@ -78,15 +94,11 @@ if(!err && !sequence) { | ||
if (err || sequence.error) { | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(err || sequence.error, origInputMsg); | ||
nodeStatusError(err || sequence.error, origInputMsg, "error") | ||
return; | ||
} | ||
if (sequence.timeout) { | ||
node.status({ fill: "red", shape: "ring", text: "timeout" }); | ||
node.error("timeout", origInputMsg); | ||
nodeStatusError("timeout", origInputMsg, "timeout"); | ||
return; | ||
} | ||
var cmdExpected = "0101"; | ||
if (sequence.response && sequence.sid != sequence.response.sid) { | ||
node.status({ fill: "red", shape: "dot", text: "Incorrect SID" }); | ||
node.error(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg); | ||
nodeStatusError(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg, "Incorrect SID") | ||
return; | ||
@@ -97,43 +109,12 @@ } | ||
if (sequence.response && sequence.response.command !== cmdExpected) | ||
ecd = `Unexpected response. Expected command '${cmdExpected}' but received " ${sequence.response.command}`; | ||
ecd = `Unexpected response. Expected command '${cmdExpected}' but received '${sequence.response.command}'`; | ||
else if (sequence.response && sequence.response.endCodeDescription) | ||
ecd = sequence.response.endCodeDescription; | ||
node.status({ fill: "red", shape: "dot", text: ecd }); | ||
node.error(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg); | ||
nodeStatusError(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg, ecd); | ||
return; | ||
} | ||
var kvMaker = function (pkt) { | ||
let kvs = {}; | ||
if (pkt.response.values) { | ||
let iWD = 0; | ||
for (let x in pkt.response.values) { | ||
let item_addr = node.client.FinsAddressToString(pkt.request.address, iWD, 0); | ||
kvs[item_addr] = pkt.response.values[x]; | ||
iWD++; | ||
} | ||
} | ||
return kvs; | ||
}; | ||
var kvMakerBits = function (pkt, asBool) { | ||
let kvs = {}; | ||
if (pkt.response.values) { | ||
let iWD = 0; | ||
let iBit = 0; | ||
for (let x in pkt.response.values) { | ||
let item_addr = node.client.FinsAddressToString(pkt.request.address, iWD, iBit); | ||
kvs[item_addr] = asBool ? !!pkt.response.values[x] : pkt.response.values[x]; | ||
iBit++; | ||
if(pkt.request.address.Bit + iBit > 15) { | ||
iBit = -pkt.request.address.Bit; | ||
iWD++; | ||
} | ||
} | ||
} | ||
return kvs; | ||
}; | ||
//backwards compatibility, try to upgrade users current setting | ||
//the output type was originally a sub option 'list' | ||
var outputFormat = "buffer"; | ||
let outputFormat = "buffer"; | ||
const builtInReturnTypes = ['buffer', 'signed', 'unsigned', 'signedkv', 'unsignedkv']; | ||
@@ -148,3 +129,3 @@ if(node.outputFormatType == "list" && builtInReturnTypes.indexOf(node.outputFormat+'') >= 0) { | ||
var value; | ||
let value; | ||
switch (outputFormat) { | ||
@@ -167,7 +148,7 @@ case "signed": | ||
case "signedkv": | ||
value = kvMaker(sequence); | ||
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values); | ||
if(sequence.request.address.isBitAddress) { | ||
value = kvMakerBits(sequence, true); | ||
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, true); | ||
} else { | ||
value = kvMaker(sequence); | ||
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values); | ||
} | ||
@@ -177,6 +158,6 @@ break; | ||
if(sequence.request.address.isBitAddress) { | ||
value = kvMakerBits(sequence, false); | ||
value = dataParser.keyValueMakerBits(node.client.FinsAddressToString, sequence.request.address, sequence.response.values, false); | ||
} else { | ||
sequence.response.values = Uint16Array.from(sequence.response.values); | ||
value = kvMaker(sequence); | ||
value = dataParser.keyValueMaker(node.client.FinsAddressToString, sequence.request.address, sequence.response.values); | ||
} | ||
@@ -210,4 +191,3 @@ break; | ||
} catch (error) { | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(error, origInputMsg); | ||
nodeStatusError(error, origInputMsg, "error"); | ||
} | ||
@@ -235,17 +215,8 @@ } | ||
/* **************** Node status **************** */ | ||
var nodeStatusError = function (err, msg, statusText) { | ||
if (err) { | ||
node.error(err, msg); | ||
} else { | ||
node.error(statusText, msg); | ||
} | ||
node.status({ fill: "red", shape: "dot", text: statusText }); | ||
}; | ||
/* **************** Get address Parameter **************** */ | ||
var address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg); | ||
const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg); | ||
/* **************** Get count Parameter **************** */ | ||
var count = RED.util.evaluateNodeProperty(node.count, node.countType, node, msg); | ||
let count = RED.util.evaluateNodeProperty(node.count, node.countType, node, msg); | ||
@@ -257,3 +228,3 @@ if (!address || typeof address != "string") { | ||
count = parseInt(count); | ||
if (Number.isNaN(count)) { | ||
if (Number.isNaN(count) || count <= 0) { | ||
nodeStatusError(null, msg, "count is not valid"); | ||
@@ -263,4 +234,7 @@ return; | ||
const opts = msg.finsOptions || {}; | ||
let sid; | ||
try { | ||
let sid = this.client.read(address, parseInt(count), finsReply, msg); | ||
opts.callback = finsReply; | ||
sid = node.client.read(address, count, opts, msg); | ||
if (sid > 0) { | ||
@@ -272,9 +246,11 @@ node.status({ fill: "yellow", shape: "ring", text: "reading" }); | ||
nodeStatusError(error, msg, "error"); | ||
let dbgmsg = { | ||
const debugMsg = { | ||
info: "read.js-->on 'input'", | ||
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`, | ||
sid: sid, | ||
address: address, | ||
size: count, | ||
count: count, | ||
opts: opts, | ||
}; | ||
console.debug(dbgmsg); | ||
node.debug(debugMsg); | ||
return; | ||
@@ -281,0 +257,0 @@ } |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable no-inner-declarations */ | ||
/* | ||
@@ -26,188 +27,195 @@ MIT License | ||
module.exports = function (RED) { | ||
var connection_pool = require("../connection_pool.js"); | ||
function omronWrite(config) { | ||
RED.nodes.createNode(this, config); | ||
var node = this; | ||
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.connectionConfig = RED.nodes.getNode(node.connection); | ||
if (this.connectionConfig) { | ||
const connection_pool = require("../connection_pool.js"); | ||
function omronWrite(config) { | ||
RED.nodes.createNode(this, config); | ||
const node = this; | ||
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.connectionConfig = RED.nodes.getNode(node.connection); | ||
node.status({ fill: "yellow", shape: "ring", text: "initialising" }); | ||
var options = Object.assign({}, node.connectionConfig.options); | ||
this.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options); | ||
/* **************** Node status **************** */ | ||
function nodeStatusError(err, msg, statusText) { | ||
if (err) { | ||
console.error(err); | ||
node.error(err, msg); | ||
} else { | ||
console.error(statusText); | ||
node.error(statusText, msg); | ||
} | ||
node.status({ fill: "red", shape: "dot", text: statusText }); | ||
} | ||
this.client.on('error', function (error) { | ||
console.log("Error: ", error); | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(error, (seq && seq.tag ? 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 reads and writes to this connection."); | ||
}); | ||
this.client.on('open', function (error) { | ||
node.status({ fill: "green", shape: "dot", text: "connected" }); | ||
}); | ||
this.client.on('close', function (error) { | ||
node.status({ fill: "red", shape: "dot", text: "not connected" }); | ||
}); | ||
this.client.on('initialised', function (error) { | ||
node.status({ fill: "yellow", shape: "dot", text: "initialised" }); | ||
}); | ||
function finsReply(err, sequence) { | ||
if(!err && !sequence) { | ||
return; | ||
function nodeStatusParameterError(err, msg, propName) { | ||
nodeStatusError(err, msg, "Unable to evaluate property '" + propName + "' value"); | ||
} | ||
var origInputMsg = (sequence && sequence.tag) || {}; | ||
try { | ||
if (err || sequence.error) { | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(err || sequence.error, origInputMsg); | ||
return; | ||
} | ||
if (sequence.timeout) { | ||
node.status({ fill: "red", shape: "ring", text: "timeout" }); | ||
node.error("timeout", origInputMsg); | ||
return; | ||
} | ||
if (sequence.response && sequence.sid != sequence.response.sid) { | ||
node.status({ fill: "red", shape: "dot", text: "Incorrect SID" }); | ||
node.error(`SID does not match! My SID: ${sequence.sid}, reply SID:${sequence.response.sid}`, origInputMsg); | ||
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) | ||
ecd = `Unexpected response. Expected command '${cmdExpected}' but received " ${sequence.response.command}`; | ||
else if (sequence.response && sequence.response.endCodeDescription) | ||
ecd = sequence.response.endCodeDescription; | ||
node.status({ fill: "red", shape: "dot", text: ecd }); | ||
node.error(`Response is NG! endCode: ${sequence.response ? sequence.response.endCode : "????"}, endCodeDescription:${sequence.response ? sequence.response.endCodeDescription : ""}`, origInputMsg); | ||
return; | ||
} | ||
//set the output property | ||
RED.util.setObjectProperty(origInputMsg, node.msgProperty, sequence.sid || 0, true); | ||
if (this.connectionConfig) { | ||
//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, | ||
dataToBeWritten: sequence.request.dataToBeWritten, | ||
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: "yellow", shape: "ring", text: "initialising" }); | ||
const options = Object.assign({}, node.connectionConfig.options); | ||
this.client = connection_pool.get(this, this.connectionConfig.port, this.connectionConfig.host, options); | ||
node.status({ fill: "green", shape: "dot", text: "done" }); | ||
node.send(origInputMsg); | ||
} catch (error) { | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
node.error(error, origInputMsg); | ||
} | ||
} | ||
this.client.on('error', function (error, seq) { | ||
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.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" }); | ||
}); | ||
this.on('close', function (done) { | ||
if (done) done(); | ||
}); | ||
function finsReply(err, sequence) { | ||
if (!err && !sequence) { | ||
return; | ||
} | ||
var origInputMsg = (sequence && sequence.tag) || {}; | ||
try { | ||
if (err || sequence.error) { | ||
node.status({ fill: "red", shape: "ring", text: "error" }); | ||
nodeStatusError(err || sequence.error, origInputMsg, "error"); | ||
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 | ||
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"); | ||
if (msg.disconnect === true || msg.topic === 'disconnect') { | ||
node.client.closeConnection(); | ||
return; | ||
} else if (msg.connect === true || msg.topic === 'connect') { | ||
node.client.connect(); | ||
return; | ||
} | ||
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) | ||
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; | ||
} | ||
/* **************** Node status **************** */ | ||
var nodeStatusError = function (err, msg, statusText) { | ||
if (err) { | ||
console.error(err); | ||
node.error(err, msg); | ||
} else { | ||
console.error(statusText); | ||
node.error(statusText, msg); | ||
} | ||
node.status({ fill: "red", shape: "dot", text: statusText }); | ||
}; | ||
var nodeStatusParameterError = function (err, msg, propName) { | ||
nodeStatusError(err, msg, "Unable to evaluate property '" + propName + "' value"); | ||
}; | ||
//set the output property | ||
RED.util.setObjectProperty(origInputMsg, node.msgProperty, sequence.sid || 0, true); | ||
/* **************** Get address Parameter **************** */ | ||
var address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg); | ||
//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, | ||
dataToBeWritten: sequence.request.dataToBeWritten, | ||
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; | ||
/* **************** Get data Parameter **************** */ | ||
var data; | ||
RED.util.evaluateNodeProperty(node.data, node.dataType, node, msg, function (err, value) { | ||
if (err) { | ||
nodeStatusParameterError(err, msg, "data"); | ||
return;//halt flow! | ||
} else { | ||
data = value; | ||
} | ||
}); | ||
node.status({ fill: "green", shape: "dot", text: "done" }); | ||
node.send(origInputMsg); | ||
} catch (error) { | ||
nodeStatusError(error, origInputMsg, "error"); | ||
if (!address || typeof address != "string") { | ||
nodeStatusError(null, msg, "address is not valid"); | ||
return; | ||
} | ||
if (data == null) { | ||
nodeStatusError(null, msg, "data is not valid"); | ||
return; | ||
} | ||
} | ||
} | ||
try { | ||
var sid = this.client.write(address, data, finsReply, msg); | ||
if (sid > 0) node.status({ fill: "yellow", shape: "ring", text: "write" }); | ||
} catch (error) { | ||
this.on('close', function (done) { | ||
if (done) done(); | ||
}); | ||
nodeStatusError(error, msg, "error"); | ||
var dbgmsg = { | ||
info: "write.js-->on 'input' - try this.client.write(address, data, finsReply)", | ||
connection: `host: ${node.connectionConfig.host}, port: ${node.connectionConfig.port}`, | ||
address: address, | ||
data: data, | ||
error: error | ||
}; | ||
console.debug(dbgmsg); | ||
return; | ||
} | ||
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 | ||
}); | ||
node.status({ fill: "green", shape: "ring", text: "ready" }); | ||
if (msg.disconnect === true || msg.topic === 'disconnect') { | ||
node.client.closeConnection(); | ||
return; | ||
} else if (msg.connect === true || msg.topic === 'connect') { | ||
node.client.connect(); | ||
return; | ||
} | ||
} else { | ||
node.status({ fill: "red", shape: "dot", text: "configuration not setup" }); | ||
} | ||
/* **************** Get address Parameter **************** */ | ||
const address = RED.util.evaluateNodeProperty(node.address, node.addressType, node, msg); | ||
} | ||
RED.nodes.registerType("FINS Write", omronWrite); | ||
omronWrite.prototype.close = function () { | ||
if (this.client) { | ||
this.client.disconnect(); | ||
/* **************** Get data Parameter **************** */ | ||
let data; | ||
RED.util.evaluateNodeProperty(node.data, node.dataType, node, msg, function (err, value) { | ||
if (err) { | ||
nodeStatusParameterError(err, msg, "data"); | ||
return;//halt flow! | ||
} else { | ||
data = value; | ||
} | ||
}); | ||
if (!address || typeof address != "string") { | ||
nodeStatusError(null, msg, "address is not valid"); | ||
return; | ||
} | ||
if (data == null) { | ||
nodeStatusError(null, msg, "data is not valid"); | ||
return; | ||
} | ||
const opts = msg.finsOptions || {}; | ||
let sid; | ||
try { | ||
opts.callback = finsReply; | ||
sid = node.client.write(address, data, opts, msg); | ||
if (sid > 0) node.status({ fill: "yellow", shape: "ring", text: "write" }); | ||
} 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); | ||
return; | ||
} | ||
}); | ||
node.status({ fill: "green", shape: "ring", text: "ready" }); | ||
} else { | ||
node.status({ fill: "red", shape: "dot", text: "configuration not setup" }); | ||
} | ||
} | ||
}; | ||
RED.nodes.registerType("FINS Write", omronWrite); | ||
omronWrite.prototype.close = function () { | ||
if (this.client) { | ||
this.client.disconnect(); | ||
} | ||
}; | ||
}; | ||
{ | ||
"name": "node-red-contrib-omron-fins", | ||
"version": "0.4.1", | ||
"version": "0.5.0-beta.0", | ||
"author": { | ||
@@ -18,4 +18,8 @@ "name": "Steve-Mcl", | ||
"omronRead": "nodes/read.js", | ||
"omronReadMultiple": "nodes/readMultiple.js", | ||
"omronWrite": "nodes/write.js", | ||
"omronConnection": "nodes/connection.js" | ||
"omronFile": "nodes/fill.js", | ||
"omronTransfer": "nodes/transfer.js", | ||
"omronConnection": "nodes/connection.js", | ||
"omronControl": "nodes/control.js" | ||
} | ||
@@ -25,4 +29,7 @@ }, | ||
"dependencies": { | ||
"omron-fins": "0.4.0-beta.1" | ||
"omron-fins": "0.5.0-beta.0" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^7.29.0" | ||
} | ||
} |
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
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
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
282200
31
1548
1
1
+ Addedomron-fins@0.5.0-beta.0(transitive)
- Removedomron-fins@0.4.0-beta.1(transitive)
Updatedomron-fins@0.5.0-beta.0