It does not have to be a json list, but that seems the obvious way to go as there are easy ways of handling such lists in templates. I just need somewhere to save it that is persistent over subsequent triggers of the automation, and I need to be able to declare it and pass a reference to it to a blueprint.
Home Assistant OS must do this all the time, but how can I do it?
I have read a lot about arrays in template sensors, but they are read-only. Is thee a way of writing attributes to a template sensor?
I usually use input_xxx helpers to save read/write data but none provide for an array of any kind. I don’t know whether I can create my own attributes?
I could write the json code as text, but a text helper only takes 255 characters, which I am likely to exceed.
HASS has some integrations that provide global variables, but I found none that support arrays / lists / dictionaries. Did I miss one?
That seems like a great idea! I would need to create the list of entities and their states dynamically using a list of entities provided as input to the blueprint and their current states.
Can I write something like …
service: scene.create
data:
scene_id: my_scene
entities: >
{% set ns=namespace(scene_list="what exactly?") %}
{% for each entity in input_lights ... %}
{% ... #put values in scene_list# ... %}
{{ ns.scene_list }}
How would I need to format scene_list so that it provides what the scene needs, i.e.
Yes, I have now tried this and it does 90% of what I want. I am able to snapshot the state when motion is detected and restore it when motion stops and the timer has expired. The only caveat is that there is no way to read the status from the scene using a template, so I cannot fade them back to the original state with a stagger interval as I do when I fade them up. You can use a transition, but it applies to all the lights in parallel. However, that was just a bit of fun. Maybe I will experiment in future with other methods, but this is acceptable and the simplest solution for now.
Some observations that are not clear in the documentation:
The scene_id appears in the scene attributes as “friendly name”, however, using a friendly name here does not work – you get ‘invalid slug’.
If you ‘create’ the same scene twice it overwrites the existing one; there is no error message, so no need to delete it first.
You do get an error message if you attempt to create a scene with no entities, so in the blueprint context I first have to check that there are any. In my use-case the list is fixed (as an input to the blueprint) but if it were variable, then one would have to specifically delete the scene when it becomes empty.
Though created with a scene_id:, the scene incongruously has to be activated (turned on) with target: / entity_id:. The difference is that the entity_id needs ‘scene.’ prepended to the scene_id used at 1 above.
To create scenes within a blueprint I have to manufacture a unique name. After trying several options I used the entity id of the current automation with the prefix ‘automation.’ stripped off – if you don’t you get ‘invalid slug’. I create separate scenes for the dimmable and non-dimmable lights.
Here are the relevant code extracts:
blueprint:
name: Night Walk
description:
Fade up lights slowly when motion detected, but only if dark and if not
already turned on manually or by voice assistant.
Converse for turning off and only after a minimum on time.
domain: automation
input:
[...]
dimmable_lights:
name: Dimmable light(s)
description: Light(s) to be faded up and down
selector:
entity:
filter:
domain: light
multiple: true
default: []
non_dimmable_lights:
name: Non-dimmable light(s)
description: Light(s) to be simply turned on and off
selector:
entity:
filter:
- domain: light
multiple: true
default: []
[...]
fade_up_time:
name: Fade up time
description: Time to fade up from 0 to 100%
selector:
number:
min: 0
max: 30
unit_of_measurement: seconds
default: 20
fade_down_time:
name: Fade down time
description: Time to fade down from 100 to 0%
selector:
number:
min: 0
max: 30
unit_of_measurement: seconds
default: 15
[...]
mode: queued
max_exceeded: silent
trigger:
# motion detected
- platform: state
id: motion_detected
entity_id: !input motion_sensors
to: "on"
for: !input on_delay
# motion clear
- platform: state
id: motion_clear
entity_id: !input motion_sensors
to: "off"
for: !input off_delay
# On timer end
- platform: state
id: timer_ended
entity_id: !input on_timer
to: idle
variables:
dimmable_lights_scene_id: >
{{ this.entity_id | string | replace("automation.", "") + "_dimmable_lights_state" }}
non_dimmable_lights_scene_id: >
{{ this.entity_id | string | replace("automation.", "") + "_non_dimmable_lights_state" }}
input_dimmable_lights: !input dimmable_lights
input_non_dimmable_lights: !input non_dimmable_lights
there_are_any_dimmable_lights: >
{{ input_dimmable_lights | list | count > 0 }}
there_are_any_non_dimmable_lights: >
{{ input_non_dimmable_lights | list | count > 0 }}
[...]
action:
- choose:
#
# ACTION[3]CHOOSE[0] Motion detected and it is within the operating time range AND dark OR in test mode
#
- conditions:
- alias: "Motion detected"
condition: trigger
id: motion_detected
[...]
sequence:
# Record the initial state of the dimmable lights
- if:
- condition: template
value_template: "{{ there_are_any_dimmable_lights }}"
then:
- service: scene.create
data:
scene_id: >-
{{ dimmable_lights_scene_id }}
snapshot_entities: !input dimmable_lights
# Record the initial state of the non-dimmable lights
- if:
- condition: template
value_template: "{{ there_are_any_non_dimmable_lights }}"
then:
- service: scene.create
data:
scene_id: >-
{{ non_dimmable_lights_scene_id }}
snapshot_entities: !input non_dimmable_lights
# Fade up dimmable lights
[...]
# Turn on any non-dimmable lights
[...]
- conditions:
- alias: "Motion clear"
condition: trigger
id: motion_clear
[...]
# Set non-dimmable lights back to previous state
- if:
- condition: template
value_template: "{{ there_are_any_non_dimmable_lights }}"
then:
- service: scene.turn_on
target:
entity_id: >
{{ "scene." + non_dimmable_lights_scene_id }}
data: {}
# Fade dimmable lights back to previous state
- if:
- condition: template
value_template: "{{ there_are_any_dimmable_lights }}"
then:
- service: scene.turn_on
target:
entity_id: >
{{ "scene." + dimmable_lights_scene_id }}
data:
transition: !input fade_down_time
[...]