# DDR-0038: Typed Library Event Subscription Surface for Home Assistant

Status: Accepted  
Date: 2026-01-13  
Related ADRs: ADR-0121, ADR-0123, ADR-0120

## Context

The Home Assistant integration must be able to consume semantic, typed library
events (e.g., CSM snapshot updates and configuration invalidation signals)
without parsing raw protocol payload dicts.

The existing library subscription mechanism delivered a generic wrapper event
(`Elke27Event`) containing `raw_type` and a `data` dict. This was sufficient for
debugging and generic telemetry but did not meet the HA contract:

- HA must not parse raw dict payloads for CSM keys or table info schemas.
- HA should react to typed events and stable models.

At the same time, existing code and tooling depend on the existing `subscribe()`
behavior.

## Decision

Add an additional typed event subscription surface to the library client:

- `subscribe_typed(callback)` registers a callback that receives concrete Event
  objects (instances of classes defined in `elke27_lib/events.py`).
- `unsubscribe_typed(callback)` removes a typed callback registration.
- Existing `subscribe()` / `unsubscribe()` behavior remains unchanged and
  continues to emit the wrapped `Elke27Event` (raw_type + data dict).

Typed subscribers receive the same semantic Event objects emitted by the library
event model (not kernel frames and not raw payload dicts).

## Rationale

- Preserves backward compatibility for existing internal tooling and raw event
  consumers.
- Provides a clean, stable contract for HA to consume typed events directly.
- Avoids forcing HA to understand evolving raw payload schemas or handler naming.
- Keeps protocol/payload parsing and semantic interpretation inside the library,
  consistent with ADR-0123.

## Consequences

- The library maintains two parallel subscription lists:
  - raw/wrapped event subscribers (existing)
  - typed event subscribers (new)
- Event emission code paths must dispatch both:
  - typed Event object → typed subscribers
  - wrapped Elke27Event → raw subscribers
- Tests must validate that typed subscribers receive concrete Event instances.
- HA integration must use `subscribe_typed()` for correctness and must not parse
  `Elke27Event.data` for CSM or configuration decisions.
