Timers stored in context fire mqtt payloads when triggered

I have a few problems I'm trying to solve.

First, not very common but does happen. For fans, lights, etc I have timers to auto shut them off. Think motion lights, bathroom fan, etc. Humidity is too high bathroom fan comes on for 10 minutes and then off. Sometimes if I'm testing something I will restart NR during these timers (happens with motion lights more often) and they will then be reset and won't trigger. It's not a huge issue but fans/lights have been left on for a while because of this.

Second, related to the first, the logic around what happens if the fan/light is manually shut off gets complicate because then the timer triggers later and might shut off prematurely. Light is triggered on because of motion, auto off in 5 minutes. I shut the light of manually in 4 minutes, then back on and a minute later the timer fires and auto shuts the light off. I have some logic in place to get around this but it's ugly.

Third, climate. I control my heatpumps via mqtt and I want to implement a hold for n hours. I could use a timer but again to my first point if I restart etc it might get reset and will never go off. It would also be nice to easily cancel this hold or change it, again, complicate NR logic to handle these case.

I've been searching for a solution but nothing has really popped up. In my ideal situation the timer (the date) would be stored and something would check every minute? if that date has passed simply trigger the event. This would easily allow me to remove, replace or catch missed events.

So, picture a state object like this

[
 { id: $unqiue_set_by_setter, trigger: $timestamp, topic: timer/fire/test },
 { id: living_climate_hold, trigger: $timestampe2, topic: climate/hold/off }
]

Every minute I loop over that list and check if it's past the timestamp. If it is I publish to the stored topic (with optional payload). Something else, probably another flow, would listen for that topic and handle the event (shut off the fan). If the light is shut off I simply remove the item from the list. If it's updated (hold changed for heatpump) I simply update the object in the list.

Thoughts? Am I overly complicating this?

Truth is, that reliable system can not be built up only on top of timers and server side switch commands. Knowledge of true state of devices the server has to control is mandatory.
But you haven't told us anything about how and what kind of the communication is set up between devices and node-red. By knowing nothing about this, it is hard to advise anything.

1 Like

I would ignore the shutoff signal and handle the timer entirely in Node-RED. That would let you reset/cancel the timer when a manual command is received.

mqtt is the communication method between devices/nodes. So, here's a scenario

  • Light turns on (Zwave, triggers state change in HA)
  • NR sees this state change through HA and sends an mqtt msg topic: timers/enable payload: {id: "mudroom_light", datetime: "2019-10-4....", "fire_topic": "timers/mudromlight/fire" } *

  • NR node listening on mqtt timers/enable sees new payload and stores the entire payload in the context
  • NR inject node is setup to fire every minute. It fires, pulls out the context list and loops over each one to see if the datetime is past the current datetime. If it is, it fires off an mqtt with all the data in the stored payload, so in this exampl topic: timers/mudromlight/fire, payload: {id: "mudroom_light", datetime: "2019-10-4...." }

  • NR node is setup to listen for timers/mudromlight/fire and issues calls the service to shut the mudroom light off.

In this scenario, the internal bullets are handled but an entire "timer node", so when you want to use it you have to setup only two nodes. First node is used to fire the initial timers/enabled msg with the payload when the light is turned on and the second node will listen for the timers/mudroomlight/fire msg and perform the action you want to happen when the timer is triggered.

In this scenario, if the server was restarted etc the timer would still fire the next time the inject node ran. Also, sending the same command again would override the existing item in the context so I wouldn't have to worry about stopping the old on. Removal is just as easy, light shuts off just fire a message to remove that id from the list.

@hotNipi so few people understand this concept, even at my workplace, timers are rife. They are (to quote the Waterboys mother), the devil.

Sure they work, sure they do a job for you. Sure 99% of the time there is no issue, then they bite.

Nothing beats true feedback and interlocking. Nothing.

I've seen professional (highly paid plc programmers) "fix" a problem with asynchronous data with a "settle timer". It boils my p*ss!

Edit...
Rant over. I feel better now. :slight_smile:

1 Like