ESP32 firmware that bridges Matter smart home protocol to WLED LED controllers over WiFi. Uses a Matter Bridge architecture so each WLED device appears as an independently named light in Apple Home, Google Home, and Amazon Alexa.
Apple Home / Google Home / Alexa
|
(Matter over WiFi)
|
ESP32 bridge (Aggregator)
├── Bridged Node 1 ──(HTTP JSON API)──> WLED device 1
├── Bridged Node 2 ──(HTTP JSON API)──> WLED device 2
└── Bridged Node N ──(HTTP JSON API)──> WLED device N
|
Web config UI
- Matter-compatible — works with Apple Home, Google Home, and Alexa
- Bridge architecture — each WLED device gets its own name in smart home apps
- Stable endpoint IDs — MAC-based persistence keeps devices stable across reboots
- Up to 16 WLED lights — each exposed as an independent bridged endpoint
- Full color control — hue/saturation, CIE XY, and color temperature (mireds)
- mDNS auto-discovery — finds WLED devices on your network automatically
- Web configuration UI — captive portal for WiFi setup, device management, live updates via SSE
- WiFi-only commissioning — no Bluetooth/BLE required
- OTA updates — update firmware over the network via ArduinoOTA or web UI
- Factory reset — Matter-only reset preserves WiFi credentials
| Target | Board | Flash | Status |
|---|---|---|---|
esp32s3 (default) |
ESP32-S3-DevKitC-1 | 8MB | Tested, recommended |
esp32s3_16mb |
ESP32-S3-DevKitC-1-N16R8 | 16MB | Tested |
esp32 |
ESP32 DevKit | 8MB | Experimental |
All targets require 8MB flash minimum (the firmware is ~2MB, and 8MB allows OTA with two 3MB app partitions). Classic ESP32 builds and links successfully but is considered experimental — IRAM is at ~82% utilisation. ESP32-C3/C6 may work but have not been tested.
Visit the web installer in Chrome or Edge to flash directly from your browser via USB.
Prerequisites: PlatformIO (CLI or IDE)
git clone https://github.com/netmindz/matter_wifi_wled.git
cd matter_wifi_wled
pio run -e esp32s3 # ESP32-S3 with 8MB flash (default)
# or: pio run -e esp32 # Classic ESP32 with 8MB flash
pio run -e esp32s3 -t uploadThe first build takes several minutes as it downloads and compiles the ESP-IDF Matter SDK from source.
- Connect to the MatterWLED-Setup WiFi network
- Configure your home WiFi in the captive portal
- Open the device's IP in a browser to discover and add WLED devices
- Pair with your smart home platform using the pairing code shown in the web UI
The device uses WiFi-only on-network commissioning. After connecting to your WiFi network, it advertises via mDNS. Pair using:
- Google Home — Add device > Matter-enabled device > enter pairing code
- Apple Home — Add Accessory > scan QR code or enter manual code
- Alexa — Devices > Add Device > Other > Matter > enter pairing code
Default pairing code: 34970112332 (test credentials — change before production)
The firmware uses PlatformIO's dual framework mode (arduino + espidf). Arduino provides OTA and WiFi management. ESP-IDF provides the HTTP server (esp_http_server with SSE for live UI updates), compiles the Matter SDK (esp_matter) from source via the IDF Component Manager, and generates a proper sdkconfig with BLE disabled.
Endpoint 0 — Root Node (Basic Information)
Endpoint 1 — Aggregator (device type 0x000E, bridge container)
Endpoint 2 — Bridged Node + Extended Color Light (WLED device 1)
Endpoint 3 — Bridged Node + Extended Color Light (WLED device 2)
...
Each bridged node carries a bridged_device_basic_information cluster (0x0039) with per-endpoint node_label, product_name, and unique_id attributes. This is what allows controllers like Google Home to display each WLED device with its own name instead of a single "WLED Bridge".
Endpoint IDs are deterministic and stable across reboots. When a WLED device is first added, the Matter stack auto-assigns an endpoint ID via bridged_node::create(). The bridge saves a mapping of WLED MAC address to endpoint ID in the mtwled_epmap NVS namespace. On subsequent boots, bridged_node::resume() re-creates each endpoint at its saved ID, so Matter controllers recognise it as the same device. This prevents devices from appearing as "new" after a reboot or configuration change.
| File | Purpose |
|---|---|
src/main.cpp |
Entry point, setup/loop, ArduinoOTA |
src/matter_manager.cpp |
Matter stack: bridge topology, endpoints, attribute callbacks |
src/web_ui.cpp |
esp_http_server, REST API, SSE event stream, captive portal, WiFi management |
src/config_store.cpp |
NVS persistence for light configuration |
src/wled_discovery.cpp |
mDNS discovery of WLED devices on the network |
src/wled_output.cpp |
HTTP POST to WLED /json/state API |
| Script | Purpose |
|---|---|
setup_matter_component.py |
Pre-script: copies idf_component.yml, patches TypeTraits.h |
generate_embed_files.py |
Post-script: generates .S cert embed files, patches TypeTraits.h |
fix_nodelist.py |
Pre-script: fixes SCons NodeList flattening in dual-framework builds |
- No BLE —
CONFIG_BT_ENABLEDis not set. WiFi-only commissioning avoids the BT controller crash that occurs with precompiled Arduino framework libs. - Shared mDNS stack —
CONFIG_USE_MINIMAL_MDNSis disabled so CHIP uses the ESP-IDF mDNS service instead of its own "minimal mDNS". This allows both Matter commissioning advertising and WLED device discovery (mdns_query_ptr) to share a single mDNS stack. - C++20 downgrade — The Matter SDK's
TypeTraits.hhas broken C++23 syntax. CMakeLists.txt downgrades fromgnu++2btognu++20. - Native HTTP client — Uses ESP-IDF's
esp_http_clientinstead of Arduino'sHTTPClientto avoidssl_clientlinker errors in dual-framework mode. - esp_netif for WiFi state — After Matter starts, Arduino's
WiFi.status()reports disconnected (state 254) even when connected. All WiFi state queries useesp_netifdirectly.
Reset Matter commissioning state without losing WiFi credentials:
Via web UI: Use the factory reset button in the web interface.
Via REST API:
curl -X POST http://<device-ip>/api/matter/resetThis erases Matter fabric data (chip-config, chip-counters, chip-factory, CHIP_KVS, esp_matter_kvs, node, mtwled_epmap NVS namespaces) and restarts the device. WiFi credentials and light configuration are preserved, but endpoint IDs will be reassigned on next boot.
| Partition | Offset | Size |
|---|---|---|
| nvs | 0x9000 | 20KB |
| otadata | 0xE000 | 8KB |
| app0 (OTA 0) | 0x10000 | 3MB |
| app1 (OTA 1) | 0x310000 | 3MB |
| spiffs | 0x610000 | 256KB |
| coredump | 0x650000 | 64KB |
A 16MB variant is available in partitions/matter_wled_16MB.csv (used by the esp32s3_16mb environment) with the same app partitions plus a larger spiffs.
These are Matter test VID/PID values. They work for development and pairing with Google Home, Apple Home, and Alexa. Replace with allocated values before production.
| Parameter | Value |
|---|---|
| Vendor ID | 0xFFF1 |
| Product ID | 0x8000 |
| Passcode | 20202021 |
| Discriminator | 3840 |
Integration tests run against a live device over the network using pytest:
pip install pytest requests
BRIDGE_IP=<device-ip> pytest tests/ -vTests cover the REST API (status, config, light states), SSE event stream, WLED mDNS discovery, web UI, config persistence, and bridge-to-WLED forwarding. Run pytest tests/ --run-destructive to include tests that modify device state (factory reset, config wipe).
See AGENTS.md for full test documentation.
This project is based on the Matter over WiFi usermod for WLED-MM, extracted into a standalone bridge firmware. See research.md for detailed technical notes on the implementation.
MIT