Skip to content

Releases: automatous-io/shelly-1-gen4-matter-thread

Shelly 1 Gen4 Opener v1.0.0 - Momentary Pulse Opener with Door Contact Sensor

16 Jun 09:46

Choose a tag to compare

What's New

Warning

Garage doors and gates can cause injury or damage. Ensure your opener has working safety/auto-reverse mechanisms. This firmware triggers your existing opener; it does not replace its safety systems. Use at your own risk.

First release of the Opener firmware variant. A momentary pulse relay with door open/closed feedback, for openers that actuate on a brief contact: garage doors, gates, electric door strikes, and similar. It is built on the same module foundation and relay safety contract introduced in the Light v1.2.1 refactor.

Momentary Pulse Relay

Turning the device on energizes the relay for a fixed pulse, then the firmware automatically returns it to off. The pulse is guaranteed in firmware. It does not depend on the controller, so the relay can't be left energized by a dropped command or a crashed hub. Default pulse width is 500 ms.

The auto off routes through the same relay_set() path as every other relay action, so the documented safety invariant (pre-init safe low, thermal lockout, Thread-loss hold, panic recovery) is fully preserved.

The Shelly 1 relay is a potential-free (dry) contact. Wire it across your opener's two trigger terminals.

Door State Contact Sensor

The SW terminal (GPIO10) is a reed/limit switch input reporting door position, exposed as a Matter Contact Sensor. State changes are reported promptly to every commissioned fabric.

Note: in this variant the SW terminal is a sensor input, not a wall toggle. The Shelly 1 Gen4 has a single SW input, so the opener dedicates it to door-state feedback. Triggering is done from the controller (or the onboard button).

Wire a normally open reed/limit switch to the SW input; magnet on the moving door, sensor on the frame. Magnet adjacent (door closed) = contact closed.

Matter Device Composition

A single node with three endpoints:

  • On/Off Plug-in Unit - the opener relay (presents as a switch/outlet, not a light).
  • Contact Sensor (Boolean State) - door open/closed.
  • Root Node.

Configuration

The following are compile time constants in main/app_priv.h. The prebuilt binary uses the defaults below. Changing them requires building from source.

  • OPENER_PULSE_MS (default 500) - relay pulse width in milliseconds.
  • CONTACT_OPEN_IS_HIGH (default 0) - reed polarity. 0 suits a standard normally open reed (magnet near =
    contacts closed = door closed). Use 1 for a normally closed reed or if open/closed reads inverted.

Ecosystem Notes

  • Apple Home: the contact sensor can be recategorized to Garage Door (also Door, Window, Blinds) in accessory settings, giving native garage door status display. The relay tile acts as the momentary trigger.
  • Home Assistant: exposes a switch (trigger) + a binary_sensor (state). Combine them into a Cover template with device_class: garage for a single garage tile.
  • Expected behavior: when triggered from a controller, the relay tile briefly shows "on" then reverts. The controller is reconciling a momentary action modeled as On/Off. Triggering from the physical button updates near instantly. This is normal.

Implementation Notes

  • New modules: contact_sensor.h/cpp (replaces the wall toggle switch_input for this variant); momentary pulse handled in app_driver.cpp via a one-shot timer.
  • Reused unchanged from the shared foundation: relay, thermal, button, status_led.
  • CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT raised to 3 (root + relay + contact).
  • Product name: "Shelly 1 Gen4 MoT Opener".

Flashing Notes

This is a first release (v1.0.0); most users are flashing fresh.

  • Web flasher (ESP Connect, ESPHome web flasher, etc.): flashing the merged binary writes NVS/phy_init; commission to your ecosystems after flashing. The radio recalibrates on first boot.

Compatibility

This firmware follows semantic versioning; within the v1.x line the NVS schema is stable. Switching firmware variants, including Light → Opener always requires erase and recommission, because each variant is a different Matter device type. The Opener and Light are distinct products and should be commissioned as separate devices.

Installation

Download automatous-io-shelly-1-gen4-opener-v1.0.0.bin below and follow the flashing instructions.

Tested Scenarios

  • Fresh commission via Apple Home: working, module init sequence correct (status_led → relay → thermal → contact_sensor → button)
  • Fresh commission via Home Assistant: working
  • Multi-Admin sharing Apple Home → Home Assistant: working
  • Remove, then add directly to Home Assistant: working, pulse and contact both intact
  • Momentary pulse via Matter (Apple Home / HA): relay energizes ~500 ms then auto-reverts
  • Momentary pulse via physical button: working
  • Contact sensor reporting on both fabrics: open/closed tracked live in Apple Home and HA
  • Apple Home contact categorized as Garage Door: status displays correctly
  • Power cycle of commissioned device: returns to operational state, fabrics retrieved from storage
  • Identify command: LED state saves and restores correctly across identify cycles
  • Reed polarity: confirmed CONTACT_OPEN_IS_HIGH=0 with a normally open reed (magnet near = closed = door closed)
  • Relay safety: auto off routes through relay_set(); thermal lockout preserved
  • Thread routing role escalation (child → router): observed during testing
  • Hardware: Shelly 1 Gen4 hardware revision v0.1.2 (printed on PCB)

About This Version

v1.0.0 is the initial release of the Opener variant. It reuses the module structure and documented relay safety contract from Light v1.2.1, adding the momentary pulse relay behavior and the door contact sensor.

This build ships on the CSA test Vendor/Product ID (0xFFF1 / 0x8000), the same identity used by the esp-matter examples and the Light builds.

Shelly 1 Gen4 Light v1.2.1 — Module Refactor, Safety Contract & Earlier Init

23 May 05:10
d69f16e

Choose a tag to compare

What's New

Module Extraction Refactor

The codebase has been refactored into per-concern modules with documented public interfaces. Code previously consolidated in app_driver.cpp is now split into button, thermal, switch_input, and relay modules (alongside the existing status_led). Each module logs under its own tag for easier debugging.

This is internal organization with no user-visible behavior change. The refactor sets up the foundation for upcoming device type variants (Switch, Light Switch, and future variants) by giving each subsystem a clear boundary that variant authors can build against.

Documented Safety Contract

Relay control now flows through a single relay_set() function with a documented safety invariant in relay.h. The contract: pre-init safe-low, thermal lockout enforcement at a single point, Thread-loss intentional hold, and panic recovery.

The relay behavior itself is unchanged from v1.2.0; what's new is that the safety guarantees are now an explicit, auditable contract rather than implicit in scattered code. This protects the safety story as the codebase grows and as additional contributors work on variants.

Initialization Timing Strengthened

Subsystem initialization (relay, thermal, switch input, button) now runs in app_main() before esp_matter::start(), rather than after Matter initialization. The relay reaches its documented safe-low state ~1-2 seconds earlier in boot, and thermal protection is active before the Matter stack initializes. Shelly's PCB pulls the MOSFET gate low in the pre-init window regardless, so this is a strengthened contract rather than a fix for an observable bug.

Per-Module Log Tags

Each module now logs under its own tag (relay, thermal, switch_input, button, status_led) rather than the consolidated tags used in v1.2.0. Boot logs and runtime logs are now scannable by subsystem. Anyone parsing serial logs programmatically will see different prefixes than in v1.2.0.

Implementation Notes

  • New modules: button.h/cpp, thermal.h/cpp, switch_input.h/cpp, relay.h/cpp (alongside the existing status_led.h/cpp from v1.2.0)
  • relay.h documents the safety invariant information
  • Init order moved before esp_matter::start(); thermal protection now active before Matter stack initializes
  • Single point of relay control enforcement: all input paths (Matter command, button, switch input, thermal fault) route through relay_set()
  • Extraction was done risk-first across multiple commits, each verified on hardware: button → thermal → switch_input → relay
  • Merge-commit strategy preserves individual verified commits in main's history for clean git bisect if regressions surface later

Upgrade Notes

Important: upgrade behavior depends on flash method.

Via web flasher (ESP Connect, ESPHome web flasher, etc.):

Flashing the merged binary will erase your device's NVS and phy_init partitions. You will need to recommission your device to Home Assistant, Apple Home, and any other ecosystems after flashing. The radio also recalibrates automatically on first boot.

This is how merged binary distribution interacts with the ESP32-C6 partition layout; it's not specific to v1.2.1 and applies to all releases since v1.0.0. True upgrade-in-place for web flasher users is on the roadmap (see Issue #4).

Before flashing via web flasher, consider noting your automation references, room assignments, and entity names for quick restoration after recommissioning.

Via ESP-IDF CLI (idf.py flash):

Your commissioning data, Thread network configuration, and ecosystem integrations are preserved. No recommissioning needed.

idf.py flash

Do NOT use idf.py erase-flash flash for the upgrade, as that would erase commissioning data.

Compatibility

This firmware follows semantic versioning. Within the v1.x line, NVS schema is stable. CLI flash upgrades preserve commissioning. Major version bumps (v1.x → v2.0) may require erase and recommission. Switching between firmware variants (when variants ship in future releases) will always require erase and recommission, since each variant represents a different Matter device type.

Installation

Download automatous-io-shelly-1-gen4-light-v1.2.1.bin below and follow the flashing instructions.

Tested Scenarios

  • Fresh commission via Apple Home: working, module init sequence correct (status_led → relay → thermal → switch_input → button)
  • Fresh commission via Home Assistant: working, all functionality intact
  • Multi-Admin sharing Apple Home → Home Assistant: working
  • Power cycle of commissioned device: returns to operational state, fabrics retrieved from storage, no re-advertising
  • Relay control via Matter: working, all input paths (Matter command, button, switch input) route through relay_set()
  • Physical button toggle: working, relay state changes propagate to ecosystem
  • Wall switch input toggle: working, relay state changes propagate to ecosystem
  • Identify command: LED state saves and restores correctly across identify cycles
  • StartUpOnOff: verified across power cycles ("On" and "Previous state" honor configured behavior after reboot)
  • Thread routing role escalation (child → router): observed during testing, no functionality impact
  • Relay polarity: confirmed active-high (relay_set(true) drives GPIO5 HIGH = energized, relay_set(false) drives LOW = de-energized)
  • Upgrade in place via CLI flash: production unit (my van installed Shelly, 12V lighting) upgraded from v1.2.0 with Apple Home commissioning preserved
  • Hardware: Shelly 1 Gen4 hardware revision v0.1.2 (printed on PCB)

About This Version

v1.2.1 is a patch release (no minor version bump) because all user-visible behavior is preserved. Internally, this is the most significant refactor since v1.0.0. Module extraction, documented safety contracts, and the foundation for upcoming device type variants.

Technical Details

See PR #3 for the full code change discussion and per-commit breakdown.

OTA Updates

Status unchanged from v1.2.0. See v1.2.0 release notes for details.

Home Assistant Note

If commissioning fails after the device was previously commissioned and factory reset, restart the Matter Server add-on. See Troubleshooting in the README.

Shelly 1 Gen4 Light v1.2.0 — Identify Cluster & Multi-Admin LED Fix

14 May 18:37

Choose a tag to compare

What's New

Identify Cluster

The device now implements the Matter Identify cluster. When a controller triggers Identify, the status LED produces an asymmetric blink pattern (100ms on, 900ms off) for the duration the controller requests, then automatically returns to its previous state.

This is useful when you have multiple identical devices commissioned and need to physically locate one. Both Apple Home ("Identify Accessory" on initial commissioning) and Home Assistant (Identify button on the device page) can trigger it.

Multi-Admin LED Fix

Matter allows a single device to be commissioned into multiple controller fabrics simultaneously (e.g., Apple Home and Home Assistant at the same time). Adding the device to a second fabric is done by the first fabric opening a temporary commissioning window for the new commissioner to join through.

In v1.1.0, the LED state machine treated any commissioning window opening as "device is ready to pair" and entered the rapid BLE advertising blink, even when the device was already commissioned and operational on Thread. The LED now correctly remains solid-on during Multi-Admin commissioning windows.

The state machine was reacting to kCommissioningWindowOpened without checking whether the device was already commissioned. The fix gates the BLE_ADVERTISING transition on commissioning state.

Hardware Version Reporting

The device now reports hardware version 0 / v0.1.2, matching the silkscreen on the Shelly 1 Gen4 PCB. Previously the SDK default test value was reported. This is visible in Matter controller device details.

Implementation Notes

  • Identify pattern (100ms/900ms asymmetric) is a fifth LED state, distinct from the v1.1.0 patterns (off, rapid blink, slow blink, solid)
  • CMakeLists.txt PROJECT_VER is authoritative for software version; CHIPProjectConfig.h holds Matter cluster strings and DEFAULT_* version overrides; sdkconfig.defaults.c6_thread_shelly holds CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION=0
  • Override SDK TEST_VERSION defaults with DEFAULT_* macro variants so reported versions are traceable rather than SDK test placeholders
  • Explicit CONFIG_OPENTHREAD_FTD=y (was inherited; now pinned)
  • Code style aligned with upstream ESP-Matter

Upgrade Notes

  • Remove Shelly 1 from ecosystem
  • Flash the new binary using the same procedure as v1.0.0/v1.1.0
  • Commission using same procedure as v1.0.0/v1.1.0

Installation

Download automatous-io-shelly-1-gen4-light-v1.2.0.bin below and follow the flashing instructions.

Tested Scenarios

  • Fresh commission via Apple Home: Identify works, LED patterns correct
  • Fresh commission via Home Assistant: Identify works, LED patterns correct
  • Multi-Admin sharing Apple Home → Home Assistant: LED stays solid through commissioning window
  • Multi-Admin sharing Home Assistant → Apple Home: LED stays solid through commissioning window
  • Identify triggered from Apple Home while device shared with Home Assistant: Working
  • Identify triggered from Home Assistant while device shared with Apple Home: Working
  • Power cycle of commissioned device: LED returns to solid on within ~1 second
  • Relay control via Matter: Working from all fabrics
  • Button trigger/reset and external switch input: Working
  • Hardware version reports v0.1.2, software version reports 1.2.0
  • Hardware: Shelly 1 Gen4 hardware revision v0.1.2 (printed on PCB)

OTA Updates

Not yet supported. OTA infrastructure (image building with ota_image_tool.py, provider hosting in Home Assistant) requires a dedicated Thread Border Router for safe testing. Current SkyConnect ZBT-1 in my environment is committed to Zigbee for safety sensors and would require a firmware switch over to Thread only. Apple TBR cannot be used per HA documentation. Planned for a future release.

Home Assistant note: if commissioning fails after the device was previously commissioned and factory reset, restart the Matter Server add-on. See Troubleshooting in the README.

Shelly 1 Gen4 Light v1.1.0 — Status LED Support

11 May 02:44

Choose a tag to compare

What's New

Status LED Support

The onboard status LED now indicates device state with four distinct patterns:

  • Off — Device starting up
  • Rapid blink — BLE advertising (ready for Matter commissioning)
  • Slow blink — Attempting Thread network attachment
  • Solid on — Connected and operational

This follows Shelly's standard LED convention, so users familiar with stock Shelly firmware will find the patterns intuitive.

GPIO15 Discovery

The Shelly 1 Gen4 status LED is on GPIO15 with active-low polarity, not GPIO0 as ESPHome documentation currently states. This was determined through systematic GPIO sweep testing on real hardware.

Implementation Notes

  • LED state machine runs as a dedicated FreeRTOS task
  • State transitions driven by Matter device events (kCommissioningWindowOpened, kThreadStateChange)
  • Clean separation: status_led.cpp owns LED hardware, app_driver.cpp owns Matter-cluster-tied hardware (relay, button, switch input)

Upgrade Notes

  • Remove Shelly 1 from ecosystem
  • Flash the new binary using the same procedure as v1.0.0
  • Commission using same procedure as v1.0.0

Installation

Download automatous-io-shelly-1-gen4-light-v1.1.0.bin below and follow the flashing instructions.

Variant-Specific Tagging

Starting with this release, tags include the model, generation, and variant (shelly-1-gen4-light-vX.Y.Z) to support future variants (Switch, 2PM, Dimmer) in the same repository.

Tested Scenarios

  • Fresh commission via Apple Home: LED transitions through advertising → connecting → connected as expected
  • Fresh commission via Home Assistant: Same as above
  • Multi-fabric (Apple Home + Home Assistant simultaneously): Working
  • Power cycle of commissioned device: LED goes to solid on within ~1 second of reconnect (Thread reattachment is very fast)
  • Relay control via Matter: Working from all fabrics
  • StartUpOnOff attribute (4 values): Working
  • Factory reset via button hold: Working
  • External switch input via GPIO10: Working
  • Hardware: Shelly 1 Gen4 hardware revision v0.1.2 (printed on PCB)

v1.0.0 — Initial Release

09 May 02:39

Choose a tag to compare

Shelly 1 Gen 4 — Matter over Thread v1.0.0

The first public release of open source Matter over Thread firmware for the Shelly 1 Gen 4.

The Gen 4 ships with an ESP32-C6 that includes an 802.15.4 Thread radio, but Shelly's stock firmware only uses Matter over WiFi — the Thread radio sits unused. Shelly has publicly stated they don't plan to add Thread support. This firmware unlocks it.

Works natively with Apple Home, Google Home, Alexa, and Home Assistant. No WiFi, no cloud, no Shelly app, no subscription, no middleware required.

What's in this release

  • Matter over Thread — your Shelly joins your Thread mesh and is controlled directly via the Matter protocol
  • Multi-fabric commissioning — commission to Apple Home, Home Assistant, and Google Home simultaneously
  • Physical button toggle on the onboard relay button
  • External wall switch input on the SW terminal (hardware-debounced ISR)
  • State sync across all controllers
  • Thread Router mode — extends your Thread mesh for other devices
  • Factory reset via long-press of the onboard button
  • Fully reversible — stock firmware backup and restore is verified working

Variant

This release is the Light variant — Matter On/Off Light device type with latching relay behavior. The relay holds whatever state you set (on or off) until you change it again. The Shelly appears as a light bulb icon in your smart home app, and the relay can switch any "set and hold" load.

Best suited for lights, fans, outlets, heaters, and similar loads.

Not suitable for garage door openers, doorbells, gates, or other devices that expect a brief contact closure. A future Switch variant will add momentary relay pulse behavior for those use cases.

Variants are separate firmware builds because Matter device types are declared at compile time and cannot be changed in the smart home app after commissioning. When the Switch variant ships, users wanting that behavior will flash a different .bin and re-commission to their ecosystem.

Tested ecosystems

  • ✅ Apple HomePod mini
  • ✅ Apple HomePod (2nd gen)
  • ✅ iPhone 15 Pro+
  • ✅ Home Assistant (SkyConnect / Yellow)

Untested but expected to work

  • Apple TV 4K (3rd gen)
  • Google Nest Hub (2nd gen)
  • Amazon Echo (4th gen)

If you successfully commission to one of these, please open an issue so we can update the compatibility list.

Known limitations

  • Power-on default is off — the relay defaults to off at power-up. The Matter StartUpOnOff attribute (which would let users configure off / on / toggle / restore-last-state behavior in their smart home app) is planned for v1.1.0. Users wanting "restore last state" behavior in v1.0.0 can use a smart home automation as a workaround (e.g., in Home Assistant: "when this device comes online, turn it on").
  • Status LED (GPIO0) — onboard LED indication for BLE advertising and Thread connection states is not functional in this release. Tracked for a future release.
  • Thermal protection — the firmware reads ESP32-C6 die temperature and includes logic to cut off the relay above 75°C, but the threshold has not been validated under controlled thermal conditions. Implementation is conservative; calibration is the open question.

Installation

See the README for the full flashing procedure with photos. Quick version:

  1. Download automatous-io-shelly-1-gen4-light-v1.0.0.bin below
  2. Connect a USB-UART adapter to the Shelly's programming header
  3. Put the Shelly into flash mode (GPIO0 to GND, then power up)
  4. Flash with ESPConnect (browser-based) or esptool (CLI)
  5. Commission with your smart home app

⚠️ Always back up your stock firmware before flashing. The backup procedure is documented in the README and stock restore is verified working — your device can be returned to factory state at any time.

⚠️ Never connect AC mains to the Shelly during flashing. The programming header is not galvanically isolated from the relay circuitry. Power the Shelly only via the USB-UART 3.3V line.

Hardware

You'll need a 3.3V USB-UART adapter (CP2102 works well) and an adapter to bridge the Shelly's 1.27mm 7-pin programming header to standard 2.54mm Dupont. The README has photos of one approach.

Why open source?

The firmware is and will remain open source under Apache 2.0. Build it yourself, fork it, modify it, ship your own version. If you find a bug or want to add features, open an issue or send a pull request.

Feedback

This is V1 of a solo project, built from inside a Mercedes Sprinter van named Mabel. If something doesn't work, open an issue with serial logs, hardware revision, and ecosystem details.

If this firmware saved you a headache, a star on the repo helps it show up in search and signals to other Shelly 1 Gen 4 owners that it exists and works.


Full README: README.md
License: Apache 2.0
Source: Built on esp-matter by Espressif Systems