WIP: ESP8266 work on connection issues (#648)

* Erase all flash for USB uploads on ESP8266s

Previously, only erased "write regions".

Downside: Config for other FWs like tasmota could be affected

Upside: Potentially fixes some ESP8266 connection issues

Related: https://github.com/esphome/issues/issues/455#issuecomment-503524479

* Clear WiFi settings for ESP8266

Clears wifi settings from retained storage on ESP8266 (if set).

Unsure if this is the actual issue, but it won't cause problems either.

* Update wifi_component_esp8266.cpp

* Revert erase chip for testing

* Improve wait_time calculation
This commit is contained in:
Otto Winter 2019-07-02 13:03:11 +02:00 committed by GitHub
parent d2938e82db
commit 13522c8f19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 44 deletions

View file

@ -452,7 +452,7 @@ def run_logs(config, address):
_LOGGER.info("Successfully connected to %s", address)
return
wait_time = min(2**tries, 300)
wait_time = int(min(1.5**min(tries, 100), 30))
if not has_connects:
_LOGGER.warning(u"Initial connection failed. The ESP might not be connected "
u"to WiFi yet (%s). Re-Trying in %s seconds",

View file

@ -31,22 +31,15 @@ float WiFiComponent::get_setup_priority() const { return setup_priority::WIFI; }
void WiFiComponent::setup() {
ESP_LOGCONFIG(TAG, "Setting up WiFi...");
this->last_connected_ = millis();
this->wifi_register_callbacks_();
bool ret = this->wifi_mode_(this->has_sta(), false);
if (!ret) {
this->mark_failed();
return;
}
this->wifi_pre_setup_();
if (this->has_sta()) {
this->wifi_disable_auto_connect_();
delay(10);
this->wifi_sta_pre_setup_();
this->wifi_apply_power_save_();
if (!this->wifi_apply_power_save_()) {
ESP_LOGV(TAG, "Setting Power Save Option failed!");
}
if (this->fast_connect_) {
this->selected_ap_ = this->sta_[0];

View file

@ -181,17 +181,18 @@ class WiFiComponent : public Component {
void print_connect_params_();
bool wifi_mode_(optional<bool> sta, optional<bool> ap);
bool wifi_disable_auto_connect_();
bool wifi_sta_pre_setup_();
bool wifi_apply_power_save_();
bool wifi_sta_ip_config_(optional<ManualIP> manual_ip);
IPAddress wifi_sta_ip_();
bool wifi_apply_hostname_();
bool wifi_sta_connect_(WiFiAP ap);
void wifi_register_callbacks_();
void wifi_pre_setup_();
wl_status_t wifi_sta_status_();
bool wifi_scan_start_();
bool wifi_ap_ip_config_(optional<ManualIP> manual_ip);
bool wifi_start_ap_(const WiFiAP &ap);
bool wifi_disconnect_();
bool is_captive_portal_active_();

View file

@ -53,8 +53,12 @@ bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
return ret;
}
bool WiFiComponent::wifi_disable_auto_connect_() {
bool WiFiComponent::wifi_sta_pre_setup_() {
if (!this->wifi_mode_(true, {}))
return false;
WiFi.setAutoReconnect(false);
delay(10);
return true;
}
bool WiFiComponent::wifi_apply_power_save_() {
@ -382,10 +386,12 @@ void WiFiComponent::wifi_event_callback_(system_event_id_t event, system_event_i
this->wifi_scan_done_callback_();
}
}
void WiFiComponent::wifi_register_callbacks_() {
void WiFiComponent::wifi_pre_setup_() {
auto f = std::bind(&WiFiComponent::wifi_event_callback_, this, std::placeholders::_1, std::placeholders::_2);
WiFi.onEvent(f);
WiFi.persistent(false);
// Make sure WiFi is in clean state before anything starts
this->wifi_mode_(false, false);
}
wl_status_t WiFiComponent::wifi_sta_status_() { return WiFi.status(); }
bool WiFiComponent::wifi_scan_start_() {
@ -522,6 +528,7 @@ IPAddress WiFiComponent::wifi_soft_ap_ip() {
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return IPAddress(ip.ip.addr);
}
bool WiFiComponent::wifi_disconnect_() { return esp_wifi_disconnect(); }
} // namespace wifi
} // namespace esphome

View file

@ -58,19 +58,6 @@ bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
return ret;
}
bool WiFiComponent::wifi_disable_auto_connect_() {
bool ret1, ret2;
ETS_UART_INTR_DISABLE();
ret1 = wifi_station_set_auto_connect(0);
ret2 = wifi_station_set_reconnect_policy(false);
ETS_UART_INTR_ENABLE();
if (!ret1 || !ret2) {
ESP_LOGV(TAG, "Disabling Auto-Connect failed!");
}
return ret1 && ret2;
}
bool WiFiComponent::wifi_apply_power_save_() {
sleep_type_t power_save;
switch (this->power_save_) {
@ -158,9 +145,7 @@ bool WiFiComponent::wifi_sta_connect_(WiFiAP ap) {
if (!this->wifi_mode_(true, {}))
return false;
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
this->wifi_disconnect_();
struct station_config conf {};
memset(&conf, 0, sizeof(conf));
@ -330,11 +315,6 @@ const char *get_disconnect_reason_str(uint8_t reason) {
}
void WiFiComponent::wifi_event_callback(System_Event_t *event) {
// TODO: this callback is called while in cont context, so delay will fail
// We need to defer the log messages until we're out of this context
// only affects verbose log level
// reproducible by enabling verbose log level and letting the ESP disconnect and
// then reconnect to WiFi.
switch (event->event) {
case EVENT_STAMODE_CONNECTED: {
auto it = event->event_info.connected;
@ -410,7 +390,62 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
WiFiMockClass::_event_callback(event);
}
void WiFiComponent::wifi_register_callbacks_() { wifi_set_event_handler_cb(&WiFiComponent::wifi_event_callback); }
bool WiFiComponent::wifi_sta_pre_setup_() {
if (!this->wifi_mode_(true, {}))
return false;
// Clear saved STA config
station_config default_config{};
wifi_station_get_config_default(&default_config);
bool is_zero = default_config.ssid[0] == '\0' && default_config.password[0] == '\0' && default_config.bssid[0] == 0 &&
default_config.bssid_set == 0;
if (!is_zero) {
ESP_LOGV(TAG, "Clearing default wifi STA config");
memset(&default_config, 0, sizeof(default_config));
ETS_UART_INTR_DISABLE();
bool ret = wifi_station_set_config(&default_config);
ETS_UART_INTR_ENABLE();
if (!ret) {
ESP_LOGW(TAG, "Clearing default wif STA config failed!");
}
}
bool ret1, ret2;
ETS_UART_INTR_DISABLE();
ret1 = wifi_station_set_auto_connect(0);
ret2 = wifi_station_set_reconnect_policy(false);
ETS_UART_INTR_ENABLE();
if (!ret1 || !ret2) {
ESP_LOGV(TAG, "Disabling Auto-Connect failed!");
}
delay(10);
return true;
}
void WiFiComponent::wifi_pre_setup_() {
wifi_set_event_handler_cb(&WiFiComponent::wifi_event_callback);
// Make sure the default opmode is OFF
uint8_t default_opmode = wifi_get_opmode_default();
if (default_opmode != 0) {
ESP_LOGV(TAG, "Setting default WiFi Mode to 0 (was %u)", default_opmode);
ETS_UART_INTR_DISABLE();
bool ret = wifi_set_opmode(0);
ETS_UART_INTR_ENABLE();
if (!ret) {
ESP_LOGW(TAG, "Setting default WiFi mode failed!");
}
}
// Make sure WiFi is in clean state before anything starts
this->wifi_mode_(false, false);
}
wl_status_t WiFiComponent::wifi_sta_status_() {
station_status_t status = wifi_station_get_connect_status();
switch (status) {
@ -435,11 +470,6 @@ bool WiFiComponent::wifi_scan_start_() {
if (!this->wifi_mode_(true, {}))
return false;
station_status_t sta_status = wifi_station_get_connect_status();
if (sta_status != STATION_GOT_IP && sta_status != STATION_IDLE) {
wifi_station_disconnect();
}
struct scan_config config {};
memset(&config, 0, sizeof(config));
config.ssid = nullptr;
@ -465,6 +495,15 @@ bool WiFiComponent::wifi_scan_start_() {
return ret;
}
bool WiFiComponent::wifi_disconnect_() {
station_config conf{};
memset(&conf, 0, sizeof(conf));
ETS_UART_INTR_DISABLE();
wifi_station_set_config(&conf);
bool ret = wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
return ret;
}
void WiFiComponent::s_wifi_scan_done_callback(void *arg, STATUS status) {
global_wifi_component->wifi_scan_done_callback_(arg, status);
}