Gracias por vuestra respuesta, os adjunto el código relacionado a esa parte que expliqué.
En cuanto a tu pregunta sobre la conexión wifi estoy seguro que se lleva a cabo ya que entra en el callback de saveWifiCallback() del propio WifiManager y a través de ese callback es cuando compruebo la conexion wifi, ajusto la hora del reloj y ya comprueba la conexion con el MQTT y la establece.
#include <WiFiManager.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
WiFiManager wm;
// Clientes WiFi y MQTT
static WiFiClientSecure wificlient;
static PubSubClient mqttclient(wificlient);
// X.509 parsed CA & Client Certs
X509List caCertX509(caCert);
X509List clientCertX509(clientCert);
PrivateKey clienteKeyX509(clientKey);
bool wifiActivado = false;
bool mqttConectado = false;
void saveWifiCallback(){
Serial.println("CALLBACK WIFI");
if(!mqttConectado){
inicia_wifi();
} else {
Serial.println("Ya se encuentra conectado a wifi y mqtt");
}
}
void setup() {
WiFi.mode(WIFI_STA);
Serial.begin(115200);
// Utilizo este resetSettings para que borre los datos de la conexión,
// y forzar que simule como si el arduino se configure por primera vez,
//de manera que tenga que volver a configurar el usuario la conexion
// con su wifi.
// Aqui es donde tengo el problema, ya que si le quito el resetSettings()
// y cargo el programa, la primera vez que configure el wifi va a fallar
// la conexion MQTT, pero simplemente volviendo a encender
// el arduino sin cargar programa ni modificando nada, coge los datos de la conexion del wifi
// guardado en el por WifiManager y con el mismo autoReconnect
// se establece la conexion perfectamente MQTT.
wm.resetSettings();
wm.setConfigPortalBlocking(false);
wm.setWiFiAutoReconnect(true);
wm.setDebugOutput(true);
wm.setSaveConfigCallback(saveWifiCallback);
bool res;
res = wm.autoConnect("WifiManagerPortal", "87654321");
if(!res) {
Serial.println("Failed to connect");
wifiActivado = false;
} else {
// Aqui vuelvo a llamar a la funcion que uso para el callback ya que
// practicamente lo que hace es comprobar la conexion y lo envia
// a la función de inicia_wifi()
saveWifiCallback();
}
}
void loop() {
wm.process();
mqttclient.loop();
yield();
if(wifiActivado){
//Revisa estado de Wifi o reintenta conexión
if (WiFi.status() != WL_CONNECTED){
inicia_wifi();
}else{
if (!mqttConectado){
Serial.println("NO SE TIENE MQTT CONECTADO Y SE VUELVE A CONECTAR");
mqttclient.disconnect();
inicia_mqtt(); // reintento
}
}
}
}
void inicia_wifi(){
//int intentos = 5;
//int cuenta = 0;
while (WiFi.status() != WL_CONNECTED)//&& (cuenta < intentos)
{
Serial.println("CONECTANDO WIFI... ");
//cuenta = cuenta+1;
delay(1000);
Serial.print(".");
}
if(WiFi.status() == WL_CONNECTED){
timeClient.begin();
delay ( 1000 );
if (timeClient.update()){
Serial.println ( "Adjust local clock" );
unsigned long epoch = timeClient.getEpochTime();
setTime(epoch);
}else{
Serial.println ( "NTP Update not WORK!!" );
}
Serial.println("WIFI conectado con exito! ");
inicia_mqtt();
} else {
Serial.println("Sin conexion wifi");
}
}
void inicia_mqtt() {
int intentos = 5;
int cuenta = 0;
wifiActivado = true;
// Configura cliente TLS
// añade CA cert en los sitios de confianza
wificlient.setTrustAnchors(&caCertX509);
// Habilita self-signed cert
wificlient.allowSelfSignedCerts();
// añade fingerprint para validar conexión
wificlient.setFingerprint(mqttCertFingerprint);
// le envia el certif icado de cliente (lo solicita el servidor)
wificlient.setClientRSACert(&clientCertX509, &clienteKeyX509);
mqttclient.setServer(MQTT_IP, MQTT_puerto);
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
mqttclient.connect(clientId.c_str());
mqttclient.setBufferSize(512);
mqttclient.setCallback(callback);
Serial.print(" MQTT Conectando a ");
Serial.println(MQTT_IP);
while (!mqttclient.connected()&&(cuenta<=intentos)){
cuenta = cuenta + 1;
delay(1000);
Serial.print(".");
}
Serial.println("");
if(mqttclient.connected()){
Serial.println("Mqtt Conectado con exito!");
Serial.println(mqttclient.state());
mqttConectado = true;
} else {
Serial.print("failed, rc=");
Serial.print(mqttclient.state());
Serial.println("Sin conexion con Mqtt");
mqttConectado = false;
Serial.println("EL MQTT CONECTADO ES FALSE Y DEBE ENTRAR OTRA VEZ");
}
}
Os dejo los logs para que podais entender visualmente un poco mejor el flujo:
** Primera vez que se carga el programa en arduino o con el uso del wm.resetsettings() para formar esa primera conexión que es la que da fallo: **
*wm: ID_MQTT
AUTO RECONNECTED O CALLBACK WIFI
Adjust local clock
WIFI conectado con exito!
MQTT Conectando a ID_MQTT
......
failed, rc=-2Sin conexion con Mqtt
EL MQTT CONECTADO ES FALSE Y DEBE ENTRAR OTRA VEZ
NO SE TIENE MQTT CONECTADO Y SE VUELVE A CONECTAR
MQTT Conectando a ID_MQTT
......
failed, rc=-2Sin conexion con Mqtt
EL MQTT CONECTADO ES FALSE Y DEBE ENTRAR OTRA VEZ
NO SE TIENE MQTT CONECTADO Y SE VUELVE A CONECTAR
MQTT Conectando a ID_MQTT
......
failed, rc=-2Sin conexion con Mqtt
EL MQTT CONECTADO ES FALSE Y DEBE ENTRAR OTRA VEZ
NO SE TIENE MQTT CONECTADO Y SE VUELVE A CONECTAR
// Así en bucle ya que no consigue conectar
Esto genera los siguientes logs en mi servidor mosquitto:
1712640217: New connection from IP_ARDUINO:54809 on port 8883.
1712640223: OpenSSL Error[0]: error:0A000126:SSL routines::unexpected eof while reading
1712640223: Client <unknown> disconnected: protocol error.
1712640223: New connection from IP_ARDUINO:55978 on port 8883.
1712640229: OpenSSL Error[0]: error:0A000126:SSL routines::unexpected eof while reading
1712640229: Client <unknown> disconnected: protocol error.
Los siguientes logs son para la situación que os indicaba, se comenta en el código el resetSettings() para que guarde la conexión. La primera vez que entra y se configura pasa lo mismo que lo comentado arriba (mismos logs ya que sigue siendo la primera vez que entra y se configura), pero aqui simplemente ya no se borran esos datos y REINICIO el arduino para que coja los datos ya guardados anteriormente de WifiManager:
*wm:v2.0.17 D:2
*wm:AutoConnect
*wm:Connecting to SAVED AP: MI_RED_WIFI
*wm:connectTimeout not set, ESP waitForConnectResult...
*wm:AutoConnect: SUCCESS
*wm:STA IP Address: 192.168.X.X
Adjust local clock
WIFI conectado con exito!
MQTT Conectando a 192.168.X.X
Mqtt Conectado con exito!
Y en los logs de mi servidor mosquitto se puede ver que funcionó todo correcto:
1712641764: New connection from 192.168.X.X:61741 on port 8883.
1712641772: New client connected from 192.168.X.X:61741 as ESP8266Client-3f8b (p2, c1, k15, u'cliente').
1712641772: No will message specified.
1712641772: Sending CONNACK to ESP8266Client-3f8b (0, 0)
1712641772: Received SUBSCRIBE from ESP8266Client-3f8b
1712641787: Received PINGREQ from ESP8266Client-3f8b
1712641787: Sending PINGRESP to ESP8266Client-3f8b
1712641802: Received PINGREQ from ESP8266Client-3f8b
1712641802: Sending PINGRESP to ESP8266Client-3f8b
Es lo que os comentaba, solo falla la primera vez que se configura (ya sea la primera carga del programa o siempre y cuando que obligue con el resetSettings() a configurar de nuevo esa conexión), todas las demás veces que se vuelva a cargar o se reinicie con esa conexión Wifi cargada, no hay ningun problema y funciona todo perfectamente.
Gracias de antemano!