Device tracker - porting `see` to template device tracker

device_tracker.see is being taken away, the intention to be replaced by a new template device_tracker[1]. In most situations this is a great idea, but I’m having trouble recreating an automation I had that used see previously.

Use case: To track the location where a vehicle was parked.

Previous solution: Use a legacy device tracker to keep track of the location of a car - when the occupancy of the car clears[2], copy (using see) the location of the driver to the legacy tracker.

The problem: GPS location updates are sometimes slow, so when the occupancy clears, we would like to “wait” for the next location of the driver before copying[3]. This is easily done in an automation using a wait trigger.

The closest equivalent I have come up with using the new template device tracker is the following (yes, it’s a blueprint):slight_smile:

blueprint:
  name: Vehicle Occupancy Device Tracker
  description: Creates a sensor that automatically updates if someone leaves a vehicle
  domain: template
  input:
    occupancy_sensor:
      name: Occupancy Sensor
      selector:
        entity:
          filter:
            - domain: binary_sensor
    source_device_tracker:
      name: Source Device Tracker
      selector:
        entity:
          filter:
            - domain: device_tracker

variables:
  source: !input source_device_tracker

trigger:
  - platform: state
    entity_id: !input occupancy_sensor
    from: "on"
    to: "off"

device_tracker:
    latitude: "{{ state_attr(source, 'latitude') }}"
    longitude: "{{ state_attr(source,'longitude') }}"
    location_accuracy: "{{ state_attr(source, 'gps_accuracy') }}"

The issue is that the last known location is used, which tends to be stale. I’ve tried thinking of how to use last_updated/changed/reported but there’s no way to track the “next update” after a point (I imagine that there are no waits in a template).

The only approaches I can think of now are:

  1. Filter updates to the template using a boolean helper, and control that boolean via an automation (which would require a boolean helper per person-vehicle combination)
  2. To do away with the vehicle device trackers altogether and just use the appropriate driver’s location (in an alert, say) but I quite like the idea of having a vehicle device tracker in general

TL;DR: how can we be more discerning about when a template sensor should update?

[1]Device tracker changes in 2027.5... what to do? - #78 by seanomat
[2] a bluetooth connection (or lack thereof) is used to determine occupancy
[3] yes, it could be that the new location is equally incorrect (as the person has walked away), but given a person is slower than a car this is seen to be the better approach (especially if a “single accurate location” is requested at the appropriate time too).

You can use Actions like Wait in a trigger-based template entity.

For a trigger-based Template entity, the procedure is roughly:

  1. Trigger fires.
  2. Templates in the Variables block are rendered.
  3. Conditions in the Condition block are checked.
  4. Actions in the Action block are performed.
  5. State value is rendered.
  6. Attribute values are rendered in turn.

Don’t forget, if you decide to stick with the binary sensor trigger, that you can also “delay” the trigger by adding a duration. That may be all that is needed for some users.

Thanks for the tip! I felt a little bad putting a wait in a template, so I decided to do something probably worse and encode a state in the location accuracy. It’s just about crazy to work:

blueprint:
  name: Vehicle Occupancy Device Tracker
  description: Creates a sensor that automatically updates if someone leaves a vehicle
  domain: template
  input:
    target_device_tracker:
      name: Target Device Tracker
    occupancy_sensor:
      name: Occupancy Sensor
      selector:
        entity:
          filter:
            - domain: binary_sensor
    source_device_tracker:
      name: Source Device Tracker
      selector:
        entity:
          filter:
            - domain: device_tracker

variables:
  source: !input source_device_tracker
  sensor: !input occupancy_sensor
  occupied: "{{ states(sensor) | bool }}"
  target: !input target_device_tracker
  force_copy: "{{ state_attr(target, 'gps_accuracy') | bool(true) }}"
  copy_state: "{{ state_attr(target, 'gps_accuracy') | int(2) }}"

trigger:
  - platform: state
    entity_id: !input occupancy_sensor
  - platform: state
    entity_id: !input source_device_tracker

device_tracker:
    in_zones: "[{{ iif(occupied or force_copy, states(source), states(target))}}]"
    latitude: "{{ iif(occupied or force_copy, state_attr(source, 'latitude'), state_attr(target, 'latitude'))}}"
    longitude: "{{ iif(occupied or force_copy, state_attr(source, 'longitude'), state_attr(target, 'longitude'))}}"
    location_accuracy: "{{ iif( occupied, 2, iif(copy_state == 2, 1, 0)) }}"

Just use a wait for trigger in your template entity action section.

I’ve marked @Didgeridrew’s post as the answer, even though I didn’t use it.

Thank you for this post - I’ve had a vehicle parking automation for ages using “see” (and I haven’t touched it in a long time). Due to on-street parking it’s very easy to forget where you parked, and I rely on this automation daily.

FWIW the solution I landed at (which does not use waits) is working great.