From ad820fff019d2b3d752b6ae8d83fa64828b9350f Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 11 Feb 2020 11:04:37 +0100 Subject: [PATCH 01/11] Allow other services to get resources while trying to connect to mqtt --- src/AmsToMqttBridge.ino | 58 ++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 1e62e723..64f003be 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -73,7 +73,7 @@ void setup() { setupWiFi(); if(config.mqttHost) { - mqtt.begin(config.mqttHost, *client); + mqtt.begin(config.mqttHost, config.mqttPort, *client); // Notify everyone we're here! sendMqttData("Connected!"); @@ -297,8 +297,17 @@ void WiFi_connect() { // Function to connect and reconnect as necessary to the MQTT server. // Should be called in the loop function and it will take care if connecting. -void MQTT_connect() -{ + +unsigned long lastMqttRetry = -10000; +void MQTT_connect() { + if(!config.mqttHost) { + if(debugger) debugger->println("No MQTT config"); + return; + } + if(millis() - lastMqttRetry < 5000) { + return; + } + lastMqttRetry = millis(); if(debugger) { debugger->print("Connecting to MQTT: "); debugger->print(config.mqttHost); @@ -306,40 +315,23 @@ void MQTT_connect() debugger->print(config.mqttPort); debugger->println(); } - // Wait for the MQTT connection to complete - while (!mqtt.connected()) { - // Connect to a unsecure or secure MQTT server - if ((config.mqttUser == 0 && mqtt.connect(config.mqttClientID)) || - (config.mqttUser != 0 && mqtt.connect(config.mqttClientID, config.mqttUser, config.mqttPass))) - { - if (debugger) debugger->println("\nSuccessfully connected to MQTT!"); + // Connect to a unsecure or secure MQTT server + if ((config.mqttUser == 0 && mqtt.connect(config.mqttClientID)) || + (config.mqttUser != 0 && mqtt.connect(config.mqttClientID, config.mqttUser, config.mqttPass))) { + if (debugger) debugger->println("\nSuccessfully connected to MQTT!"); - // Subscribe to the chosen MQTT topic, if set in configuration - if (config.mqttSubscribeTopic != 0 && strlen(config.mqttSubscribeTopic) > 0) - { - mqtt.subscribe(config.mqttSubscribeTopic); - if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.mqttSubscribeTopic); - } + // Subscribe to the chosen MQTT topic, if set in configuration + if (config.mqttSubscribeTopic != 0 && strlen(config.mqttSubscribeTopic) > 0) { + mqtt.subscribe(config.mqttSubscribeTopic); + if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.mqttSubscribeTopic); } - else - { - if (debugger) - { - debugger->print("."); - debugger->print("failed, "); - debugger->println(" trying again in 5 seconds"); - } - - // Wait 2 seconds before retrying - mqtt.disconnect(); - - delay(2000); + } else { + if (debugger) { + debugger->print(" failed, "); + debugger->println(" trying again in 5 seconds"); } - - // Allow some resources for the WiFi connection - yield(); - delay(2000); } + yield(); } // Send a simple string embedded in json over MQTT From 5f1451725884d6aa0f3b8dd98673fee8ae37c814 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 11 Feb 2020 17:25:52 +0100 Subject: [PATCH 02/11] Minor changes after testing MQTT reconnect --- src/AmsToMqttBridge.ino | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 64f003be..a1d1099c 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -72,12 +72,6 @@ void setup() { { setupWiFi(); - if(config.mqttHost) { - mqtt.begin(config.mqttHost, config.mqttPort, *client); - - // Notify everyone we're here! - sendMqttData("Connected!"); - } // Configure uart for AMS data #if defined SOFTWARE_SERIAL if(config.meterType == 3) { @@ -118,15 +112,16 @@ void loop() // Reconnect to WiFi and MQTT as needed if (WiFi.status() != WL_CONNECTED) { WiFi_connect(); - } - - if (config.mqttHost) { - mqtt.loop(); - delay(10); // <- fixes some issues with WiFi stability - if(!mqtt.connected()) { - MQTT_connect(); + } else { + if (config.mqttHost) { + mqtt.loop(); + yield(); + if(!mqtt.connected()) { + MQTT_connect(); + } } } + readHanPort(); } else @@ -305,6 +300,7 @@ void MQTT_connect() { return; } if(millis() - lastMqttRetry < 5000) { + yield(); return; } lastMqttRetry = millis(); @@ -315,6 +311,11 @@ void MQTT_connect() { debugger->print(config.mqttPort); debugger->println(); } + + mqtt.disconnect(); + + mqtt.begin(config.mqttHost, config.mqttPort, *client); + // Connect to a unsecure or secure MQTT server if ((config.mqttUser == 0 && mqtt.connect(config.mqttClientID)) || (config.mqttUser != 0 && mqtt.connect(config.mqttClientID, config.mqttUser, config.mqttPass))) { @@ -325,6 +326,8 @@ void MQTT_connect() { mqtt.subscribe(config.mqttSubscribeTopic); if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.mqttSubscribeTopic); } + + sendMqttData("Connected!"); } else { if (debugger) { debugger->print(" failed, "); @@ -341,11 +344,6 @@ void sendMqttData(String data) if (config.mqttPublishTopic == 0 || strlen(config.mqttPublishTopic) == 0) return; - // Make sure we're connected - if (!client->connected() || !mqtt.connected()) { - MQTT_connect(); - } - // Build a json with the message in a "data" attribute StaticJsonDocument<500> json; json["id"] = WiFi.macAddress(); From 4b9cb27e5800c0be934b0916f1a3894ea6e9beac Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 11 Feb 2020 17:32:18 +0100 Subject: [PATCH 03/11] Disable web security if AP mode is triggered --- src/web/AmsWebServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 06fa5546..d8c15b24 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -87,7 +87,7 @@ void AmsWebServer::setJson(StaticJsonDocument<500> json) { } bool AmsWebServer::checkSecurity(byte level) { - bool access = !config->hasConfig() || config->authSecurity < level; + bool access = WiFi.getMode() == WIFI_AP || !config->hasConfig() || config->authSecurity < level; if(!access && config->authSecurity >= level && server.hasHeader("Authorization")) { println(" forcing web security"); String expectedAuth = String(config->authUser) + ":" + String(config->authPass); From 058dc658c1acd907dced0c4eae9fa9a0c8e9ee32 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 12 Feb 2020 13:16:49 +0100 Subject: [PATCH 04/11] Switched to reactive import for Q --- lib/HanToJson/src/HanToJson.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/HanToJson/src/HanToJson.cpp b/lib/HanToJson/src/HanToJson.cpp index ee8f7185..8fd26d34 100644 --- a/lib/HanToJson/src/HanToJson.cpp +++ b/lib/HanToJson/src/HanToJson.cpp @@ -134,7 +134,7 @@ static void hanToJsonAidon3phaseIT(int listSize, JsonObject& data, HanReader& ha data["type"] = hanReader.getString( (int)Aidon_List3PhaseIT::MeterType); int p = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower); data["P"] = p; - data["Q"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveExportPower); + data["Q"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveImportPower); double i1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10; double i3 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10; double u1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10; From fa0f93cefe6bfd5f7442a79da0908a03e5bcefd6 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 12 Feb 2020 13:25:36 +0100 Subject: [PATCH 05/11] Switched to reactive import for Q --- lib/HanToJson/src/HanToJson.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/HanToJson/src/HanToJson.cpp b/lib/HanToJson/src/HanToJson.cpp index 8fd26d34..f54754e0 100644 --- a/lib/HanToJson/src/HanToJson.cpp +++ b/lib/HanToJson/src/HanToJson.cpp @@ -85,7 +85,7 @@ static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanR data["id"] = hanReader.getString( (int)Aidon_List3Phase::MeterID); data["type"] = hanReader.getString( (int)Aidon_List3Phase::MeterType); data["P"] = hanReader.getInt( (int)Aidon_List3Phase::ActiveImportPower); - data["Q"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveExportPower); + data["Q"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveImportPower); data["I1"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL1)) / 10; data["I2"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL2)) / 10; data["I3"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL3)) / 10; @@ -111,7 +111,7 @@ static void hanToJsonAidon1phase(int listSize, JsonObject& data, HanReader& hanR data["id"] = hanReader.getString( (int)Aidon_List1Phase::MeterID); data["type"] = hanReader.getString( (int)Aidon_List1Phase::MeterType); data["P"] = hanReader.getInt( (int)Aidon_List1Phase::ActiveImportPower); - data["Q"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveExportPower); + data["Q"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveImportPower); data["I1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CurrentL1)) / 10; data["U1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10; } From b6efae656f954167ae5040261d1582e05813218a Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 12 Feb 2020 16:40:51 +0100 Subject: [PATCH 06/11] Expose export power in JSON --- lib/HanToJson/src/HanToJson.cpp | 37 ++++++++++++++++++++------------- src/AmsToMqttBridge.ino | 2 +- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/HanToJson/src/HanToJson.cpp b/lib/HanToJson/src/HanToJson.cpp index f54754e0..e7ae4c19 100644 --- a/lib/HanToJson/src/HanToJson.cpp +++ b/lib/HanToJson/src/HanToJson.cpp @@ -10,9 +10,11 @@ static void hanToJsonKaifa3phase(int listSize, JsonObject& data, HanReader& hanR { data["lv"] = hanReader.getString( (int)Kaifa_List3Phase::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Kaifa_List3Phase::MeterID); - data["type"] = hanReader.getString( (int)Kaifa_List3Phase::MeterType); + data["type"] = hanReader.getString( (int)Kaifa_List3Phase::MeterType); data["P"] = hanReader.getInt( (int)Kaifa_List3Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Kaifa_List3Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Kaifa_List3Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL1)) / 1000; data["I2"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL2)) / 1000; data["I3"] = ((double) hanReader.getInt((int)Kaifa_List3Phase::CurrentL3)) / 1000; @@ -39,6 +41,8 @@ static void hanToJsonKaifa1phase(int listSize, JsonObject& data, HanReader& hanR data["type"] = hanReader.getString( (int)Kaifa_List1Phase::MeterType); data["P"] = hanReader.getInt( (int)Kaifa_List1Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Kaifa_List1Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Kaifa_List1Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt((int)Kaifa_List1Phase::CurrentL1)) / 1000; data["U1"] = ((double) hanReader.getInt((int)Kaifa_List1Phase::VoltageL1)) / 10; } @@ -86,6 +90,8 @@ static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanR data["type"] = hanReader.getString( (int)Aidon_List3Phase::MeterType); data["P"] = hanReader.getInt( (int)Aidon_List3Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Aidon_List3Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Aidon_List3Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL1)) / 10; data["I2"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL2)) / 10; data["I3"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::CurrentL3)) / 10; @@ -112,6 +118,8 @@ static void hanToJsonAidon1phase(int listSize, JsonObject& data, HanReader& hanR data["type"] = hanReader.getString( (int)Aidon_List1Phase::MeterType); data["P"] = hanReader.getInt( (int)Aidon_List1Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Aidon_List1Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Aidon_List1Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::CurrentL1)) / 10; data["U1"] = ((double) hanReader.getInt( (int)Aidon_List1Phase::VoltageL1)) / 10; } @@ -132,21 +140,16 @@ static void hanToJsonAidon3phaseIT(int listSize, JsonObject& data, HanReader& ha data["lv"] = hanReader.getString( (int)Aidon_List3PhaseIT::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Aidon_List3PhaseIT::MeterID); data["type"] = hanReader.getString( (int)Aidon_List3PhaseIT::MeterType); - int p = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower); - data["P"] = p; + data["P"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveImportPower); - double i1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10; - double i3 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10; - double u1 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10; - double u2 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL2)) / 10; - double u3 = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL3)) / 10; - double i2 = 0.00; - data["I1"] = i1; - data["I2"] = i2; - data["I3"] = i3; - data["U1"] = u1; - data["U2"] = u2; - data["U3"] = u3; + data["PO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::ReactiveExportPower); + data["I1"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL1)) / 10; + data["I1"] = 0; + data["I3"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::CurrentL3)) / 10; + data["U1"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL1)) / 10; + data["U2"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL2)) / 10; + data["U3"] = ((double) hanReader.getInt( (int)Aidon_List3PhaseIT::VoltageL3)) / 10; } if (listSize >= (int)Aidon::List3PhaseITLong) @@ -196,6 +199,8 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h data["type"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterType); data["P"] = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Kamstrup_List3Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Kamstrup_List3Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL1)) / 100; data["I2"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL2)) / 100; data["I3"] = ((double) hanReader.getInt((int)Kamstrup_List3Phase::CurrentL3)) / 100; @@ -222,6 +227,8 @@ static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& h data["type"] = hanReader.getString( (int)Kamstrup_List1Phase::MeterType); data["P"] = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveImportPower); data["Q"] = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveImportPower); + data["PO"] = hanReader.getInt( (int)Kamstrup_List1Phase::ActiveExportPower); + data["QO"] = hanReader.getInt( (int)Kamstrup_List1Phase::ReactiveExportPower); data["I1"] = ((double) hanReader.getInt((int)Kamstrup_List1Phase::CurrentL1)) / 100; data["U1"] = hanReader.getInt( (int)Kamstrup_List1Phase::VoltageL1); } diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index a1d1099c..75cae7c8 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -24,7 +24,7 @@ AmsWebServer ws; // WiFi client and MQTT client WiFiClient *client; -MQTTClient mqtt(384); +MQTTClient mqtt(512); // Object used for debugging HardwareSerial* debugger = NULL; From d2f93c07bd7095acc7ba34c4c8e555251867d56b Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Thu, 13 Feb 2020 20:50:13 +0100 Subject: [PATCH 07/11] Not sure if this does anything, but increased json and mqtt limits to see if Kamstrup list 3 is received --- lib/HanToJson/src/HanToJson.cpp | 1 + src/AmsToMqttBridge.ino | 2 +- src/web/AmsWebServer.cpp | 2 +- src/web/AmsWebServer.h | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/HanToJson/src/HanToJson.cpp b/lib/HanToJson/src/HanToJson.cpp index e7ae4c19..6aea6cf3 100644 --- a/lib/HanToJson/src/HanToJson.cpp +++ b/lib/HanToJson/src/HanToJson.cpp @@ -194,6 +194,7 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h { if (listSize >= (int)Kamstrup::List3PhaseShort) { + data["ls"] = listSize; data["lv"] = hanReader.getString( (int)Kamstrup_List3Phase::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterID); data["type"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterType); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 75cae7c8..08c17c72 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -202,7 +202,7 @@ void readHanPort() if (debugger) debugger->println(time); // Define a json object to keep the data - StaticJsonDocument<500> json; + StaticJsonDocument<1024> json; // Any generic useful info here json["id"] = WiFi.macAddress(); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index d8c15b24..ff52f5ba 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -41,7 +41,7 @@ void AmsWebServer::loop() { server.handleClient(); } -void AmsWebServer::setJson(StaticJsonDocument<500> json) { +void AmsWebServer::setJson(StaticJsonDocument<1024> json) { if(!json.isNull()) { p = json["data"]["P"].as(); diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index cc9e0d01..317a78b9 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -24,12 +24,12 @@ class AmsWebServer { public: void setup(configuration* config, Stream* debugger); void loop(); - void setJson(StaticJsonDocument<500> json); + void setJson(StaticJsonDocument<1024> json); private: configuration* config; Stream* debugger; - StaticJsonDocument<500> json; + StaticJsonDocument<1024> json; int maxPwr; int p; double u1, u2, u3, i1, i2, i3; From 554cc7c023ebb7482629dd76194ce55c22c676d5 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 14 Feb 2020 16:03:52 +0100 Subject: [PATCH 08/11] Added date and time from meter as rtc in json --- lib/HanToJson/src/HanToJson.cpp | 38 +++++++++++++++------------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/lib/HanToJson/src/HanToJson.cpp b/lib/HanToJson/src/HanToJson.cpp index 6aea6cf3..3b084861 100644 --- a/lib/HanToJson/src/HanToJson.cpp +++ b/lib/HanToJson/src/HanToJson.cpp @@ -25,6 +25,7 @@ static void hanToJsonKaifa3phase(int listSize, JsonObject& data, HanReader& hanR if (listSize >= (int)Kaifa::List3PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Kaifa_List3Phase::MeterClock); data["tPI"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Kaifa_List3Phase::CumulativeReactiveImportEnergy); @@ -49,6 +50,7 @@ static void hanToJsonKaifa1phase(int listSize, JsonObject& data, HanReader& hanR if (listSize >= (int)Kaifa::List1PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Kaifa_List1Phase::MeterClock); data["tPI"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Kaifa_List1Phase::CumulativeReactiveImportEnergy); @@ -81,10 +83,8 @@ static void hanToJsonKaifa(JsonObject& data, HanReader& hanReader, Stream *debug } -static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) -{ - if (listSize >= (int)Aidon::List3PhaseShort) - { +static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) { + if (listSize >= (int)Aidon::List3PhaseShort) { data["lv"] = hanReader.getString( (int)Aidon_List3Phase::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Aidon_List3Phase::MeterID); data["type"] = hanReader.getString( (int)Aidon_List3Phase::MeterType); @@ -100,8 +100,8 @@ static void hanToJsonAidon3phase(int listSize, JsonObject& data, HanReader& hanR data["U3"] = ((double) hanReader.getInt( (int)Aidon_List3Phase::VoltageL3)) / 10; } - if (listSize >= (int)Aidon::List3PhaseLong) - { + if (listSize >= (int)Aidon::List3PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Aidon_List3Phase::Timestamp); data["tPI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Aidon_List3Phase::CumulativeReactiveImportEnergy); @@ -126,6 +126,7 @@ static void hanToJsonAidon1phase(int listSize, JsonObject& data, HanReader& hanR if (listSize >= (int)Aidon::List1PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Aidon_List1Phase::Timestamp); data["tPI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Aidon_List1Phase::CumulativeReactiveImportEnergy); @@ -154,6 +155,7 @@ static void hanToJsonAidon3phaseIT(int listSize, JsonObject& data, HanReader& ha if (listSize >= (int)Aidon::List3PhaseITLong) { + data["rtc"] = hanReader.getTime( (int)Aidon_List3PhaseIT::Timestamp); data["tPI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Aidon_List3PhaseIT::CumulativeReactiveImportEnergy); @@ -190,11 +192,8 @@ static void hanToJsonAidon(JsonObject& data, HanReader& hanReader, Stream *debug } } -static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) -{ - if (listSize >= (int)Kamstrup::List3PhaseShort) - { - data["ls"] = listSize; +static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) { + if (listSize >= (int)Kamstrup::List3PhaseShort) { data["lv"] = hanReader.getString( (int)Kamstrup_List3Phase::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterID); data["type"] = hanReader.getString( (int)Kamstrup_List3Phase::MeterType); @@ -210,8 +209,8 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h data["U3"] = hanReader.getInt( (int)Kamstrup_List3Phase::VoltageL3); } - if (listSize >= (int)Kamstrup::List3PhaseLong) - { + if (listSize >= (int)Kamstrup::List3PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Kamstrup_List3Phase::MeterClock); data["tPI"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Kamstrup_List3Phase::CumulativeReactiveImportEnergy); @@ -219,10 +218,8 @@ static void hanToJsonKamstrup3phase(int listSize, JsonObject& data, HanReader& h } } -static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) -{ - if (listSize >= (int)Kamstrup::List1PhaseShort) - { +static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& hanReader, Stream *debugger) { + if (listSize >= (int)Kamstrup::List1PhaseShort) { data["lv"] = hanReader.getString( (int)Kamstrup_List1Phase::ListVersionIdentifier); data["id"] = hanReader.getString( (int)Kamstrup_List1Phase::MeterID); data["type"] = hanReader.getString( (int)Kamstrup_List1Phase::MeterType); @@ -234,8 +231,8 @@ static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& h data["U1"] = hanReader.getInt( (int)Kamstrup_List1Phase::VoltageL1); } - if (listSize >= (int)Kamstrup::List1PhaseLong) - { + if (listSize >= (int)Kamstrup::List1PhaseLong) { + data["rtc"] = hanReader.getTime( (int)Kamstrup_List1Phase::MeterClock); data["tPI"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeActiveImportEnergy); data["tPO"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeActiveExportEnergy); data["tQI"] = hanReader.getInt( (int)Kamstrup_List1Phase::CumulativeReactiveImportEnergy); @@ -243,8 +240,7 @@ static void hanToJsonKamstrup1phase(int listSize, JsonObject& data, HanReader& h } } -static void hanToJsonKamstrup(JsonObject& data, HanReader& hanReader, Stream *debugger) -{ +static void hanToJsonKamstrup(JsonObject& data, HanReader& hanReader, Stream *debugger) { int listSize = hanReader.getListSize(); switch (listSize) { From fe79a968278ee3a432b1e4e22e14d3ffe7f1a3de Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 14 Feb 2020 19:52:15 +0100 Subject: [PATCH 09/11] Added change to allow auto modem sleep --- src/AmsToMqttBridge.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 08c17c72..cad99b8c 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -131,6 +131,7 @@ void loop() else led_off(); } ws.loop(); + delay(1); // Needed for auto modem sleep } From b2174dd521e67d84318b5c509c8648bc3497dc1d Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 14 Feb 2020 20:14:30 +0100 Subject: [PATCH 10/11] If debug mode and HW_ROARFRED, use software serial to set upp RX for HAN with 2400 and TX for debugging with 115200 --- src/AmsToMqttBridge.h | 6 ++++++ src/AmsToMqttBridge.ino | 22 ++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/AmsToMqttBridge.h b/src/AmsToMqttBridge.h index 0b984c9f..111f42bf 100644 --- a/src/AmsToMqttBridge.h +++ b/src/AmsToMqttBridge.h @@ -17,7 +17,13 @@ #include #define TEMP_SENSOR_PIN 5 // Temperature sensor connected to GPIO5 +#if DEBUG_MODE +#define SOFTWARE_SERIAL 1 +#include +SoftwareSerial *hanSerial = new SoftwareSerial(3); +#else HardwareSerial *hanSerial = &Serial; +#endif // Build settings for Wemos Lolin D32 #elif defined(ARDUINO_LOLIN_D32) diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index cad99b8c..2a73e32e 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -27,7 +27,7 @@ WiFiClient *client; MQTTClient mqtt(512); // Object used for debugging -HardwareSerial* debugger = NULL; +Stream* debugger = NULL; // The HAN Port reader, used to read serial data and decode DLMS HanReader hanReader; @@ -39,17 +39,15 @@ void setup() { } #if DEBUG_MODE - debugger = &Serial; - #if SOFTWARE_SERIAL - debugger->begin(115200, SERIAL_8N1); - #else - if(config.meterType == 3) { - hanSerial->begin(2400, SERIAL_8N1); - } else { - hanSerial->begin(2400, SERIAL_8E1); - } - #endif - while (!&debugger); +#if HW_ROARFRED + SoftwareSerial *ser = new SoftwareSerial(-1, 1); + ser->begin(115200, SWSERIAL_8N1); + debugger = ser; +#else + HardwareSerial *ser = &Serial; + ser->begin(115200, SERIAL_8N1); +#endif + debugger = ser; #endif if (debugger) { From 4e24e2949aed0a1380988264c528d3bde44e5f7e Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 15 Feb 2020 18:01:10 +0100 Subject: [PATCH 11/11] Updated featheresp32 config to use Serial2 for Mbus --- hardware/README.md | 2 +- src/AmsToMqttBridge.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/README.md b/hardware/README.md index b37dcb8e..a191f9e6 100644 --- a/hardware/README.md +++ b/hardware/README.md @@ -27,7 +27,7 @@ You can also use a ESP based development board and combine this with a M-Bus mod - Jump GPIO4 to GND to force AP mode during boot [Adafruit HUZZAH32](https://www.adafruit.com/product/3405) -- M-Bus connected to RX +- M-Bus connected to GPIO16 Combine one of above board with an M-Bus module. Connect 3.3v and GND together between the boards and connect the TX pin from the M-Bus board to the dedicated M-Bus pin on the ESP board. diff --git a/src/AmsToMqttBridge.h b/src/AmsToMqttBridge.h index 111f42bf..61431869 100644 --- a/src/AmsToMqttBridge.h +++ b/src/AmsToMqttBridge.h @@ -51,7 +51,7 @@ SoftwareSerial *hanSerial = new SoftwareSerial(D1); #define LED_ACTIVE_HIGH 1 #define AP_BUTTON_PIN INVALID_BUTTON_PIN -HardwareSerial *hanSerial = &Serial; +HardwareSerial *hanSerial = &Serial2; // Default build settings #else