MQTT Cover

I am having trouble setting up a MQTT Cover for my garage. So I have it set up in the NodeMCU so that if it receives a message from home/garage/door with a message of 1 then it will trigger the output pin low for 1 sec then switch to high which turns the relay on then off. And I have a state message at home/garage/status that is hooked to a reed switch to signal open or closed. So I used the command line to send a message and this works however when I take it over to the HA side the garage will open then a second later close then open then close and keep repeating until I turn off the NodeMCU. I then had to switch the MQTT topic because this one became corrupt and I thought I figured it out but the same thing happened on the new topic. Any ideas on what I am doing wrong? Below is my cover.yaml file.

- platform: mqtt
  name: "Garage Door"
  state_topic: "home/garage/status"
  command_topic: "home/garage/door1"
  payload_open: "1"
  payload_close: "1"
  payload_stop: "1"
  state_open: "1"
  state_closed: "0"
  optimistic: true
  qos: 2
  retain: true

I am using MQTT for a doorbell and that seems to work fine and the command line also work fine. Just stumped.

Thanks,
Matt

I think that your problem is the payload for open and close, it should be 1 for open and 0 to close. Try setting optimistic to false and check is that fix your problem.

I think from this that you are emulating a push button that
a) opens the door if it is closed
b) closes the door if it is open

If this is true, the main problem I can see is the retain flag. When this is true, if the nodemcu disconnects from the broker and reconnects due to a wifi problem, it will receive a new command and change the state of the door, which is probably not what you want.

I’m not sure what you mean about a corrupt topic, but I suspect it is to do with the retain flag as well. To clear it, you have to publish a null payload with the retain flag set to that topic.

This doesn’t help with your initial problem though, which I think is an interaction between the cover automation and the status of the switch. I haven’t used the MQTT cover so I can’t shed much light on that.

Can you get a log of the mqtt messages being sent? That might explain what is going on.

I tried setting this to 1 and 0 and it didn’t seem to help. If I push close it will stop but when I push open again it will go back to turn on then off then on and off.

Ok I see what you are saying I think about the retain flag and I think it does connect/disconnect often which is why I am seeing this problem. I am unsure how to do a log. I have tried a few other things but am still lost. I have found out if I set my code to publish to a topic and upload with a usb and leave the usb plugged in then the code runs fine however when I unplug the usb cable and plug it back in then I start seeing the clicking of the on/off. To make it stop clicking I have to change the topic to something else and upload to the NodeMCU again. So really the second I unplug the power I start to see the problems. This won’t do since if I lose power at some point my garage door will go haywire the second the power comes back on. Any advice?

I don’t know which broker you are using, which would determine which tools you have available.

I generally use mosquitto_sub:

mosquitto_sub -t "#" -v -h  "your mqtt host location"

I don’t know if this helps, but I’ll post it anyway😂

It’s the sourcecode of my own nodemcu garagedoor-opener. One thing, I’m using 2 reed-sensors.

I wasn’t able to get the log file before I went to work this morning however here is the arduino code I have on my NodeMCU.

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

// Use these lines to setup MQTT Server and WiFi
#define MQTT_SERVER "XXX.XXX.XXX.XXX"
const char* ssid = "XXXXXX";
const char* password = "XXXXXX";

// Define GPIO on NodeMCU
const int doorPin = 13;
const int relayPin = 14;

// Define Variables
//int garageRelay = 0;
bool isOpen = false;

// Topics to Publish to
char* relayTopic = "home/garage/door";

// Topics to Subscribe to
char* doorTopic = "home/garage/status";

WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);


void setup() {
  pinMode(doorPin, INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);

  // Start the serial line for debugging
  Serial.begin(115200);   // com to computer

  delay(100);

  // Start wifi subsystem
  WiFi.begin(ssid, password);

  // Attempt to connect to the WIFI network and then connect to the MQTT server
  reconnect();

  // Wait for a bit before starting main loop
  delay(2000);
}

void loop() {
  // Reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  // Maintain MQTT connection
  client.loop();
  
  //grab the current garage door state
  bool doorState = digitalRead(doorPin);

  if(!doorState && !isOpen){  //if door is open and the state closed, publish
    client.publish(doorTopic,"0");  //send closed
    isOpen = true;
    delay(500);
  }
  else if(doorState && isOpen){   //if door is closed and the state is open, publish
    client.publish(doorTopic,"1");  //send open
    isOpen = false;
    delay(500);
  }

  // Delay to allow ESP8266 WIFI functions to run
  delay(10);
  
}

// MQTT callback function -(Use only if topics are being subscribed to)
void callback(char* topic, byte* payload, unsigned int length){

  // Convert topic to string to make it easier to work with
  String topicStr = topic;
  char byteToSend = 0;

  // Handle relayTopic
  if(topicStr.equals(relayTopic)){
    if(payload[0] == '1'){
      digitalWrite(relayPin, LOW);
      delay(1000);
      digitalWrite(relayPin, HIGH);
      delay(500);
    }
    else if (payload[0] == '0'){
      digitalWrite(relayPin, HIGH);
    }
  }
  else {
    delay(10);
  }
}


void reconnect() {
   //attempt to connect to the wifi if connection is lost
  if(WiFi.status() != WL_CONNECTED){
    //debug printing
    Serial.print("Connecting to ");
    Serial.println(ssid);

    //loop while we wait for connection
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    //print out some more debug once connected
    Serial.println("");
    Serial.println("WiFi connected");  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //make sure we are connected to WIFI before attemping to reconnect to MQTT
  if(WiFi.status() == WL_CONNECTED){
  // Loop until we're reconnected to the MQTT server
    while (!client.connected()) {
      Serial.println("");
      Serial.print("Attempting MQTT connection...");

      // Generate client name based on MAC address and last 8 bits of microsecond counter
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      //if connected, subscribe to the topic(s) we want to be notified about
      if (client.connect("(char*) clientName.c_str()", "XXXXXX", "XXXXXX")) {
        Serial.println("");
        Serial.print("\tMTQQ Connected");
//        client.subscribe(doorTopic);
        client.subscribe(relayTopic);
      }
      

      //otherwise print failed for debugging
      else{Serial.println("\tFailed."); abort();}
    }
  }
}

// Generate unique name from MAC addr
String macToStr(const uint8_t* mac){
  
  String result;
  
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    
    if (i < 5){
      result += ':';
    }
  }
  
  return result;
}

I have just been thinking about a more reliable design.

At the moment, you have HA sending the same message for on and off, which doesn’t really tell your nodemcu whether the door should be open or closed.

I suggest

  1. Change the payload of the mqtt message to 1 for open and 0 for closed.
  2. If the nodemcu gets a 1 and the door is not open, it sends a pulse to make the door change state
  3. Similarly, if the nodemcu gets a 0 and the door is not closed, it sends a pulse.
  4. Whenever the nodemcu receives a command from HA, it publishes the state of the door, with the retain flag set.

This way the door should always end up in the state you want.

This is what oriolism suggested and I tried it and it appeared to be working for awhile but maybe I messed something up. Maybe I just don’t understand what is going on. If the door is closed then I push the open button it fires a message with a payload of 1 to open the door correct? Then if the door is open and I select the close button will it send a message of 0? This won’t do anything because the door only signals when a 1 is published to the topic correct? Maybe I am missing something.

Its easier to write than explain :slight_smile:


void loop() {
  // Reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  // Maintain MQTT connection
  client.loop();
  
  // Delay to allow ESP8266 WIFI functions to run
  delay(10);
  
}

// MQTT callback function -(Use only if topics are being subscribed to)
void callback(char* topic, byte* payload, unsigned int length){

  // Convert topic to string to make it easier to work with
  String topicStr = topic;
  char byteToSend = 0;
  char* DOOR_OPEN = "1";
  char* DOOR_CLOSED = "0";

  // Handle relayTopic
  if(topicStr.equals(relayTopic)){
    //grab the current garage door state
    bool doorState = digitalRead(doorPin);
    if(payload[0] == '1'){
      if (doorstate == 0 ) {  // Door closed
        // Open door    
        digitalWrite(relayPin, LOW);
        delay(1000);
        digitalWrite(relayPin, HIGH);
        delay(500);
      }
      client.publish(doorTopic, DOOR_OPEN);  //send open
    }
    else if (payload[0] == '0'){
      if (doorstate == 1 ) {  // Door open
        // Close door    
        digitalWrite(relayPin, LOW);
        delay(1000);
        digitalWrite(relayPin, HIGH);
        delay(500);
      }
      client.publish(doorTopic, DOOR_CLOSED);  //send open
    }
  }
}

This seems to work for the most part however it will click continuously until the door state is changed. So i don’t think it will be a problem opening because the sensor will trip quick however when the door is closing it will take much longer because the door has to shut before the sensor is tripped. I could probably do a delay but don’t think this is the best solution. Is there something that I am doing wrong. Below is the log file.

home/garage/door3 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/door3 1
home/garage/status 0
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/door3 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/status 0
home/garage/door3 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1
home/garage/status 1

Here is what the new code looks like:
#include <PubSubClient.h>
#include <ESP8266WiFi.h>

// Use these lines to setup MQTT Server and WiFi
#define MQTT_SERVER "###.###.###.###"
const char* ssid = "######";
const char* password = "######";

// Define GPIO on NodeMCU
const int doorPin = 13;
const int relayPin = 14;
char* DOOR_OPEN = "1";
char* DOOR_CLOSED = "0";

// Define Variables
//int garageRelay = 0;
//bool isOpen = false;

// Topics to Publish to
char* relayTopic = "home/garage/door3";

// Topics to Subscribe to
char* doorTopic = "home/garage/status";

WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);


void setup() {
  pinMode(doorPin, INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);

  // Start the serial line for debugging
  Serial.begin(115200);   // com to computer

  delay(100);

  // Start wifi subsystem
  WiFi.begin(ssid, password);

  // Attempt to connect to the WIFI network and then connect to the MQTT server
  reconnect();

  // Get Initial Door State
  bool doorState = digitalRead(doorPin);
  if(doorState == 0) { //If Door is Closed
    // Publish Door Closed to doorTopic
    client.publish(doorTopic, DOOR_CLOSED);  //send close
  }
  else if(doorState == 1) { //If Door is Open
    // Publish Door Open to doorTopic
    client.publish(doorTopic, DOOR_OPEN);  //send close
  }
  
  // Wait for a bit before starting main loop
  delay(2000);
}

void loop() {
  // Reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  // Maintain MQTT connection
  client.loop();
  
//  //grab the current garage door state
//  bool doorState = digitalRead(doorPin);
//
//  if(!doorState && !isOpen){  //if door is open and the state closed, publish
//    client.publish(doorTopic,"0");  //send closed
//    isOpen = true;
//    delay(500);
//  }
//  else if(doorState && isOpen){   //if door is closed and the state is open, publish
//    client.publish(doorTopic,"1");  //send open
//    isOpen = false;
//    delay(500);
//  }

  // Delay to allow ESP8266 WIFI functions to run
  delay(10);
  
}

// MQTT callback function -(Use only if topics are being subscribed to)
void callback(char* topic, byte* payload, unsigned int length){

  // Convert topic to string to make it easier to work with
  String topicStr = topic;
  char byteToSend = 0;
  char* DOOR_OPEN = "1";
  char* DOOR_CLOSED = "0";

  // Handle relayTopic
  if(topicStr.equals(relayTopic)){
    // Grab the current garage door state
    bool doorState = digitalRead(doorPin);
    
    if(payload[0] == '1'){
      if(doorState == 0) { //If Door is Closed
        // Open Door
        digitalWrite(relayPin, LOW);
        delay(1000);
        digitalWrite(relayPin, HIGH);
        delay(500);
        // End Open Door
      }
      // Publish Door Open to doorTopic
      client.publish(doorTopic,DOOR_OPEN);  //send open
    }
    
    else if (payload[0] == '0'){
      if(doorState == 1) { //If Door is Open
        // Close Door
        digitalWrite(relayPin, LOW);
        delay(1000);
        digitalWrite(relayPin, HIGH);
        delay(500);
      }
      // Publish Door Closed to doorTopic
      client.publish(doorTopic, DOOR_CLOSED);  //send close
    }
  }
  else {
    delay(10);
  }
}


void reconnect() {
   //attempt to connect to the wifi if connection is lost
  if(WiFi.status() != WL_CONNECTED){
    //debug printing
    Serial.print("Connecting to ");
    Serial.println(ssid);

    //loop while we wait for connection
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    //print out some more debug once connected
    Serial.println("");
    Serial.println("WiFi connected");  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //make sure we are connected to WIFI before attemping to reconnect to MQTT
  if(WiFi.status() == WL_CONNECTED){
  // Loop until we're reconnected to the MQTT server
    while (!client.connected()) {
      Serial.println("");
      Serial.print("Attempting MQTT connection...");

      // Generate client name based on MAC address and last 8 bits of microsecond counter
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      //if connected, subscribe to the topic(s) we want to be notified about
      if (client.connect("(char*) clientName.c_str()", "######", "######")) {
        Serial.println("");
        Serial.print("\tMTQQ Connected");
//        client.subscribe(doorTopic);
        client.subscribe(relayTopic);
      }
      

      //otherwise print failed for debugging
      else{Serial.println("\tFailed."); abort();}
    }
  }
}

// Generate unique name from MAC addr
String macToStr(const uint8_t* mac){
  
  String result;
  
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    
    if (i < 5){
      result += ':';
    }
  }
  
  return result;
}

I’m not sure why so many status messages are being printed. There should only be one status message for each command, unless I misunderstand how often callback is being called. But if it works generally, that is a minor problem.

I also understand now that your sensor is a closed/not closed sensor rather than closed/open.

I think a flag variable to indicate that you have issued a closing command and are waiting for the door to close. That would prevent issuing another command until it had actually closed.

The flag can be cleared by checking if the doorPin in the main loop.

If you got an open command while the door is open, you have to find out if you can send a pulse to get it to open rather than close, or if you have to wait until it finishes.

p.s.
there is also an else { delay(10 } in the callback script which I don’t understand the reason for, and may cause problems if it receives other commands.

The only problem I see with using the flag or the delay is that if the sensor was tripped for something being in the way of the door closing then either the door would continue to close with it turning on/off after the delay or the door would be stuck open if a flag was used because I could not issue another command with the flag still not triggered.

I will remove the delay(10) next time I try it.

You can change your code to only send and update to the mqtt server only when the garage door state changes. I use this:

bool gState = 0; //logical placeholder - current status of the garage
bool gPrevious = 1; //logical placeholder - previous status of the garage

// ========{ Garage Magnetic SW Monitoring Input }==================
void garageMagSensor ()
{
gState = digitalRead(13);
if (gState != gPrevious) { //only run if there is a status change from previous state
gPrevious = gState; //reinitialize
if (gState == LOW)
{
client.publish(“GarageDoor/status”, “CLOSE”);
Serial.print(“Garage Door is Closed”);
}
else
{
client.publish(“GarageDoor/status”, “OPEN”);
Serial.print(“Garage Door is Open”);
}
}
}

Then in void loop() add garageMagSensor();

It seems like this is just becoming a total failure. I think my code is fine but I think it has to do with the cover component and the number of reed switches I have. When I push open button the reed switch will separate almost immediately so there is no problem however when I close the door it takes some time for the reed switch to become triggered. If the state has not changed by the time it runs through the callback then it will send the same message until the state changes. Does this make sense and would adding an additional reed switch help my issue by sending a signal right away when I push the close button?

PS: I have been thinking about this more. Does this mean if I opened or closed it with another device that was not MQTT that the arduino would try to correct this to make the correct state as what was chosen by the arduino previously. For example if I opened the door with the arduino but then closed it from my car remote. Then when the state changed from the reed switch changed would it try to open the door again because that is what I am seeing from my testing. My callback is getting called multiple times if the state is not correct.

Its just more complicated than you thought initially. Which is why many software projects end up late and over budget.:slight_smile: Actually, it sounds like you are making good progress.

That is what I was trying to explain with the flag variable in my previous comment. A flag is different from a delay because it allows other commands to be received and acted upon while the door is closing.

The arduino (or NodeMCU which I assume is what you mean) should check the state of the relay to determine what the actual state of the door is before acting. If the door can be opened by other means, your sketch needs to include some code to send the new status via mqtt to HA (or whatever else is listening).

So what I did last night was create a new payload so that if it ran through the open or close command it would publish a payload of “5” instead of “0” or “1” from inside the main loop. Then for this payload it would update the pin status as either open or close. Which I believe is similar to a flag however when I performed this the code would run so if I pressed open the code will click the relay once but if the state does not change then the relay will signal again. But while doing this the payload of “5” was being sent because I saw it in the serial monitor so it should not be clicking the relay I think. Then once the state changes it will stop changing the relay. However if I change the state of the reed switch using something other than the NodeMCU then the relay will start firing again until the reed switch is back to what was called previously. Not sure why this is happening. I guess I will try to put something in the callback as a flag variable to try to prevent it from calling the relay after the first firing of the message.

Sorry for all the messages but this one is just frustrating me a little but I am getting there I hope.

Ok i think i almost have it. i just have one last issue. i threw a flag variable called hold in the callback so now when the relay runs once it wont run again until the reed switch is tripped which resets the flag. The one issue I have is that if I open or shut the garage door manually it will trigger the relay once but then wait for a state change again. i think i have an idea but I haven’t had time to try it yet i will give it a go tonight and let you know how it goes. Here is what the code looks like right now:

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

// Use these lines to setup MQTT Server and WiFi
#define MQTT_SERVER "xxxxxxxx"
const char* ssid = "xxxxxx";
const char* password = "xxxxxx";

// Define GPIO on NodeMCU
const int doorPin = 13;
const int relayPin = 14;

char* DOOR_CLOSED = "0";
char* DOOR_OPEN = "1";
char* DOOR_WAIT = "5";
char* DOOR_CLEAR = "8";

// Define Variables
//int garageRelay = 0;
bool isOpen = false;
int hold = 0;

// Topics to Publish to
char* relayTopic = "home/garage/door";

// Topics to Subscribe to
char* doorTopic = "home/garage/status";

WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);


void setup() {
  pinMode(doorPin, INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);

  // Start the serial line for debugging
  Serial.begin(115200);   // com to computer

  delay(100);

  // Start wifi subsystem
  WiFi.begin(ssid, password);

  // Attempt to connect to the WIFI network and then connect to the MQTT server
  reconnect();

  // Get Initial Door State
  bool doorState = digitalRead(doorPin);
  if(doorState == 0) { //If Door is Closed
    // Publish Door Closed to doorTopic
    client.publish(doorTopic, DOOR_CLOSED);  //send close
  }
  else if(doorState == 1) { //If Door is Open
    // Publish Door Open to doorTopic
    client.publish(doorTopic, DOOR_OPEN);  //send close
  }
  
  // Wait for a bit before starting main loop
  delay(2000);
}

void loop() {
  // Reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  // Maintain MQTT connection
  client.loop();
  
  //grab the current garage door state
  bool doorState = digitalRead(doorPin);
  if(!doorState && !isOpen){  //if door is open and the state closed, publish
    client.publish(doorTopic,DOOR_CLOSED);  //send closed
    isOpen = true;
    hold=0; // Set hold to 0 to allow MQTT
    delay(500);
  }
  else if(doorState && isOpen){   //if door is closed and the state is open, publish
    client.publish(doorTopic,DOOR_OPEN);  //send open
    isOpen = false;
    hold=0; // Set hold to 0 to allow MQTT
    delay(500);
  }

  // Delay to allow ESP8266 WIFI functions to run
  delay(50);
  
}

// MQTT callback function -(Use only if topics are being subscribed to)
void callback(char* topic, byte* payload, unsigned int length){

  // Convert topic to string to make it easier to work with
  String topicStr = topic;
  char byteToSend = 0;


  // Handle relayTopic
  if(topicStr.equals(relayTopic)){
    // Grab the current garage door state
    bool doorState = digitalRead(doorPin);
    if(hold == 0){
      if(payload[0] == '1'){
        if(doorState == 0) { //If Door is Closed
          // Open Door
          digitalWrite(relayPin, LOW);
          delay(1000);
          digitalWrite(relayPin, HIGH);
          delay(1000);
          hold = 1;
          // End Open Door 
          Serial.println("");
          Serial.println("Open Called");
        }
      // Publish Door Open to doorTopic
      //client.publish(doorTopic, DOOR_OPEN);  //send open
    }
    
      else if(payload[0] == '0'){
        if(doorState == 1) { //If Door is Open
          // Close Door
          digitalWrite(relayPin, LOW);
          delay(1000);
          digitalWrite(relayPin, HIGH);
          delay(1000); 
          hold = 1;
          // End Close Door
          Serial.println("");
          Serial.println("Close Called");
        }
      // Publish Door Closed to doorTopic
      //client.publish(doorTopic, DOOR_CLOSED);  //send close
      }
    }

    else if(hold == 1){
      digitalWrite(relayPin, HIGH);
      Serial.println("");
      Serial.println("Nothing Called");
    }

    if(payload[0] == '5'){
      digitalWrite(relayPin, HIGH);
      hold=0;
    }
  }
}


void reconnect() {
   //attempt to connect to the wifi if connection is lost
  if(WiFi.status() != WL_CONNECTED){
    //debug printing
    Serial.print("Connecting to ");
    Serial.println(ssid);

    //loop while we wait for connection
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    //print out some more debug once connected
    Serial.println("");
    Serial.println("WiFi connected");  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //make sure we are connected to WIFI before attemping to reconnect to MQTT
  if(WiFi.status() == WL_CONNECTED){
  // Loop until we're reconnected to the MQTT server
    while (!client.connected()) {
      Serial.println("");
      Serial.print("Attempting MQTT connection...");

      // Generate client name based on MAC address and last 8 bits of microsecond counter
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      //if connected, subscribe to the topic(s) we want to be notified about
      if (client.connect("(char*) clientName.c_str()", "xxxxxx", "xxxxxx")) {
        Serial.println("");
        Serial.print("\tMTQQ Connected");
//        client.subscribe(doorTopic);
        client.subscribe(relayTopic);
      }
      

      //otherwise print failed for debugging
      else{Serial.println("\tFailed."); abort();}
    }
  }
}

// Generate unique name from MAC addr
String macToStr(const uint8_t* mac){
  
  String result;
  
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    
    if (i < 5){
      result += ':';
    }
  }
  
  return result;
}

Well my idea didn’t work so any advice would be welcome.