Multiple injections at the same time?

Hello,

My idea is to develope a datalogger in node-red. If I have use a injection node (1 minute of interval) to write to a database diferent tags (values, some kind of identification, ...) from diferent sources (variables collect form several plcs). With one plc the app works fine, but if I need to datalogger several plcs then the system loss its consistency!
Can someone explain that?

Hi @agmacedo, welcome to the forum.

not really.

You havent stated what PLCs or what protocols, whether you are gathering data in arrays or single items.

you havent said what database you are using

You also haven't showed us your flow.

TBH, with sooo little information, all i can offer is general advice.

  • read as many contiguous values in as few reads as possible
  • group related data in the PLC so they are read out in the same request (ensures consistency)
  • avoid flow / global context unless you understand the order of events of your flow (remember things are asynchronous) - instead, get your values, convert or coerce then write to database all in one serial operation.

Hello again and thanks for answer.

TCP/IP Modbus protocol and 8 PLCs (Modicon).
The data are colected in single items. It is possible but I want to avoid changing the PLCs programs.
The database is MS SQl Server (express edition).
In the past I implemented this type of datalloger with Winform (C# using async/await). But here I think it is not possible to use class and objects, wich is a several limitation.
The tags are all in the database so it's easy to collect and put all together in the same array. The problem is that the modbus flex getter need to specefy the ip adress for each PLC. I use the same injection node (1 minute interval) but just read all the tags for one PLC and somitime read the others with no noticeable pattern. It is really strange !
I use two flows variables for each PLC (8 in total).
Using the debugs nodes I think the problem is just after the modbus flex getter.

Regards

It is possible to group together all the tags in a single array, I still have to use diferent change the ip adress of the PLC everytime I change the PLC. So I have to use a different flow for each PLC and use different r modbus flex gettebecause the ip adress.


P

If you are willing to share your flow I will import it and take a look for any obvious issues.

To export your flow, select the items to export, press ctrl+e, copy to clipboard, paste into a reply between backticks
```
like this
```

Ok,
I send a txt file. The system reply doesn´t allow so many chars.

Flow1.txt (33.7 KB)

[{"id":"f5c32c9b.8a69f","type":"tab","label":"Trending_copy","disabled":true,"info":""},{"id":"403c887a.8cc7a8","type":"inject","z":"f5c32c9b.8a69f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":160,"wires":[["8a677f52.3039a","cdee1f90.ae9ae"]]},{"id":"8a677f52.3039a","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_TagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT [id] as idTag\r\n      ,[nome]\r\n      ,[ip]\r\n      ,[adress]\r\n      ,[dtype]\r\n      ,[hist]\r\n  FROM [hmiFscam].[dbo].[tagsTrend]\r\n  WHERE [ip] = '192.168.1.42'\r\n  order by ip, id","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":370,"y":160,"wires":[["8fb7268c.49b228"]]},{"id":"8fb7268c.49b228","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"tagsTrendForno_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":160,"wires":[[]]},{"id":"cdee1f90.ae9ae","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_nRegsTagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT COUNT(id) AS nReg\r\nFROM dbo.tagsTrend\r\nwhere [ip] = '192.168.1.42'","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":390,"y":100,"wires":[["25abead0.c039a6"]]},{"id":"25abead0.c039a6","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"nRegsTrendForno_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":100,"wires":[["5df3976c.0e3898"]]},{"id":"5df3976c.0e3898","type":"debug","z":"f5c32c9b.8a69f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":790,"y":100,"wires":[]},{"id":"51cc7053.d6972","type":"modbus-flex-getter","z":"f5c32c9b.8a69f","name":"Forno","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"server":"57332e15.d4ae5","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"x":510,"y":900,"wires":[["ba3cff0.dc59a"],[]]},{"id":"1c6841c.f103cbe","type":"inject","z":"f5c32c9b.8a69f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"15","crontab":"","once":false,"onceDelay":0.1,"topic":"leitOK","payload":"","payloadType":"date","x":150,"y":1120,"wires":[["f777fb3e.6ea2d8","fd96cb5b.3a9758","433a3c6a.39db54","57551078.7ed3b"]]},{"id":"fd96cb5b.3a9758","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrendForno_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {\n    var j=1;\n    id = flow.get(\"tagsTrendForno_fVal\")[i].idTag;\n    nome = flow.get(\"tagsTrendForno_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrendForno_fVal\")[i].adress;\n    dtype = flow.get(\"tagsTrendForno_fVal\")[i].dtype;\n    switch(dtype){\n        case \"int\":\n            //node.send({\"payload\" : { value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1}}); Alternativa! \n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n            break;\n        case \"float\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"long\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"bool\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n    }\n    //node.send(msg);\n\n    \n}\n\n/*\nvar id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrend_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {   \n    id = flow.get(\"tagsTrend_fVal\")[i].id;\n    nome = flow.get(\"tagsTrend_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrend_fVal\")[i].adress;\n    msg.payload = { value: id,'fc': 3, 'unitid': 1, 'address': adress-1 , 'quantity': 1 };\n    node.send(msg)\n}\n*/","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":900,"wires":[["51cc7053.d6972","a0fe3079.b18fd"]]},{"id":"ba3cff0.dc59a","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var idtag = msg.modbusRequest.unitid;\nvar val = msg.payload;\nvar dtype = msg.modbusRequest.value;\n\nvar msg1 = {payload:null};\nvar msg2 = {payload:null};\nvar msg3 = {payload:null};\n\nswitch(dtype){\n        case \"int\" || \"bool\":\n            msg1.payload = val;\n            msg1.topic = idtag;\n            node.send([[msg1],[null],[null]]);\n            break;\n        case \"float\":\n            msg2.payload = val;\n            msg2.topic = idtag;\n            node.send([[null],[msg2],[null]]);\n            break;\n        case \"long\":\n            msg3.payload = val;\n            msg3.topic = idtag;\n            node.send([[null],[null],[msg3]]);\n    }","outputs":3,"noerr":0,"initialize":"","finalize":"","x":700,"y":900,"wires":[["98c704de.4c2fd8","2222bf63.7448b"],["a76e0e68.6dab8"],["b6e47112.e3e44"]]},{"id":"98c704de.4c2fd8","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qInsert_Trending","outField":"payload","returnType":"1","throwErrors":1,"query":"Insert into dbo.Trending(idtag,tempo,val)\nValues(@idtag,CURRENT_TIMESTAMP, @val)","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"editor","params":[{"output":false,"name":"SO2","type":"Int","valueType":"flow","value":"SO2_Value"},{"output":false,"name":"CO","type":"Int","valueType":"flow","value":"CO_Value"},{"output":false,"name":"idtag","type":"real","valueType":"msg","value":"topic"},{"output":false,"name":"val","type":"Real","valueType":"msg","value":"payload"}],"x":1150,"y":920,"wires":[[]]},{"id":"a76e0e68.6dab8","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":940,"wires":[["98c704de.4c2fd8","2222bf63.7448b"]]},{"id":"b6e47112.e3e44","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"string","name":"topic","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":980,"wires":[["98c704de.4c2fd8","2222bf63.7448b"]]},{"id":"c22bb5a7.8158a8","type":"comment","z":"f5c32c9b.8a69f","name":"Leitura de tags de trending / Forno","info":"","x":180,"y":60,"wires":[]},{"id":"433a3c6a.39db54","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrendFieira_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {\n    var j=1;\n    id = flow.get(\"tagsTrendFieira_fVal\")[i].idTag;\n    nome = flow.get(\"tagsTrendFieira_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrendFieira_fVal\")[i].adress;\n    dtype = flow.get(\"tagsTrendFieira_fVal\")[i].dtype;\n    switch(dtype){\n        case \"int\":\n            //node.send({\"payload\" : { value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1}}); Alternativa! \n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n            break;\n        case \"float\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"long\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"bool\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n    }\n    //node.send(msg);\n\n    \n}\n\n/*\nvar id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrend_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {   \n    id = flow.get(\"tagsTrend_fVal\")[i].id;\n    nome = flow.get(\"tagsTrend_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrend_fVal\")[i].adress;\n    msg.payload = { value: id,'fc': 3, 'unitid': 1, 'address': adress-1 , 'quantity': 1 };\n    node.send(msg)\n}\n*/","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":1040,"wires":[["3ae06a17.092416","a69ccf95.527f4"]]},{"id":"3ae06a17.092416","type":"modbus-flex-getter","z":"f5c32c9b.8a69f","name":"Fieira","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"server":"e8394247.b7eec","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"x":510,"y":1040,"wires":[["4484487b.77c178"],[]]},{"id":"4484487b.77c178","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var idtag = msg.modbusRequest.unitid;\nvar val = msg.payload;\nvar dtype = msg.modbusRequest.value;\n\nvar msg1 = {payload:null};\nvar msg2 = {payload:null};\nvar msg3 = {payload:null};\n\nswitch(dtype){\n        case \"int\" || \"bool\":\n            msg1.payload = val;\n            msg1.topic = idtag;\n            node.send([[msg1],[null],[null]]);\n            break;\n        case \"float\":\n            msg2.payload = val;\n            msg2.topic = idtag;\n            node.send([[null],[msg2],[null]]);\n            break;\n        case \"long\":\n            msg3.payload = val;\n            msg3.topic = idtag;\n            node.send([[null],[null],[msg3]]);\n    }","outputs":3,"noerr":0,"initialize":"","finalize":"","x":700,"y":1040,"wires":[["d90fbe64.27df9","4a667d1e.400e04"],["f6a32711.97d188"],["1dac9b5f.f9ad95"]]},{"id":"f6a32711.97d188","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":1080,"wires":[["d90fbe64.27df9","4a667d1e.400e04"]]},{"id":"1dac9b5f.f9ad95","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"string","name":"topic","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":1120,"wires":[["d90fbe64.27df9","4a667d1e.400e04"]]},{"id":"d90fbe64.27df9","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qInsert_Trending","outField":"payload","returnType":0,"throwErrors":1,"query":"Insert into dbo.Trending(idtag,tempo,val)\nValues(@idtag,CURRENT_TIMESTAMP, @val)","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"editor","params":[{"output":false,"name":"SO2","type":"Int","valueType":"flow","value":"SO2_Value"},{"output":false,"name":"CO","type":"Int","valueType":"flow","value":"CO_Value"},{"output":false,"name":"idtag","type":"real","valueType":"msg","value":"topic"},{"output":false,"name":"val","type":"Real","valueType":"msg","value":"payload"}],"x":1150,"y":1080,"wires":[[]]},{"id":"4a667d1e.400e04","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1130,"y":1020,"wires":[]},{"id":"2222bf63.7448b","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1130,"y":880,"wires":[]},{"id":"f777fb3e.6ea2d8","type":"debug","z":"f5c32c9b.8a69f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","targetType":"msg","statusVal":"","statusType":"auto","x":360,"y":840,"wires":[]},{"id":"1f579b94.e61314","type":"comment","z":"f5c32c9b.8a69f","name":"Insert de tags de trending","info":"","x":150,"y":840,"wires":[]},{"id":"a23c3094.960c2","type":"comment","z":"f5c32c9b.8a69f","name":"Leitura de tags de trending / Secador","info":"","x":180,"y":420,"wires":[]},{"id":"688d85ac.6452dc","type":"inject","z":"f5c32c9b.8a69f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":520,"wires":[["6ec6b99.b48b548","38b1158b.148e7a"]]},{"id":"6ec6b99.b48b548","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_TagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT [id] as idTag\r\n      ,[nome]\r\n      ,[ip]\r\n      ,[adress]\r\n      ,[dtype]\r\n      ,[hist]\r\n  FROM [hmiFscam].[dbo].[tagsTrend]\r\n  WHERE [ip] = '192.168.1.46'\r\n  order by ip, id","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":370,"y":520,"wires":[["fb7b9f2a.3910b"]]},{"id":"fb7b9f2a.3910b","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"tagsTrendSecador_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":520,"wires":[[]]},{"id":"38b1158b.148e7a","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_nRegsTagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT COUNT(id) AS nReg\r\nFROM dbo.tagsTrend\r\nwhere [ip] = '192.168.1.46'","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":390,"y":460,"wires":[["a81282d8.08c0b"]]},{"id":"a81282d8.08c0b","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"nRegsTrendSecador_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":460,"wires":[["c4acb0a8.5a326"]]},{"id":"c4acb0a8.5a326","type":"debug","z":"f5c32c9b.8a69f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":790,"y":460,"wires":[]},{"id":"57551078.7ed3b","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrendSecador_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {\n    var j=1;\n    id = flow.get(\"tagsTrendSecador_fVal\")[i].idTag;\n    nome = flow.get(\"tagsTrendSecador_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrendSecador_fVal\")[i].adress;\n    dtype = flow.get(\"tagsTrendSecador_fVal\")[i].dtype;\n    switch(dtype){\n        case \"int\":\n            //node.send({\"payload\" : { value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1}}); Alternativa! \n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n            break;\n        case \"float\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"long\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 2};\n            node.send(msg);\n            break;\n        case \"bool\":\n            msg.payload = {value: dtype,'fc': 3, 'unitid': id, 'address': adress-1 , 'quantity': 1};\n            node.send(msg);\n    }\n    //node.send(msg);\n\n    \n}\n\n/*\nvar id;\nvar nome;\nvar adress;\n\nvar numeroRegs = flow.get(\"nRegsTrend_fVal\")[0].nReg;\nfor (var i = 0 ; i < numeroRegs ; i++) {   \n    id = flow.get(\"tagsTrend_fVal\")[i].id;\n    nome = flow.get(\"tagsTrend_fVal\")[i].nome;\n    adress = flow.get(\"tagsTrend_fVal\")[i].adress;\n    msg.payload = { value: id,'fc': 3, 'unitid': 1, 'address': adress-1 , 'quantity': 1 };\n    node.send(msg)\n}\n*/","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":1180,"wires":[["26f9bd6a.d9aef2","af4d9152.af8db"]]},{"id":"26f9bd6a.d9aef2","type":"modbus-flex-getter","z":"f5c32c9b.8a69f","name":"Secador","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"server":"24f82de6.9decb2","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"x":520,"y":1180,"wires":[["1f0012de.3a0e1d"],[]]},{"id":"1f0012de.3a0e1d","type":"function","z":"f5c32c9b.8a69f","name":"","func":"var idtag = msg.modbusRequest.unitid;\nvar val = msg.payload;\nvar dtype = msg.modbusRequest.value;\n\nvar msg1 = {payload:null};\nvar msg2 = {payload:null};\nvar msg3 = {payload:null};\n\nswitch(dtype){\n        case \"int\" || \"bool\":\n            msg1.payload = val;\n            msg1.topic = idtag;\n            node.send([[msg1],[null],[null]]);\n            break;\n        case \"float\":\n            msg2.payload = val;\n            msg2.topic = idtag;\n            node.send([[null],[msg2],[null]]);\n            break;\n        case \"long\":\n            msg3.payload = val;\n            msg3.topic = idtag;\n            node.send([[null],[null],[msg3]]);\n    }","outputs":3,"noerr":0,"initialize":"","finalize":"","x":700,"y":1180,"wires":[["e3fbd85b.594b58","20b4412e.bdab3e"],["9bc5f144.dcbe2"],["55a0eda3.74f804"]]},{"id":"9bc5f144.dcbe2","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":1220,"wires":[["e3fbd85b.594b58","20b4412e.bdab3e"]]},{"id":"55a0eda3.74f804","type":"buffer-parser","z":"f5c32c9b.8a69f","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatle","name":"payload","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"string","name":"topic","offset":0,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":870,"y":1260,"wires":[["e3fbd85b.594b58","20b4412e.bdab3e"]]},{"id":"e3fbd85b.594b58","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qInsert_Trending","outField":"payload","returnType":0,"throwErrors":1,"query":"Insert into dbo.Trending(idtag,tempo,val)\nValues(@idtag,CURRENT_TIMESTAMP, @val)","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"editor","params":[{"output":false,"name":"SO2","type":"Int","valueType":"flow","value":"SO2_Value"},{"output":false,"name":"CO","type":"Int","valueType":"flow","value":"CO_Value"},{"output":false,"name":"idtag","type":"real","valueType":"msg","value":"topic"},{"output":false,"name":"val","type":"Real","valueType":"msg","value":"payload"}],"x":1150,"y":1220,"wires":[[]]},{"id":"20b4412e.bdab3e","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1130,"y":1160,"wires":[]},{"id":"b6dacaeb.738998","type":"comment","z":"f5c32c9b.8a69f","name":"Leitura de tags de trending / SecBiomassa","info":"","x":200,"y":600,"wires":[]},{"id":"2b2df37b.5b394c","type":"inject","z":"f5c32c9b.8a69f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":720,"wires":[["cbf6d0ac.3758c","1b1335e2.e6cc5a"]]},{"id":"cbf6d0ac.3758c","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_TagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT [id] as idTag\r\n      ,[nome]\r\n      ,[ip]\r\n      ,[adress]\r\n      ,[dtype]\r\n      ,[hist]\r\n  FROM [hmiFscam].[dbo].[tagsTrend]\r\n  WHERE [ip] = '192.168.1.35'\r\n  order by ip, id","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":370,"y":720,"wires":[["21e57f83.5a729"]]},{"id":"21e57f83.5a729","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"tagsTrendSecBiomassa_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":720,"wires":[[]]},{"id":"1b1335e2.e6cc5a","type":"MSSQL","z":"f5c32c9b.8a69f","mssqlCN":"3222edfd.86f4d2","name":"qView_nRegsTagsTrend","outField":"payload","returnType":0,"throwErrors":1,"query":"SELECT COUNT(id) AS nReg\r\nFROM dbo.tagsTrend\r\nwhere [ip] = '192.168.1.35'","modeOpt":"","modeOptType":"query","queryOpt":"","queryOptType":"editor","paramsOpt":"","paramsOptType":"none","params":[],"x":390,"y":660,"wires":[["bb647503.68dfb8"]]},{"id":"bb647503.68dfb8","type":"function","z":"f5c32c9b.8a69f","name":"","func":"flow.set(\"nRegsTrendSecBiomassa_fVal\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":660,"wires":[["ed4eae9a.862e2"]]},{"id":"ed4eae9a.862e2","type":"debug","z":"f5c32c9b.8a69f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":790,"y":660,"wires":[]},{"id":"a0fe3079.b18fd","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":530,"y":960,"wires":[]},{"id":"a69ccf95.527f4","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":530,"y":1100,"wires":[]},{"id":"af4d9152.af8db","type":"debug","z":"f5c32c9b.8a69f","name":"","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":530,"y":1240,"wires":[]},{"id":"3222edfd.86f4d2","type":"MSSQL-CN","tdsVersion":"7_4","name":"hmiFscam_cnn","server":"192.168.1.17\\sqlexpress","port":"1433","encyption":false,"database":"hmiFscam","useUTC":false,"connectTimeout":"15000","requestTimeout":"15000","cancelTimeout":"5000","pool":"5","parseJSON":false,"enableArithAbort":true},{"id":"57332e15.d4ae5","type":"modbus-client","name":"Forno","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.1.42","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true},{"id":"e8394247.b7eec","type":"modbus-client","name":"Fieira","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.1.27","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"2","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true},{"id":"24f82de6.9decb2","type":"modbus-client","name":"Secador","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.1.46","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":1,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true}]

Ok, so I now understand what you are doing...

You read the Modbus Addresses & expected type from a DB table, then loop through each row firing that to the Modbus Flex getter.

All these individual reads will make this the slowest possible way of collecting data with the biggest chance of inconsistent data. (i.e. the time between reading first item and last item is likely the first item will have updated in the PLC)

Possible solution...
Add a column to the database called poll_group e.g...

id name poll_group ip address hist
1 item 1 g1 192.168.1.27 1000 true
2 item 2 g1 192.168.1.27 1003 true
3 item 3 g1 192.168.1.27 1009 true
4 item 4 g2 192.168.1.27 2007 true
5 item 5 g2 192.168.1.27 2009 true
6 item 6 g2 192.168.1.27 2012 true

then when you get the poll data from the database, request the flex getter to get data from the groups lowest address to the quantity of max address - lowest address.

In other words, having a poll_group would permit you to calculate the first modbus address and quantity so that you can get all of values in that group consistently (in one read).

Additionally, from that table, you can easily generate a dynamic specification for the buffer parser

e.g...

var bpSpec = {
    "options": {
        "byteSwap": ["swap16"],
        "resultType": "keyvalue",
        "multipleResult": false,
        "setTopic": true,
        "msgProperty": "payload"
    },
    "items": [ ]
}

var sizes = {
    "byte" : 1,
    "int8" : 1,
    "uint8" : 1,
    "int16be" : 2,
    "int16le" : 2,
    "uint16be" : 2,
    "uint16le" : 2,
    "floatbe" : 4,
    "floatle" : 4,
    "int32be" : 4,
    "int32be" : 4,
    "uint32be" : 4,
    "uint32be" : 4
}

let offs = 0
for (let index = 0; index < dbGroup.length; index++) {
    //get the row of this group
    const row = dbGroup[index];
    //add a spec item to the buffer parser dynamic spec
    bpSpec.items.push( {
        "name": row.name,
        "type": row.dType,
        "offset": offs
    })
    offs += sizes[row.dType];
}

//pass dynamic spec into buffer parser
msg.spec = bpSpec; 
return msg;

then pass that msg to the buffer parser so when it runs, you get a payload like this for each group...

 {
    "Temp 1 canal 1": 28.6,
    "Temp 1 canal 2": 23.7,
    "Temp 1 canal 3": 29.4,
    "Temp 1 canal 4": 31.6,
}

all data (in that group) collected in one hit & prepared in one object (all together).

The following benefits can be realised...

  1. reduces polling by a large amount (reading 100 items is FAR faster than even 3 separate polls or 1 WORD - so the speed increase is significant)
  2. group data is read in one poll - meaning data values are read with consistency to each other.

NOTES...

Do not try to read a quantity of data > 100 items (the modbus node cannot do it & will likely crash node-red) - in other words, be clever with your grouping.

Thanks again for the tip.

I believe you are right but I still have a problem. In the end I must separate all the adress to put just the needed values in the database.
I will try, but I think that doesn´t solve the issue! The problem on the flow is understand why just one, and sometimes two modbus flex getter nodes, send message for the next node. If you observe just the debug nodes after the modbus flex getter on the image I send before, just the second debug node get the values. I will need 8 modbus-flex-getter nodes because I have 8 PLCs. This will complicate even more the situation.

Thanks,

No you don't

you can generate the SQL Query for each value from the payload generated by the buffer parser.

e.g. If you set the buffer parser to return an Array of object you will get all your values like this...

then you can use a split node to generate multiple messages that you can feed into a SQL insert query / procedure using .name or some other property that you decide as a key for your data.


As for your issue - without access to your devices it is impossible to test but i suspect a bug in one of the libraries somewhere under the hood getting mixed up with multiple inflight modbus transmissions (in your current flow, you trigger all 3 modbus reads from one inject). How I have fixed this issue for other users is it to put the modbus operations in series - like this...

... so now the modbus operations all occur sequentially. This of course means you should probably speed up data retrieval (by grouping)

Also, you can set the buffer parser to output multiple messages

image

this will output 1 object per item in the buffer parser

you can then generate a SQL insert for each message.

The KEY point is minimising the POLLS to the PLC (for consistency and speed) - and I have already shown you how to achieve the modbus read grouping.

Error message:
"Error: items property is not an array of objects"
I think is missing something to the buffer parser accept the items values!

var bpSpec = {
    "options": {
        "byteSwap": ["swap16"],
        "resultType": "keyvalue",
        "multipleResult": false,
        "setTopic": true,
        "msgProperty": "payload"
    },
    "items": [ ]
}

var sizes = {
    "byte" : 1,
    "int8" : 1,
    "uint8" : 1,
    "int16be" : 2,
    "int16le" : 2,
    "uint16be" : 2,
    "uint16le" : 2,
    "floatbe" : 4,
    "floatle" : 4,
    "int32be" : 4,
    "int32be" : 4,
    "uint32be" : 4,
    "uint32be" : 4
}

let offs = 0
for (let index = 0; index < dbGroup.length; index++) {
    //get the row of this group
    const row = dbGroup[index];
    //add a spec item to the buffer parser dynamic spec
    bpSpec.items.push( {
        "name": row.name,
        "type": row.dType,
        "offset": offs
    })
    offs += sizes[row.dType];
}

//pass dynamic spec into buffer parser
msg.spec = bpSpec; 
return msg;

Hi @agmacedo

Your function code is missing an object dbGroup so i made up a fake value for it.

test flow...

[{"id":"16d7b199.41963e","type":"function","z":"42ea7bd7.2e3c24","name":"build spec","func":"\n//data\nvar dbGroup = msg.dbGroup;\n\nvar bpSpec = {\n    \"options\": {\n        \"byteSwap\": [\"swap16\"],\n        \"resultType\": \"keyvalue\",\n        \"multipleResult\": false,\n        \"setTopic\": true,\n        \"msgProperty\": \"payload\"\n    },\n    \"items\": [ ]\n}\n\nvar sizes = {\n    \"byte\" : 1,\n    \"int8\" : 1,\n    \"uint8\" : 1,\n    \"int16be\" : 2,\n    \"int16le\" : 2,\n    \"uint16be\" : 2,\n    \"uint16le\" : 2,\n    \"floatbe\" : 4,\n    \"floatle\" : 4,\n    \"int32be\" : 4,\n    \"int32be\" : 4,\n    \"uint32be\" : 4,\n    \"uint32be\" : 4\n}\n\nlet offs = 0\nfor (let index = 0; index < dbGroup.length; index++) {\n    //get the row of this group\n    const row = dbGroup[index];\n    //add a spec item to the buffer parser dynamic spec\n    bpSpec.items.push( {\n        \"name\": row.name,\n        \"type\": row.dType,\n        // \"length\": 1,\n        // \"offsetbit\": 0,\n        // \"mask\": 0,\n        // \"scale\": 0,\n        \"offset\": offs\n    })\n    offs += sizes[row.dType];\n}\n\n//pass dynamic spec into buffer parser\nmsg.spec = bpSpec; \n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":180,"wires":[["ce1b33.444e54d","febc26ab.49d5f8"]]},{"id":"5af6ac2e.be2074","type":"inject","z":"42ea7bd7.2e3c24","name":"fake buffer","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[16,12,66,225,233,246,58,151,104,222,0,177]","payloadType":"bin","x":100,"y":180,"wires":[["d7e497d5.733328"]]},{"id":"ce1b33.444e54d","type":"debug","z":"42ea7bd7.2e3c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":610,"y":120,"wires":[]},{"id":"62a6326a.5d8d2c","type":"buffer-parser","z":"42ea7bd7.2e3c24","name":"UI spec","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"byte","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int16be","name":"item2","offset":1,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatbe","name":"item3","offset":3,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int32be","name":"item4","offset":7,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":620,"y":240,"wires":[["54cb852a.02641c"]]},{"id":"54cb852a.02641c","type":"debug","z":"42ea7bd7.2e3c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":790,"y":240,"wires":[]},{"id":"febc26ab.49d5f8","type":"buffer-parser","z":"42ea7bd7.2e3c24","name":"dynamic spec","data":"payload","dataType":"msg","specification":"spec","specificationType":"msg","items":[{"type":"byte","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int16be","name":"item2","offset":1,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatbe","name":"item3","offset":3,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int32be","name":"item4","offset":7,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":640,"y":180,"wires":[["96ad9e5d.34d4d"]]},{"id":"96ad9e5d.34d4d","type":"debug","z":"42ea7bd7.2e3c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":790,"y":180,"wires":[]},{"id":"aa06b3d9.8bffe","type":"inject","z":"42ea7bd7.2e3c24","name":"fake buffer","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[16,12,66,225,233,246,58,151,104,222,0,177]","payloadType":"bin","x":100,"y":240,"wires":[["62a6326a.5d8d2c"]]},{"id":"d7e497d5.733328","type":"change","z":"42ea7bd7.2e3c24","name":"","rules":[{"t":"set","p":"dbGroup","pt":"msg","to":"[{\"name\":\"item1_byte\",\"dType\":\"byte\"},{\"name\":\"item2_int16be\",\"dType\":\"int16be\"},{\"name\":\"item3_floatbe\",\"dType\":\"floatbe\"},{\"name\":\"item4_int32be\",\"dType\":\"int32be\"}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":180,"wires":[["16d7b199.41963e"]]}]