//! Captive-portal provisioning and status web UI for ESP32 firmware.
//!
//! Extracted from the `nfc-522` scanner so the same setup flow can be reused
//! across devices. The crate owns the *mechanism* — SoftAP, captive DNS, the
//! config form, NVS persistence, asset serving — while each firmware supplies
//! its own config schema and status payload.
//!
//! # Shape of a consumer
//!
//! ```ignore
//! // 1. Declare the config. Fragments flatten into one flat JSON blob.
//! #[derive(Serialize, Deserialize, Clone, Default)]
//! struct Config {
//! #[serde(flatten)] wifi: WifiConfig,
//! #[serde(default)] udp_start: u16,
//! }
//! impl PortalConfig for Config {
//! fn from_form(f: &Form) -> Self {
//! Self { wifi: WifiConfig::from_form(f), udp_start: f.parsed_or("udp_start", 7777) }
//! }
//! fn wifi(&self) -> &WifiConfig { &self.wifi }
//! }
//!
//! // 2. Boot: provision when unconfigured, otherwise connect and serve status.
//! let store = ConfigStore::new(nvs);
//! let cfg: Config = store.load();
//! if !cfg.is_provisioned() {
//! provision::run::<Config, _>(modem, sysloop, store, "flex-setup-0a1b2c", Pages::default())?;
//! }
//! ```
//!
//! # Features
//!
//! * `mqtt` — adds [`MqttConfig`], a ready-made broker-settings fragment, and
//! switches the built-in portal page to the variant with the broker form.
//! Config only: it does not pull in or own an MQTT client.
//! * `rebuild-assets` — regenerate the CSS/HTML from `web/` with Tailwind at
//! build time instead of using the pre-built bytes in `assets/`. Requires
//! Node.js + npm. Off by default so consumers need no JS toolchain.
//!
//! # Host testing
//!
//! `esp-idf-svc` is a target-scoped dependency, so `cargo test` on a normal
//! host compiles and runs the pure modules ([`form`], [`dns`], [`config`],
//! [`device_id`], [`mqtt_config`]) without an ESP toolchain. Everything
//! requiring the ESP-IDF is behind `#[cfg(target_os = "espidf")]`.
// ---- Portable: builds and tests on the host. ----
pub mod assets;
pub mod config;
pub mod device_id;
pub mod dns;
pub mod form;
#[cfg(feature = "mqtt")]
pub mod mqtt_config;
// ---- ESP-IDF only. ----
#[cfg(target_os = "espidf")]
pub mod http;
#[cfg(target_os = "espidf")]
pub mod portal;
#[cfg(target_os = "espidf")]
pub mod provision;
#[cfg(target_os = "espidf")]
pub mod status;
#[cfg(target_os = "espidf")]
pub mod store;
#[cfg(target_os = "espidf")]
pub mod wifi;
// ---- Convenience re-exports. ----
pub use assets::Asset;
pub use config::{PortalConfig, WifiConfig, WifiNetwork, MAX_NETWORKS};
pub use device_id::setup_ssid;
pub use form::Form;
#[cfg(feature = "mqtt")]
pub use mqtt_config::MqttConfig;
#[cfg(target_os = "espidf")]
pub use device_id::device_id;
#[cfg(target_os = "espidf")]
pub use portal::Pages;
#[cfg(target_os = "espidf")]
pub use status::StatusServer;
#[cfg(target_os = "espidf")]
pub use store::ConfigStore;
neiam
/neiam-portal
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
2.9 KiB · text
History
65cab78