64 lines
4.0 KiB
Markdown
64 lines
4.0 KiB
Markdown
# Architecture
|
|
|
|
## Core Layers
|
|
|
|
- `ha_deconz_bridge.color`: shared color model and conversions
|
|
- `ha_deconz_bridge.lights`: typed light definitions and validation
|
|
- `ha_deconz_bridge.solver_model`: compiled light-model and exclusivity combinations
|
|
- `ha_deconz_bridge.solver_numeric`: shared numeric color-solve helpers
|
|
- `ha_deconz_bridge.solver`: solve orchestration and deterministic elimination policy
|
|
- `ha_deconz_bridge.translate`: controller and virtual-light translation helpers
|
|
|
|
## Runtime Layers
|
|
|
|
- `ha_deconz_bridge.backends.base`: backend protocol
|
|
- `ha_deconz_bridge.backends.deconz`: deCONZ HTTP and websocket normalization
|
|
- `ha_deconz_bridge.automation`: remote specs, gesture detection, and automation rule matching
|
|
- `ha_deconz_bridge.controller`: one physical controller runtime
|
|
- `ha_deconz_bridge.group_light`: exposed groups that translate commands into member light commands
|
|
- `ha_deconz_bridge.groups`: group specs, member restrictions, and capability derivation
|
|
- `ha_deconz_bridge.light`: one virtual Home Assistant light
|
|
- `ha_deconz_bridge.ha`: MQTT discovery, commands, and state publishing
|
|
- `ha_deconz_bridge.queueing`: HA command coalescing and event prioritization
|
|
- `ha_deconz_bridge.app`: service wiring
|
|
|
|
## Debug Layer
|
|
|
|
- `ha_deconz_bridge.debugger.mpl_debugger` is an offline simulator.
|
|
- It uses the same `Color`, solver, and translation code as runtime.
|
|
- It does not have a separate solver branch.
|
|
|
|
## Solver Shape
|
|
|
|
- Each exposed virtual light or debugger selection is compiled once into a light model.
|
|
- Only exclusivity groups create solver branches; independent control paths may be active together.
|
|
- `solve_light()` treats all emitters uniformly in one shared color space.
|
|
- Semantic labels like `rgb` and `color_temp` are used only during policy stages, not in the mixing math itself.
|
|
|
|
## Event Flow
|
|
|
|
1. Home Assistant command arrives over MQTT.
|
|
2. The command is normalized into a typed HA event.
|
|
3. The event queue coalesces pending commands for the same virtual light. Sensor events run first, HA commands run before pending light readback events, and deCONZ light readbacks are deduplicated by controller.
|
|
4. Individual `VirtualLight` entities merge the command with their last stable state and ask the solver for controller targets.
|
|
5. Group entities translate the group command into member `VirtualLight` commands. A group member may have a fixed RGB or CT restriction that applies only when that group is controlled.
|
|
6. Each `PhysicalController` writes the solver's physical command to deCONZ. HA-driven writes trust a successful HTTP response and keep the accepted logical report state while near-term stale readbacks arrive.
|
|
7. `VirtualLight` and group entities aggregate accepted-or-physical output state and publish it back to Home Assistant.
|
|
8. Unsolicited deCONZ events update hardware truth directly when they are not near-term stale readbacks from a just-written command.
|
|
|
|
## Remote Event Flow
|
|
|
|
1. deCONZ sends a websocket sensor event for a configured remote.
|
|
2. The raw `buttonevent` is normalized into a button and gesture.
|
|
3. Double-press detection is tracked per physical sensor ID.
|
|
4. Automation rules match the remote's internal `remote_id`, button, gesture, and optional time condition.
|
|
5. Actions execute through the same virtual-light command path as Home Assistant.
|
|
|
|
## Shared Controllers
|
|
|
|
- Runtime owns exactly one `PhysicalController` object per physical deCONZ controller ID.
|
|
- Individual virtual lights reference those shared controller objects. Configured groups reference individual virtual lights, not controllers directly.
|
|
- `ha_deconz_bridge.app` maintains a controller-to-virtual-lights index.
|
|
- A deCONZ event updates the shared controller once, then every virtual light that includes that controller recomputes and republishes state. Groups containing any changed member recompute after those member updates.
|
|
- This allows overlapping exposed entities, such as one individual light and one room/group light, to stay consistent after external physical changes.
|