15#ifndef WIFI_CONFIG_PORTAL_TIMEOUT
16#define WIFI_CONFIG_PORTAL_TIMEOUT 180
27 const String& client_ssid,
28 const String& client_password,
29 const String& ap_ssid,
30 const String& ap_password)
32 bool config_loaded =
load();
35 if (ap_ssid !=
"" && ap_password !=
"") {
44 if (!config_loaded && client_ssid !=
"" && client_password !=
"") {
53 for (
int i = 0; i < num_fill; i++) {
57 ESP_LOGD(__FILENAME__,
"Enabling WiFi provisioner");
61 WiFi.setMinSecurity(WIFI_AUTH_WPA_PSK);
65 WiFi.setHostname(hostname.c_str());
69 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
75 WiFi.mode(WIFI_AP_STA);
95 this->ap_settings_.captive_portal_enabled_) {
96 dns_server_ = std::unique_ptr<DNSServer>(
new DNSServer());
98 dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
111 WiFi.disconnect(
true);
116 WiFi.setHostname(hostname.c_str());
118 ESP_LOGI(__FILENAME__,
"Starting access point %s",
126 ESP_LOGE(__FILENAME__,
"Failed to start access point.");
133 WiFi.setHostname(hostname.c_str());
136 auto reconnect_cb = [
this]() {
137 static uint32_t attempt_num = 0;
138 static uint32_t current_config_idx = 0;
139 static int last_applied_idx = -1;
143 if (WiFi.status() == WL_CONNECTED) {
145 current_config_idx = 0;
150 if (num_configs == 0) {
151 ESP_LOGW(__FILENAME__,
152 "No client settings defined. Leaving WiFi client disconnected.");
156 uint32_t prev_config_idx = current_config_idx;
161 for (current_config_idx = current_config_idx;
162 current_config_idx < prev_config_idx + num_configs;
163 current_config_idx++) {
170 ESP_LOGD(__FILENAME__,
"Current client config index: %d",
172 ESP_LOGD(__FILENAME__,
"Attempt number: %d", attempt_num);
173 ESP_LOGD(__FILENAME__,
"Config SSID: %s", config.
ssid_.c_str());
179 "No valid client settings found. Leaving WiFi client disconnected.");
183 ESP_LOGI(__FILENAME__,
184 "Connecting to wifi SSID %s (connection attempt #%d).",
185 config.
ssid_.c_str(), attempt_num);
188 ESP_LOGI(__FILENAME__,
"Using static IP address: %s",
189 config.
ip_.toString().c_str());
205 int applied_idx =
static_cast<int>(current_config_idx % num_configs);
206 if (applied_idx != last_applied_idx) {
207 WiFi.disconnect(
false);
210 last_applied_idx = applied_idx;
212 current_config_idx++;
226 JsonObject apSettingsJson = root[
"apSettings"].to<JsonObject>();
229 JsonObject clientSettingsJson = root[
"clientSettings"].to<JsonObject>();
231 JsonArray clientConfigsJson = clientSettingsJson[
"settings"].to<JsonArray>();
232 int num_serialized = 0;
237 JsonObject clientConfigJson = clientConfigsJson.add<JsonObject>();
238 config.as_json(clientConfigJson);
244 if (config[
"hostname"].is<String>()) {
246 String hostname = config[
"hostname"].as<String>();
249 if (config[
"ssid"].is<String>()) {
250 String
ssid = config[
"ssid"].as<String>();
251 String password = config[
"password"].as<String>();
253 if (config[
"ap_mode"].is<String>()) {
254 if (config[
"ap_mode"].as<String>() ==
"Access Point" ||
255 config[
"ap_mode"].as<String>() ==
"Hotspot") {
267 if (config[
"apSettings"].is<JsonVariant>()) {
272 if (config[
"clientSettings"].is<JsonVariant>()) {
273 const JsonObject& client_settings_json = config[
"clientSettings"];
276 const JsonArray& client_settings_json_array =
277 client_settings_json[
"settings"];
278 for (
const JsonObject& cfg_json : client_settings_json_array) {
295 ESP_LOGI(__FILENAME__,
"Resetting WiFi SSID settings");
298 WiFi.disconnect(
true);
301 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
306 if (WiFi.status() != WL_CONNECTED) {
307 ESP_LOGD(__FILENAME__,
308 "WiFi is not connected. Disconnecting to allow scanning.");
311 ESP_LOGI(__FILENAME__,
"Starting WiFi network scan");
312 int result = WiFi.scanNetworks(
true);
313 if (result == WIFI_SCAN_FAILED) {
314 ESP_LOGE(__FILENAME__,
"WiFi scan failed to start");
319 std::vector<WiFiNetworkInfo>& ssid_list) {
320 int num_networks = WiFi.scanComplete();
321 if (num_networks == WIFI_SCAN_RUNNING) {
322 return WIFI_SCAN_RUNNING;
324 if (num_networks == WIFI_SCAN_FAILED) {
325 return WIFI_SCAN_FAILED;
328 for (
int i = 0; i < num_networks; i++) {
329 WiFiNetworkInfo info(WiFi.SSID(i), WiFi.RSSI(i), WiFi.encryptionType(i),
330 WiFi.BSSID(i), WiFi.channel(i));
331 ssid_list.push_back(info);
Storage object for WiFi access point settings.
static AccessPointSettings from_json(const JsonObject &json)
void as_json(JsonObject &doc)
Storage object for WiFi client settings.
static ClientSSIDConfig from_json(const JsonObject &json)
virtual bool clear() override
Delete the data from a persistent storage.
virtual bool load() override
Load and populate the object from a persistent storage.
Automatic calling of the reset() method when the device needs to be reset.
static String get_hostname()
Get the current hostname.
static const std::shared_ptr< SensESPBaseApp > & get()
Get the singleton instance of the SensESPBaseApp.
WiFi network info storage class returned by scan results.
void start_access_point()
bool from_json(const JsonObject &config) override
AccessPointSettings ap_settings_
std::vector< ClientSSIDConfig > client_settings_
int16_t get_wifi_scan_results(std::vector< WiFiNetworkInfo > &ssid_list)
WiFiProvisioner(const String &config_path, const String &client_ssid="", const String &client_password="", const String &ap_ssid="", const String &ap_password="")
~WiFiProvisioner() override
bool to_json(JsonObject &doc) override
void start_client_autoconnect()
std::unique_ptr< DNSServer > dns_server_
std::shared_ptr< reactesp::EventLoop > event_loop()
constexpr int kMaxNumClientConfigs