If statement in automation to determine triggers "for:" time

right, please do. Thing is, Ive just tested the same setup, with a few adjusted entities in my HA instance, and the original script/automation set works as expected, and no errors arise…

17

Did have to make 1 extra service call, which I had expected tbh. We have to cancel the script first, before we call it again in the automation. This is to prevent calling an already running script, in the case of turn_on.

What I did notice when copying from the community here, is sometimes incorrect quotes are used. These quotes pass the config checker, but don’t pass the real life situation. And have unrelated errors in the logs, causing one to search in the wrong direction…
So always check all quotes extra before hating restart.

this is what I just tested:

script:
  switch_off_lights_delay:
    alias: Switch off lights with delay
    sequence:
      - delay:
          minutes: >
            {{ '1' if states('input_number.presence_timer' ) | int >= 150 else '2' }}
      - service: light.turn_off
        entity_id: light.living

and automation:

  - alias: 'Living lights off when no motion'
    id: 'Living lights off when no motion'
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: binary_sensor.auditorium_motion_sensor
    condition: []
    action:
      - service: script.turn_off
        entity_id: script.switch_off_lights_delay
      - service_template: >
          script.turn_{{ 'on' if is_state('binary_sensor.auditorium_motion_sensor','off') else 'off' }}
        entity_id: script.switch_off_lights_delay

tested the various timings with the input_numner and the correct change in switch_off delay.
also tested movement during the delay, causing restart of the automation, script and timing again.

so for now, this minimal setup has your desired effect.

there’s one thing you need to consider still:
what will happen when the humidity changes to below/above the threshold during the delay.
Right now, humidity isn’t a trigger for the automation, and I think that is correct. One could argue an extra numeric trigger for humidity with a below, or above setting, depending on the rest of the automation.
This would however complicate things considerably, so Id suggest you see first how you fare with the current combination, and come back with results, and see if a further adjustment would be desired.

Also, set the Hue app accessory details to a correct level of movement and light sensitivity. We can program everything you want in HA, but if the App sets the motion sensor to insensitive, it won’t ever trigger …:wink:

check this, it might save you lot of headaches (see overrides part)

wow, that’s a nice package, thanks for posting! never saw it before, so will study with much interest.

for the current topic, this still might be overkill, and way more complex than 1 small automation and accompanying script. But it sure could be very interesting if it would cover the whole Home :wink:

Never gotten around to Appdeamon myself, but since this seems to be a complete component, it might be easier on the learning curve…

me neither, but it was trasformed to a custom_compopnent, so now its way easier

check my config

lithingsm:
      guest_room: 
        sensor: binary_sensor.pir_guest_room
        entity: light.standing_lamp
        service_data:
          brightness: 255
        start_time: '18:00:00'
        end_time: '07:00:00'
        delay: 120
        sensor_type_duration: True
        overrides:
          - media_player.denon_receiver
          - binary_sensor.auto_lights_override
          - binary_sensor.guest_room_lights_override


    binary_sensor:
      - platform: template
        sensors: 
          guest_room_lights_override:
            value_template: '{% if is_state("binary_sensor.pir_guest_room", "on") and states("sensor.illumination_guest_room")|float < 8 %} off {% else %} on {% endif %}'
            device_class: motion        
            friendly_name: Not motion-low light guest room
     - platform: template
        sensors: 
          auto_lights_override:
            friendly_name: 'Auto Lights Override'
            value_template: >-
              {{  not ( ( state_attr('sun.sun','elevation')|int < 5  or ( state_attr('sun.sun','elevation')|int < 15 and states('sensor.dark_sky_cloud_coverage')|int > 90 ) )         
            }}

I will! cool.
A quick glance though shows the value_template in your overrides, that resemble the beginning of this thread though… It’s always the finetuning when automatic takeover causes us to be bothered by exceptions :wink:

to finalyze this thread, thanks to the OP @Jonde :+1: I now have this little but effective combination added to my setup, which will easily be translated to a broader set of lighting scene in my use-case:

automation:
  - alias: 'Living lights off when no motion'
    id: 'Living lights off when no motion'
#    initial_state: 'on'  #use restore state for this
    trigger:
      platform: state
      entity_id: binary_sensor.auditorium_motion_sensor #use the new Hue CC creating binary_sensors for the motion_sensor
    condition: [] # took these out since I don't need that
    action:
      - service: script.turn_off
        entity_id: script.switch_off_lights_delay
      - condition: template
        value_template: >
          {{ is_state('binary_sensor.auditorium_motion_sensor', 'off') }} #need only to check for state 'off' now
      - service: script.switch_off_lights_delay 

and script:

  switch_off_lights_delay:
    alias: Switch off lights with delay
    sequence:
      - delay:
          minutes: >
            {{ states('input_number.lighting_timer' )|int }}  # I use another template, but that is of no importance, as long as the templates evaluates to a correct number ;-)
      - service: light.turn_off
        entity_id: light.living # further development can use variables here, to make it more generic and re-usable with other lights and scenarios 

this is new:

input_number:
  lighting_timer:
    name: Lighting timer
    icon: mdi:timer
    initial: 20
    min: 0
    max: 60
    step: 10

and getting back to the OP’s needs, this should do it:

automation:

- alias: 'Bathroom lights off when no motion'
  id: 'Bathroom lights off when no motion'
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: sensor.bathroom_motion_sensor
  condition:
    condition: time
    after: '07:00:00'
    before: '00:00:00'
  action:
    - service: script.turn_off
      entity_id: script.switch_off_lights_delay
    - condition: template
      value_template: >
        {{ is_state('sensor.bathroom_motion_sensor', 'off') }}
    - service: script.switch_off_lights_delay

script:

switch_off_lights_delay:
  alias: Switch off lights with delay
  sequence:
    - delay:
        minutes: >
          {{ '2' if states('sensor.zha_01ddaf89_1_1029' ) | int >= 50 else '1' }}
    - service: light.turn_off
      entity_id: light.bathroom

__EDIT__UPDATE

since this automation is now working very promptly, I can see it being triggered to run the script more often than motion explains. And I should have anticipated that… sorry.
triggers with platform state trigger in each change in the state, not necessarily the state.state, but also the attributes changes. Since this is a motion_sensor with many attributes that change constantly:

39

we need to narrow down the triggering to only trigger on to: 'on' and to: 'off'

Ive changed the automation accordingly, adding also an extra condition that seems superflous but ensures for 100% the action won’t take place if condition isn’t met:

  - alias: 'Living lights off when no motion'
    id: 'Living lights off when no motion'
#    initial_state: 'on'
    trigger:
     - platform: state
       entity_id: binary_sensor.auditorium_motion_sensor
       to: 'on'
     - platform: state
       entity_id: binary_sensor.auditorium_motion_sensor
       to: 'off'
    condition:
      condition: template
      value_template: >
        {{ trigger.to_state.state in ['on','off'] }}
    action:
      - service: script.turn_off
        entity_id: script.switch_off_lights_delay
      - condition: template
        value_template: >
          {{ is_state('binary_sensor.auditorium_motion_sensor', 'off') }}
#          {{ trigger.to_state.state == 'off' }}
      - service: script.switch_off_lights_delay

I would ultimately use the {{ trigger.to_state.state == 'off' }} condition, but somehow this doesn’t pass, I don’t understand why just yet, because I use that in many automation elsewhere in the setup…

There’s so much info here, can you give me a rundown?

cool, main point is still here: Why won't this trigger.to_state.state evaluate correctly?

Yet another problem. I copied your code and made sure all the quotes are OK and so on. Automation triggers, script triggers but I get this in HA logs and the light won’t turn off.

Error doing job: Task exception was never retrieved

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/automation/__init__.py", line 294, in async_trigger
    await self._async_action(self.entity_id, variables, context)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/automation/__init__.py", line 378, in action
    await script_obj.async_run(variables, context)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/script.py", line 130, in async_run
    await self._handle_action(action, variables, context)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/script.py", line 172, in _handle_action
    action, variables, context)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/script.py", line 261, in _async_call_service
    context=context
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/service.py", line 81, in async_call_from_config
    domain, service_name, service_data, blocking=blocking, context=context)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/core.py", line 1121, in async_call
    self._execute_service(handler, service_call))
  File "/usr/local/lib/python3.6/site-packages/homeassistant/core.py", line 1143, in _execute_service
    await handler.func(service_call)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/script.py", line 94, in turn_off_service
    in component.async_extract_from_service(service)], loop=hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 304, in wait
    raise ValueError('Set of coroutines/Futures is empty.')
ValueError: Set of coroutines/Futures is empty

This is an error not yet experienced here. As a matter of fact, I don’t get any error, and the set runs perfectly. Switches on and off, triggers the script depending on set conditions and cancels and retriggers when motion happens during delay.

The error is about a loop , but there is no loop, it is why I made the adjustment in the action part, to first stop the script and consecutively run it if condition is met. You did take that version?

This I have

automation:

- alias: 'Bathroom lights off when no motion'
  id: 'Bathroom lights off when no motion'
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: sensor.bathroom_motion_sensor
  condition:
    condition: time
    after: '07:00:00'
    before: '00:00:00'
  action:
    - service: script.turn_off
      entity_id: script.switch_off_lights_delay
    - condition: template
      value_template: >
        {{ is_state('sensor.bathroom_motion_sensor', 'off') }}
    - service: script.switch_off_lights_delay

script:

switch_off_lights_delay:
  alias: Switch off lights with delay
  sequence:
    - delay:
        minutes: >
          {{ '2' if states('sensor.zha_01ddaf89_1_1029' ) | int >= 50 else '1' }}
    - service: light.turn_off
      entity_id: light.bathroom

please adjust to below :

- alias: 'Bathroom lights off when no motion'
  id: 'Bathroom lights off when no motion'
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: on
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: off
  condition:
    condition: time
    after: '07:00:00'
    before: '00:00:00'
  action:
    - service: script.turn_off
      entity_id: script.switch_off_lights_delay
    - condition: template
      value_template: >
        {{ is_state('sensor.bathroom_motion_sensor', 'off') }}
    - service: script.switch_off_lights_delay

and see if the adjusted trigger would prevent a loop by preventing unwanted triggering in attributes changes.

1 Like

Current situation is that the automation is working and the script is working. Have not tested the if humidity > 50 part yet.

So the light turns on when motion is detected and it will turn off after time has passed if there is no motion. If motion is seen during the timer, it will reset it. So now that part works as intetended!

I will keep testing and report back to you!

But again, thank you! This would have been impossible for me to tackle alone!

your most welcome!

as before, the humidity sensor might be causing unexpected issues, we have to research that deeper.

I did a quick test and changed the script so it will work with humidity >25 and it did change the value correctly and lights changed on longer.

So currently everything works :slight_smile: But testing continues!

Here is the working code:

Automation

- alias: 'Bathroom lights off when no motion'
  id: 'Bathroom lights off when no motion'
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: 'on'
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: 'off'
  condition:
    condition: time
    after: '07:00:00'
    before: '00:00:00'
  action:
    - service: script.turn_off
      entity_id: script.switch_off_lights_delay
    - condition: template
      value_template: >
        {{ is_state('sensor.bathroom_motion_sensor', 'off') }}
    - service: script.switch_off_lights_delay

Scripts:

switch_off_lights_delay:
  alias: Switch off lights with delay
  sequence:
    - delay:
        minutes: >
          {{ '2' if states('sensor.zha_01ddaf89_1_1029' ) | int >= 25 else '1' }}
    - service: light.turn_off
      entity_id: light.bathroom
1 Like

yess, indeed!

so you’ve got all variables in place, and things are much tidier than with the first attempts at a trigger template. Let alone the possibility of restart, and, important, extensibility.

Keep the feedback coming please!

EDIT
Btw have a look here, just stumbled on this thread Slider input delay off switch? Help what have I done wrong? where @pnbruckner creates the exact same solution …

Now that makes me smile.

Yes indeed that is the same solution :smiley:

The code seems to work for me too based on one night testing.

One thing I started to think about is that if I would like to make the logic better the automation would react to humidity on lower levels. This because now there is a chance that the humidity is still too low and the longer timer does not trigger. And also after the shower there is no need for the timer to be so long so the timer should be shorter but the humidity is still too high eventhoug it drops pretty fast (unless really long shower).

I think that would be the next step to make the code even better but need think closely on the facts that triggers the timers :slight_smile:

But for now, the code works so that it makes life easier :slight_smile:

Great.
And yes, that’s the way to go on and develop. Now it’s working and the logic and structure are as it should be, you can add conditions, or change current ones to your needs. Remember to decide where you add or change, in automation or scripts. If a script stops (because of a condition not being met, the main automation will still go on. While if you put all in the automation the automation would then stop …

Let us know how you fare!

1 Like

I have been using the automation for a while now and it seems to work pretty well. Only thing that I’m trying to change is that there would be 1 minute delay before the humidity is checked. This is because when someone goes to showe, motion sensor goes really fast to ‘off’ and this means that the automation triggers and humidity is still really low. If that would be delayed like a 1 minute, the humidity would have risen enough.

I tried to add delay to automation but that did not actually work. First it seemed like OK but later I noticed that the timer does not reset always when there are motion so it was not usable. The code looked like this (I tried multiple positions for the delay part so not sure if that was the best place for it):

- alias: 'Bathroom lights off when no motion'
  id: 'Bathroom lights off when no motion'
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: 'on'
    - platform: state
      entity_id: sensor.bathroom_motion_sensor
      to: 'off'
  condition:
    condition: time
    after: '07:00:00'
    before: '00:00:00'
  action:
    - service: script.turn_off
      entity_id: script.switch_off_lights_delay
    - delay: '00:01:00'
    - condition: template
      value_template: >
        {{ is_state('sensor.bathroom_motion_sensor', 'off') }}
    - service: script.switch_off_lights_delay

Scripts:

switch_off_lights_delay:
  alias: Switch off lights with delay
  sequence:
    - delay:
        minutes: >
          {{ '2' if states('sensor.zha_01ddaf89_1_1029' ) | int >= 25 else '1' }}
    - service: light.turn_off
      entity_id: light.bathroom

well, here you are,… this seems to be the exact issue I had when I wanted to have a delay built-in on the trigger, and created my intermediary binary_sensor template we discussed in the beginning of this thread.I use it as a wait_template, but maybe (behavior of these sensors is not always as you’d expect, so you have to try) you can already set in in the trigger section:

If suggest replacing the second trigger with a new sensor, it has a delay for the state Off of a minute, and if motion is detected won’t turn Off, so the automation won’t trigger on Off yet):

binary_sensor:
  - platform: template
    sensors:
      bathroom_motion_sensor_timed:
        friendly_name: 'Bathroom motion sensor timed'
        value_template: >
          {{ is_state('sensor.bathroom_motion_sensor','on')}}
        delay_off:
          minutes: 1
        device_class: motion

reason I suggest shit is it woud always reset the full automation if motion would occur during the wait.

I have an automation using this which is only triggered on to: on, so works a bit differently. I post it here for your information, and maybe second option to try if above wouldn’t go as you want it to:

  - alias: 'Switch Masterbed outlet when movement'
    id: 'Switch Masterbed outlet when movement'
#    initial_state: 'on'
    trigger:
      platform: state
      entity_id: binary_sensor.master_bedroom_motion_sensor
      to: 'on'
    condition:
      - condition: template
        value_template: >
          {{ is_state ('sensor.activity_selection', 'Slapen')}}
      - condition: template
        value_template: >
          {{is_state('switch.master_bed_outlet', 'off')}}
    action:
      - service: switch.turn_on
        entity_id: switch.master_bed_outlet
#      - wait_template: >
#          {{as_timestamp(now()) | int - 
#            as_timestamp(states.sensor.master_bedroom_motion_sensor.last_changed) | default(0) | int > 120 }}
      - wait_template: >
          {{ is_state('binary_sensor.master_bedroom_motion_sensor_timed','off')}}
#          {{ is_state('sensor.master_bedroom_motion_sensor', 'off') }}
#      - delay:
#          minutes: 1
      - service: switch.turn_off
        entity_id: switch.master_bed_outlet
      - condition: template
        value_template: >
          {{ is_state('input_boolean.notify_system', 'on')}}
      - service: notify.notify
        data_template:
          message: >
            {{as_timestamp(now()) | timestamp_custom("%X") }}: You've walked safely lit. Signing off.

please note the commented delays and other options Ive left in to see what didn’t work :wink:

1 Like