Script execution based on time-of-day

Hello!

I am looking for some help with time-specific script triggering if anyone has a moment to advise:

I am using the HomeKit component to add a switch to my iOS devices:

homekit:
   filter:
     include_entities:
       - switch.familyroomlights

Then in configuration.yaml using the below to trigger the relevant script for on/off:

switch:
   - platform: template
     switches:
       familyroomlights:
         friendly_name: Family Room Lights
         value_template: "{{ is_state('switch.familyroomlights', 'on') }}"
         turn_on:
           service: script.turn_on
           data_template:
             entity_id: script.familyroombright
         turn_off:
           service: script.turn_on
           data_template:
             entity_id: script.familyroomoff

This all works great - but I would like to expand on it, so that different ‘turn_on’ scripts will be triggered based on the time of day, so that telling HomeKit to ’Turn on Family Room Lights’ will turn on bright lights during the day, and dim lights during the evening/night. This simplification will help out with family :slight_smile:

So for example:

switch:
   - platform: template
     switches:
       familyroomlights:
         friendly_name: Family Room Lights
         value_template: "{{ is_state('switch.familyroomlights', 'on') }}"
         turn_on:
           service: script.turn_on
           data_template:
 ****If between 9am and 6pm then****
             entity_id: script.familyroombright
 ****else if between 6pm and 9am then****
             entity_id: script.familyroomdim
         turn_off:
           service: script.turn_on
           data_template:
             entity_id: script.familyroomoff

I have been researching timestamping and templating the last few days but sadly my head is not absorbing it very well!

Does anybody have any advice how I may achieve this?

Thank you in advance

Ford

I’m no expert but I did just spend a lot of time learning templating and I think I can help.

First, you’ll need to add sensor.time see Time & Date Integration

sensor:
  - platform: time_date
    display_options:
      - 'time'

Second, your template should look like this

switch:
  - platform: template
    switches:
      familyroomlights:
        friendly_name: Family Room Lights
        value_template: "{{ is_state('switch.familyroomlights', 'on') }}"
        turn_on:
          service: script.turn_on
          data_template: 
            entity_id: >-
              {% if states('sensor.time') > '09:00' and states('sensor.time') < '18:00' %}
                script.familyroombright
              {% else %}
                script.familyroomdim
              {% endif %}
        turn_off:
          service: script.turn_on
          data_template:
            entity_id: script.familyroomoff
1 Like

Yes! This is perfect and works great.

And also taught me something about the correct formatting.

Thank you!!

Just a further question on this:

I am now trying to modify the times to something like this:

{% if states('sensor.time') > "{{ as_timestamp(states.sun.sun.attributes.next_rising) | timestamp_custom('%H:%M') }}" and states('sensor.time') < "{{ as_timestamp(states.sun.sun.attributes.next_setting) | timestamp_custom('%H:%M') }}" %}
  script.familyroombright
{% else %}
  script.familyroomdim
{% endif %}

I would imagine i’m making another format error here but from reading the jinja2 documentation I can’t see where. Trying to achieve the hours to be between sunrise and sunset.

Thank you

Whilst this may be clunky i’ve currently solved this with:

switch:
  - platform: template
    switches:
      familyroomlights:
        friendly_name: Family Room Lights
        value_template: "{{ is_state('switch.familyroomlights', 'on') }}"
        turn_on:
          service: script.turn_on
          data_template: 
            entity_id: >-
              {% set daylighthours = {
                "sunrise": as_timestamp(states.sun.sun.attributes.next_rising) | timestamp_custom('%H:%M'),
                "sunset": as_timestamp(states.sun.sun.attributes.next_setting) | timestamp_custom('%H:%M')
              } %}
              {% if states('sensor.time') > daylighthours.sunrise and states('sensor.time') < daylighthours.sunset %}
                script.familyroombright
              {% else %}
                script.familyroomdim
              {% endif %}
        turn_off:
          service: script.turn_on
          data_template:
            entity_id: script.familyroomoff

Clunky,
Try using sun.sun above_horizon instead

By the way, a script executed at a specific time of day is an automation

As an FYI, scripts also support templating in their actions. Right now it looks like you’ve created 3 different scripts, one to turn the light brightly, one to turn the light on dimly and one to turn it off. The logic of what brightness to turn the light to is then in here in this switch.

I might suggest an alternate approach. Since you didn’t show us your script i’m going to assume for this example that your light is called light.familyroomlights. Feel free to change that to whatever id you do use. Your script could then do something like this:

script:
  familyroomon:
    alias: Family room on
    sequence:
    - service: light.turn_on
      entity_id: light.familyroomlights
      data_template:
        brightness_pct: >-
          {% if is_state(sun.sun, 'above_horizon') %}
            100
          {% else %}
            50
          {% endif %}

The benefit of this is that your switch can be simplified to just calling either script.familyroomon or script.familyroomoff. It also means you can change the logic of this script without restarting home assistant (since changes to switches require a restart but you can change scripts right from the UI). And it means your script can be used elsewhere in your automations on its own since it includes the logic of what state to set the light to based on time of day.

Take a look at the doc on scripts to see more of what scripts can do, they’re pretty powerful. They also support parameters and conditionals if you wanted to add to this logic based on other sensor data over time.

2 Likes

Thank you - will try that!

Also - I am not executing this script at a specific time of day. I am trying to use the time of day as a condition for which script will be executed.

So:

HomeKit ‘Turn on Family Room Lights’ -> switch template -> script output chosen based on condition of time of day

Thanks for the input! My background is not in software engineering…

Ah great! Yes this is very helpful - and the logic makes much more… sense! That approach is better.

And not having to reboot each time will be nice.

I will work on this - thank you!!!

Further to this - in response to the setup for that room:

Yes, I have three scripts. Each script triggers a scene (for lighting), but may also have other things like switching music off for example, for which the flexibility of a script is much more useful.

But using the logic you explained I can adjust this to trigger different scenes/scripts based on the horizon.

Thanks again

Well you are, specifically at sunrise and sunset. These are times of the day, or at least events that you specifically tried to interpret as times.
You generally need to be more flexible in your interpretation of how you approach a trigger for your controls.

Pretty much anything you can put in a script you can put in an automation though you can’t always do the opposite.

Read examples across the forum, ask questions, look at other people’s work, try to understand how they work, then adapt them to your needs.

Ok thank you! Yes - that’s been the most helpful part so far, reading the forum, adapting other’s code and learning the basics. Sometimes though you just need a little help :slight_smile: and someone to go “Like this!”