Repository navigation
0.6.0
[0.6.0] - 2026-08-05
Added
MqttProfile— stored MQTT broker settings (enabled, host, port, TLS,
username, password) withcheckConfig(),saveCfg()/loadCfg()and
toJson(). It lives here rather than in a library of its own for the same
reason the NTP servers do: it is something a networked device stores in order
to reach a service, and the two are always deployed together. It knows nothing
about MQTT itself — no client, no topics, no connection — so the same profile
serves an ESP32 task, an ESP8266 loop and an AVR without a portal.
Topics are deliberately absent, being project-specific; the virtual hooks are
there for a subclass that needs them.enabledis a field of its own rather than an empty host standing in for it:
"switched off" and "not configured yet" are different facts, and a device taken
off the broker for a while should not have to forget its address to do it.MqttProfilelocks the same wayNetworkProfiledoes — astd::timed_mutex
where preemption exists (ESP32), a no-op on AVR and ESP8266 — because the
settings are copied field by field: the portal saving while a client task
reads would otherwise hand out half of each.getConfig()andsetConfig()
returnboolaccordingly.checkConfig()takes the config as a parameter, as
NetworkProfile's does, so validation runs on a staged copy and needs no lock
at all — but it is virtual rather than static, since a static one called
through a base reference silently skips a subclass's own rules.detail/prefs_tools.hwithprefs_putStr()— the empty-string storage rule
(store non-empty, remove the key otherwise) now has one implementation instead
of one per profile class.
Changed
-
Passing a subclass's config to a base-class
checkConfig(),isValidConfig()
orsetConfig()is now a compile error rather than a silent half-check. These
are static, so the compiler picks by declared type: aWiFiConfighanded to
the base version — which is what happens the moment a caller holds a
NetworkProfile&— checked the addressing, skipped the SSID, password and
TX-power rules, and reported Ok. Deleted derived-type overloads now catch it.Where it fires, either call through the concrete type
(WiFiProfile::checkConfig(cfg)), which is nearly always what was meant, or
state that only the addressing is of interest:
checkConfig(static_cast<const NetworkConfig&>(cfg)). Slicing a config into a
NetworkConfigvariable first still loses the subclass fields — by then they
are gone, and no signature can catch that.MqttProfilecarries the same
guard.Impact on the dependent libraries was one call site, inside
WiFiProfile
itself;NetworkManager,AsyncConfigPortalandAsyncWiFiPortalall already
called through the concrete type or cast explicitly.
Note
- The MQTT password is not written to
toJson(), matchingWiFiProfile: a
backup file may travels through mail and cloud storage. Restoring one
therefore needs the broker password entered again.