All notable changes to this project are documented in this file. The format is based on Keep a Changelog, and the project follows Semantic Versioning.
[0.4.0] - 2026-07-12
Added
:indirect_transmission_timeoutoption forZigbee.form_network/2andZigbee.reestablish_network/2(and thusreestablish_or_form_network/2) — the milliseconds the coordinator buffers a unicast for a sleepy end device to collect on its next poll before discarding it (0..65535, default7680, the Zigbee MAC spec'smacTransactionPersistenceTime). Raise it so buffered frames survive longer poll gaps on very sleepy devices. Volatile NCP config, re-applied on both form and reestablish; out-of-range values are clamped to the uint16 field.
[0.3.0] - 2026-07-11
Added
Zigbee.remove_device/3— unpair a paired device by instructing it to leave the network (coordinator-driven, trust-center authenticated via the EmberZNetremoveDevicecommand) and dropping it from the coordinator's tables. Backed by a newremove_device/3callback onZigbee.Adapter.- A new
:device_leftevent (payload%{node_id: _, eui64: _}), delivered to the subscriber when a device leaves the network — on its own or viaremove_device/3.
Fixed
Zigbee.EZSP.Adaptermislabelled a device departure (atrustCenterJoinHandlerwithEmberDeviceUpdate= DEVICE_LEFT) as a device-join event; it now emits a:device_leftevent.
[0.2.0] - 2026-07-10
Added
Zigbee.ZCL.write_attributes/3— manufacturer-specific writes (optional:manufacturer_code) plus octet-string (0x41) value encoding.Zigbee.EZSP.Adapter: injectable EZSP process via the:ezspoption, with integration tests driven by a fake NCP (Zigbee.FakeEZSP).- Trust-center / end-device config suite applied on both form and reestablish (TC address cache, indirect-transmission / end-device-poll / transient-key timeouts, max end-device children).
- Well-known transient link key installed on
permit_joining/2, hashed trust-center link keys, and an Aqara/Lumi manufacturer-code join workaround.
Fixed
- EZSP key-request policy ids were wrong (
TC_KEY_REQUEST0x09→0x05,APP_KEY_REQUEST0x0A→0x06) and the TC-key decision was inverted (0x50is DENY; now0x51= allow). Zigbee 3.0 devices that request keys now commission instead of rejoin-looping. incomingMessageHandlerdecode crashed on EmberZNet v13 frames that append a trailing byte after the APS payload.- Trust-center / key-request policies are now re-applied on
reestablish_network/2— they are volatile across NCP reboots. - Security bitmask corrected: removed the stray
GET_LINK_KEY_WHEN_JOININGflag (wrong on a coordinator) and switched to hashed link keys.
0.1.0 - 2026-07-07
Initial release: a from-scratch, pure-Elixir Zigbee coordinator stack for Silicon
Labs EmberZNet dongles. No NIFs and no C daemons, just circuits_uart and binary
pattern matching.
Added
Zigbeefacade: the backend-agnostic public API (start_link/2,form_network/2,reestablish_network/2,reestablish_or_form_network/2,reset_network/1,permit_joining/2,add_endpoint/6,send_aps/7,identifier/1,subscribe/2,info/1).Zigbee.Adapter: the behaviour that separates the application layer from the radio. Backends emit normalized{:zigbee, :device_joined, _}and{:zigbee, :message, %Zigbee.Message{}}events.Zigbee.EZSP.Adapter: the Silicon Labs EmberZNet backend (EZSP over ASH), including the ASH framing, the EZSP protocol client, and NCP diagnostics. Verified live against a Home Assistant Connect ZBT-2 on EmberZNet 7.5.1.0.Zigbee.ZCLandZigbee.ZDO: chip-agnostic Zigbee-spec codecs for cluster-library and device-object frames.Zigbee.Interview: the join, interview, bind, and configure-reporting flow, pluscollect/2to decode incoming reports into engineering units.Zigbee.Message: the normalized inbound APS message.Zigbee.MockAdapter: an in-memory backend for testing without hardware.- Examples:
pair_and_read.exs(a runnable end-to-end demo) andsensor_hub.exs(a supervised GenServer that owns the radio and reacts to events).
Known limitations
- The pairing flow (
Interview.run/4and report decoding) is written to the spec and tested againstZigbee.MockAdapter, but has not yet been exercised against live Zigbee end-devices. Expect to tune the incoming-message layout and per-device quirks. reestablish_network/2is implemented but not yet confirmed against real paired devices across a restart. See "Persistence & restart" in the README.- Only the Silicon Labs EmberZNet (EZSP) family is supported. TI Z-Stack and deCONZ
radios need their own
Zigbee.Adapterbackend.