17#ifndef WIFI_CONFIG_PORTAL_TIMEOUT
18#define WIFI_CONFIG_PORTAL_TIMEOUT 180
29 const String& client_password,
const String& ap_ssid,
30 const String& ap_password)
38 bool config_loaded =
load();
41 if (ap_ssid !=
"" && ap_password !=
"") {
50 if (!config_loaded && client_ssid !=
"" && client_password !=
"") {
59 for (
int i = 0; i < num_fill; i++) {
63 ESP_LOGD(__FILENAME__,
"Enabling Networking");
67 WiFi.setMinSecurity(WIFI_AUTH_WPA_PSK);
71 WiFi.setHostname(hostname.c_str());
75 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
81 WiFi.mode(WIFI_AP_STA);
101 this->ap_settings_.captive_portal_enabled_) {
102 dns_server_ = std::unique_ptr<DNSServer>(
new DNSServer());
104 dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
117 WiFi.disconnect(
true);
126 WiFi.setHostname(hostname.c_str());
128 ESP_LOGI(__FILENAME__,
"Starting access point %s",
136 ESP_LOGE(__FILENAME__,
"Failed to start access point.");
146 WiFi.setHostname(hostname.c_str());
149 auto reconnect_cb = [
this]() {
150 static uint32_t attempt_num = 0;
151 static uint32_t current_config_idx = 0;
155 if (WiFi.status() == WL_CONNECTED) {
157 current_config_idx = 0;
162 if (num_configs == 0) {
163 ESP_LOGW(__FILENAME__,
164 "No client settings defined. Leaving WiFi client disconnected.");
168 uint32_t prev_config_idx = current_config_idx;
173 for (current_config_idx = current_config_idx;
174 current_config_idx < prev_config_idx + num_configs;
175 current_config_idx++) {
182 ESP_LOGD(__FILENAME__,
"Current client config index: %d",
184 ESP_LOGD(__FILENAME__,
"Attempt number: %d", attempt_num);
185 ESP_LOGD(__FILENAME__,
"Config SSID: %s", config.
ssid_.c_str());
191 "No valid client settings found. Leaving WiFi client disconnected.");
195 ESP_LOGI(__FILENAME__,
196 "Connecting to wifi SSID %s (connection attempt #%d).",
197 config.
ssid_.c_str(), attempt_num);
200 ESP_LOGI(__FILENAME__,
"Using static IP address: %s",
201 config.
ip_.toString().c_str());
207 current_config_idx++;
224 JsonObject apSettingsJson = root[
"apSettings"].to<JsonObject>();
227 JsonObject clientSettingsJson = root[
"clientSettings"].to<JsonObject>();
229 JsonArray clientConfigsJson = clientSettingsJson[
"settings"].to<JsonArray>();
230 int num_serialized = 0;
235 JsonObject clientConfigJson = clientConfigsJson.add<JsonObject>();
236 config.as_json(clientConfigJson);
242 if (config[
"hostname"].is<String>()) {
244 String hostname = config[
"hostname"].as<String>();
247 if (config[
"ssid"].is<String>()) {
248 String ssid = config[
"ssid"].as<String>();
249 String password = config[
"password"].as<String>();
251 if (config[
"ap_mode"].is<String>()) {
253 if (config[
"ap_mode"].as<String>() ==
"Access Point" ||
254 config[
"ap_mode"].as<String>() ==
"Hotspot") {
266 if (config[
"apSettings"].is<JsonVariant>()) {
271 if (config[
"clientSettings"].is<JsonVariant>()) {
272 const JsonObject& client_settings_json = config[
"clientSettings"];
275 const JsonArray& client_settings_json_array =
276 client_settings_json[
"settings"];
277 for (
const JsonObject& cfg_json : client_settings_json_array) {
294 ESP_LOGI(__FILENAME__,
"Resetting WiFi SSID settings");
297 WiFi.disconnect(
true);
300 WiFi.begin(
"0",
"0", 0,
nullptr,
false);
305 if (WiFi.status() != WL_CONNECTED) {
306 ESP_LOGD(__FILENAME__,
307 "WiFi is not connected. Disconnecting to allow scanning.");
310 ESP_LOGI(__FILENAME__,
"Starting WiFi network scan");
311 int result = WiFi.scanNetworks(
true);
312 if (result == WIFI_SCAN_FAILED) {
313 ESP_LOGE(__FILENAME__,
"WiFi scan failed to start");
318 std::vector<WiFiNetworkInfo>& ssid_list) {
319 int num_networks = WiFi.scanComplete();
320 if (num_networks == WIFI_SCAN_RUNNING) {
321 return WIFI_SCAN_RUNNING;
323 if (num_networks == WIFI_SCAN_FAILED) {
324 return WIFI_SCAN_FAILED;
327 for (
int i = 0; i < num_networks; i++) {
328 WiFiNetworkInfo info(WiFi.SSID(i), WiFi.RSSI(i), WiFi.encryptionType(i),
329 WiFi.BSSID(i), WiFi.channel(i));
330 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