An asynchronous Home Assistant custom integration for advanced device tracker localization using local or remote GeoJSON layers. It cleanly processes nested, complex geometries—automatically prioritizing your smallest physical zones over larger overlapping ones.
To add this integration, please add the custom repository https://github.com/ticstyle/GeoZones/ to HACS in your Home Assistant setup.
This integration is written and maintained exclusively in English. All entity states, attributes, configuration dialogues, and logging diagnostic files use English standards.
- Smallest-Area Priority Hierarchy: Automatically parses your GeoJSON data, exploding any complex
MultiPolygonarrays into clean individual polygons. It then automatically sorts them from smallest to largest area, ensuring that nested sub-zones (like a small store inside a large shopping district) match first. - Smart Wi-Fi SSID Localizing: Pairs with your device's native companion app network sensor. It features an intelligent keyword matching algorithm that automatically ignores hardware BSSID/MAC addresses, isolates your true network SSID, and binds your tracking state instantly to home when connected to a designated Wi-Fi network.
- GPS Jitter & Accuracy Filtering: Configure a customized maximum GPS accuracy threshold (defaults to 50 meters) to ignore sloppy coordinate drift, preventing false-positive zone updates during weak signal telemetry events.
- In-Memory RAM Caching: Files are read into memory exactly once at startup or after update sequences. This prevents slow disk I/O reads or loop bottlenecks during high-frequency real-time GPS coordinate telemetry updates.
- Nightly Auto-Sync Sweeps: Every night at exactly 02:37 AM, the integration wakes up to redownload, validate, and resort all mapped GeoJSON configurations, ensuring your local spatial assets stay up to date.
- Strict Validation Guardrails: Protects your core engine loops by scanning structural constraints. If a processed workspace target exceeds 2,500 individual zones or 250,000 vertices, the layout drops safely and flags error reports into your system logs.
Via HACS or manually copy the geozones folder from the latest release to the custom_components folder inside your Home Assistant configuration directory.
Add and adjust the integration via the Home Assistant User Interface. The setup step can be run multiple times to spin up separate mirrored entity layers for different tracking devices, and existing entries can be fully tweaked on the fly using the native Reconfigure and Options flow.
During setup or reconfiguration, you will be prompted to provide:
- Source Device Tracker: An existing
device_trackerentity from your registry map records. - GeoJSON Source: A web URL destination path link (starting with
http://orhttps://) or a direct path location pointing to a local file asset. - Max GPS Accuracy: High-frequency GPS telemetry filter distance threshold in meters (default:
50). - Wi-Fi SSID Sensor (Optional): The parent sensor tracking your device's connected SSID (automatically matched during setup).
- Home SSIDs (Optional): A customizable list of network names that designate your Home wireless network profile.
- Home Zone (Optional): The target zone representing your primary residence (default:
zone.home).
When parsing your selected source tracker (e.g., device_tracker.iphone_stoffe), the integration registers a mirrored tracking device entry containing a custom identifier map:
| Entity ID | Name in UI | State Example | Description |
|---|---|---|---|
device_tracker.geozones_my_phone |
GeoZones my_phone | Coffee Shop |
The current matching zone name, prioritizing the smallest area structure. Returns not_home when outside polygon footprints. |
The generated tracker entity exposes rich metadata parameters to analyze tracking boundaries:
source_entity_id: The underlying device tracker entity being monitored.containing_zones: A nested string array listing all overlapping zones that the device is currently inside, sorted sequentially from smallest to largest area footprints.
To visually draw, edit, or customize your geographic zones, we recommend using Krata Maps — a clean, free, browser-based GeoJSON editor.
- Open krata.app in your web browser.
- Use the Draw Polygon tool to draw shapes around your desired areas (e.g., home, neighborhood, office, school).
- Click on each drawn shape in the left pane and give it a name: (Don't worry about calculating surface area — GeoZones automatically calculates polygon areas and orders overlapping boundaries for you!)
- Click Export and choose export as .geojson to download the file (e.g.,
my_zones.geojsonormy_zones.json).
Upload your exported file into your Home Assistant /config/geozones/ directory using your preferred method:
- File Editor Add-on: Navigate to
geozones/and click Upload File. - Studio Code Server / VS Code: Drag and drop the file into the
geozones/folder. - Samba Share / SSH: Copy the file into
/config/geozones/.
💡 Tip: If the
geozonesfolder doesn't exist yet, simply installing the GeoZones integration creates it automatically!
- In Home Assistant, go to Settings ➔ Devices & Services ➔ Add Integration ➔ GeoZones.
- GeoZones will automatically detect your file inside
/config/geozones/and pre-fill the path for you in the setup window!
Because calculated parameters are exposed cleanly to the event bus, you can easily design contextual dashboards using native Markdown tools without complicated layout configurations.
type: markdown
title: GeoZones status
content: >-
{% set trackers = states.device_tracker
| selectattr('entity_id', 'search', '^device_tracker\\.geozones_')
| list %}
{% if trackers | length > 0 %}
### {% for tracker in trackers %}
### 📱 {{ tracker.name }}
* **Current Zone:** `{{ tracker.state }}`
* **Source Target:** `{{ state_attr(tracker.entity_id, 'source_entity_id') }}`
**Active in these zones (from smallest to largest):**{% set zones = state_attr(tracker.entity_id, 'containing_zones') %}{% if zones and zones | length > 0 %}{% for zone in zones %}
- {{ zone }}{% endfor %}
{% else %}
*Not inside any custom zones at the moment.*
{% endif %}
{% if not loop.last %}---{% endif %}
{% endfor %}
{% else %}No active GeoZones tracker mirrors detected in the system entity
registry.
{% endif %}