Need help optimising flow and Chart output


#4

Maybe I'm not understanding the Rules for the Change node. The counter node expects msg.reset to reset. But output I get is this:

17.3.2019, 11:36:15node: 239e78f6.65c258
msg.payload : undefined
undefined

When I set it to move instead of change, I get the same output.
Here is what I set it to:


#5

Hi, your post was very clear, included correct formatting, examples, and indicated you tried stuff before asking so i felt inclined to to try and help you.

NOTE: there are many ways to skin a cat & others will have other ideas. This is just one.

Screen shots...

nr-st2

The flow...
[{"id":"e99d400c.6ac15","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"d1da66ed.8ed4f8","type":"function","z":"e99d400c.6ac15","name":"matrix red on","func":"msg.payload = \"4,0,red,4,1,red,4,2,red,4,3,red,5,0,red,5,1,red,5,2,red,5,3,red,6,0,red,6,1,red,6,2,red,6,3,red,7,0,red,7,1,red,7,2,red,7,3,red\";\nmsg.topic = \"A\";\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":80,"wires":[["eefa2946.5b3d08"]]},{"id":"ef34d559.e4a878","type":"switch","z":"e99d400c.6ac15","name":"A or B or other","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"!AIVDM,1,1,,A,","vt":"str"},{"t":"cont","v":"!AIVDM,1,1,,B,","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":280,"y":100,"wires":[["d1da66ed.8ed4f8"],["2dd5498a.db6576"],["5503f0a6.0505c","1d88b922.cfa7f7"]]},{"id":"5503f0a6.0505c","type":"function","z":"e99d400c.6ac15","name":"matrix red off","func":"msg.payload = \"4,0,off,4,1,off,4,2,off,3,off,5,0,off,5,1,off,5,2,off,5,3,off,6,0,off,6,1,off,6,2,off,6,3,off,7,0,off,7,1,off,7,2,off,7,3,off\";\nmsg.topic = \"\";\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":160,"wires":[[]]},{"id":"2dd5498a.db6576","type":"function","z":"e99d400c.6ac15","name":"matrix green on","func":"msg.payload = \"0,4,green,0,5,green,0,6,green,0,7,green,1,4,green,1,5,green,1,6,green,1,7,green,2,4,green,2,5,green,2,6,green,2,7,green,3,4,green,3,5,green,3,6,green,3,7,green\";\nmsg.topic = \"B\";\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":120,"wires":[["eefa2946.5b3d08"]]},{"id":"1d88b922.cfa7f7","type":"function","z":"e99d400c.6ac15","name":"matrix green off","func":"msg.payload = \"0,4,off,0,5,off,0,6,off,0,7,off,1,4,off,1,5,off,1,6,off,1,7,off,2,4,off,2,5,off,2,6,off,2,7,off,3,4,off,3,5,off,3,6,off,3,7,off\";\nmsg.topic = \"\";\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":200,"wires":[[]]},{"id":"daa58ccf.31e4a","type":"udp in","z":"e99d400c.6ac15","name":"","iface":"","port":"10110","ipv":"udp4","multicast":"false","group":"","datatype":"utf8","x":100,"y":100,"wires":[["ef34d559.e4a878"]]},{"id":"e64cb1a3.843cb","type":"comment","z":"e99d400c.6ac15","name":"listen for Channel A and B messages","info":"","x":190,"y":40,"wires":[]},{"id":"98e87438.0b9f58","type":"comment","z":"e99d400c.6ac15","name":"switch LED matrix on/off depending on Channel","info":"","x":600,"y":40,"wires":[]},{"id":"682d9713.9e3188","type":"inject","z":"e99d400c.6ac15","name":"A","topic":"","payload":"!AIVDM,1,1,,A,","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":160,"wires":[["ef34d559.e4a878"]]},{"id":"7c475136.306fb","type":"inject","z":"e99d400c.6ac15","name":"B","topic":"","payload":"!AIVDM,1,1,,B,","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":200,"wires":[["ef34d559.e4a878"]]},{"id":"eefa2946.5b3d08","type":"function","z":"e99d400c.6ac15","name":"log counts A and B in flow contect store","func":"if(msg.topic !== \"A\" && msg.topic !== \"B\"){\n return null;//halt flow\n} \n//set the payload to the memory value stored in flow contect\n//note: as we verified above that msg.topic is definitely A or B\n//we simply get from flow contect using msg.topic\nmsg.payload = flow.get(msg.topic) || 0; // if value is empty, ||0 will set it to 0 (like a default)\nmsg.payload += 1;//increment the value \nflow.set(msg.topic, msg.payload);//update the value in flow store\nreturn msg;//return the message\n","outputs":1,"noerr":0,"x":780,"y":100,"wires":[[]]},{"id":"90bc0552.721448","type":"function","z":"e99d400c.6ac15","name":"get & reset counts A and B","func":"var msgA = {};\nmsgA.topic = \"A\";\nmsgA.payload = flow.get(msgA.topic) || 0; // if value is empty, ||0 will set it to 0 (like a default)\n\nvar msgB = {};\nmsgB.topic = \"B\";\nmsgB.payload = flow.get(msgB.topic) || 0; // if value is empty, ||0 will set it to 0 (like a default)\n\n//store prev counters\nflow.set(\"A_Prev\",msgA.payload);\nflow.set(\"B_Prev\",msgB.payload);\n//reset counters\nflow.set(\"A\",0);\nflow.set(\"B\",0);\n\n//for learning purposes, i return 2 objects on 2 outputs\n//we could skip this by using 2 node.send(msg) if we wanted \nreturn [msgA, msgB];","outputs":2,"noerr":0,"x":400,"y":360,"wires":[["c0288161.721c3"],["c0288161.721c3"]]},{"id":"c0288161.721c3","type":"ui_chart","z":"e99d400c.6ac15","name":"","group":"4680bb7c.986364","order":0,"width":"0","height":"0","label":"","chartType":"line","legend":"true","xformat":"auto","interpolate":"step","nodata":"","dot":false,"ymin":"0","ymax":"","removeOlder":"1","removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":670,"y":360,"wires":[[]]},{"id":"beaa55c1.fd55e8","type":"inject","z":"e99d400c.6ac15","name":"Every minute","topic":"","payload":"true","payloadType":"bool","repeat":"60","crontab":"","once":true,"onceDelay":0.1,"x":140,"y":360,"wires":[["90bc0552.721448"]]},{"id":"cc2cfba3.3669e8","type":"comment","z":"e99d400c.6ac15","name":"Trigger chart update every minute","info":"","x":170,"y":320,"wires":[]},{"id":"4680bb7c.986364","type":"ui_group","z":"","name":"AIS Message Count","tab":"e1ead9a8.b76758","order":1,"disp":true,"width":"6","collapse":false},{"id":"e1ead9a8.b76758","type":"ui_tab","z":"","name":"AIS","icon":"dashboard","order":6,"disabled":false,"hidden":false}]


#6

Hi Steve,
and thank you so much. That is a lot more than expected!

Now I need to work my way through your nodes and see how you had things done. That will be the fun part :slight_smile:

Just deployed and noticed that you split into A/B in the chart. That is not necessary as I want the total amount of messages (A+B). In real life there are these two channels just for the purpose of providing more bandwidth. Imagine a main port like Hongkong or wherever with hundreds if not thousands of ships. Each one sending an AIS message every 3 to 30 seconds. For the receiver it doesn't matter whether it was from channel A or B.

Another thing I discovered is that both LEDs (red and green) stays lit with your flow. Not sure what's going on, but will look into it. edit: my fault. For debug purposes I disconnected the off function nodes...display works fine.


#7

Hi yeah - I was not 100% sure of your final intent (some assumptions were made) .

The changes I made were mostly academic & for showing you alternative methods.

Mainly I wanted to show you how the graph can be populated.

From what I've seen from you I am sure you can integrate what I did with your work & get it going pretty quickly & easily.

Key points I tried to make were...

  • using topics
  • use of flow context
  • use of function nodes with multiple outputs
  • how to populate graph

Let us know if you get stuck.


#8

oh and in case you dont know of it, check out the right hand side bar in particular the Context Data - here you can see what value things are.

nr-st3


#9

Thanks again very much!

The intent is only for learning. Sorry if I was not clear enough.
And no better way than to learn from others, how they do it or how they solve problems.

I must admit I've never heard of flow context, but I can see and understand how it works. When I discovered node-red I really thought it is all plug'n play. Wire a few nodes and there you go. How wrong I was :wink: But thats the fun of it. Finally I have a lot of ideas how to make real use of NR.


#10

Sorry I should have said 'set msg.reset to msg.payload' like this:
08%20AM


#11

zenofmud, not your fault. But a better understanding of this sure will help me.

When I set msg.reset to msg.payload per your example, it sends 0 (as was injected) to the output. The other way around is undefined.


#12

I've always found the SET confusing - it sets the top item to what ever the bottom item is. So it is setting msg.reset' to what evermsg.payload' contains. I probably should have set set msg.reset to 0 because - if you read the info on the node you will see:

Control
It's possible to control the counter with incoming msg properties:

  • msg.increment : counter will be incremented by the given value.
  • msg.decrement : counter will be decremented by the given value.
  • msg.reset : resets the counter to it's initial count, or to the given value, when it's a number.

#13

Indeed, very confusing with the change node. I read that too that msg.reset could be a number and so I accepted 0 to be valid. But is not. As soon as I set msg.reset to 1 or any other number, it works.

Ugh, hard bread. But we finally got there :slight_smile: Thanks very much, zenofmud!


#14

did you mke sure to send the number 0 and not the letter 0. i.e. This:
47%20PM

and not this:

47%20PM

Note the a/z vrs 0/9 for the type


#15

Of course, I did and always verified the output to be a number. It accepts 0, but 0 doesn't reset the counter node.

Here is how it will reset. Please notice that once it resets the counter, it starts counting 1 twice. Means the counter does not start at 0. I cannot explain this as I'm too much of a novice in these things. But sure someone can. Or maybe a bug in the counter node?

[{"id":"c3d38fe.78f58f","type":"inject","z":"5e4ca564.2d1b1c","name":"","topic":"","payload":"1","payloadType":"num","repeat":"15","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":220,"wires":[["cb9075c0.e35628"]]},{"id":"6c0a456e.fb47ac","type":"counter","z":"5e4ca564.2d1b1c","name":"","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":2,"x":640,"y":160,"wires":[["e59a770f.b2b8a"],[]]},{"id":"2def1ed.2724962","type":"inject","z":"5e4ca564.2d1b1c","name":"","topic":"","payload":"!AIVDM","payloadType":"str","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":240,"y":160,"wires":[["6c0a456e.fb47ac"]]},{"id":"e59a770f.b2b8a","type":"debug","z":"5e4ca564.2d1b1c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":810,"y":200,"wires":[]},{"id":"cb9075c0.e35628","type":"change","z":"5e4ca564.2d1b1c","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":220,"wires":[["6c0a456e.fb47ac","e59a770f.b2b8a"]]}]

#16

Which counter node are you using (node-red-contrib-something probably)?


#17

It's the node-red-contrib-counter.


#18

About msg.reset the readme says " msg.reset : resets the counter to it's initial count, or to the given value, when it's a number." The emboldening is mine. Look at what value you have given for msg.reset. The counter is reset to that value.


#19

@colin - it looks like there is a bug when msg.reset is set to zero. In that case it doesn't reset the counter. I'm going to take a look at the node and see if I can see why


#20

Yup there is a bug! in the code it does this

            // handle reset
            if( msg.hasOwnProperty("reset") && msg.reset ) {
                node.count = typeof msg.reset === "number" ? msg.reset : node.init;
            }

the problem is that if msg.reset containg a zero the if statement will always fail because msg.reset evaluate to false. the code should be

            // handle reset
            if( msg.hasOwnProperty("reset") &&  typeof msg.reset === "number" ) {
                node.count = typeof msg.reset === "number" ? msg.reset : node.init;
            }

I will create a PR for this
@Stefanie in the meantime you can fix this in the code yourself if you are daring :stuck_out_tongue_winking_eye:
If you are on a Pi:

  1. open a terminal window
  2. enter nano $HOME/.node-red/node_modules/node-red-contrib-counter/counter.js
  3. use the down arrow to scroll down until you find the code above.
  4. make the change and press ctrl-x the y then the enter key
  5. restart NR and giveit a whirl

NOTE: I updated this code to the correct fix, my original fix only worked it the msg.reset was 0 but it can be any number.


#21

The flow posted sets msg.reset to 1. Which also is not correct.


#22

I set it to 1 as an example only.


#23

Haha, I certainly will when Iā€˜m back home Wednesday :innocent: