16#ifndef WIFI_CONFIG_PORTAL_TIMEOUT
17#define WIFI_CONFIG_PORTAL_TIMEOUT 180
28 const String& client_password,
const String& ap_ssid,
29 const String& ap_password)
37 bool config_loaded =
load();
40 if (ap_ssid !=
"" && ap_password !=
"") {
49 if (!config_loaded && client_ssid !=
"" && client_password !=
"") {
58 for (
int i = 0; i < num_fill; i++) {
62 ESP_LOGD(__FILENAME__,
"Enabling Networking");
66 WiFi.setMinSecurity(WIFI_AUTH_WPA_PSK);
70 WiFi.setHostname(hostname.c_str());
74 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
80 WiFi.mode(WIFI_AP_STA);
100 this->ap_settings_.captive_portal_enabled_) {
101 dns_server_ = std::unique_ptr<DNSServer>(
new DNSServer());
103 dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
116 WiFi.disconnect(
true);
125 WiFi.setHostname(hostname.c_str());
127 ESP_LOGI(__FILENAME__,
"Starting access point %s",
135 ESP_LOGE(__FILENAME__,
"Failed to start access point.");
145 WiFi.setHostname(hostname.c_str());
148 auto reconnect_cb = [
this]() {
149 static uint32_t attempt_num = 0;
150 static uint32_t current_config_idx = 0;
154 if (WiFi.status() == WL_CONNECTED) {
156 current_config_idx = 0;
161 if (num_configs == 0) {
162 ESP_LOGW(__FILENAME__,
163 "No client settings defined. Leaving WiFi client disconnected.");
167 uint32_t prev_config_idx = current_config_idx;
172 for (current_config_idx = current_config_idx;
173 current_config_idx < prev_config_idx + num_configs;
174 current_config_idx++) {
181 ESP_LOGD(__FILENAME__,
"Current client config index: %d",
183 ESP_LOGD(__FILENAME__,
"Attempt number: %d", attempt_num);
184 ESP_LOGD(__FILENAME__,
"Config SSID: %s", config.
ssid_.c_str());
190 "No valid client settings found. Leaving WiFi client disconnected.");
194 ESP_LOGI(__FILENAME__,
195 "Connecting to wifi SSID %s (connection attempt #%d).",
196 config.
ssid_.c_str(), attempt_num);
199 ESP_LOGI(__FILENAME__,
"Using static IP address: %s",
200 config.
ip_.toString().c_str());
206 current_config_idx++;
223 JsonObject apSettingsJson = root[
"apSettings"].to<JsonObject>();
226 JsonObject clientSettingsJson = root[
"clientSettings"].to<JsonObject>();
228 JsonArray clientConfigsJson = clientSettingsJson[
"settings"].to<JsonArray>();
229 int num_serialized = 0;
234 JsonObject clientConfigJson = clientConfigsJson.add<JsonObject>();
235 config.as_json(clientConfigJson);
241 if (config[
"hostname"].is<String>()) {
243 String hostname = config[
"hostname"].as<String>();
246 if (config[
"ssid"].is<String>()) {
247 String ssid = config[
"ssid"].as<String>();
248 String password = config[
"password"].as<String>();
250 if (config[
"ap_mode"].is<String>()) {
252 if (config[
"ap_mode"].as<String>() ==
"Access Point" ||
253 config[
"ap_mode"].as<String>() ==
"Hotspot") {
265 if (config[
"apSettings"].is<JsonVariant>()) {
270 if (config[
"clientSettings"].is<JsonVariant>()) {
271 const JsonObject& client_settings_json = config[
"clientSettings"];
274 const JsonArray& client_settings_json_array =
275 client_settings_json[
"settings"];
276 for (
const JsonObject& cfg_json : client_settings_json_array) {
293 ESP_LOGI(__FILENAME__,
"Resetting WiFi SSID settings");
296 WiFi.disconnect(
true);
299 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
304 if (WiFi.status() != WL_CONNECTED) {
305 ESP_LOGD(__FILENAME__,
306 "WiFi is not connected. Disconnecting to allow scanning.");
309 ESP_LOGI(__FILENAME__,
"Starting WiFi network scan");
310 int result = WiFi.scanNetworks(
true);
311 if (result == WIFI_SCAN_FAILED) {
312 ESP_LOGE(__FILENAME__,
"WiFi scan failed to start");
317 std::vector<WiFiNetworkInfo>& ssid_list) {
318 int num_networks = WiFi.scanComplete();
319 if (num_networks == WIFI_SCAN_RUNNING) {
320 return WIFI_SCAN_RUNNING;
322 if (num_networks == WIFI_SCAN_FAILED) {
323 return WIFI_SCAN_FAILED;
326 for (
int i = 0; i < num_networks; i++) {
327 WiFiNetworkInfo info(WiFi.SSID(i), WiFi.RSSI(i), WiFi.encryptionType(i),
328 WiFi.BSSID(i), WiFi.channel(i));
329 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.
virtual void reset() override
std::unique_ptr< DNSServer > dns_server_
void start_client_autoconnect()
Start WiFi using preset SSID and password.
virtual bool from_json(const JsonObject &config) override
void start_access_point()
Start an access point.
int16_t get_wifi_scan_results(std::vector< WiFiNetworkInfo > &ssid_list)
Networking(const String &config_path, const String &client_ssid="", const String &client_password="", const String &ap_ssid="", const String &ap_password="")
virtual bool to_json(JsonObject &doc) override
Serialize the current configuration to a JSON document.
std::shared_ptr< LambdaConsumer< WiFiState > > wifi_state_emitter_
std::vector< ClientSSIDConfig > client_settings_
AccessPointSettings ap_settings_
std::shared_ptr< WiFiStateProducer > wifi_state_producer_
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.
void emit(const WiFiState &new_value)
WiFi Network Information storage class.
std::shared_ptr< reactesp::EventLoop > event_loop()
constexpr int kMaxNumClientConfigs