How to create an Modbus-TCP alarm status dashboard

Try this...

the key to this is to fire the reads sequentially. (PS, you will need to chose your modbus config in the modbus nodes)

[{"id":"e65eb5ea.4fa858","type":"modbus-getter","z":"5e6c8b.7f38b374","name":"0 ~ 99","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"unitid":"1","dataType":"HoldingRegister","adr":"0","quantity":"100","server":"d1841b37.604628","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"x":1584,"y":960,"wires":[["63c6d18f.950c8"],[]]},{"id":"2cc804d5.2e33bc","type":"modbus-getter","z":"5e6c8b.7f38b374","name":"100 ~ 199","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"unitid":"1","dataType":"HoldingRegister","adr":"100","quantity":"100","server":"d1841b37.604628","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":1596,"y":1024,"wires":[["9a94f150.5222"],[]]},{"id":"63c6d18f.950c8","type":"change","z":"5e6c8b.7f38b374","name":"","rules":[{"t":"set","p":"data1","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1776,"y":960,"wires":[["4fb126bd.00d5f8","2cc804d5.2e33bc"]]},{"id":"85684a01.bfd1f8","type":"inject","z":"5e6c8b.7f38b374","name":"","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":1442,"y":960,"wires":[["e65eb5ea.4fa858"]]},{"id":"9a94f150.5222","type":"change","z":"5e6c8b.7f38b374","name":"","rules":[{"t":"set","p":"data2","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1776,"y":1024,"wires":[["196ffb.89463005","ffc09dbd.9bc89"]]},{"id":"196ffb.89463005","type":"modbus-getter","z":"5e6c8b.7f38b374","name":"200 ~ 299","showStatusActivities":false,"showErrors":false,"logIOActivities":false,"unitid":"1","dataType":"HoldingRegister","adr":"100","quantity":"100","server":"d1841b37.604628","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":true,"x":1596,"y":1088,"wires":[["72d2709e.14a7d"],[]]},{"id":"72d2709e.14a7d","type":"change","z":"5e6c8b.7f38b374","name":"","rules":[{"t":"set","p":"data3","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1776,"y":1088,"wires":[["d5a57cd.c815d8","c18e20a2.23a71"]]},{"id":"d5a57cd.c815d8","type":"function","z":"5e6c8b.7f38b374","name":"Make 1 array","func":"msg.payload = [msg.data1.map(e => e), msg.data2.map(e => e), msg.data3.map(e => e)]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1686,"y":1168,"wires":[["cf84ffc3.151ed","58fd7ace.0eb404"]]},{"id":"cf84ffc3.151ed","type":"function","z":"5e6c8b.7f38b374","name":"generate alarm table","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\nvar lookup = {\n    1: \"NO COMM. ON MAIN NETWORK\",\n    2: \"NO COMM. ON BACKUP NETWORK\",\n    3: \"MAIN SERVER OUT OF ORDER\",\n    4: \"BACKUP SERVER OUT OF ORDER\",\n    5: \"NO COMM. MAIN SERVER ON MAIN NETWORK\",\n    6: \"NO COMM. MAIN SERVER ON BACKUP NETWORK\",\n    7: \"NO COMM. BACKUP SERVER ON MAIN NETWORK\",\n    8: \"NO COMM. BACKUP SERVER ON BACKUP NETWORK\",\n    9: \"MAXIMUM DISKSPACE USED. LOGGING STOPPED\",\n    10: \"ALARMLOG: FILE CAN NOT BE WRITTEN\",\n    11: \"MTUS PORT: RD4 COM PORT FAILURE\",\n    12: \"MTUS PORT: RD4 NO COMMUNICATION\",\n    13: \"MTUS PORT: RD4 ERROR IN COMMUNICATION\",\n    14: \"MTUS STBD: RD5 COM PORT FAILURE\",\n    15: \"MTUS STBD: RD5 NO COMMUNICATION\",\n    16: \"MTUS STBD: RD5 ERROR IN COMMUNICATION\",\n    17: \"X101 NOT PRESENT\",\n    18: \"X102 NOT PRESENT\",\n    19: \"X103 NOT PRESENT\",\n    20: \"X104 NOT PRESENT\",\n    21: \"X109 NOT PRESENT\",\n    22: \"X110 NOT PRESENT\",\n    23: \"X111 NOT PRESENT\",\n    24: \"X117 NOT PRESENT\",\n    25: \"X118 NOT PRESENT\",\n    26: \"X119 NOT PRESENT\",\n    27: \"X125 NOT PRESENT\",\n    28: \"X126 NOT PRESENT\",\n    29: \"X127 NOT PRESENT\",\n    30: \"X128 NOT PRESENT\",\n    31: \"XP101 MAIN LINK NOT PRESENT\",\n    32: \"XP109 MAIN LINK NOT PRESENT\",\n    33: \"XP117 MAIN LINK NOT PRESENT\",\n    34: \"XP125 MAIN LINK NOT PRESENT\",\n    35: \"XP101 BACKUP LINK NOT PRESENT\",\n    36: \"XP109 BACKUP LINK NOT PRESENT\",\n    37: \"XP117 BACKUP LINK NOT PRESENT\",\n    38: \"XP125 BACKUP LINK NOT PRESENT\",\n    39: \"X101 INVALID BOARD TYPE\",\n    40: \"X102 INVALID BOARD TYPE\",\n    41: \"X103 INVALID BOARD TYPE\",\n    42: \"X104 INVALID BOARD TYPE\",\n    43: \"X109 INVALID BOARD TYPE\",\n    44: \"X110 INVALID BOARD TYPE\",\n    45: \"X111 INVALID BOARD TYPE\",\n    46: \"X117 INVALID BOARD TYPE\",\n    47: \"X118 INVALID BOARD TYPE\",\n    48: \"X119 INVALID BOARD TYPE\",\n    49: \"X125 INVALID BOARD TYPE\",\n    50: \"X126 INVALID BOARD TYPE\",\n    51: \"X127 INVALID BOARD TYPE\",\n    52: \"X128 INVALID BOARD TYPE\",\n    53: \"MBS_TCP: RD18 TCP/IP Socket Error\",\n    54: \"MBS_TCP: RD18 No Communication\",\n    55: \"MAIN SERVER IO SERVER NOT FOUND\",\n    56: \"BACKUP SERVER IO SERVER NOT FOUND\",\n    57: \"FB1 MAIN LINK NO COMMUNICATION\",\n    58: \"FB1 BACKUP LINK NO COMMUNICATION\",\n    59: \"FB2 MAIN LINK NO COMMUNICATION\",\n    60: \"X201 NOT PRESENT\",\n    61: \"X202 NOT PRESENT\",\n    62: \"X203 NOT PRESENT\",\n    63: \"X204 NOT PRESENT\",\n    64: \"X209 NOT PRESENT\",\n    65: \"X210 NOT PRESENT\",\n    66: \"X211 NOT PRESENT\",\n    67: \"X217 NOT PRESENT\",\n    68: \"X218 NOT PRESENT\",\n    69: \"X219 NOT PRESENT\",\n    70: \"X220 NOT PRESENT\",\n    71: \"FB2 BACKUP LINK NO COMMUNICATION\",\n    72: \"XP201 MAIN LINK NOT PRESENT\",\n    73: \"XP209 MAIN LINK NOT PRESENT\",\n    74: \"XP217 MAIN LINK NOT PRESENT\",\n    75: \"XP201 BACKUP LINK NOT PRESENT\",\n    76: \"XP209 BACKUP LINK NOT PRESENT\",\n    77: \"XP217 BACKUP LINK NOT PRESENT\",\n    78: \"X202 INVALID BOARD TYPE\",\n    79: \"X203 INVALID BOARD TYPE\",\n    80: \"X204 INVALID BOARD TYPE\",\n    81: \"X210 INVALID BOARD TYPE\",\n    82: \"X211 INVALID BOARD TYPE\",\n    83: \"X212 INVALID BOARD TYPE\",\n    84: \"X218 INVALID BOARD TYPE\",\n    85: \"X219 INVALID BOARD TYPE\",\n    86: \"X220 INVALID BOARD TYPE\",\n    87: \"X301 NOT PRESENT\",\n    88: \"X302 NOT PRESENT\",\n    89: \"X303 NOT PRESENT\",\n    90: \"X304 NOT PRESENT\",\n    91: \"X309 NOT PRESENT\",\n    92: \"XP301 MAIN LINK NOT PRESENT\",\n    93: \"XP309 MAIN LINK NOT PRESENT\",\n    94: \"XP301 BACKUP LINK NOT PRESENT\",\n    95: \"FB3 MAIN LINK NO COMMUNICATION\",\n    96: \"FB3 BACKUP LINK NO COMMUNICATION\",\n    97: \"FB3 PROC301 IEC-1131 CONFIG NOT LOADED\",\n    98: \"FB3 PROC301 IEC-1131 PROGRAM NOT RUNNING\",\n    99: \"NMEA_WIND: RD6 COM PORT ERROR\",\n    100: \"NMEA_WIND: RD6 NO COMMUNICATION\",\n    101: \"FB3 PROC309 IEC-1131 CONFIG NOT LOADED\",\n    102: \"FB3 PROC309 IEC-1131 PROGRAM NOT RUNNING\",\n    103: \"X301 INVALID BOARD TYPE\",\n    104: \"X302 INVALID BOARD TYPE\",\n    105: \"X303 INVALID BOARD TYPE\",\n    106: \"X304 INVALID BOARD TYPE\",\n    107: \"X309 INVALID BOARD TYPE\",\n    108: \"FB4 MAIN LINK NO COMMUNICATION\",\n    109: \"FB4 BACKUP LINK NO COMMUNICATION\", \n    110: \"FB4 LOP MESS NOT PRESENT\",\n    111: \"FB4 LOP ENGINEER NOT PRESENT\",\n    112: \"FB4 LOP 1ST MATE NOT PRESENT\",\n    113: \"FB4 LOP ALARMPANEL ENGINEROOM\",\n    114: \"ALARM PANEL E.R. POWER FAIL\",\n    115: \"ALARM PANEL E.R. EARTH FAULT\",\n    116: \"WATERTIGHT DOORS POWER FAILURE\",\n    117: \"WATERTIGHT DOORS BATTERY LOW\",\n    118: \"BILGE FORE PEAK LEVEL HIGH\",\n    119: \"BILGE BOW THRUSTER ROOM LEVEL HIGH\",\n    120: \"BILGE COFFERDAM LEVEL HIGH\"\n}\n\n\n\nvar previous = context.get(\"previous\") || [];\nvar current = [...msg.payload];\nvar table = context.get(\"table\") || [];\nfor (var i = 0; i < msg.payload.length; i++) {\n    var channel = (\"\" + (i + 100)).padStart(5,\"0\");\n    var sensorNo = (i + 100);\n    var sensorName = lookup[sensorNo] || (\"Unknown \" + sensorNo);\n    //has value changed?\n    if (previous[i] !== current[i]) {\n        var row = table.find(e => e.Channel == channel);\n\n        if (!row) {\n            if (current[i] === 0)\n                continue; //dont add this one (its 0)\n            \n            row = {\n                \"Time\":t,\n                \"Channel\": channel,\n                \"Alarm\": \"\",                \n                \"Status\": \"\",\n                \"Alarmlog\": \"\",                \n                \"Statuslog\": \"\"                \n            }            \n            table.push(row);\n        } else {\n            //there is a row in the table...\n            if (current[i] === 0) {\n                ///remove it because its now 0\n                table = table.filter(e => e.Channel !== channel);\n                continue;\n            }\n        }\n\n        row.Time = t;//update the time\n        if (current[i] === 2) {\n            row.Status = \"<div style='background-color: red; width:100%; color:white'>\" + \"ALARM\" + \"</div>\";\n            row.Alarm = \"<div style='background-color: red; width:100%; color:white'>\" + sensorName + \"</div>\";\n            row.Statuslog = \"ALARM !\";\n            row.Alarmlog = sensorName ;            \n        } else if (current[i] === 1027) {\n            row.Status = \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\";\n            row.Alarm = \"<div style='background-color: red; width:100%; color:white'>\" + sensorName + \"</div>\";\n            row.Statuslog = \"ALARM\";\n            row.Alarmlog = sensorName ;            \n        } else if (current[i] === 1028) {\n            row.Status = \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\";\n            row.Alarm = \"<div style='background-color: red; width:100%; color:white'>\" + sensorName + \"</div>\";\n            row.Statuslog = \"ALARM\";\n            row.Alarmlog = sensorName ;\n        } else if (current[i] === 1029) {\n            row.Status = \"<div style='background-color: yellow; width:100%; color:red'>\" + \"ALARM\" + \"</div>\";\n            row.Alarm = \"<div style='background-color: red; width:100%; color:white'>\" + sensorName + \"</div>\";\n            row.Statuslog = \"ALARM\";\n            row.Alarmlog = sensorName ;\n        } else if (current[i] === 1088) {\n            row.Status = \"<div style='background-color: yellow; width:100%; color:red'>\" + \"SENSOR FAIL\" + \"</div>\";\n            row.Alarm = \"<div style='background-color: red; width:100%; color:white'>\" + sensorName + \"</div>\";\n            row.Statuslog = \"SENSOR FAIL\";\n            row.Alarmlog = sensorName ;\n        }\n                //TODO: \n        // You can create the SQL here and send it in the topic OR send an object with \n        // the clean alarm and notes info (i.e. no HTML) then build a SQL query in the next node \n        node.send( [null, { topic: (\"INSERT INTO alarmlog (Time,Channel,Alarm,Status) \" +\n        \"VALUES ('\"+row.Time+\"','\"+row.Channel+\"','\"+row.Alarmlog+\"','\"+row.Statuslog+\"')\")}] ); //Send the SQL query out of output 2\n    }\n}\n\ncontext.set(\"previous\", current);\ncontext.set(\"table\", table);\n\nmsg.payload = table;\nreturn [msg, null]; //Return table to function output 1;","outputs":2,"noerr":0,"initialize":"","finalize":"","x":1924,"y":1168,"wires":[["37fac07c.eb383"],["b3b05181.6d535"]]},{"id":"37fac07c.eb383","type":"debug","z":"5e6c8b.7f38b374","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2226,"y":1136,"wires":[]},{"id":"b3b05181.6d535","type":"debug","z":"5e6c8b.7f38b374","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2226,"y":1184,"wires":[]},{"id":"4fb126bd.00d5f8","type":"debug","z":"5e6c8b.7f38b374","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2002,"y":960,"wires":[]},{"id":"ffc09dbd.9bc89","type":"debug","z":"5e6c8b.7f38b374","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2002,"y":1024,"wires":[]},{"id":"58fd7ace.0eb404","type":"debug","z":"5e6c8b.7f38b374","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1698,"y":1216,"wires":[]},{"id":"c18e20a2.23a71","type":"debug","z":"5e6c8b.7f38b374","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":2002,"y":1088,"wires":[]},{"id":"d1841b37.604628","type":"modbus-client","name":"","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"192.168.1.59","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}]

NOTE: Why yours didnt work...

  1. You have no guarantee which of those read nodes would fire first (then the join would make the 1st array 2nd and the 2nd array first - completely out of order)
  2. There can be problems sending reads to a modbus at the same time. Reading sequentially avoids this potential issue.
  3. You were duplicating the function node which was designed to operate on a single array (of any size) - the solution was to join the arrays BEFORE sending to the function (not the other way around)