problem with button and mqtt after restart gateway



  • Hello everyone.

    I am a beginner 😉
    Based on the sketch from this forum, I wrote my own with control the switches, one button and a temperature sensor.
    If it i turn led on/off from HA, the state is written in eeprom and mqtt . However, if you control it with the button, state changes in HA (everything seems ok) but after restarting the gateway, the state is correct for a while (read from epreom I think), but after establishing the connection to the broker, led is switch to state is as the last one in HA (by clik).

    // Enable debug prints to serial monitor
    //#define MY_DEBUG
    
    // Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
    #define MY_BAUD_RATE 9600
    
    // Enables and select radio type (if attached)
    //#define MY_RADIO_RF24
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #define MY_GATEWAY_MQTT_CLIENT
    #define MY_GATEWAY_ESP8266
    
    // Set this node's subscribe and publish topic prefix
    #define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
    #define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
    
    // Set MQTT client id
    #define MY_MQTT_CLIENT_ID "mysensors-1"
    
    // Enable these if your MQTT broker requires username/password
    #define MY_MQTT_USER "***"
    #define MY_MQTT_PASSWORD "***"
    
    // Set WIFI SSID and password
    #define MY_WIFI_SSID "***"
    #define MY_WIFI_PASSWORD "***"
    
    // Set the hostname for the WiFi Client. This is the hostname
    // passed to the DHCP server if not static.
    #define MY_HOSTNAME "ESP8266_MQTT_GW"
    
    // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
    //#define MY_IP_ADDRESS 192,168,178,87
    
    // If using static ip you can define Gateway and Subnet address as well
    //#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
    //#define MY_IP_SUBNET_ADDRESS 255,255,255,0
    
    // MQTT broker ip address.
    #define MY_CONTROLLER_IP_ADDRESS 192, 168, 1, 100
    
    //MQTT broker if using URL instead of ip address.
    // #define MY_CONTROLLER_URL_ADDRESS "test.mosquitto.org"
    
    // The MQTT broker port to to open
    #define MY_PORT 1883
    
    // Enable inclusion mode
    //#define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    //#define MY_INCLUSION_BUTTON_FEATURE
    // Set inclusion mode duration (in seconds)
    //#define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    //#define MY_INCLUSION_MODE_BUTTON_PIN D1
    
    // Set blinking period
    //#define MY_DEFAULT_LED_BLINK_PERIOD 300
    
    // Flash leds on rx/tx/err
    //#define MY_DEFAULT_ERR_LED_PIN 16  // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN  16  // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN  16  // the PCB, on board LED
    
    
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <DHT.h>
    
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN D5
    #define DHTTYPE DHT11     // typ czujnika (DHT11). Jesli posiadamy DHT22 wybieramy DHT22
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    
    #define CHILD_ID_HUM 3
    #define CHILD_ID_TEMP 4
    #define CHILD_ID_LIGHT 5
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    //czyjnik światła
    int lastodczytanaWartosc = 0;
    
    DHT dht(DHT_DATA_PIN, DHTTYPE);
    #define RELAY_ON 0                      // switch around for ACTIVE LOW / ACTIVE HIGH relay
    #define RELAY_OFF 1
    
    
    #define noRelays 3                     //2-4
    #define noButtons 1 
    const int relayPin[] = {D2,D3,D6};          //  switch around pins to your desire
    const int buttonPin[] = {D1};      //  switch around pins to your desire
    
    class Relay             // relay class, store all relevant data (equivalent to struct)
    {
    public:                                      
      int buttonPin;                   // physical pin number of button
      int relayPin;             // physical pin number of relay
      int value;
      boolean relayState;               // relay status (also stored in EEPROM)
    };
    
    
    Relay Relays[noRelays]; 
    Bounce debouncer[noRelays];
    MyMessage msg[noRelays];
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgIlu(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    
    
    void setup(){
        sendHeartbeat();
        wait(100);
    
        dht.begin(); 
        
        // Initialize Relays
        for (int i = 0; i < noRelays; i++){
       // Relays[i].buttonPin = buttonPin[i];              // assign physical pins
        Relays[i].relayPin = relayPin[i];
        msg[i].sensor = i;                                   // initialize messages
        msg[i].type = V_LIGHT;   
       // pinMode(Relays[i].buttonPin, INPUT_PULLUP);
       // wait(100);
        pinMode(Relays[i].relayPin, OUTPUT);
        Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
        digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
        send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
        wait(50);
        //debouncer[i] = Bounce();                        // initialize debouncer
        //debouncer[i].attach(buttonPin[i]);
        //debouncer[i].interval(20);
        //wait(50);
        }
         // Initialize Button
        for (int i = 0; i < noButtons; i++){
        Relays[i].buttonPin = buttonPin[i];              // assign physical pins
        //msg[i].sensor = i;                                   // initialize messages
        //msg[i].type = V_LIGHT;   
        pinMode(Relays[i].buttonPin, INPUT_PULLUP);
        wait(100);
        //pinMode(Relays[i].relayPin, OUTPUT);
        //Relays[i].relayState = loadState(i);                               // retrieve last values from EEPROM
        //digitalWrite(Relays[i].relayPin, Relays[i].relayState? RELAY_ON:RELAY_OFF);   // and set relays accordingly
        //send(msg[i].set(Relays[i].relayState? true : false));                  // make controller aware of last status  
        //wait(50);
        debouncer[i] = Bounce();                        // initialize debouncer
        debouncer[i].attach(buttonPin[i]);
        debouncer[i].interval(20);
        wait(50);
        }
    }
    void presentation()  {
          
          sendSketchInfo("MultiRelayButton", "1.0");
          wait(100);
          for (int i = 0; i < noRelays; i++){
          present(i, S_LIGHT);                               // present sensor to gateway
          }
          
    // Register all sensors to gw (they will be created as child devices)
         present(CHILD_ID_HUM, S_HUM);
         present(CHILD_ID_TEMP, S_TEMP);
         wait(100);
    
         present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
         wait(100);
    }
    void loop()
    {
      // pomiar światła
      int odczytanaWartosc = analogRead(A0);
        if (odczytanaWartosc != lastodczytanaWartosc) {
            send(msgIlu.set(odczytanaWartosc));
            lastodczytanaWartosc = odczytanaWartosc;
        }
        sleep(30000);
      // Get temperature from DHT library
      float temperature = dht.readTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
    
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.readHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
        
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL); 
    
      // relay&button
        for (byte i = 0; i < noRelays; i++) {
            if (debouncer[i].update()) {
                Relays[i].value= debouncer[i].read();
                if(Relays[i].value == LOW){
                  saveState(i, !loadState(i));
                  digitalWrite(Relays[i].relayPin, loadState(i)?RELAY_ON:RELAY_OFF);
                  send(msg[i].set(loadState(i)));
                  //send(msg[i].set(Relays[i].relayState? true : false));
                  // save sensor state in EEPROM (location == sensor number)
                  //saveState( i, Relays[i].relayState );
            }                 
        }
        wait(20);
    }}
    // process incoming message 
    void receive(const MyMessage &message){        
       if (message.type == V_LIGHT){ 
       if (message.sensor <noRelays){            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
       Relays[message.sensor].relayState = message.getBool(); 
       digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState? RELAY_ON:RELAY_OFF); // and set relays accordingly
       saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
       }
      }
      wait(20);
    }
    

    What am I doing wrong? 😄
    please help


  • Contest Winner

    This post is deleted!

Log in to reply
 

Suggested Topics

  • 3
  • 6
  • 12
  • 1
  • 11
  • 11
  • 3
  • 7

213
Online

10.3k
Users

10.7k
Topics

109.8k
Posts