Backend for the Zone Mapper Lovelace card. Persists zone definitions and exposes per‑zone occupancy sensors based on tracked X/Y entities.
Starting with 1.1.0, this integration seeds a "Zone Mapper" view with the card on your default dashboard the first time it's set up, so you don't have to drop the card in by hand. The companion Zone Mapper card still needs to be installed separately via HACS.
- 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
- Seeds a "Zone Mapper" view with the card on the default dashboard the first time the integration is set up (storage‑mode dashboards only, opt‑out available in integration options)
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 both custom repositories 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 as type
Integration: https://github.com/ApolloAutomation/zone-mapper - Add this URL as type
Dashboard: https://github.com/ApolloAutomation/zone-mapper-card
- Go to
-
Install Zone Mapper:
- In HACS, search for
Zone Mapperand download both the integration and the card - Restart Home Assistant when prompted
- Go to
Settings→Devices and Services - Click
Add Integration - Search
Zone Mapperand add it - Open the new "Zone Mapper" view on your default dashboard, pick the device and target entities on the card, and start drawing
- In HACS, search for
- Copy contents of
custom_componentsfolder to your Home Assistant custom components directory:
/config/custom_components/zone_mapper
- (Optional) add entry to your
configuration.yamlif you want YAML-mode setup:
zone_mapper:-
Restart Home Assistant.
-
Install the companion Zone Mapper card (download
zone-mapper-card.jsto/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)
