Skip to content

Commit

Permalink
fix(wifi): do not trust platform auto reconnect routines
Browse files Browse the repository at this point in the history
  • Loading branch information
tspopp committed Aug 19, 2024
1 parent bf873b6 commit 2ed0d29
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 26 deletions.
12 changes: 6 additions & 6 deletions AquaMQTT/include/config/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ constexpr EOperationMode OPERATION_MODE = EOperationMode::MITM;
*/
constexpr bool OVERRIDE_TIME_AND_DATE_IN_MITM = true;


/**
* Choose to publish raw messages represented as hex-string on debug mqtt topics
*/
Expand All @@ -53,19 +52,20 @@ constexpr bool DEBUG_RAW_SERIAL_MESSAGES = false;
/**
* Change the time interval where all known attributes are re-published to the MQTT broker.
*/
constexpr uint32_t MQTT_FULL_UPDATE_MS = 1000*60*30;
constexpr uint32_t MQTT_FULL_UPDATE_MS = 1000 * 60 * 30;

/**
* Change the fixed time interval where the attributes published to the stats topic are updated.
*/
constexpr uint16_t MQTT_STATS_UPDATE_MS = 5000;
constexpr uint16_t MQTT_STATS_UPDATE_MS = 5000;

/**
* Self explanatory internal settings: most probably you don't want to change them.
*/
constexpr uint8_t WATCHDOG_TIMEOUT_S = 60;
constexpr uint8_t MQTT_MAX_TOPIC_SIZE = 80;
constexpr uint8_t MQTT_MAX_PAYLOAD_SIZE = 255;
constexpr uint8_t WATCHDOG_TIMEOUT_S = 60;
constexpr uint16_t WIFI_RECONNECT_CYCLE_S = 10;
constexpr uint8_t MQTT_MAX_TOPIC_SIZE = 80;
constexpr uint8_t MQTT_MAX_PAYLOAD_SIZE = 255;

/**
* Pin assignments for AquaMQTT Board Rev 1.0
Expand Down
32 changes: 32 additions & 0 deletions AquaMQTT/include/handler/Wifi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef AQUAMQTT_WIFI_H
#define AQUAMQTT_WIFI_H

#include <WiFi.h>

namespace aquamqtt
{
class WifiHandler
{
public:
WifiHandler();

virtual ~WifiHandler() = default;

void setup();

void loop();

private:
static void wifiCallback(WiFiEvent_t event);

unsigned long mLastCheck;

static bool mConnectedToWifiWithValidIpAddress;

};

} // namespace aquamqtt



#endif // AQUAMQTT_WIFI_H
71 changes: 71 additions & 0 deletions AquaMQTT/src/handler/Wifi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "handler/Wifi.h"

#include "config/Configuration.h"

namespace aquamqtt
{

bool WifiHandler::mConnectedToWifiWithValidIpAddress = false;

WifiHandler::WifiHandler() : mLastCheck(0)
{
}

void WifiHandler::setup()
{
WiFiClass::mode(WIFI_STA);

// we don't trust the auto reconnect routine, as it seems there are edge cases where it does not work
WiFi.setAutoReconnect(false);

// we trust the wifi callbacks to determine if we are properly connected or disconnected
WiFi.onEvent(wifiCallback);

// begin a single wifi session
WiFi.begin(aquamqtt::config::ssid, aquamqtt::config::psk);

// perform the next wifi check in config::WIFI_RECONNECT_CYCLE_S
mLastCheck = millis();
}

void WifiHandler::loop()
{
if ((millis() - mLastCheck) >= (config::WIFI_RECONNECT_CYCLE_S * 1000))
{
mLastCheck = millis();

// we don't trust WiFi.isConnected() or WiFi.status() == WL_CONNECTED, since it is suspected to be unreliable
if (!mConnectedToWifiWithValidIpAddress)
{
Serial.println("[wifi] attempting reconnect");
WiFi.disconnect();
WiFi.reconnect();
}
}
}

void WifiHandler::wifiCallback(WiFiEvent_t event)
{
Serial.print("[wifi] event: ");
Serial.println(WiFi.eventName(event));

switch (event)
{
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
// if we lost connection or ip address, we wil enforce a reconnect within the next cycle
mConnectedToWifiWithValidIpAddress = false;
break;
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
// if we got connection and therefore a valid ip address we have a valid connection
Serial.print("[wifi] ip address: ");
Serial.println(WiFi.localIP().toString().c_str());
mConnectedToWifiWithValidIpAddress = true;
break;
default:
break;
}
}

} // namespace aquamqtt
28 changes: 8 additions & 20 deletions AquaMQTT/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <Arduino.h>
#include <WiFi.h>
#include <esp_task_wdt.h>

#include "config/Configuration.h"
#include "handler/OTA.h"
#include "handler/RTC.h"
#include "handler/Wifi.h"
#include "task/ControllerTask.h"
#include "task/HMITask.h"
#include "task/ListenerTask.h"
Expand All @@ -19,28 +19,18 @@ ListenerTask listenerTask;
MQTTTask mqttTask;
OTAHandler otaHandler;
RTCHandler rtcHandler;
WifiHandler wifiHandler;


void wifiCallback(WiFiEvent_t event)
{
switch (event)
{
case WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_CONNECTED:
Serial.println(F("ARDUINO_EVENT_WIFI_STA_CONNECTED"));
break;
case WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println(F("ARDUINO_EVENT_WIFI_STA_DISCONNECTED"));
WiFi.setAutoReconnect(true);
break;
default:
break;
}
}

void loop()
{
// watchdog
esp_task_wdt_reset();

// handle wifi events
wifiHandler.loop();

// handle over-the-air module in main thread
otaHandler.loop();

Expand All @@ -58,10 +48,8 @@ void setup()
esp_task_wdt_init(WATCHDOG_TIMEOUT_S, true);
esp_task_wdt_add(nullptr);

// connect to Wi-Fi
WiFiClass::mode(WIFI_STA);
WiFi.onEvent(wifiCallback);
WiFi.begin(aquamqtt::config::ssid, aquamqtt::config::psk);
// setup wifi
wifiHandler.setup();

// setup rtc module
rtcHandler.setup();
Expand Down

0 comments on commit 2ed0d29

Please sign in to comment.