Ардуино Реле и Homeasistant

mrkolea
Offline
Зарегистрирован: 02.09.2020

Всем привет, есть такая дилема может ктото сталкивался с такой проблеммой, Ардуино настроенно под 4 реле
, в Homeassistant тоже введены все топики, связь между ними брокер Mqtt  всё вроде работает, вот только если Ардуино выключаеться то потом начинаеться вакханалия, ардуино выключенна но в HomeAssistant рубилник от реле остаёться включённым потом при включение Ардуинки идёт сдвиг и включаеться рандомный реле.
Вопрос как можно скидывать положение рубильника если ардуино отключенна?

mrkolea
Offline
Зарегистрирован: 02.09.2020
//ESP8266 Simple MQTT switch controller


#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>
#include <SoftwareSerial.h>;
#include "DHT.h"
#include "Relay.h"

//MH-Z19 DETAILS
SoftwareSerial CO2Sensor(D7, D8); // D7 -> Tx PIN, D8 -> Rx PIN
byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; 
unsigned char response[9];




void callback(char* topic, byte* payload, unsigned int length);

//EDIT THESE LINES TO MATCH YOUR SETUP
#define MQTT_SERVER "111"  //your MQTT IP Address
#define mqtt_user "111" 
#define mqtt_password "1111"
#define mqtt_port "1883"



//DHT DETAILS
#define DHTPIN D6 
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);


const char* ssid = "111";
const char* password = "111";



const int switchPin1 = D2;
const int switchPin2 = D3;
const int switchPin3 = D4;
const int switchPin4 = D5;
Relay switch1(switchPin1,true);
Relay switch2(switchPin2,true);
Relay switch3(switchPin3,true);
Relay switch4(switchPin4,true);

char const* switchTopic1 = "/ac1/switch1/";
char const* switchTopic2 = "/ac1/switch2/";
char const* switchTopic3 = "/ac1/switch3/";
char const* switchTopic4 = "/ac1/switch4/";
#define temperature_topic "/ac1/sensor_temp1/"
#define humidity_topic "/ac1/sensor_humidity1/"
#define co2_topic "/ac1/sensor_carbonoxide1/"
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;
float co2 = 0.0;
unsigned int ppm = 0;

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

void setup() {
  CO2Sensor.begin(9600);
  dht.begin();
  switch1.begin();
  switch2.begin();
  switch3.begin();
  switch4.begin();
  //initialize the switch as an output and set to LOW (off)
  //pinMode(switchPin1, OUTPUT); // Relay Switch 1
  digitalWrite(switchPin1, HIGH);  
  //pinMode(switchPin2, OUTPUT); // Relay Switch 2
  digitalWrite(switchPin2, HIGH);
  //pinMode(switchPin3, OUTPUT); // Relay Switch 3
  digitalWrite(switchPin3, HIGH);
  //pinMode(switchPin4, OUTPUT); // Relay Switch 4
  digitalWrite(switchPin4, HIGH);


  //start the serial line for debugging
  Serial.begin(115200);
  delay(100);

  //start wifi subsystem
  WiFi.begin(ssid, password);
  //attempt to connect to the WIFI network and then connect to the MQTT server
  reconnect();
     delay(2000); 
}





  //wait a bit before starting the main loop
 





void loop(){
     //MH-Z19 START
 CO2Sensor.write(cmd, 9);
  memset(response, 0, 9);
  CO2Sensor.readBytes(response, 9);
  int i;
  byte crc = 0;
  for (i = 1; i < 8; i++) crc+=response[i];
  crc = 255 - crc;
  crc++;

  if ( !(response[0] == 0xFF && response[1] == 0x86 && response[8] == crc) ) {
    Serial.println("CRC error: " + String(crc) + " / "+ String(response[8]));
  } else {
    unsigned int responseHigh = (unsigned int) response[2];
    unsigned int responseLow = (unsigned int) response[3];
   ppm = (256*responseHigh) + responseLow;
    //(256*responseHigh) + 
  }
  //MH-Z19 END


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

  //maintain MQTT connection
  client.loop();
  
  


  //MUST delay to allow ESP8266 WIFI functions to run
  delay(10); 
  ArduinoOTA.handle();
  //DHT22
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;

    float newTemp = dht.readTemperature();
    float newHum = dht.readHumidity();
    float newCo2 = ppm;

    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      Serial.print("New temperature:");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic, String(temp).c_str(), true);
    }

    if (checkBound(newHum, hum, diff)) {
      hum = newHum;
      Serial.print("New humidity:");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic, String(hum).c_str(), true);
    }
    
    if (checkBound(newCo2, co2, diff)) {
      co2 = newCo2;
      Serial.print("New co2:");
      Serial.println(String(co2).c_str());
      client.publish(co2_topic, String(co2).c_str(), true);
   
  }
}
  
}  
void callback(char* topic, byte* payload, unsigned int length) {

  //convert topic to string to make it easier to work with
  String topicStr = topic; 
  //EJ: Note:  the "topic" value gets overwritten everytime it receives confirmation (callback) message from MQTT

  //Print out some debugging info
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);
//--------------------------------------------1 реле----------------------------------------------------------------------------


   if (topicStr == "/ac1/switch1/") 
    {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       switch1.turnOff();
       client.publish("/ac1/switchConfirm1/", "1");
        }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){  
       switch2.turnOff();
      client.publish("/ac1/switchConfirm2/", "1");
      switch3.turnOff();
      client.publish("/ac1/switchConfirm3/", "1");
      delay(700);
      switch1.turnOn(); 
    //  client.publish("/ac1/switch1/availability", "online", false);
      client.publish("/ac1/switchConfirm1/", "0");     
       
        }
     }
//----------------------------------------2 реле--------------------------------------------------------------------------
     // EJ: copy and paste this whole else-if block, should you need to control more switches
     else if (topicStr == "/ac1/switch2/") 
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       switch2.turnOff();
       client.publish("/ac1/switchConfirm2/", "1");
      }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
      switch1.turnOff();
      client.publish("/ac1/switchConfirm1/", "1");
      switch3.turnOff();
      client.publish("/ac1/switchConfirm3/", "1");
      delay(700);
      switch2.turnOn();
     // client.publish("/ac1/switch2/availability", "online", false);
      client.publish("/ac1/switchConfirm2/", "0");
      }
     }
//---------------------------------------------3 реле------------------------------------------------------------------------------     
     else if (topicStr == "/ac1/switch3/") 
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
       switch3.turnOff();
        client.publish("/ac1/switchConfirm3/", "1");
      }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
       switch1.turnOff();
      client.publish("/ac1/switchConfirm1/", "1");
      switch2.turnOff();
      client.publish("/ac1/switchConfirm2/", "1");
      delay(700);
      switch3.turnOn();
    //  client.publish("/ac1/switch3/availability", "online", false);
      client.publish("/ac1/switchConfirm3/", "0");
      }
     }
  
//------------------------------------------------4 реле----------------------------------------------------------------------------     
     else if (topicStr == "/ac1/switch4/") 
     {
     //turn the switch on if the payload is '1' and publish to the MQTT server a confirmation message
     if(payload[0] == '1'){
        switch4.turnOff();
        client.publish("/ac1/switchConfirm4/", "1");
        }

      //turn the switch off if the payload is '0' and publish to the MQTT server a confirmation message
     else if (payload[0] == '0'){
        switch4.turnOn();
        client.publish("/ac1/switchConfirm4/", "0");
        }
    } 
//callback
   }




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.print("Attempting MQTT connection...");

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

      //if connected, subscribe to the topic(s) we want to be notified about
      //EJ: Delete "mqtt_username", and "mqtt_password" here if you are not using any 
      if (client.connect((char*) clientName.c_str(),mqtt_user, mqtt_password)) {  //EJ: Update accordingly with your MQTT account 
        Serial.print("\tMQTT Connected");
        client.subscribe(switchTopic1);
        client.subscribe(switchTopic2);
        client.subscribe(switchTopic3);
        client.subscribe(switchTopic4);
        client.subscribe(temperature_topic);
        client.subscribe(humidity_topic);
        client.subscribe(co2_topic);
       
        
        //EJ: Do not forget to replicate the above line if you will have more than the above number of relay switches
      }

      //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;
}
bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}

 

mrkolea
Offline
Зарегистрирован: 02.09.2020

подключение на плате очень проста 4 Relay Module подключенна к Wemos D1 R2, + и - и от D2-D5 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

mrkolea пишет:

есть такая дилема

А дилемма-то в чём?

sadman41
Offline
Зарегистрирован: 19.10.2016

Тяни, например, вход управления реле к питанию через резистор.