Puzzle time! What’s the most practical way of creating “inching” behaviour in NodeRED? If you want to challenge yourself, don’t read further and send me your solution. Requirements:
- use stock nodes
- single payload messages on ON|OFF (no repeating values)
- custom inching time
- ability to retrigger or cancel at will
Sonoff devices come with an “inching” option available via eWeLink app or Tasmota. But what if you are itching to add inching to other systems?
Inching like a pro
I needed a simple flow for inching mechanism. If you don’t know what “inching” means, it’s a fancy term for turning a thing ON and then turning it OFF a couple of seconds/minutes later. You could call it a timer wannabee with a preset timer.
It seemed easy at first until I figured out there is more to “inching” than just delaying a payload for a couple of seconds. Feel free to scroll to the bottom for the grand finale (flow download), or read on to learn something new.
I’ve got 99 problems
Inching could be implemented in more than one way in NodeRED, but my goal was to use as little nodes as possible – one! This is the behaviour I expect from my flow
- custom timeout
- payload
true|false
must be issued just once - false cancels the current timeout
- true resets the current timeout
- quick toggling
true>false>true
works as expected
To solve this puzzle, I’m going to use asynchronous code in JavaScript. It sounds so sophisticated, but it means that a piece of code is executed outside of the main thread – think of this as a side quest. The result is submitted back to the main thread once the task is done, or the timeout had occurred.
function inching(){ let alarm1 = context.get("alarmState"); if(alarm1 === true){ msg = {payload: false}; context.set("alarmState", false); msg1 = {payload: false, topic: "inching"}; node.send([msg, msg1]); } }
JavaScript has the ability to delay the function by using setTimeout(function, time)
– this method takes a function and stalls it for X seconds (time
). Once the time is up, the result of the function is available in NodeRED. Timeout on its own won’t save the day, as I need the ability to:
- Check if the status of the toggle changed since the trigger
- Update the Dashboard toggle without duplicating the payload
The second statement got me puzzled for some time actually, as I wanted to make sure that only single payload (true|false
) would be sent. To achieve this and update the visual state of the dashboard toggle, I had to exercise my brain further.
The key was to differentiate the dashboard user input and the feedback loop that would set the toggle to a correct position without retriggering the switch again. I achieved this by setting a custom topic in the payload that would be sent back to the toggle.
if(topic !== "inching"){ // Case one: alarm not set // Case two: alarm is set } else{//do nothing}
The last piece of this puzzle was a flow variable that stores the information about inching in progress. Each time the toggle is activated, this is checked first, and an appropriate statement is executed.
Inch by inch
I mentioned setTimeout();
method to set the inching. This is a convenient way of doing things because I can also cancel the existing timeout with clearTimeout();
. Each time toggle sends a payload during the inching timeout, the timeout is either reset or cancelled depending on the payload type.
Feedback loop sets a msg.topic = "inching";
that is used to identify the payload. The distinction between the user action via dashboard toggle (it sends the payload) and the payload originated from the function node (not passed through) helps the function node correctly assess the payload origin.
Trigger Alternative
There is one more node you can use to mimic the same behaviour – Trigger node. You will need to write a separate logic to update the switch, the Trigger node comes with a very useful feature.
You can add more time, instead of resetting it each time. I’m pretty sure I could add the option in my original flow (I might do), but I only got that tip after publishing the article (thank you Nick O’Leary) so for now, my take on it, is different. Please note that this flow won’t send false
as your 1st message.
Conclusion
If you are still awake – I congratulate you. You just read about possibly the first (and not the last) asynchronous implementation of the code in NodeRED done by me. Now you can add “inching” to any NodeRED flow. The mandate for Sonoff switches to run it exclusively is over! If you skipped all that to just get the flow – shame on you – but I also totally understand you – I have done that myself way too many times! Feel free to leave me a comment in this Reddit thread.
Project Download
Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.