parere su codice comando punto luce

Buonasera a tutti,

sto provando un punto luce con una wemos d1 mini, comandata via mqtt, vi allego il codice, al momento funziona, ho solo un problema, quando perde la connessione wifi, diventa quasi impossibile accendere la luce e quando riprende il wifi, la spegne se è accesa.

accetto consigli e modifiche al programma, grazie a tutti

//  
// lettura temperatura umidita e comando luce
//  wemos d1 mini  soggiorno
// pin rele D1 --> 5
// pin dht D4 --> 2
//pin input D5 --> 14

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <DHT.h>
                    
#define DHTPIN 2
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE, 20);

const char* ssid = "linksys";
const char* password = "YourPASS";
const char* mqtt_server = "192.168.1.60";
long previousMillis = 0;
long interval = 60000;

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* outTopic = "home/soggiorno/stato/output/1";
const char* inTopic = "home/soggiorno/luce";
const char* outTopic_dht_temp = "home/soggiorno/temperatura";
const char* outTopic_dht_umid = "home/soggiorno/umidita";
const char* outIP = "home/soggiorno/ip";

int relay_pin = 5;
int button_pin = 14;
bool relayState = LOW;

// Instantiate a Bounce object :
Bounce debouncer = Bounce(); 

void setup_wifi() {

  delay(10);
  WiFi.begin(ssid);

  while (WiFi.status() != WL_CONNECTED) {
    extButton();
    for(int i = 0; i<500; i++){
      extButton();
      delay(1);
    }
    Serial.print(".");
  }
}

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

  // Switch on the Light if an 1 was received as first character
  if ((char)payload[0] == '1') {
    if (relayState == LOW){
      digitalWrite(relay_pin, HIGH);   // Turn the Light on
      relayState = HIGH;
      client.publish(outTopic, "1");
   }
      else if (relayState == HIGH) {
        digitalWrite(relay_pin, LOW);   // Turn the Light off
        relayState = LOW;
        client.publish(outTopic, "0");
    }
  
  } else if ((char)payload[0] == '0') {
    digitalWrite(relay_pin, LOW);  // Turn the Light off 
    relayState = LOW;
    client.publish(outTopic, "0");
  } 
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Soggiorno2")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(outTopic, "py-home-slave booted");
      // ... and resubscribe
      client.subscribe(inTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      for(int i = 0; i<5000; i++){
        extButton();
        delay(1);
      }
    }
  }
}

void extButton() {
  debouncer.update();
   
   // Call code if Bounce fell (transition from HIGH to LOW) :
   if ( debouncer.fell() ) {
     relayState = !relayState;
     digitalWrite(relay_pin,relayState);
     if (relayState == 1){
      client.publish(outTopic, "1");
     }
     else if (relayState == 0){
      client.publish(outTopic, "0");
     }
   }
}

void read_dht(){
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
  float h = dht.readHumidity();
  float f = dht.readTemperature();
  if (isnan(h) || isnan(f)) {
          Serial.println("Failed to read from DHT sensor!");
          return;
        }
  previousMillis = currentMillis;
      
  
 // Serial.println("DHT sensor read and transmitted");
  char buffer[10];
  dtostrf(f,2,2, buffer);
  client.publish(outTopic_dht_temp,buffer);
  dtostrf(h,2,2, buffer);
  client.publish(outTopic_dht_umid,buffer);
  client.publish(outIP, WiFi.localIP().toString().c_str());
  }
}
 

void setup() {
  dht.begin();
  pinMode(relay_pin, OUTPUT);     // Initialize the relay pin as an output
  pinMode(button_pin, INPUT);     // Initialize the relay pin as an input
  digitalWrite(relay_pin,relayState);
  
  debouncer.attach(button_pin);   // Use the bounce2 library to debounce the built in button
  debouncer.interval(50);         // Input must be low for 50 ms
  
  Serial.begin(115200);
  setup_wifi();                   // Connect to wifi 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  
  // START OTA
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
//END OTA
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  ArduinoOTA.handle();
  client.loop();
  extButton();
  read_dht();
}

Beh, quando riconnette tu riesegui la extButton() che non fa che interrogare il bottone per una pressione.
Ma se non c'e' non fa nulla. E comunque entrasse nel if( debouncer.fell()) ti invertirebbe il rele.
Dovresti fare un'altra funzione tipo extButton ma che fa solo la digitalWrite(relay_pin,relayState);
e forse il client.publish che non so a cosa serve (mqtt forse?)
Oppure (ma non conosco mqtt) dovresti interrogare (se possibile) il servizio mqtt per sapere lo stato precedente.

Banalmente i numeri dei pin, int non serve a nulla e poi sono valori costanti, quindi:
const byte relay_pin = 5;

grazie per la risposta,

proverò a togliere la exButton(), anche se quando la scheda cerca di ricollegarsi non mi permette di accendere e spegnere la luce