TIL: How to store and restore the state of multiple entities in Home Assistant

3 minute read Published:

Short howto: store/restore state in HA

The problem: Automations sometimes need to store the state of several entities at once and then restore all of them at a later point in time. An example of this is:

When I open my balcony door at night, I want the lights in my room to turn off. when I close the balcony door, I want the lights to be restored to the exact same state they were previously.

Siytek’s post brought up the idea that one can store states in a newly created scene, then change stuff and later activate the scene to restore everything. AMAZING!

The problem with their outlined approach: You need to exactly specify which states and attributes of which entities to store in the scene and this can quickly escalate when you want to keep track of multiple entities at once.

My solution: using a python_script to do all the heavy lifting. It only wants 2 things:

  1. the name of the scene to create
  2. a list of all entities to store their state

Dependencies

Code

python_scripts/store_and_turn_off.py

entities = data.get("entities", [])
scene = data.get("scene", "")
logger.info("[store_and_turn_off]: [scene: '%s'] storing state for %s", scene, entities)

scene_entities = {}

for entity in entities:
    state_wrapper = hass.states.get(entity)
    state_dict = state_wrapper.as_dict()
    stored_state = {
        "state": state_dict["state"],
        **state_dict["attributes"]
    }
    scene_entities[entity] = stored_state

scene_data = {
    "scene_id": scene,
    "entities": scene_entities
}

if len(entities) == 0:
    logger.info("[store_and_turn_off]: entities not set")

if not scene:
    logger.info("[store_and_turn_off]: scene not set")
else:
    hass.services.call("scene", "create", scene_data, True)
    logger.info("[store_and_turn_off] stored state in scene %s", scene)

# if you don't want this script to turn off stuff, then remove all following lines:
turn_off_data = {
    "entity_id": entities
}

hass.services.call("homeassistant", "turn_off", turn_off_data, True)

example usage

When I open the office balcony door at night for longer than 1s, the entities light.office_whiteboard, light.office_woodboard, switch.office_light_switch will get their state stored in scene.zz_office and then be turned off. When the door is closed again, their state will be restored again by activating scene.zz_office

alias: window_open_night_office
mode: single
description: ''
trigger:
- type: opened
  platform: device
  device_id: ab0909b30b0a3
  entity_id: binary_sensor.lumi_lumi_sensor_magnet_aq2_on_off
  domain: binary_sensor
  for:
    hours: 0
    minutes: 0
    seconds: 1
    milliseconds: 0
condition: # Only run this automation when it's dark outside // the sun is under the horizon
- condition: template
  value_template: '{{ state_attr(''sun.sun'', ''elevation'') < 0 }}'
action:
- service: python_script.store_and_turn_off
  data:
    scene: zz_office
    entities:
    - light.office_whiteboard
    - light.office_woodboard
    - switch.office_light_switch
- wait_for_trigger:
  - type: not_opened
    platform: device
    device_id: ab0909b30b0a3
    entity_id: binary_sensor.lumi_lumi_sensor_magnet_aq2_on_off
    domain: binary_sensor
- service: scene.turn_on
  target:
    entity_id: scene.zz_office

Sidenote: I prefix the scene names with zz_ to make sure that they will not pollute my list of automations.

This solution is heavily inspired by Siytek’s blog post!