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);