Repository navigation
Device setup improvments (Device identity, WiFi provisioning, MQTT autodiscovery) - #14
Merged
Merged
Conversation
Enable ESP WiFi NVS storage so provisioned station credentials are loaded by the driver. Stop starting WiFi during wifi_init(); keep radio startup in wifi_start() so the FSM controls power use. Add helpers to detect stored credentials and synchronize state when another component starts WiFi.
Enable ESP32 BLE/Bluedroid support and the larger single-app partition defaults needed for provisioning. Add the qrcode managed component and lockfile so debug builds can print provisioning QR codes. Ignore managed_components because the component manager regenerates it from the lockfile.
Add a BLE provisioning FSM state that starts when no WiFi credentials are stored. Store credentials through the standard Espressif provisioning app without running immediate WiFi validation. Replace WiFi scan requests with an empty low-power scan endpoint because scanning is not supportable on the power budget. Print the provisioning URL and emit the terminal QR code only in debug builds.
Describe the BLE provisioning flow, including manual SSID entry, disabled WiFi scans, and deferred WiFi validation. Update menuconfig setup instructions now that WiFi credentials are provisioned instead of built in. Document debug QR code output and the qrcode component dependency.
Before only a unique white flash was done before entering provisoning. Now, a 10ms/0,5Hz flash is emitted.
Poll the BOOT button from the existing FSM loop so long-press detection does not add an always-running task or extra wakeups. Enter BLE provisioning after GPIO0 is held for at least two seconds, and require release before accepting another trigger. Keep existing WiFi credentials when manual provisioning fails so stored credentials are only replaced after the provisioning app submits new ones.
Run NVS, LED, ADC, and power-management initialization once before entering the main state loop so INIT no longer participates in state LED blinking. Remove STATE_INIT from the pure FSM model and update voltage watchdog tests to reflect that WAIT_VOLTAGE is now the first runtime state. Update the firmware README diagram, state table, and test description to match the init-plus-FSM boot flow.
Keep normal QEMU runs out of the manual provisioning path by wrapping GPIO0 as released by default and by mocking wifi_has_config() instead of calling the real WiFi driver state API. Exclude the real BLE provisioning implementation from QEMU builds and provide an emulation stub so manual provisioning requests can be observed without pulling in unsupported BLE runtime behavior. Add a manual provisioning QEMU mode, build-only support in the runner, a CI job, and a log assertion that verifies the simulated BOOT long press reaches the provisioning stub without panic/assert markers.
- MQTT discovery: discover Home Assistant via _home-assistant._tcp.local, build mqtt://<ha-ip>:1883, and fall back to mqtt://homeassistant.local:1883. - MQTT topics: remove the configurable topic prefix and derive runtime topics as linkey/<mac_suffix>/state, status, and debug paths. - MQTT username: use linkey_<mac_suffix> by default when MQTT Username is left empty, while keeping an explicit Kconfig username override. - Add the espressif/mdns managed dependency and disable mDNS autodiscovery in QEMU defaults. - Update QEMU MQTT assertions, CI probes, and documentation for MAC-derived identity and topics.
Add a factory_data NVS partition and a shared factory_config_schema.h that owns the factory partition label, namespace, NVS key names, and development fallback secrets. Read MQTT password and BLE provisioning PoP from the factory partition when available, with empty Kconfig values acting only as development overrides instead of owning defaults. Keep normal firmware logs from printing provisioning credentials; QR/provisioning URL output remains debug-log only.
Add a Python factory flashing tool that reads the ESP32 MAC, generates or reuses per-device MQTT and BLE provisioning secrets, creates the factory NVS image, flashes factory_data, and prints install information for Home Assistant/provisioning. Read the factory schema from factory_config_schema.h so the Python tool does not duplicate partition, namespace, key, or fallback definitions. Keep the ESP32 in ROM bootloader after MAC read and flash factory_data before the final firmware flash, avoiding a second manual BOOT/reset cycle on boards without reliable auto-boot. Ignore generated per-device factory files and the isolated build-factory directory.
Describe the factory_data NVS partition, the per-device BLE PoP and MQTT password keys, and how tools/factory_flash.py generates, flashes, and prints the installation information. Clarify that Kconfig password and PoP values are optional development overrides, while factory_config_schema.h owns the fallback values and factory_data overrides them in production.
Configure CI Mosquitto to reject anonymous clients and require the deterministic QEMU credentials linkey_ddeeff / mqtt-password, matching the mocked MAC suffix and factory schema fallback. Authenticate CI probe, subscription capture, and debug request publishing so the smoke test fails if firmware MQTT auth regresses. Align the local Docker Mosquitto setup and emulation docs with the same credential-gated broker behavior. Add a lightweight CI validation step for factory_flash.py schema parsing so schema/header changes cannot silently break the factory tool.
Make the generated Mosquitto password file world-readable so the broker can open it after dropping privileges to its runtime user.
- Rename BLE provisioning service names from Linkey-XXXXXX to Linkey_XXXXXX in firmware and newly generated factory setup data. - Make the Home Assistant MQTT discovery device name default to Linkey_<last6mac> when no explicit menuconfig override is set. - Document the BLE and MQTT/Home Assistant naming behavior so multiple Linkey devices get distinct names.
- Add a two-sided quick start guide HTML template with Linkey branding, provisioning QR placement, and MQTT credential placeholders. - Extend factory_flash.py to generate per-device quick_start.html and quick_start.pdf next to the existing setup text file. - Resolve logo and app badge assets to local file URIs before PDF rendering so headless Chrome embeds them reliably. - Include local Google Play and App Store badge assets and add --chrome / --no-guide-pdf controls for the generator.
Konkzor
force-pushed
the
feature/setup-refactor
branch
from
September 7, 2026 20:48
9ae004e to
7d22ed6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR refactors Linkey setup around runtime provisioning and per-device identity.
It removes build-time WiFi credentials, adds BLE WiFi provisioning through the Espressif provisioning app, introduces per-device factory secrets for BLE PoP and MQTT password, and derives the default device name, MQTT username, and MQTT topics from the ESP32 WiFi MAC suffix. It also adds Home Assistant MQTT broker discovery via mDNS with a configurable fallback URI.
Main Changes
WiFi
MQTT
Factory Setup
factory_dataNVS partition for per-device secrets.tools/factory_flash.pyto generate/reuse secrets, flash factory data, and produce setup information.CI / Tests / Docs
What is needed next