From 21bbafb63df75fc64f8b3c5a7303634c253fd4c1 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Fri, 18 Oct 2019 14:46:44 +0200 Subject: [PATCH] Captive portal fixes (#766) * Enable MDNS logs comment * Work around ESP8266 mDNS broken for AP See also https://github.com/esp8266/Arduino/issues/6114 * Enable captive_portal in AP-only mode Fixes https://github.com/esphome/issues/issues/671 * Make ESP32 connecting faster See also https://github.com/espressif/arduino-esp32/pull/2989 * Format --- esphome/components/logger/__init__.py | 2 + esphome/components/wifi/wifi_component.cpp | 15 +++- .../components/wifi/wifi_component_esp32.cpp | 14 +++- esphome/core/util.cpp | 73 ++++++++++++------- esphome/core/util.h | 6 ++ 5 files changed, 77 insertions(+), 33 deletions(-) diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index f15fd44612..3e07334313 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -123,6 +123,8 @@ def to_code(config): 'TLS_MEM', 'UPDATER', 'WIFI', + # Spams logs too much: + # 'MDNS_RESPONDER', } for comp in DEBUG_COMPONENTS: cg.add_build_flag("-DDEBUG_ESP_{}".format(comp)) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 1f705e507f..0608f222f7 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -49,10 +49,16 @@ void WiFiComponent::setup() { } } else if (this->has_ap()) { this->setup_ap_config_(); +#ifdef USE_CAPTIVE_PORTAL + if (captive_portal::global_captive_portal != nullptr) + captive_portal::global_captive_portal->start(); +#endif } this->wifi_apply_hostname_(); +#ifdef ARDUINO_ARCH_ESP32 network_setup_mdns(); +#endif } void WiFiComponent::loop() { @@ -103,7 +109,8 @@ void WiFiComponent::loop() { ESP_LOGI(TAG, "Starting fallback AP!"); this->setup_ap_config_(); #ifdef USE_CAPTIVE_PORTAL - captive_portal::global_captive_portal->start(); + if (captive_portal::global_captive_portal != nullptr) + captive_portal::global_captive_portal->start(); #endif } } @@ -157,6 +164,9 @@ void WiFiComponent::setup_ap_config_() { this->ap_setup_ = this->wifi_start_ap_(this->ap_); ESP_LOGCONFIG(TAG, " IP Address: %s", this->wifi_soft_ap_ip().toString().c_str()); +#ifdef ARDUINO_ARCH_ESP8266 + network_setup_mdns(this->wifi_soft_ap_ip(), 1); +#endif if (!this->has_sta()) { this->state_ = WIFI_COMPONENT_STATE_AP; @@ -416,6 +426,9 @@ void WiFiComponent::check_connecting_finished() { ESP_LOGD(TAG, "Disabling AP..."); this->wifi_mode_({}, false); } +#ifdef ARDUINO_ARCH_ESP8266 + network_setup_mdns(this->wifi_sta_ip_(), 0); +#endif this->state_ = WIFI_COMPONENT_STATE_STA_CONNECTED; this->num_retried_ = 0; return; diff --git a/esphome/components/wifi/wifi_component_esp32.cpp b/esphome/components/wifi/wifi_component_esp32.cpp index 87298f2608..353a51040a 100644 --- a/esphome/components/wifi/wifi_component_esp32.cpp +++ b/esphome/components/wifi/wifi_component_esp32.cpp @@ -162,10 +162,16 @@ bool WiFiComponent::wifi_sta_connect_(WiFiAP ap) { conf.sta.channel = *ap.get_channel(); } - esp_err_t err = esp_wifi_disconnect(); - if (err != ESP_OK) { - ESP_LOGV(TAG, "esp_wifi_disconnect failed! %d", err); - return false; + wifi_config_t current_conf; + esp_err_t err; + esp_wifi_get_config(WIFI_IF_STA, ¤t_conf); + + if (memcmp(¤t_conf, &conf, sizeof(wifi_config_t)) != 0) { + err = esp_wifi_disconnect(); + if (err != ESP_OK) { + ESP_LOGV(TAG, "esp_wifi_disconnect failed! %d", err); + return false; + } } err = esp_wifi_set_config(WIFI_IF_STA, &conf); diff --git a/esphome/core/util.cpp b/esphome/core/util.cpp index b75a1bc26f..ea5e347c72 100644 --- a/esphome/core/util.cpp +++ b/esphome/core/util.cpp @@ -2,6 +2,7 @@ #include "esphome/core/defines.h" #include "esphome/core/application.h" #include "esphome/core/version.h" +#include "esphome/core/log.h" #ifdef USE_WIFI #include "esphome/components/wifi/wifi_component.h" @@ -38,40 +39,56 @@ bool network_is_connected() { return false; } -void network_setup_mdns() { - MDNS.begin(App.get_name().c_str()); -#ifdef USE_API - if (api::global_api_server != nullptr) { - MDNS.addService("esphomelib", "tcp", api::global_api_server->get_port()); - // DNS-SD (!=mDNS !) requires at least one TXT record for service discovery - let's add version - MDNS.addServiceTxt("esphomelib", "tcp", "version", ESPHOME_VERSION); - MDNS.addServiceTxt("esphomelib", "tcp", "address", network_get_address().c_str()); - } else { -#endif - // Publish "http" service if not using native API. - // This is just to have *some* mDNS service so that .local resolution works - MDNS.addService("http", "tcp", 80); - MDNS.addServiceTxt("http", "tcp", "version", ESPHOME_VERSION); -#ifdef USE_API - } -#endif -} -void network_tick_mdns() { #ifdef ARDUINO_ARCH_ESP8266 - MDNS.update(); +bool mdns_setup; #endif -} -std::string network_get_address() { +#ifdef ARDUINO_ARCH_ESP8266 +void network_setup_mdns(IPAddress address, int interface) { + // Latest arduino framework breaks mDNS for AP interface + // see https://github.com/esp8266/Arduino/issues/6114 + if (interface == 1) + return; + MDNS.begin(App.get_name().c_str(), address); + mdns_setup = true; +#endif +#ifdef ARDUINO_ARCH_ESP32 + void network_setup_mdns() { + MDNS.begin(App.get_name().c_str()); +#endif +#ifdef USE_API + if (api::global_api_server != nullptr) { + MDNS.addService("esphomelib", "tcp", api::global_api_server->get_port()); + // DNS-SD (!=mDNS !) requires at least one TXT record for service discovery - let's add version + MDNS.addServiceTxt("esphomelib", "tcp", "version", ESPHOME_VERSION); + MDNS.addServiceTxt("esphomelib", "tcp", "address", network_get_address().c_str()); + } else { +#endif + // Publish "http" service if not using native API. + // This is just to have *some* mDNS service so that .local resolution works + MDNS.addService("http", "tcp", 80); + MDNS.addServiceTxt("http", "tcp", "version", ESPHOME_VERSION); +#ifdef USE_API + } +#endif + } + void network_tick_mdns() { +#ifdef ARDUINO_ARCH_ESP8266 + if (mdns_setup) + MDNS.update(); +#endif + } + + std::string network_get_address() { #ifdef USE_ETHERNET - if (ethernet::global_eth_component != nullptr) - return ethernet::global_eth_component->get_use_address(); + if (ethernet::global_eth_component != nullptr) + return ethernet::global_eth_component->get_use_address(); #endif #ifdef USE_WIFI - if (wifi::global_wifi_component != nullptr) - return wifi::global_wifi_component->get_use_address(); + if (wifi::global_wifi_component != nullptr) + return wifi::global_wifi_component->get_use_address(); #endif - return ""; -} + return ""; + } } // namespace esphome diff --git a/esphome/core/util.h b/esphome/core/util.h index 649b2e1440..0e121ef382 100644 --- a/esphome/core/util.h +++ b/esphome/core/util.h @@ -1,6 +1,7 @@ #pragma once #include +#include "IPAddress.h" namespace esphome { @@ -10,7 +11,12 @@ bool network_is_connected(); std::string network_get_address(); /// Manually set up the network stack (outside of the App.setup() loop, for example in OTA safe mode) +#ifdef ARDUINO_ARCH_ESP8266 +void network_setup_mdns(IPAddress address, int interface); +#endif +#ifdef ARDUINO_ARCH_ESP32 void network_setup_mdns(); +#endif void network_tick_mdns(); } // namespace esphome