My goal is to motorize 350 addresses of a PLC over a modebus-tcp, and if any of the values are different then 0 (zero) to display on a dashboard those address, the corresponding status (based on the value reported) and the trigger time.
In other words to create an alarm dashboard that shows in real time the PLC status.
Some clarification:
- The flow only pulls modbus-tcp data (every second) no need to send any commands (values)
- Each address can report only the following values:
- "0" - normal state (value not displayed)
- "2" - not acknowledge alarm (display in red)
- "1027" - acknowledge alarm (display in yellow)
- "1088" - sensor fail (sensor fail) - Each address is associated with a certain area of the system (ex. 0001 = valve 1; 0002 = light1; 0003 = main computer .....) on the dashboard I want to display the associated name of each address too.
- beside the real time dashboard I want to create an alarm log (a database with all reported alarms as they occur)
I need some help with he following:
- how to display the initial triggered alarm time (on my flow time refreshes with every data pull)
- how to separate the triggered alarms from the modbus-read array and to use a database to associate the names of the triggered address (for all 350 of them)
- how to separate the triggered alarms from the modbus-read array to be logged to a database
Any help is much appreciated.
Here is a print screen of my dashboard and the flow I have so far:
[{"id":"e36f3a9f.a38dd8","type":"ui_table","z":"74d8f714.ab8378","group":"81dd3718.b97888","name":"Alarm","order":1,"width":"12","height":"8","columns":[{"field":"Time","title":"<center>Time</>","width":"25%","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"Register","title":"<center>Channel</>","width":"10%","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"Notes","title":"<center>Alarm Message</>","width":"50%","align":"center","formatter":"html","formatterParams":{"target":"_blank"}},{"field":"Alarm","title":"<center>Status</>","width":"15%","align":"center","formatter":"html","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":850,"y":1460,"wires":[]},{"id":"80183847.7650d8","type":"modbus-read","z":"74d8f714.ab8378","name":"","topic":"","showStatusActivities":true,"logIOActivities":false,"showErrors":true,"unitid":"","dataType":"HoldingRegister","adr":"0","quantity":"100","rate":"5","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"c6527b9f.17c448","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":170,"y":1480,"wires":[["c37bbf47.cf40d8","6cd67e6f.8345f8","55ab041b.5d0f3c","2856eb17.df3bb4","bb3c74a1.d7b4c","74cfddeb.27a7e4","7fbc0c6f.1603dc","345beee5.52173a"],[]]},{"id":"6cd67e6f.8345f8","type":"function","z":"74d8f714.ab8378","name":"1-100 test all alarms code","func":"\nvar t = new Date();\nt = (('00' + t.getHours()).slice(-2) + ':' + ('00' + t.getMinutes()).slice(-2) + ':' + ('00' + t.getSeconds()).slice(-2) + ' / ' + ('00' + (t.getMonth()+1)).slice(-2) + '.' + ('00' + t.getDate()).slice(-2) + '.' + t.getFullYear());\n\n//var i=0;\nfor (var i=0; i < msg.payload.length ; i++) {\n\nif (msg.payload[i]!==0) {\n if (i<9) {\n if (msg.payload[i]===2) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"0000\" + (i+1),\n \"Alarm\": \"<div style='background-color: red; width:100%; color:white'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1027) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"0000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1028) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"0000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1029) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"0000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n if (msg.payload[i]===1088) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"0000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"SENSOR FAIL\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n }\n if (i>=9 && i<99) {\n if (msg.payload[i]===2) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"000\" + (i+1),\n \"Alarm\": \"<div style='background-color: red; width:100%; color:white'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1027) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1028) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1029) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n if (msg.payload[i]===1088) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"000\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"SENSOR FAIL\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n }\n if (i==99) {\n if (msg.payload[i]===2) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"00\" + (i+1),\n \"Alarm\": \"<div style='background-color: red; width:100%; color:white'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1027) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"00\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1028) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"00\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n }\n if (msg.payload[i]===1029) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"00\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n if (msg.payload[i]===1088) {\n msg.payload.push(\n {\n \"Time\": t,\n \"Register\":\"00\" + (i+1),\n \"Alarm\": \"<div style='background-color: yellow; width:100%; color:red'>\" + \"SENSOR FAIL\" + \"</div>\",\n \"Notes\": \"<div style='background-color: red; width:100%; color:white'>\" + \"NO COMM. ON MAIN NETWORK\" + (i+1) +\"</div>\"\n })\n } \n }\n}\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":430,"y":1460,"wires":[["8bb0330c.318e2","42560203.14ce24","a8504d6b.fc97f","5285815a.bef9b","f4cbbe3f.7cd658"]]},{"id":"42560203.14ce24","type":"function","z":"74d8f714.ab8378","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":680,"y":1460,"wires":[["e36f3a9f.a38dd8"]]},{"id":"81dd3718.b97888","type":"ui_group","name":"Active Alarms","tab":"4e11db25.239e94","order":1,"disp":true,"width":"12","collapse":true},{"id":"c6527b9f.17c448","type":"modbus-client","name":"","clienttype":"tcp","bufferCommands":false,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.1.120","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":"4e11db25.239e94","type":"ui_tab","name":"Alarms Monitiring","icon":"dashboard","order":1,"disabled":false,"hidden":false}]