Turn on switch on every 4th sunday at 7:30am

Is there any way I can turn on a switch every 4th sunday at a specific time?

I’d probably look to use an input_slider to track “which” Sunday it is, one automation to increase that each Sunday (say at 07:00), and then the other with a condition for the input_slider to be at 4, plus an additional action to reset the input_slider to zero.

This template will return true on the 4th sunday of every month:

{{(now().strftime("%d")|int>=22) and (now().strftime("%d")|int <=28) and (now().strftime("%w")|int==0)}}

And here it is in a sample automation that turns a switch on at sunrise the 4th Sunday of every month.

- alias: 4thSundaySwitch
  trigger:
    - platform: sun
      event: sunrise
  condition:
    condition: template
    value_template : '{{(now().strftime("%d")|int>=22) and (now().strftime("%d")|int <=28) and (now().strftime("%w")|int==0)}}'
  action: 
    - service: switch.turn_on
      entity_id : switch.sundayswitch
7 Likes

Thanks for that but it’s not quite what I am looking for.

I want it to run every 4th Sunday - not the 4th Sunday of the month. I was thinking if it could read my google calendar for a specific event that could do it but I don’t seem to be able to do that.

Then use the approach I suggested :wink:

input_slider:
  sunday_tracker:
    name: 'Which Sunday is it'
    initial: 0
    min: 0
    max: 4
    step: 1

automation:
  initial_state: 'on'
  alias: 'Increment Sunday'
  trigger:
    platform: time
    at '07:00:00'
  condition:
    condition: time
    weekday: sun
  action:
    service: input_slider.select value
    data_template:
      entity_id: input_slider.sunday_tracker
      value '{{ states.input_slider.sunday_tracker.state + 1 }}'

And then one more to use the state of 4, on a Sunday, which resets it to zero and takes your other action

2 Likes

Many thanks. I am a noob at this and a lot of what people say is all Greek to me. It eventually sinks in. Thanks.

Keeping a counter with an input slider or the new counter component will “kinda” work, but none of these components keep their state through reboot. So if you lose power, reboot your system, or do a system update you are going to lose track of where you were.

A more reliable method, but much more complex would be to write the state to a text file that does survive reboot. It might also be possible to track how many days it has been since your automation last fired and use that as your basis, but I’m not certain how that handles reboot either.

2 Likes

just an idea:

i’m not great at templating/jinja, but is it possible to hard code a starting sunday (say 24 sep 2017), then everyday calculate the number of days since the start date, and check if days mod 28 == 0?

1 Like

I like the idea of calculating mod 28 of days between dates. How can I do that?

i think something like this should work, but i haven’t thoroughly tested it or anything

- alias: sunday switch
  trigger:
    platform: time
    at: '07:30:00'
  condition:
    condition: template
    value_template: '{{((as_timestamp(now()) - as_timestamp("2017-09-24 07:30:00"))/86400) | round() % 28  == 0}}'
  action:
    service: switch.turn_on
    entity_id: switch.sundayswitch

the timestamp difference will be in seconds, so dividing by 86400 converts to days. can change the start date of course.

let me know how that goes.

So I tried to enter this but it’s not triggering. Any hint as to what I have wrong? I set it for a different time obviously and it didn’t trigger.

- action:
  - data:
      entity id: switch.coffeemaker
    service: switch.turn_on
  alias: Sunday Switch
  condition:
  - condition: template
    value_template: '{{((as_timestamp(now()) - as_timestamp("2017-09-24 07:30:00"))/86400)
      | round() % 28  == 0}}'
  id: '1506314379417'
  trigger:
  - entity_id: switch.coffeemaker
    from: 'off'
    platform: state
    to: 'on'
  - at: 07:30:00
    platform: time
- action:
  - data:
      entity id: switch.coffeemaker
    service: switch.turn_on
  alias: Sunday Switch
  condition:
  - condition: template
    value_template: '{{((as_timestamp(now()) - as_timestamp("2017-09-24 07:30:00"))/86400)
      | round() % 28  == 0}}'
  id: '1506314379417'
  trigger:
  - at: 07:30:00
    platform: time

I think I screwed up - does this look better as a trigger?

A question - wouldn’t I use 2017-09-24 00:00:00? I don’t think the 7:30 in the test is significant is it? I really just want to know if it’s day zero?

can you post your code inside triple backticks? start and end a code block with ```. otherwise it’s hard to tell if indentation, order, etc. might be an issue.

just a guess (depends on where you live): did you run it last night with the start date/time as “2017-09-24 07:30:00” (or maybe a date in the past but left it as 7:30am)?

for example, let’s say you ran it last night at 10pm with the starting timestamp as “2017-09-24 07:30:00”. the value_template will round to 1 rather than 0 since it’s greater than half a day. that’s the reason i put 7:30am in the value_template as well – to ensure that it doesn’t round up/down to the wrong number of days.

in a different programming language i’d probably use “2017-09-24 00:00:00” and floor() instead of round() so the time wouldn’t have to be hard coded, but i don’t think an equivalent to floor() exists in home assistant.

there might also be a way to do this:

  value_template: '{{((as_timestamp("TODAYS DATE" 00:00:00) - as_timestamp("2017-09-24 00:00:00"))/86400) | round() % 28  == 0}}'

but i don’t know how.

just realized “2017-09-24 00:00:00” and int instead of round() might work, but i haven’t tried.

yeah, i think this works for the value_template:

'{{((as_timestamp(now()) - as_timestamp("2017-09-24 00:00:00"))/86400) | int % 28 == 0}}'

i imagine there’s a chance if you’re triggering an automation at midnight that it would miscalculate because of time precision issues, but that’s not your case here anyway.

Youch!!!

You’v been busy while I was sleeping.

What I did was try and trigger it yesterday afternoon but nothing happened. I’ll try the above and see if I can make it trigger this morning and I’ll post my code.

My automation is validating so I think at that level it’s all OK but let me have a bit of a play and I’ll get back here and let you know.

Thanks for your help. I appreciate it a lot!

Also wondering if I can run a script or ? from the command line so I can see what values the functions are actually returning? I’d like to see what “as_timestamp(now()” actually is in seconds…

Also I’m assuming it’s using local time in HA for this?

OK! It says in HA it triggered but it’s not turned on. I will need to check the entity name somehow. It’s a Wemo switch and it was autodetected in HA. I got the entity name from the states page under current entities.

Error: 2017-09-26 10:42:00 ERROR (MainThread) [homeassistant.core] Invalid service data for switch.turn_on: extra keys not allowed @ data[‘entity id’]. Got ‘switch.coffeemaker’

Here’s my code: (I am using the pre tag here so spaces should all be ok)

- action:
  - data:
      entity id: switch.coffeemaker
    service: switch.turn_on
  alias: Sunday Switch
  condition:
  - condition: template
    value_template: '{{((as_timestamp(now()) - as_timestamp("2017-09-26 00:00:00"))/86400)
      | int % 28  == 0}}'
  id: '1506314379417'
  trigger:
  - at: '10:42:00'
    platform: time

This was what I just tried now and it did fire at 10:42 but nothing happened and I got the error I posted above.

So close now I can taste it! haha.

Holy Crap!!!

I just removed the entity id line from the action so now my action is just {} and it triggered! My coffee maker turned on.

Why the hell doesn’t it need the entity name? and what would happen if I had more than one switch?

If you don’t specify the entity, then it turns on all switches.

Your problem is that you didn’t format the action correctly, if you look at the switch documentation (link above), you’ll see it should be:

- action:
    service: switch.turn_on
    entity id: switch.coffeemaker