Hi,
I have an ESP32 logging data from my energy meter to an MQTT broker running on my Synology NAS. If I reboot my NAS or disconnect the ethernet, the ESP stop sending new data and I have to reboot the ESP to get it going again. I have programmed the onboard LED to indicate when it's sending data, and it is still flashing. I would like the ESP to resolve the connection loss automatically.
// HAN Reader/Parser for AMS meter.
// Tested on Kaifa MA105H2E
// Not tested on Kaifa 3-phase meter
//
// NodeMCU-32S
// UART2 RX = RX2, TX = TX2
#include <WiFi.h>
#include <ArduinoMqttClient.h>
#include <ArduinoJson.h>
#include <Arduino.h>
#include <ArduinoOTA.h>
#include <TON.h>
#include <AMS.h>
#include <CREDENTAILS.h>
AMS meter;
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASS;
const char broker[] = "192.168.0.199";
int port = 1883;
WiFiClient espClient;
MqttClient mqttClient(espClient);
const char topic_AMS[] = "AMS";
void setup() {
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, LOW);
Serial2.begin(2400);
//Serial.swap(); // Use UART2 for ESP8266
setup_wifi();
setup_ota();
mqttClient.connect(broker, port);
}
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
delay(5000);
ESP.restart();
}
}
void loop() {
if (Serial2.available() > 0){
uint8_t data = Serial2.read();
uint8_t list = meter.han(data);
if(list != 0){
digitalWrite(BUILTIN_LED, HIGH);
DynamicJsonDocument doc(1024);
switch(list){
case 0x1:
doc["TS"] = meter.epoch;
doc["ECH"] = meter.wh;
doc["PAP"] = meter.powerPositiveActive;
break;
case 0x12:
doc["TS"] = meter.epoch;
doc["ECH"] = meter.wh;
doc["PAP"] = meter.powerPositiveActive;
doc["PAN"] = meter.powerNegativeActive;
doc["PRP"] = meter.powerPositiveReactive;
doc["PRN"] = meter.powerNegativeReactive;
doc["L1C"] = meter.L1current;
doc["L1V"] = meter.L1voltage;
doc["OBIS"] = meter.OBIS_ver;
doc["M_ID"] = meter.meterID;
doc["M_Typ"] = meter.meterType;
break;
case 0x13:
doc["TS"] = meter.epoch;
doc["ECH"] = meter.wh;
doc["PAP"] = meter.powerPositiveActive;
doc["PAN"] = meter.powerNegativeActive;
doc["PRP"] = meter.powerPositiveReactive;
doc["PRN"] = meter.powerNegativeReactive;
doc["L1C"] = meter.L1current;
doc["L1V"] = meter.L1voltage;
doc["EAP"] = meter.energyPositiveActive;
doc["EAN"] = meter.energyNegativeActive;
doc["ERP"] = meter.energyPositiveReactive;
doc["ERN"] = meter.energyNegativeReactive;
//doc["OBIS"] = meter.OBIS_ver;
//doc["M_ID"] = meter.meterID;
//doc["M_Typ"] = meter.meterType;
break;
case 0x32:
doc["TS"] = meter.epoch;
doc["ECH"] = meter.wh;
doc["PAP"] = meter.powerPositiveActive;
doc["PAN"] = meter.powerNegativeActive;
doc["PRP"] = meter.powerPositiveReactive;
doc["PRN"] = meter.powerNegativeReactive;
doc["L1C"] = meter.L1current;
doc["L1V"] = meter.L1voltage;
doc["L2C"] = meter.L2current;
doc["L2V"] = meter.L2voltage;
doc["L3C"] = meter.L3current;
doc["L3V"] = meter.L3voltage;
doc["OBIS"] = meter.OBIS_ver;
doc["M_ID"] = meter.meterID;
doc["M_Typ"] = meter.meterType;
break;
case 0x33:
doc["TS"] = meter.epoch;
doc["ECH"] = meter.wh;
doc["PAP"] = meter.powerPositiveActive;
doc["PAN"] = meter.powerNegativeActive;
doc["PRP"] = meter.powerPositiveReactive;
doc["PRN"] = meter.powerNegativeReactive;
doc["L1C"] = meter.L1current;
doc["L1V"] = meter.L1voltage;
doc["L2C"] = meter.L2current;
doc["L2V"] = meter.L2voltage;
doc["L3C"] = meter.L3current;
doc["L3V"] = meter.L3voltage;
doc["EAP"] = meter.energyPositiveActive;
doc["EAN"] = meter.energyNegativeActive;
doc["ERP"] = meter.energyPositiveReactive;
doc["ERN"] = meter.energyNegativeReactive;
//doc["OBIS"] = meter.OBIS_ver;
//doc["M_ID"] = meter.meterID;
//doc["M_Typ"] = meter.meterType;
break;
default:
break;
}
uint8_t buff[1024];
size_t n = serializeJson(doc, buff);
mqttClient.beginMessage(topic_AMS);
mqttClient.write(buff, n);
mqttClient.endMessage();
digitalWrite(BUILTIN_LED, LOW);
}
}
ArduinoOTA.handle();
mqttClient.poll();
}
void setup_ota(){
ArduinoOTA.setHostname("AMS_ESP32");
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()
});
ArduinoOTA.onEnd([]() {
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
});
ArduinoOTA.onError([](ota_error_t error) {
if (error == OTA_AUTH_ERROR) {
} else if (error == OTA_BEGIN_ERROR) {
} else if (error == OTA_CONNECT_ERROR) {
} else if (error == OTA_RECEIVE_ERROR) {
} else if (error == OTA_END_ERROR) {
}
});
ArduinoOTA.begin();
ArduinoOTA.handle();
}