Find shortest distance between phone and coordinates

hi

I’m trying to find the shortest distance with name between phone and GPS locations. I have enabled phone location and tried below code but the result is unknown. Can someone help?

{% set locations = {
  "San Francisco": (5.169231175822279, 76.50155407099898),
  "Los Angeles": (5.169135339347688, 76.50266904873067),

} %}

{% set phone_lat = state_attr('device_tracker.iphone', 'latitude') %}
{% set phone_lon = state_attr('device_tracker.iphone', 'longitude') %}

{% if phone_lat is not none and phone_lon is not none %}
  {% set min_dist = 9999 %}
  {% set closest_location = "Unknown" %}

  {% for name, coords in locations.items() %}
    {% set dist = distance(phone_lat, phone_lon, coords[0], coords[1]) %}
    {% if dist < min_dist %}
      {% set min_dist = dist %}
      {% set closest_location = name %}
    {% endif %}
  {% endfor %}

  Closest Location: {{ closest_location }}
{% else %}
  "Unknown"
{% endif %}

You need to use a namespace to extract the value from the loop.

{% set locations = {
  "San Francisco": (5.169231175822279, 76.50155407099898),
  "Los Angeles": (5.169135339347688, 76.50266904873067)
} %}

{% set phone_lat = state_attr('device_tracker.iphone', 'latitude') %}
{% set phone_lon = state_attr('device_tracker.iphone', 'longitude') %}
{% if phone_lat is not none and phone_lon is not none %}
  {% set min_dist = 9999 %}
  {% set ns = namespace(closest_location="Unknown") %}
  
  {% for name, coords in locations.items() %}
    {% set dist = distance(phone_lat, phone_lon, coords[0], coords[1]) %}
    {% if dist < min_dist %}
      {% set min_dist = dist %}
      {% set ns.closest_location = name %}
    {% endif %}
  {% endfor %}

  Closest Location: {{ ns.closest_location }}
{% else %}
  "Unknown"
{% endif %}

FWIW, you can use the device_tracker entity ID directly as the first arg for distance() instead of extracting the lat and long.

This is Ok in the Developer Tool template but still shows unknown when the sensor is set. Any idea? I have cleared browser cache but the issue still persists.

A state value of “unknown” can often be caused by a minor configuration error. Please share the full sensor configuration.

- sensor:
      - name: "f_shortest_distance"
        unit_of_measurement: "Km"
        state: > 
          {% set phone_lat = state_attr('device_tracker.iphone', 'latitude') %}
          {% set phone_lon = state_attr('device_tracker.iphone', 'longitude') %}

          {% if phone_lat is not none and phone_lon is not none %}
            {% set phone_lat = phone_lat %}
            {% set phone_lon = phone_lon %}

            {% set locations = [
              {'name': 'San Francisco', 'coords': (37.7749, -122.4194)},
              {'name': 'Los Angeles', 'coords': (34.0522, -118.2437)},
              {'name': 'Las Vegas', 'coords': (36.1699, -115.1398)}
            ] %}

            {% set ns = namespace(shortest_distance=none, shortest_location="Unknown") %}

            {% for location in locations %}
              {% set dist = distance(phone_lat, phone_lon, location.coords[0], location.coords[1]) %}
              {% if ns.shortest_distance is none or dist < ns.shortest_distance %}
                {% set ns.shortest_distance = dist %}
                {% set ns.shortest_location = location.name %}
              {% endif %}
            {% endfor %}
            
            {{ ns.shortest_location }}: {{ ns.shortest_distance | round(2) }} km
          {% else %}
            Unknown
          {% endif %}

You need to get rid of the unit of measurement. Sensor’s with a defined unit_of_measurement must return a numeric value… your template will always return a string like “Las Vegas: 3010.1 km”.

1 Like

And that error should be visible in the log.