You’d think the problem is widespread and many people have tried to solve it, but that does not seem to be the case.
I have a Philips Hue motion sensor and we all know once it detects motion, it will stay in that state for 10 seconds, and then resets to “no motion”. So if you want light on for at least 40 seconds after motion, the automation looks like below. This algorithm also is used as the standard motion-activated light blueprint that comes with Home Assitant core as far as I know.
The automation uses “restart” mode, which will kill an already running instance of the automation and start a new instance. This is required if the first instance hangs in the 30s delay loop, and the motion sensor is triggered again: the light stays on and the countdown starts at 10s+30s again. No rocket science so far.
So far so good - all of this works.
However, the algorithm above has the following problems:
If the light was on before, human enters the motion zone, and exists, the automation turns off the light after 40 seconds. Instead, it should stay on (like it was before).
Likewise, if the light was dimmed or had a nice color, and human enters the motion zone, the automation set the light to bright white for 40 seconds (good) and then turns it off (bad). Instead, it should restore the previous state. This can be addressed by creating a dynamic scene and restoring that scene at the end of the automation. However, if the automation is reset, then the 2nd instance of that automation will again save the dynamic scene (which now is bright white), and when it finishes, the light is not returned to previous state. Instead, it stays in bright white forever. Light never is turned off.
When working with dynamic scenes (to address problem 2.), then there’s yet another problem: If another automation turns the light off (e.g. because TV was turned on) while the motion-automation is in its waiting loop, then it will turn the light back on. I admit solving this problem is a bit too much to ask for, and it rarely happens.
I’ve tried working with now() to find out how long ago the automation was last triggerd (or scene saved/applied) and I tried to solve this with a variable to carry information from one instance to the next. I could not wrap my head around it and got nothing, because the 2nd instance starts just with the same information as the first one. The first instance never has a chance to finish because it will be killed in reset mode.
I tried the single mode - this solves problems 1 and 2, but then the light is turned off after 40 seconds even if there’s motion again, so I stand in the dark.
I thought of two automations to address different problems, but would not know how.
I ran out of ideas.
Instead of putting it all in one automation, I’d use a timer. That way you can check if the timer is aleady running or not when the light is on (see the difference between light is already on or motion is continuing). If the timer is already there, just restart the time, if it runs out, restore the scene.
Also, you can cancel the timer if the light is turned on for another reason.
Never did that so I’m throwing ideas that are most probably bad … sorry.
What if you trigger on motion AND no motion in single mode.
If there is a re-entry it will fail and the 30 seconds will continue.
But at the end, you can condition the turn_off based on the motion status and only do it if it is clear.
If not, it’ll keep the light on because motion was still detected and end the automation.
One time or another, the motion will be clear and it will restart this automation but this time because of the “no motion” trigger and you can therefore turn off the light or something similar.
To avoid complex things, I’d create various helpers to keep the information about your light (boolean to store the previous on/off, numbers for brightness or color) and initialize all of them as the first actions of the motion detected part. It’ll help going back to previous state as it will act like global variables.
EDIT: “Conditional turn off” or “Clear motion trigger” could be a call to one common script with all your helpers as the needed information to restore the light as it was before.
This was a perfect example of good teamwork. None of you solved the problem, but all of you together solved it. The biggest piece was delivered by @123 with the idea of using the delay option for the off-trigger. @Olivier1974 came up with the boolean helper idea and @Edwin_D mentioned using more than one automation.
I combined all ideas and added some of my own to come up with the below solution, which solved all three (1.-3.) problems descibed above. The key was to use two automations (one to make the light bright white, one to restore light previous state) and use a boolean helper variable to remember if we are between the two automations.
Add a boolean helper variable input_boolean.hall_motion
The if-then logic even solves problem (3.) and accounts for the light being turned off by another automation. It uses the last_changed timestamp, which only is updated when the light is turned off or on, but not when color or brightness would change. I experimented with the last_updated timestamp first, but that one is being updated too often, e.g. when I did not change the light’s brightness or color, HA also updates last_updated. I’m good with last_changed because the other automation turns the light off when the TV is turned on.
If a user would change the light’s color while between the two automations, that user change is overwritten by the second automation after 30 seconds latest. This is a drawback, but I found no variable to check for light state changes besides last_updated (updated too frequently) and last_changed (not updated when color/brightness changes).
The example I posted wasn’t meant to solve all the requirements you posted. It simply demonstrates that triggers can be used to perform most of the workload in a single automation. It was the foundation for adding the other requirements.
The example also demonstrated that listening for the ‘no motion’ event can be part of the automation’s trigger as opposed to your original example where it’s part of the action.
The State Trigger’s for option is not a “delay option for the off-trigger”. It’s effectively an internal timer that requires the state value to remain unchanged, at a specified value, for a specified duration. The timer is reset if the value changes. It’s not a simple “delay”.
All of the requirements can be fulfilled by a single automation. Two automations is a matter of choice, not necessity.
The input_boolean serves as a ‘flag’, to indicate status, but that role can be fulfilled by the snapshot scene. In other words, the input_boolean isn’t explicitly needed because the scene can serve as the ‘flag’ (specifically, the scene’s state value which is a timestamp).
Anyway, glad to hear you found a solution by combining several ideas.
From settings, in the same section where the intrgrations live, the rightmost tab called helpers. You can add various type of entities here, timer is among them.