Good remark @Mariusthvdb
I tried that first, it was working better than the default prioritisation done in person but was still not really satisfied.
Especially for two use cases if I recall correctly:
when hovering around the zone perimeter gave many state alterations. I recently added even some hysteresis for that
When GPS is stucked to home (as described above). I ignore GPS state, only GPS triggers matter ( stationary, states are reliable though )
The custom integration has complex configuration options, but I simply couldn’t figure out the intent to get it working better.
Edit: Just for the fun, leaving and enter examples (first line is the composite):
Note: I can really advice to add BLE trackers using EspHome BLE scanners and the Prive BLE integration to be able to recognize you phones. Most phone loose the network quite often for several minutes while not used, but BLE tends to work both way faster (detecting in seconds) and more reliable (almost 24/7 stable)
Just use this.state in your templates. It's not possible, nor will it ever be possible, to have this in the triggers or conditions in the main section. The coordinator that handles triggers, the action section, and the condition section, is built well before the entities are built. It's a chicken/egg scenario that cannot be overcome without an entire rewrite. Secondly, the likelihood of template blueprints remaining single entity is low. I'll likely remove this restriction in the future when i start reworking the blueprints.
@petro Thanks for the crisp answer!!
Can you maybe reflect if my last (3rd) option is viable (do the update, but use previous settings to only update last recorded)
Can you explain what you mean? Updates are purely handled by core. Meaning they determine when to update those properties based on the update they receive from the integration. I.e. This is typically handled by the user and their template with template entities.
I mean that if I don't want to update the state of the device tracker (without this above entity_level that is to be determined at entity level), I hope to pass exacly the previous values, in order not to send a new value to the recorder (so only last reported changed).
It that works I know how to proceed. Understanding the forums it seems this would do the job:
template:
…
device_tracker:
- name: test
variables:
no_update: “{{ true if ... }}”
in_zones: “{{ this.attributes.in_zones if no_update else … }}”
latitude: "{{ this.attributes.latitude if no_update else … }}"
longitude: "{{ this.attributes.longitude if no_update else … }}"
location_accuracy: "{{ this.attributes.gps_accuracy if no_update else … }}"
I got stuck with the trigger based device_tracker template
I expected to have this available at entity level, but it isn't for variables inside the entity:
device_tracker:
- name: Car
variables:
old_state: "{ this.state }}"
I get:
2026-06-08 15:25:06.192 ERROR (MainThread) [homeassistant.helpers.template] Template variable error: 'this' is undefined when rendering '{{ this.state }}'
Is that a bug?
I really need the old state at this point
I have the device tracker working, except for preventing state changes, even with identical data
The trace of a simple automation (triggered by any state or attribute changes) demonstrates:
AFIKT the to and from states are identical, except for last_changed, reported and updated
They have changed, even with identical state. I expected only reported to be updates?!
Do you think this is a bug in the core classed used?!
Sorry, its big (don’ see how to upload as a file). Stationary updates nicely preserve the last zone and GPS information, but state is reported,updated and changed:
- trigger:
- platform: state
entity_id:
- device_tracker.iphone_eric
- device_tracker.iphone_eric_nmap
- device_tracker.ble_iphone_eric_bermuda_tracker
variables:
latitude: "{{ trigger.to_state.attributes.latitude | default(None) }}"
longitude: "{{ trigger.to_state.attributes.longitude| default(None) }}"
gps_accuracy: "{{ trigger.to_state.attributes.gps_accuracy | default(20) }}"
gps_update: "{{ latitude!=None and longitude!=None }}"
enabled: true
- platform: homeassistant
event: start
variables:
latitude: "{{None }}"
longitude: "{{None }}"
gps_accuracy: "{{ None }}"
gps_update: false
variables:
input_trackers:
- device_tracker.iphone_eric
- device_tracker.iphone_eric_nmap
- device_tracker.ble_iphone_eric_bermuda_tracker
trigger_at_startup: true
gps_home_filter:
- bluetooth_le
- bluetooth
conditions:
- condition: template
value_template: "{{ trigger.platform!='homeassistant' or trigger_at_startup }}"
device_tracker:
- name: Car
variables:
# old_state: |
# {{ this.state if this.state else 'unknown' }}
new_state: |
{% if gps_update %}
{% if trigger.to_state.state!='home'
and
(expand(input_trackers)
| selectattr('attributes.source_type','in',gps_home_filter)
| selectattr('entity_id', 'is_state', 'home')
| list | count > 0
)
and
(distance(trigger.entity_id)*1000 <
(gps_accuracy+state_attr("zone.home", "radius")|float(30))
)
%}
{#- overrule GPS reporting not home in case a
selected stationary tracker still report
home and the distance to home is close enough
-#}
{{ 'home' }}
{% else %}
{{ trigger.to_state.state }}
{% endif %}
{% else %}
{#-
home, if any stationary tracker report home.
Preserve other zones by using old_state when not home
-#}
{{ 'home' if (expand(input_trackers)
|rejectattr('attributes.latitude','defined')
|rejectattr('attributes.longitude','defined')
|selectattr('state','in',['home','on'])|list|count>0)
else 'not_home' }}
{% endif %}
# else old_state if
# (old_state not in ['home','unknown','unavailable'])
in_zones: |
{# use old state to preserve other zones when a stationary tracker reports not_nome #}
{% set old_state= this.state if this is defined and this.state is defined else 'unknown' %}
{% if gps_update or old_state in ['home','unknown','unavailable'] or new_state!='not_home' %}
{{ ['zone.'~new_state] if (states.zone[new_state]) else [] }}
{% else %}
{{ ['zone.'~old_state] if (states.zone[old_state]) else [] }}
{% endif %}
latitude: |
{% set old_state= this.state if this is defined and this.state is defined else 'unknown' %}
{{ latitude if gps_update else None if old_state!=new_state else this.attributes.latitude|default(None) }}
longitude: |
{% set old_state= this.state if this is defined and this.state is defined else 'unknown' %}
{{ longitude if gps_update else None if old_state!=new_state else this.attributes.longitude|default(None) }}
location_accuracy: |
{% set old_state= this.state if this is defined and this.state is defined else 'unknown' %}
{{ gps_accuracy if gps_update else None if old_state!=new_state else this.attributes.gps_accuracy|default(None)}}
Thanks for looking onto this ,Do you agree this is a bug of the core platform? I will then raise an issue.
(This is why I originally wanted to filter unwanted updates in the condition section. Cleaner code and more certain ).
I don't necessarily agree if it's a bug or not. The device_tracker platform is different from all other platforms, this may be something that is intentional.