Turn off light after x minutes at certain brightness

Hey @Kbeesnees

Sorry I just got back to looking into this. I’m still having issues with the for statement. This appears to work (had to quote the alias and change the condition from ‘data_template’ to ‘value_template’) - at least it’s not erroring out. I’m not home to check how the light is behaving.

  - alias: 'Turn off dining room light when <50 brightness for 5 minutes'
    trigger:
      - platform: template
        value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float < 50  }}'
    condition:
      condition: template
      value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float < 50 }}'
      #for:
      #  minutes: '5'
    action:
      service: light.turn_off
      entity_id: light.dining_room_light_level_11_0 

As soon as I comment out the for lines though it throws a fit:

17-02-02 16:28:58 ERROR (MainThread) [homeassistant.bootstrap] Invalid config for [automation]: extra keys not allowed @ data['condition'][0]['for']. Got None
not a valid value for dictionary value @ data['condition'][0]['condition']. Got None
required key not provided @ data['condition'][0]['entity_id']. Got None. (See /home/hass/.homeassistant/configuration.yaml, line 426). Please check the docs at https://home-assistant.io/components/automation/

If I leave the condition as a data_template I get another error:

17-02-02 16:27:34 ERROR (MainThread) [homeassistant.bootstrap] Invalid config for [automation]: extra keys not allowed @ data['condition'][0]['data_template']. Got None
not a valid value for dictionary value @ data['condition'][0]['condition']. Got None
required key not provided @ data['condition'][0]['entity_id']. Got None. (See /home/hass/.homeassistant/configuration.yaml, line 426). Please check the docs at https://home-assistant.io/components/automation/

For template triggers and conditions, the right keyword is always value_template, never data_template.
Also, only the state trigger and condition support the for: statement. All the other triggers and conditions do not.

2 Likes

That’s what I had thought which is why I was confused.

Ahh so that would explain that error! Any thoughts then on how to get this to work?

I worked around this current limitation using a threshold binary sensor. In my use case, the state of this sensor is based on the luminance in my office:

- platform: threshold
  name: "Office Multi Luminance templated"
  threshold: 45
  type: upper
  entity_id: sensor.office_multi_luminance_3_3

That way, I can use a state trigger in my automation to switch off my desk lamps, combined with the for statement:

- alias: "Turn lights off when bright enough"
  trigger:
    - platform: state
      entity_id: binary_sensor.office_multi_luminance_templated
      from: 'off'
      to: 'on'
      for:
        minutes: 5
        seconds: 0
  condition:
    - condition: state
      entity_id: light.desk_lamps
      state: 'on'
  action:
    - service: light.turn_off
      data:
        entity_id: light.desk_lamps
        transition: 5
2 Likes

Ahh, ok that requires another sensor. Crap. No way to do this using just the brightness of the dimmer then?

Try making the action a script that waits for 10 minutes and then turns off the light.

kind of the opposite of this:

you’d also need an additional trigger to cancel the script run if the brightness went above 50%

There’s probably other ways to accomplish this, I’m just sharing the workaround I can live with personally.

For what it’s worth, there is a feature request on this forum: For-statement for automation with numeric state. So please vote! :wink:

I’m obviously not the best with templates but they are so powerful. It takes me some trial and error to get them working. I was working this out as well during the above conversation. You could try…

input_slider:
  - off_delay:
    name: Off Delay
    min: 0
    max: 20
    step: .5

automation:
  - alias: 'Turn off dining room light when at <50 brightness for set duration'
    trigger:
      - platform: template
        value_template: '{{ (as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= (states.input_slider.off_delay.state|float * 60) }}'
    condition:
      condition: template
      value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50 }}'
    action:
      service: light.turn_off
      entity_id: light.dining_room_light_level_11_0

@fanaticDavid, I didn’t realize “for” has those limitations. Thanks for this piece of info. Also didn’t realize (never thought about it) the difference between data_template and value_template. It makes sense now. I copied some of that code from another post somewhere and I’m sure they were using it correctly. :blush: Thanks again. Always learning, often from you.

If you don’t want the slider, use this for your trigger…
It is set at 300 seconds i.e. 5 minutes

{{ (as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= 300 }}
2 Likes

@mrtips, @fanaticDavid, and @Kbeesnees I think these suggestions should get me up and running, thanks! Time to do some testing and see if I can get a working automation. I’ll make sure to post what I end up using. Thanks for all your help!!!

1 Like

@Kbeesnees I’m FINALLY circling back to this one and am still unable to get it working. The switch is updating status as expected now (YAY!) but the automation still isn’t doing it’s job. I’m using your automation from the other thread:

  - alias: 'Turn off dining room light when at <50 brightness for set duration'
    trigger:
      - platform: template
        value_template: '{{ (as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= (states.input_slider.off_delay.state|float * 60) and  (states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50) }}'
    condition:
      condition: template
      value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50 }}'
    action:
      service: light.turn_off
      entity_id: light.dining_room_light_level_11_0

I have the slider set to 1 minute just for easy testing. I put it all the way one for a few minutes, then took it way down to like 10 brightness. Left it there almost 10 minutes and it never turned off. Any other thoughts?

Glad you figured out the cause and were able to get the switch to update correctly :slight_smile:

Can you test each part of the templates in the dev tools template editor individually to verify they are giving the expected results?

Does this result in true or false during the proper conditions? It should be true when the light hasn’t been adjusted for greater than duration set on the slider. It should be false if it was adjusted more recently than the time set on the slider.

{{(as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= (states.input_slider.off_delay.state|float * 60)}}

Does this result in true when the brightness level is below 50%?

{{(states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50)}}

EDIT: Also, make sure the light and input slider names are correct in the templates.

1 Like

As far as I can tell the parts are working as expected. Though the “last_update” (your first condition) seems to be returning true regardless but I’m wondering if that’s just a lag in my changing the state and that state updating in HASS since I have the slider at 1 minute. Pics:

So it should be triggering if changing from false to true. Are you able to cause conditions to make it result in false? I’m wondering if for some reason they are always returning true. It shouldn’t trigger unless moving from false to true. Also, we could try to take the input slider out for testing to simplify.

If you want to set a fixed value in seconds instead of using the slider, replace “(states.input_slider.dr_off_delay.state|float * 60)” with the number of seconds.

1 Like

Ok, I swapped out the slider for the time being to this code:

{{ (as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= 300 and (states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50) }}

It was false for ~5 minutes (didn’t time it exactly), then flipped to true. However the light remained on.

I feel like I’m missing something really stupid here…

Me too. I just realized, Silly me :blush: You want the switch to turn off. Change light.turn_off to switch.turn_off in the action.

1 Like

Still no joy. :frowning: I feel like we are close, just not quite there.

Sorry for the late response. Just came across another post that made me think of your situation. Part of the post said, [quote=“ih8gates, post:2, topic:12595”]
I have lots of trouble getting template triggers to work for me.
[/quote]
and

Any errors in your log that might have to do with the automation? I noticed a hyphen in front of platform in the trigger that isn’t needed because it is’nt a list. Might try removing that and verifying the formatting before trying the suggestion below.

The the suggestion above didn’t work, maybe the following will. Still trial and error like before so not sure if this will do it. Fingers crossed.

sensor:
  - platform: template
    sensors:
      brightness_trigger:
        value_template: '{{ (as_timestamp (now()) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated))|float >= (states.input_slider.off_delay.state|float * 60) and  (states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50) }}'
        friendly_name: 'Sun angle'

  - alias: 'Turn off dining room light when at <50 brightness for set duration'
    trigger:
      platform: state
      entity_id: sensor.brightness_trigger
      to: 'true'
    condition:
      condition: template
      value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50 }}'
    action:
      service: light.turn_off
      entity_id: light.dining_room_light_level_11_0

OK, So the post above will not work either but I have finally had time to sit down and try this myself with one of my automations. I found a post that had the solution here courtesy of @ReneTode. He also explains in that thread why what I was recommending doesn’t work and why this solution does. My brief understanding is you need a state change for a trigger to be tripped. It wont simply monitor the duration of a previous change. By creating the new sensor, it creates a state change every minute causing the template to be re-analyzed. I was able to successfully use this in an automation. Essentially the difference is this compares against a sensor with the system time that updates every minute instead of comparing against the system time directly.

sensors:
  - platform: time_date
    display_options:
      - 'date_time'

  - alias: 'Turn off dining room light when at <50 brightness for set duration'
    trigger:
      platform: template
      value_template: '(as_timestamp(states.sensor.date__time.last_updated)) -as_timestamp (states.light.dining_room_light_level_11_0.last_updated) >= 300 and (states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50)'
    condition:
      condition: template
      value_template: '{{ states.light.dining_room_light_level_11_0.attributes.brightness | float <= 50 }}'
    action:
      service: light.turn_off
      entity_id: light.dining_room_light_level_11_0
2 Likes

Hey @Kbeesnees thanks so much for this! I would love to test tonight but I sprained my ankle pretty bad so moving around and playing isn’t easy. :confused: I should be able to test tomorrow so I’ll let you know what I come up with. Thanks again and I really appreciate you working with me on this!!!