Releases: szymkiewiczmathieu/ha_enocean_custom
Release list
EnOcean Custom v2.4.1 — optional which/onoff device trigger filters
EnOcean Custom 2.4.1 — optional which/onoff filters on device triggers
Device triggers can now be refined with optional channel (which: 0/1/10) and position (onoff: 0/1) filters, using the standard Home Assistant trigger-capabilities mechanism. This makes every legacy button_pressed event trigger — including release-driven shutter controls with per-position actions — convertible to a native device trigger with byte-identical matching semantics.
Details
- Optional selectors on every rocker trigger; omitting them preserves the broad v2.4.0 matching.
- Frontend stores selector values as strings (
"0","1","10"); validation normalizes them to integers on every path, with a defensive normalization at attach time and a dedicated string-config test. - Contradictory configurations are rejected: the channel-pinned types (
Channel 1/2 button pressed) refuse a conflictingwhichfilter. - Backward compatible: a v2.4.0 trigger configuration behaves exactly the same.
Verification
- 199 unit tests (guarded for environments without Home Assistant), real HA smoke test, Ruff on the CI target list, compile + JSON gates: all green.
- CI
Validate4/4 green (HACS, tests/smoke, Hassfest 2026.7.3, dependency audit).
Full Changelog: v2.4.0...v2.4.1
EnOcean Custom v2.4.0 — native device triggers
EnOcean Custom 2.4.0 — native device triggers for rockers
The automation editor now offers clickable device triggers for every EnOcean rocker: pick the device, then the action, instead of typing the raw button_pressed event and radio ID by hand. Automations created this way reference the device, so they finally show up in the device's "Used in" section.
What you get
- Four native triggers per rocker device: Button pressed, Button released, Channel 1 button pressed, Channel 2 button pressed (labels 1-indexed for humans; channels map to the rocker's
whichvalue). - Matching is exact and subset-based against the existing
button_pressedpayload (id,pushed,which) — the legacy event and all existing automations are untouched. - A5-14-01 door/window contacts are excluded: they decode 4BS telegrams and never emit
button_pressed. - Trigger creation survives malformed registry entries: unknown devices and corrupt identifiers return no triggers instead of raising.
Notes and limits
- Existing event-based automations keep working forever; converting them to device triggers is a separate, optional migration.
- A disabled rocker entity exposes no triggers (a disabled entity emits nothing).
- Multi-touch telegrams (
which == 10) match only the generic "Button pressed" trigger.
Verification
- 193 unit tests (14 new, including end-to-end ESP3 frame → decoder → bus → trigger), real Home Assistant smoke test, Ruff check/format on the CI target list, compile + JSON gates, dependency audit: all green.
- CI
Validate4/4 green (HACS, tests/smoke, Hassfest 2026.7.3, dependency audit).
Full Changelog: v2.3.0...v2.4.0
EnOcean Custom v2.3.0 — YAML to UI import
EnOcean Custom 2.3.0 — YAML to UI import without losing entity ids
This release lets legacy YAML installations move their devices into the UI without breaking entity IDs, dashboards, or automations.
What it does
- A new options-flow entry « Importer les équipements YAML » appears when importable YAML devices are detected.
binary_sensorandswitchYAML blocks become UI devices with exactly the same unique ID as the YAML platform produced — including the historical{id}-Noneform when nodevice_classwas declared — so Home Assistant keeps every existing entity ID.- Devices already managed in the UI are skipped; malformed YAML rows are counted, never half-imported; nothing is ever imported without explicit confirmation.
- YAML
sensor,light, andclimateblocks are honestly counted as not importable and stay in YAML. - The tracking registry is in-memory only: never persisted, never logged, never exported in diagnostics, purged on unload.
Migration order
- Import from the UI (entities keep running from YAML; HA logs a benign duplicate-unique-ID warning per device until step 3).
- Remove the imported YAML blocks.
- Restart Home Assistant — UI devices take over the same entity IDs.
- Verify your entities and dashboards.
Validation
- 179 unit and regression tests, including unique-ID parity tests for declared/undeclared
device_classand channel/RPS switches - Home Assistant 2026.7.3 import and runtime smoke
- HACS validation and Hassfest
- Ruff lint/format and runtime dependency audit
Documentation: README — migration section
EnOcean Custom v2.2.0 — Passive radio inbox, local DDF catalog, A5-14-01 decoder
EnOcean Custom 2.2.0 — Passive radio inbox, local DDF catalog, A5-14-01 decoder
This release observes the radio more honestly without ever transmitting more.
Passive radio inbox
- In-memory observation per sender: UTC last-seen, packet count, last RSSI (dBm), last repeater count, and observed RORGs.
- Strictly passive: zero radio transmission added; the receive hook snapshots bounded facts on the serial thread and transfers them to the Home Assistant loop.
- Bounded by design: 64-entry LRU for unconfigured senders, no
.storagepersistence, full purge on config-entry unload. - The options-flow radio card (FR/EN) shows last-seen, signal and repeater facts when available.
- Exportable diagnostics expose only an aggregate
observed_senders_count— never sender IDs.
Local DDF catalog
scripts/import_ddf.pyconverts the official EnOcean Alliance DDF repository into a deterministic, versioneddata/ddf_catalog.json. No runtime network access.- Catalog precision fix: non-gateway Afriso Cositherm products (
002D00000004,002D00000005) transmit GPB0-00-00and receive eleven A5-10 profiles; only gateway variants (002D0000000A,002D0000000B) useD2-34-10. v2.1 attributedD2-34-10to all four. - Manufacturer registry seeded only with publicly documented IDs; unreferenced manufacturers stay honestly « non référencé ».
Decoder
A5-14-01(window/door contact + supply voltage monitor) is now decoded: contact as adoorbinary sensor, 0–5 V supply as a diagnostic sensor disabled by default; reserved values 251–255 are ignored.D2-34-10stays explicitly unsupported: no public bit-level specification exists, so no decoder is invented.
Validation
- 170 unit and regression tests
- Home Assistant 2026.7.3 import and runtime smoke
- HACS validation and Hassfest
- Ruff lint/format and runtime dependency audit
- DDF catalog verified against an independent re-parse of the source XML
Full design notes and compatibility matrix: Device Intelligence documentation
EnOcean Custom v2.1.0 — Device Intelligence
EnOcean Custom 2.1.0 — Device Intelligence
This release adds local, evidence-based device identification without pretending that a radio sender ID is a commercial product reference.
Highlights
- Extracts exact RORG/FUNC/TYPE and manufacturer ID from UTE and enriched 4BS teach-in telegrams.
- Parses EnOcean Alliance
30S/1Plabels with strict 32-bit EURID and Product ID validation. - Adds explicit evidence and compatibility levels: exact, assisted, manual, profile unknown; supported, manual, unsupported, unknown.
- Adds a strict manual EEP field that cannot overwrite radio- or product-declared evidence.
- Groups UI and legacy YAML entities in the Home Assistant Device Registry by radio sender.
- Resolves manufacturer/model only from an exact local Product ID catalogue match.
- Adds French and English radio identity cards and a documented EEP-to-platform implementation matrix.
Radio safety and privacy
- Automatic background UTE acknowledgement is disabled. Unsolicited UTE telegrams are observed for identity evidence but never answered on the radio.
- QR security containers
10Z,11Z, and13Z, raw QR payloads, sender IDs, Product IDs, and radio metadata are excluded from exportable diagnostics. - Device intelligence is fully local and requires no runtime network service.
Initial implementation matrix
Implemented profiles include F6-02-01/02, F6-10-00, D5-00-01, A5-10-06, A5-12-01, A5-20-04, A5-38-08, D2-01-0B, and D2-01-12. Configuration mode and receive/transmit limitations are shown separately in the UI and documentation.
Validation
- 159 unit and regression tests
- Home Assistant 2026.7.3 import and runtime smoke
- HACS validation and Hassfest
- Ruff formatting/lint and runtime dependency audit
Honest limitations
- A sender ID alone never identifies a manufacturer or model.
- Passive F6/D5 devices can legitimately remain profile-unknown.
- Existing YAML entities are grouped but are not assigned retroactive identity claims.
- A catalogued product can still be unsupported when no exact decoder exists.
Full design, privacy model, sources, and compatibility matrix: Device Intelligence documentation
v2.0.1 — brand images
Ships the official EnOcean brand images in brand/ (HA 2026.3+ mechanism). No functional change over v2.0.0.
v2.0.0 — Apache-2.0 rebase (properly licensed)
Now actually open source
The integration is rebuilt on the official Home Assistant Core EnOcean component (Apache-2.0, © Open Home Foundation) and ships with its own LICENSE (Apache-2.0) and NOTICE. Everything from v1.2.4 to v1.5.0 is ported; the parts that used to come from the unlicensed upstream fork are re-implemented from scratch — RPS rocker simulation, sender_id support, extra sensors, and a fully rewritten climate platform.
Same repo, same HACS custom-repository install path — now with a real license, so default-catalog submission is unblocked.
Everything carried over
- Serial lifecycle with no zombie threads, transactional RET_OK state, bounded I/O
- Teach-in from the UI (binary sensors, D2 emitters)
- D2-01-12 bidirectional feedback (channel-filtered, sender-verified)
- QR commissioning code parsing (strict)
- Guided actuator pairing wizard (relay & dimmer)
- UI device management with registry-safe delete
New / fixed in v2.0.0
- Climate: rewritten; transactional commits; correct A5-20-04 wake-up quantization (26 min no longer becomes 3 h); strict YAML validation (no booleans, no NaN/inf)
- Powersensor devices expose an additional energy entity
- Light: byte-exact dimmer payloads (brightness 254 = 100 %)
- UI: climate device selector only offers types it can persist (A5-20-04 stays YAML-only)
82 tests, HA 2026.7.3 smoke harness, hassfest and HACS validation all green.
v1.5.0 — Guided actuator pairing (bye DolphinView)
Pair a receiver straight from the UI
Settings → EnOcean Custom → Configure → Pair an actuator (guided):
- Scan/paste the module's Alliance QR label (or type its
AA:BB:CC:DDradio ID) - Pick its family — Relay (RPS, e.g. Ubiwizz) or 4BS dimmer (e.g. Eltako) — name, channel
- Put the module in pairing mode (Ubiwizz: 3 short PRESS) and watch the progress screen
- Relays confirm automatically when the module's first D2-01 status arrives on the configured channel; 4BS dimmers report an honest “verify physically” (A5-38-08 has no radio confirmation)
Timeout? Choose retry, keep the device, or delete it (YAML-managed IDs stay protected). Abandoning the flow cancels its background task cleanly.
Adversarial-review hardened
Every finding reproduced with executable HA harnesses, then fixed and re-tested: wrong-channel false success, dongle-rejected teach-ins reported as sent, unbounded service calls, success after concurrent deletion. 60+ unittests, HA 2026.7.3 smoke, Ruff, CI 4/4.
v1.4.0 — Bidirectional actuator feedback + QR + full UI
Actuators now talk back
D2-01-12 actuators (e.g. Ubiwizz UBID1507C) report their real state, and the integration listens: physical wall-switch toggles on directly-paired modules now sync switch/light entities (channel-filtered), exposed as d2_channel / d2_output_value / power-failure attributes. Validated in production on a live module.
Also in this release
- QR commissioning: paste an EnOcean Alliance product label (or
AA:BB:CC:DD) in Configure → Add via QR code - climate & sensor in the UI: full options-flow management, YAML field/bounds/unique_id parity — YAML can now be emptied entirely
enocean_custom.send_teach_in: teach Eltako 4BS dimmers (A5-38-08) without DolphinView- Delete protection: UI deletion refuses IDs still managed by YAML (including send-only YAML lights)
Review discipline
Two adversarial review rounds with executable repros: 5 findings reproduced and fixed (light channel arbitration, QR smuggling, yaml_managed bypass, forwarding rollback residue, bare-env CI guards). 60+ unittests, HA 2026.7.3 smoke, Ruff, CI 4/4.
v1.3.0 — UI teach-in
Manage EnOcean devices entirely from the UI
No more configuration.yaml editing for devices: Settings → EnOcean → Configure → Add a device, press the physical button, fill the short form, done. The entity is created immediately and survives restarts.
What is new
- Options flow to add/remove
binary_sensor,switchandlightdevices from the UI; UI devices coexist with existing YAML ones - Teach-in learn window (60 s, configurable 15-300) captures the first unknown EnOcean sender; also available as the
enocean_custom.learnservice firingenocean_custom_device_learned - Manage screen deletes a UI device (options + exact entity registry row); its EnOcean ID becomes teachable again immediately
unique_ids reuse the exact YAML formulas, so a later YAML→UI migration preservesentity_idand automationsswitch_type(default/RPS, RPS channels 0/1) selectable in the form- French translation
Hardening (two adversarial review rounds)
- Device forms use only websocket-serializable selectors
- Learn windows are serialized and owned; captures are timestamped
- Known IDs are re-seeded on every window and now include YAML
sensor/climatesenders - Malformed hand-edited
ui_devicesrows are skipped instead of crashing setup - Dongle is unloaded if platform forwarding fails (no zombie serial reader)
Gates
51 unittests + HA 2026.7.3 smoke, Ruff, compileall, EN/FR translation parity, CI 4/4 green. Deployed on production and validated with a live hardware teach-in (capture, entity creation, press/release decoding).
climate and sensor devices remain YAML-only in this release.