Standalone ESP32-C3 Bluetooth Mesh gateway for local Steinel control, diagnostics, firmware updates and Home Assistant integration.
Steinel devices <-> Bluetooth Mesh <-> ESP32-C3 gateway -> Home Assistant
A standalone Bluetooth Mesh gateway for Steinel installations, with a local web interface and Home Assistant integration through the standard ESPHome API. Version 2.0.0 supports multiple devices from one network.
Author and maintainer: Bartosz Supcziński — bartek@env.pl
Steinel Connect Mesh devices communicate through Bluetooth Mesh, while Home Assistant uses an IP network. The ESP32-C3 joins the existing Mesh installation, exchanges commands and status messages directly with its devices, and publishes them through ESPHome.
The gateway imports the existing network from Steinel Cloud or an app-exported JSON backup. You select devices with checkboxes in its web interface. On the next boot, supported entities are registered with ESPHome and discovered by Home Assistant. No key extraction, per-lamp YAML editing, MQTT broker or custom HA integration is required.
Cloud access is a setup operation, not a dependency of everyday control. In normal use, commands and readings travel locally over Bluetooth Mesh and Wi-Fi.

The built-in page provides setup, control, diagnostics and browser-based firmware updates.

The standard ESPHome integration exposes each selected device separately in Home Assistant. The screenshot below shows NightmatIQ Plus.

An optional frontend module combines sensor state, illuminance, operating mode and twilight threshold in one compact dialog for NightmatIQ Plus.

The native ESPHome integration provides the controls without a custom integration, MQTT broker or per-device YAML files.
The USB interface normally appears as an Espressif USB JTAG/serial device (303a:1001) and as /dev/ttyACM* on Linux.
The firmware is designed for the ESP32-C3 and ESP-IDF. Bluetooth 5 extended features are disabled because Bluetooth Mesh uses the BLE 4.2 advertising path. The configuration is intentionally sized for the limited RAM of the ESP32-C3.
| Profile / model | Exposed functions |
|---|---|
| Device operating mode | Auto / Always On / Always Off |
Generic OnOff Server 1000 |
Confirmed output, On/Off select |
Light Lightness Server 1300 |
Brightness number, 0–100% |
Light LC Server 130F |
Automatic control On/Off select, light threshold and run-time properties |
Sensor Server 1100 |
Illuminance and motion/presence, when those properties are reported |
| Scene / Scheduler | Recognized in metadata; no generic scene editor or schedule programming |
The gateway checks bound SIG models and authenticated Composition Data: element count, Company/Product IDs and imported capabilities. Missing Composition Data does not block valid replies using the imported AppKey; a confirmed mismatch blocks controls.
Groups, neighbouring groups and Master/Slave remain configured in Steinel Connect. The gateway uses the existing network configuration without changing it.
Output controls use the first eligible model (a Lightness output is preferred over a separate OnOff element). All Sensor elements are polled. Multiple independent outputs in one device are not represented as separate channels. Sensor readings remain unknown until the applicable property is received. A successfully transmitted command is not presented as a confirmed device state.
| Devices | Support path | Scope / condition |
|---|---|---|
| NightmatIQ Plus, IS 180 (Mesh variant) | SIG models | Controls and readings according to device equipment and firmware |
| L 800 SC, L 810 SC / C, L 820 SC, L 830 SC / C, L 835 SC / C, L 840 SC / C | SIG models | Controls and readings according to device equipment and firmware |
| L 40 SC / C, L 42 SC / C | SIG models | Controls and readings according to device equipment and firmware |
| L 270 digi SC, L 271 digi SC / C | SIG models | Controls and readings according to device equipment and firmware |
| RS 200 SC / C, GL 80 SC / C | SIG models | Controls and readings according to device equipment and firmware |
| Spot One SC, Spot Duo SC, Spot Way SC, Spot Garden SC, XLED home 2 SC | SIG models | Controls and readings according to device equipment and firmware |
Compatibility depends on the actual models and firmware, not the commercial name alone. The gateway checks these automatically. Sensorless C variants do not gain their own sensors through the gateway.
All entries require a valid Connect network backup, Company ID 0x0563, supported models bound to the imported AppKey, and the limits below. Older proprietary Bluetooth firmware, ordinary non-connected variants, Z-Wave/KNX/DALI-only products and client-only buttons are not covered. Mesh conversion can be irreversible and affect compatibility with older devices; consult Steinel’s Connect FAQ before updating a lamp.
See compatibility details and the 2.0.0 release description.
Every selected device has the same web card, expandable identity details and a separate HA device. Functions are discovered from authenticated replies or sensor descriptors; merely having an LC or Sensor model does not create every possible control. Writes require a recent device response. Newly discovered functions are saved and exposed through a controlled restart, because native ESPHome entities must be registered at boot. Discovery can take several polling cycles on slow or unreachable devices.
Details include the model, manufacturer, Company/Product IDs and supported Mesh models, plus firmware and hardware revisions when provided by the device. Mesh addresses and hexadecimal identifiers use lowercase letters. UUID and Composition VID are omitted from the regular web details.
The main device list contains Steinel devices. Entries without a manufacturer identifier appear separately under Unrecognized devices; devices identified as another manufacturer are excluded. After import, cloud sign-in and local backup import collapse under Change or reimport network and remain available for later configuration changes.
Requested settings appear immediately in the web interface and Home Assistant while confirmation runs in the background. Actual output and sensor readings come from device responses, not inferred values. Output readback has priority after a control change and is retried without waiting for the next regular polling cycle. NightmatIQ Plus exposes its operating mode, twilight threshold, illuminance and actual output, without brightness or motion run-time controls.
Use each device’s Available entity in automations. Output and automatic control use On/Off selects so Home Assistant receives an unknown state when their individual readings expire. The gateway rejects writes when the device is unavailable or its live composition contradicts the import.
The web diagnostics show free internal RAM and the largest free block during operation. Build reports list the firmware’s static RAM and flash usage separately.
Device details include up to eight raw Sensor properties, separated by element, with data age and truncation indicators. A disabled-by-default Sensor diagnostics text entity exposes the same bounded snapshot in HA. These readings are not written to flash.
To report another device, open its details and choose Prepare device report. Enter the model from the label, start collection and optionally mark observations such as a covered light sensor or motion. Download report stops collection and saves one JSON file for attaching to an issue. Collection lasts up to three minutes, uses read-only probes and also works for imported devices not selected in HA. The report omits keys, credentials, private names, UUIDs and network addresses. It includes Composition Data, SIG/vendor model IDs, raw replies, failures and explicit truncation/missing-event indicators. The gateway keeps one bounded RAM session; the browser holds the history, so leave the page open. If the gateway disconnects, the collected data can still be downloaded and the report marks the unconfirmed stop or failed final read.
admin with password 12345678; change it on the device page immediately after joining Wi-Fi.12345678.| Path | Purpose |
|---|---|
esphome/steinel-c3.yaml |
Main ESPHome firmware configuration |
esphome/components/steinel_mesh/ |
Bluetooth Mesh, device catalog, Steinel Cloud import and local web component |
esphome/components/steinel_mesh/mesh_protocol.h |
Portable wire-format and validation helpers |
esphome/components/steinel_mesh/steinel_nodes.cpp |
Device entities and transaction scheduler |
scripts/ |
Installation, validation, USB, OTA and release helpers |
tests/ |
Protocol, parser, transport and browser regression tests |
home-assistant/ |
Optional Home Assistant package and compact control dialog |
docs/images/ |
Public README images |
docs/DEVICE_COMPATIBILITY.md |
Supported devices and compatibility details |
docs/releases/ |
Release descriptions |
demo/ |
Local web interface demo |
The recommended first installation does not require compiling ESPHome:
steinel-mesh-esp32-c3-gateway-vX.Y.Z-factory.bin from GitHub Releases.-factory.bin file.The file is processed locally by ESPHome Web. The -factory.bin image is for a new board or USB recovery; later browser updates use the -ota.bin image.
The supplied installer creates an isolated, reproducible environment using unmodified ESPHome 2026.7.3. No patch is applied to the installed ESPHome package.
The supplied installer uses apt on Debian/Ubuntu. On macOS, use a Python 3.12–3.14 virtual environment with ESPHome 2026.7.3. The helper scripts also accept an ESPHOME environment variable pointing to its executable.
Clone or download this repository, enter its directory and install the pinned toolchain:
sudo bash scripts/01_install_esphome.sh
bash scripts/03_validate_all.sh
This runs repository checks and validates the ESPHome configuration.
bash scripts/00_self_test.sh
bash scripts/11_test_mesh.sh
esphome compile esphome/steinel-c3.yaml
bash scripts/10_prepare_release.sh
Protocol and backup-parser tests run with AddressSanitizer/UndefinedBehaviorSanitizer and synthetic data. They cover truncated packets/JSON, composition parsing, address overlap, group limits, key bindings and response correlation.
Browser tests: cd tests && npm install && npm test. The test-only jsdom dependency is not included in the firmware. They check all four languages, saved preferences, dynamic device cards, checkbox preservation and unchanged API command values.
If another ESP-IDF is exported in your shell, compile in a clean shell or use env -u IDF_PATH -u IDF_TOOLS_PATH esphome compile esphome/steinel-c3.yaml.
Connect the ESP32-C3 and use its stable /dev/serial/by-id/ path when available:
sudo bash scripts/09_upload_usb.sh /dev/serial/by-id/usb-Espressif_USB_JTAG_serial_debug_unit_*-if00
If the board has no by-id link, use the detected ACM port:
sudo bash scripts/09_upload_usb.sh /dev/ttyACM0
The same compiled image can be installed on every supported ESP32-C3 board. The first USB installation also prepares the device for subsequent browser updates, so the boot button is normally not required again.
nightmatiq-gateway-XXXXXX using password 12345678..local.The Wi-Fi configuration is stored by the device and survives firmware updates.
admin with factory password 12345678.The initial device address is optional; leave it automatic unless a specific address is required. The IV Index normally synchronizes with the network. Steinel credentials remain only in the browser form for the setup requests.
You can change the selection later in the same web panel. If devices or keys change in the Steinel app, disable Mesh, import a fresh backup and select again. Existing selections are retained by device identity where possible.
The panel supports English, Polish, German and French. English is the default; the language selector remembers your choice in this browser. Lamp names, account data and API command values are not translated.
The gateway checks the latest stable GitHub release when its page opens; CHECK FOR UPDATES repeats the check manually. If a newer version is available, DOWNLOAD AND INSTALL downloads it over HTTPS, verifies its size and SHA-256 digest, installs it and restarts the gateway. A failed update leaves the current firmware active.
Manual installation remains available under Manual firmware file. Use only the release file ending in -ota.bin; -factory.bin is intended exclusively for the first USB installation. No separate OTA password is used or shown to the user.
Factory reset removes Wi-Fi, administrator and Bluetooth Mesh settings, then restores the factory account and configuration access point without changing the installed firmware version.
From the command line, enter the administrator password when requested:
bash scripts/05_upload_ota.sh DEVICE_IP_OR_HOSTNAME
Use an OTA image through the web updater; do not upload a factory image as OTA. Wi-Fi, administrator credentials and saved Mesh configuration are retained.
Use Home Assistant 2025.7 or newer for ESPHome sub-device discovery.
Home Assistant usually discovers the gateway automatically through ESPHome. If it does not:
Each selected Mesh node appears as a separate device with its own controls and diagnostics. Gateway diagnostics include the current IP address.
Disabling Mesh or entering firmware-update mode keeps selected devices and their entities registered in Home Assistant, preserving their area assignments. Readings become unavailable when communication stops; the devices are not removed.
Home Assistant may retain registry entries for deselected devices; remove unused entries if needed.
The standard ESPHome integration provides all entities and controls. The files in home-assistant/ add the compact area tile and control dialog shown above.
steinel-nightmatiq-package.yaml to the Home Assistant packages directory.steinel-nightmatiq-popup.js to /config/www/./local/steinel-nightmatiq-popup.js?v=200 as a JavaScript module in dashboard resources.The module detects the target automatically when exactly one matching device is present. With several matching devices, set window.steinelNightmatiqEntities in the JavaScript file and the target_entities mapping in the YAML package to the chosen device’s entity IDs. Check these mappings if Home Assistant added _2 or another suffix. This optional dialog is for NightmatIQ Plus; other devices use the standard Home Assistant controls.
The module customizes the generated area tile and Home Assistant’s more-info dialog. Because that area strategy is part of the Home Assistant frontend, a future frontend release may require an update to the optional module.
The area view shows one sensor-state tile that opens the control dialog. Additional tiles for the same sensor are omitted from this view without disabling their entities or automations. Automatic target detection checks gateway identity, not just similar entity names from other integrations.
During network import, each gateway derives a Mesh address policy from the selected installation and its own hardware identity. The same firmware can therefore be configured for different ESP32-C3 boards and Steinel installations.
The MAC suffix in the device name is enabled by default, so multiple gateways receive unique hostnames and access-point names. Configure a unique administrator password on each gateway.
If the configured Wi-Fi network is unavailable for 60 seconds, the gateway starts its password-protected access point again. Connect using factory access-point password 12345678 and update the Wi-Fi configuration through the captive portal. The local page remains protected by the administrator password selected on the device.
The same Steinel NightmatIQ Plus functionality is also available as an optional integration in the AR01V3 RF/IR, ESP-RC01 & Steinel NightmatIQ Plus Gateway. Choose that project when NightmatIQ should be added to an existing multifunction AR01V3 gateway; choose this repository for a small, dedicated ESP32-C3 installation.
Copyright (C) 2026 Bartosz Supcziński.
This project is licensed under the GNU General Public License version 3 only (GPL-3.0-only). See LICENSE.
envpl.steinel_mesh_gateway.When reporting a problem, include the firmware version, ESPHome version, reset reason and relevant logs. Remove passwords, keys, authorization headers, private backups and network identifiers before sharing diagnostics.
This is an independent community project and is not an official Steinel, ESPHome, or Home Assistant product.