I created a blueprint that has been very useful for me personally. Hopefully I can help someone else as well by sharing it here. This is the first blueprint I share so any constructive feedback is welcome.
What does it do?
The blueprint creates a script to toggle a specific scene on. And if any entity in the scene is already on, it will turn all entities in the scene off. Because scenes are stateless, this creates a kind of toggle functionality for scenes.
Because the generic home assistant turn off function is used the entities must support this service to work.
Use case
By having a script you can now use a service call to have for example either a physical switch in your home, or a button on your dashboard, toggle on a specific scene in a room. And it will turn all lights off if any light is on in that room (if you have all lights specified in that specific scene).
Blueprint
blueprint:
name: Toggle scene
description: >-
Toggle a scene on and off. If any of the entities is on, switch everything off. Else, activate scene.
domain: script
input:
the_scene:
name: Scene to toggle
description: The scene you want to toggle
selector:
entity:
domain: scene
mode: queued
sequence:
- alias: "Set up variables"
variables:
the_scene: !input the_scene
scene_entities: "{{ state_attr(the_scene, 'entity_id') }}"
- alias: "Toggle the scene"
if:
- condition: template
value_template: |-
{% for entity_ids in scene_entities if is_state(entity_ids, 'on')%}
{% if loop.index == 1 %}
true
{% endif %}
{% else %}
false
{% endfor %}
then:
- service: homeassistant.turn_off
data: {}
target:
entity_id: "{{ scene_entities }}"
else:
- service: scene.turn_on
target:
entity_id: !input the_scene
metadata: {}
Is it possible to add an option to invert the part when: “if any entity is on switch everything off” to “If any entity is on then switch everything on”
Could you eleborate a bit more on what you are looking for? Because the way as I understand it now is that you are looking to activate a scene regardless of the state of the entities. Which would be the same as just turning on the scene.
I have a single button that toggles a scene, the scene is multiple lights and typically 1 light is on but I would prefer when I press the button to toggle the scene on (all lights) it first toggles the single light off then another press toggles the scene on (all lights) on, then another press will switch scene back off.
In that case I think my blueprint should create a script that does exactly what you are looking for, as long as the first light is part of your scene.
It should work like this: if the first light is on, than an entity in the scene is on and the script will turn all entities off, including the first light. Calling the script again would mean all entities are off (because the script did this on the first call) and the scene is activated and your lights are turned on. Calling the script now for a third time (ie pushing your button again) would turn everything off again since there is at least one entity on.
In case your first light is not part of your scene it would still work, but you would have to add it to your scene in the off state.
Just give it a try and let me know if it is operating in an unexpected way.
I don’t know what to your use case would be but you could either create a new scene including all the lights or use the blueprint to create multiple scripts and run all the separate scripts one by one. Would this provide a solution for you?
Question - My programing logic is very rusty. And I for some reason have issues wrapping my head around YAML. I can read some of it — but again its been a long time since programming with a C.
What I understand your loop is doing, is to run the entities array and see if any are on. If so then turn off the entities in the scene.
Do I need to build a variable array to store the values?
Goal to report 3 states - All scene lights on , all off , mixed.
if all on then turn off, if all off then turn on, if mixed then turn on.
Sorry doing this from my phone. It makes not shown the code correctly.
I am doing the logic if one light is on and I use the “scene” button - then turn the other lights on.
If all the lights are on then the assumption is the scene is active. And turn it off. You could add additional code to check for the lights to be at the set level and if they are not. Activate scene. Else turn off.