How to autmoatically increase a percentage value using start and stop triggers


Hi there,

I am looking for a way to do the following:
Input node is numeric, delivers either a "1" for begin or a "0" for stop (like pressing a button triggers the "1", while releasing it sends the "0").

Output node expects a number as well, which is between 0 and 100 (which is the absolute brightness of a bulb between 0 and 100%).

Now, when pressing the button and holding it down, I am looking for a way (probably some lines of code, as I am no developer) to increase the brightness automatically, while holding the button. Something like

while inc_dec==1
brightness = brightness + 1
return msg.payload.brightness
return to start

(ok, you have surely noticed by now that I have really no idea, how to code that :slight_smile: )

Would be happy to get some ideas from you skilled guys here...




When you say button do you mean a physical button, a button (inject?) in Node-RED or a button on a webpage (dashboard)?

If you mean a button in the Node-RED interface unfortunately it isn’t possible as the interface isn’t supposed to be a dashboard. which is why there is the node-red-dashboard project



Sorry, I have been unclear here:

The button would be a KNX sensor (wall rocker) that would be pressed physically. This then would trigger a message (so called GA on KNX) which then would be read by a KNX node on NodeRed and used as the input to the respective function node. So no Dashboard involved here.

Background is, that I would like to control the dimming of a Hue Bulb using a KNX Rocker as Dimmer. The KNX rocker sends a start / stop dimming (the 1/0 I mentioned above) while the Hue Bulb expects an absolute percentage for the brightness.

Make sense?



so start by linking up the Knx rocker in Node-RED to a debug node and see what kind of output it gives you.



Should the full solution contain solutions for both direction of dimming? Or is there two separated buttons for this?



thats the simple part. It delivers an array where "" is set to "1" while pressed, and returns to "0" when released. No problem to extract this one, using a function node and passing the extracted value to the next function node then.... But how to create a counter then, that increases an output object, based on how long the button has been pressed? (like 10% every second the button is pressed f.e.).

like msg.payload.brightness = 10....then 20....then 30 and have it sent every time it's value is updated?



Good point, forgot that as well

msg.payload.incr_decr is set to 1 for increasing and set to 0 for decreasing the dimming value. is set to 1 while the button is pressed, and set to 0 when released.

So f.e. = 1 + msg.payload.incr_decr=1 means button pressed, increase brightness = 1 + msg.payload.incr_decr=0 means button pressed, decrease brightness = 0 + msg.payload.incr_decr=1 means button released, stop dimming = 0 + msg.payload.incr_decr=0 means button released, stop dimming

(sorry, I am only allowed to post 2 pics. So for Pressed Dim Down it changes incr_decr to 0)
Pics show Pressed Up, Released button



Raw basics can be something like this

[{"id":"1eb7a2e9.c876ed","type":"function","z":"b02a69cb.a920e8","name":"dimmer controller","func":"var iv = flow.get(\"incrementvalue\") || 0;\nif(iv === 0){\n return null\n}\nvar dimmer = flow.get(\"dimmervalue\") || 0;\ndimmer += iv;\nif(dimmer > 100){\n dimmer = 100;\n}\nif(dimmer < 0){\n dimmer = 0;\n}\n\nflow.set(\"dimmervalue\",dimmer)\n\nmsg.payload = dimmer;\nreturn msg","outputs":1,"noerr":0,"x":380,"y":580,"wires":[["79319717.d374c8"]]},{"id":"79319717.d374c8","type":"debug","z":"b02a69cb.a920e8","name":"dimmer debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":590,"y":580,"wires":[]},{"id":"1f917d40.b23d53","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"up","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":700,"wires":[["366cb4dc.1b577c"]]},{"id":"e49df5d8.895788","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"up","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":660,"wires":[["366cb4dc.1b577c"]]},{"id":"366cb4dc.1b577c","type":"function","z":"b02a69cb.a920e8","name":"button input to state","func":"var step = flow.get(\"dimmerstep\") || 1\nif(msg.topic === \"up\"){\n if(msg.payload === 1){\n flow.set(\"incrementvalue\",step)\n }\n else{\n flow.set(\"incrementvalue\",0)\n }\n}\nelse{\n if(msg.payload === 1){\n flow.set(\"incrementvalue\",step * -1)\n }\n else{\n flow.set(\"incrementvalue\",0)\n }\n}\nreturn msg\n","outputs":1,"noerr":0,"x":390,"y":720,"wires":[["cf6ef6f8.1554b8"]]},{"id":"b1fdeb3.f08f318","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"down","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":740,"wires":[["366cb4dc.1b577c"]]},{"id":"293cc6cf.6d262a","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"down","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":780,"wires":[["366cb4dc.1b577c"]]},{"id":"cf6ef6f8.1554b8","type":"debug","z":"b02a69cb.a920e8","name":"state debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":590,"y":720,"wires":[]},{"id":"ad75d17c.d2703","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"","payload":"","payloadType":"date","repeat":".25","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":580,"wires":[["1eb7a2e9.c876ed"]]},{"id":"5133c8dd.5700f8","type":"change","z":"b02a69cb.a920e8","name":"","rules":[{"t":"set","p":"dimmerstep","pt":"flow","to":"5","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":500,"wires":[[]]},{"id":"82f008c7.8d25b8","type":"inject","z":"b02a69cb.a920e8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":500,"wires":[["5133c8dd.5700f8"]]}]



Thanks a lot, that looks very promising! I will need to get the other variables and objects togehter and see, if i can make them work. You helped me a lot. Will post the end result in case I can make it fly :slight_smile:

One thing that's not entirely clear to me: Do I need to initiate the set.dimstep value flow (the very first line) every timy NodeRed reboots?



If you are using filesystem storage option, then no, last selected value survives reboots.



ok, so i would need to check how the makers of openhabianpi did their config.

I have noticed, that the down:0 or up:0 command does not only stop the counter, but sets the value for "incrementvalue" to 0. So I can only dimm to a certain value, only to switch the light off then :wink:



Wasn't that the requirement? if you are relasing the physical dimming button, then the dimming action should be terminated.



Mh, yes and no. So after releasing the button, the dimming action itself needs to stop, right. But the bulb should obviously stay at the last brightness level.

Now it dimms to x percent, I release the button and the light goes dark.

What should happen is, that the last selected brightness level that is selected when the button is released, that's the one that is sent to the bulb as the last command.



From those functions you can find how to retrieve "dimmervalue" (from flow context). Use same logic in the place where condition for last command are met and try send it out as last known good value.



I have no idea how to do that, but will do my best to figure it out :slight_smile:
Thanks so far, guess I have a starting point and will need to dig into this on my own.

1 Like


That's the answer I like :slight_smile: