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 ?
    9bb9f3ba-e591-4bea-862a-42a0d34f2415-image.png
    a1c86e26-e134-43bc-a278-9cc7af733709-image.png

    [{"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);
    

Log in to reply
 

Suggested Topics

12
Online

11.4k
Users

11.1k
Topics

112.7k
Posts