offset \ˈȯf-ˌset\ noun

a force or influence that makes an opposing force ineffective or less effective

Convert KML Placemarks to Zones for Home Assistant with Python

I have a habit of tracking the places we've been to in Google Earth Pro. I have a list of folders that are named after countries and, inside them, a list of places that we've been to. Sure, I can export to a KML/KMZ format but Google Maps refuses to load the file because of the size. I would also like to display the places in the Home Assistant, but there's no easy way and I really don't want to over-engineer this.

Home Assistant is self-hosted and I can control it, so I decided to whip up a quick script in Python to help me accomplish seeing the places in Home Assistant.

  1. I opened Google Earth and selected all the places, then exported them to a KML file that I called places.kml. I saved it to a location where I put the Python script.

/media/images/google-earth-places.png
  1. The script is in a file called kml2zones.py and safely nested in a virtual environment on Python 3.10.x. I installed the requirements with pip (pykml and PyYAML) and ran the script python kml2zones.py which in turn output the zones.yaml file in the same folder. Here are the contents:
from pykml import parser
from yaml import dump

# load kml into object
with open("places.kml") as f:
    root = parser.parse(f).getroot()

# iterate through the kml,
# extract what is needed in to a dict,
# then append that dict to to the list
data = []
for country in root.Folder.Folder:
    for placemark in getattr(country, "Placemark", []):
        try:
            coordinates = str(placemark.Point.coordinates).split(",")
        except Exception:
            coordinates = str(placemark.MultiGeometry.Point.coordinates).split(",")
        data.append({
            "name": str(placemark.name),
            "latitude": float(coordinates[1]),
            "longitude": float(coordinates[0]),
        })

# dump the list to a yaml format file
with open("zones.yaml", "w") as f:
    dump(data, f)
  1. I copied over the zones.yaml to the Home Assistant configuration folder and edited the configuration.yaml in it to have: zone: !include zones.yaml at the end, then I restarted the Home Assistant.
  2. I planned to load them in the Map card, but that card accepts only a list of entities which are generated from zones when the Home Assistant loads. I got the list of entities with Developer Tools in Home Assistant. Under Template, I put the following:
{% for item in states | map(attribute='entity_id') | list %}{% if item.startswith("zone") %}
  - entity: {{ item }}{% endif %}{% endfor %}

/media/images/home-assistant-template-zones.png

Good enough of that black magic, except the first result in the list which I had to indent manually. I copied the entities.

  1. I created a new tab on the dashboard with only one card so it expands, the type was Map, I added two zones in visual editor, as well as set the zoom to 3, then switched over to the code editor. This showed me how I wanted it to look like.

/media/images/home-assistant-map-card.png
  1. I removed those two zones under entities and in their place put the clipboard content obtained from step 4. Then I searched for the ones that I had from before in that list that are not from the zones.yaml (like zone.home or the local stores that I previously had saved in the Home Assistant database) and removed them. I finished editing the card.

/media/images/home-assistant-map.png

That's pretty much it. It really shows how it's easy to do things with Python.

As of this moment, I did a number of small stupid scripts for doing various things. Some of them grew into a full fledged service like Mellow. Mellow was more an opportunity to play with what AWS has to offer than anything else. The kml2zones.py could maybe be converted into a service as well but I cannot be bothered and, what's more likely, people would not really use it, but it is there if someone wants to nibble on it and help themselves. Even executing it without a file, through REPL itself.

Some of the scripts I did end up as a snippet, some of them as a repository. Of the top of my head I made:

  1. Mellow - the conversion from Trello board to Coggle mind map
  2. kml2zones.py - the conversion from KML file to zones.yaml for Home Assistant
  3. geotag-gallery - making a KML file with placemarks from photos and tagging them with convolution AI results
  4. led-morse - blinking LED light on Arduino in a Morse code
  5. Shamrock - getting plant data from a 3rd party service.

Probably more. Writing those things is easy and the possibilities are endless.

The script in this article is an example of how things can be done quick and dirty if one only wants to invest a bit of time. I remember seeing some videos of people using Python as a scripting language much like a macro in an operating system. It would open browser, start some pages, click through some of the options and so on. Generally automating a plethora of mundane tasks. I'm sure people could utilize it in their own life, too.