MQTT switch state update help

Hi all,

I am trying to make a mqtt momentary/timed switch to control a relay, press the button relay is active for 2 seconds then goes off.

I am using a simple code see below.

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

const char* ssid = "B*********";
const char* password = "R**********";
const char* mqtt_server = "192.********";
#define mqtt_user "mqtt" //enter your MQTT username
#define mqtt_password "******" //enter your password

WiFiClient espClient;
PubSubClient client(espClient);
int SwitchedPin = 5, LEDPin = 2, Override = 14, OverrideMem = 0;
bool HassSwitch = false;
String switch1;
String strTopic;
String strPayload;

void setup_wifi() {
 Serial.begin(115200);
  delay(2000);
 
  Serial.println();
  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());

  pinMode(LEDPin,OUTPUT);
  digitalWrite(LEDPin, HIGH);

  
}

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  strTopic = String((char*)topic);
  if(strTopic == "ha/switch1")
    {
    switch1 = String((char*)payload);
    if(switch1 == "ON")
      {
        Serial.println("ON");
        digitalWrite(SwitchedPin, HIGH);
        digitalWrite(LEDPin, LOW);
        HassSwitch = true;
      delay(2000);
      Serial.println("OFF");
        digitalWrite(SwitchedPin, LOW);
        digitalWrite(LEDPin, HIGH);
        HassSwitch = false;
      }
    else
      {
        Serial.println("OFF");
        digitalWrite(SwitchedPin, LOW);
        digitalWrite(LEDPin, HIGH);
        HassSwitch = false;
      }
    }
}
 
 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.subscribe("ha/#");
    } 
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
 
void setup()
{
  setup_wifi(); 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  pinMode(SwitchedPin, OUTPUT);
  digitalWrite(SwitchedPin, LOW);
}
 
void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  if(digitalRead(Override) != OverrideMem && !HassSwitch)
  {
    if(digitalRead(Override))
    {
      Serial.println("ON");
      digitalWrite(SwitchedPin, HIGH);
      digitalWrite(LEDPin, LOW);
      OverrideMem = 1;
    }
    else
    {
      Serial.println("OFF");
      digitalWrite(SwitchedPin, LOW);
      digitalWrite(LEDPin, HIGH);
      OverrideMem = 0;
    }
  }

The code works but what isn’t working is the switch state doesn’t update in home assistant when the relay switches off.

My .yaml code is

switch:
  - platform: mqtt
    mqtt name: "Switch1"
    state_topic: "ha/switch1"
    command_topic: "ha/switch1"
    qos: 2
    payload_on: "ON"
    payload_off: "OFF"
    false retain: true

Can anyone help with this issue,

Thanks

No clue, but this is definitively wrong.

false retain: true

That has already been removed as it was throwing up a configuration error.

This is a red flag too:

    state_topic: "ha/switch1"
    command_topic: "ha/switch1"

The entity is subscribed to the same topic it publishes to. Basically, it’s a loopback and defeats the intended purpose of subscribing to what the device publishes (not what the entity publishes).

You need to add mqtt publish commands in your anduino sketch both when the light is turned on and off again. As 123 says, these need to publish to a different topic to the command topic, and then change the HA configuration to listen to that topic with the state_topic:

Thanks for the replies,

I get what you are saying but how to implement it is my next problem.
This what I came up with

ESP code

     if (strTopic == "ha/switch2/cmd")
      {
        switch2 = String((char*)payload);
        if (switch2 == "ON")
        {
          Serial.println("SW2 ON");
          digitalWrite(LEDPin2, LOW);
          HassSwitch = true;
          client.publish("ha/switch2/stat", "ON");
          delay(2000);
          Serial.println("SW2 OFF");
          digitalWrite(LEDPin2, HIGH);
          HassSwitch = false;
          client.publish("ha/switch2/stat", "OFF");

and the config.yaml

switch:
  - platform: mqtt
    name: "Switch2"
    state_topic: "ha/switch2/stat"
    command_topic: "ha/switch2/cmd"
    qos: 2
    payload_on: "ON"
    payload_off: "OFF"

this does not work, but am I on the right tracks.

Thanks

You didn’t say anything about the device your code runs on.
Maybe you don’t have to reinvent the wheel?

I’m using a nodemcu. I’ll have a read of that link.

Thanks

After having a play with this add on I’ve found its excellent

While I like to play around with the code on the nodemcu just as a learning exercise more than anything this program allow more learning of the .yaml configurations without worrying about the
rest.

Thanks