Skip to content

Releases: szymkiewiczmathieu/ha_enocean_custom

EnOcean Custom v2.4.1 — optional which/onoff device trigger filters

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 05 Aug 18:00

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 conflicting which filter.
  • 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 Validate 4/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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 05 Aug 16:43

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 which value).
  • Matching is exact and subset-based against the existing button_pressed payload (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 Validate 4/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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 05 Aug 13:28

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_sensor and switch YAML blocks become UI devices with exactly the same unique ID as the YAML platform produced — including the historical {id}-None form when no device_class was 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, and climate blocks 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

  1. Import from the UI (entities keep running from YAML; HA logs a benign duplicate-unique-ID warning per device until step 3).
  2. Remove the imported YAML blocks.
  3. Restart Home Assistant — UI devices take over the same entity IDs.
  4. Verify your entities and dashboards.

Validation

  • 179 unit and regression tests, including unique-ID parity tests for declared/undeclared device_class and 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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 05 Aug 12:31

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 .storage persistence, 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.py converts the official EnOcean Alliance DDF repository into a deterministic, versioned data/ddf_catalog.json. No runtime network access.
  • Catalog precision fix: non-gateway Afriso Cositherm products (002D00000004, 002D00000005) transmit GP B0-00-00 and receive eleven A5-10 profiles; only gateway variants (002D0000000A, 002D0000000B) use D2-34-10. v2.1 attributed D2-34-10 to 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 a door binary sensor, 0–5 V supply as a diagnostic sensor disabled by default; reserved values 251–255 are ignored.
  • D2-34-10 stays 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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 05 Aug 10:05

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 / 1P labels 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, and 13Z, 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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 29 Jul 20:50

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)

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 29 Jul 20:07

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)

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 29 Jul 18:25

Pair a receiver straight from the UI

Settings → EnOcean Custom → Configure → Pair an actuator (guided):

  1. Scan/paste the module's Alliance QR label (or type its AA:BB:CC:DD radio ID)
  2. Pick its family — Relay (RPS, e.g. Ubiwizz) or 4BS dimmer (e.g. Eltako) — name, channel
  3. Put the module in pairing mode (Ubiwizz: 3 short PRESS) and watch the progress screen
  4. 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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 29 Jul 17:03

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

Choose a tag to compare

@szymkiewiczmathieu szymkiewiczmathieu released this 29 Jul 15:28
e3cc60b

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, switch and light devices 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.learn service firing enocean_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 preserves entity_id and automations
  • switch_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/climate senders
  • Malformed hand-edited ui_devices rows 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.