Using node-red-contrib-groov-io

I am learning node-red on the groov products. I have 12 analog channels. I have placed 12 groov-io-input nodes on a flow and configured them to read analog values and then just feeding those to the debugger node to observe. This seems to work fine.

I noticed that there is an option to read a 32 bit value, which can be a float. It reads this from the mmp. There is mention of a length parameter that can specify multiple locations which I assume are consecutive and that when doing this it will read values into an array.

I have not tried this yet. I am trying to understand how this would be properly used.

  1. Do I need 12 nodes to read 12 consecutive channels of analog?

  2. Is there a way to do this with one node using 32 bit read?

  3. What is the recommended way to scan and read multiple analog channels?



The quick answers to your questions:

  1. No, it can be done with just one groov-io read node!
  2. No. (I’ll explain below.)
  3. The best way I’ve found is to use the dynamic settings with a groov-io read node.

Now for the longer answers.
Unfortunately the memory locations of the values are not consecutive in the way that it sounds like you’re expecting. The best way to show this is with the MMP Calculator – you can find this in groov Manage under I/O, select I/O Tools, then click MMP Calculator to see this screen:

Here you can see I’m checking the “Analog Channel Read” area, where the first address holds the analog value that you’re looking for, but then the next consecutive addresses are still associated with this I/O point, but instead hold the minimum and maximum values. Because of this you cannot just read a chunk of memory and have just the values in a nice tidy list, it will have mins and maxes (and a few other things) as well.

Thankfully there’s another approach: dynamic settings!
Here’s a snippet from the help tab for the groov-io read nodes (specifically “read”, not “input”) where it shows that you can inject properties with the module and channel index to grab specific values:


We can use this to our advantage by sending a bunch of messages at this single node, once for each channel, then join all 12 messages together on the other side to give us a nice array of 12 values:

Here’s the simple program I’ve put in the “loop” function node:

module_length = 12;
module_number = 3;
for(var i = 0; i < module_length; i++) {
    node.send({ moduleIndex : module_number,
                channelIndex : i});

I just loop from 0 to 12, and each time I send a new msg object with the properties msg.moduleIndex and msg.channelIndex, where the channelIndex i increments each time. This will get the groov-io node to produce 12 separate msg.payloads with each value from that one module, where you can either consume them individually or join them into an array of 12 elements.

You can import this flow using the text below and modify it for your own needs, but in my experience this is the best way to read multiple channels without having to drag in a bunch of separate groov-io nodes.

Flow import:

[{"id":"9bcad53e.3d5748","type":"join","z":"6773a439.5cfddc","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"12","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1250,"y":1560,"wires":[["7e02fe7e.6669b"]]},{"id":"f388653f.829a68","type":"groov-io-read","z":"6773a439.5cfddc","device":"128a79ee.3b01b6","dataType":"channel-analog","moduleIndex":"","channelIndex":"","mmpAddress":"0xF0D81000","mmpType":"int32","mmpLength":"1","mmpEncoding":"ascii","value":"","valueType":"msg.payload","itemName":"","name":"","x":1100,"y":1560,"wires":[["9bcad53e.3d5748"]]},{"id":"7e02fe7e.6669b","type":"debug","z":"6773a439.5cfddc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1390,"y":1560,"wires":[]},{"id":"592b1cca.42bf24","type":"function","z":"6773a439.5cfddc","name":"loop","func":"module_length = 12;\nmodule_number = 3;\n\nfor(var i = 0; i < module_length; i++) {\n    node.send({ moduleIndex : module_number,\n                channelIndex : i});\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":950,"y":1560,"wires":[["f388653f.829a68"]]},{"id":"b3788d49.ff037","type":"inject","z":"6773a439.5cfddc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":820,"y":1560,"wires":[["592b1cca.42bf24"]]},{"id":"128a79ee.3b01b6","type":"groov-io-device","address":"localhost","msgQueueFullBehavior":"DROP_OLD"}]
1 Like

Thanks, I will play with this.

I did get this imported flow to work after deleting the read node and redoing it and setting the API key for the localhost on the RIO. I am now trying this on a second RIO and I am not able to get past either an API Key error or an “address does not match certificate” error.

I am going to go read on the certificates. The first time I got this working I was running node-red on itself. I don’t think I even tried to load a certificate. I was trying things to get around the API Key which I grabbed from the admin account page and pasted into the device config in the analog read node.

Puzzled, more reading

I am not 100% sure what you mean ‘trying on a second RIO’… I think you mean you have two RIOs and you are wanting the exact same flow on both?

You will need to do the same thing on the second RIO as the first. Delete all the groov-io nodes, deploy the flow, delete the unused configurations, then drag a new set of groov-io nodes onto the canvas and reconfigure localhost and the API key.
The reason for this is because Terry configured the certificate in the groov-io node.
I rarely do that as I only use RIO on my local (trusted) network. Terry did the right thing setting up SSL.
The downside is, the certificate in the flow you deploy/copy/move has the SSL settings for RIO #1 which does not match the certificate in RIO #2.

This post here will help.

Bottom line, the IP address or hostname has to match the certificate.

Feel free to ask more questions, or supply some screenshots if I have misunderstood.

1 Like

By second RIO I just meant another one. Just duplicating my test. I restarted the device and the issue resolved itself. I am not yet running more than one device at a time. I am also only experimenting on my local trusted network.