How to use TASMOTA inside BLYNK and HOME ASSISTANT [Work in Progress]

NODE_MQTT_PIR_TEMP.ino

  #include <ESP8266WiFi.h>
  #include <ESP8266mDNS.h>
  #include <WiFiUdp.h>
  #include <ArduinoOTA.h>
  #include <PubSubClient.h>
  #include <ArduinoJson.h>
  
  #include <BlynkSimpleEsp8266.h>
  #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space  

  #include "Settings.h"
  #include "mqtt_publish.h"
  #include "timer.h"    
  #include "mqtt_subscribe.h"    
  #include "wifi_credentials.h"
/*-------------------------------- Setup -------------------------------------*/
  void setup() {
    WiFi.mode(WIFI_STA);
    Serial.begin(115200);  // See the connection status in Serial Monitor
    Serial.println(F("\n Setup STARTING"));
    WiFi.begin(WIFI_SSID, WIFI_PASS);
    if(WiFi.status() == 6) Serial.println("\tWiFi not connected yet.");

//----------------------------------Blynk------------------------------------
    #ifdef LOCAL_SERVER
      Blynk.config(AUTH, LOCAL_SERVER ,8080);
    #else
      Blynk.config(AUTH, Geo_DNS_SERVER);
    #endif
    while (Blynk.connect() == false) {             // Wait until connected
      if ((millis() - last_UP_change) > 30000) {   // 30s before reset
        Serial.println(F("resetting"));
        ESP.restart();
      } 
    } 

    client.setServer(MQTT_SERVER, 1883);
    client.setCallback(callback);
//-----------------------------------OTA--------------------------------------
    ArduinoOTA.setHostname(OTA_HOSTNAME);
//  ArduinoOTA.setPassword(OTA_PASSWORD);  //If you need a Password uncomment this line
    ArduinoOTA.begin();

    Serial.println(F(" Entering loop"));
    timer.setInterval(4000L, Heartbeat);       // Heartbeat 4000L

    CountdownTimer = timer.setInterval(1000, CountdownTimerFunction);
    timer.disable(CountdownTimer); // disable it on boot

    Blynk.syncVirtual(vPIN_ON_OFF_1);
    Blynk.syncVirtual(vPIN_ON_OFF_2);
    Blynk.syncVirtual(vPIN_AUTO_MOTION);
    Blynk.syncVirtual(vPIN_NUMERIC_TIMER);

    Blynk.virtualWrite(vPIN_COUNTDOWN,  "  0:00:00" );
    Blynk.setProperty(vPIN_ON_OFF_1, "label",  String("T1 = ") + "0:00:00" + String(" S") );
    Blynk.setProperty(vPIN_PIR_LED, "label",  String ("PIR <---- ") + memory1 + String(" S") );
    Blynk.setProperty(vPIN_HEARTBEAT, "label",  String("\xF0\x9F\x92\x93") + " HEARTBEAT");
  }

/*----------------------------------Loop--------------------------------------*/

  void loop() {
    Blynk.run();
    if(!Blynk.connected()) {
      Serial.println(F("Resetting in loop"));
      ESP.restart();
    }
    timer.run();
    if (!client.connected()) {
      reconnect();
    }
    client.loop();
    ArduinoOTA.handle();
  }

/*=============================================================================*/

Settings.h

/*****************************************************************************
 *
 *                             Settings.h
 *
 *****************************************************************************/


/*---------------------------Blynk Auth Code----------------------------------*/
  #define AUTH   "*******************************************" // NodeMCU

 /*-------------------------Over The Air Hostname------------------------------*/

  #define OTA_HOSTNAME          "N-MQTT_Bridge"   // put here your host name
  #define OTA_PASSWORD          "blynk"     // your password for OTA if needed

/*----------------------------Hardware Pins-----------------------------------*/
                             /*-NodeMCU#*/

/*-------------------------------Virtual Pins---------------------------------*/
   
  #define vPIN_HEARTBEAT          V0
  #define vPIN_DS18B20_1_TEMP     V1
  #define vPIN_DS18B20_2_TEMP     V2
  #define vPIN_DS18B20_3_TEMP     V3
  #define vPIN_DS18B20_4_TEMP     V4
  #define vPIN_AM2301_TEMP        V5
  #define vPIN_AM2301_HUM         V6
  #define vPIN_SR04_DIST          V7
  #define vPIN_PIR_LED            V8
  #define vPIN_TEMP_UNIT          V9

  #define vPIN_HUM                V10
  #define vPIN_ALL_TEMP           V11

  #define vPIN_ON_OFF_1           V21     // ON/OFF POWER 1  Activated by Motion (Tasmota Rule1 & Rule2)
  #define vPIN_AUTO_MOTION        V22     // when motion is detected Relay1 turns on for timer sec & repeats 
  #define vPIN_NUMERIC_TIMER      V23     // up to 32767 ~9hrs
  #define vPIN_COUNTDOWN          V24     // triggered by motion countdown for timer sec and restart with each PIR trigger
  #define vPIN_AUTO_SR04          V25     // Activate/Desactivate Rule3

  #define vPIN_ON_OFF_2           V31     // ON/OFF POWER 2  Activated by Sun  
/*-----------------------------variables-------------------------------------*/

  bool  memory2 ;
  int   memory1 ;
  int   counter = 0;
  int   CountdownTimer;
  int   CountdownRemain;
  long int  last_UP_change = millis();
  
  int   rssi;
  float Vcc;
  float Distance;

mqtt_publish.h

/******************************************************************************
 *
 *                            mqtt_publish.h
 *
 *****************************************************************************/
  WiFiClient espClient;
  PubSubClient client(espClient);

  BlynkTimer timer;
//----------------------------------------------℃/℉-----------------------------------------------------------
  BLYNK_WRITE(vPIN_TEMP_UNIT) {  // Change Temp. Unit from Celsius ℃ to Fahrenheit 
    if (param.asInt()) {
      client.publish("stairs/cmnd/setoption8","1"); // Fahrenheit ℉
      Blynk.setProperty(vPIN_TEMP_UNIT, "label",String("\xf0\x9f\x8c\xa1") + "Fahrenheit ℉");
    } else {
      client.publish("stairs/cmnd/setoption8","0"); // Celcius ℃
      Blynk.setProperty(vPIN_TEMP_UNIT, "label",String("\xf0\x9f\x8c\xa1") + " Celsius ℃");
    }
  }
//---------------------------------------------POWER1----(Motion)-------------------------------------------
  BLYNK_WRITE(vPIN_ON_OFF_1) {    // ON/OFF switch
    if (param.asInt()) {
      client.publish("stairs/cmnd/POWER1","1");
    } else {
      client.publish("stairs/cmnd/POWER1","0");
    }
  }

  BLYNK_WRITE(vPIN_AUTO_MOTION) {  // AUTO/Manual
    if (param.asInt()) {
      client.publish("stairs/cmnd/mem2","1");
      Blynk.setProperty(vPIN_AUTO_MOTION, "label",String("\xF0\x9F\x92\xAB") + "    AUTO    PIR");
      memory2 = 1;
    } else {
      client.publish("stairs/cmnd/mem2","0");
      Blynk.setProperty (vPIN_AUTO_MOTION, "label",String("\xE2\x9C\x8B") + "    MANUAL    PIR");
      memory2 = 0;
      CountdownRemain = 1;
    }
  }

  BLYNK_WRITE(vPIN_NUMERIC_TIMER) { // TIMER 0-300 Sec  up to 32767sec [9hr:06min:07sec] 
   int VALUE = param.asInt();
    char value[4];
    dtostrf(VALUE, 3, 0, value);
    client.publish("stairs/cmnd/Mem1", value);
    Blynk.setProperty(vPIN_PIR_LED, "label",  String("PIR <---- ") + value + String(" S") );
    if (memory2 == 1) { 
      client.publish("stairs/cmnd/POWER1", "ON");
    } else {
      CountdownRemain = 1;
    }
  }
//-----------------------------------------------SR04---------------------------------------------------
  BLYNK_WRITE(vPIN_AUTO_SR04) {  // AUTO/Manual
    if (param.asInt()) {
      client.publish("stairs/cmnd/Rule3","1");
      Blynk.setProperty(vPIN_AUTO_SR04, "label",String("\xF0\x9F\x92\xAB") + "    AUTO    SR04");
    } else {
      client.publish("stairs/cmnd/Rule3","0");
      Blynk.setProperty (vPIN_AUTO_SR04, "label",String("\xE2\x9C\x8B") + "    MANUAL    SR04");
    }
  }
//---------------------------------------------POWER2----(Sun)-------------------------------------------
  BLYNK_WRITE(vPIN_ON_OFF_2) {    // ON/OFF switch
    if (param.asInt()) {
      client.publish("stairs/cmnd/POWER2","1");
    } else {
      client.publish("stairs/cmnd/POWER2","0");
    }
  }

/*--------------------------------Heartbeat--------------------------------*/

  void Heartbeat() {
    Blynk.virtualWrite(vPIN_HEARTBEAT,"    \xF0\x9F\x92\x96"); //  
timer.setTimeout(2000L,[](){Blynk.virtualWrite(vPIN_HEARTBEAT,"    \xF0\x9F\x92\x97");}); 
    }

/*--------------------------------------------------------------------------*/

mqtt_subscribe.h

/*******************************************************************************
 *
 *                            mqtt_subscribe.h
 *
 ******************************************************************************/
  #define MQTT_SERVER        IPAddress(192,168,xxx,xxx) // Your MQTT Broker IP address
  #define MQTT_USERNAME      "xxxx"   // put here your MQTT username
  #define MQTT_PASSWORD      "xxxx"    // put here your MQTT password
  
  #define InTOPIC_0          "stairs/tele/STATE" 
  #define InTOPIC_1          "stairs/tele/SENSOR" 
  #define InTOPIC_2          "stairs/PIR_stairs/state" 
  #define InTOPIC_3          "stairs/stat/POWER1" 
  #define InTOPIC_4          "stairs/stat/POWER2" 
  #define InTOPIC_5          "stairs/Distance" 
  #define InTOPIC_6          "stairs/stat/RESULT" 
  

  void reconnect() {      // Loop until we're reconnected
    while (!client.connected()) {
      Serial.print(" Attempting MQTT connection...");   // Attempt to connect
      if (client.connect("DVES",MQTT_USERNAME,MQTT_PASSWORD)) {
        Serial.println("connected");
        counter = 0;     // ... and resubscribe
        client.subscribe(InTOPIC_0);
        client.subscribe(InTOPIC_1);
        client.subscribe(InTOPIC_2);
        client.subscribe(InTOPIC_3);
        client.subscribe(InTOPIC_4);
        client.subscribe(InTOPIC_5);
        client.subscribe(InTOPIC_6);
      } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 0.3 second");
        ++counter;
        if (counter > 180) ESP.reset();     // Wait .3 seconds before retrying
        delay(300);
      }
    }
  }

  void callback(char* topic, byte* payload, unsigned int length) { 
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i = 0; i < length; i++) {
      Serial.print((char)payload[i]);
    }
    Serial.println();
    Serial.println();
//-------------------------------------------STATE------------------------------------------------
//  MQT: stairs/tele/STATE = 
//  {"Time":"2019-03-18T17:56:18","Uptime":"0T18:23:11","Vcc":3.002,"SleepMode":"Dynamic",
//  "Sleep":50,"LoadAvg":19,"POWER1":"ON","POWER2":"OFF","Wifi":{"AP":1,"SSId":"BLYNK",
//  "BSSId":"48:F8:B3:84:AB:22","Channel":10,"RSSI":84,"LinkCount":6,"Downtime":"0T00:00:21"}}

    if (String(topic) == InTOPIC_0) {   // stairs/tele/STATE
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
                    Vcc = root["Vcc"];            // 3.002
                    rssi = root["Wifi"]["RSSI"];  // 84

//        const char* Time = root["Time"];          // 2019-03-18T17:56:18
//        const char* Uptime = root["Uptime"];      // 0T18:23:11
//        const char* SleepMode = root["SleepMode"];// Dynamic
//               int  Sleep = root["Sleep"];        // 50
//               int  LoadAvg = root["LoadAvg"];    // 19
//        const char* POWER1 = root["POWER1"];      // ON
//        const char* POWER2 = root["POWER2"];      // OFF
//               int  AP = root["Wifi"]["AP"];      // 1  
//        const char* SSId = root["Wifi"]["SSId"];  // BLYNK
//        const char* BSSId = root["Wifi"]["BSSId"];// 48:F8:B3:84:AB:22
//               int  Chl = root["Wifi"]["Channel"];// 10  
//               int  LC= root["Wifi"]["LinkCount"];// 6
//        const char* DT = root["Wifi"]["Downtime"];// 0T00:00:21

//-------------------------------------------SENSOR-----------------------------------------------
//MQT: stairs/tele/SENSOR = 
//{"Time":"2019-03-19T13:19:16","Switch1":"OFF","DS18B20-1":{"Id":"000006F242B1","Temperature":21.9},
//"DS18B20-2":{"Id":"000006F2B80A","Temperature":22.0},"DS18B20-3":{"Id":"00000789E508","Temperature":21.9},
//"DS18B20-4":{"Id":"8000001F18D8","Temperature":22.6},"AM2301":{"Temperature":22.0,"Humidity":68.7},
//"ADS1115":[{"A0":-1,"A1":26033,"A2":4851,"A3":4809}],"SR04":{"Distance":40.509},"TempUnit":"C"}

    }else if (String(topic) == InTOPIC_1) { // stairs/tele/SENSOR
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        const char* Time = root["Time"];                      // 2019-03-19T13:19:16
             float  DS1_T = root["DS18B20-1"]["Temperature"]; // 21.9
             float  DS2_T = root["DS18B20-2"]["Temperature"]; // 22.0
             float  DS3_T = root["DS18B20-3"]["Temperature"]; // 21.9
             float  DS4_T = root["DS18B20-4"]["Temperature"]; // 22.6
             float  Temp = root["AM2301"]["Temperature"];     // 22.0
             float  Hum = root["AM2301"]["Humidity"];         // 68.7           
             float  Dist = root["SR04"]["Distance"];          // 40.509          

//        const char* Switch1 = root["Switch1"];        // OFF
//        const char* DS1_ID = root["DS18B20-1"]["Id"]; // 000006F242B1
//        const char* DS2_ID = root["DS18B20-2"]["Id"]; // 000006F2B80A
//        const char* DS3_ID = root["DS18B20-3"]["Id"]; // 00000789E508
//        const char* DS4_ID = root["DS18B20-4"]["Id"]; // 8000001F18D8
//             float  ADS_A0 = root["ADS1115"]["A0"];   // -1
//             float  ADS_A1 = root["ADS1115"]["A1"];   // 26033
//             float  ADS_A2 = root["ADS1115"]["A2"];   // 4851
//             float  ADS_A3 = root["ADS1115"]["A3"];   // 4809
//        const char* TU = root["TempUnit"];// "C"

//        Blynk.virtualWrite(vPIN_DS18B20_1_TEMP,DS1_T);  
//        Blynk.virtualWrite(vPIN_DS18B20_2_TEMP,DS2_T);  
//        Blynk.virtualWrite(vPIN_DS18B20_3_TEMP,DS3_T);  
//        Blynk.virtualWrite(vPIN_DS18B20_4_TEMP,DS4_T);  
//        Blynk.virtualWrite(vPIN_AM2301_TEMP,Temp);  
//        Blynk.virtualWrite(vPIN_AM2301_HUM,Hum);  
//        Blynk.virtualWrite(vPIN_SR04_DIST,Dist);  
        Blynk.virtualWrite(vPIN_ALL_TEMP, (String (DS1_T,1)+"    "+String (DS2_T,1)+"    "+String (DS3_T,1)+"    "+String (DS4_T,1)+"    "+String (Temp,1)));  
        Blynk.setProperty (vPIN_ALL_TEMP, "label",String("\xf0\x9f\x8c\xa1") + "DS18B20-1         DS18B20-2         DS18B20-3         DSPROBE-4         "+String("\xf0\x9f\x8c\xa1")+"AM2302");
        Blynk.virtualWrite(vPIN_HUM,String (Hum,1)+"%"+"  "+String("\xF0\x9F\x93\xB6")+String (rssi)+"%"+"  "+String(Vcc)+"V");
        Blynk.setProperty (vPIN_HUM, "label",String("\xF0\x9F\x92\xA7")+"AM2302  Hum     "+ String (Time)+"     Vcc");

//--------------------------------------------PIR------------------------------------------------
    }else if (String(topic) == InTOPIC_2) { // stairs/PIR_stairs/state = (1/0)
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        if ((char)payload[0] == '1') { // Switch1 on LED if 1 was received as first character
          Blynk.virtualWrite(vPIN_PIR_LED,255);  
          Serial.println("PIR = ON");
          Blynk.setProperty (vPIN_AUTO_MOTION, "label",String("\xF0\x9F\x9A\x85")+ "MOTION  >>> detected");
     }else{
          Blynk.virtualWrite(vPIN_PIR_LED,0);  
          Serial.println("PIR = OFF");
          if (memory2==1) {  
            Blynk.setProperty (vPIN_AUTO_MOTION, "label",String("\xF0\x9F\x92\xAB") +  "    AUTO    PIR            ");
          } else {
            Blynk.setProperty (vPIN_AUTO_MOTION, "label",String("\xE2\x9C\x8B") + "    MANUAL    PIR              ");
          }
     }
//---------------------------------------------POWER1-----------------------------------------------
    }else if (String(topic) == InTOPIC_3) { // stairs/stat/POWER1
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        if ((char)payload[1] == 'N') {
          Blynk.virtualWrite(vPIN_ON_OFF_1,1);  
          Serial.println("POWER1 = ON");
        }else{
          Blynk.virtualWrite(vPIN_ON_OFF_1,0);  
          Serial.println("POWER1 = OFF");
        }
//----------------------------------------------POWER2----------------------------------------------
    }else if (String(topic) == InTOPIC_4) { // stairs/stat/POWER2
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        if ((char)payload[1] == 'N') {
          Blynk.virtualWrite(vPIN_ON_OFF_2,1);  
          Serial.println("POWER2 = ON");
        }else{
          Blynk.virtualWrite(vPIN_ON_OFF_2,0);  
          Serial.println("POWER2 = OFF");
        }
//--------------------------------------------------------------------------------------------
    }else if (String(topic) == InTOPIC_5) { // stairs/Distance
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        Distance = root["Distance"];           
        Blynk.virtualWrite(vPIN_SR04_DIST,Distance);  
        Blynk.setProperty (vPIN_SR04_DIST, "label", "DISTANCE in Cm");
//--------------------------------------------------------------------------------------------
//09:59:13 MQT: stairs/stat/RESULT = {"T1":30,"T2":0,"T3":0,"T4":0,"T5":0,"T6":0,"T7":0,"T8":0}
//10:01:05 MQT: stairs/stat/RESULT = {"POWER1":"ON"}
//10:01:40 MQT: stairs/stat/RESULT = {"POWER1":"OFF"}
//10:04:11 MQT: stairs/stat/RESULT = {"Mem1":"20_"}

    }else if (String(topic) == InTOPIC_6) { //stairs/stat/RESULT
      StaticJsonBuffer<450> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject((char*)payload);
        int memory1 = root["Mem1"];
        int T1 = root["T1"];
        const char* POWER1 = root["POWER1"]; // "OFF"

        if ( memory1 > 0) {
          Blynk.setProperty(vPIN_PIR_LED, "label",  String("PIR ") + memory1 + String(" S") );
          CountdownRemain =  memory1;
          Serial.print("memory1 = "); Serial.print(memory1); Serial.println(" Sec");
          Serial.println(CountdownRemain);
          if (CountdownRemain) { // check if there is a time set or not
            CountdownShowFormatted(CountdownRemain);
            timer.enable(CountdownTimer);
          }
        }  

        if ( T1 > 0) {
          Blynk.setProperty(vPIN_PIR_LED, "label",  String("PIR ") + T1 + String(" S") );
          CountdownRemain =  T1;
          if (CountdownRemain) { // check if there is a time set or not
            CountdownShowFormatted(CountdownRemain);
            timer.enable(CountdownTimer);
          }
        }  
    }     
  }

timer.h

/*******************************************************************************
 *
 *                                timer.h
 *
 *******************************************************************************/
  void CountdownShowFormatted(int seconds) {
    long hours = 0;
    long mins = 0;
    long secs = 0;
    String secs_o = ":";
    String mins_o = ":";
    secs = seconds; // set the seconds remaining
    mins = secs / 60; //convert seconds to minutes
    hours = mins / 60; //convert minutes to hours
    secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max
    mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max
    if (secs < 10) {
      secs_o = ":0";
    }
    if (mins < 10) {
      mins_o = ":0";
    }
    if (memory2 == 1){
    Blynk.virtualWrite(vPIN_COUNTDOWN,  String("  ")+ hours + mins_o + mins + secs_o + secs);
    Blynk.setProperty(vPIN_ON_OFF_1, "label", String("\xE2\x8F\xB3") +  String("T1 = ") + hours + mins_o + mins + secs_o + secs + String(" S"));
    } else {
      Blynk.virtualWrite(vPIN_COUNTDOWN, "  0:00:00");
      Blynk.setProperty(vPIN_ON_OFF_1, "label",  String("T1 = ") + "0:00:00" + String(" S") );
    }
  }

  void CountdownTimerFunction() {
    CountdownRemain--;              // remove 1 every second
    CountdownShowFormatted(CountdownRemain);
    if (!CountdownRemain) {   // check if CountdownRemain == 0/FALSE/LOW
      timer.disable(CountdownTimer);     // if 0 stop timer
      if (memory2 == 1) { 
        Blynk.setProperty(vPIN_ON_OFF_1, "label",  String("T1 = ") + "0:00:00" + String(" S") );
        client.publish("stairs/cmnd/POWER1", "0");
      }
    }   
  }

wifi_credentials.h

/*******************************************************************************
 *
 *                          wifi_credentials.h
 *
 ******************************************************************************/

/*******************************************************************************
Local Blynk Server Settings (uncomment to use local server and set address)
*******************************************************************************/

  #define WIFI_SSID          "xxxx"       // ["xxxx"   PW = "xxxx" ]
  #define WIFI_PASS          "xxxx"       //Set pass to "" for open networks.
//#define LOCAL_SERVER       IPAddress(192, 168,xxx, xxx)  //your Local IP Server
  #define Geo_DNS_SERVER     IPAddress(xxx, xxx, xxx, xxx) //FRANKFURT

  • Put all files in the same Folder

all%20files%20in%20same%20folder

2 Likes