Backend for the Zone Mapper Lovelace card. Persists zone definitions and exposes per‑zone occupancy sensors based on tracked X/Y entities.
Warning
This integration requires the Zone Mapper lovelace card for functionality. Install it from HACS or from the repository.
- Stores zone shapes and data as attributes on coordinate sensors (one per zone)
- Creates an occupancy binary_sensor for each zone
- Restores zones, tracked entities, and rotation after Home Assistant restarts
- Listens for and processes updates from the card via a single service
- Auto‑discovers and (re)loads platforms at startup based on existing entities
There are two ways to install this integration. Both this integration and the lovelace card must be installed
HACS is like an app store for Home Assistant. It makes installing and updating custom integrations much easier. Here's how to install using HACS:
-
Install HACS if you don't have it:
- If HACS is not installed yet, download it following the instructions on https://hacs.xyz/docs/use/download/download/
- Follow the HACS initial configuration guide at https://hacs.xyz/docs/configuration/basic
-
Add this custom repository to HACS:
- Go to
HACSin your Home Assistant sidebar - CLick on the 3 dots in the upper right corner
- Click "Custom repositories"
- Add this URL to the repository: https://github.com/ApolloAutomation/zone-mapper
- Select
Integrationfor the type - Click the
ADDbutton
- Go to
-
Install Zone Mapper:
- Go to
HACSin your Home Assistant sidebar - Search for
Zone Mapperin HACS - Click on the card when you find it
- Click the
Downloadbutton at the bottom right - Repeat for lovelace card
- Restart Home Assistant
- Go to
Devices and Services - Click
Add Integration - Search
Zone Mapper - Add
Zone Mapper
- Go to
- Copy contents of
custom_componentsfolder to your Home Assistant custom components directory:
/config/custom_components/zone_mapper
- Add entry to your
configuration.yaml:
zone_mapper:-
Restart Home Assistant.
-
Companion card: download
zone-mapper-card.jsfrom the card repo under/config/wwwand add it as a Dashboard Resource.
- Service not found: confirm the integration is installed and
zone_mapper:is present in configuration.yaml - Zones don’t persist: check the coordinate sensor attributes; they should include
shape,data, andentities, (androtation_degif set) - Presence never turns on: verify tracked X/Y sensor states are numeric and confirm the point lies within the zone
- Entities missing after restart: draw zones once to initialize entity creation; subsequent restarts should restore automatically
Per location and zone (created on first update from the card):
-
Coordinate sensor
- Entity ID:
sensor.zone_mapper_<slug(location)>_zone_<id> - Attributes:
shape,data,entities,rotation_deg - Purpose: persists zone definition and tracks entities list for presence
- Entity ID:
-
Presence binary sensor
- Name:
<location> Zone <id> Presence - Device class:
occupancy - Purpose: turns on when any tracked target lies within the zone
- Name:
Note
- The card and backend use a Y‑down coordinate system (Y increases downward)
- Presence math rotates tracked points by the stored
rotation_degso it matches the card’s rotated visuals - The
locationis normalized with Home Assistant'sslugify, so punctuation and accents are stripped (e.g.Living Room (Front)→living_room_front)
- On HA startup, the integration examines the entity registry to discover existing Zone Mapper sensors and loads platforms per location.
- Coordinate sensors restore their last attributes (zones, entities, rotation) and seed the in‑memory state to make presence work without user interaction.
Single service to create/update/clear zones and update rotation and entity lists.
Fields:
location(string, required): Friendly location name used by the card and for entity idszone_id(number, optional): Zone to update; omit for angle‑only updateshape(optional):none|rect|ellipse|polygondata(optional): Shape payload (or null to clear)rotation_deg(number, optional): −180..180, updates per‑location rotation when providedentities(list, optional): Array of{ x: <entity_id>, y: <entity_id> }pairs for presencename(string, optional): Friendly name for the zone; updates entity friendly namesdelete(boolean, optional): When true, deletes the zone and removes its entities for this zone
Shape payloads:
rect:{ x_min, x_max, y_min, y_max }(numeric; requires x_min < x_max and y_min < y_max)ellipse:{ cx, cy, rx, ry }(numeric; rx, ry > 0)polygon:{ points: [ { x, y }, ... ] }(3..32 points)
Behavior:
- Send
shape: noneordata: nullto clear a zone. - Provide only
rotation_degto update the device angle without changing any zone. - Providing
entitiesreplaces the tracked list for the location, used by all zone presence sensors there. nameupdates the friendly names of the coordinate and presence entities for the zone.delete: trueremoves the zone and its entities. Rotation and entities are location‑wide and can be updated withoutzone_id.
Examples
Clear zone 1:
service: zone_mapper.update_zone
data:
location: Office
zone_id: 1
shape: none
data: nullUpdate rotation only:
service: zone_mapper.update_zone
data:
location: Office
rotation_deg: 30Create/update a polygon:
service: zone_mapper.update_zone
data:
location: Office
zone_id: 2
shape: polygon
data:
points:
- { x: -500, y: 400 }
- { x: 300, y: 600 }
- { x: 0, y: 1200 }Rename a zone:
service: zone_mapper.update_zone
data:
location: Office
zone_id: 1
name: "Entryway"Delete a zone and its entities:
service: zone_mapper.update_zone
data:
location: Office
zone_id: 1
delete: true- Platforms:
sensor(coordinates storage) andbinary_sensor(presence) - Event bus: fires
zone_mapper_zone_updatedto notify platform entities of changes - Constants and limits are defined in
const.py(e.g.,POLYGON_MAX_POINTS = 32)
