devWaves / SwitchBot-MQTT-BLE-ESP32

Allows for multiple SwitchBot bots and curtains to be controlled via MQTT sent to ESP32. ESP32 will send BLE commands to switchbots and return MQTT responses to the broker. Also supports Temperature, Motion, Contact sensors

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ESP Devices stop working after a view hours to days

thotha opened this issue · comments

Home Assistant:
Core 2024.1.6, Supervisor 2023.12.1, Operating System 11.4, Frontend 20240104.0

Arduion IDE MacOS:
Version: 2.2.1, Date: 2023-08-31T13:53:43.373Z (5 months ago), CLI Version: 0.34.0

Either Wemos D1 ESP32 MiniKit or M5Stack ESP 32 Atom Lite

Settings
your example Config-Example1 - Mesh-PrimaryESP32-Config with changed "Wifi Settings", "MQTT Settings" and "Switchbot Curtain", "Switchbot Meter", "Switchbot Contact Sensor".

The ESP32 device works for between a view hours up to a view days. On the Wemos I can see that the blue LED goes off and then all devices ar seen as "Offline" within Home Assistant. On the M5Stack I can't see any LED's as I cant firgure out which setting to use for the LED in "ESP32 LED Settings". Each time I retart (Power Toggle) the ESP Device(s) it works again for the mentioned time.

Before I did try your setup, I've used "Bluetooth proxy" form the ESPHome Project website without problems.

Any idea and suggestions how to find the problem and how to solve it?

Just wanted to write up the very same issue.

I have a setup with one mesh host and one mesh slave (though, the same occured using only the host) with the config provided on github - changed to add devices and wifi.

Both ESPs are still on the Wifi and reachable via their dedicated IP adresses but stop forwarding any MQTT messages for any switchbot devices (I am using Switchbot meters only) after either a few days or hours. Only a reset will help. RSSI values and lastwill (online) are still sent out, but no devices are recognized anymore.

I am not using HomeAssistant but Mosquitto on a Pi4.

Update: Some things got clearer now:

  • The ESP will stay online and thus, lastwill = online is persistent.
  • The connection to meters is lost gradually over time (one after the other disappears with time).
  • My rescanTime was set to 86400 (= 24 hours), which may have exceeded the allowed range of the static const int

I will now try to reduce rescanTime and roll back to a 100% stock setup and see if there are any improvements. Will also try 100% active scanning (onlyActiveScan=true).

  • Meshing seems to cause trouble: When the mesh slave dissappears/reappears on the net (e.g. due to roaming, reset, anything), the mesh host will stop sending MQTT packets.
  • I disabled mesh on my main ESP and tried it solo with a few low RSSI devices: After two hours, the host stopped sending MQTT packets. It seems as if low RSSI devices cause trouble, too.
  • Retrying with high RSSI devices only, the ESP is running without problems for >> 24 hours.

Summary: It seems as if there is insufficient error handling within the code. Either mesh slaves reconnecting to WiFi or switchbot devices dissappearing (temporarily) during passive/active scanning will cause the main loop to stop sending any MQTT messages related to switchbot devices.

As a workaround, I will implement a somewhat crude "hardware" watchdog: I will restart the ESP via a Shelly Plug S when there are no MQTT messages sent within an hour or so.

I just made it restart every 24 hours, works for me.

Patch:

@@ -335,6 +337,7 @@
 #include <Update.h>
 #include <CRC32.h>
 #include <ArduinoQueue.h>
+#include <esp_task_wdt.h>
 
@@ -4265,6 +4265,7 @@
   forceRescan = false;
   pinMode (LED_BUILTIN, OUTPUT);
   Serial.begin(115200);
+  Serial.println("ESP32 has restarted!"); // Print a message on restart
   // Connect to WiFi network
   WiFi.begin(ssid, password);
   printAString("");
@@ -4524,6 +4525,9 @@
   pScan->setMaxResults(100);
   //pScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL);
 
+  // Initialize the WDT
+  esp_task_wdt_init(7200, true); // Set for 86400 seconds (24 hours)
+  esp_task_wdt_add(NULL); // Add the current thread to WDT watch
 }
 
 void rescan(int seconds) {
@@ -4772,6 +4776,7 @@
       }
     }
   }
+  esp_task_wdt_reset();
   //printAString("END loop...");
 }