ESP 8266 MQTT Switch for Home Assistant V2.0

   
 /* ################################################################  
   ################################################################  
   ########## ESP 8266 MQTT Switch for Home Assistant V2.0 #######  
   ################################################################  
   ###################*** MOSQUITTO ***############################  
 */  
   
   // UPDATED: SEP 5 2018
   // CHANGE SwitchReset and SwitchResetConfirm to SwitchOta and SwitchOtaConfirm in the .yaml file
 //########################################################################################  
   
 // You Can find this sketch on Home Assistant forum i have just modified it according to my  
 // Requirements as it is just a waste of time trying to re-invent the wheel  
 // so thank you for it random citizen :D  
   
 //** INCLUDE LIBRARIES ** make sure you have all the Libraries installed  
 // Get them from within the Arduino IDE Sketch > Include Libraries > Manage Libraries  
   
 //########################################################################################  
 // Update libraries from library Manager and Boards from Boards Manager to latest  
   
   
 #include <PubSubClient.h>  
 #include <ESP8266WiFi.h>  
 #include <ArduinoOTA.h>  
 #include <ESP8266mDNS.h>  
 #include <WiFiUdp.h>  
   
   
   
 //##################################################################  
   
   
 void callback(char* topic, byte* payload, unsigned int length);  
   
   
   
 #define MQTT_SERVER "192.168.1.6"   // IP of your MQTT Server    
   
   
   
 const char* ssid = "Internet";  // SSID for you Wifi Hotspot  
 const char* password = "12345678qwerty";     // Password for Wifi Hotspot  
   
   
 //########### ESP 8266 GPIO Pins ###########################################  
   
   
 const int switchPin1 = 4;  
 const int switchPin2 = 5;  
 const int switchPin3 = 13;  
 const int switchPin4 = 12;  
   
 unsigned long secs = 0;  
   
 //#########################################################################  
   
   
 // ***** MQTT Topics Defined In Home Assistant's Configuration.yaml file ***  
   
   
 //#########################################################################  
   
 char const* switchTopic1 = "/house/switch1/";   //four switches for relays  
   
 char const* switchTopic2 = "/house/switch2/";  
   
 char const* switchTopic3 = "/house/switch3/";  
   
 char const* switchTopic4 = "/house/switch4/";  
   
   
   
 char const* switchSleep = "/house/switchSleep/"; // fifth for putting the Esp in sleep mode  
   
 char const* switchOta = "/house/switchOta/"; // sixth for updating the Esp  // port 8266 //check firewall 
   
 //##########################################################################  
   
   
   
 WiFiClient wifiClient;  
   
   
 PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);  
   
   
   
   
   
   
 //#################################################################################  
 //#################################################################################  
   
 //############## SETUP BEGINS #####################################################  
   
 //#################################################################################  
 //#################################################################################  
   
   
   
 void setup()  
 {  
  digitalWrite(switchPin1, LOW);  
   
  digitalWrite(switchPin2, LOW);  
   
  digitalWrite(switchPin3, LOW);  
   
  digitalWrite(switchPin4, LOW);  
   
  // These lines will keep the Relays off during start-up  
   
  // Because i'm Using NPN transistors for  
   
  // switching the relays which are actually  
   
  // LOW-level-trigger type  
   
  // adding the transistor will invert that logic  
   
  // and LOW will be OFF because Transistor is off  
   
   
   
   
  pinMode(switchPin1, OUTPUT);  // Relay Switch 1  
   
  pinMode(switchPin2, OUTPUT);  // Relay Switch 2  
   
  pinMode(switchPin3, OUTPUT);  // Relay Switch 3  
   
  pinMode(switchPin4, OUTPUT);  // Relay Switch 4  
   
   
   
  //####################################################################################  
   
   
   
   
  Serial.begin(115200);  
  delay(100);  
   
   
   
   
   
   
  WiFi.mode(WIFI_STA);    // Set Esp8266 in Station mode  
   
  WiFi.begin(ssid, password);  
   
   
  secs = millis() / 1000 ;  
   
  while (WiFi.waitForConnectResult() != WL_CONNECTED)  
  {  
   
   Serial.println("Waiting for WiFi Connection ...");  
   
   delay(2000);  
   
   /*if (millis() / 1000 - secs > 60)  
   {  
    Serial.println("Going to Sleep for 10 secs ...");  
   
    ESP.deepSleep(10 * 1000000);  
   }  */
  }  
   
   
   
   
  //############################################################################################  
  //############################################################################################  
   
  //############# CHANGE OTA UPDATE PASSWORD ###################################################  
  //############################################################################################  
  //############################################################################################  
   
  ArduinoOTA.setPassword((const char *)"123"); // Password for OTA Update "123"  
  ArduinoOTA.begin();  
   
   
   
   
 }  
   
 //##########################################################################################  
   
 //############ SETUP END ###################################################################  
   
 //##########################################################################################  
   
   
 bool ota_update = false ; // Don't change this manually  
   
   
   
   
   
 //#########################################################################################  
   
 //######### LOOP BEGINS ##################################################################  
   
 //#########################################################################################  
   
   
 void loop()  
 {  
   
  if (!client.connected() && WiFi.status() == 3)  
   
  {  
   
   reconnect(); // Reconnect if connection is lost  
   
  }  
   
   
  client.loop(); // Maintain MQTT connection  
  if (ota_update)    
  {     secs = millis() / 1000 ;  }
   
  delay(10);   // MUST delay to allow ESP8266 WIFI functions to run  
  OTA();  
   
 }  
   
   
 //#########################################################################################  
 //################# WAIT FOR OTA UPDATE ON EVERY START UP #################  
 //#########################################################################################  
 void OTA()  
 {  
  if (ota_update)    
  {  
   Serial.println("Waiting for Ota update");  
   
   while (millis() / 1000 - secs < 20 )  
   {  
    ArduinoOTA.handle() ;  
    delay(10);  
   }  
  }  
 }  
 //#################################################3  
   
   
   
 //#########################################################  
   
   
   
 void callback(char* topic, byte* payload, unsigned int length) {  
   
   
  String topicStr = topic;  
   
   
   
  Serial.println("Callback update.");  
  Serial.print("Topic: ");  
  Serial.println(topicStr);  
   
   
  //################## Switch 1 ################### COPY THESE BLOCKS FOR MORE SWITCHES ####################  
   
  if (topicStr == "/house/switch1/")  
  {  
   
   if (payload[0] == '1')  
   {  
   
    digitalWrite(switchPin1, HIGH);  
   
    client.publish("/house/switchConfirm1/", "1");  
    delay(1000);  
   }  
   
   
   
   else if (payload[0] == '0')  
   {  
   
    digitalWrite(switchPin1, LOW);  
   
    client.publish("/house/switchConfirm1/", "0");  
   
   }  
   
  }  
   
   
   
   
  //################## Switch 2 #####################################################  
   
   
   
   
   
   
  else if (topicStr == "/house/switch2/")  
  {  
   
   
   
   if (payload[0] == '1')  
   {  
   
    digitalWrite(switchPin2, HIGH);  
   
    client.publish("/house/switchConfirm2/", "1");  
    delay(1000);  
   
   }  
   
   
   
   else if (payload[0] == '0')  
   {  
   
    digitalWrite(switchPin2, LOW);  
   
    client.publish("/house/switchConfirm2/", "0");  
   
   }  
   
  }  
   
   
   
  //################## Switch 3 #####################################################  
   
   
   
   
   
   
  else if (topicStr == "/house/switch3/")  
  {  
   
   
   
   if (payload[0] == '1')  
   {  
   
    digitalWrite(switchPin3, HIGH);  
   
    client.publish("/house/switchConfirm3/", "1");  
   
    delay(1000);  
   
   }  
   
   
   
   else if (payload[0] == '0')  
   {  
   
    digitalWrite(switchPin3, LOW);  
   
    client.publish("/house/switchConfirm3/", "0");  
   
   }  
  }  
   
   
   
   
   
  //################## Switch 4 #####################################################  
   
   
   
   
  else if (topicStr == "/house/switch4/")  
  {  
   
   
   if (payload[0] == '1')  
   {  
    digitalWrite(switchPin4, HIGH);  
   
    client.publish("/house/switchConfirm4/", "1");  
   
    delay(1000);  
   
   }  
   
   
   
   else if (payload[0] == '0')  
   {  
    digitalWrite(switchPin4, LOW);  
   
    client.publish("/house/switchConfirm4/", "0");  
   }  
  }  
   
   
  //################## Switch 5 Sleep Mode #######################################  
   
   
  else if (topicStr == "/house/switchSleep/")  
  {  
   
   
   if (payload[0] == '1')  
   {  
   
    client.publish("/house/switchSleepConfirm/", "1");  
   
    Serial.println("going to sleep for 60 secs");  
   
    delay(1000);  
   
    ESP.deepSleep(60 * 1000000);  
   
   
   }  
   
   
   
   else if (payload[0] == '0')  
   {  
    client.publish("/house/switchSleepConfirm/", "0");  
   }  
  }  
   
   
   
   
  //################## Switch 6 ota #######################################  
   
   
  else if (topicStr == "/house/switchOta/")  
  {  
   
   
   if (payload[0] == '1')  
   {  
    client.publish("/house/switchOtaConfirm/", "1");  
   
    ota_update = true ;  
   
   }  
   
   else if (payload[0] == '0')  
   {  
    client.publish("/house/switchOtaConfirm/", "0");  
    ota_update = false ;  
   
   }  
  }  
   
   
   
   
   
   
   
   
   
   
   
 }  
   
   
 //#########################################################################################  
   
 //######### LOOP ENDS ##################################################################  
   
 //#########################################################################################  
   
   
   
   
   
   
 void reconnect() {  
   
   
   
  if (WiFi.status() != WL_CONNECTED)  
  {  
   
   Serial.print("Connecting to ..");  
   
   Serial.println(ssid);  
   
   
   
   while (WiFi.status() != WL_CONNECTED)  
   {  
   
    delay(500);  
   
    Serial.print(".");  
   
   }  
   
   
   
   Serial.println("");  
   
   Serial.println("WiFi connected");  
   
   Serial.println("IP address: ");  
   
   Serial.println(WiFi.localIP());  
  }  
   
   
   
   
   
  if (WiFi.status() == WL_CONNECTED) {  
   
   while (!client.connected()) {  
   
    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);  
   
   
    //#########################################################################################  
   
    //######### CHANGE MQTT USER NAME AND PASSWORD BELOW ####################################  
   
    //#########################################################################################  
   
   
   
   
    if (client.connect((char*) clientName.c_str(), "newuser", "12345")) {  
   
     Serial.print("\tMQTT Connected");  
   
   
   
     client.subscribe(switchSleep);  
   
   
     client.subscribe(switchOta);    // the order in which topics are arranged here  
   
   
     // is how ESP will Subscribe and if you put  
   
     // relays first and also turn them on and ota or sleep too  
   
     // the switches will turn on momentarily untill it gets the message to sleep or ota update  
   
     client.subscribe(switchTopic1);  
   
     client.subscribe(switchTopic2);  
   
     client.subscribe(switchTopic3);  
   
     client.subscribe(switchTopic4);  
   
     // ##**************************######## Add MORE TOPICS FOR SWITCHES HERE  #####################  
   
   
    }  
   
   
    else  
    {  
     Serial.println("\tFailed.");  
   
     delay(2000);  
   
     break;  
   
    }  
   
   }  
   
  }  
   
 }  
   
   
   
   
   
 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;  
 }