For loop utilizing ui_numeric

I need something like this. I need to set my charge value in a recipe window for the operational parameters of a device. I will have another button somewhere which sets multiple possibilities.

  1. Set Auto or Single Shot mode
  2. Start or Run
  3. Validate ( Do not actually operate the device but validate the recipe and record the timing to accomplish the task.

I haven't tried to use the nodes to write a for loop yet, and need a little prod forward. I get the loop, but cant see how to get the ui_numeric and the inject to work.

[{"id":"ced75f23.f50368","type":"ui_numeric","z":"574cc1b.fd32a4","name":"Charge","label":"Charge","tooltip":"","group":"e55118c9.d1ac08","order":3,"width":0,"height":0,"wrap":true,"passthru":false,"topic":"Charge","format":"{{value}}","min":0,"max":"1500","step":1,"x":320,"y":260,"wires":[["681e4883.5cefe8","93996c17.94769"]]},{"id":"b32d89a4.cc4d38","type":"function","z":"574cc1b.fd32a4","name":"++","func":"if ( (msg.i += 1) < msg.items.length ) return msg;\n","outputs":1,"noerr":0,"x":510,"y":400,"wires":[["681e4883.5cefe8"]]},{"id":"681e4883.5cefe8","type":"function","z":"574cc1b.fd32a4","name":"for each item","func":"if( msg.i     == undefined ) msg.i = 0;\nif( msg.items == undefined ) msg.items = msg.payload;\n\nmsg.payload = msg.items[ msg.i ];\n\nreturn msg;","outputs":1,"noerr":0,"x":520,"y":320,"wires":[["b32d89a4.cc4d38","93996c17.94769"]]},{"id":"93996c17.94769","type":"debug","z":"574cc1b.fd32a4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":710,"y":260,"wires":[]},{"id":"13f8cbc4.5227dc","type":"inject","z":"574cc1b.fd32a4","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":260,"wires":[["ced75f23.f50368"]]},{"id":"e55118c9.d1ac08","type":"ui_group","z":"","name":"Recipe","tab":"80410626.fc27e8","order":1,"disp":true,"width":"6","collapse":false},{"id":"80410626.fc27e8","type":"ui_tab","z":"","name":"Pump Control Recipe","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

Sorry, but I can't make sense of it.

Could you please try to explain what you want to do?

In the flow you posted, I can't see an option to set "Auto" or "Single shot" modes.

What is it all doing?

What is msg.i
What is msg.items
What is msg.items[ msg.i ]

How are they defined?

How are they set?

It is all just a bit too vague.

I have a device. I need to open a valve a number of times. Say 50 times.

I want to use the ui_numeric to set this value. wee will call this value charge.

I think it should be global.charge so that when I want to operate the device it will pull global.charge that has been set in the UI window

Here is the pump dashboard.

Now I will have another operational tab the will have buttons to set globals as follows

Run > run the Recipe
Single mode > run the recipe once
Automatic mode > run the recipe until you receive stop or error
Validation > Run the recipe but don't operate the device to validate the code loops and execution states.

Building the loops and getting the global variables set for the "Recipe" in node-red is a little confusing to me right now. I haven't done this before with the nodes. and I need a little help.

Here is the "Pump Recipe" tab and some stuff I'm playing with to figure it out.

But asking for help here to get going.

[{"id":"c3b01f99.76eae8","type":"change","z":"574cc1b.fd32a4","name":"","rules":[{"t":"set","p":"result","pt":"msg","to":"msg.result = msg.result + msg.payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":340,"wires":[["6e0feac5.a472c4"]]}]

The last flow posted has only a single change node.

Yes, but it isn't passing correctly and I cant figure out how to tie in the loop. Any suggestions?

node-red-contrib-loop-processing

Getting the counter loop to work like the doc without it being an example is a guess at best for me.

Sorry, but I'm stuck.

A valve can only be open (on?) or closed (off)

Turning it on 50 times doesn't make sense.
I can let that slide for the sake of the code, but it isn't helping me understand what and why you are doing it.

I'm reading the other posts now.

Here is a basic loop flow.

It does 10 loops.

[{"id":"e83004c8.c06948","type":"switch","z":"b9924a74.4d98f8","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":340,"y":3720,"wires":[["e02a58f5.04333"],["5d3aea5.d941b14"]]},{"id":"e02a58f5.04333","type":"debug","z":"b9924a74.4d98f8","name":"DONE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":660,"y":3690,"wires":[]},{"id":"dadec0b0.6d204","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":3720,"wires":[["e83004c8.c06948"]]},{"id":"5d3aea5.d941b14","type":"delay","z":"b9924a74.4d98f8","name":"Delay","pauseType":"delay","timeout":"0.5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":490,"y":3760,"wires":[["a7822d2e.f7db28"]]},{"id":"acf46b7a.f84c88","type":"link in","z":"b9924a74.4d98f8","name":"","links":["1e54624b.3b286e"],"x":225,"y":3760,"wires":[["e83004c8.c06948"]]},{"id":"a7822d2e.f7db28","type":"function","z":"b9924a74.4d98f8","name":"Step","func":"var x = msg.payload;\nx = x - 1;\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":3800,"wires":[["1e54624b.3b286e"]]},{"id":"1e54624b.3b286e","type":"link out","z":"b9924a74.4d98f8","name":"","links":["acf46b7a.f84c88"],"x":605,"y":3800,"wires":[]}]

It has a delay in just to make it traceable. You can delete the node if you want.

For the basics, does that do what you want, or do you also need 10 outputs?
If so, they could be taken after the step node before the link out node.

If that is good, we can build on it.

I think I stated above the valve needed to be operated. I think that implies an on/off operation...

Boy you guys are making it hard on me to get the pump operational before 4th of July so I can shoot a mach 4.5 Marshmallow for the worlds record...I think it will push out to 2021.. Have to post last years video again this year. PVC doesn't hold up to Mach 4.5 Velocities even though the pressure was only 50 PSI...

And yes, stand in its way and it would kill you...Death by Marshmallow.....

How about this flow?

[{"id":"e83004c8.c06948","type":"switch","z":"b9924a74.4d98f8","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":340,"y":3720,"wires":[["1965341f.f551c4"],["a7822d2e.f7db28"]]},{"id":"dadec0b0.6d204","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":3720,"wires":[["e83004c8.c06948"]]},{"id":"acf46b7a.f84c88","type":"link in","z":"b9924a74.4d98f8","name":"","links":["1e54624b.3b286e"],"x":225,"y":3760,"wires":[["e83004c8.c06948"]]},{"id":"1965341f.f551c4","type":"change","z":"b9924a74.4d98f8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"Pump Marshmellows","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":3720,"wires":[["e02a58f5.04333"]]},{"id":"a7822d2e.f7db28","type":"function","z":"b9924a74.4d98f8","name":"Step","func":"var x = msg.payload;\nx = x - 1;\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":3760,"wires":[["1e54624b.3b286e","1965341f.f551c4"]]},{"id":"e02a58f5.04333","type":"debug","z":"b9924a74.4d98f8","name":"DONE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":850,"y":3720,"wires":[]},{"id":"1e54624b.3b286e","type":"link out","z":"b9924a74.4d98f8","name":"","links":["acf46b7a.f84c88"],"x":585,"y":3760,"wires":[]}]

Now make the loop utilize ui_numeric so it can be set by the dashboard

I like the link nodes was planning on using MQTT in part of it to pass stuff to differing raspberry pi units.

setting global.charge and utilizing it would seem to be better for the overall "Recipe"

Ok, but really you should be doing this.

It doesn't teach you if we spoon feed you* the answers.

[{"id":"e83004c8.c06948","type":"switch","z":"b9924a74.4d98f8","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":340,"y":3720,"wires":[["1965341f.f551c4"],["b97f5365.a11828"]]},{"id":"dadec0b0.6d204","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":3720,"wires":[["e83004c8.c06948"]]},{"id":"acf46b7a.f84c88","type":"link in","z":"b9924a74.4d98f8","name":"","links":["1e54624b.3b286e"],"x":225,"y":3780,"wires":[["e83004c8.c06948"]]},{"id":"1965341f.f551c4","type":"change","z":"b9924a74.4d98f8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"ON","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":3720,"wires":[["a5178e04.f6a11"]]},{"id":"b97f5365.a11828","type":"delay","z":"b9924a74.4d98f8","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":350,"y":3780,"wires":[["a7822d2e.f7db28"]]},{"id":"3f9650c8.a8df5","type":"ui_slider","z":"b9924a74.4d98f8","name":"How many","label":"slider","tooltip":"","group":"48d9dd9c.267f3c","order":35,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"50","step":1,"x":200,"y":3680,"wires":[["e83004c8.c06948"]]},{"id":"a7822d2e.f7db28","type":"function","z":"b9924a74.4d98f8","name":"Step","func":"var x = msg.payload;\nx = x - 1;\nmsg.payload = x;\nreturn msg;","outputs":1,"noerr":0,"x":500,"y":3780,"wires":[["1e54624b.3b286e","1965341f.f551c4"]]},{"id":"a5178e04.f6a11","type":"trigger","z":"b9924a74.4d98f8","op1":"","op2":"OFF","op1type":"pay","op2type":"str","duration":"250","extend":false,"units":"ms","reset":"","bytopic":"all","name":"Pulse the valve","x":730,"y":3720,"wires":[["e02a58f5.04333"]]},{"id":"1e54624b.3b286e","type":"link out","z":"b9924a74.4d98f8","name":"","links":["acf46b7a.f84c88"],"x":615,"y":3780,"wires":[]},{"id":"e02a58f5.04333","type":"debug","z":"b9924a74.4d98f8","name":"DONE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":930,"y":3720,"wires":[]},{"id":"48d9dd9c.267f3c","type":"ui_group","z":"","d":true,"name":"Full_Remote","tab":"b128eb09.9f681","order":1,"disp":false,"width":"3","collapse":false},{"id":"b128eb09.9f681","type":"ui_tab","z":"","name":"HDMI_TV_control","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

You need to set where the slider is.

Things to note:
The valve needs to be turned ON and OFF to shoot a marshmallow. I don't think leaving it always ON will work.

Look at the DONE node and that is the signal that will be sent to the solenoid / valve.
Really it should be a true and false or 1 and 0. But I hope you can do that.

1 Like

That is a WHOLE OTHER set of variables that need to be declared before now.

Look at the flow I posted.

Again, I know how to set up what you guys are showing me, but I can't get ui_numeric as the node to set the starting count.

ui_numeric passes a message each time I increment the count...Bad for your loops, and when I need to set 1500...Ugh

I need the functionality of ui_numeric to let me set it and then to poke it when called to pass its count.

[{"id":"3f9650c8.a8df5","type":"ui_slider","z":"b9924a74.4d98f8","name":"How many","label":"slider","tooltip":"","group":"48d9dd9c.267f3c","order":35,"width":0,"height":0,"passthru":true,"outs":"end","topic":"","min":0,"max":"50","step":1,"x":200,"y":3680,"wires":[["e83004c8.c06948"]]},{"id":"dadec0b0.6d204","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"10","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":3720,"wires":[["e83004c8.c06948"]]},{"id":"e83004c8.c06948","type":"switch","z":"b9924a74.4d98f8","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":340,"y":3720,"wires":[["1965341f.f551c4"],["b97f5365.a11828"]]},{"id":"48d9dd9c.267f3c","type":"ui_group","z":"","d":true,"name":"Full_Remote","tab":"b128eb09.9f681","order":1,"disp":false,"width":"3","collapse":false},{"id":"b128eb09.9f681","type":"ui_tab","z":"","name":"HDMI_TV_control","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

That starts the loop and counts down.

Change the values from 1 to 50 to 1 to 1500... 1,00,000,000 if you really must.

I decrement the counter so it stops at 0. A lot easier.

I need ui_numeric not ui_slider

Maybe ui_numeric needs to be rethought a bit.

[{"id":"7554cca2.9cfefc","type":"ui_text_input","z":"b9924a74.4d98f8","name":"","label":"","tooltip":"","group":"48d9dd9c.267f3c","order":36,"width":0,"height":0,"passthru":true,"mode":"number","delay":300,"topic":"","x":190,"y":3670,"wires":[["e83004c8.c06948"]]},{"id":"48d9dd9c.267f3c","type":"ui_group","z":"","d":true,"name":"Full_Remote","tab":"b128eb09.9f681","order":1,"disp":false,"width":"3","collapse":false},{"id":"b128eb09.9f681","type":"ui_tab","z":"","name":"HDMI_TV_control","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Ain't rocket science.
Well, it is (seemingly) marshmallow science.

2 Likes

Actually...It is rocket science. Hypersonic Pulse Detonation and it solves the thermal issues. Mine operates silently at room temperature. And its logarithmic not linear in the charge to pressure..No one in the world other than I and my PhD Chemist father-in-law understand it...

Again. trying to slip in anything but ui_numeric...

You guys are going to force me to write my loops in Python Function...Aren't you....

1 Like