Thanks for node-red-contrib-mysensors and a question regarding collections or arrays
-
Hi everyone,
thanks for implementing node-red-contrib-mysensors, which works great and has rejuvenated my interest in MySensors! I find it a lot more accessible compared to others controllers like HomeAssistant, with which I always had problems in implementing my own sensors mainly due to hidden raw data in HomeAss (and others), also problems with persistence (which I did not want) etc etc. Node-Red is very transparent I think, and a great way to receive and process/display MySensor data.Now I am looking into getting my dashboard dynamic. I have a couple of MySensors nodes, which are pretty identical (apart from the nodeId), sending 4 childSensorIds of interest to me, based on which I also added a msg.type (temp, humi, pres or voltage). nodeIds are hardcoded in the sketch, so this does not need handling.
What I would like to do is to show received data without any further ado, when a node is transmitting (meaning in my case when it has battery power).
A node is transmiting -> data is presented in a table.
A node is out of power -> entries are removed rsp. not shown in the table, are at least not updated anymore.
A new node is added to the network -> data is automatically appended to the table.Table data might possibly be shown via a template node, see below.
What I did not get now despite many tries is how to store the received sensor data in an array or collection, to iterate over this in the template node. I guess the strucutre would be to add an entry for every nodeId, and as "subentries" (key:values?) the type and msg.payload. All of this stored in global or flow context to be accessible by the template node.
Now, anyone might have a hint how to declare the array/collection and how to store and update the sensor data? This is what I did not get to work, see below.
Thanks everyone for any hints,
Joost
[ { "id": "97bf2754.81864", "type": "debug", "z": "654a29b5.1136", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 370, "y": 380, "wires": [] }, { "id": "10894f66.719a01", "type": "ui_template", "z": "654a29b5.1136", "group": "38e6fc1d.b2f114", "name": "", "order": 17, "width": 0, "height": 0, "format": "<div ng-bind-html=\"msg.payload\"></div>\n\n<div layout=\"row\" layout-align=\"start center\">\n <span flex>Node ID</span>\n <span flex>Temp</span>\n <span flex>Humi</span>\n <span flex>Pres</span>\n <span flex>Voltage</span>\n</div>\n<div layout=\"row\" layout-align=\"start center\" ng-repeat=\"individual_data in msg.global_individual_data\">\n <span flex style=\"color: green\">{{individual_data.node}}</span>\n <span flex style=\"color: red\">{{individual_data.node.humi}}</span>\n <span flex style=\"color: black\">{{individual_data.node.pres}}%</span>\n <span flex style=\"color: black\">{{individual_data.node.voltage}}</span>\n</div>", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, "templateScope": "local", "x": 380, "y": 340, "wires": [ [] ] }, { "id": "b98e0e8c.b686c", "type": "function", "z": "654a29b5.1136", "name": "Store nodeIDs in array", "func": "var nodeId_array=global.get(\"nodeId_array\");\nif (nodeId_array===undefined) {\n nodeId_array=[];\n}\n\nif (! nodeId_array.includes(msg.nodeId)) {\n nodeId_array.push(msg.nodeId);\n global.set(\"nodeId_array\", nodeId_array);\n}\nmsg.nodeId_array=nodeId_array;\n\n//key=msg.nodeId+\".\"+msg.type;\n//var individual_data={ \"node\":msg.nodeId, \"type\":msg.type, \"payload\":msg.payload};\nvar nodekey=msg.nodeId;var datatype=msg.type;var payload=msg.payload;\n//var individual_data={ nodekey, {datatype, payload}};\nvar ind_data=[];\nind_data.push[nodekey][datatype]=payload;\n\nvar global_individual_data=global.get(\"global_invidual_data\");\nif (global_individual_data===undefined) {\n global_individual_data={\"node\":0,\"type\":\"voltage\", \"payload\":3.3333 };\n}\n//global_individual_data.add(individual_data);\n//var nodekey=msg.nodeId;var datatype=msg.type;\n//global_individual_data[nodekey][datatype]=msg.payload;\n\nglobal.set(\"global_individual_data\",global_individual_data);\nmsg.global_individual_data=global_individual_data;\n\n//for (i=0;i<3;i++){\n//message=message+i; //add count to message\n//var newmsg={payload:message,topic:msg.topic}\n// m_out.push(newmsg);\n//return[m_out];\n\nreturn msg;\n\n//local.count +=1;\n//msg.payload=\"F2 \"+msg.payload+\" \"+local.count;\n//context.set('data',local);\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 180, "y": 340, "wires": [ [ "10894f66.719a01", "97bf2754.81864" ] ] }, { "id": "872133a5.70d8a8", "type": "function", "z": "654a29b5.1136", "name": "msg.topic according to childSensorId", "func": "switch (msg.childSensorId) {\n case 0:\n msg.topic = \"Node \" + msg.nodeId + \" Temp\";\n msg.type=\"temp\";\n break;\n case 1:\n msg.topic = \"Node \" + msg.nodeId + \" Humi\";\n msg.type=\"humi\";\n break;\n case 2:\n msg.topic = \"Node \" + msg.nodeId + \" Press\";\n msg.type=\"pres\";\n break;\n case 9:\n msg.topic = \"Node \" + msg.nodeId + \" Voltage\";\n msg.type=\"volt\";\n break;\n}\n\nvar datetimeJC = new Date();\nmsg.timestampJC = datetimeJC.getHours() + \":\" + ('00' + datetimeJC.getMinutes()).slice(-2);\n\nreturn msg;\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 190, "y": 260, "wires": [ [ "b359fbb4.3b12f", "b98e0e8c.b686c" ] ] }, { "id": "ce62c592.b3c958", "type": "switch", "z": "654a29b5.1136", "name": "Filter childSensorIds", "property": "childSensorId", "propertyType": "msg", "rules": [ { "t": "eq", "v": "0", "vt": "str" }, { "t": "eq", "v": "1", "vt": "str" }, { "t": "eq", "v": "2", "vt": "str" }, { "t": "eq", "v": "9", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 4, "x": 240, "y": 140, "wires": [ [ "872133a5.70d8a8" ], [ "872133a5.70d8a8" ], [ "872133a5.70d8a8" ], [ "872133a5.70d8a8" ] ] }, { "id": "2434c5bc.48688a", "type": "mysdecode", "z": "654a29b5.1136", "database": "", "name": "", "mqtt": false, "enrich": false, "x": 290, "y": 40, "wires": [ [ "3d2bf478.a96f2c", "ce62c592.b3c958" ] ] }, { "id": "d8a0a27c.b28218", "type": "serial in", "z": "654a29b5.1136", "name": "", "serial": "65ccd652.db113", "x": 70, "y": 40, "wires": [ [ "2434c5bc.48688a" ] ] }, { "id": "38e6fc1d.b2f114", "type": "ui_group", "z": "", "name": "Default", "tab": "d3c44e8c.f5c748", "order": 1, "disp": true, "width": "8", "collapse": true }, { "id": "65ccd652.db113", "type": "serial-port", "z": "", "serialport": "/dev/ttyUSB0", "serialbaud": "38400", "databits": "8", "parity": "none", "stopbits": "1", "waitfor": "", "dtr": "none", "rts": "none", "cts": "none", "dsr": "none", "newline": "\\n", "bin": "false", "out": "char", "addchar": "", "responsetimeout": "10000" }, { "id": "d3c44e8c.f5c748", "type": "ui_tab", "z": "", "name": "JC_Dashboard", "icon": "dashboard", "disabled": false, "hidden": false } ] -
PS: this here
var nodekey=msg.nodeId;var datatype=msg.type;var payload=msg.payload; //var individual_data={ nodekey, {datatype, payload}}; var ind_data=[]; ind_data.push[nodekey][datatype]=payload; var global_individual_data=global.get("global_invidual_data"); if (global_individual_data===undefined) { global_individual_data={"node":0,"type":"voltage", "payload":3.3333 }; } //global_individual_data.add(individual_data); //var nodekey=msg.nodeId;var datatype=msg.type; //global_individual_data[nodekey][datatype]=msg.payload; global.set("global_individual_data",global_individual_data); msg.global_individual_data=global_individual_data;is just my last non-working attempt and probably way way off (I know ind_data is not added to global_individual_data in there at this point); I have tried innumerable variations before with no success. I am pretty lost here...
Debug log right now:
10/25/2020, 8:52:05 AMnode: Store nodeIDs in arrayfunction : (error) "TypeError: Cannot set property 'humi' of undefined" 10/25/2020, 8:52:05 AMnode: Store nodeIDs in arrayfunction : (error) "TypeError: Cannot set property 'pres' of undefined" 10/25/2020, 8:52:05 AMnode: Store nodeIDs in arrayfunction : (error) "TypeError: Cannot set property 'volt' of undefined" -
Ok, with this I can at least create an individual data point object:
var ind_data={}; ind_data.nodeid=msg.nodeId; ind_data.type=msg.type; ind_data.payload=msg.payload; var global_individual_data=global.get("global_invidual_data"); if (global_individual_data===undefined) { global_individual_data={}; } global_individual_data.push(ind_data);But "pushing" this on to global_individual_data gives me an error. How could I store those indivudal objects in global context and iterate over them in a template node?
-
Hi @Joost
did you try with the node-red-node-ui-table ?


[{"id":"7bd456cb.117438","type":"ui_table","z":"9e0024db.fa0ee8","group":"db0ce087.cc771","name":"","order":3,"width":0,"height":0,"columns":[],"outputs":0,"cts":false,"x":660,"y":4380,"wires":[]},{"id":"5766ed81.1001b4","type":"function","z":"9e0024db.fa0ee8","name":"","func":"msg.payload=[\n {\n \"Name\": \"Kazuhito Yokoi\",\n \"Age\": \"35\",\n \"Favourite Color\": \"red\",\n \"Date Of Birth\": \"12/09/1983\",\n \"Rating\": 5\n },\n {\n \"Name\": \"Oli Bob\",\n \"Age\": \"12\",\n \"Favourite Color\": \"red\",\n \"Date Of Birth\": \"12/08/2017\",\n \"Rating\": 2\n }\n]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":530,"y":4380,"wires":[["7bd456cb.117438"]]},{"id":"96793ea3.29b8b","type":"inject","z":"9e0024db.fa0ee8","name":"msg","props":[{"p":"nodeId","v":"3","vt":"str"},{"p":"payload"},{"p":"port","v":"com66","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"-666","payloadType":"str","x":390,"y":4380,"wires":[["5766ed81.1001b4"]]},{"id":"db0ce087.cc771","type":"ui_group","name":"log","tab":"db35bd74.691fe","order":1,"disp":true,"width":"12","collapse":false},{"id":"db35bd74.691fe","type":"ui_tab","name":"MySensors","icon":"dashboard","order":1,"disabled":false,"hidden":false}] -
HI, thanks, I guess right now the problem lies in the data storage in global or flow context.
With this I can build the individual obejct, and pushing it on a global array gives no error. But the array is not properly stored and retrieved from the global context:var ind_data={}; ind_data.nodeid=msg.nodeId; ind_data.type=msg.type; ind_data.payload=msg.payload; var global_individual_data=global.get("global_invidual_data"); if (global_individual_data===undefined) { msg.kein_array_vorhanden="true" global_individual_data=[]; } global_individual_data.push(ind_data); global.set("global_individual_data",global_individual_data); -
This seems to evaluate to true/undefined every time, effectively resetting the array:
var global_individual_data=global.get("global_invidual_data"); if (global_individual_data===undefined) { msg.kein_array_vorhanden="true" global_individual_data=[]; }even though it's later set with
global.set("global_individual_data",global_individual_data);
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login