Node-red error : help

I’ve installed a new pi3 with thethingbox as I didn’t want to fool to much on the emoncms pi and node-red.
As I don’t know much about coding and even less nodes and reds :wink:

I found a node that would make it possible to read my Victron solar regulator/controller (the box does it all in short) and send it to my cms.
The script can be found at this url
Installing the node was easy enough and activating it even easier but it spits out an error and I can’t seem to find the bug …

the error it spits

Build EmonCMS url
function : (error)
TypeError: Cannot assign to read only property ‘_msgid’ of diff = 8.733999967575073

I went in the Build EmonCMS url but couldn’t find much to solve. Think there is a “;” to much on a line but that didn’t solve the issue …
Tried reading around and also found some code allowing to make diff writable but …

I think the connection with the victron is ok as I see a green ‘light"’ next to that tab but as it is spitting so many errors I can’t even look at the different debug tabs … it is a continuous flow …

Before trying to contact the scripter, is there an expert around here that could have a look at the code from the Build EmonCMS tab and advice a solution / hint at what could be wrong ?

I know this isn’t the easiest script to start with node-red :innocent:
thanks

I would suggest the easiest route would be to raise a git issue with the script author…

Paul

Export the flow to the clipboard and then post the flow here. It seems like a function node is doing something similar to:
msg._msgid = n.nnnnnn;

but that’s a bit of a wild guess on my part…

And “yes”, you are suppose to start with “Hello World” and work your way up to regulator/controllers talking to emoncms!! :wink:

I know I should start with ‘hello’ but … I love to do things backwards starting with just installing existing things and then slowly learn via trouble shooting. I hate to code around ‘nothing’ …

this is the code in Build EmonCMS tab

// The received message is stored in ‘msg’
// It will have at least a ‘payload’ property:
// console.log(msg.payload);
// The ‘context’ object is available to store state
// between invocations of the function
// context = {};

//expects JSON payload and destination specified in topic
var diff = 0;
if(context.lastrun !== undefined){

diff = (new Date()/1000) - context.lastrun;

if(diff < 10)
{
bla = "diff = " + diff;
return [null,bla]
}
}

context.lastrun = new Date()/1000;

var key = “EMONCMS API KEY”;

//destination will be last part node of topic
var values = JSON.stringify(msg.values);
var node = msg.node;
//console.log(values);

if(isNaN(node))
{
//not a valid destination
return null;
}

msg.url =“http://emoncms.org/input/post.json?node=”;
msg.url += node;
msg.url += “&json=”;
msg.url += values;
msg.url += “&apikey=”;
msg.url += key;

if(msg.timestamp !== undefined){
msg.url += “&time=”+msg.timestamp
}else{
msg.url += “&time=”+Math.floor(Date.now() / 1000)
}
//console.log(msg.url);

return [msg ,"posted: " +diff];

I guess that I also need to insert in this bit my write api and change the url ? though I found another tab HTTP GET to EmonCMR.org linked just behind it with this … that should allow to send to my server but then there is no write api to add …

guess I’ll have to learn code after all … :sweat:

no worries - I started the same way. I started the “hello world” and then quickly dozed off. I needed something real to get started.

What you posted is helpful and I see an error or two where Objects are getting confused with Strings. If you’re sending to emoncms the msg.payload is a String and msg is the Object. The return [null,bla] is returning a bla as an Object when it should be a string. Not too confusing, eh?!?
Read thru this for an example → http://nodered.org/docs/getting-started/first-flow

Paste the entire Flow by Exporting the code using these steps:

  • go to the Tab with your Flow
  • Select all of the items in the node
  • Click on the hamburger menu (upper right)
  • click on Export
  • click on Clipboard
  • then copy the code (highlighted in blue for me) and paste it into a post.
     

 

wanted to avoid to paste all these lines as it is on this page : victron_thethingbox/node-red_paste at master · liaan/victron_thethingbox · GitHub

but here you go for the export. I was able between the flow of error to see some debug tabs with indeed results from my victron. So it is getting data … it is just that the url build thing is messy. What I do understand is that it cycles around 10 seconds and after that it really posts to the server instead posting every second as it can on a local branch (i deleted those tabs)

[
    {
        "id": "3e72b989.c18d46",
        "type": "serial in",
        "z": "c4a05491.3b5fa8",
        "name": "Mk2",
        "serial": "37f5231a.c80adc",
        "x": 56,
        "y": 743.7142601013184,
        "wires": [
            [
                "1354798f.ecab86",
                "d2f7fbd5.2d0808"
            ]
        ]
    },
    {
        "id": "1354798f.ecab86",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 222.28570938110352,
        "y": 794.2856817245483,
        "wires": []
    },
    {
        "id": "e6aec800.195138",
        "type": "inject",
        "z": "c4a05491.3b5fa8",
        "name": "Get Led Status",
        "topic": "",
        "payload": "L",
        "payloadType": "string",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 145.7142448425293,
        "y": 172,
        "wires": [
            [
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "1bcf635a.e4309d",
        "type": "template",
        "z": "c4a05491.3b5fa8",
        "name": "Make Packet",
        "field": "payload",
        "fieldType": "msg",
        "syntax": "mustache",
        "template": "{{#leds}}\n\n{{name}} is {{status}}\n\n{{/leds}}",
        "x": 1007.5715522766113,
        "y": 574.2856750488281,
        "wires": [
            [
                "79ed8398.86127c"
            ]
        ]
    },
    {
        "id": "d2f7fbd5.2d0808",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Decode MK2 String",
        "func": "\ncommand = String.fromCharCode(msg.payload[2]);\n\nchecksum = 0;\n\nfor (i=0;i<msg.payload.length;i++){\n  checksum = (checksum + msg.payload.readInt8(i))%0x100 ;\n}\nmsg.checksum = checksum\nif(checksum != 0){\n\treturn null\n}\n\nif(msg.payload[1] == 255){ \n\tswitch (command){\n\t\tcase \"L\": //LED Status\n\t\t\t\n\t\t\tmsg.type = 1;\t\t\n\t\t\tmsg.value = [msg.payload[3],msg.payload[4]];\n\t\t\t\n\t\tbreak;\n\t\tcase 'V': // Version\n\t\t  \n\t\t  msg.type = 2;\n\t\t  \n\t\t \n\t\tbreak;\n\t\tcase 'F':\t\t\n\t\t\tmsg.type = 3;\n\t\t\t\n\t\tbreak;\n\t\tdefault:\n\t\t\tmsg.type=0;\n\t\tbreak;\n\t}\n\treturn [msg,null,msg]\n}\n\n//Info Frame\nif(msg.payload[1] == 0x20){\n\t\n\treturn [null,msg,msg];\t\n}\n\n\n",
        "outputs": "3",
        "x": 257.00000381469727,
        "y": 743.9999794960022,
        "wires": [
            [
                "2fd3c918.d02c36"
            ],
            [
                "25ffb974.da0046"
            ],
            [
                "d86b0698.2794f8"
            ]
        ]
    },
    {
        "id": "3e6baed2.c19452",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 661.6507759094238,
        "y": 613.0635375976562,
        "wires": []
    },
    {
        "id": "2fd3c918.d02c36",
        "type": "switch",
        "z": "c4a05491.3b5fa8",
        "name": "Switch MK2 packet type",
        "property": "type",
        "rules": [
            {
                "t": "eq",
                "v": "1"
            },
            {
                "t": "eq",
                "v": "0"
            }
        ],
        "checkall": "true",
        "outputs": 2,
        "x": 473.5873603820801,
        "y": 649.15869140625,
        "wires": [
            [
                "3e6baed2.c19452",
                "ae5b514a.51a4b"
            ],
            [
                "8220443.f7ddfb8"
            ]
        ]
    },
    {
        "id": "79ed8398.86127c",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "false",
        "x": 1181.1428413391113,
        "y": 577.7142944335938,
        "wires": []
    },
    {
        "id": "ae5b514a.51a4b",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Mk2: Decode LED String",
        "func": "var leds = Array();\n\nleds[0] = {\n\tname : 'Mains',\n\tstatus : 0\n}\nleds[1] = {\n\tname : 'Absorpion',\n\tstatus : 0\n}\nleds[2] ={\n\tname : 'Bulk',\n\tstatus : 0\n}\nleds[3] = {\n\tname : 'Float',\n\tstatus : ''\n}\nleds[4] = {\n\tname : 'Inverter',\n\tstatus : ''\n}\nleds[5] = {\n\tname : 'Overload',\n\tstatus : ''\n}\nleds[6] = {\n\tname : 'Low Battery',\n\tstatus : ''\n}\nleds[7] = {\n\tname : 'Temperature',\n\tstatus : ''\n}\n\ndecode_on_off (msg.value[0])\ndecode_blinking(msg.value[1])\n\n//Assign LED array\nmsg.leds = leds;\n\n\n//Return\nreturn msg;\n\n\n/*\n* Decode LED on Off\n* \n*/\nfunction decode_on_off(value){\n\n\tfor(i=0;i<8;i++){\n\t\tleds[i]['status'] = (value & 1<<i)?'On':'Off';\n\t\tleds[i]['status_id'] = (value & 1<<i)?1:0;\n\t}\t\t\t\n\n\t\n}\n\n/*\n* Decode Blinking State\n*/\nfunction decode_blinking(value){\n\n\tfor(i=0;i<8;i++){\n\t\n\t\t (value & 1<<i) ? (leds[i]['status'] = 'Blinking'):'';\n\t\t (value & 1<<i) ? (leds[i]['status_id'] = 2):'';\t\t\n\t}\t\t\t\n\n}\n",
        "outputs": 1,
        "x": 736.3333930969238,
        "y": 659.8729858398438,
        "wires": [
            [
                "1bcf635a.e4309d",
                "6c74e91.f938b18"
            ]
        ]
    },
    {
        "id": "2a68d702.d59728",
        "type": "inject",
        "z": "c4a05491.3b5fa8",
        "name": "Get AC/DC/LED Info State",
        "topic": "0",
        "payload": "F",
        "payloadType": "none",
        "repeat": "0.2",
        "crontab": "",
        "once": false,
        "x": 176.80946731567383,
        "y": 425.25396728515625,
        "wires": [
            [
                "739dcc7e.8c6234"
            ]
        ]
    },
    {
        "id": "da892a11.2576d8",
        "type": "inject",
        "z": "c4a05491.3b5fa8",
        "name": "Get MasterLED State",
        "topic": "5",
        "payload": "F",
        "payloadType": "string",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 157.80949783325195,
        "y": 217.53968811035156,
        "wires": [
            [
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "8220443.f7ddfb8",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "Unkown Frame",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 593.5714302062988,
        "y": 721.1428833007812,
        "wires": []
    },
    {
        "id": "ea75361f.158ac8",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 916.5714302062988,
        "y": 752.1428833007812,
        "wires": []
    },
    {
        "id": "6c74e91.f938b18",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "LED to emoncms",
        "func": "var bla = {};\nvar newMsg = {};\nnewMsg.values = make_emoncms(msg.leds)\n\n//bla.nodegroup = \"ab\";\n//msg = bla;\nnewMsg.node = 0;\nnewMsg.packet_type = 3;\n\nreturn newMsg;\n\nfunction make_emoncms(leds){\n\t//var payload = \"1\";\n\tvar payload = {};\n\t//payload2 = {};\n\t\n\tleds.forEach(function (byte,index) {\n\t\t\n\t\tvar color = 10;\n\t\tswitch (byte.status_id)\n\t\t{\n\t\t\tcase 0: //off\n\t\t\t color = 10 //green\n\t\t\t break;\n\t\t\tcase 1://on\n\t\t\t  color=1\n\t\t\t break;\n\t\t\tcase 2://blink\n\t\t\t  color = 4\n\t\t\t  break\n\t\t\tdefault:\n\t\t\t color = 5\n\t\t\t break;\n\t\t}\n     // payload += ','+[byte.name]+':'+color\n\t  payload[byte.name] = color\n\t  \n\t})\n\treturn payload;\n\t//return JSON.stringify(payload);\n}",
        "outputs": 1,
        "x": 789.5714302062988,
        "y": 814.1428833007812,
        "wires": [
            [
                "ea75361f.158ac8",
                "d46a9f17.2b956"
            ]
        ]
    },
    {
        "id": "25ffb974.da0046",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Decode Info Frame",
        "func": "try{\nvar packet = Array();\nvar phase = msg.payload[2+4];\n\nswitch (phase){\n\tcase 0x0C: //DC\n\t\t//msg.values = decode_dc();\n\t\tmsg.type = 1;\n\t\tmsg.run = 'DC';\n\tbreak;\n\tcase 0x08: //AC L1\n\t\t//msg.values = decode_ac();\n\t\tmsg.run = 'ac';\n\t\tmsg.type = 2;\n\tbreak;\n\tdefault:\n\t\tmsg.run = 'Unkown packet'+ phase.charCodeAt(0);\n\tbreak;\n}\n\nreturn msg;\n\n\n}catch(e){\n\tconsole.log(e);\n\treturn msg;\n}",
        "outputs": 1,
        "x": 400.2856864929199,
        "y": 963.0000324249268,
        "wires": [
            [
                "b6e29220.491d7",
                "a47e5d1e.5b81a"
            ]
        ]
    },
    {
        "id": "b6e29220.491d7",
        "type": "switch",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "property": "type",
        "rules": [
            {
                "t": "eq",
                "v": "1"
            },
            {
                "t": "eq",
                "v": "2"
            }
        ],
        "checkall": "true",
        "outputs": 2,
        "x": 581.1428337097168,
        "y": 961.5714340209961,
        "wires": [
            [
                "afe5f9d5.501a08"
            ],
            [
                "4671b523.b98e4c"
            ]
        ]
    },
    {
        "id": "4671b523.b98e4c",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Decode AC Frame",
        "func": "try {  \n\nmsg.values = decode_ac(msg.payload);\nmsg.type = 'Inverter AC'\nmsg.node = 1;\nmsg.packet_type = 2;\nreturn msg;\nfunction decode_ac(packet){\n\tvar ac = {\t\n\t\tbf_factor: packet.readInt8(2+0)\n\t    ,inverter_factor: packet.readUInt8(2+1)\n\t    ,mains_volt: packet.readInt16LE(2+5)/100\n\t\t,mains_current : packet.readInt16LE(2+7)/100 //((packet[2+7])+(packet[2+8]*255))/100\n\t\t,inverter_voltage : packet.readInt16LE(2+9)/100 //((packet[2+9])+(packet[2+10]*255))/100\n\t\t,inverter_current : packet.readInt16LE(2+11)/100 // ((packet[2+11])+(packet[2+12]*255))/100\n\t\t,mains_period : 10/(packet.readUInt8(2+13)*0.0010235414534288639)\n\t\t\n\t}\n\t\n\tac['mains_watts'] = (ac.mains_current * ac.mains_volt * ac.bf_factor);\n\tac['inverter_watts'] = (ac.inverter_voltage * ac.inverter_current * ac.inverter_factor);\n\tac['InverterWattsOut'] = ac['inverter_watts'] \n\t\n\treturn ac;\n}\n}catch(e){\nconsole.log(e)\n}",
        "outputs": 1,
        "x": 789.1428413391113,
        "y": 1072.5714111328125,
        "wires": [
            [
                "d46a9f17.2b956",
                "f0221e51.0fdde"
            ]
        ]
    },
    {
        "id": "afe5f9d5.501a08",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Decode DC Frame",
        "func": "try {\n\n\n\nmsg.values = decode_dc(msg.payload)\nmsg.type = 'Inverter DC'\nmsg.node = 1;\nmsg.packet_type = 1;\nreturn msg;\n\nfunction decode_dc(packet){\n\tvar dc = {\n\t\t\n\t\tbat_volt: packet.readInt16LE(2+5)/100 //cket[2+5])+packet[2+6]*255)/100\n\t\t,bat_current_used :  ((packet[2+7])+(packet[2+8]*255)+(packet[2+9]*255*255))/10\n\t\t,bat_current_charge : ((packet[2+10])+(packet[2+11]*255)+(packet[2+12]*255*255))/10\n\t\t,bat_inverter_period : 10/((packet.readUInt8(2+13)+256)*0.0005099)\n\t\t\n\t}\n\t\n\tdc['bat_watts'] = (dc.bat_current_used * dc.bat_volt);\n\tdc['bat_charge_watts'] = (dc.bat_current_charge * dc.bat_volt);\n\t\n\treturn dc;\n}\n\n\n\n}\ncatch(e){\nconsole.log(e)\n}\n",
        "outputs": 1,
        "x": 787.1428413391113,
        "y": 890.5714111328125,
        "wires": [
            [
                "79aef29c.86510c",
                "d46a9f17.2b956"
            ]
        ]
    },
    {
        "id": "a47e5d1e.5b81a",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 560.2856864929199,
        "y": 1082.4285488128662,
        "wires": []
    },
    {
        "id": "ac45aed5.53ba5",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Build EmonCMS url",
        "func": "// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n//   console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n//   context = {};\n\n//expects JSON payload and destination specified in topic\nvar diff = 0;\nif(context.lastrun !== undefined){\n\n\tdiff = (new Date()/1000) - context.lastrun;\n\n\tif(diff < 10)\n\t{\n\t\tbla = \"diff = \" + diff;\n\t\treturn [null,bla]\n\t}\n}\n\ncontext.lastrun = new Date()/1000;\n\nvar key = \"emoncms api key\";\n\n//destination will be last part node of topic\nvar values = JSON.stringify(msg.values);\nvar node = msg.node;\n//console.log(values);\n\nif(isNaN(node))\n{\n//not a valid destination\nreturn null;\n}\n\nmsg.url =\"https://wouters.fr/emon/input/post.json?node=\";\nmsg.url += node;\nmsg.url += \"&json=\";\nmsg.url += values;\nmsg.url += \"&apikey=\";\nmsg.url += key;\n\nif(msg.timestamp !== undefined){\n\tmsg.url += \"&time=\"+msg.timestamp\n}else{\n\tmsg.url += \"&time=\"+Math.floor(Date.now() / 1000)\n}\n//console.log(msg.url);\n\nreturn [msg ,\"posted: \" +diff];",
        "outputs": "2",
        "noerr": 0,
        "x": 1285.8928413391113,
        "y": 894.0714721679688,
        "wires": [
            [
                "aa426571.55bd98",
                "9b604af9.649fb8"
            ],
            [
                "5a59ec21.a5a614"
            ]
        ]
    },
    {
        "id": "aa426571.55bd98",
        "type": "http request",
        "z": "c4a05491.3b5fa8",
        "name": "HTTP GET to EmonCMS.org",
        "method": "GET",
        "ret": "txt",
        "url": "",
        "tls": "",
        "x": 1536.8095893859863,
        "y": 815.8214721679688,
        "wires": [
            [
                "b20c8df.f4df37"
            ]
        ]
    },
    {
        "id": "b20c8df.f4df37",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "EmonCMS HTTP Request Result",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 1846.8095703125,
        "y": 821.6548461914062,
        "wires": []
    },
    {
        "id": "79aef29c.86510c",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 828.1428413391113,
        "y": 961.3214721679688,
        "wires": []
    },
    {
        "id": "1d1b53c6.e2e4ac",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "EmonCMS URL",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 1745.3928413391113,
        "y": 889.3214721679688,
        "wires": []
    },
    {
        "id": "9b604af9.649fb8",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Debug EmonCMS URL",
        "func": "// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n//   console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n//   context = {};\n\n\nreturn msg.url;",
        "outputs": 1,
        "noerr": 0,
        "x": 1529.1428413391113,
        "y": 898.0714721679688,
        "wires": [
            [
                "1d1b53c6.e2e4ac"
            ]
        ]
    },
    {
        "id": "2df41437.d20bec",
        "type": "serial out",
        "z": "c4a05491.3b5fa8",
        "name": "Mk2_out",
        "serial": "37f5231a.c80adc",
        "x": 1092.8571434020996,
        "y": 181.1428508758545,
        "wires": []
    },
    {
        "id": "2525bb02.dada44",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 1024.698398590088,
        "y": 248.74605178833008,
        "wires": []
    },
    {
        "id": "f1166d35.0ee99",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Make Command",
        "func": "\ncmd = msg.payload;\ncmd = cmd.charCodeAt(0);\ndata = msg.topic\n\nvar packet = [];\npacket.push(0xff);\npacket.push(cmd);\nif(data !==''){\n\tpacket.push(data);\n}\n\nlength = packet.length;\n//Add Length to begining\npacket.unshift(length)\n//Calculate Checksum\nchecksum = 0;\n\npacket.forEach(function (byte) {\n  checksum -= byte;\n}) \n\n//checksum = 0xB3;\n\n\n//Add Checksum to end\npacket.push(checksum);\n\n\n//Make it a Buffer and assign to payload\nmsg.payload = new Buffer(packet,'hex');\n\n\nreturn [msg];",
        "outputs": "1",
        "x": 821.0000190734863,
        "y": 204.42856216430664,
        "wires": [
            [
                "2525bb02.dada44",
                "2df41437.d20bec"
            ]
        ]
    },
    {
        "id": "9460a65b.6b9f58",
        "type": "change",
        "z": "c4a05491.3b5fa8",
        "name": "DC",
        "action": "replace",
        "property": "topic",
        "from": "",
        "to": "0",
        "reg": false,
        "x": 328.3968391418457,
        "y": 291.50794982910156,
        "wires": [
            [
                "61e6f000.9e191"
            ]
        ]
    },
    {
        "id": "61e6f000.9e191",
        "type": "delay",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "pauseType": "delay",
        "timeout": "150",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 470.1111030578613,
        "y": 290.7936553955078,
        "wires": [
            [
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "d72ad86.f28d528",
        "type": "change",
        "z": "c4a05491.3b5fa8",
        "name": "AC",
        "action": "replace",
        "property": "topic",
        "from": "",
        "to": "1",
        "reg": false,
        "x": 327.5396614074707,
        "y": 249.65081024169922,
        "wires": [
            [
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "d86b0698.2794f8",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "checksum",
        "x": 448.2856636047363,
        "y": 873,
        "wires": []
    },
    {
        "id": "9e8d829.f61728",
        "type": "change",
        "z": "c4a05491.3b5fa8",
        "name": "LED",
        "action": "replace",
        "property": "payload",
        "from": "",
        "to": "L",
        "reg": false,
        "x": 326.3967475891113,
        "y": 337.22222900390625,
        "wires": [
            [
                "e561e1cf.1a9e2"
            ]
        ]
    },
    {
        "id": "e561e1cf.1a9e2",
        "type": "delay",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "pauseType": "delay",
        "timeout": "350",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 469.3967475891113,
        "y": 338.22222900390625,
        "wires": [
            [
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "d46a9f17.2b956",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Merge Packets",
        "func": "\n//Set defaults if not set yet\nif(context.dc === undefined){\n\tcontext.dc = false;\n}\nif(context.led === undefined){\n\tcontext.ac = false;\n}\nif(context.packet === undefined){\n\tcontext.packet = {};\n}\nif(context.led === undefined){\n\tcontext.led = false;\n}\n\nif(msg.packet_type === 1){\n\n\tcontext.dc = true;\n}\n\nif (msg.packet_type === 2){\n\tcontext.ac = true;\n}\nif (msg.packet_type === 3){\n\tcontext.led = true;\n}\n\n\nObject.keys(msg.values).forEach(function(key) {\n  \t\tcontext.packet[key] = msg.values[key];\n\n});\n\n\n\nif(context.dc && context.ac && context.led){\n\t//var newMsg = { values: context.packet }\n    msg.values = context.packet;\n    context.ac = false;\n    context.dc = false;\n    delete context.packet;\n    \n\treturn msg;\n}else {\n\treturn [null]\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1152.2856636047363,
        "y": 1016,
        "wires": [
            [
                "661d2d37.99e2d4",
                "ac45aed5.53ba5"
            ]
        ]
    },
    {
        "id": "661d2d37.99e2d4",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 1324.2856636047363,
        "y": 1018,
        "wires": []
    },
    {
        "id": "5a59ec21.a5a614",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 1499.2856636047363,
        "y": 984,
        "wires": []
    },
    {
        "id": "739dcc7e.8c6234",
        "type": "function",
        "z": "c4a05491.3b5fa8",
        "name": "Next Packet",
        "func": "delete msg.payload;\nif(context.count == undefined || context.count 3){\n\tcontext.count = 1\n}\nif(context.running == undefined){\n\tcontext.running = false;\n}\n//if already running, return .\nif(context.running === true){\n\treturn [null]\n}\ncontext.running = true;\n// AC\nif(context.count === 1){\n\tmsg.topic = 1;\n\tmsg.payload = \"F\";\n\t\n}\n//DC\nif(context.count === 2){\n\tmsg.topic = 0;\n\tmsg.payload = \"F\";\n\t\n}\nif(context.count === 3){\n\tmsg.topic = '';\n\tmsg.payload = \"L\";\n\t\n}\n\ncontext.count += 1\ncontext.running = false;\nreturn msg;",
        "outputs": 1,
        "x": 408.50786209106445,
        "y": 424.2221984863281,
        "wires": [
            [
                "c798b240.38675",
                "f1166d35.0ee99"
            ]
        ]
    },
    {
        "id": "c798b240.38675",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 570.5078926086426,
        "y": 424.1111145019531,
        "wires": []
    },
    {
        "id": "74f3b87b.8b0c48",
        "type": "inject",
        "z": "c4a05491.3b5fa8",
        "name": "Manual Trigger",
        "topic": "",
        "payload": "F",
        "payloadType": "string",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 147.28566360473633,
        "y": 298,
        "wires": [
            [
                "d72ad86.f28d528",
                "9460a65b.6b9f58",
                "9e8d829.f61728"
            ]
        ]
    },
    {
        "id": "f0221e51.0fdde",
        "type": "debug",
        "z": "c4a05491.3b5fa8",
        "name": "",
        "active": false,
        "console": "false",
        "complete": "true",
        "x": 823.2856636047363,
        "y": 1011,
        "wires": []
    },
    {
        "id": "37f5231a.c80adc",
        "type": "serial-port",
        "serialport": "/dev/ttyUSB0",
        "serialbaud": "2400",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "newline": "85",
        "bin": "bin",
        "out": "time",
        "addchar": true
    }
]

Wow! You did start BIG! I’d suggest breaking this into smaller parts.

Learn how to write data to emoncms first. Copy a few nodes (like the ones above) into a new Flow (new tab). Send some pretend data to a emoncms Node (I usually pick on Node 13 as my test node). Once you figure out that side you may want to download the emoncms node that Glyn helped debug (or maybe helped create) . This might make things easier (or not!!).

I am guessing the above error (your first post) is related to returning strings instead of objects. I made a couple of changes to the Build EmonCMS url function node. This is untested.

// The received message is stored in 'msg'
// It will have at least a 'payload' property:
//   console.log(msg.payload);
// The 'context' object is available to store state
// between invocations of the function
//   context = {};

//expects JSON payload and destination specified in topic
msg2 = {};
var diff = 0;
if(context.lastrun !== undefined){

	diff = (new Date()/1000) - context.lastrun;

	if(diff < 10)
	{
		bla = "diff = " + diff;
		msg2.payload = bla;
		return [null,msg2];
	}
}

context.lastrun = new Date()/1000;

var key = "emoncms api key";

//destination will be last part node of topic
var values = JSON.stringify(msg.values);
var node = msg.node;
//console.log(values);

if(isNaN(node))
{
//not a valid destination
return null;
}

msg.url ="https://wouters.fr/emon/input/post.json?node=";
msg.url += node;
msg.url += "&json=";
msg.url += values;
msg.url += "&apikey=";
msg.url += key;

if(msg.timestamp !== undefined){
	msg.url += "&time="+msg.timestamp;
}else{
	msg.url += "&time="+Math.floor(Date.now() / 1000);
}
//console.log(msg.url);

msg2.payload = "posted: " +diff;
return [msg ,msg2];

first test and I get data in my emoncms … :joy:

Yes this is quite a big flow but it was finding this that made me decide to buy another pi and play with node-red … for sure other things will follow as I hopefully learn more and more

Jon a GREAT THANK YOU

I did the same with a separate RasPi. It makes testing & debugging much easier! Glad it helped - have fun!

oops talked to soon, well yes/no am I clear lol

I get the data in my feeds on my cms but the node-red still generates this error

function : (error)
TypeError: Cannot assign to read only property ‘_msgid’ of https://wouters.fr/emon/input/post.json?node=1&json={“Mains”:10,“Absorpion”:10,“Bulk”:10,“Float”:10,“Inverter”:1,“Overload”:10,“Low Battery”:10,“Temperature”:10,“bf_factor”:1,“inverter_factor”:1,“mains_volt”:235.54,“mains_current”:0,“inverter_voltage”:237.96,“inverter_current”:0.39,“mains_period”:50.1025641025641,“mains_watts”:0,“inverter_watts”:92.8044,“InverterWattsOut”:92.8044,“bat_volt”:25.76,“bat_current_used”:1.2,“bat_current_charge”:0,“bat_inverter_period”:50.02981777139175,“bat_watts”:30.912,“bat_charge_watts”:0}&apikey=apikeyhere&time=1472318354
2

just to help me understand - it added all of the data (see below) to your emoncms but you still get the error?

"Mains": 10,
"Absorpion": 10,
"Bulk": 10,
"Float": 10,
"Inverter": 1,
"Overload": 10,
"Low Battery": 10,
"Temperature": 10,
"bffactor": 1,
"inverter_factor": 1,
"mains_volt": 235.54,
"mains_current": 0,
"inverter_voltage": 237.96,
"inverter_current": 0.39,
"mains_period": 50.1025641025641,
"mains_watts": 0,
"inverter_watts": 92.8044,
"InverterWattsOut": 92.8044,
"bat_volt": 25.76,
"bat_current_used": 1.2,
"bat_current_charge": 0,
"bat_inverter_period": 50.02981777139175,
"bat_watts": 30.912,
"bat_charge_watts": 0

also - where did you see this error. Is it in the debug window to the right? or in the node-red log file? or?

as said the weird thing is that the data is published to my cms but in no-red debug console I still get this message regarding read only variable or something like that (still trying to understand all this new stuff to me)

please post a screen shot of the entire error (or of the entire screen). something like this (but with your error):

ok, guess your change of code has to be reflected in the next tab Debug EmonCMS URL.
basically it is there that the new error is throw …

there is just 1 line in there

return msg.url;

and requested image

Ahhh! This helps big time!

Let me finish up talking with my little sister and I’ll be back.

In the original Debug EmonCMS URL there is basically nothing - I am guessing it wasn’t completed.
 

 

it should be something more like this below. Again this is not tested.

msg.payload = msg.url;
return msg;

 

EDIT: You may want to just quickly delete the connection (the grey line) to the Debug EmonCMS URL node. That will work also.

indeed I could have thought about just disconnecting the tab lol.
Now I have a working flow thanks for that.
Next step, duplicate and go fiddle in it to see how all theses nodes interact and slowly learn the language.
Once again thanks Jon

Going to post the result with the script owner so others can use it also

Eric - Something to keep in mind as you learn. Some of the code in victron_thethingbox code should eventually be updated. Though I would not suggest doing this first :wink:

Node-RED has changed how data is stored. Read through this section —> http://nodered.org/docs/writing-functions#storing-data

In the sample below the context.lastrun becomes context.get('lastrun') for getting the lastrun data. And becomes context.set('lastrun',YourValue) for setting the lastrun data. (I like the old way better!)

EDIT: corrected ‘lastrun’ - sometimes I really hate spel cheeck!!! Thank you to Bill !

1 Like

for those interested : a page with most data in graphs etc … will be amended over time as I understand better what each means but it is pretty complete
Just one thing I miss is the state of batterie charge … couldn’t find it. Must be calculated but how ?
Will have to ask Victron how they measure the batterie % …
Will also play with the other graph module and see if I can combine a few.