Mastodon

We're looking for the trash fence...

Adding GPS to Victron Energy System and Home Assistant

Posted on Wed 06 September 2023 in ADVVAN

I have been working on a project to add GPS based location updates to my van automation. This will allow me to track my location and the location of my van on a map. I will also be able to use this data to trigger events and fetch location specific information (ex: weather) in Home Assistant.

Hardware

I am using a Adafruit Ultimate GPS with USB and a Parsec Belgian Shepherd 7-in-1 Antenna which will also provides external LTE and WIFI antennas for my router.

Adafruit Ultimate GPS with USB Parsec Belgian Shepherd 7-in-1 Antenna

Software

The Adafruit GPS is connected to the Victron Cerbo GX via USB. It was automatically recognized by the Cerbo GX and is then available in VRM and Victron Connect. Victron is integrated into my Home Assistant instance using SFStars's HASS-Victron integration. I had already set this up previously and had to ReScan the GX Device to get the GPS to show up in Home Assistant as entities.

Configuration

Sample Scripts

To test all this, I made several Home Assistant Scripts to write to the logbook, work out how to get the GPS data, and to do some special calculations. These scripts are created in Home Assistant under settings, Automation and Scenes, and then select Scripts. I used the YAML editor exclusively.

Current Location

This is how to access the location set in Home Assistant. This is stored in the zone.home entity which has latitude and longitude attributes. Notice I am using the state_attr() helper not states(). This was non-obvious to me as it does not use use dot notaton object.attribute or object[''] style like in Python and took a while to figure out.

alias: Log Current Location
mode: single
icon: mdi:map-marker
sequence:
  - service: logbook.log
    data:
      name: Current Location
      message: >-
        lat: {{ state_attr('zone.home', 'latitude') }}, lon: {{
        state_attr('zone.home', 'longitude') }}

Update Home Assistant Current Location

This script captures the current location from the Victron attached GPS and then updates the current location in Home Assistant with the homeassistant.set_location service.

I also started to get more advanced here and I'm using script variables at the beginning which makes the code more readable to me.

alias: Update Van Location
mode: single
icon: mdi:crosshairs-gps
variables:
  cur_latitude: "{{ states('sensor.victron_gps_latitude_100') }}"
  cur_longitude: "{{ states('sensor.victron_gps_longitude_100') }}"
sequence:
  - service: logbook.log
    data:
      name: New Location
      message: "lat: {{ cur_latitude }}, lon: {{ cur_longitude }}"
  - service: homeassistant.set_location
    data:
      latitude: "{{ cur_latitude }}"
      longitude: "{{ cur_longitude }}"

Distance between Home Zone and Current Location

This script calculates the distance between the current location and the home location. This is done using the Haversine formula which I found on Omni Calculator and then convterted to Jinja \ HA Script with Chat-GPT4.

If you want to use this, but you prefer Miles over Kilometers, you can change the earth_radius_km variable to earth_radius_mi in the formular for the distance variable

alias: Calculate Distance
mode: single
icon: mdi:map-marker-distance
variables:
  earth_radius_km: 6371
  earth_radius_mi: 3959
  pi: 3.141592653589793
  prev_latitude_deg: "{{ state_attr('zone.home', 'latitude') }}"
  prev_longitude_deg: "{{ state_attr('zone.home', 'longitude') }}"
  new_latitude_deg: "{{ states('sensor.victron_gps_latitude_100') }}"
  new_longitude_deg: "{{ states('sensor.victron_gps_longitude_100') }}"
  prev_latitude_rad: " {{ prev_latitude_deg * (pi / 180) }}"
  prev_longitude_rad: "{{ prev_longitude_deg * (pi / 180) }}"
  new_latitude_rad: "{{ new_latitude_deg * (pi / 180) }}"
  new_longitude_rad: "{{ new_longitude_deg * (pi / 180) }}"
  distance: |-
    {{
      (2 * earth_radius_km) * asin(sqrt(sin((new_latitude_rad - prev_latitude_rad) / 2) ** 2 +
      cos(prev_latitude_rad) * cos(new_latitude_rad) *
      sin((new_longitude_rad - prev_longitude_rad) / 2) ** 2))
    }}
sequence:
  - service: logbook.log
    data:
      name: Distance From Last Known Location
      message: "Distance: {{ distance|round(0,floor)|int}} Km"

This could be made more robust by checking each variable is valid but if everything is working, it works. I did have a problem where all my sensor.victron_gps_** entities switched from ending in _0 to _100 after upgrading HA to 2023.9, this appears to be a known issue.

Final Scripts

... More to come ...