# How to calculate a geofence and know when in or out of it

I now have my mobile HA instance location being update every 5 minutes with Latitude and Longitude.

I’d like to be able to set a geofence of say 50m every time the vehicle stops and then get notified when HA moves out of that geofence.

I think I first need to be able to calculate the geofence circle from latitude and longitude.

Secondly calculate the distance from the stop point.

Any ideas?

Make a template sensor using a trigger of your choice with

``````for:
minutes: 5
``````

then in the template sensor store the latitude and longitude as attributes.

Second make a template sensor that calculates the distance between your current location and the previous template sensor. Use the `distance()` jinja function to do that. The output of the distance function is meters.

Then do whatever you want with the second sensor’s distance.

I have a feeling you’ll need more help. So…

``````template:
- trigger:
- platform: state
entity_id: person.xyz
to: ~
for:
minutes: 5
sensor:
- name: XYZ Last Location
unique_id: something_long_and_unique
state: >
{{ trigger.to_state.state }}
attributes:
latitude: >
{{ trigger.to_state.attributes.latitude }}
longitude: >
{{ trigger.to_state.attributes.longitude }}

- sensor:
- name: XYZ Distance from last location
unique_id: something_long_and_unique2
device_class: distance
unit_of_measurement: m
state: >
{{ distance('person.xyz', 'sensor.xyz_last_location') }}
``````
1 Like

Thank you both.

I found this calculation.

It’s a little more complicated than a subtraction but I can’t see a way of doing this using templating as the cos and arctan don’t seem to be available.

In python it looks like this (as far as I can work out) but I don’t know how to use it with HA.

i

``````import math

latitude_change = (new_latitude-stationary_latitude) * math.pi/180

longitude_change = (new_longitude-stationary_longitude) * math.pi/180

a = math.sin(latitude_change/2) * math.sin(latitude_change/2) + \

math.sin(longitude_change/2) * math.sin(longitude_change/2)

c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))

``````

You don’t need what is there, the distance function in HA does this already without needing that calculation. Did you try what I wrote?

I have a feeling you didn’t read anything I wrote, I’m the single person who replied to you.

Apologies, Petro.

Yes, I did read it, or rather misread it. I wasn’t aware that ‘distance’ did that.

I will give it a try when I get home and let you know how it goes.

That’s an excellent solution.

My challenge is creating the dummy person.xyz to use the HA lat and long for location.

Checking in Dev Tools the location of HA doesn’t seem to be available as an entity.

I have created lat and long sensors but how would I use them with person.xyz?

I could create a new sensor with both lat and long attributes and trigger from changes to that maybe. Not something I tried to do before so a nice challenge.

You don’t need a person, you can use a device tracker too. Or a sensor with lat/lon.

It just needs an entity with lat/lon attributes.

e.g.

``````template:
- sensor:
- name: My Coordinates
unique_id: something_long_and_unique0
state: >
{{ states('sensor.lat') }}, {{ states('sensor.lon') }}
attributes:
latitude: >
{{ states('sensor.lat') }} }}
longitude: >
{{ states('sensor.lon') }}

- trigger:
- platform: state
entity_id: sensor.my_coordinates
to: ~
for:
minutes: 5
sensor:
- name: XYZ Last Location
unique_id: something_long_and_unique
state: >
{{ trigger.to_state.state }}
attributes:
latitude: >
{{ trigger.to_state.attributes.latitude }}
longitude: >
{{ trigger.to_state.attributes.longitude }}

- sensor:
- name: XYZ Distance from last location
unique_id: something_long_and_unique2
device_class: distance
unit_of_measurement: m
state: >
{{ distance('person.xyz', 'sensor.xyz_last_location') }}
``````

Thank you.

So, replace person.xyz with sensor.my coordinates in the last line?

just replace `sensor.lat` and `sensor.lon` wherever you see that in what I pasted with your lat/lon senosrs.

Then use that sensor in the trigger of the other sensor.

Sir, you are a genius. Works a treat. Thank you so much for your help.

``````  - sensor:
- name: CIP Coordinates
unique_id: cip_coordinates_for_geofence
state: >
{{ states('sensor.latitude') }}, {{ states('sensor.longitude') }}
attributes:
latitude: >
{{ states('sensor.latitude') }}
longitude: >
{{ states('sensor.longitude') }}

- trigger:
- platform: state
entity_id: sensor.cip_coordinates
to: ~
for:
seconds: 5
sensor:
- name: CIP Last Location
unique_id: cip_last_coordinates
state: >
{{ trigger.to_state.state }}
attributes:
latitude: >
{{ trigger.to_state.attributes.latitude }}
longitude: >
{{ trigger.to_state.attributes.longitude }}

- sensor:
- name: CIP Distance from last location
unique_id: cip_distance_from_parked_location
device_class: distance
unit_of_measurement: m
state: >
{{ distance('sensor.cip_coordinates', 'sensor.cip_last_location') }}
``````

It does produce some rather odd distance values though.

I’m guessing that’s just micro movements caused by the satellites. I’m not able to actually move it just now but it all seems good.

Thanks again.

You can round the result with a `{{ distance('sensor.cip_coordinates', 'sensor.cip_last_location') | round(2) }}`