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';