After update MQTT won't work

Hi, my hassio worked fine untill update. Maybe someone can help me?

configuration.yaml

mqtt:
  broker: 192.168.1.109 
  client_id: RaspberryPi3

switch:
- platform: mqtt
  name: "Relay 99"
  state_topic: "ha/Relay_99"
  command_topic: "ha/Relay_99"
  qos: 0
  payload_on: "ON"
  payload_off: "OFF"
  optimistic: false
  retain: true

ino file

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "RIGHT_WIFI_SSID";
const char* password = "RIGHT_PASSWORD";
const char* mqtt_server = "192.168.1.109";

WiFiClient espClient;
PubSubClient client(espClient);
int RelayPin = 16;
String switch1;
String strTopic;
String strPayload;

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
    {
      delay(500);
      Serial.print(".");
    }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length)
  {
    payload[length] = '\0';
    strTopic = String((char*)topic);
    Serial.println(strTopic);
    Serial.println((char*)payload);
    if(strTopic == "ha/Relay_99")
      {
        switch1 = String((char*)payload);
        if(switch1 == "ON")
          {
            Serial.println("Relay_99 ON");
            digitalWrite(RelayPin, LOW);
          }
        else
          {
            Serial.println("Relay_99 OFF");
            digitalWrite(RelayPin, HIGH);
          }
      }
  }
 
 
void reconnect()
  {
    while (!client.connected())
      {
        Serial.print("Attempting MQTT connection...");
        if (client.connect("NodeMCU"))
          {
            Serial.println("connected");
            client.subscribe("ha/#");
          }
        else
          {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
          }
      }
  }
 
void setup()
  {
    Serial.begin(115200);
    setup_wifi(); 
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    pinMode(RelayPin, OUTPUT);
    digitalWrite(RelayPin, HIGH);
  }
 
void loop()
  {
    if (!client.connected())
      {reconnect();}
    client.loop();
  }

AND Serial monitor

Connecting to RIGHT_WIFI_SSID
...........................
WiFi connected
IP address: 
192.168.1.120
Attempting MQTT connection...connected

but switch doesn’t work

in switch status shows

September 27, 2020
11:41:05 PM
turned off
11:40:57 PM
changed to unavailable

Im try to find solution like one week, but i have no ideo and i decide to ask help :confused:
thanks

I think I can see a couple of problems.

First I think it is dangerous to just append a \0 to the received message because you receive a pointer to a string which is not null terminated and then you add a \0 to a byte that is not part of the string.

Here is an example from my own similar application

A couple of details. I call my callback routine mqttCallback. That is just a different name and not important.

I use the same initial code in all my mqtt callback routines
It is important to know that the pubSub library uses the same memory area to receive and send messages so to be able to use same code for publishing messages inside the call back I make a copy of both topic and message strings
And for the message string I reserve the extra byte for the null terminator
I do not use String. I use basic C strings. That saves memory which can be important in larger programs.

The topic names are defined earlier in the program as global const chars

const char* mqttTopicSet      = "magicmirror/set";
const char* mqttTopicState    = "magicmirror/state";

and callback function

void mqttCallback(char* topic, byte* payload, unsigned int length) {

    // Creating safe local copies of topic and payload
    // enables publishing MQTT within the callback function
    // We avoid functions using malloc to avoid memory leaks
    
    char topicCopy[strlen(topic) + 1];
    strcpy(topicCopy, topic);
    
    char message[length + 1];
    for (int i = 0; i < length; i++) message[i] = (char)payload[i];
    
    message[length] = '\0';
  
    if ( strcmp(topicCopy, mqttTopicSet) == 0 ) {
        if ( strcmp(message, "on") == 0 ) lightOn();
        if ( strcmp(message, "off") == 0 ) lightOff();
    }

    else {
        return;
    }

}

And the two on and off routines look like this. You could just put the code inside the callback but I use two functions as I also have same function based on physical button press

bool lightOn() {
        lightStatus = true;
        digitalWrite(RELAY, HIGH);
        client.publish(mqttTopicState, "on", true );
        return true;
}

bool lightOff(void) {
        lightStatus = false;
        digitalWrite(RELAY, LOW);
        client.publish(mqttTopicState, "off", true );
        return true;
}

Note that the device receives message with the mqttTopicSet topic. And then it reports its state back on mqttTopicState.

You always want to use two different topics.

Best is to have the set topic not retained. And the state topic retained. This way Home Assistant knows what the state is when it restarts. When the device restarts it will set itself to a default. You can however choose to read the state topic at boot and then unsubscribe from it.

Can u please share your yaml file and ino file?
I am studing only this and i nees to understand things

Sure I can

I just added several of my MQTT devices to github.

Here is a Sonoff TH10 with an external on/off switch controlling a groups of lights around a makeup mirror https://github.com/KennethLavrsen/Magic-Mirror

Here is a D1 mini controlling a linear actuator with an H bridge, and it gets its position via potentiometer in actuator https://github.com/KennethLavrsen/Small-Window

Here is a bathroom fan with humidity and temperature sensor using a Sonoff TH10 https://github.com/KennethLavrsen/Fan

You can find my entire Home Assistant configuration here https://github.com/KennethLavrsen/Home-Assistant-Config

Specific files to note

  • covers.yaml
  • fans.yaml
  • lights.yaml
  • automations/fan.yaml
  • automations/workshop-blinds.yaml
  • automations/smallwindow.yaml

I hope this is a help to you and others.

And finally. If anyone has the question “Why don’t you use ESPHome or Tasmota?” The answer is that I like to have full control over thing and once you have the first MQTT controlled device working it is easy to just keep on making more of them.