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

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

Thank you again, I shall try to get this working :slight_smile: Just to clarify that I still call the script like currently, just add the wait_template to the automation?

no, as said, id first try to change the sensor in the trigger part to this new binary_sensor you have to make.