# ADR-0122: Entity Mapping Stability Policy (Identity, Filtering, and Schema)

Status: Draft

## Context

Home Assistant entity stability depends on creating a consistent set of entities
with stable unique identifiers across:
- reconnects and session changes
- IP/host changes (discovery by MAC)
- CSM-driven configuration refreshes
- library internal refactors

If entity mapping is not stabilized early, users experience:
- entity churn (entities removed/recreated)
- broken automations and dashboards
- confusing duplicates or renamed entities

The E27 integration is inventory-driven and event-driven. It must map E27
domains (areas, zones, outputs, lights, thermostats) into HA platforms using a
predictable and testable policy.

## Decision

Entity mapping for the E27 integration follows a stability-first policy:

### 1. Stable Identity and Unique IDs

- Device identity:
  - Primary: MAC address
  - Secondary: serial number (informational)

- Entity unique_id:
  - Must be deterministic and independent of:
    - IP address, host hint
    - session_id
    - discovery order
    - paging order
  - Format:
    <mac>:<domain>:<numeric_id>

Examples:
- <mac>:area:1
- <mac>:zone:31
- <mac>:output:4
- <mac>:tstat:1

### 2. Entity Creation Filters

Entities are created only for configured, meaningful objects.

- Only objects returned by configured inventory enumeration are eligible.
- Domain-specific filters apply before creating entities.
- Zones with definition "UNDEFINED" produce no entities (ADR-0119).

### 3. Mapping Tables

Each domain has a mapping table that defines:
- which HA platform is used
- device_class (where applicable)
- default enabled/disabled behavior
- attribute vs entity decisions

For zones:
- the zone "definition" field selects platform and device_class
- flags refine attributes/capabilities but do not drive existence

### 4. Naming Policy

- Prefer panel-provided names.
- If missing, use deterministic fallbacks (e.g., "Zone 31").
- Name changes do not change unique_id.
- Duplicate names are allowed; uniqueness is handled via unique_id.

### 5. Configuration Change Handling

When configuration changes are detected (via CSM or refresh):
- New configured objects may create new entities.
- Objects removed from inventory are removed as entities.
- Objects transitioning to UNDEFINED are removed (per ADR-0119).
- Attribute-only changes update existing entities without changing unique_id.

### 6. HA-Facing Snapshot Schema Contract

To reduce churn from library refactors:
- coordinator.data exposes a stable HA-facing snapshot schema containing only
  the fields needed for entity mapping and state display.
- HA entities must not depend on library internal object types.

### 7. Verification

Entity mapping stability is validated by:
- a golden inventory fixture (representative configured objects)
- a deterministic list of expected entities:
  (unique_id, platform, device_class, enabled_default)

## Rationale

Stability-first mapping:
- protects users from automation/dashboard breakage
- makes future refactors safe
- provides a clear boundary between E27 protocol evolution and HA UX

## Consequences

- Mapping tables become a maintained artifact (inventory + mapping).
- Entity churn is treated as a breaking change unless explicitly documented.
- The integration will prefer adding new attributes over creating new entities
  unless there is clear user value.

## Scope / Non-Goals

- Does not define the full mapping table content (to be expanded iteratively).
- Does not mandate how golden fixtures are implemented (tests vs tooling).
- Does not prevent users from manually disabling entities via HA registry.

## References

- ADR-0114: CSM-Based Configuration Invalidation and Selective Bootstrap
- ADR-0118: Multi-Panel Support with Single Session per Panel
- ADR-0119: Zone Definition Filtering and Entity Creation Rules
- ADR-0121: Hub + DataUpdateCoordinator Separation
