Vacation Lighting - Replay Historical Lighting

I’ve taken the concept others have suggested on this forum and created a blueprint to replay lighting behavior. Credit to this awesome community!

Description: A blueprint to replay the same lighting behavior from the previous week. For each light that will be controlled as part of your vacation/away lighting, a ‘history_stats’ sensor should be created to track the historical behavior. The blueprint maps each ‘history_stats’ sensor to its corresponding light entity then replays the on/off behavior on sensor state changes.

If enabled for more than one week, the same behavior is replayed.

  • Vacation mode input_boolean
    An input boolean is used as the on/off condition of the blueprint
  • Controls up to 10 Lights
    This blueprint controls up to (10) lights. Home assistant doesn’t like blank !input variables, so for fewer than (10) lights, a dummy sensor can be used as placeholders for those entities
  • Controls light or switch entities
    • Default Brightness
      A default brightness of 50 is used and can be adjusted as an input when turning on light entities.

Dependencies:

Recorder Integration:

  • Needs to be set to keep data longer than 7 days or the history stats sensors need to be set to pull data for no longer ago than the recorder is keeping data.
##########
# Input Boolean
##########
input_boolean:
  # Vacation Mode Toggle: Used as the condition for vacation lighting blueprint
  vacation_mode:
    name: Vacation Mode
    icon: mdi:beach
##########
# Sensors
##########
sensor:
  # Replay Sensor - Make a new one for each light to monitor
  # All sensors will have naming convention "sensor.replay_xxxxx"
  - platform: history_stats
    name: "replay_office_lamp"
    entity_id: light.office_lamp
    state: "on"
    type: count
    start: >
      {{ as_timestamp(now()) - (7*86400) }}
    duration: 00:00:30
blueprint:
  name: Blueprint - Vacation Lighting 
  description: Vacation Lighting - Replay Sensors to Light Behavior
  domain: automation
  input:
    vacation_mode_toggle:
      name: Vacation Mode - Input Boolean
      selector:
        entity:
          domain: input_boolean
    default_brightness:
      name: Default Brightness
      default: 50
      selector:
        number:
          min: 1
          max: 100
          unit_of_measurement: "%"
          mode: slider
    replay_sensor_1:
      name: Replay Sensor (1)
      selector:
        entity:
          domain: sensor
    light_target_1:
      name: Light Target (1)
      selector:
        entity:
    replay_sensor_2:
      name: Replay Sensor (2)
      selector:
        entity:
          domain: sensor
    light_target_2:
      name: Light Target (2)
      selector:
        entity:
    replay_sensor_3:
      name: Replay Sensor (3)
      selector:
        entity:
          domain: sensor
    light_target_3:
      name: Light Target (3)
      selector:
        entity:
    replay_sensor_4:
      name: Replay Sensor (4)
      selector:
        entity:
          domain: sensor
    light_target_4:
      name: Light Target (4)
      selector:
        entity:
    replay_sensor_5:
      name: Replay Sensor (5)
      selector:
        entity:
          domain: sensor
    light_target_5:
      name: Light Target (5)
      selector:
        entity:
    replay_sensor_6:
      name: Replay Sensor (6)
      selector:
        entity:
          domain: sensor
    light_target_6:
      name: Light Target (6)
      selector:
        entity:
    replay_sensor_7:
      name: Replay Sensor (7)
      selector:
        entity:
          domain: sensor
    light_target_7:
      name: Light Target (7)
      selector:
        entity:
    replay_sensor_8:
      name: Replay Sensor (8)
      selector:
        entity:
          domain: sensor
    light_target_8:
      name: Light Target (8)
      selector:
        entity:
    replay_sensor_9:
      name: Replay Sensor (9)
      selector:
        entity:
          domain: sensor
    light_target_9:
      name: Light Target (9)
      selector:
        entity:
    replay_sensor_10:
      name: Replay Sensor (10)
      selector:
        entity:
          domain: sensor
    light_target_10:
      name: Light Target (10)
      selector:
        entity:
# Declare blueprint inputs as variables for use in {{templates}}        
variables:
  replay_sensor_1: !input replay_sensor_1
  light_target_1: !input light_target_1
  replay_sensor_2: !input replay_sensor_2
  light_target_2: !input light_target_2
  replay_sensor_3: !input replay_sensor_3
  light_target_3: !input light_target_3
  replay_sensor_4: !input replay_sensor_4
  light_target_4: !input light_target_4
  replay_sensor_5: !input replay_sensor_5
  light_target_5: !input light_target_5
  replay_sensor_6: !input replay_sensor_6
  light_target_6: !input light_target_6
  replay_sensor_7: !input replay_sensor_7
  light_target_7: !input light_target_7
  replay_sensor_8: !input replay_sensor_8
  light_target_8: !input light_target_8
  replay_sensor_9: !input replay_sensor_9
  light_target_9: !input light_target_9
  replay_sensor_10: !input replay_sensor_10
  light_target_10: !input light_target_10

# Automation Mode - Parallel
mode: parallel
  
# Trigger when replay sensor changes state
trigger:
  - platform: state
    entity_id: !input replay_sensor_1
  - platform: state
    entity_id: !input replay_sensor_2
  - platform: state
    entity_id: !input replay_sensor_3
  - platform: state
    entity_id: !input replay_sensor_4
  - platform: state
    entity_id: !input replay_sensor_5
  - platform: state
    entity_id: !input replay_sensor_6
  - platform: state
    entity_id: !input replay_sensor_7
  - platform: state
    entity_id: !input replay_sensor_8
  - platform: state
    entity_id: !input replay_sensor_9
  - platform: state
    entity_id: !input replay_sensor_10

# As long as Vacation Mode is on
condition:
  - condition: state
    entity_id: !input vacation_mode_toggle
    state: 'on'


action:
  - variables:
      corresponding_light: >
        {% if trigger.entity_id == replay_sensor_1 %}
          {{ light_target_1 }}
        {% elif trigger.entity_id == replay_sensor_2 %}
          {{ light_target_2 }}
        {% elif trigger.entity_id == replay_sensor_3 %}
          {{ light_target_3 }}
        {% elif trigger.entity_id == replay_sensor_4 %}
          {{ light_target_4 }}
        {% elif trigger.entity_id == replay_sensor_5 %}
          {{ light_target_5 }}
        {% elif trigger.entity_id == replay_sensor_6 %}
          {{ light_target_6 }}
        {% elif trigger.entity_id == replay_sensor_7 %}
          {{ light_target_7 }}
        {% elif trigger.entity_id == replay_sensor_8 %}
          {{ light_target_8 }}
        {% elif trigger.entity_id == replay_sensor_9 %}
          {{ light_target_9 }}
        {% elif trigger.entity_id == replay_sensor_10 %}
          {{ light_target_10 }}
        {% endif %}
  - choose:
      # Replay turned on && entity_id is "LIGHT"
      - conditions:
          condition: and
          conditions: 
            - condition: template
              value_template: '{{ trigger.to_state.state  == "1" }}'
            - condition: template
              value_template: '{{ corresponding_light.split(".")[0] == "light" }}'
        sequence:
          - service: light.turn_on
            data:
              entity_id: '{{ corresponding_light }}'
              brightness_pct: !input default_brightness
          - service: system_log.write
            data:
              message: 'Vacation - Replay Lighting (Blueprint): {{trigger.to_state.entity_id}}: turning on: {{ corresponding_light }}'
              level: info

      # Replay turned on && entity_id is "SWITCH"
      - conditions:
          condition: and
          conditions: 
            - condition: template
              value_template: '{{ trigger.to_state.state == "1" }}'
            - condition: template
              value_template: '{{ corresponding_light.split(".")[0] == "switch" }}'
        sequence:
          - service: switch.turn_on
            data:
              entity_id: '{{ corresponding_light }}'
          - service: system_log.write
            data:
              message: 'Vacation - Replay Lighting (Blueprint): {{trigger.to_state.entity_id}}: turning on:{{ corresponding_light }}'
              level: info

      # Replay turned off
      - conditions:
          condition: and
          conditions: 
            - condition: template
              value_template: '{{ trigger.to_state.state == "0" }}'
        sequence:
          - service: homeassistant.turn_off
            data:
              entity_id: '{{ corresponding_light }}'
          - service: system_log.write
            data:
              message: 'Vacation - Replay Lighting (Blueprint): {{trigger.to_state.entity_id}}: turning off:{{ corresponding_light }}'
              level: info

Notes:

  • Fewer than 10 Lights
    Home assistant requires you to select a value for all of the available blueprint inputs when creating the automation. If there are fewer than 10 lights that need to be controlled you can do one of the following
    1. Modify the blueprint to use only the number of required entities
    2. Use a dummy entity to select for both the unused Replay Sensor and the Light inputs. This sensor will do absolutely nothing other than act as a selectable placeholder that lets you save the blueprint as an automation
# DO NOTHING HELPER
# Use this sensor as a dummy placeholder in the blueprint automation
sensors:
  - platform: template
    sensors:
      do_nothing:
        friendly_name: 'Do Nothing - Dummy Sensor'
        value_template: 'off'
25 Likes

You should probably note that you need to make sure that for this to work either the recorder integration needs to be set to keep data longer than 7 days or the history stats sensors need to be set to pull data for no longer ago than the recorder is keeping data.

My recorder is set to purge data every 5 days so if I set the history stats sensor as you have it configured (7 days) then the state is always “unknown”.

If I change the template in the history stats to multiply by 5 instead of 7 the sensor works as expected.

Another thing I just thought of is that you could get into a situation that the history_stats sensor may return a value > 1 if the light was switched off & on more than once in those 30 seconds that the history stats is looking at. In that case none of your condition tests will be satisfied and since you didn’t give a default action I’m not sure how the system handles that.

It might be better to change the conditions to check for an integer > 1 instead of a string equal to “1”.

And one other question - what is the purpose of the dummy sensor?

I don’t see it used anywhere. Unless I missed it.

2 Likes

Those are all very good points!

I’ll make the recommended changes to original post.

Only purpose of the dummy sensor is Home Assistant throws an error on the automation when deploying the blueprint if an entity isn’t selected for every single input. When going to save the automation user receives an error “message malformed, missing input xxxxx”. The sensor doesn’t do anything than to act as a placeholder to get past the automation build screen. I would love a better way to work around this behavior!

Yeah, but I don’t see where it’s actually used in the blueprint.

I keep looking for because it seems I may be missing something but as many times as I’ve looked I just can’t see it if it’s there.

Another thing after you made your changes to the comparisons is that the trigger state is a string and you can’t compare a string to “1” and get the results you think you are going to get.

for example you can test this by entering the following into the template editor:

{{ "9" > "10" }}

{{ "9" < "10" }}

the result of the first will be true and the result of the second will be false.

so to get the expected result you need to convert the state to an int and then remove the quotes around the 1 to make it a number:

- condition: template
  value_template: '{{ trigger.to_state.state | int > 1 }}'

You’re not crazy. It’s not used by the blueprint itself. It was what I learned I needed to use if I have fewer than 10 lights only when trying to use the blueprint as an automation

For example, I have 9 lights I want to control. But home assistant doesn’t let you have empty inputs when you use the blueprint to make the automation. For this 10th pair of inputs, I select the dummy sensor as both the replay sensor and the light simply as a placeholder to let home assistant allow me to “save” the automation.

If this is too confusing, I can remove it as its not necessarily a “dependency” and others can figure out their own workarounds.

No, I just wanted to make sure I wasn’t missing something obvious.

But I think that explanation should go in the original post tho.

Did you look at the second part of that post about the comparisons?

yes and modified. thanks for the feedback!
will include the extra description on that sensor as well

1 Like

Hi Timgiwo,

I have an error when I try to import your blueprints

No valid blueprint found in the topic. Blueprint syntax blocks need to be marked as YAML or no syntax.
2 Likes

Hi Comperta- i’ve seen this with other blueprints too. This is only my guess… I think its because the import feature doesn’t like multiple yaml code blocks… or may be it only checks the first one? In any I think you may need to manually copy and paste as a yaml file in your blueprints folder.

2 Likes

Thanks. Was wondering why I was getting issues.

Hi Timgiwo,
same error as comperta. Unable to upload the blueprint. Where I can find the updates source to manually import? Thanks.

@timgiwo
Sorry if this is a stupid question. Currently I only record history for the entities I’m interested in. When you say “Recorder integration needs to be set to keep data longer than 7 days”, is the 7 day+ time period referring to the lights we want to include in the vacation automation or, the replay sensors we create? Thank you.

@Gregkg Just the lights. The replay sensor will generate state history of the light from the same time/day a week ago to a granularity of every 30 seconds. For days 7+, it just plays it over again since the automation was presumably changing the status of the lights from the first 7 days

1 Like

@LPK You’ll have to manually create the blueprint yaml, by copying and pasting the code above. Seems to be a limitation of how they implemented the import feature. doesn’t seem to like multiple code blocks

Thank you sir.

Maybe you can put the blueprint code in a Github gist?

How do you add a blueprint?

edit: I see. Manually create the YAML file under the /config folder.

That looks great. Would there be any way that the toggle could allow a binary_sensor as well as an input_boolean?
I have a template binary_sensor which automatically sets a holiday/vacation mode based on my calendar, and it would be great if that could be used to enable or disable this without needing a separate input_boolean.

Why not use an input_boolean that reflects the state of your binary_sensor? That way no code changes would be needed.

If I’m not mistaken, that would need a separate automation which is triggered by a change in the binary_sensor and updates the input_boolean.
Is that what you mean?