See, I would say that’s over complex - the majority of your actions are turning on or off the other automations. If this was just one automation then the only actions would be to turn the light on and off.
Also it relies on timers and input numbers to determine the length of time a light should be on, rather than a for: statement in a trigger (for which you could still invite an end user to use an input_number if they so desired)
No offence, but this is easily reduced to one automation, and really should have been all along.
I would say this is a prime example of why blueprints are here, so that people aren’t making multiple automations like this when one will do.
Yeah. And I 100% get that. And that’s the tool we have at the moment, so, that’s how it is. I’m only saying, I can absolutely see a use for a single blueprint instance to result in more than one automation.
As a seasoned programmer who writes most of my automations in python (via pyscript), even then, I sometimes write two “automations” that could be one just because it’s easier to maintain, debug, or troubleshoot that way.
As I said, so do I. But the point is that maintenance of the automation is no longer required, because its in a (hopefully tried and tested!) blueprint.
So as I alluded to earlier I currently have 3 automations that I intend to combine into one blueprint. The first of those 3 already replaces the 4 automations posted by the OP - and then there’s 2 more that most people probably use multiple automations for. If we work on the same ratio, my single blueprint would replace 12 automations per entity for most users.
I think the extra effort to combine it into 1 is worth it to make it a single reproducible ‘package’ (not to be confused with packages, of course)
It is quite complex. However, it has the extra feature of, essentially, if someone changes this light while the automation is waiting out the delay to turn it off, then the automation will not turn off the light. (at least, the OP claims it does this in the code comments. I haven’t actually verified that in the code).
This added piece is possible with a complex nest of choose statements, but REALLY easy with an automation that can just be turned off.
Here’s the included blueprint for “see motion; turn on light”:
blueprint:
name: Motion-activated Light
description: Turn on a light when motion is detected.
domain: automation
source_url: https://github.com/home-assistant/core/blob/4880a1d55a12c5ae0f8456a828aff69819f791d5/homeassistant/components/automation/blueprints/motion_light.yaml
input:
motion_entity:
name: Motion Sensor
selector:
entity:
domain: binary_sensor
device_class: motion
light_target:
name: Light
selector:
target:
entity:
domain: light
no_motion_wait:
name: Wait time
description: Time to leave the light on after last motion is detected.
default: 120
selector:
number:
min: 0
max: 3600
unit_of_measurement: seconds
# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent
trigger:
platform: state
entity_id: !input motion_entity
from: "off"
to: "on"
action:
- service: light.turn_on
target: !input light_target
- wait_for_trigger:
platform: state
entity_id: !input motion_entity
from: "on"
to: "off"
- delay: !input no_motion_wait
- service: light.turn_off
target: !input light_target
How would you modify this to NOT turn off the light if it was adjusted during the delay period?
I absolutely agree, the effort is worth it. Not only from your perspective, so that when you do make a change to how that logic works, all of your automations from that blueprint are automatically updated. But also because there will now be countless numbers of users who don’t have to go through the pain of dialing in every last detail just right to make it perfect, they can just use what you’ve done and move on to the next thing – no need to reinvent the wheel.
blueprint:
name: Motion-activated Light
description: Turn on a light when motion is detected.
domain: automation
source_url: https://github.com/home-assistant/core/blob/4880a1d55a12c5ae0f8456a828aff69819f791d5/homeassistant/components/automation/blueprints/motion_light.yaml
input:
motion_entity:
name: Motion Sensor
selector:
entity:
domain: binary_sensor
device_class: motion
light_target:
name: Light
selector:
target:
entity:
domain: light
no_motion_wait:
name: Wait time
description: Time to leave the light on after last motion is detected.
default: 120
selector:
number:
min: 0
max: 3600
unit_of_measurement: seconds
# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: !input motion_entity
from: "off"
to: "on"
- platform: state
entity_id: !input motion_entity
from: "on"
to: "off"
for: !input no_motion_wait
action:
- choose:
- conditions:
- condition: state
entity_id: !input motion_entity
state: 'on'
sequence:
- service: light.turn_on
target: !input light_target
- conditions:
- condition: state
entity_id: !input motion_entity
state: 'off'
sequence:
- service: light.turn_off
target: !input light_target
and then, somewhere in that, you would condition out if the light state has changed? How would you do that? How would you know the light had be dimmed or had the color change? With a second automation that gets turned on when this automation fires, I could look for any service calls for the light entity and cancel the sequence when that service call was seen.
So, perhaps you’d add an event trigger to this to look for the service call, and then some more choose statements to determine if it was the motion or the service call that triggered this, and some kind of input_boolean to mark that it shouldn’t be touched?
The op uses the event, so you could use that and set an input boolean (you’d have to tell end users to create the boolean).
But personally, given that the automation turned the light on and therefore knows the brightness its supposed to be at, I would just compare the current brightness to the expected brightness and stop execution if they don’t match.
(You have to also consider that these aren’t my automations we’re talking about so I haven’t conceptualised them, I would have designed them differently from the start).
That’s a decent option… if the automation knows the brightness and color that it turned the light on with, it could easily check to see if that was still the case before turning it off.
And, yeah, it’s hard to consider automations that start from a different place than you might have started from or that take a different approach than you would.
In many of my (non-blueprint) automations, I look for lighting changes in order to know that someone really cares about the light in that room and doesn’t like the way the automation set it. However, I don’t keep the light from turning off, I just extend the “delay” time considerably until the entire motion event (and turning off of the light) has happened. Then the delay goes back the way it was. I’ve almost got the logic for it all wrapped up neatly enough to be what I’d truly consider “usable by others”. But the automation was too complicated for me to get any enjoyment out of trying to bash it through a rat’s nest of “choose” statements. So it’s all written in pyscript. However, I’m hoping to make it available as a “blueprint” by utilizing pyscript services. We’ll see if I get there.
Yeah, that’s how I’d do it if it was my automation.
Also, people ‘live’ differently, so the vast majority of my automations for this sort of thing are in places where people don’t hang around (halls, landings) - then for the places people do (bathroom, kitchen) I’ve added different override methods, and then bedrooms have a completely different set of rules.
But yeah, what I’m saying is that it can be done, I think the key is to remember we’re not writing an automation (where we might say it’s easier just to do two), we’re writing a comprehensive blueprint which is an entirely different beast and should be approached as such.
Absolutely. “choose” is pretty powerful. And since Home Assistant allows multiple triggers on the same automation and all of the aspects of the trigger exposed to the action, I’m not brave enough to say “anything you can do with 5 automations you can do with 1 and a pile of choose statements”… but it’s likely true.
I imagine even, maybe, if you really wanted to, you could automate EVERYTHING with one single automation. But, I wouldn’t want to even TRY to write it. Though, if someone HAS done this, I’d love to see it.
You definitely can. Although I think chucking templates in tends to make it easier.
Again, you definitely could, but it would ruin my OCD. That said it equally ruins my OCD to use several automations for one function.
To me, an automation should cater for a situation. The only reason I have 3 instead of one (in the examples I was talking about above) is for maintenance purposes, and I only do that in very specific circumstances. Even then, as soon as blueprints were announced I knew they were getting merged
By design blueprints end up being more complex for the person writing them than the equivalent automation would be.
I agree that it makes it easier for the end user to implement the blueprint in the automation (even if that end user will be the author using it for different entities/details).
Have you seen the large amount of code that goes into a blueprint to define the metadata that the blueprint exposes to an automation? And then after the blueprint is properly commented and described to make it understandable to the end user (who didn’t write it) it’s ridiculously huge.
I honestly couldn’t imagine trying to combine all of those automations that you have now into one automation then try to translate that into a single blueprint. Even if the blueprint had the ability to have multiple different trigger/condition/action sections to incorporate many different automations into one huge blueprint (I think I realized that is what you are asking) the resulting blueprint would be unreadable and almost impossible to maintain.
You still have to dexscribe every single entity, trigger, condition, action, setting, option etc just like you do in an automation in the blueprint. And the add more to it. I can’t see how it makes it more simple.
That’s the reason why the response on discord is to use more than one automation - “It’s easier to write and troubleshoot two automations.” It would be exactly the same (only more so) for blueprints just due to their nature.
In the two years I have been helping people fix their automations, this early batch of blueprints is revealing some of the most eyebrow-raising examples I’ve ever seen.
I’ve stated elsewhere that blueprints are proving to be the fastest way to distribute an unoptimized automation.
Now I see a request to allow a single blueprint to deliver multiple unoptimized automations.
Perhaps the focus should be on refinement prior to distribution.
Hi there! I’m experimenting with blueprints for the first time, and also have encountered this desire – I’d love to have multiple automations generated by a single blueprint. I’m sure @anon43302295 will tell me I’m wrong to want this, but let me describe my needs so I can get shot down.
I have 13 rooms in my home with motion sensors. I want their lights to turn on dimly if motion is sensed at night, and be able to turn the lights on and off with the wall switches at any time.
I’m using the Vantage Infusion custom component, and fully realize my code is useless to anyone else. So I have no intention of sharing my blueprint, or “optimizing my code” for sharing. My #1 goal is ease of maintenance.
Right now I’ve generated a template for my motion sensor automation, and have made 13 copies of that template and specialized each one by hand for each room. Each room has 5 automations in a single file.
Which means if I want to change it, I have to make the change 13 times. Annoying!
I’ve been tempted to use GNU m4 or the like, but have not gone that far yet.
I figured blueprints should be perfect! But they don’t seem to support my template with multiple automations per room. And if I create 5 blueprints per room, the code is almost as awkward as what I already have.
Given the comments above about optimizing blueprints and combining automations into single mega-automations, I’m guessing my use case (“make code maintenance for my own code easier”) is not the goal use case for blueprints. Instead, the goal is to make it easy to share easy-to-use blueprints with others, at the cost of making blueprint creation somewhat more complex. Is this correct?
If it is helpful, here is my template which I specialize for each room:
- alias: '%NAME% lights button or off button pressed'
trigger:
- platform: event
event_data:
button: %BUTTON1%
event_type: vantage_button_pressed
- platform: event
event_data:
button: %BUTTON2%
event_type: vantage_button_pressed
- platform: event
event_data:
button: %BUTTON3%
event_type: vantage_button_pressed
action:
# Suppress motion sensing for 10 seconds so the lights don't immediately
# turn on just after I turn them off.
- service: timer.start
data:
entity_id: timer.%LNAME%_nightlights_suppress_motion
duration: '00:00:10'
- alias: '%NAME% motion sensor triggered, lights currently off'
trigger:
- platform: state
entity_id: sensor.%MOTION%_motion
to: Violated
condition:
- condition: state
entity_id: sensor.%BSTATE%_lights_button_state
state: '1.0' # Off
# Only trigger at night:
- condition: template
value_template: '{{ state_attr("sun.sun", "elevation") < -2 }}'
- condition: state
entity_id: timer.%LNAME%_nightlights_suppress_motion
state: idle
action:
# Potential race condition: what if the lights are turned on just as this
# motion event arrives (a.k.a. the two automations are run in parallel)?
# Unlikely to happen, but possible.
# Turn the lights on dimly:
- service: light.turn_on
data:
entity_id: light.%DIMLIGHTS%
transition: 1
brightness_pct: %PCT%
# Set button to blue:
- service: vantage.set_variable_vid
data:
vid: %VID% # A.k.a. sensor.%BSTATE%_lights_button_state
value: 3 # Dimly lit
- alias: '%NAME% motion sensor no longer triggered'
trigger:
# Trigger once we've been in dim mode for 2 minutes, at least 2 minutes
# after the last motion event.
- platform: state
entity_id: sensor.%MOTION%_motion
to: Normal
for: "00:02:00"
- platform: state
entity_id: sensor.%BSTATE%_lights_button_state
to: '3.0' # Dimly lit
for: "00:02:00"
condition:
- condition: state
entity_id: sensor.%MOTION%_motion
state: Normal
for: "00:02:00"
- condition: state
entity_id: sensor.%BSTATE%_lights_button_state
state: '3.0' # Dimly lit
for: "00:02:00"
action:
# Another potential (but unlikely) race conditon: what if this condition
# becomes true just as someone turns on the lights?
# Turn off the lights
- service: light.turn_off
data:
entity_id: light.%DIMLIGHTS%
transition: 1
# Set button to green:
- service: vantage.set_variable_vid
data:
vid: %VID% # A.k.a. sensor.%BSTATE%_lights_button_state
value: 1 # Off
- alias: '%NAME% empty, turn off lights'
trigger:
# Trigger once we haven't had motion for a long time:
- platform: state
entity_id: sensor.%MOTION%_motion
to: Normal
for: "00:15:00"
action:
# Turn off the lights
- service: light.turn_off
data:
entity_id: light.%ROOM%
transition: 1
# Set button to green:
- service: vantage.set_variable_vid
data:
vid: %VID% # A.k.a. sensor.%BSTATE%_lights_button_state
value: 1 # Off
# If someone turns off the lights manually (such as with the Home Assistant
# UI), update the button state to match:
- alias: '%NAME% light turned off manually'
trigger:
# Trigger once we haven't had motion for a long time:
- platform: state
entity_id: light.%ROOM%
to: 'off'
action:
# Set button to green:
- service: vantage.set_variable_vid
data:
vid: %VID% # A.k.a. sensor.%BSTATE%_lights_button_state
value: 1 # Off
Then you’re not looking at blueprints, and you can make as many automations to facilitate your needs as you desire.
Also, as blueprints only create automations and not timers, and several of your automation’s require timers, you’d be out of luck to blueprint them in the current state without additional work by the recipient.
However to transpose your idea in to blueprints, you don’t need a blueprint to make 5 automations, you can just make 5 blueprints. Or you can slim down your existing 5 automations into 4, 3, 2 or 1 automation(s) - ideally replacing the timer entities with better methods as you go so that whatever number you end up with are reproducible without additional configurations - and make that number of blueprints.
But nevertheless, the point is that from the very outset you don’t require blueprints. You currently have 5 automations per room, and if you blueprinted it in its current form, you would still need 5 automations per room, it’s just that they will be generated by the blueprint instead of copy and paste. If it’s not a shareable concept, then transforming them in to a blueprint is pointless.
Reducing them from 5 to any number lower than 5 will vastly improve your coding though, and you should aim for 1, for personal code-ninja glory if nothing else.
Edit - just as a simple optimisation to get you started, adding the trigger of automation 5 to automation 4, negates the need for the 5th automation before you’ve even started. And the action for automation 3 and 4 are exactly the same, so they’re clearly mergeable - so in less than 10 minutes, in spite of it being way past my bedtime, half of the work to reduce this to 1 automation is already done
Thanks for confirming – it sounds like blueprints were not designed for my use case (of reducing redundant code).
I have to admit, in my career as a software engineer, I’ve never aimed for “personal code-ninja glory”. I aim for the opposite – easy to understand, easy to maintain, simple code. Of course, I don’t always achieve that.
I would disagree that having those 5 automations are ‘easy to maintain’ and ‘simple’, given that 3 of the 5 are basically repetition. 3 times the code == 3 times the chances of a mistake creeping in.