Wait_template in automation melting my head

I’m trying to use a wait_template to keep a light on until the sensor which triggered the automation has not been triggered for a minute or two.

ATM I am using an input_boolean as a fake input to trigger the automation.

The automation works correctly up to the wait statement and works completely if the wait is removed.

The Hass template editor proves this template works correctly.

Really losing my head now!

#####################################
# MOTION ACTIVATED KITCHEN LIGHTING #

#####################################

# turn on kitchen ceiling light if motion detected
# in kitchen. bright white if dusk-midnight,
# dull yellow if midnight-dawn. store the current
# state of the light before changing it. Restore to
# stored state two minutes after motion has stopped.
# Do not run this automation if the intruder alarm is armed.

- id: auto kitchen light
  alias: auto kitchen light
  trigger:
    # if motion detected in kitchen
    platform: state
    entity_id: input_boolean.fake_motion #DEBUG
    from: 'off'
    to: 'on'
  condition:
    condition: and
    conditions:
      # start monitoring 45mins before sunset
      - condition: sun
        after: sunset
        after_offset: '-0:45:00'
      # stop monitoring 45mins after dawn
      - condition: sun
        before: sunrise
        before_offset: '0:45:00'
      # do NOT trigger if intruder alarm is armed
      - condition: state
        entity_id: input_boolean.intruder_alarm
        state: 'off'
  action:
    # STOP this auto from triggering again during execution
    - service: automation.turn_off
      entity_id: automation.auto_kitchen_light
    # STORE current state of kitchen light
    - service: python_script.light_store
      data:
        store_name: kitchen_store
        entity_id: light.bedroom #DEBUG  
      # SWITCH ON kitchen light
    - service: light.turn_on
      data_template:
        entity_id: light.bedroom #DEBUG 
        # IF between midnight & 5am brightness = 100  ELSE brightness = 255.
        brightness: '{% if now().hour > 0 and now().hour < 5 %} 100  {% else %} 255 {% endif %}'
        # IF between midnight & 5am colour = orange  ELSE colour = white
        color_name: '{% if now().hour > 0 and now().hour < 5 %} orange  {% else %} white {% endif %}'
    # WAIT UNTIL no motion in kitchen for one two minutes
    - wait_template: '{{ ((as_timestamp(now()) - 
as_timestamp(states.input_boolean.fake_motion.last_changed)) | int ) > 30 }}' #DEBUG 
    # RESTORE LIGHT to the state they were in before automation triggered
    - service: python_script.light_store
      data:
        store_name: kitchen_store
        operation: restore
    # ENABLE AUTOMATION to run again
    - service: automation.turn_on
      entity_id: automation.auto_kitchen_light 

the actual line above causing the problem is:

  • wait_template: ‘{{ ((as_timestamp(now()) -
    as_timestamp(states.input_boolean.fake_motion.last_changed)) | int ) > 30 }}’

It should pause the automation until the fake motion input has not changed state for thirty seconds. The automation actually freezes at this point even though the template has changed from ‘false’ to ‘true’.

EDIT
Just realised my conditions don’t work correctly either! I had them disabled whilst debugging. Supposed to allow auto to trigger just before dark to just after first light, and not trigger if the alarm is set. Any ideas where I’ve gone wrong?

Thank you for looking.

You can’t use now() because it is only evaluated ‘at this moment’, use the time sensor.

Fixed conditions problem. The sunrise/sunset statements were over lapping. Didn’t realise sunset means sunset-midnight and sunrise means midnight-sunrise. Solution was to nest an ‘or’ condition for the sun settings and ‘and’ that with the alarm state check.

# only active between '45mins before dusk' and '45mins after dawn' AND when alarm not set
  condition:
    condition: and
    conditions:
      # is intruder alarm disarmed?
      - condition: state
        entity_id: input_boolean.intruder_alarm
        state: 'off'
      - condition: or
        conditions:
          # is time between '45mins before sunset' and 'midnight'?
          - condition: sun
            after: sunset
            after_offset: "0:45:00"
          # is time between 'midnight' and '45mins after sunrise'?
          - condition: sun
            before: sunrise
            before_offset: "0:45:00"

thanks for the reply mf_social.

I used now() because I need a fixed point to subtract the increasing amount of time the input’s state was last changed from. Could you give me a clue as to how you would use sensor.time in my case?

The template I am trying to use is one I have seen other lighting automations use many times. This is my first time using it though.

Here is an example from another thread

 {{as_timestamp(now()) | int - 
          as_timestamp(states.sensor.master_bedroom_motion_sensor.last_changed)) 
         | default(0) | int > 120 }}

you won’t need it in your template, (if you use my example you refer to) since the template finds the last_changed of the motion_sensor.
You only need the sensor.time if you use now() and now() only, or other entities the template parser can’t find a timestamp in.

like this:

  dayofyear:
    friendly_name: 'Day Number'
    entity_id: sensor.time
    value_template: >
      {{ now().strftime('%j') }}
1 Like

Not in a wait_template.

A wait_template waits for the value of the template to be evaluated as true.

When your automaton gets to that point the template evaluates to false and is never reevaluated because now() is ‘at this moment’, which was the time you first got to it.

Creating a template sensor similar to @Mariusthvdb and using the state of that sensor in your wait_template is probably the best option.

1 Like

Thank you so much, It works! I guess I should’ve read your thread more closely. Little bit annoying that as usual we have to generate dummy sensors etc. to enable complex behaviour. Really wish I’d done this in Node-Red!

Here is my dummy template_sensor that watches my actual kitchen PIR sensor:

binary_sensor:
- platform: template
 sensors:
    kitchen_pir_monitor:
      friendly_name: 'kitchen pir retriggered'
      value_template: >
        {{ is_state('input_boolean.fake_motion','on')}}
      delay_off:
        seconds: 10 #DEBUG
    #    minutes: 1
      device_class: motion

This is the complete and functional automation:

# turn on kitchen ceiling light if motion detected
# in kitchen. bright white if dusk-midnight,
# dull yellow if midnight-5am, bright white again if
# 5am-sunrise store the current state of the light before
# changing it. Restore to stored state two minutes after 
# motion has stopped.
# Do NOT run this automation if the intruder alarm is armed.

- id: auto kitchen light
  alias: auto kitchen light
  trigger:
    # if motion detected in kitchen
    platform: state
    entity_id: input_boolean.fake_motion #DEBUG
    from: 'off'
    to: 'on'
# only activate dusk till dawn and when alarm not set
  condition:
    condition: and
    conditions:
      # is intruder alarm disarmed?
      - condition: state
        entity_id: input_boolean.intruder_alarm
        state: 'off'
      - condition: or
        conditions:
          # is time between '45mins before sunset' and 'midnight'?
          - condition: sun
            after: sunset
            after_offset: "0:45:00"
          # is time between 'midnight' and '45mins after sunrise'?
          - condition: sun
            before: sunrise
            before_offset: "0:45:00"
  action:
    # STOP this auto from triggering again during execution
    - service: automation.turn_off
      entity_id: automation.auto_kitchen_light
    # STORE current state of kitchen light
    - service: python_script.light_store
      data:
        store_name: kitchen_store
        entity_id: light.bedroom #DEBUG  
      # SWITCH ON kitchen light
    - service: light.turn_on
      data_template:
        entity_id: light.bedroom #DEBUG 
        # IF between midnight & 5am brightness = 100  ELSE brightness = 255.
        brightness: '{% if now().hour > 0 and now().hour < 5 %} 100  {% else %} 255 {% endif %}'
        # IF between midnight & 5am colour = orange  ELSE colour = white
        color_name: '{% if now().hour > 0 and now().hour < 5 %} orange  {% else %} white {% endif %}'
    # WAIT UNTIL no motion in kitchen for two minutes
    - wait_template:  "{{ is_state('binary_sensor.kitchen_pir_monitor','off')}}"
    # RESTORE LIGHT to the state they were in before automation triggered
    - service: python_script.light_store
      data:
        store_name: kitchen_store
        operation: restore
    # ENABLE AUTOMATION to run again
    - service: automation.turn_on
      entity_id: automation.auto_kitchen_light

Thanks again for your help, really is very much appreciated.

2 Likes

cool, and as always, glad to be of any help.

2 Likes