Hi, I have a Power Monitoring System running on an ESP32 which sends data to PVoutput and also MQTT (Mosquitto Broker) for use by HomeAssistant running on a Raspberry Pi 4. This all works fine except I have an issue when for whatever reason the MQTT Broker goes down / disconnects that it won't reconnect. I have tried various things I have found online including trying to disconnect Wifi and reconnect and then attempting to reconnect to the MQTT Broker but it doesn't seem to work.
I have attached a cut down version of my program where I have removed almost all the code that is not relevant to WiFi / MQTT connection and sending. Any assistance on how to get the MQTT to reconnect when it disconnects for whatever reason would be appreciated. I send data at 5 minute intervals to MQTT/PVoutput and would like to check it at the start of this routine and attempt a reconnect if necessary and then run through my code (regardless of if MQTT is up or not). If its down then it just doesn't get sent that cycle.
Hope that all makes sense.
// Connectivity Libraries (including MQTT)
#include <WiFi.h>
#include <WiFiClient.h>
#include <ArduinoMqttClient.h>
// Set Static IP address
IPAddress local_IP(192, 168, 0, 81);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 0, 1);
const char* ssid = "MySSID";
const char* wifipass = "MyWiFiPASS";
int WiFi_LoopCnt = 0;
long startTime;
long LastMillisMQTTPoll;
//MQTT Required. Need to have a 4 topics (ie. 1 for each sensor)
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.0.11";
int mqttport = 1883;
const char topic0[] = "PowerESP32/HouseUsage";
const char topic1[] = "PowerESP32/SolarGeneration";
double MQTTHouseUse;
double MQTTGenerate;
//Needed when using VSCode. All routines / functions need to be declared except Setup and Loop
void WiFiCheck_Func();
void WiFiConnect_Func();
void DataOutput();
void setup()
{
Serial.begin(115200);
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS))
{
Serial.println("STA Failed to configure");
}
WiFiConnect_Func(); //Calling direct as no need to check if WiFi is up
}
void loop()
{
if ((millis() - LastMillisMQTTPoll) > 30000) //if MQTT hasn't been polled for 30 seconds do it
{
LastMillisMQTTPoll = millis();
if (!mqttClient.connected()) //Added this routine section as if MQTT connection is dropped it doesn't attempt to re-establish
{
WiFiConnect_Func(); //Disconnect and Reconnect WiFi. See if this resolve current issue
//The Following didn't work but read that ut appears that the WiFi Stack may need to reset in order to reattempt connect
/*
if (!mqttClient.connect(broker, mqttport))
{
Serial.print("MQTT reconnection error ");
Serial.println(mqttClient.connectError());
}
Serial.println("You're connected to the MQTT broker!");
*/
}
mqttClient.poll();
}
if ((millis() - LastMillisPVoutput) > PVoutputTimer )
{
DataOutput(); //This Routine sends data to PVOutput, HomeAssistant (MQTT)
}
}
void DataOutput()
{
LastMillisPVoutput = LastMillisPVoutput + PVoutputTimer;
WiFiCheck_Func(); //Checks WiFi and if down calls for reconnect
MQTTHouseUse = AValueThatHasBeenCalculated(CodeRemoved);
MQTTGenerate = AValueThatHasBeenCalculated(CodeRemoved);
mqttClient.beginMessage(topic0);
mqttClient.print(String(MQTTHouseUse));
mqttClient.endMessage();
//THEN HAVE CODE TO SEND DATA TO PVOUTPUT. THIS ALL FUNCTIONS FINE (INCLUDING WIFI/INTERNET DOWN). REMOVED FROM THIS EXAMPLE
}
void WiFiCheck_Func()
{
if (WiFi.status() != WL_CONNECTED)
{
WiFiConnect_Func(); //As WiFi is not connected run WiFi connect code. Will loop multiple times if fails and then restart ESP
}
}
void WiFiConnect_Func()
{
WiFi.disconnect(); //When this is called WiFi is likely already disconnected or hasn't yet been connected
delay (1000); //Added to ensure WiFi Disconnect has fully completed (As sometimes this had failed prior to adding)
WiFi.begin(ssid, wifipass); //When reconnecting could use WiFi.reconnect() instead
startTime = millis();
while (WiFi.status() != WL_CONNECTED && (millis() - startTime) <= 10000) // try for 10 seconds
{
delay(500);
}
if (WiFi.status() == WL_CONNECTED)
{
//Serial.print("\nWiFi Connected\n");
WiFi_LoopCnt = 0; //As want it reset to 0 if it got higher
} else
{
WiFi_LoopCnt ++;
Serial.print("WiFi Fail. Loop = "); Serial.println(WiFi_LoopCnt);
if (WiFi_LoopCnt > 10)
{
Serial.print("About to reboot as WiFi failed to connect more than 10 times");
ESP.restart();
}
delay(30000);
WiFiCheck_Func(); //As want to recheck connection. If this is run its likely down so therefore this routine will then get called again immediately.
}
//MQTT
mqttClient.setId("PowerESP32");
mqttClient.setUsernamePassword("MQTT", "MQTTH0me");
//Serial.print("Attempting to connect to the MQTT broker: ");
//Serial.println(broker);
if (!mqttClient.connect(broker, mqttport)) {
//Serial.print("MQTT connection failed! Error code = ");
//Serial.println(mqttClient.connectError());
while (1);
}
//Serial.println("You're connected to the MQTT broker!");
}