How to turrn lights off with sunset but at a minimum time?

I have a light on a Tuya plug for my fish tanks that I have been using an automation to turn off 1hr before sunset, however as the nights are closing in this is now triggering around 14:50. I’d like to set a minimum turn off time at 16:00.

I’ve seen similar issues but the other way around, where a light turns on at sunset or a time, typically the condition that occurs first triggers the action, but I need the latter event to trigger the action, so far nothing I’ve tried works.

This is what I’ve tried and how I’ve interpreted what it’s supposed to do:

My initial test - Turn off the lights 1hr before sunset but only after 16:00
(I can see why this doesn’t work because sunset is not occurring after 16:00)

- id: '1600967437672'
  alias: 'Fish: Fish Lights off'
  description: ''
  trigger:
  - event: sunset
    offset: -01:00:00
    platform: sun
  condition:
  - condition: time
    after: '16:00'
  action:
  - device_id: 2b23566d5e4640c09e1cde310f1c9605
    domain: switch
    entity_id: switch.32066407cc50e3d46c9e_4
    type: turn_off
  mode: single

When the sun’s elevation is below 3.5 turn off the lights, but only when the time is after 16:00
(I don’t see why this doesn’t work because the sun’s elevation is below 3.5 at 16:00 in the winter)

- id: '1607474680677'
  alias: 'Fish: Fish Lights Off Elevation'
  description: ''
  trigger:
  - platform: numeric_state
    entity_id: sun.sun
    attribute: elevation
    below: '3.5'
  condition:
  - condition: time
    after: '16:00:00'
  action:
  - type: turn_off
    device_id: 2b23566d5e4640c09e1cde310f1c9605
    entity_id: switch.32066407cc50e3d46c9e_4
    domain: switch
  mode: single

Set the status of a boolean to off (which in turn triggers the lights) 1hr before sunset but only after 16:00 and whilst the boolean is set to on, check every 10 minutes.

- id: '1607679428050'
  alias: 'Boolean Trigger: Fish Lights off'
  description: ''
  trigger:
  - event: sunset
    offset: -01:00:00
    platform: sun
  - platform: time_pattern
    minutes: '10'
  condition:
  - condition: and
    conditions:
    - condition: time
      after: '16:00:00'
      weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
    - condition: state
      entity_id: input_boolean.fishlight_status
      state: 'on'
  action:
  - service: input_boolean.turn_off
    data: {}
    entity_id: input_boolean.fishlight_status
  mode: single

I also want to be able to override this behaviour and turn the lights on/off manually in the evening (when cleaning the fish tanks) so I don’t want the turn off event to keep triggering whenever the sun’s elevation or time updates (hence the boolean helper).

How can I best handle this?

use a template trigger:

trigger:
  - platform: template
    value_template: "{{ state_attr('sun.sun', 'elevation') <= 3.5 and now().hour >= 16 }}"

I gave this a try, I put it in and reloaded my automations but it got to 16:00 today and the lights still didn’t turn off

post the entire code for your automation right now that didn’t work.

This is the entire code:

- id: '1607474680677'
  alias: 'Fish: Fish Lights Off Elevation'
  description: ''
  trigger:
  - platform: template
    value_template: '{{ state_attr(''sun.sun'', ''elevation'') <= 3.5 and now().hour <= 16 }}'
  condition: []
  action:
  - type: turn_off
    device_id: 2b23566d5e4640c09e1cde310f1c9605
    entity_id: switch.32066407cc50e3d46c9e_4
    domain: switch
  mode: single

I entered the line in exactly as you’ve written above

value_template: "{{ state_attr('sun.sun', 'elevation') <= 3.5 and now().hour >= 16}}"

but the UI changes it to

value_template: '{{ state_attr(''sun.sun'', ''elevation'') <= 3.5 and now().hour <= 16 }}'

If you put the template into the template editor a bit after 16:00 what is the value returned (true or false)?

For

value_template: "{{ state_attr('sun.sun', 'elevation') <= 3.5 and now().hour >= 16}}"
value_template: "True"

It’s currently 20:50, so for

value_template: "{{ state_attr('sun.sun', 'elevation') <= 3.5 and now().hour >= 21}}"
value_template: "False"

For what the UI is correcting it to:

value_template: '{{ state_attr(''sun.sun'', ''elevation'') <= 3.5 and now().hour <= 16 }}'

TemplateSyntaxError: expected token ',', got 'sun'

You said the UI is correcting it to the following:

But I don’t see why the UI is correcting the part that has “>=16” to “<=16”?

The other thing is if the UI is adding the quotation marks then I’m not sure why it would then complain about the syntax.

Can you manually edit the yaml and add the template exactly as I put it and then see if it gives the same error?

Sorry, that’s from me not correcting back fully after trying some tests after the light failed to turn off at 16:00 - i.e. I tried to see if the conditions would trigger before 18:00

I’ve pasted it into the automations.yaml, it’s not showing any error, however if I come back it’s still changing the quotations and giving the error when I try that in the Developer Tools Template tester

Hmmm… that’s strange.

The UI editor adds those extra quotation marks to “escape” the quotation marks used in the template.

Normally when writing out the templates using yaml you need to use different types of quotation marks on the inside of the brackets {{…}} than you do on the outside. For example if you write it out manually you can use "" on the outside and '' on the inside (as in my code) or the other way around using '' outside and "" inside.

The UI editor only uses a single type of quotation mark so it has to use a different method to differentiate between the inner and outer single quotation marks. It does it by “escaping” the inner quotation marks by using two single quotation marks in a row to denote a single inside quotation mark.

The strange part is using that same syntax in the template editor doesn’t work and throws the error you are seeing. I just tried it on mine and I get the same error.

I’m really sorry that trhis doesn’t seem to be going as I had planned. This is another good justification for why I never use the UI editors.

But as long as the template is entered as I wrote it above it should work even if the UI editor modifies it to escape the quotes.

Are there any errors in the home-assistant.log file related to that automation?

If not then there are a couple of options…

we can keep trying to go down the path of troubleshooting this method using a template trigger but that’s getting more complicated since it’s hard to troubleshoot something that really should be working - especially since it’s returning the proper values (true) in the template editor the wsay I wrote it.

The other is modifying the original automation using different combinations of triggers and conditions (and foregoing the template) to accomplish the same thing.

I can do either. Just let me know how you want to proceed.

It’s even from when adding the lines directly into automations.yaml in the file editor that it’s correcting too.

I did notice this formatting in the demo template:

{% if is_state("sun.sun", "above_horizon") -%}

So I’ve just tried this in the automation, which it does not alter the quotations when going back and forth from the yaml editor to UI, which seemed more promising

{{ state_attr("sun.sun", "elevation") <= 3.5 and now().hour >= 1}}

Unfortunately this still hasn’t triggered the lights to turn off after watching the clock tick over and the value in the template editor change from false to true.

There’s nothing relating to it in the log either and the automation says it has never been run

It’s always the case isn’t it lol, it should work.

Ideally I would have liked to keep with using the 1hr before sunset trigger as I have no concept of how an elevation of 3.5 corresponds to time and how this may be affected through the year

I think it may have started working…
I left it overnight with this and now it’s showing some activity :face_with_raised_eyebrow:

{{ state_attr("sun.sun", "elevation") <= 3.5 and now().minute >= 30}}

aaand the lights were still on when I came home at 16:46…

I’ve come up with something which seems to work in tested scenarios, either where sunset comes first and where the minimum time comes first

So If it’s after 16:00, 1hr before sunset and the boolean is set to on, set the boolean to off (which turns off the light) - this allows me to override it manually directly via turning the switch on/off.

alias: 'Boolean Trigger: Fish Lights off'
description: ''
trigger:
  - platform: time_pattern
    minutes: /10
condition:
  - condition: and
    conditions:
      - condition: sun
        after: sunset
        after_offset: '-01:00:00'
      - condition: time
        after: '16:00:00'
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
          - sat
          - sun
      - condition: state
        entity_id: input_boolean.fishlight_status
        state: 'on'
action:
  - service: input_boolean.turn_off
    data: {}
    entity_id: input_boolean.fishlight_status
mode: single

Thank you for your help @finity, I really have no idea why the template didn’t work today when it seemed like it was going to after my test last night.

I believe I figured out why the template approach didn’t work.

Apparently there is a bug when using now() in a template trigger.

See here for more info (and the link to the bug report) - Add time to time object

I knew that I wasn’t crazy and it was supposed to work!

But I’m glad you got it working.

1 Like