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);
74 if (this->
ap_settings_.enabled_ && this->client_enabled_ ==
true) {
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;
142 if (WiFi.status() == WL_CONNECTED) {
144 current_config_idx = 0;
149 if (num_configs == 0) {
150 ESP_LOGW(__FILENAME__,
151 "No client settings defined. Leaving WiFi client disconnected.");
155 uint32_t prev_config_idx = current_config_idx;
160 for (current_config_idx = current_config_idx;
161 current_config_idx < prev_config_idx + num_configs;
162 current_config_idx++) {
169 ESP_LOGD(__FILENAME__,
"Current client config index: %d",
171 ESP_LOGD(__FILENAME__,
"Attempt number: %d", attempt_num);
172 ESP_LOGD(__FILENAME__,
"Config SSID: %s", config.
ssid_.c_str());
178 "No valid client settings found. Leaving WiFi client disconnected.");
182 ESP_LOGI(__FILENAME__,
183 "Connecting to wifi SSID %s (connection attempt #%d).",
184 config.
ssid_.c_str(), attempt_num);
187 ESP_LOGI(__FILENAME__,
"Using static IP address: %s",
188 config.
ip_.toString().c_str());
199 current_config_idx++;
212 JsonObject apSettingsJson = root[
"apSettings"].to<JsonObject>();
215 JsonObject clientSettingsJson = root[
"clientSettings"].to<JsonObject>();
217 JsonArray clientConfigsJson = clientSettingsJson[
"settings"].to<JsonArray>();
218 int num_serialized = 0;
223 JsonObject clientConfigJson = clientConfigsJson.add<JsonObject>();
224 config.as_json(clientConfigJson);
230 if (config[
"hostname"].is<String>()) {
232 String hostname = config[
"hostname"].as<String>();
235 if (config[
"ssid"].is<String>()) {
236 String
ssid = config[
"ssid"].as<String>();
237 String password = config[
"password"].as<String>();
239 if (config[
"ap_mode"].is<String>()) {
240 if (config[
"ap_mode"].as<String>() ==
"Access Point" ||
241 config[
"ap_mode"].as<String>() ==
"Hotspot") {
253 if (config[
"apSettings"].is<JsonVariant>()) {
258 if (config[
"clientSettings"].is<JsonVariant>()) {
259 const JsonObject& client_settings_json = config[
"clientSettings"];
262 const JsonArray& client_settings_json_array =
263 client_settings_json[
"settings"];
264 for (
const JsonObject& cfg_json : client_settings_json_array) {
281 ESP_LOGI(__FILENAME__,
"Resetting WiFi SSID settings");
284 WiFi.disconnect(
true);
287 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
292 if (WiFi.status() != WL_CONNECTED) {
293 ESP_LOGD(__FILENAME__,
294 "WiFi is not connected. Disconnecting to allow scanning.");
297 ESP_LOGI(__FILENAME__,
"Starting WiFi network scan");
298 int result = WiFi.scanNetworks(
true);
299 if (result == WIFI_SCAN_FAILED) {
300 ESP_LOGE(__FILENAME__,
"WiFi scan failed to start");
305 std::vector<WiFiNetworkInfo>& ssid_list) {
306 int num_networks = WiFi.scanComplete();
307 if (num_networks == WIFI_SCAN_RUNNING) {
308 return WIFI_SCAN_RUNNING;
310 if (num_networks == WIFI_SCAN_FAILED) {
311 return WIFI_SCAN_FAILED;
314 for (
int i = 0; i < num_networks; i++) {
315 WiFiNetworkInfo info(WiFi.SSID(i), WiFi.RSSI(i), WiFi.encryptionType(i),
316 WiFi.BSSID(i), WiFi.channel(i));
317 ssid_list.push_back(info);
Storage object for WiFi access point settings.
static AccessPointSettings from_json(const JsonObject &json)
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.
FileSystemSaveable(const String &config_path)
Resettable(int priority=0)
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