Automation based on time and illumination

I would like to create an automation that turns on the lights 15 minutes before sunset but not after 22:00 and only if the outdoor illumination is below 250 and indoor illumination is below 10 for 2 minutes.

I think I need it to trigger on outdoor illumination with the durration of 2 minutes, then set a condition based on indoor illumination and time and then set the action to turn on the lights. Any thoughts on this automation?

Try this:

alias: example 1
id: example_1
trigger:
- platform: sun
  event: sunset
  offset: '-00:15:00'
- platform: numeric_state
  entity_id: sensor.outdoor_light_level
  below: 250
condition:
- condition: time
  before: '22:00:00'
- condition: numeric_state
  entity_id: sensor.outdoor_light_level
  below: 250
- condition: numeric_state
  entity_id: sensor.indoor_light_level
  below: 10
action:
- service: light.turn_on
  target:
    entity_id: light.whatever

Change the entity names to match the ones you have in your system.

How it works

  • It is triggered 15 minutes before sunset or when outdoor light level is below 250.
  • It checks if:
    • The current time is before 22:00
    • The outdoor light level is below 250
    • The indoor light level is below 10
  • If all conditions evaluate to true then it executes the action (turns on a light).

The one thing it does not do is the part where you specified the indoor light level must be below 10 for at least 2 minutes. A State Condition can check if a value remains unchanged for a given period of time. For example this checks if the indoor light level has remained unchanged at 10 for 2 minutes:

  condition: state
  entity_id: sensor.indoor_light_level
  state: 10
  for: '00:02:00'

However, it means the light level cannot drop below 10 during those 2 minutes; it must remain unchanged. Therefore a State Condition would not meet your requirement. A Numeric State Condition doesn’t support a for option but it does handle your requirement for checking if the value is anything below 10.

There is a small, optional enhancement you can add and that’s to only turn on the light if it is currently off (do nothing if it is already on). It’s simply a matter of adding a State Condition:

alias: example 2
id: example_2
trigger:
- platform: sun
  event: sunset
  offset: '-00:15:00'
- platform: numeric_state
  entity_id: sensor.outdoor_light_level
  below: 250
condition:
- condition: time
  before: '22:00:00'
- condition: numeric_state
  entity_id: sensor.outdoor_light_level
  below: 250
- condition: numeric_state
  entity_id: sensor.indoor_light_level
  below: 10
- condition: state
  entity_id: light.whatever
  state: 'off'
- condition:
action:
- service: light.turn_on
  target:
    entity_id: light.whatever
1 Like

Sunset doesn’t really work as a trigger unless the other trigger is true. Could you not use the indoor light with a template trigger to satisfy the 2 minutes requirement. Then use sunset under condition?

Can you provide an example of it?

Just as a sidenote, if you are often working with the sun component, you should take a look at sun2 from pnbruckner.

You can find it here:

There you can setup some binary_sensors that you can use as triggers.

 trigger:
    - platform: numeric_state
      entity_id: sensor.indoor_light_level
      below: 10
      for: "00:02:00"

That’s a Numeric State Trigger. Your suggestion was to use a Template Trigger.

I was wondering how you intended to implement the “for 2 minutes” with a Template Trigger.

I’m really just learning this so when I went to check, I saw numeric state but could something like this be used as well?

automation:
  trigger:
    - platform: template
      value_template: "{{ is_state('sensor.indoor_light_level' < '10') }}"
      for: "00:02:00"

Yes, that’s more like it.

Let’s consider the implications of that Template Trigger being part of several other triggers including:

  • when the outdoor illumination drops below 250
  • when its 15 minutes prior to sunset

If any of the other triggers trigger the automation, the Numeric State Condition is still limited to only checking if the indoor light level is “below 10” and not “below 10 for 2 minutes”. So there’s still a loop-hole where that requirement is not met.

If we were to eliminate the other two triggers, and only use your Template Trigger, that would definitely satisfy the “below 10 for 2 minutes” requirement. However, if the indoor light level were to ever decrease below 10 before sunset or before outdoor light level is below 250 the conditions would prevent the light from being turned on. If it remained below 10 when sunset occurred, the automation would not trigger because a Template Trigger, once it has evaluated to true, must first return to false before it can trigger again.

Ideally, the Numeric State Condition would support for but, according to its documentation, it does not.

I’m sure this has caused past automations to fail for me, thanks.

The value template I posted though, has problems when I plug it into dev tools. I get

value_template: "{{ is_state('sensor.indoor_light_level' < '10') }}"

TypeError: is_state() missing 1 required positional argument: 'state'

I believe I need to add

value_template: "{{ is_state('sensor.2a_main_02_amps', float) > 1 }}"

which passes the editor but the end result is not correct, where am I going wrong?

Yes, sorry, when I said “that’s more like it” I meant the use of for: in the Template Trigger. I completely ignored the actual template (which is incorrect).

The is_state() function doesn’t support tests like ‘greater/less than’ only ‘equal to’ and it is implicit (i.e. it doesn’t require that you explicitly add an equals sign within the function). For example, this means is the sensor’s state value equal to 10.

value_template: "{{ is_state('sensor.indoor_light_level', '10') }}"

If you want to check if its less than 10 then you must use the states() function and convert the sensor’s state value to a number.

value_template: "{{ states('sensor.indoor_light_level') | int < 10 }}"

Another example:

value_template: "{{ states('sensor.2a_main_02_amps') | float > 1 }}"
3 Likes

Thanks all for the input, it’s greatly appreciated. For the 2 minute issue I could use a “Helper” and create an automation that sets the helper to on when it’s below 10 and off when it’s above 10.

Another way is to create a Template Binary Sensor and use the delay_on option:

Using the recently introduced ‘modern’ format:

template:
  - binary_sensor:
      - name: Indoor Low Light
        state: "{{ states('sensor.indoor_light_level') | int < 10 }}"
        delay_on: '00:02:00'

Or in the ‘legacy’ format:

binary_sensor:
  - platform: template
    sensors:
       indoor_low_light:
         friendly_name: Indoor Low Light
         value_template: "{{ states('sensor.indoor_light_level') | int < 10 }}"
         delay_on: '00:02:00'

The delay_on: '00:02:00' option will set the binary_sensor’s state to on only if the template is evaluates to true for a minimum of 2 minutes. In other words, the light level must be below 10 for at least 2 minutes in order for the binary_sensor to report on (otherwise it will report off).

1 Like