I am working on perfecting my timer automation described here:
In short, I am running a circulating timer that will turn on a switch for 2 minutes, then turn off for 20 minutes, and repeat.
I have several time periods, each set up as a separate automation, to implement this automation. Some of them are back to back.
The issue I have is that sometimes the switch will turn on+off near the end of one time period. And when the next time period starts, the switch will turn on much sooner than it needs to be.
I tried putting in a “wait for trigger” right before starting the circulation. The screenshot below shows how it is currently set. We wait for the hot water circulator to be off for 18 minutes. I don’t think this is working as I imagined.
What I really want is for it to proceed if it has been off for at least 18 minutes. Or, if it is less than 18 minutes, wait until it has been 18 minutes before proceeding.
If the switch has been off for >18 minutes when the automation runs, I think it just endlessly waits? I am probably using this trigger wrong.
please post code using this instead of screenshots:
lots of ways to solve your problem. but some of them will have different behaviors.
one way to do this to have an 18 minute timer that’s triggered when the pump turns off (or 20 minute when it turns on depending on what you want in the boundary conditions).
then in your code, if the timer is running, wait for the timer to finish otherwise don’t wait… then turn on the pump.
you can’t do what you’re doing because your wait will, starting from when that code is hit, look for the hot water circulator to turn off then wait 18 minutes after it sees it turn off. it won’t go back in time.
Thank you for your response. I’m new to modern coding in general (PASCAL anyone?) but I will post code going forward.
The timer idea sounds good and simple. Here’s what I’ve made so far.
The code for one of the automations, for mid-day.
alias: Midday water circulation
description: Turn on circulation when home during midday
trigger:
- platform: time
at: "10:15:00"
- platform: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
event: enter
- platform: homeassistant
event: start
condition:
- condition: time
after: "10:15:00"
before: "17:00:00"
weekday:
- sat
- fri
- thu
- wed
- tue
- mon
- sun
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
action:
- service: notify.mobile_app_sm_g970u1
metadata: {}
data:
message: We ready to turn on circulation now?
- repeat:
sequence:
- service: scene.turn_on
metadata: {}
target:
entity_id: scene.hot_water_switch_1_on
- delay:
hours: 0
minutes: 22
seconds: 0
milliseconds: 0
while:
- condition: time
after: "10:15:00"
before: "17:00:00"
weekday:
- sat
- fri
- thu
- wed
- tue
- mon
- sun
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
mode: single
I made a separate timer automation. I believe I’ll be querying for the IDLE state which indicates the timer is done?
alias: Time since hot water off
description: Use to limit hot water turning back on
trigger:
- platform: device
type: turned_off
device_id: 32dd54355a2471d7f10f05c07c63125a
entity_id: 671a0a417a33671f6d707e4a5a85f05b
domain: switch
condition: []
action:
- service: timer.start
metadata: {}
data:
duration: "00:18:00"
target:
entity_id: timer.hot_water_off_timer
mode: single
Putting the two together is where I lose it.
The loop should wait to start until the timer is confirmed IDLE. I thought “Wait for trigger” would work, but again, that only looks for a change in state, not if the timer is IDLE already.
i’m not exactly positive what you want to do where, but i’m taking some guesses.
look through this code before you try it. see if the logic is what you want:
alias: Midday water circulation
description: Turn on circulation when home during midday
trigger:
- platform: time
at: "10:15:00"
- platform: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
event: enter
- platform: homeassistant
event: start
condition:
- condition: time
after: "10:15:00"
before: "17:00:00"
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
action:
- service: notify.mobile_app_sm_g970u1
data:
message: We ready to turn on circulation now?
- repeat:
sequence:
- if:
- condition: state
entity_id: timer.hot_water_off_timer
state: active
then:
- wait_for_trigger:
- platform: state
entity_id:
- timer.hot_water_off_timer
to: idle
- service: scene.turn_on
target:
entity_id: scene.hot_water_switch_1_on
data: {}
- delay:
hours: 0
minutes: 22
seconds: 0
milliseconds: 0
while:
- condition: time
after: "10:15:00"
before: "17:00:00"
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
mode: single
i did nuke all your days of the week. if you want every day, you can omit that.
and here’s the timer trigger code:
alias: Time since hot water off
description: Use to limit hot water turning back on
trigger:
- platform: state
entity_id:
- switch.hot_water
to: "off"
condition: []
action:
- service: timer.start
data:
duration: "00:18:00"
target:
entity_id: timer.hot_water_off_timer
mode: single
replace the switch.hot_water with the correct entity_id. don’t use device_id’s.
also make sure you have created the timer.hot_water_off_timer helper, and you should make it restore on restart.
holler if any of this code doesn’t make sense.
by the way, if the time you want the water pump on to be 2 minutes, personally i would make the timer be 20 minutes and make it start when the water turns on… because if you don’t, when this code runs, if the water was just turned yon 1 minute ago, it will try to turn the water on right away while it’s still on… but i don’t know your use case so i don’t know if that’s what you want or not.
Your code mods were enlightening. I’ve made changes to the automation and think your additions will accomplish what I need. Apparently I have a weakness thinking up how to place and phrase IF/THEN commands.
Good suggestion setting the timer to start when hot water turns ON, as opposed to OFF. I was playing the probability game that most likely the water wouldn’t be just turned on when the separate automations handoff from one time period to the next.
Just one question to aid me in the future.
I was using the visual editor when constructing the timer and just saw it pulled in numerical device_id and entity_id instead of actual text. Any reason why it would do that? Wouldn’t I just need one anyway?
well… i hope it’s working for you now. and if so, in complete violation of the principle of “don’t fix what’s not broken”… and perhaps just more for learning purposes since you seem interested not just in “getting it done”… consider this:
alias: Midday water circulation
description: Turn on circulation when home during midday
trigger:
- platform: time
at: "10:15:00"
id: notify
- platform: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
event: enter
id: notify
- platform: homeassistant
event: start
id: notify
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.hot_water_off_timer
id: timer
condition:
- condition: time
after: "10:15:00"
before: "17:00:00"
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
action:
- if:
- condition: trigger
id:
- notify
then:
- service: notify.mobile_app_sm_g970u1
data:
message: We ready to turn on circulation now?
sequence: null
- if:
- condition: not
conditions:
- condition: state
entity_id: timer.hot_water_off_timer
state: active
then:
- service: scene.turn_on
target:
entity_id: scene.hot_water_switch_1_on
data: {}
mode: single
since you have the timer now that is turned on whenever the water starts, i think you can now get rid of your while loop and the wait for … and instead add a trigger for whenever the timer finishes.
the reason is that if the timer is going already then you don’t need a wait… because when it finishes, it will trigger this automation. you also don’t need a while loop because when you turn on the hot water, it will set a timer that will eventually hit this automation… turn on the water which will set your timer… which will eventually fire and … and it will keep doing this until it violates your condition…
i didn’t really understand the conditions when you want to be notified, so i put some code in to notify on the 3 cases you were being notified before and not on the case of every 20 minutes (the timer event).
i am not setup to test this code, so all caution as appropriate… no refunds… but maybe the concept is helpful to you to simplify your code…
I tried streamlining it as you suggested, and logicallly it should work. But I ran into this problem though. It will run once, but then maybe because the timer state check happens so frequently afterwards, the automation times out:
Error: While condition [{‘condition’: ‘time’, ‘after’: datetime.time(10, 15), ‘before’: datetime.time(17, 0), ‘weekday’: [‘sat’, ‘fri’, ‘thu’, ‘wed’, ‘tue’, ‘mon’, ‘sun’]}, {‘condition’: ‘zone’, ‘entity_id’: [‘device_tracker.sm_g970u1’], ‘zone’: [‘zone.home’]}] terminated because it looped 10000 times
A separate question regarding timer + helpers–the 2 are linked and the helper is created when I create the timer? I could have sworn when I first created the timer automation, it automatically created the helper and input the duration?
However, if I edit the timer duration in my automation, the duration in the helper does not change. Is that normal behavior, that editing the timer automation afterwards will not sync the duration in the helper? What issues will this cause if the two are different durations?
strange that it would have looped 10000… since there’s a delay 22mins there and you’re breaking the condition after 5pm… seems like it should stop each day and never loop more than 100 times a day.
can you post your very final automation and let me see? to help avoid any misunderstanding, post all related code… your latest of your main circulation as well as the timer getting triggered. let’s just look at the whole thing to make sure it’s all set.
all the more reason to do the final solution though… it has no loops whatsoever…
to answer your other question…
you asked:
helper is created when I create the timer?
i’m not sure what you mean. the timer helper IS the timer. they are one and the same. the timer automation starts the timer helper… you should do that whenever the water pump turns on. you don’t create helpers in code.
when you start the timer helper, you have the option to specify the duration. if you specify the duration, that duration will be used that time the timer is run… it will not change the default. if you do not specify a duration, the default duration is used.
in the example i gave, there is only 1 timer. the timer is an entity. so if you call to start the timer twice in short succession , the second call will restart the timer… essentially nullifying the first call.
hopefully that was all clear. holler if i’ve confused things!
Ahh, I see where I went wrong. I misread your last comments entirely on not needing a loop and didn’t see that you removed the loop entirely and added the timer.finished event to the initial triggers.
For laughs, here’s the bad frankenstein code I was running:
alias: Bad midday code
description: Turn on circulation when home during midday
trigger:
- platform: time
at: "10:15:00"
- platform: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
event: enter
- platform: homeassistant
event: start
condition:
- condition: time
after: "10:15:00"
before: "17:00:00"
weekday:
- sat
- fri
- thu
- wed
- tue
- mon
- sun
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
action:
- service: notify.mobile_app_sm_g970u1
metadata: {}
data:
message: We ready to turn on circulation now?
- repeat:
sequence:
- if:
- condition: not
conditions:
- condition: state
entity_id: timer.hot_water_on_timer
state: active
then:
- service: scene.turn_on
metadata: {}
target:
entity_id: scene.hot_water_switch_1_on
while:
- condition: time
after: "10:15:00"
before: "17:00:00"
- condition: zone
entity_id: device_tracker.sm_g970u1
zone: zone.home
mode: single
So as long as the timer was active, it kept looping thousands of times waiting for it to turn idle.
Regarding my timer/helper question, I found that if I edit the timer duration here (19 min):
alias: Time since hot water on
description: Use to limit hot water turning back on
trigger:
- platform: state
entity_id:
- switch.hot_water_socket_1
from: "off"
to: "on"
condition: []
action:
- service: timer.start
metadata: {}
data:
duration: "00:19:00"
target:
entity_id:
- timer.hot_water_on_timer
mode: single
The duration here under the helper settings (19 min) did not always match:
ah right… if you use the thing i did at the end, you need to both remove the loop, but add the time ending as one of the triggers. doing one without the other doesn’t work