Writing to array elements

Hi All,
Hopefully someone can help me out here, I’ve been using node red for a while now, and whilst I can get round most thing, with some knowledge of c the syntax of JavaScript I’m struggling with and I’m guessing there is a simple answer, I’ve searched but cannot find a solution, I’ve spent hours an hours, and usually try my best at working things out myself

Basically I have an inject node (as a test) that sends a msg 0:[255,255,255] this a command sent to an ArtNet function node that uses this format, where 0 defines the universe (address) and each element represents a channel for instance (0,1,2).

The above turns the first three channels on 100%
Iikewise if I send 0:[0,0,0] the first three channels get turned off, channel values sent are uint8 0-255.

This array can be up to 512 elements ( one for each channel); but I need a function that would allow me for instance to use sliders outputting there value to defined elements i.e slider 1, 2, 3 writing to universe 0 first 3 elements, and slider 4,5,6 writing to universe 0 elements 8,9,10

This is so I can send values to certain channels to as required controlling lighting modules.

I’ve found loads of posts regarding reading an array and it elements but nothing on sending out.

I would be grateful if anyone can point me in the right direction, I should be able to work it out from there.

Many Thanks

Jono

Just for better understanding:

The message you are mentioning has both numbers and characters. Or is it actually a string??? Or should it be a javascript object? Can you better describe the type and format required? Is this sent by what? Assuming a TCP node?

As for setting all the values with sliders, look at the dashboard, there you have this slider component for the gui. But hey, 512 sliders in a gui, well you have to be a master to operate that

In the below example, an array is created at init and all 512 values set to zero. Each slider produces an output 0-255. Each of those outputs goes to a change node and sets the corresponding element in the array (in this example I have only included two sliders, one for the first and one for the last element)

Each output from the change nodes are then connect to a function node (via a delay node, eventually not needed) to a common function node. The function node is responsible for "assembling" what needs to be sent to Art-Net

This is likely where things can wrong, I have just made some assumptions, no idea if and what actually works....

Anyway, the code in the function node tries to build the message structure you wrote, starting with 0:[ etc etc and sends it out via tcp

You can try with a the real system and see if and what...

Obviously you would eventually also have to add sliders and change nodes for the remaining sliders you need, some heavy copy & pasting & editing is awaiting...

[{"id":"905e8b15.d226d8","type":"ui_slider","z":"d01d2553.fd9838","name":"","label":"slider 0","tooltip":"","group":"16fdc5e1.9ee0fa","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":140,"y":950,"wires":[["e022de0d.afd06"]]},{"id":"b772e677.578f18","type":"debug","z":"d01d2553.fd9838","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1080,"y":1110,"wires":[]},{"id":"c075b765.c5cbf8","type":"trigger","z":"d01d2553.fd9838","op1":"","op2":"true","op1type":"nul","op2type":"bool","duration":"25","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":610,"y":950,"wires":[["62e39b9f.56b1e4"]]},{"id":"32561b7f.59ea44","type":"inject","z":"d01d2553.fd9838","name":"Init","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":850,"wires":[["178e6238.81f33e"]]},{"id":"178e6238.81f33e","type":"function","z":"d01d2553.fd9838","name":"","func":"var arr = new Array(512);\nvar i;\nfor (i = 0; i < arr.length; i++) { \n  arr[i] = 0;\n}\nflow.set(\"array\", arr);\n\nnode.status({\n\t    text : \"Array length: \"+arr.length.toString()\n});\n","outputs":0,"noerr":0,"x":330,"y":850,"wires":[]},{"id":"e022de0d.afd06","type":"change","z":"d01d2553.fd9838","name":"","rules":[{"t":"set","p":"array[0]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":950,"wires":[["c075b765.c5cbf8"]]},{"id":"2da8eea8.ba6552","type":"ui_slider","z":"d01d2553.fd9838","name":"","label":"slider 511","tooltip":"","group":"16fdc5e1.9ee0fa","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":140,"y":1120,"wires":[["a27d3c88.73501"]]},{"id":"a27d3c88.73501","type":"change","z":"d01d2553.fd9838","name":"","rules":[{"t":"set","p":"array[511]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":1120,"wires":[["c075b765.c5cbf8"]]},{"id":"62e39b9f.56b1e4","type":"function","z":"d01d2553.fd9838","name":"","func":"var arr = flow.get(\"array\");\nnode.send({ payload:0 });\nnode.send({ payload:':' });\nnode.send({ payload:'[' });\nvar i;\nfor (i = 0; i < arr.length; i++) { \n    node.send({ payload:arr[i] });\n    if (i < arr.length-1){\n        node.send({ payload:',' });\n    }\n}\nnode.send({ payload:']' });\n","outputs":1,"noerr":0,"x":840,"y":950,"wires":[["5bae6701.1e0128"]]},{"id":"5bae6701.1e0128","type":"tcp out","z":"d01d2553.fd9838","host":"127.0.0.1","port":"1234","beserver":"client","base64":false,"end":false,"name":"","x":880,"y":1030,"wires":[]},{"id":"defb40fd.5dd31","type":"tcp in","z":"d01d2553.fd9838","name":"","server":"server","host":"","port":"1234","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":850,"y":1110,"wires":[["b772e677.578f18"]]},{"id":"16fdc5e1.9ee0fa","type":"ui_group","z":"","name":"Buttons","tab":"8f57f520.e87078","order":2,"disp":false,"width":"6","collapse":false},{"id":"8f57f520.e87078","type":"ui_tab","z":"","name":"Some stuff","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Hi krambriw,

Thank you so much for taking the time to build the example, I have tried it, but format must be wrong (I apologies i probabley didnt explain it very well), Artnet is sent via UDP on port 6454, my node has been written on Atmel 328, and thats working fine, I can see how you have done it, defining an array and looping through, makes sense.

When i operated the sliders My Pi (hosting my node red crashed) The error I get from the debug is

8/22/2019, 3:21:25 PMnode: 3088f50e.7a245afunction : (error)

"TypeError [ERR_INVALID_ARG_TYPE]: The "list[1]" argument must be one of type Array, Buffer, or Uint8Array. Received type string"

Below is the my complete flow for testing so you can see for yourself, you can see the sub flow call Artnet, that node does all the work to send out the data.

Heres the full flow for my test.

Regards

Jono

[{"id":"2e555652.746eaa","type":"subflow","name":"Artnet","info":"# Art-Net encoder/decoder\n\nThis sublow is a bi-directional Art-Net encoder/decoder.\n\n## Receiving\n\nConnect a udp in object set to port 6454 to the input of the subflow. \nThe Art-Net data will be output as msg.payload in Buffer form. \nThe universe is available as msg.topic.\n\n## Sending\n\nSend an Array or Buffer to the Art-Net subflow and connect the sublow's output to a udp out object set to port 6454.\nThe universe must be set as msg.topic.","in":[{"x":180,"y":140,"wires":[{"id":"341dd2db.4ed8d6"}]}],"out":[{"x":440,"y":140,"wires":[{"id":"341dd2db.4ed8d6","port":0}]}]},{"id":"341dd2db.4ed8d6","type":"function","z":"2e555652.746eaa","name":"Artnet","func":"const HEADER_SIZE = 18;\nconst ID = "Art-Net\0";\nconst ArtDmxOpCode = 0x5000;\nconst ProtVer = 14;\ncontext.sequence = context.sequence || 0;\nconst Physical = 0;\n\nvar header = new Buffer(HEADER_SIZE);\nheader.fill(0);\n\nheader.write(ID);\nheader.writeUInt16LE(ArtDmxOpCode, 8);\nheader.writeUInt16BE(ProtVer, 10);\nheader.writeUInt8(Physical, 13);\n\n// Parse incoming Art-Net packets\nif (msg.payload.slice(0, 8).toString() == ID) {\n var Opcode = msg.payload.readUInt16LE(8);\n if (Opcode == ArtDmxOpCode) {\n var Universe = msg.payload.readUInt16LE(14);\n var Length = msg.payload.readUInt16BE(16);\n msg.topic = Universe;\n msg.payload = msg.payload.slice(HEADER_SIZE, Length + HEADER_SIZE);\n node.send(msg);\n }\n// Format incoming buffer or array into Art-Net packet\n} else {\n context.sequence++;\n header.writeUInt8(context.sequence, 12);\n if (context.sequence >= 255)\n context.sequence = 0;\n \n var Universe = msg.topic;\n var Length = msg.payload.length;\n if (Array.isArray(msg.payload)) {\n msg.payload = new Buffer(msg.payload);\n }\n header.writeUInt16LE(Universe, 14);\n header.writeUInt16BE(Length, 16);\n \n msg.payload = Buffer.concat([header, msg.payload]);\n node.send(msg);\n}\n\n\n","outputs":1,"noerr":0,"x":310,"y":140,"wires":[]},{"id":"e2a9b961.e911e8","type":"udp in","z":"ded91775.54ad","name":"","iface":"","port":"6454","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":110,"y":201,"wires":[["d47e1dfc.842a48"]]},{"id":"c379aac.06a4558","type":"inject","z":"ded91775.54ad","name":"","topic":"0","payload":"[255,255,255,255,255]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":"","x":160,"y":341,"wires":[["3088f50e.7a245a"]]},{"id":"d70cbb0c.908808","type":"debug","z":"ded91775.54ad","name":"","active":true,"console":"false","complete":"false","x":480,"y":201,"wires":},{"id":"21041abb.754cb6","type":"comment","z":"ded91775.54ad","name":"Receive","info":"","x":100,"y":161,"wires":},{"id":"d47e1dfc.842a48","type":"subflow:2e555652.746eaa","z":"ded91775.54ad","name":"","x":280,"y":201,"wires":[["d70cbb0c.908808"]]},{"id":"bfbbc79.31082b8","type":"udp out","z":"ded91775.54ad","name":"","addr":"192.168.10.20","iface":"","port":"6454","ipv":"udp4","outport":"","base64":true,"multicast":"false","x":639,"y":341,"wires":},{"id":"3088f50e.7a245a","type":"subflow:2e555652.746eaa","z":"ded91775.54ad","name":"","x":400,"y":341,"wires":[["bfbbc79.31082b8"]]},{"id":"60d83709.cb50e","type":"comment","z":"ded91775.54ad","name":"Send","info":"","x":100,"y":301,"wires":},{"id":"b5845bdd.fac8e8","type":"comment","z":"ded91775.54ad","name":"Art-Net sending and receiving","info":"","x":170,"y":101,"wires":},{"id":"cb61da95.fab7f","type":"inject","z":"ded91775.54ad","name":"","topic":"0","payload":"[0,0,0]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":"","x":107,"y":388,"wires":[["3088f50e.7a245a"]]},{"id":"e3e77f1c.7bbc18","type":"ui_slider","z":"ded91775.54ad","name":"","label":"slider 0","tooltip":"","group":"2e448404.b81cf4","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":108,"y":571,"wires":[["92ef86a0.88e208"]]},{"id":"a63efaee.31603","type":"debug","z":"ded91775.54ad","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":840,"y":601,"wires":},{"id":"5068dae3.60367c","type":"trigger","z":"ded91775.54ad","op1":"","op2":"true","op1type":"nul","op2type":"bool","duration":"25","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":491,"y":602,"wires":[["317fe0fa.6f94b8"]]},{"id":"d2e6a564.b54968","type":"inject","z":"ded91775.54ad","name":"Init","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":100,"y":499,"wires":[["a915d40a.8d166"]]},{"id":"a915d40a.8d166","type":"function","z":"ded91775.54ad","name":"","func":"var arr = new Array(512);\nvar i;\nfor (i = 0; i < arr.length; i++) { \n arr[i] = 0;\n}\nflow.set("array", arr);\n\nnode.status({\n\t text : "Array length: "+arr.length.toString()\n});\n","outputs":0,"noerr":0,"x":300,"y":499,"wires":},{"id":"92ef86a0.88e208","type":"change","z":"ded91775.54ad","name":"","rules":[{"t":"set","p":"array[0]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":298,"y":571,"wires":[["5068dae3.60367c"]]},{"id":"e436e45b.888768","type":"ui_slider","z":"ded91775.54ad","name":"","label":"slider 2","tooltip":"","group":"2e448404.b81cf4","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":107,"y":635,"wires":[["c41ed7db.d6fe2"]]},{"id":"c41ed7db.d6fe2","type":"change","z":"ded91775.54ad","name":"","rules":[{"t":"set","p":"array[2]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":297,"y":635,"wires":[["5068dae3.60367c"]]},{"id":"317fe0fa.6f94b8","type":"function","z":"ded91775.54ad","name":"","func":"var arr = flow.get("array");\nnode.send({ payload:0 });\nnode.send({ payload:':' });\nnode.send({ payload:'[' });\nvar i;\nfor (i = 0; i < arr.length; i++) { \n node.send({ payload:arr[i] });\n if (i < arr.length-1){\n node.send({ payload:',' });\n }\n}\nnode.send({ payload:']' });\n","outputs":1,"noerr":0,"x":641,"y":602,"wires":[["a63efaee.31603","3088f50e.7a245a"]]},{"id":"2e448404.b81cf4","type":"ui_group","z":"","name":"DMX","tab":"3bc203ee.438e94","disp":true,"width":"6","collapse":false},{"id":"3bc203ee.438e94","type":"ui_tab","z":"","name":"Testboard","icon":"dashboard","disabled":false,"hidden":false}]

You need to put code between 2 lines of 3 back ticks otherwise the forum corrupts it...

```
code here
```

I see, it seems you are just sending a string to your Artnet node. Then I think you can simplify the code in my function node to this (replace with the code below):

var arr = flow.get("array");
msg.payload = "0:["+arr.toString()+"]";
return msg;

Thanks Steve will do :slight_smile:

Hi Krambriw,

Tried that, but i get error, see screen shot below, if you look at message that works im def sending an array of unit8,

Ill try attaching the flow again, this time between the back ticks as Steve told me.

Thanks again for your time, this seemed like such a simple thing to do yet its taking me days its driving me nuts.

Regards

Jono

Heres the flow

[{"id":"2e555652.746eaa","type":"subflow","name":"Artnet","info":"# Art-Net encoder/decoder\n\nThis sublow is a bi-directional Art-Net encoder/decoder.\n\n## Receiving\n\nConnect a `udp in` object set to port *6454* to the input of the subflow.  \nThe Art-Net data will be output as `msg.payload` in Buffer form.  \nThe universe is available as `msg.topic`.\n\n## Sending\n\nSend an `Array` or `Buffer` to the Art-Net subflow and connect the sublow's output to a `udp out` object set to port *6454*.\nThe universe must be set as `msg.topic`.","in":[{"x":180,"y":140,"wires":[{"id":"341dd2db.4ed8d6"}]}],"out":[{"x":440,"y":140,"wires":[{"id":"341dd2db.4ed8d6","port":0}]}]},{"id":"341dd2db.4ed8d6","type":"function","z":"2e555652.746eaa","name":"Artnet","func":"const HEADER_SIZE = 18;\nconst ID = \"Art-Net\\0\";\nconst ArtDmxOpCode = 0x5000;\nconst ProtVer = 14;\ncontext.sequence = context.sequence || 0;\nconst Physical = 0;\n\nvar header = new Buffer(HEADER_SIZE);\nheader.fill(0);\n\nheader.write(ID);\nheader.writeUInt16LE(ArtDmxOpCode, 8);\nheader.writeUInt16BE(ProtVer, 10);\nheader.writeUInt8(Physical, 13);\n\n// Parse incoming Art-Net packets\nif (msg.payload.slice(0, 8).toString() == ID) {\n    var Opcode = msg.payload.readUInt16LE(8);\n    if (Opcode == ArtDmxOpCode) {\n        var Universe = msg.payload.readUInt16LE(14);\n        var Length = msg.payload.readUInt16BE(16);\n        msg.topic = Universe;\n        msg.payload = msg.payload.slice(HEADER_SIZE, Length + HEADER_SIZE);\n        node.send(msg);\n    }\n// Format incoming buffer or array into Art-Net packet\n} else {\n    context.sequence++;\n    header.writeUInt8(context.sequence, 12);\n    if (context.sequence >= 255)\n        context.sequence = 0;\n    \n    var Universe = msg.topic;\n    var Length = msg.payload.length;\n    if (Array.isArray(msg.payload)) {\n        msg.payload = new Buffer(msg.payload);\n    }\n    header.writeUInt16LE(Universe, 14);\n    header.writeUInt16BE(Length, 16);\n    \n    msg.payload = Buffer.concat([header, msg.payload]);\n    node.send(msg);\n}\n\n\n","outputs":1,"noerr":0,"x":310,"y":140,"wires":[[]]},{"id":"e2a9b961.e911e8","type":"udp in","z":"ded91775.54ad","name":"","iface":"","port":"6454","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":110,"y":201,"wires":[["d47e1dfc.842a48"]]},{"id":"c379aac.06a4558","type":"inject","z":"ded91775.54ad","name":"","topic":"0","payload":"[255,255,255,255,255]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":"","x":160,"y":341,"wires":[["3088f50e.7a245a","5eb856b7.5f90e8"]]},{"id":"d70cbb0c.908808","type":"debug","z":"ded91775.54ad","name":"","active":true,"console":"false","complete":"false","x":480,"y":201,"wires":[]},{"id":"21041abb.754cb6","type":"comment","z":"ded91775.54ad","name":"Receive","info":"","x":100,"y":161,"wires":[]},{"id":"d47e1dfc.842a48","type":"subflow:2e555652.746eaa","z":"ded91775.54ad","name":"","x":280,"y":201,"wires":[["d70cbb0c.908808"]]},{"id":"bfbbc79.31082b8","type":"udp out","z":"ded91775.54ad","name":"","addr":"192.168.10.20","iface":"","port":"6454","ipv":"udp4","outport":"","base64":true,"multicast":"false","x":639,"y":341,"wires":[]},{"id":"3088f50e.7a245a","type":"subflow:2e555652.746eaa","z":"ded91775.54ad","name":"","x":400,"y":341,"wires":[["bfbbc79.31082b8"]]},{"id":"60d83709.cb50e","type":"comment","z":"ded91775.54ad","name":"Send","info":"","x":100,"y":301,"wires":[]},{"id":"b5845bdd.fac8e8","type":"comment","z":"ded91775.54ad","name":"Art-Net sending and receiving","info":"","x":170,"y":101,"wires":[]},{"id":"cb61da95.fab7f","type":"inject","z":"ded91775.54ad","name":"","topic":"0","payload":"[0,0,0]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":"","x":107,"y":388,"wires":[["3088f50e.7a245a","5eb856b7.5f90e8"]]},{"id":"e3e77f1c.7bbc18","type":"ui_slider","z":"ded91775.54ad","name":"","label":"slider 0","tooltip":"","group":"2e448404.b81cf4","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":108,"y":571,"wires":[["92ef86a0.88e208"]]},{"id":"a63efaee.31603","type":"debug","z":"ded91775.54ad","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":840,"y":601,"wires":[]},{"id":"5068dae3.60367c","type":"trigger","z":"ded91775.54ad","op1":"","op2":"true","op1type":"nul","op2type":"bool","duration":"25","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":491,"y":602,"wires":[["317fe0fa.6f94b8"]]},{"id":"d2e6a564.b54968","type":"inject","z":"ded91775.54ad","name":"Init","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":100,"y":499,"wires":[["a915d40a.8d166"]]},{"id":"a915d40a.8d166","type":"function","z":"ded91775.54ad","name":"","func":"var arr = new Array(512);\nvar i;\nfor (i = 0; i < arr.length; i++) { \n  arr[i] = 0;\n}\nflow.set(\"array\", arr);\n\nnode.status({\n\t    text : \"Array length: \"+arr.length.toString()\n});\n","outputs":0,"noerr":0,"x":300,"y":499,"wires":[]},{"id":"92ef86a0.88e208","type":"change","z":"ded91775.54ad","name":"","rules":[{"t":"set","p":"array[0]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":298,"y":571,"wires":[["5068dae3.60367c"]]},{"id":"e436e45b.888768","type":"ui_slider","z":"ded91775.54ad","name":"","label":"slider 2","tooltip":"","group":"2e448404.b81cf4","order":1,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"255","step":1,"x":107,"y":635,"wires":[["c41ed7db.d6fe2"]]},{"id":"c41ed7db.d6fe2","type":"change","z":"ded91775.54ad","name":"","rules":[{"t":"set","p":"array[2]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":297,"y":635,"wires":[["5068dae3.60367c"]]},{"id":"317fe0fa.6f94b8","type":"function","z":"ded91775.54ad","name":"","func":"var arr = flow.get(\"array\");\nmsg.payload = \"0:[\"+arr.toString()+\"]\";\nreturn msg;","outputs":1,"noerr":0,"x":641,"y":602,"wires":[["a63efaee.31603","3088f50e.7a245a"]]},{"id":"5eb856b7.5f90e8","type":"debug","z":"ded91775.54ad","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":428.57142857142856,"y":274.2857142857143,"wires":[]},{"id":"2e448404.b81cf4","type":"ui_group","z":"","name":"DMX","tab":"3bc203ee.438e94","disp":true,"width":"6","collapse":false},{"id":"3bc203ee.438e94","type":"ui_tab","z":"","name":"Testboard","icon":"dashboard","disabled":false,"hidden":false}]

Try this then:

msg.topic = "0"
msg.payload = flow.get("array");
return msg;

You are sending an array as the msg.payload with the msg.topic = "0", this is your universe

Hi Krambriw,

You are a legend, absolutely works perfect.

Thank you so much :smile:

Kind Regards

John