Automation based on a specified time

I have some blinds that I have configured in HA so I can make them go up and down. I have also made an automation for it to go down at 10PM and up again at 12AM. I would like to make it possible for me to set a time for the blinds to go up if I want them to go up earlier or later.
I have created an input_boolean named “wakeup” and two input_select named “hour” and “minutes”.

My idea was to make the automation look at “wakeup” and see if a new time was set or not. If it is set it should take the time from “hour” and “minutes” and make the blinds go up at that time instead of 12AM.

But I can’t seem to get it to work.

My current code looks like this:

>  - id: '1556565182056'                                                                                                                              
>   alias: Blinds up                            
>   trigger:                                                                                                                                         
>   - at: '12:00'                                                                                                                                    
>     platform: time                                                                                                                                 
>   condition: []                                                                                                                                    
>   action:                                           
>   - data_template:                                  
>       entity_id: cover.sovrum_norr, cover.sovrum_ost
>     service: cover.open_cover

I would suggest using a Template Trigger. You’ll also need to enable sensor.time. Maybe something like this:

- id: '1556565182056'
  alias: Blinds up
  trigger:
    - platform: template
      value_template: >
        {% if is_state('input_boolean.wakeup', 'off') %}
          {{ is_state('sensor.time', '12:00') }}
        {% else %}
          {% set time_now = states('sensor.time').split(':') %}
          {% set hour = time_now[0]|int %}
          {% set minutes = time_now[1]|int %}
          {{ states('input_select.hour')|int == hour and
             states('input_select.minutes')|int == minutes }}
        {% endif %}
  ...

BTW, '12:00' is 12PM (aka noon), not 12AM. :wink:

Thank you for helping me(even with the clock… :wink: ). Unfortunately it doesn’t work. Probably am I doing something wrong… I have tried the following:

- id: '1556603923223'                               
  alias: Blinds up                           
  trigger:                                          
    - platform: template                            
      value_template: >                             
        {% if is_state('input_boolean.wakeup', 'off') %}
          {{ is_state('sensor.time', '12:00') }}        
        {% else %}                                      
          {% set time_now = states('sensor.time').split(':') %}
          {% set hour = time_now[0]|int %}                     
          {% set minutes = time_now[1]|int %}                  
          {{ states('input_select.hour')|int == hour and states('input_select.minutes')|int == minutes }}
        {% endif %}                                                                                                                                
  condition: []                                                                                          
  action:                                                                                                
  - data_template:                                                                                       
      entity_id: cover.sovrum_norr                                                                       
    service: cover.open_cover

Try this (and make sure the automation is on):

- id: '1556603923223'
  alias: 'Blinds up'
  trigger:
  - platform: template
    value_template: >-
      {% if is_state('input_boolean.wakeup', 'off') %}
        {{ is_state('sensor.time', '12:00') }}
      {% else %}
        {{ states('input_select.hour')|int == now().hour and states('input_select.minutes')|int == now().minute }}
      {% endif %}
  action:
  - service: cover.open_cover
    data:
      entity_id: cover.sovrum_norr

Thank you for your help. Unfortunately this didn’t work either…

I revised the template so sensor.time is in the first statement. This gives Home Assistant something to monitor and it will check it every minute. I tested the template on my system and it works.

- alias: 'Blinds up'
  trigger:
  - platform: template
    value_template: >-
      {% if is_state('sensor.time', '12:00')  %}
        {{ is_state('input_boolean.wakeup', 'off') }}
      {% else %}
        {{ is_state('input_boolean.wakeup', 'on') and 
           states('input_select.hour')|int == now().hour and 
           states('input_select.minutes')|int == now().minute }}
      {% endif %}
  action:
  - service: cover.open_cover
    data:
      entity_id: cover.sovrum_norr

EDIT
I was mistaken. There’s no need for the template’s first statement to contain an entity that Home Assistant can use for monitoring state-changes. As long as the template contains one such entity (that Home Assistant can readily detect) anywhere within it then Home Assistant will monitor it.

See pnbruckner’s comment below. I repeated my tests and confirmed it was true.

The entire template will be scanned for entities, and all the entities found will be monitored for state changes. The way I wrote the template it will find all the entities, so the template will be evaluated, and possibly trigger the automation, whenever input_boolean.wakeup, sensor.time, input_select.hour or input_select.minutes changes. Like all template triggers, it will “fire” if it evaluates to true at startup, and thereafter whenever it evaluates to true after having evaluated to false. (I.e., accept at startup, it has to change from false to true to actually trigger.)

@patrikhummel, have you made sure the automation is turned on? (@123 suggested that, too, but you didn’t comment on whether or not you checked.)

The version shown in this post, where the first statement checks the input_boolean, failed to trigger on my system (and patrik’s). It makes sense it should scan the entire template to create its listeners but I wasn’t getting any triggering until I moved sensor.time into the first if.

I’ll try again tomorrow to ensure the failure wasn’t due a testing error I may have made.

I returned to testing the automation with fresh eyes and you are 100% correct. Home Assistant scanned the entire template, found sensor.time, and proceeded to monitor the template for changes every minute. I’ve amended my earlier, erroneous comment about the alleged needs of the ‘first statement’.

This automation worked flawlessly on my system and toggled the light at whatever time I set with the input_selects.

- alias: 'test ib trigger'                           
  trigger:
    - platform: template
      value_template: >
        {% if is_state('input_boolean.wakeup', 'off') %}
          {{ is_state('sensor.time', '12:00') }}
        {% else %}
          {% set time_now = states('sensor.time').split(':') %}
          {% set hour = time_now[0]|int %}
          {% set minutes = time_now[1]|int %}
          {{ states('input_select.hour')|int == hour and states('input_select.minutes')|int == minutes }}
        {% endif %}
  condition: []
  action:
  - data_template:
      entity_id: light.family                                                                       
    service: light.toggle

This one, with the simplified method for acquiring the current hour and minute, also worked perfectly.

- alias: 'test ib trigger'                           
  trigger:
    - platform: template
      value_template: >
        {% if is_state('input_boolean.wakeup', 'off') %}
          {{ is_state('sensor.time', '12:00') }}
        {% else %}
          {{ states('input_select.hour')|int == now().hour and 
             states('input_select.minutes')|int == now().minute }}
        {% endif %}
  condition: []
  action:
  - data_template:
      entity_id: light.family                                                                       
    service: light.toggle

If neither of these two versions work for patrik then something else is causing the problem.

1 Like

I can’t figure out what I am doing wrong. I have tried all versions without good result.
I have made sure the automation and boolean is on. I have checked the logbook and it says it has turned on and that the input_selects has been set.

Thank you for trying to help me. I feel really lost…

Config right now:

> - id: '1556603923223'                               
>   alias: Rullgardin vakna                           
>   trigger:                                          
>     - platform: template                            
>       value_template: >                             
>         {% if is_state('input_boolean.wakeup', 'on') %}
>           {{ states('input_select.hour')|int == now().hour and
>              states('input_select.minutes')|int == now().minute }}
>         {% else %}                                                
>           {{ is_state('sensor.time', '12:00') }}                  
>         {% endif %}                                                                                                                                
>   condition: []                                                   
>   action:                                                         
>   - service: cover.open_cover                                     
>     data_template:                                                
>       entity_id: cover.sovrum_norr

Although it probably doesn’t matter, you can simplify your action like so:

  action:                                                         
  - service: cover.open_cover                                     
    entity_id: cover.sovrum_norr

Did you try manually triggering the automation to see if the action runs? The easiest way to do that is to find it on the States page, click the “More Info” button to the left of it, then click on the word TRIGGER. If that works then you can rule out the action part being the problem.

Have you checked that all the entity_id’s are correct and match the actual entity_id’s of your entities? If you have a typo in an entity_id, you won’t see an error, it just won’t work.

EDIT: I’m referring to input_boolean.wakeup, input_select.hour & input_select.minutes. Also, do you see sensor.time on the States page?

It worked when I found it in states page and triggered it. So I guess there is no error with the entity_id.

Sensor.time is not visible. Maybe this can be the problem?

That is indeed the problem. You must have overlooked this:

You need to make sure the following is in your HA configuration:

sensor:
  - platform: time_date
    display_options:
      - 'time'

Boom! There it is; the ‘something else’ in ‘something else is causing the problem’. :partying_face:

FWIW, I have sensor.time defined precisely the way it’s shown in pnbruckner’s example. Without it, you can’t reference sensor.time in a template and expect it to work.

Perhaps a future version of Config Check will complain about non-existent entities but it currently doesn’t.

So generally using states() or is_state() is encouraged, because it handles the situation where the entity doesn’t exist (which can happen with some entities in “normal” use. And actually, to be more accurate, it handles the situation where the entity is not represented in the state machine, whether or not it “exists.”) However, a downside is this situation - no warning that an entity that should exist doesn’t. This is where using states.sensor.time.state == '12:00' instead of is_state('sensor.time', '12:00') would have at least given a clue (i.e., I think it would have caused an error.) Not that I’m advocating… :wink:

And, in case you’re wondering, entity_id extraction from a template works just as well with states.domain.object_id... as with states('domain.object_id')... or is_state('domain.object_id', ....

If memory serves me correctly, I recall a post (possibly in the Architecture section of the Github repo) briefly discussing how they find entities within a template to monitor. Apparently, it involves the use of a regex search. Had I remembered that yesterday, I wouldn’t have made my absurd claim about the entity having to be in the template’s first statement! :man_facepalming:

I don’t know about that. I just looked at the perfectly clear code:

_RE_GET_ENTITIES = re.compile(
    r"(?:(?:states\.|(?:is_state|is_state_attr|state_attr|states)"
    r"\((?:[\ \'\"]?))([\w]+\.[\w]+)|([\w]+))", re.I | re.M
)

I’m sure the :bulb: just came on, right?! :laughing:

My lightbulb icon has a tiny “WTF?” in it. My regex-fu has met its match with that pattern.

I see a few recognizable things … but to truly grok it I’ll probably have to cheat and throw that beast into regex101.com.

1 Like