# Table with 5 sensors data with fixed row

**URL:** <https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515>\
**Category:** Dashboard\
**Created:** [21 February 2023 14:53 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515 "2023-02-21T14:53:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lance99](https://avatars.discourse-cdn.com/v4/letter/l/6de8d8/32.png) [@Lance99](https://discourse.nodered.org/u/Lance99)\
**Post date:** [21 February 2023 14:53 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/1 "2023-02-21T14:53:18Z")

</div>

I have five different sensors with live measurements. I want the sensor ID to be sorted (colum A) and measure data in colum B, C, ...  
With this setup, I get only one one row of data and the latest message overwrites the previous.

```auto
[{"id":"b9fcf9e5.8e1eb8","type":"ui_table","z":"161bc1d0.dbc88e","group":"1638a6ad.34a9f9","name":"EE","order":5,"width":"13","height":"3","columns":[],"outputs":0,"cts":false,"x":750,"y":360,"wires":[]},{"id":"a8b6cdb3.c73df","type":"function","z":"161bc1d0.dbc88e","name":"filter","func":"msg.payload = [\n {\n \"serial\": msg.payload.serialNo,\n \"Timestamp\": new Date(msg.payload).toLocaleString(),\n \"rssi\": msg.payload.rssi,\n \"Manuf\": msg.payload.manufacturer,\n}\n];\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":360,"wires":[["b9fcf9e5.8e1eb8"]]},{"id":"1638a6ad.34a9f9","type":"ui_group","z":"","name":"AmundTabell","tab":"7cda3603.64ae68","disp":true,"width":"13","collapse":false},{"id":"7cda3603.64ae68","type":"ui_tab","z":"","name":"Tabell_Test","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

```

How can I have five rows (one for each sensors), sensor ID sorted colum A, and the data corresponds to the correct row and cell?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [21 February 2023 15:33 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/2 "2023-02-21T15:33:37Z")

</div>

I you look at the `Help` tab for the node, it will show an example of multiple rows and columns.  
to get the data from the five sensors you need to use a `join` node to combine the data.

---

<div class="post-metadata">

**Author:** ![Lance99](https://avatars.discourse-cdn.com/v4/letter/l/6de8d8/32.png) [@Lance99](https://discourse.nodered.org/u/Lance99)\
**Post date:** [2 March 2023 12:04 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/3 "2023-03-02T12:04:49Z")

</div>

Thanks zenofmud

I can so far live with sensordata that is not actually fixed to a row. Now the sensor data updating the table every 10 sec, thats OK right no. Later fixed rows 🙂 -)

But ... I use a TickCross symbol in one colomn. Now, both symbols are red color. I want the Tick to be green. I have searched the forum, but I still don't understand how to implement it.

I followded this one:  
Youtube : [How to create a data table in Node RED Dashboard - YouTube](https://www.youtube.com/watch?v=L4RTrXKXd7M&ab_channel=OptoVideo)  
... and it is working, but how to change to tick color?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [2 March 2023 12:29 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/4 "2023-03-02T12:29:44Z")

</div>

Without seeing your actual flow all I can do is guess

---

<div class="post-metadata">

**Author:** ![Lance99](https://avatars.discourse-cdn.com/v4/letter/l/6de8d8/32.png) [@Lance99](https://discourse.nodered.org/u/Lance99)\
**Post date:** [2 March 2023 12:34 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/5 "2023-03-02T12:34:25Z")

</div>

Sorry ...  
here it is:

```auto
[{"id":"6766777f.a1cc18","type":"function","z":"161bc1d0.dbc88e","name":"filter","func":"tableData2 = flow.get(\"savedData2\") || [];\n\ntableData2.unshift({\n \"Node ID\": msg.payload.bridgeId,\n //\"Tid\": new Date(msg.payload.timeStamp).toLocaleString(\"no-NO\"),\n \"Tid\": Date(msg.payload.timeStamp).toLocaleString(),\n \"RSSI\": msg.payload.rssi,\n \"OK\": msg.payload.tickcross,\n \"Manuf\": \"Vitir\"\n});\n\nif (tableData2.length >5) tableData2.pop();\n\nmsg.payload = tableData2;\n \nflow.set(\"savedData2\", tableData2);\n\nreturn msg;","outputs":1,"noerr":0,"x":870,"y":80,"wires":[["d659ea4b.40b698"]]},{"id":"d659ea4b.40b698","type":"trigger","z":"161bc1d0.dbc88e","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","outputs":1,"x":1050,"y":80,"wires":[["4c56eee1.aeb4e"]]},{"id":"4c56eee1.aeb4e","type":"ui_table","z":"161bc1d0.dbc88e","group":"1638a6ad.34a9f9","name":"Bridges","order":2,"width":"10","height":"4","columns":[{"field":"Node ID","title":"Bridge ID","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"Tid","title":"Time","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"RSSI","title":"rssi","width":"","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"OK","title":"Pass/Fail","width":"","align":"center","formatter":"tickCross","formatterParams":{"target":"_blank"}},{"field":"Manuf","title":"Manuf.","width":"","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":1240,"y":80,"wires":[]},{"id":"9ed67d72.c0453","type":"json","z":"161bc1d0.dbc88e","name":"","property":"payload","action":"","pretty":false,"x":690,"y":80,"wires":[["6766777f.a1cc18"]]},{"id":"6b55e2f6.f9fa3c","type":"mqtt in","z":"161bc1d0.dbc88e","name":"","topic":"","qos":"2","datatype":"auto","x":500,"y":100,"wires":[["9ed67d72.c0453"]]},{"id":"1638a6ad.34a9f9","type":"ui_group","name":"Signalstyrke","tab":"7cda3603.64ae68","order":1,"disp":true,"width":"12","collapse":false},{"id":"7cda3603.64ae68","type":"ui_tab","name":"Tabell_Test","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

```

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [2 March 2023 12:40 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/6 "2023-03-02T12:40:13Z")

</div>

I can't 'import' your code. Have a look at this link to see how to do it.

In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote `````)

````auto
``` 
   code goes here 
```

````

You can edit and correct your post by clicking the pencil ✏ icon.

See this post for more details - [How to share code or flow json](https://discourse.nodered.org/t/how-to-share-code-or-flow-json/506)

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [2 March 2023 17:55 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/7 "2023-03-02T17:55:27Z")

</div>

Please add a `debug` node (set to display the complete msg object) to the output of the `mqtt-in` node then copy and paste two of the outputs of the `debug` node so we have some test data.

There’s a great page in the docs ([Working with messages : Node-RED](https://nodered.org/docs/user-guide/messages)) that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

![BX00Cy7yHi](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/d/bd1f333a9e043b061b39917c328b0094d3e52d30.gif)

---

<div class="post-metadata">

**Author:** ![Lance99](https://avatars.discourse-cdn.com/v4/letter/l/6de8d8/32.png) [@Lance99](https://discourse.nodered.org/u/Lance99)\
**Post date:** [7 March 2023 12:29 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/8 "2023-03-07T12:29:11Z")

</div>

```auto
7.3.2023, 13:28:16node: 15abe96c.a49c67
mrfdatarsp : msg.payload : array[5]
array[5]
0: object
Node ID: "C6E607CE"
Tid: "Tue Mar 07 2023 12:28:16 GMT+0000 (Coordinated Universal Time)"
RSSI: -71
TickCross: 0
Manuf: "MM"
1: object
2: object
3: object
4: object

```

When Tickcross = 0, the symbol should be RED, Tickcross = 1 means GREEN symbol.

---

<div class="post-metadata">

**Author:** ![Lance99](https://avatars.discourse-cdn.com/v4/letter/l/6de8d8/32.png) [@Lance99](https://discourse.nodered.org/u/Lance99)\
**Post date:** [7 March 2023 12:37 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/9 "2023-03-07T12:37:25Z")

</div>

```auto
[{"id":"6766777f.a1cc18","type":"function","z":"161bc1d0.dbc88e","name":"filter","func":"tableData2 = flow.get(\"savedData2\") || [];\n\ntableData2.unshift({\n \"Node ID\": msg.payload.bridgeId,\n //\"Tid\": new Date(msg.payload.timeStamp).toLocaleString(\"no-NO\"),\n \"Tid\": Date(msg.payload.timeStamp).toLocaleString(),\n \"RSSI\": msg.payload.rssi,\n \"TickCross\": msg.payload.tickcross,\n \"Manuf\": \"MM\"\n});\n\nif (tableData2.length >5) tableData2.pop();\n\nmsg.payload = tableData2;\n \nflow.set(\"savedData2\", tableData2);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":850,"y":80,"wires":[["d659ea4b.40b698"]]},{"id":"d659ea4b.40b698","type":"trigger","z":"161bc1d0.dbc88e","name":"","op1":"","op2":"","op1type":"pay","op2type":"payl","duration":"10","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":1030,"y":60,"wires":[["4c56eee1.aeb4e"]]},{"id":"4c56eee1.aeb4e","type":"ui_table","z":"161bc1d0.dbc88e","group":"1638a6ad.34a9f9","name":"Bridges","order":2,"width":"10","height":"4","columns":[{"field":"Node ID","title":"Bridge ID","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"Tid","title":"Time","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"RSSI","title":"rssi","width":"","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"TickCross","title":"Pass/Fail","width":"","align":"center","formatter":"tickCross","formatterParams":{"target":"_blank"}},{"field":"Manuf","title":"Manuf.","width":"","align":"center","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":1220,"y":60,"wires":[]},{"id":"9ed67d72.c0453","type":"json","z":"161bc1d0.dbc88e","name":"","property":"payload","action":"","pretty":false,"x":690,"y":80,"wires":[["6766777f.a1cc18"]]},{"id":"6126129a.4c810c","type":"mqtt in","z":"161bc1d0.dbc88e","name":"","topic":"","qos":"2","datatype":"auto","broker":"581bb373.5011bc","x":500,"y":80,"wires":[["9ed67d72.c0453"]]},{"id":"1638a6ad.34a9f9","type":"ui_group","name":"Signalstyrke","tab":"7cda3603.64ae68","order":1,"disp":true,"width":"12","collapse":false},{"id":"581bb373.5011bc","type":"mqtt-broker","name":"","broker":"","port":"15548","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"7cda3603.64ae68","type":"ui_tab","name":"Tabell_Test","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

```

The flow ... continious flow of incomming json objects, feed into a table of 5 rows

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [7 March 2023 13:26 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/10 "2023-03-07T13:26:26Z")

</div>

Here is how I populate a dashboard table with hostname and IP address of Linux devices alive on my network. It may be applicable to your list of sensors.

 ![Untitled 1](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/6/766af3e20f45c797085577d1951f6159293b2260.jpeg)

```auto
[{"id":"5669fc4cac1d0dfc","type":"group","z":"90fe1578c260fc2b","name":"Save info messages to context","style":{"label":true,"stroke":"#6f2fa0","fill":"#bfdbef","fill-opacity":"0.3"},"nodes":["23155ac8fea5b99d","7d726eaf71e047d0","3daf41fd05c6ea8b","7c174eceb569e8a8","c8519e227fe92b5b"],"x":14,"y":39,"w":772,"h":122},{"id":"23155ac8fea5b99d","type":"mqtt in","z":"90fe1578c260fc2b","g":"5669fc4cac1d0dfc","name":"","topic":"info/pi/#","qos":"2","datatype":"auto-detect","broker":"6acd88c889789c5c","nl":false,"rap":true,"rh":0,"inputs":0,"x":90,"y":100,"wires":[["3daf41fd05c6ea8b"]]},{"id":"7d726eaf71e047d0","type":"function","z":"90fe1578c260fc2b","g":"5669fc4cac1d0dfc","name":"Save to context","func":"var devices = flow.get(\"devices\") ?? {} // default is an empty object\nconst ip = msg.payload.ip // I want my table sorted by ip address so use it as key\nconst ts = new Date() // Timestamp message arrival\ndevices[ip] = msg.payload // Add message to object keyed by ip\ndevices[ip].timestamp = ts // Timesamp so I can identify stale messages\nflow.set (\"devices\", devices) // Save the updated context \n\nmsg.payload = devices[ip] // For debug output\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":80,"wires":[[]]},{"id":"3daf41fd05c6ea8b","type":"function","z":"90fe1578c260fc2b","g":"5669fc4cac1d0dfc","name":"Filter bad data","func":"msg.type = typeof(msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":100,"wires":[["c8519e227fe92b5b"]]},{"id":"7c174eceb569e8a8","type":"debug","z":"90fe1578c260fc2b","g":"5669fc4cac1d0dfc","name":"Bad data","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":660,"y":120,"wires":[]},{"id":"c8519e227fe92b5b","type":"switch","z":"90fe1578c260fc2b","g":"5669fc4cac1d0dfc","name":"type is Object?","property":"type","propertyType":"msg","rules":[{"t":"eq","v":"object","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":460,"y":100,"wires":[["7d726eaf71e047d0"],["7c174eceb569e8a8"]]},{"id":"6acd88c889789c5c","type":"mqtt-broker","name":"","broker":"192.168.1.11","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"broker/birth","birthQos":"2","birthPayload":"\"Connected\"","birthMsg":{},"closeTopic":"broker/close","closeQos":"2","closePayload":"\"Disconnecting\"","closeMsg":{},"willTopic":"broker/dead","willQos":"2","willPayload":"\"Disconnected\"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"75db055c564dc258","type":"group","z":"90fe1578c260fc2b","name":"Delete context variable at midnight to reset device list ","style":{"label":true,"stroke":"#6f2fa0","fill":"#dbcbe7","fill-opacity":"0.3"},"nodes":["04899783273dec1c","51c3ae80e4b0caad"],"x":14,"y":319,"w":432,"h":82},{"id":"04899783273dec1c","type":"inject","z":"90fe1578c260fc2b","g":"75db055c564dc258","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":360,"wires":[["51c3ae80e4b0caad"]]},{"id":"51c3ae80e4b0caad","type":"change","z":"90fe1578c260fc2b","g":"75db055c564dc258","name":"","rules":[{"t":"delete","p":"devices","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":360,"wires":[[]]},{"id":"733fb7b343c1f04d","type":"group","z":"90fe1578c260fc2b","name":"Construct Table","style":{"label":true,"stroke":"#92d04f","fill":"#e3f3d3","fill-opacity":"0.3"},"nodes":["222ba04e6e9a9f73","060287df849594fd","28a4d3149680d07f"],"x":14,"y":199,"w":552,"h":82},{"id":"222ba04e6e9a9f73","type":"inject","z":"90fe1578c260fc2b","g":"733fb7b343c1f04d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"20","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":240,"wires":[["060287df849594fd"]]},{"id":"060287df849594fd","type":"function","z":"90fe1578c260fc2b","g":"733fb7b343c1f04d","name":"Get from context","func":"function sortObj(obj) {\n return Object.keys(obj).sort().reduce(function (result, key) {\n result[key] = obj[key];\n return result;\n }, {});\n}\n\nlet devices = flow.get(\"devices\") ?? {} // get data from context\ndevices = sortObj(devices) // Sort it by key (IP address)\n\nlet arr = [] // Will pass an array of objects to the table\nconst now = new Date().getTime()\n\nfor (let ip in devices) { // Loop through sensors\n const age = (now - devices[ip].timestamp.getTime())/1000 // Age in seconds of the sensor report - can use to id stale records\n let rec = { // Construct object for this sensor\n \"ip\": ip,\n \"hostname\": devices[ip].hostname,\n // etc, etc\n }\n arr.push(rec) // Add it to the array\n}\n\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":240,"wires":[["28a4d3149680d07f"]]},{"id":"28a4d3149680d07f","type":"ui_table","z":"90fe1578c260fc2b","g":"733fb7b343c1f04d","group":"a29767e44538ea22","name":"Table ","order":0,"width":"9","height":"6","columns":[],"outputs":0,"cts":false,"x":490,"y":240,"wires":[]},{"id":"a29767e44538ea22","type":"ui_group","name":"Pies","tab":"75458084fdb19d21","order":1,"disp":false,"width":"30","collapse":false,"className":""},{"id":"75458084fdb19d21","type":"ui_tab","name":"Status","icon":"dashboard","disabled":false,"hidden":false}]

```

I don't use a join node, each incoming mqtt message is added/updated discretely in a context variable.  
My context variable is an object keyed by IP address rather than an array, so I can sort the data by IP.

![Untitled 2](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/4/748179cea4274e14d51516bc623b260ca85bbce0.jpeg)

ps. I don't actually know if I need to sort the context variable, maybe it will automatically come out in alphabetical order of the key?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [7 March 2023 14:14 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/11 "2023-03-07T14:14:42Z")

</div>

I have a couple questions about your flow and function node. As I understand it you are

1. receiving a json string from the `mqtt-in` node and you run it thru the `json` node to convert it to an object.  
(do you know you can set the `Output` option in the `mqtt-in` node to  
`auto-detect (parsed JSON object, string or buffer)` or  
`a parsed JSON object`  
eliminating the need for the `json` node)
2. you run it thru the `json` node to parse the JSON string into an object.
3. now it enters the `function` node  
a) you grab the flow variable 'savedData2` (an array) and add another array entry populating it with data from msg.payload. you start with

```auto
"Node ID": msg.payload.bridgeId,

```

issue 1 - msg.payload is an array so you would need to array occurrence like

```auto
"Node ID": msg.payload[0].bridgeId,

```

but `bridgeId` is not in msg.payload but there is a `Node ID` so you would have to use

```auto
"Node ID": msg.payload[0]["Node ID"]

```

issue 2 - you have several case issue with the RSSI and tickcross. Case is important!

clean that all up and see what you get. And add `debug` nodes so you can see what is going into and out of nodes, it helps in debugging.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [6 April 2023 14:14 UTC](https://discourse.nodered.org/t/table-with-5-sensors-data-with-fixed-row/75515/12 "2023-04-06T14:14:45Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
