Help: Creating an automation that turns a light on for an hour and off for 30 minutes repeatedly 4 times

Thank you @AllHailJ, I certainly would like to make use of templates in my automatons but I am a beginner and most of what you have shared here is way over my head.

automation:
  trigger:
    - platform: sun
      event: sunrise
      variables:
        state: 'on'
    - platform: sun
      event: sunrise
      offset: "01:30:00"
      variables:
        state: 'on'
    - platform: sun
      event: sunrise
      offset: "02:00:00"
      variables:
        state: 'on'
    - platform: sun
      event: sunrise
      offset: "03:30:00"
      variables:
        state: 'on'
    - platform: sun
      event: sunrise
      offset: "00:30:00"
      variables:
        state: 'off'
    - platform: sun
      event: sunrise
      offset: "02:00:00"
      variables:
        state: 'off'
    - platform: sun
      event: sunrise
      offset: "02:30:00"
      variables:
        state: 'off'
    - platform: sun
      event: sunrise
      offset: "04:00:00"
      variables:
        state: 'off'

action:
  - choose:
      - conditions: {{ state == 'on' }}
        sequence:
          - service: light.turn_on
            target:
              - entity_id: light.room_plant
      default:
        - service: light.turn_off
          target:
            - entity_id: light.room_plant
1 Like

The offests had a couple errors… you can also use trigger variables to define the service without needing to use a Choose action.

- alias: 100 - Test Lights
  id: Test Lights
  initial_state: true
  trigger:
    - platform: sun
      event: sunrise
      id: 'on'
    - platform: sun
      event: sunrise
      offset: "01:30:00"
      id: 'on'
    - platform: sun
      event: sunrise
      offset: "03:00:00"
      id: 'on'
    - platform: sun
      event: sunrise
      offset: "04:30:00"
      id: 'on'
    - platform: sun
      event: sunrise
      offset: "01:00:00"
      id: 'off'
    - platform: sun
      event: sunrise
      offset: "02:30:00"
      id: 'off'
    - platform: sun
      event: sunrise
      offset: "04:00:00"
      id: 'off'
    - platform: sun
      event: sunrise
      offset: "05:30:00"
      id: 'off'
  conditions: []
  action:
    - service: light.turn_{{trigger.id}}
      target:
        - entity_id: light.room_plant
  mode: single
1 Like

Thank you @Didgeridrew, I saw them and was correcting for it in my automation. But you bet me to it. And thank you so much for the extra - using trigger ids.

Create a Template Binary Sensor called binary_sensor.plant_light. It’s computed state represents when the light should be on or off.

template:
  - binary_sensor:
      - name: 'Plant Light'
        state: >
          {% set sr = today_at((state_attr('sun.sun', 'next_rising') | as_datetime | as_local).strftime('%H:%M')) %}
          {{ sr <= now() < sr + timedelta(hours=1) or
             sr + timedelta(hours=1.5) <= now() < sr + timedelta(hours=2.5) or
             sr + timedelta(hours=3) <= now() < sr + timedelta(hours=4) or
             sr + timedelta(hours=4.5) <= now() < sr + timedelta(hours=5.5) }}

Create an automation that is triggered by the state-changes of binary_sensor.plant_light or a restart.

alias: Control Plant Lights
trigger:
  - platform: state
    entity_id: binary_sensor.plant_light
    to:
      - 'on'
      - 'off'
  - platform: homeassistant
    event: start
condition: []
action:
  - service: "light.turn_{{ states('binary_sensor.plant_light') }}"
    target:
      entity_id:
        - light.your_first_plant_light
        - light.your_second_plant_light
        - light.your_third_plant_light

NOTE

  • The reason the State Trigger explicitly specifies the desired to states is because a Template Binary Sensor can potentially have an unknown state and we don’t want to trigger on that.

  • There are other things that can be done to make the automation even more robust but this should meet your requirements (including the ability to survive a restart and set the lights to the correct state).


EDIT

Correction. Added missing action: statement.

2 Likes

Thank you so much @123, With just one read I couldn’t wrap my head around this. But I am going to read again and try to implement this as this is the ideal solution I want.

@123 If it dies, reboots or reloads the automation after sunrise then the next rising will be tomorrows sunrise. You can use sun2 and get around this problem.

Another elegant solution BTW!

1 Like

Yes and it will also happen immediately after sunrise time has passed because, as you pointed out, sun.sun’s next_rising attribute will be computed for the next day. However, the first line of the template ensures the datetime object, that represents sunrise, contains today’s date (meaning today’s date but with tomorrow’s sunrise time … which for most purposes is sufficient because the difference is minor). This ensures the time comparisons employing now() work correctly.

1 Like

Thanks for educating me on that - I understand now. It’s also why I like sun2 as you get a sensor.sunrise that is always today.

As it should be IMHO but, due to reasons lost in history, sun.sun’s attributes behave like they do. FWIW, I’ve seen commentary by the development team that sun.sun ought to be re-engineered (more along the line’s of pnbruckner’s sun2 component) but the concern is it would be a major breaking change.

1 Like

I assume you mean the template because the rest of it is straightforward (a simple automation triggered by either a binary_sensor or a restart).

The first line of the template simply creates a variable named sr representing sunrise. Its value is sunrise time represented as a datetime object.

The remainder of the template determines in which of the four time ranges the current time is in. each time range represents when the light should be on.

Current time is between sunrise and sunrise + 1 hour OR
Current time is between sunrise + 1.5 hours and sunrise + 2.5 hours OR
Current time is between sunrise + 3 hours and sunrise + 4 hours OR
Current time is between sunrise + 4.5 hours and sunrise + 5.5 hours

  • If the current time is within any of the four time ranges, the binary_sensor’s state is on.
  • If the current time is not within any of the four time ranges, the binary_sensor’s state is off.
1 Like

Thank you very much @123, it started making sense now. I will try to implement it and post back here.

I get a configuration formatting error that says:

bad indentation of a mapping entry at line 11, column 3:
- service: "light.turn_{{ states …


Could someone help me figure out how to fix it?

That’s my fault; I overlooked to include the action: statement in the original example. I have updated the example above.

Simply add action: on a separate line after the condition.

2 Likes

I don’t know what I am doing wrong here but the automation is not working for me. The light (switch.socket_plant_light_one) wouldn’t turn on even if the trace shows its turned on. This is what I have as configuration.

In the debug trace I have an error related to mobile app that’s a fault I made.

In /config/templates.yaml:

- binary_sensor:
    - name: 'Plant Light One Timer'
      state: >
        {% set sun_rise = today_at((state_attr('sun.sun', 'next_rising') | as_datetime | as_local).strftime('%H:%M')) %}
        {{ sun_rise <= now() < sun_rise + timedelta(hours=1) or
            sun_rise + timedelta(hours=1.5) <= now() < sun_rise + timedelta(hours=2.5) or
            sun_rise + timedelta(hours=3) <= now() < sun_rise + timedelta(hours=4) or
            sun_rise + timedelta(hours=4.5) <= now() < sun_rise + timedelta(hours=5.5) }}

In /config/automations/routines/light/plant-light-one-timer.yaml

- id: 'plant_light_one_timer'
  alias: Control Plant Light One
  trigger:
    - platform: state
      entity_id: binary_sensor.plant_light_one_timer
      to:
        - 'on'
        - 'off'
    - platform: homeassistant
      event: start
  condition: []
  action:
    - service: "light.turn_{{ states('binary_sensor.plant_light_one_timer') }}"
      target:
        entity_id:
          - switch.socket_plant_light_one

    - service: notify.mobile_app_aruns_iphone
      data:
        title: "Plant Light One Alerts"
        message: "Plant light one turned {{ states('binary_sensor.plant_light_one_timer') }}"
        data:
          group: "plantlight-notification-group"

    - service: notify.alexa_media
      data:
        message: >-
          Plant Light One turned {{ states('binary_sensor.plant_light_one_timer') }}
        target:
          - media_player.echo_main_bedroom
        data:
          type: announce

I get these messages in trace:






Restarting homeassistant gives me this:


I realized my silly mistake. In my case it should be switch.turn_on|off NOT light.turn_on|off

  action:
    - service: "switch.turn_{{ states('binary_sensor.plant_light_one_timer') }}"
      target:
        entity_id:
          - switch.socket_plant_light_one

As you have discovered, if you use a service call meant for light entities then the entity_id should contain light entities. Similarly, a service call for switch entities requires switches.

For future reference, if you need a service call to turn on a mix of entity types, you can use homeassistant.turn_on.

1 Like

If you wish, you can use script variables to streamline the automation a little bit:

- id: 'plant_light_one_timer'
  alias: Control Plant Light One
  trigger:
    - platform: state
      entity_id: binary_sensor.plant_light_one_timer
      to:
        - 'on'
        - 'off'
    - platform: homeassistant
      event: start
  condition: []
  action:
    - variables:
        t1: "{{ states('binary_sensor.plant_light_one_timer') }}"
        msg: "Plant light one turned {{ t1 }}"

    - service: "switch.turn_{{ t1 }}"
      target:
        entity_id:
          - switch.socket_plant_light_one

    - service: notify.mobile_app_aruns_iphone
      data:
        title: "Plant Light One Alerts"
        message: "{{ msg }}"
        data:
          group: "plantlight-notification-group"

    - service: notify.alexa_media
      data:
        message: "{{ msg }}"
        target:
          - media_player.echo_main_bedroom
        data:
          type: announce
1 Like

Even after making the changes above the light/socket doesn’t turn on.

- id: 'plant_light_test'
  alias: Plant light Test

  trigger:
    - platform: state
      entity_id: binary_sensor.plant_light_test
      to:
        - 'on'
        - 'off'
    - platform: homeassistant
      event: start
  condition: []
  action:
    - service: "switch.turn_{{ states('binary_sensor.plant_light_test') }}"
      target:
        entity_id:
          - switch.socket_plant_light_one

I made a change in the binary sensor condition to reflect the time now for testing purpose as below:

- binary_sensor:
    - name: 'Plant Light Test'
      state: >
        {% set sr = today_at((state_attr('sun.sun', 'next_rising') | as_datetime | as_local).strftime('%H:%M')) %}
        {{ sr <= now() < sr + timedelta(hours=1) or
            sr + timedelta(hours=1.5) <= now() < sr + timedelta(hours=2.5) or
            sr + timedelta(hours=3) <= now() < sr + timedelta(hours=4) or
            sr + timedelta(hours=4.5) <= now() < sr + timedelta(hours=5.5) or
            sr + timedelta(hours=10.5) <= now() < sr + timedelta(hours=11.5) }}

Thank you so much for this.