Is it possible to set historical state changes as conditions in automations?
Say i.e. that i want to trigger an automation when a light turns on, but I only want the automation to run if the light has been off for at lest 30min prior to being turned on.
How can I do that?
This checks it’s currently off
and hasn’t changed for more than 1800 seconds. Assumes it doesn’t go unknown
or unavailable
.
condition:
- condition: state
entity_id: light.your_light
state: 'off'
- "{{ now()|as_timestamp - states.light.your_light.last_changed|as_timestamp(0) > 1800 }}"
The other way would be to make a trigger-based template sensor that records the current time when the light switches off and compare that in the condition instead: that’d be more robust to dropped connections, restarts etc.
Excellent - thank you so much!!
@Troon why do these templates come out with incorrect values:
If i subtract 23 - 15 = 8 which is an 8 hour time difference. While the template in line 6 calculates this to nearly 7 hours. There’s almost an hour missing?
Timezones. Look at the end of the results for lines 3 and 4.
Of course - how stupid of me!
But how should that be understood - does it mean that now()
is aware of my TimeZone while last_changed
is not?
Correct — I should have realised this when I made my suggestion above, but I’m in a UTC timezone at the moment. If you’d asked in the summer I might have realised . Try utcnow()
instead:
{{ utcnow()|as_timestamp - states.light.your_light.last_changed|as_timestamp(0) > 1800 }}
We’re getting there. What happens now, is that my automation is triggered by the entity Persons
changing to Home
. Then immediately followed by a conditional test as you so helpfully described. But your test always returns False
since the state obviously just changed. What I want to test is not the last_changed
but the one before last (if you understand what I mean).
So the duration of the state-1 should be more than 30 minutes.
Is that possible?
OK: with the original setup I’d assumed that the automation was going to turn the light on, not that it was triggering from the light.
I’d do what you want with a trigger-based template sensor to record the time when your entity went to whatever you’re calling the “off” state, to record the “state-1” time — then use that in your condition.
Example, with assumptions on your entity ID and state definition:
template:
- trigger:
- platform: state
entity_id: group.persons
to: not_home
sensor:
- name: "Persons not home"
state: "{{ now() }}"
device_class: timestamp
Based on your input I tried this approach - but it doesnt’ work. The sensor never updates (?)
template:
- binary_sensor:
- name: "persons_away"
state: >
{% if is_state('group.persons', 'away') %}
{{ on }}
{% endif %}
delay_on:
minutes: 30
So many things wrong with that. Try:
template:
- binary_sensor:
- name: "persons_away"
state: "{{ is_state('group.persons', 'not_home') }}"
delay_on:
minutes: 30
Your attempt checks for the state away
, which I’m pretty sure the group will never be — check on the states page. If it is away
, then output the undefined variable on
, otherwise… nothing.
You could also use the home zone if you’ve defined it: its state is the number of people in the zone. If it’s working properly, you could use:
state: "{{ is_state('zone.home', '0') }}"
EDIT: I thought so:
Yes, I found that.The strange thing is that when I check the history as well as the state value in the developers page, they both list the value as away
and home
It doesn’t say not_home
so intuitively I assumed that the docs were just outdated.
The actual state is shown in the state table on Developer Tools / Template: it’s that one you want, rather than the “sanitised”, friendly-but-incorrect version shown elsewhere:
Aha, I see. Many thanks. Is this a case of inconsistency, or just by (good?) design, I wonder…
Oh, by the way - it works now! Thank you ever so much for your valuable help.
Question, is this possible to do with Zones aswell?
I’ve got an issue where one of my zones is quite small, but using condition such as below doesnt work, the trace shows “Wanted_state: 0”
- condition: state
entity_id: zone.lidl
state: "0"
for:
hours: 0
minutes: 30
seconds: 0
This is how the issue looks like when having a smaller zone at the shop
What’s the trigger? That condition should pass if there has been no-one in zone.lidl
for 30 minutes.
This is the entire automation:
Triggers are state based ones ( as zones didnt work for me, dont know why… But zones never really liked me )
That’ll never work. You’re triggering off Philippe entering Lidl or Citygross zones (assume this is working or you wouldn’t have a trace).
Your condition block then needs all of the following to be true:
- Nikoline at home
- No-one in Lidl for the last 30 minutes
- No-one in Citygross for the last 30 minutes
Because of your trigger, you’re guaranteeing that one of the last two conditions is false: Philippe is in one of those zones. The evaluation is done after the trigger has fired.
Describe exactly what you’re trying to achieve and we’ll have a go at helping.