You didn’t say that. You only provided very little context. Therefore I think you can ignore what I said.
no I wont ignore, I’m deep printing it in my head… thank you sir.
still, don’t want to leave you out of context, so here’s the whole thing:
- alias: Presence Tracking
id: 'Presence Tracking'
trigger:
- platform: state
entity_id:
# - device_tracker.1
# - device_tracker.2
# - device_tracker.3
# - device_tracker.4
- device_tracker.iphone
- device_tracker.telefoon
condition:
- condition: template
value_template: >
{{ trigger.to_state.state is not none and
trigger.from_state.state is not none and
trigger.to_state.state != trigger.from_state.state
}}
- condition: template
value_template: >
{% set zones = states.zone | map(attribute='entity_id')|list %}
{{trigger.to_state.state in ['home','not_home'] or
trigger.zone in zones}}
- condition: template
value_template: >
{{ (now() - trigger.from_state.last_changed).total_seconds() > 120 }}
- condition: template
value_template: >
{{ is_state('input_boolean.notify_presence', 'on')}}
action:
service: notify.m
data_template:
title: 'Presence Tracking:'
message: >
{% set name = trigger.to_state.attributes.friendly_name %}
{% set to_state = trigger.to_state.state %}
{% set from_state = trigger.from_state.state %}
{% if to_state == 'not_home' %}
{{ name }} left {{from_state}}
{% elif from_state == 'not_home' %}
{{ friendly_name }} arrived at {{to_state}}
{% else %}
{{ name }} left {{from_state}} and arrived at {{to_state}}
{% endif %}
as you can see I’ve taken your advice to heart and left the a != a
out…
the second value template, I am now uncertain of. I meant it to select only the possible states it should pass for the action to fire. But since you’ve told me it only shows valid state and will always be yes, it might be superfluous here too?
So the first condition should only allow state changes where the state string changed (and didn’t change from or to None.) I think that’s fine.
I’m not sure the second condition will work, mainly because for a state trigger there’s no such thing as trigger.zone. That only exists for a zone trigger, which you’re not using here. Also, looking past that detail and what I think the intent of this condition was, I’m not sure it does anything for you. A device_tracker’s state string will probably always be ‘home’, ‘not_home’ or the name of a zone. So why have a condition that the state string is something it will probably always be? Or are you trying to filter out ‘unknown’, ‘unavailable’, etc.?
The third condition only allows changes through where the device_tracker was in a given state for at least 2 minutes. That seems fine also.
And, of course, the fourth condition is fine, too.
Looking at the message template, I see one typo - using {{ friendly_name }}
when you haven’t defined a variable named friendly_name. I suspect you meant {{ name }}
. And, FWIW, you can simplify:
{% set name = trigger.to_state.attributes.friendly_name %}
to
{% set name = trigger.to_state.name %}
That will be the same as attributes.friendly_name if it exists, or the entity_id (or object_id, I don’t really remember which) if the entity does not have a friendly_name defined.
So, are you saying this automation notifies too often? If so, I’m not sure how.
is that so? These are my phones iCloud device_trackers, which are Zone capable? They report leaving or entering a zone…
yep, indeed, try to do that as much as possible, only allow the states Im interested in and filter out all other possible options.
indeed , typo, missed the one, thanks. will test again with this change to see what happens.
we were talking before about the triggering behavior of binary_sensors, and you said they trigger also when the object they listen to change. I thought that woud be very cool so changed:
- alias: 'Low light - Hallway motion sensors'
id: 'Low light - Hallway motion sensors'
#initial_state: on
trigger:
- platform: state
entity_id: sensor.mean_living_lux
- platform: state
entity_id: binary_sensor.low_lux_input
- platform: state
entity_id: sun.sun
to: 'below_horizon'
condition:
- condition: template
value_template: >
{{ trigger.to_state.state is not none and
trigger.from_state.state is not none and
trigger.to_state.state != trigger.from_state.state }}
# - condition: template
# value_template: >
# states('binary_sensor.low_lux_input') in ['on','off'] }}
- condition: template
value_template: >
{{ (as_timestamp(now()) -
as_timestamp(state_attr('automation.low_light__hallway_motion_sensors','last_triggered'))
| default(0) | int > 240) }}
action:
- service_template: >
homeassistant.turn_{{ states('binary_sensor.low_lux_input') }}
entity_id: group.philips_hallway_motion_sensor_switches
- condition: template
value_template: >
{{is_state('input_boolean.notify_notify', 'on')}}
- service: notify.notify
data_template:
message: >-
{{as_timestamp(now()) | timestamp_custom("%X") }}:
Hallway motion detection is {{ states('binary_sensor.low_lux_input') }},
Low lux threshold: {{(states('input_number.low_lux') | float)}}
{{'>' if is_state('binary_sensor.low_lux_input', 'on') else '<'}}
Mean living light : {{ states('sensor.mean_living_lux')}}.
Sun is {{states('sun.sun')}}.
in to this:
- alias: 'Low light - Hallway motion sensors'
id: 'Low light - Hallway motion sensors'
# initial_state: on
trigger:
- platform: state
entity_id: binary_sensor.low_lux_input
- platform: state
entity_id: sun.sun
to: 'below_horizon'
condition:
- condition: template
value_template: >
{{ trigger.to_state.state is not none and
trigger.from_state.state is not none and
trigger.to_state.state != trigger.from_state.state }}
# - condition: template
# value_template: >
# {{ states('binary_sensor.low_lux_input') in ['on','off'] }}
- condition: template
value_template: >
{{ (as_timestamp(now()) -
as_timestamp(state_attr('automation.low_light__hallway_motion_sensors','last_triggered'))
| default(0) | int > 240) }}
action:
- service_template: >
homeassistant.turn_{{ states('binary_sensor.low_lux_input') }}
entity_id: group.philips_hallway_motion_sensor_switches
- condition: template
value_template: >
{{is_state('input_boolean.notify_notify', 'on')}}
- service: notify.notify
data_template:
message: >-
{{as_timestamp(now()) | timestamp_custom("%X") }}:
Hallway motion detection is {{ states('binary_sensor.low_lux_input') }},
Low lux threshold: {{(states('input_number.low_lux') | float)}}
{{'>' if is_state('binary_sensor.low_lux_input', 'on') else '<'}}
Mean living light : {{ states('sensor.mean_living_lux')}}.
Sun is {{states('sun.sun')}}.
using:
binary_sensor:
- platform: template
sensors:
low_lux_input:
friendly_name: Low lux input
device_class: light
value_template: >
{{(states('sensor.mean_living_lux') | float) <
(states('input_number.low_lux') | float)}}
thinking the binary_sensor would catch the continuous light level changes of the sensor.mean_living_lux. It doesnt. It now triggers perfectly the the actual state of the binary changes on/off or when the sun trigger triggers. no automatic changes on light level, which the first example did trigger on…
but, as the added trigger keeps triggering the automation after the set time is passed, and even though I have the condition {{trigger.to_state.state != trigger.from_state.state}}
I added @lolouk44 's suggestion for condition to rule that out for good…
- condition: template
value_template: >
{{ states('group.philips_hallway_motion_sensor_switches') !=
states('binary_sensor.low_lux_input') }}
lets see what happens…
the check for the boiler was a bit more complex, since it required 2 trigger entities to check. Can this be simplified further?
- condition: template
value_template: >
{{ states('switch.sw_boiler_bijkeuken_template') !=
('on' if is_state('binary_sensor.zp_opbrengst_threshold_input','on') or
is_state('sensor.huidig_tarief', '1')
else 'off')}}
Yes, that is so. What fields are in the trigger variable have to do with the trigger platform, not the entity. And, BTW, all device_trackers (that are GPS based) are “zone capable.”
I was only talking about the threshold binary sensor, not every binary sensor.
Ok, thx. Trying to get to the bottom of this… how come the Message displays my zones just fine then? And I don’t mean home/not_home, but the real zones I declared in the zone component configuration ? They are passed on , without setting them as trigger .
Btw the difference between the behavior of the binary_sensor is noteworthy. Glad you pointed that out.
Wonder how one has to find out without this community…
@pnbruckner @lolouk44
all seems to be working fine now, so heres the full setup for reference thank you both for your invaluable advice and suggestions:
binary_sensor:
- platform: threshold
name: 'ZP Opbrengst threshold'
entity_id: sensor.zp_actuele_opbrengst
upper: 1500
- platform: template
sensors:
zp_opbrengst_threshold_input:
friendly_name: 'ZP Opbrengst threshold input'
value_template: >
{{(states('sensor.zp_actuele_opbrengst') | float) >
(states('input_number.zp_opbrengst_threshold') | float)}}
group:
solar_switch_monitor:
name: Solar switch monitor
control: hidden
icon: mdi:theme-light-dark
entities:
- switch.sw_boiler_bijkeuken_template
- sensor.huidig_tarief
- sensor.zp_actuele_opbrengst
- input_number.zp_opbrengst_threshold
- binary_sensor.zp_opbrengst_threshold_input
- binary_sensor.zp_opbrengst_threshold
- automation.boiler_switch
binary_sensor.zp_opbrengst_threshold_input:
show_last_changed: true
binary_sensor.zp_opbrengst_threshold:
show_last_changed: true
automation.boiler_switch:
show_last_changed: true
templates:
icon: >
if (state === 'on') return 'mdi:bell';
return 'mdi:bell-off';
icon_color: >
if (state === 'on') return 'rgb(251, 210, 41)';
return 'rgb(54, 95, 140)';
- alias: Boiler switch
id: 'Boiler switch'
trigger:
- platform: state
entity_id: sensor.huidig_tarief
- platform: state
entity_id: binary_sensor.zp_opbrengst_threshold_input
condition:
- condition: template
value_template: >
{{ trigger.to_state.state is not none and
trigger.from_state.state is not none and
trigger.to_state.state != trigger.from_state.state }}
# - condition: template
# value_template: >
# {{ states('binary_sensor.zp_opbrengst_threshold_input') in ['on','off'] }}
- condition: template
value_template: >
{{ (as_timestamp(now()) -
as_timestamp(state_attr('automation.boiler_switch','last_triggered'))
| default(0) | int > 240) }}
- condition: template
value_template: >
{{ states('switch.sw_boiler_bijkeuken_template') !=
('on' if is_state('binary_sensor.zp_opbrengst_threshold_input','on') or
is_state('sensor.huidig_tarief', '1')
else 'off')}}
action:
- service_template: >
switch.turn_{{'on' if is_state('binary_sensor.zp_opbrengst_threshold_input','on') or
is_state('sensor.huidig_tarief', '1') else 'off'}}
entity_id: switch.sw_boiler_bijkeuken_template
- condition: template
value_template: >
{{ is_state('input_boolean.notify_notify', 'on')}}
- service: notify.notify
data_template:
message: >
Threshold: {{states('binary_sensor.zp_opbrengst_threshold_input')}}, ZP {{states('sensor.zp_actuele_opbrengst')}}, Tarief {{states('sensor.huidig_tarief')}}:
Switching Boiler: {{'on' if is_state('binary_sensor.zp_opbrengst_threshold_input','on') or
is_state('sensor.huidig_tarief', '1') else 'off' }}.
the sensor Badge:
sensor.levering_of_verbruik:
state_card_mode: badges
templates:
# icon_color: >
# if (state === 'Levering') return 'rgb(251, 210, 41)';
# return 'rgb(54, 95, 140)';
theme: >
if (state > 0) return 'orange';
return 'green';
unit_of_measurement: >
${entities['sensor.calculated_bruto_verbruik'].state}
levering_of_verbruik:
friendly_name_template: >
{% if states('sensor.netto_verbruik')|int > 0 %} Verbruik
{% else %} Levering
{% endif %}
icon_template: >
{% if states('sensor.netto_verbruik')|int > 0 %} mdi:import
{% else %} mdi:export
{% endif %}
value_template: >
{{states('sensor.netto_verbruik')|int}}
based on a mqtt sensor reading from my smart meter: sensor.netto_verbruik
Thanks!
please let me get back to this for a little unclarity on my side. Since we talked about the string/number issue. Ive been rewriting all to reflect the correct format. And try to have numbers everywhere without the quotes, so reading the yaml makes it clear what I am dealing with.
However when dealing with this, i am a bit confused:
this works:
customize-ui syntax:
group.personal:
templates:
icon: >
if (entities['sensor.family_home'].state === '0') return 'mdi:account-off';
if (entities['sensor.family_home'].state === '1') return 'mdi:account';
if (entities['sensor.family_home'].state === '2') return 'mdi:account-multiple';
return 'mdi:account-group';
Jinja:
templates:
icon: >
{% if is_state('sensor.family_home', '0') %} 'mdi:account-off'
{% elif is_state('sensor.family_home','1') %} 'mdi:account'
{% elif is_state('sensor.family_home', '2' ) %} 'mdi:account-multiple'
{% else %} 'mdi:account-group'
{% endif %}
as you see I have to put the numbers in quotes. that is, if I use the is_state() format. I can leave the quotes out with |int
when using the states.sensor.family_home.state
format:
{% if states.sensor.family_home.state|int == 0 %} 'mdi:account-off'
{% elif states.sensor.family_home.state|int == 1 %} 'mdi:account'
{% elif states.sensor.family_home.state|int == 2 %} 'mdi:account-multiple'
{% else %} 'mdi:account-group'
{% endif %}
Not sure why the numbers are turned into strings and I have to make them numbers again using the |int ( in the python script which creates this sensor I can safely use the unquoted numbers.
Secondly, is here a way to use the |int in the first 2 templates above? I can t seem to find a correct format/syntax for that.
thx,
Marius
First, if you have any templates that are evaluated in the frontend (vs the backend), I can’t comment on that. I don’t use any custom UI and I’m not familiar with how any of that works.
Second, all states are strings, no matter what they were before being updated in the state machine. See this code – the first thing it does with a new state value is to turn it into a string.
yes, I understand.
I guess it doesnt make a lot of difference then, but since the numbers here should be true numbers, as in the count of people home, they shouldn’t be quoted and turned into strings, as you mentioned before. And, consequently, the sensor state should be turned into a number again by using |int
…
All a matter of principle of course.
question remains:
can I write the is_state() construction below:
{% if is_state('sensor.family_home', '0') %} 'mdi:account-off'
{% elif is_state('sensor.family_home','1') %} 'mdi:account'
{% elif is_state('sensor.family_home', '2' ) %} 'mdi:account-multiple'
{% else %} 'mdi:account-group'
{% endif %}
somehow, using the |int, so I don’t have to quote the numbers. Like
{% if states.sensor.family_home.state|int == 0 %} 'mdi:account-off'
{% elif states.sensor.family_home.state|int == 1 %} 'mdi:account'
{% elif states.sensor.family_home.state|int == 2 %} 'mdi:account-multiple'
{% else %} 'mdi:account-group'
{% endif %}
or
{% if states('sensor.family_home')|int == 0 %} 'mdi:account-off'
{% elif states('sensor.family_home')|int == 1 %} 'mdi:account'
{% elif states('sensor.family_home')|int == 2 %} 'mdi:account-multiple'
{% else %} 'mdi:account-group'
{% endif %}
I can find no way to use the is_state() construction with the |int …
Any of those will probably work. And, yes, is_state takes two parameters, an entity_id, and a value to compare that entity_id’s state to. And since an entity_id’s state is a string, the second parameter should also be a string.
The problem with numbers as strings is you sometimes can’t tell exactly how they’ll be converted. E.g., ‘0’, ‘00’, ‘0.0’ are all valid string representations for the number zero (the first two being representations for integers, and the third being a representation for a float.) But, if, for a particular entity, you now how the number will be represented, then you could do a string compare for equality. Still, you’re probably better off using an expression that allows comparisons as numbers instead of strings (which means, in this case, the is_state function may not be useful.)