# HG changeset patch # User Michiel Broek # Date 1680634669 -7200 # Node ID 64028e178ff1f23c187535c51c67d0d5d625234d # Parent 2a9f67ecbc720032b7685c18895fef0c9686c53b Splitted wifi and mqtt connect states to make the connections more robust. Protect the mqtt connection request against requests when a request is already done or in progress. diff -r 2a9f67ecbc72 -r 64028e178ff1 main/iotbalkon.c --- a/main/iotbalkon.c Tue Apr 04 14:33:26 2023 +0200 +++ b/main/iotbalkon.c Tue Apr 04 20:57:49 2023 +0200 @@ -12,10 +12,12 @@ */ typedef enum { State_Init = 0, - State_Connect, + State_Connect_Wifi, + State_Connect_MQTT, State_Working, State_WorkDone, - State_Stop, + State_Disconnect_MQTT, + State_Disconnect_Wifi, State_Wait, State_Measure, State_GoSleep @@ -50,7 +52,6 @@ uint8_t loops = 0; uint8_t ST_LOOPS = 6; -bool WorkAgain = false; int DisCounter = 0; extern BMP280_State *bmp280_state; ///< I2C state @@ -215,7 +216,7 @@ if (xSemaphoreTake(xSemaphoreBMP280, 25) == pdTRUE) { temperature = bmp280_state->temperature; pressure = bmp280_state->pressure / 100.0; - ESP_LOGI(TAG, "Temperature: %.3f Pressure: %.1f hPa\n", temperature, pressure); + ESP_LOGI(TAG, "Temperature: %.2f Pressure: %.1f hPa", temperature, pressure); xSemaphoreGive(xSemaphoreBMP280); } else { ESP_LOGE(TAG, "Can't lock xSemaphoreBMP280"); @@ -272,8 +273,8 @@ m_Time[loopno] = ms - gLastTime; gLastTime = ms; - ESP_LOGI(TAG, "Measure: %d Valid: %s Solar: %.4fV %.4fmA Battery: %.4fV %.4fmA time %llu", - loopno, (m_Valid[loopno]) ? "true":"false", s_Volts[loopno], s_Current[loopno], b_Volts[loopno], b_Current[loopno], m_Time[loopno]); + ESP_LOGI(TAG, "Measure: %d Valid: %s Battery: %.3fV %.1fmA Solar: %.3fV %.1fmA time %llu", + loopno, (m_Valid[loopno]) ? "true":"false", b_Volts[loopno], b_Current[loopno], s_Volts[loopno], s_Current[loopno], m_Time[loopno]); if (loopno < (MAX_LOOPS - 1)) loopno++; @@ -441,30 +442,57 @@ case State_Init: getTempBaro(); getLightValues(); getVoltsCurrent(); - State = State_Connect; + State = State_Connect_Wifi; DisCounter = 0; request_WiFi(true); break; - case State_Connect: if (ready_WiFi() && ready_mqtt()) { - State = State_Working; + case State_Connect_Wifi: if (ready_WiFi()) { + State = State_Connect_MQTT; + /* + * Give the network stack a bit more time to setup + */ + vTaskDelay(250 / portTICK_PERIOD_MS); + request_mqtt(true); Alarm &= ~AL_NOWIFI; - ESP_LOGI(TAG, "Connected counter %d", DisCounter); + ESP_LOGI(TAG, "Connected counter WiFi %d", DisCounter); DisCounter = 0; } else { + /* + * 30 seconds connection try. + */ DisCounter++; + vTaskDelay(1000 / portTICK_PERIOD_MS); + ESP_LOGI(TAG, "* Counter WiFi %d", DisCounter); if (DisCounter > 30) { Alarm |= AL_NOWIFI; request_WiFi(false); State = State_Init; + vTaskDelay(4000 / portTICK_PERIOD_MS); } - vTaskDelay(2000 / portTICK_PERIOD_MS); } break; - case State_Working: WorkAgain = false; + case State_Connect_MQTT: if (ready_mqtt()) { + State = State_Working; + ESP_LOGI(TAG, "Connected counter MQTT %d", DisCounter); + DisCounter = 0; + } else { + DisCounter++; + if (DisCounter > 60) { + request_mqtt(false); + request_WiFi(false); + State = State_Init; + vTaskDelay(2000 / portTICK_PERIOD_MS); + } + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + break; - // Measure + case State_Working: /* + * The final measure power usage. + * This one should include the WiFi usage current. + */ getVoltsCurrent(); solarVolts = solarCurrent = solarPower = batteryVolts = batteryCurrent = batteryPower = 0; loops = 0; @@ -517,11 +545,11 @@ ESP_LOGI(TAG, "Battery Volts: %.4fV Current %.4fmA Power %.4fmW", batteryVolts, batteryCurrent, batteryPower); /* Check alarm conditions */ - if (batteryState <= 10) { - Alarm |= AL_ACCULOW; - } else { +// if (batteryState <= 10) { +// Alarm |= AL_ACCULOW; +// } else { Alarm &= ~AL_ACCULOW; - } +// } } getTempBaro(); publish(); @@ -529,36 +557,33 @@ gTimeNext = millis() + SUB_TIME; break; - case State_WorkDone: vTaskDelay(2 / portTICK_PERIOD_MS); - // Hang around for a while to process the subscriptions. - if (WorkAgain) { - // Some command was executed. - State = State_Working; - } + case State_WorkDone: vTaskDelay(20 / portTICK_PERIOD_MS); if (gTimeInMillis > gTimeNext) { - State = State_Stop; + State = State_Disconnect_MQTT; + request_mqtt(false); } break; - case State_Stop: request_WiFi(false); + case State_Disconnect_MQTT: wait_mqtt(10000); + State = State_Disconnect_Wifi; + break; + + case State_Disconnect_Wifi: request_WiFi(false); // // Reset values for average current measurement. // HaveIP = false; loopno = 0; gLastTime = millis(); - vTaskDelay(10 / portTICK_PERIOD_MS); - // #if defined(ARDUINO_ESP8266_WEMOS_D1MINI) - // WiFi.forceSleepBegin(0); // 0 == forever - // #endif + //vTaskDelay(10 / portTICK_PERIOD_MS); /* * If any output is on, use 6 10 seconds loops. * If nothing on, do a deep sleep. */ - // if (EEPROM.read(EM_Relay1) || EEPROM.read(EM_Relay2) || EEPROM.read(EM_Dimmer3) || EEPROM.read(EM_Dimmer4)) { + if (Relay1 || Relay2 || Dimmer3 || Dimmer4) { // if (EEPROM.read(EM_DS_Active)) { // EEPROM.write(EM_DS_Active, 0); // EEPROM.commit(); - // } + } // // Active mode, 60 seconds loop ST_LOOPS = 6; @@ -583,20 +608,6 @@ // } // State = State_GoSleep; // } - /* - * Update CRC and write rtcData. - */ - // rtcData.crc32 = calculateCRC32((uint8_t*) &rtcData.data, sizeof(rtcData)-4); - // #if defined(ARDUINO_ESP8266_WEMOS_D1MINI) - // if (ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData))) { - // #if Debug == true - // Serial.print("Write: "); - // printMemory(); - // #endif - // } else { - // Serial.println("Write error rtcData"); - // } - // #endif break; case State_Wait: if (gTimeInMillis > gTimeNext) { @@ -613,7 +624,7 @@ if (loopno >= ST_LOOPS) { ESP_LOGI(TAG, "Enough loops, do connect"); getLightValues(); - State = State_Connect; + State = State_Connect_Wifi; DisCounter = 0; request_WiFi(true); } else { diff -r 2a9f67ecbc72 -r 64028e178ff1 main/task_mqtt.c --- a/main/task_mqtt.c Tue Apr 04 14:33:26 2023 +0200 +++ b/main/task_mqtt.c Tue Apr 04 20:57:49 2023 +0200 @@ -47,12 +47,23 @@ extern uint8_t Dimmer4; -void connect_mqtt(bool state) +void request_mqtt(bool state) { - if (state) - xEventGroupSetBits(xEventGroupMQTT, TASK_MQTT_CONNECT); - else - xEventGroupSetBits(xEventGroupMQTT, TASK_MQTT_DISCONNECT); + if (state) { + if (xEventGroupGetBits(xEventGroupMQTT) & TASK_MQTT_CONNECTED) { + ESP_LOGW(TAG, "request_mqtt(true) but already connected"); + } else { + xEventGroupSetBits(xEventGroupMQTT, TASK_MQTT_CONNECT); + } + } else { + if (xEventGroupGetBits(xEventGroupMQTT) & TASK_MQTT_DISCONNECT) { + ESP_LOGW(TAG, "request_mqtt(false) already in progress"); + } else if (! (xEventGroupGetBits(xEventGroupMQTT) & TASK_MQTT_CONNECTED)) { + ESP_LOGW(TAG, "request_mqtt(false) but already disconnected"); + } else { + xEventGroupSetBits(xEventGroupMQTT, TASK_MQTT_DISCONNECT); + } + } } @@ -446,7 +457,7 @@ xEventGroupClearBits(xEventGroupMQTT, TASK_MQTT_CONNECT); } else if (uxBits & TASK_MQTT_DISCONNECT) { - ESP_LOGI(TAG, "Request MQTT disconnect"); + ESP_LOGI(TAG, "Request MQTT disconnect start"); /* * Unsubscribe if connected */ @@ -479,7 +490,10 @@ ESP_LOGI(TAG, "stopped"); } + xEventGroupClearBits(xEventGroupMQTT, TASK_MQTT_CONNECTED); + xEventGroupSetBits(xEventGroupMQTT, TASK_MQTT_DISCONNECTED); xEventGroupClearBits(xEventGroupMQTT, TASK_MQTT_DISCONNECT); + ESP_LOGI(TAG, "Request MQTT disconnect done"); } } } diff -r 2a9f67ecbc72 -r 64028e178ff1 main/task_mqtt.h --- a/main/task_mqtt.h Tue Apr 04 14:33:26 2023 +0200 +++ b/main/task_mqtt.h Tue Apr 04 20:57:49 2023 +0200 @@ -12,7 +12,7 @@ * @brief Request a MQTT connection * @param state Request of disconnect a connection. */ -void connect_mqtt(bool state); +void request_mqtt(bool state); /** diff -r 2a9f67ecbc72 -r 64028e178ff1 main/task_wifi.c --- a/main/task_wifi.c Tue Apr 04 14:33:26 2023 +0200 +++ b/main/task_wifi.c Tue Apr 04 20:57:49 2023 +0200 @@ -42,7 +42,7 @@ bool ready_WiFi(void) { - if (wifi_state->STA_connected && wifi_state->STA_online) + if ((xEventGroupGetBits(xEventGroupWifi) & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_HAS_IP)) == (TASK_WIFI_STA_CONNECTED | TASK_WIFI_HAS_IP)) return true; return false; } @@ -72,7 +72,6 @@ #ifdef CONFIG_CODE_TESTING ESP_ERROR_CHECK(esp_netif_set_hostname(sta_netif, "wemos")); #endif -// ESP_ERROR_CHECK(esp_wifi_connect()); break; case WIFI_EVENT_STA_CONNECTED: { @@ -93,9 +92,11 @@ } case WIFI_EVENT_STA_DISCONNECTED: { - ESP_LOGI(TAG, "Event STA disconnected"); -// wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; -// ESP_LOGI(TAG, "Event STA disconnected, reason:%d", disconnected->reason); + wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; + + ESP_LOGI(TAG, "Event STA disconnected, reason: %d", disconnected->reason); + if (disconnected->reason != 8) + request_mqtt(false); if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) { wifi_state->STA_connected = false; wifi_state->STA_online = false; @@ -103,8 +104,6 @@ } else { ESP_LOGE(TAG, "wifi_event_handler() lock error WIFI_EVENT_STA_DISCONNECTED"); } - if (ready_mqtt()) - connect_mqtt(false); xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); break; @@ -135,7 +134,6 @@ } else { ESP_LOGE(TAG, "got_ip_event_handler() lock error IP_EVENT_STA_GOT_IP"); } - connect_mqtt(true); break; case IP_EVENT_STA_LOST_IP: @@ -150,8 +148,6 @@ } else { ESP_LOGE(TAG, "got_ip_event_handler() lock error IP_EVENT_STA_LOST_IP"); } - if (ready_mqtt()) - connect_mqtt(false); break; default: @@ -215,8 +211,6 @@ * user requested a disconnect, this will in effect disconnect the wifi */ ESP_LOGI(TAG, "Request STA disconnect"); - connect_mqtt(false); - wait_mqtt(10000); ESP_ERROR_CHECK(esp_wifi_disconnect()); xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY );