I would have hoped for this to be simple but it’s turning out to be a lot more involved and I am wondering if I am missing something basic - or if there is a more elegant way to do this.
The use case is simple enough.
I need to setup approx 25 lights to start switching on as it gets darker in steps using the input from a simple light sensor e.g.
if the sensor readings reach n1, switch on room 1 and room 2 lights at 50%
As it gets darker and sensor reaches n2 , switch on a few more
At n3, all indoor lights at full intensity
At n4 , add outdoor lights
The lights switch off at a pre-determined time
Ideally I would have liked the transition to be gradual (most of the lights support levels) but could not figure out a simple way to do so - hence created stepped scenes 1-6 with step 1 as all off and step 6 as all on
Initially I tried setting up simple templated based automation to trigger each scene based on the sensor hitting a value e.g. trigger scene 1 if sensor value > n1 and <n2 - this didn’t work as expected
Based on a similar thread, I created a set of template sensors to trigger scenes based on sensor state
- id: '1594473621991'
alias: Auto Lights - Step 2
description: ''
trigger:
- entity_id: sensor.dark_2
for: 00:01:00
from: 'False'
platform: state
to: 'True'
condition:
- after: '11:00:00'
before: '21:00:00'
condition: time
- condition: and
conditions:
- condition: state
entity_id: sensor.dark_3
state: 'False'
- condition: and
conditions:
- condition: state
entity_id: sensor.dark_4
state: 'False'
action:
- scene: scene.lights_step_2
This is working a little better but still not reliable as the sensor (esphome) sometime resends its values which re-triggers multiple scenes .
Any thoughts or pointers?
That looks far more elegant than what I have . Although to be honest, the data template has me stumped .
Let me read up a bit on data templates again.
Also, apologies that I wasn’t very clear on the issue in my original post.
The intent is to have the automation trigger once when the conditions are met - and to stay that way unless the conditions change (e.g. once the sensor reaches say 21.1, trigger scene 2 and do not retrigger anything unless the value goes below 21 or above 23)
However, With a strategy based on the numeric_state, the automations tend to get re-triggered somewhat randomly even if the boundary conditions are unchanged
I believe you could add a switch or input number that holds the last activated scene.
For instance: you have a number that changes the same way as Phil templated to 1, 2, 3, 4, 5, 6 as the action of the automation.
This number is then used as a condition, the activating scene has to be > input number.
That way it will only trigger once and will count up to 6, then I guess you need to set it back to 1 in the automation that switches off the lights.
Regarding dimming of the lights, I think that is easier to do per light.
Trigger is light on
And the action is to fade in the light.
Umm, That is not the case.
Switching during day time is understandable.
However this also occurs after dusk and twilight end when the sensor value is well above the thresholds.
@pnbruckner’s automation will do half of that (very cleverly too, I might add, although I think it’s working “backwards” and turning more lights on the lighter it gets…) — it triggers whenever the ambient light sensor state increases across one of the defined thresholds. You’ll still need to write the “opposite” automation to turn things off when the light level drops.
There shouldn’t be anything “somewhat random” about it: if you’re finding problems with the short-term fluctuations in light level, you have some options:
add a “for:” declaration for each trigger (so only trigger if the light level goes above x and stays there for y seconds: I do this with my hall light with a 30s “on” pause and a 10m “off” pause);
build some hysteresis into the system by having different, lower levels for the switch-off automation — so you might switch on level 1 when the light goes below 18, and switch it off only when the light level rises above 20.
This is a good idea but I believe it’s better to do what I suggested and make sure it can only count up in scene number.
(That is at least how I interpreted the request)
Because it could drop to 16 and then go back up to 20 again. It’s completely possible but if you limit it to only be possible to count up then there is no risk of it happening
An “above: X” trigger will not re-fire unless the value becomes X or less and then goes back above X again.
However the trigger can get re-initialized if the sensor’s state becomes something other than a numeric value (e.g., “unavailable”), or HA restarts, or the automation is turned off and back on, or automations are reloaded. Those are all known events that can cause the trigger to fire on the next sensor state change that meets the criteria. But they’re not random.
When a numeric_state trigger fires the trigger variable will contain the above value of the trigger that fired. The template uses that to look up the desired script number in a dictionary. I.e., this is a dictionary:
{18: 1, 21: 2, 23: 3, 26: 4}
and this expression extracts the value:
[trigger.above]
So if the trigger with the “above” value of 21 fired, then it will extract the value 2. That is then appended to the scene name.
Then you need to see what your sensor is actually doing and address that before you use it as a trigger to an automation. The automation for responding to light level changes is probably complicated enough; it shouldn’t have to do the job of filtering the sensor, too.
Which is what I would have thought given code is meant to be definitive and certainly not random unless by design.
So your comment got me investigating and it turns out that my esphome devices are indeed going to unavailable for very short intervals - wasn’t affecting anything else as they reconnect pretty quickly but certainly an issue - especially for this.
In fact there is a long running thread regarding esphome and sensors/ devices periodically going unavailable.
Let me try switching the sensor in question over to Tasmota MQTT and see if I see this recurring.
And Thanks for that explanation - It is indeed quite clever and elegant.
As pointed out by @Troon , i have added a for: declaration (1 min) for now .
It’s just about getting dark here so let me see how it works in practice.
Next step would be to stabilize the sensor (hopefully Tasmota will do the trick) and then move the automation to the template you have suggested
Probably a digression - I am not sure if it’s an esphome issue or an issue with the esp8266s.
Either way, tasmota ran stable for me for years for 15 odd esp8266s.
I moved to esphome last week and the unavailable messages started happening right after.
Now it’s entirely possible that even Tasmota has brief disconnects but the regular mqtt stack may probably not even realize that the device became unavailable.
I have moved the sensor in question to tasmota now and have switched to @pnbruckner ‘s code
Will report back on how it goes
If I see issues, will surely try out the filtered value template (which I am anyway bookmarking for future use cases)
Almost there but there seems to be something wrong with my understanding of how triggers work.
The sensor has been moved to tasmota and is now stable- it reports values from 0 to 330 with increasing values as it gets darker (i.e. 330 is complete darkness)
The code in use - snippet 1 is supposed to switch on lights as it gets darker while snippet 2 is the reverse
Scenes are set as scene.lights_step_n with n from 0 to 6 - with 0 as all off (i.e. bright outside) and progressively to 6 as all on at max (i.e. dark outside)
The issue is that snippet 2 is acting reverse of what’s expected - The current sensor reading is 90 so I would expect snippet 2 to activate scene_lights_step_0 but it seems to be activating scene_lights_step_5 instead
I think this is due to how numeric_state triggers work, which I explained above. The first sensor state change can cause more than one trigger to fire, and in your example, 90 would cause all the triggers to fire.
As a workaround, I’d suggest reversing the order of the triggers in the second automation. Triggers are evaluated in order, so that would then make the lowest below value evaluated last, and it should be the last to “take effect.”
If that doesn’t work then we can probably come up with something better.
Reversed the trigger order and it all seems to be in order now.
Saying Seems to be because I the logbook or history isn’t showing the exact scene triggered so I guess I will have to observe it for a day or two.
On a related note, is there a way to evaluate a two-step template (like yours) in the template editor?
Would be very useful for debugging .