Arduino sketches with MQTT PubSubClient stop working

I have 3 ESP devices on which I have arduino sketches which uses MQTT PubSubClient library.
All my devices stop worked yesterday.
Those are light switches/dimmers and temperature sensors that uses Home Assistant MQTT broker. Seems like yesterday was some update for HomeAssistant MQTT broker add on which might be related with my problem, but I don't know exactly what is going on.

I already started discussion on Home Assistant forum about this:

What I was able to noticed is that according to traces from my ESP device, it mannages to connect on MQTT broker. I also confirm the same from broker side. It detects IP adresses of the client devices.
However, exchanging of messages doesn't work.
Just to emphasize, devices worked flawlessly for almost half a year and yesterday all have same problem.
I try to reinstall MQTT broker in home assistant etc, remove/add integration, but it doesn't helped.

Does any one uses PubSubClient library with latest Mosquitto broker 6.0.1 add on in HA maybe?

Here are some parts from sketch related with MQTT:


#include "WiFi.h"
#include "PubSubClient.h"

#define LIGHT_PIN 32

// Number of MQTT retiries 
const int RETRIES = 100;

// PWM settings
const int FREQUENCY = 10000;
const int LED_CHANNEL = 0;
const int RESOLUTION = 8;

// WiFi and MQTT configuration variables
const char* WIFI_SSID = "";
const char* WIFI_PASSWORD = "";
const char* MQTT_SERVER = "x.x.x.x";
const int   MQTT_PORT = 1883;
const char* MQTT_USERNAME = "my_mqtt_user";
const char* MQTT_PASSWORD = "my_mqtt_pass";
const char* MQTT_CLIENT_NAME = "/light/bedroom/desk/"; 

// WiFi Static IP example
IPAddress staticIP(x,x,x,x);
IPAddress gateway(x,x,x,x);
IPAddress subnet(x.x.x.x);
IPAddress dns1(x,x,x,x);
IPAddress dns2(x,x,x,x);

// WiFi and MQTT clients
WiFiClient wifiClient;
PubSubClient mqtt_client(wifiClient);

// Light structure
struct Light
{
  // Light Availability Status
  enum Availability 
  {
    OFFLINE,
    ONLINE
  };
  
  // Light State
  enum State
  {
    OFF,
    ON
  };
    
  Light(Availability availability, State state, int brightness)
    : availability(availability), state(state), brightness(brightness){}
private:
  Availability availability;
  State state; 
  int brightness;

  public:
  void turn_onOff()
  {
    if(state == ON)
    {
      if(brightness == 0)
      {
        brightness = 255;   
      }
    }
    if(state == OFF)
    {
      brightness = 0;
    }
    Serial.println("Turn " + stateToStr(state) + " light with brightness " + brightness);
    ledcWrite(LED_CHANNEL, brightness);
  }
// Getters and Setters
...
}

Light light(Light::OFFLINE, Light::OFF, 0);

/*************************************/
/* Main setup() - executed only once */
/*************************************/
void setup() 
{  
  Serial.begin(115200);
  
  // Configure LED PWM functionalitites
  ledcSetup(LED_CHANNEL, FREQUENCY, RESOLUTION);

  // Attach the channel to the GPIO to be controlled
  ledcAttachPin(LIGHT_PIN, LED_CHANNEL);
  
  setup_wifi();
  mqtt_client.setServer(MQTT_SERVER, MQTT_PORT);
  mqtt_client.setCallback(mqtt_receive);
  delay(1000);
}

/***************/
/* Main loop() */
/***************/
void loop() 
{
  mqtt_connect();
  mqtt_client.loop();
  delay(50);  
}

/********************************/
/* Used to setup WiFi connecton */
/********************************/
void setup_wifi() 
{  
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WIFI_SSID);

  // Set WIFI mode, WIFI_STA - Station (STA) mode is used to get ESP module connected to a WiFi network established by an access point
  WiFi.mode(WIFI_STA);
  WiFi.config(staticIP, gateway, subnet, dns1, dns2); //For statis IP address
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

/***************************************************************************/
/* Initial MQTT connection/reconnection, publishing and subscribing topics */
/***************************************************************************/
void mqtt_connect() 
{  
  int retries = 0;
  const int willQoS = 0;
  const boolean willRetain = true;
  char willTopic[40] = {0};
  char willPayload[40] = {0};
  
  while (!mqtt_client.connected()) {
    if(retries < RETRIES)
    {
      Serial.println("Attempting MQTT connection...");
      strcpy(willTopic, MQTT_CLIENT_NAME);
      strcat(willTopic, "availability");
      strcpy(willPayload, "offline");
      if (mqtt_client.connect(MQTT_CLIENT_NAME, MQTT_USERNAME, MQTT_PASSWORD, willTopic, willQoS, willRetain, willPayload)) 
      {
        light.setAvailability(Light::ONLINE);
        Serial.println("MQTT client state: " + String(mqtt_client.state()));

        // Publish MQTT topics
        mqtt_publish ("availability", light.availabilityToStr(light.getAvailability()), true);
        mqtt_publish ("state", light.stateToStr(light.getState()), true);
        mqtt_publish ("brightness", String(light.getBrightness()), true);

        //Subscribe MQTT topics
        mqtt_subscribe ("state/set");
        mqtt_subscribe ("brightness/set");
      } 
      else 
      {
        light.setAvailability(Light::OFFLINE);

        // Publish MQTT topic
        mqtt_publish ("availability", light.availabilityToStr(light.getAvailability()), true);
        
        Serial.println("Failed to connect to MQTT server");
        Serial.println("MQTT client state: " + String(mqtt_client.state()));
        Serial.println("Try again in 5 seconds...");
        retries++;
        // Wait 5 seconds before retrying
        delay(5000);
      }
    }
    if(retries >= RETRIES)
    {
      light.setAvailability(Light::OFFLINE);

      // Publish MQTT topic
      mqtt_publish ("availability", light.availabilityToStr(light.getAvailability()), true);
      
      Serial.print("Restarting board, state: " + String(light.getAvailability()));
      ESP.restart();
    }
  } 
}

/********************************************************************/
/* Callback function for receiving subscribed MQTT messages arrives */
/********************************************************************/
void mqtt_receive(char* topic, byte* payload, unsigned int length) 
{
  payload[length] = '\0';
  String topicString = String(topic);
  String payloadString = String((char *)payload);
  
  Serial.println("Message arrived [" + topicString + "] payload: " + payloadString);

  switch (light.getAvailability())
  {
    case Light::ONLINE:
      if(topicString.equals(String(MQTT_CLIENT_NAME) + "state/set"))
      {
        payloadString.equals("ON") ? light.setState(Light::ON) : light.setState(Light::OFF);
        Serial.println("Current state set to " + light.stateToStr(light.getState()));
        light.turn_onOff();
        mqtt_publish ("state", light.stateToStr(light.getState()), true);
        mqtt_publish ("brightness", String(light.getBrightness()), true);
      }
      if(topicString.equals(String(MQTT_CLIENT_NAME) + "brightness/set"))
      {
        light.setBrightness(payloadString.toInt());
      }
    break;
    default:
      Serial.println("ERROR: MQTT message [" + topicString + "] received in wrong state = " + light.availabilityToStr(light.getAvailability()));
    break;  
  }
}

/***************************************/
/* Method for publishing MQTT messages */
/***************************************/
void mqtt_publish (String stringTopic, String stringPayload, boolean retain)
{
  char topic[50] = {0};
  char payload[50] = {0};

  strcpy(topic, MQTT_CLIENT_NAME);
  strcat(topic, stringTopic.c_str());
  strcpy(payload, stringPayload.c_str());

  mqtt_client.publish(topic, payload, retain);
  Serial.println("Publishing topic [" + String(topic) + "] payload: " + String(payload));  
}

/*******************************************/
/* Method for subscribing on MQTT messages */
/*******************************************/
void mqtt_subscribe (String stringTopic)
{
  char topic[50] = {0};

  strcpy(topic, MQTT_CLIENT_NAME);
  strcat(topic, stringTopic.c_str());

  mqtt_client.subscribe(topic);
  Serial.println("Subscribing on topic [" + String(topic) + "]");  
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.