automation:
- alias: Cover stookhok is moving
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
action:
service: script.trigger
- alias: Cover stookhok final update
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
condition:
action:
- delay:
seconds: 3
- wait_template: >
{{(now() - state_attr('automation.cover_stookhok_is_moving','last_triggered'))
.total_seconds() > 5}}
- service: homeassistant.update_entity
entity_id: binary_sensor.raamverduistering_stookhok_moving
- service: notify.system
data_template:
title: Cover is moving
message: current position is {{trigger.to_state.attributes.current_position}}
I want my binary_sensor to be updated automatically, just after the final stop of my cover (which is recorded by the trigger state on each current_position.
Idea: the automation triggers on each current_position change, and will cancel the wait, until the final one, and then update the binary_sensor. And, for checks, Ive added the notify service. What is actually happening: the notification is sent every change of state! While the wait_template isnt evaluated to true, as I can see in the developer-tools/template…
well, tbh, I am not sure what to use anymore. I simply want to update a sensor, within a few seconds after the last trigger of the automation has happened (or, few seconds after the entity has last been updated)
If I turn the wait_template into a condition, like this:
- alias: Cover stookhok final update
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
condition: []
action:
- delay:
seconds: 3
- condition: template
value_template: >
{{as_timestamp(now()) - as_timestamp(states.cover.raamverduistering_stookhok.last_updated) > 3}}
## - wait_template: >
## {{(now() - state_attr('automation.cover_stookhok_is_moving','last_triggered'))
## .total_seconds() > 5}}
- service: homeassistant.update_entity
entity_id: binary_sensor.raamverduistering_stookhok_moving # need this or otherwise it wont update
# the sensor after the final motion
- service: notify.system
data_template:
title: Cover is no longer moving
message: current position is {{trigger.to_state.attributes.current_position|int}} %
nothing ever happens again…
thing is, I would rather trigger off the binary_sensor:
and not need the update_entity at all. Unfortunately, this binary_sensor will only immediately turn on, and doesn’t turn off when the covers are changing position…
HA processes templates to look for entity IDs and then re-evaluates them every time state changes for one of the tracked entity IDs. now() is not an entity ID so essentially HA is only going to recalcuate your template when state changes for cover.raamverduistering_stookhok (or in the case of your first one automation.cover_stookhok_is_moving).
So it seems like your logic doesn’t really have a way of working right now. The problem with your first wait_template was that you were comparing apples to oranges. You were subtracting the total_seconds (a single number) from now() (a datetime object) which isn’t really meaningful logic. I guess it was always returning true but its kind of just an undefined situation. The problem with your second is that any time that condition is actually being evaluated its going to be less then 5 seconds from the last time the state of cover.raamverduistering_stookhok changed so the condition will evaluate to false and that will be the end of the script.
Based on my understanding of your problem, I’m going to suggest a different approach. For the automation, do this:
script:
- alias: Cover stookhok final update
sequence:
- delay:
seconds: 5
- service: homeassistant.update_entity
entity_id: binary_sensor.raamverduistering_stookhok_moving
- service: notify.system
data_template:
title: Cover is moving
message: current position is {{trigger.to_state.attributes.current_position}}
What that will do is every time the cover changes it will stop the script and then start it again. The script itself will first delay for 5 seconds before proceeding with the update and notification. It will only be able to proceed past the delay if its been more then 5 seconds since the last state change of cover.raamverduistering_stookhok. Which to my understanding is something that only occurs if the cover has stopped moving.
Let me know if this is what you’re trying to do? Like @tom_l I’m a bit confused by the actual automations you’re sharing but mostly going off your description of the problem and what you want to happen.
well, no. tbh, both templates work as expected in the template editor… and I can see them change correctly, as long as I press enter.
also, triggering of the state of the cover works, as long as its changing state (or any of its attributes change). The issue is only, how to trigger the final update, when the cover has actually stopped changing position.
So I am trying to calculate that based on the last_updated of the cover entity, or last_triggered of the automation…
Right but the problem here is that this kind of logic isn’t a trigger, its a condition. You can trigger events off of things like time of day, state changing in an entity, event fired, etc. You can condition off of things like entity in a certain state, or entity hasn’t been updated in the past x seconds/minutes/hours. But what you can’t do is trigger off logic like ‘entity changed states x seconds/minutes/hours’ ago. There’s no event fired for ‘an entity changed states x amount of time ago’ so there’s nothing to trigger a script off of.
This is my main issue with the current logic. You’re trying to wait for something which isn’t a trigger. Yes your template works in the template editor but as you said, only when you press ‘enter’. That’s because pressing enter is effectively your event/trigger there forcing recalculation. In an automation you’ll be missing that trigger.
So that’s why instead I suggested my proposal. Where your automation kicks off a script on state change but only lets it finish if its been more then 5 seconds since the last state change (i.e. cover movement has finished). It still sounds like something like that would work would it not?
EDIT 2: I don’t know what your cover entity looks like and how it behaves, but if other attributes might change besides current_position which might cause this not to work correctly, you could always add the following to the first automation:
I fear this will be the only way. Which still feels rather inadequate. Why can we automate on motion, but not on the halting of that motion directly.
Ive already FR’d the addition of attributes ‘opening’ and ‘closing’ which apparently ought to be on all covers, but lack in this IKEA integration. That would solve the issue at the source level.
ending for now with this, which only triggers on ‘off’, because of the sensor.time. ‘on’ is fine:
- platform: template
sensors:
raamverduistering_stookhok_moving:
friendly_name: Stookhok moving
entity_id:
- sensor.time
- cover.raamverduistering_stookhok
- automation.cover_stookhok_is_moving
value_template: >
{{(now() - states.cover.raamverduistering_stookhok.last_updated)
.total_seconds() < 2}}
# {{is_state('binary_sensor.raamverduistering_stookhok_opening','on') or
# is_state('binary_sensor.raamverduistering_stookhok_closing','on')}}
device_class: moving
automation:
- alias: Cover stookhok is moving
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
action:
service: script.trigger
- alias: Cover stookhok final update
trigger:
platform: state
entity_id: binary_sensor.raamverduistering_stookhok_moving
to: 'off'
condition: []
action:
# - delay:
# seconds: 3
# - condition: template
# value_template: >
# {{as_timestamp(now()) - as_timestamp(states.cover.raamverduistering_stookhok.last_updated) > 3}}
## - wait_template: >
## {{(now() - state_attr('automation.cover_stookhok_is_moving','last_triggered'))
## .total_seconds() > 5}}
# - service: homeassistant.update_entity
# entity_id: binary_sensor.raamverduistering_stookhok_moving # need this or otherwise it wont update
# the sensor after the final motion
- service: notify.system
data_template:
title: Cover is no longer moving
message: current position is {{state_attr('cover.raamverduistering_stookhok','current_position')|int}} %
Automations are triggered by events. Something happening is an event. Something not happening is the absence of an event. How can something be triggered by something not happening???
Not sure I understand why you “fear” a valid, reasonable solution. It is creating the event you’re looking for. I.e., when the timer expires, then the cover hasn’t moved in the specified time period, and that’s the “event” you want.
I don’t use covers, and I’m not that familiar with how they generally work, but yes, I’d agree that this is something the cover entity should do – i.e., indicating it’s moving or not. This isn’t in the state? I.e., open, closed, opening, closing, …???
Regarding you last solution, why would this not work (i.e., without the need for the automations/scripts):
Oh. I Didn’t know that.
I posted this code as I not long ago did something similar, and this was the code I used (I of course adapted it to this example).
I also see that my code doesn’t really add anything compared to your code further up the thread. But hey, nobody complains about to many examples
of course it can’t. No, I was looking for the end of the triggering event. But that will probably be clear…
Well, fear might be a bit heavy. Surprised would be better? that we have to create the even manually, use a timer with a hardcoded length, instead of the integration doing that in core. We cant use a template like in the media_play.play media where we use the length of the media file. Here we have to estimate. Since the automation triggers each second, I figured 2 seconds would be enough for the ‘off’ event to be created. But that was just a bit sharp. restarting for 3 now…
It would be really nice to have an event_stopped event in HA core. We have many events that are binary, these are clear. This one isn’t, (clear nor digital) but would warrant its own
No, its state is always open or closed, hence my FR to change that, as apparently other cover integrations do. Or at least have an attribute.
I dont know, I ave been struggling with this all day, in many variants. it simply doesnt track the value_template, other than on sensor.time. Which can take up to a minute. Which of course is unacceptable for a frontend representation.
the input_boolean is a nice technique indeed. Just too bad it isn’t using the new Script logic was really happy to use the script and mode: parallel as I had posted it…
An “event stopped” event? What is that? What does that even mean? And what do you mean by “events that are binary”? An event is something that ocurrs in an instant, it’s not off & on.
I think you mean you want “something” to monitor for a particular event, and after it sees it, it waits until it doesn’t see it for at least X seconds, and when it doesn’t it does something (fire another event, trigger an automation, etc.) And then it starts monitoring for the event again, …
FWIW, you could probably do something like this (using the new automation capabilities that are hopefully coming soon):
Every time cover.raamverduistering_stookhok changes state (or an attribute changes) the action will start running, or restart running. So the service step would only be executed if the entity changed at least once, and then didn’t change for at least 3 seconds.
Is that what you’re wanting?
And since the new modes will only be available in scripts first, then you could do this instead:
for starters, this works now, perfection. So a big thanks is in order! thanks.
automation:
- alias: Cover stookhok is moving
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
action:
# service: script.trigger
- service: input_boolean.turn_on
entity_id: input_boolean.raamverduistering_stookhok_moving
- service: timer.start
entity_id: timer.raamverduistering_stookhok_moving
- alias: Cover stookhok no longer moving
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.raamverduistering_stookhok_moving
condition: []
action:
- service: input_boolean.turn_off
entity_id: input_boolean.raamverduistering_stookhok_moving
- service: notify.system
data_template:
title: Cover is no longer moving
message: >-
Cover is
{%- set position = state_attr('cover.raamverduistering_stookhok','current_position')|int %}
{%- set phrase = 'positioned at: ' %}
{%- if is_state('cover.raamverduistering_stookhok','closed')%} Closed
{%- elif position|int == 100 %} Open
{%- else %} {{phrase}}{{position}}
{% endif %}
and, this customization reflects that in the frontend:
homeassistant:
customize:
cover.raamverduistering_stookhok:
templates:
icon: >
if (entities['binary_sensor.raamverduistering_stookhok_moving'].state == 'on') return 'mdi:animation';
if (state == 'open' && attributes.current_position == 100) return 'mdi:window-shutter-open';
if (state == 'closed') return 'mdi:window-shutter';
else return 'mdi:window-shutter-alert';
icon_color: >
if (entities['binary_sensor.raamverduistering_stookhok_moving'].state == 'on') return 'red';
if (state == 'open' && attributes.current_position == 100) return 'gold';
if (state == 'closed') return 'darkblue';
else return 'green';
not sure this is true, at least not in the way I meant it to. I tried to express the desire to template the time it takes to go from moving to not moving. Might be a chicken an egg issue…
yes, an event stopped. the event would be state_changed_to_moving. and state changed from moving to not moving. or playing, or any other event that takes more time than the instant.
But, maybe this is all caused by the integration not correctly stating the opening/closing.
I’d simply like to trigger as we can do with a light. turn_on/off, and between it is glowing. these event are missing here. I can only trigger on the attribute current_position to be changing…
hmm, I guess yes, will have to try and see if that ends up doing the same How would the binary_sensor need to be templated with this? because that’s the end goal, have a binary change state, and show the frontend the cover is moving or not.
so a little more experimenting seems to allow for determining ‘opening’ and ‘closing’, by adding 1 script.cover_stookhok_position, and adding that in the sequence before the existing one:
script:
cover_stookhok_position:
alias: Cover stookhok position
mode: restart
sequence:
- condition: template
value_template: >
{{toposition != fromposition}}
- service: input_boolean.turn_on
data_template:
entity_id: >
input_boolean.{{'cover_stookhok_opening' if toposition > fromposition else 'cover_stookhok_closing'}}
# below not needed because booleans are turned off anyway. and always start from 'off'
# - service: input_boolean.turn_off
# data_template:
# entity_id: >
# input_boolean.{{'cover_stookhok_opening' if toposition < fromposition else 'cover_stookhok_closing'}}
automation:
- alias: Cover stookhok
trigger:
platform: state
entity_id: cover.raamverduistering_stookhok
action:
- service: script.cover_stookhok_position
data_template:
toposition: '{{trigger.to_state.attributes.current_position}}'
fromposition: '{{trigger.from_state.attributes.current_position}}'
- service: script.cover_stookhok
this in turn allows me to customize the icon even better, and, instead of the ‘motion’ icon, show ‘archive-arrow-down’ and ‘archive-arrow-up’
which is a nice and unforeseen use of these ‘Archive’ icons…
homeassistant:
customize:
cover.raamverduistering_stookhok:
templates:
icon: >
if (entities['input_boolean.cover_stookhok_opening'].state == 'on') return 'mdi:archive-arrow-up';
if (entities['input_boolean.cover_stookhok_closing'].state == 'on') return 'mdi:archive-arrow-down';
if (state == 'open' && attributes.current_position == 100) return 'mdi:window-shutter-open';
if (state == 'closed') return 'mdi:window-shutter';
else return 'mdi:window-shutter-alert';
icon_color: >
if (entities['binary_sensor.raamverduistering_stookhok_moving'].state == 'on') return 'red';
if (state == 'open' && attributes.current_position == 100) return 'gold';
if (state == 'closed') return 'midnightblue';
else return 'green';