From e12980db11f3652c5255c570370d14609a2b2dcd Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 10 Mar 2020 18:43:18 +0100 Subject: [PATCH] Added option to send data as raw values to MQTT --- src/AmsConfiguration.cpp | 89 ++++++++++++++++++++++++++++++++++++++++ src/AmsConfiguration.h | 6 ++- src/AmsToMqttBridge.ino | 81 +++++++++++++++++++++++++++++------- src/web/AmsWebServer.cpp | 13 ++++-- web/configmqtt.html | 19 ++++++--- 5 files changed, 182 insertions(+), 26 deletions(-) diff --git a/src/AmsConfiguration.cpp b/src/AmsConfiguration.cpp index eff237ed..a066349f 100644 --- a/src/AmsConfiguration.cpp +++ b/src/AmsConfiguration.cpp @@ -123,6 +123,14 @@ void AmsConfiguration::setMqttPassword(String mqttPassword) { this->mqttPassword = String(mqttPassword); } +int AmsConfiguration::getMqttPayloadFormat() { + return this->mqttPayloadFormat; +} + +void AmsConfiguration::setMqttPayloadFormat(int mqttPayloadFormat) { + this->mqttPayloadFormat = mqttPayloadFormat; +} + void AmsConfiguration::clearMqtt() { setMqttHost(""); setMqttPort(1883); @@ -214,6 +222,7 @@ bool AmsConfiguration::hasConfig() { case 72: case 75: case 80: + case 81: return true; default: return false; @@ -238,6 +247,9 @@ bool AmsConfiguration::load() { case 80: success = loadConfig80(address); break; + case 81: + success = loadConfig81(address); + break; } EEPROM.end(); return success; @@ -278,6 +290,7 @@ bool AmsConfiguration::loadConfig72(int address) { setMqttUser(""); setMqttPassword(""); } + setMqttPayloadFormat(0); clearAuth(); @@ -332,6 +345,7 @@ bool AmsConfiguration::loadConfig75(int address) { setMqttUser(""); setMqttPassword(""); } + setMqttPayloadFormat(0); address += readByte(address, &authSecurity); if (authSecurity > 0) { @@ -403,6 +417,80 @@ bool AmsConfiguration::loadConfig80(int address) { } else { clearMqtt(); } + setMqttPayloadFormat(0); + + address += readByte(address, &authSecurity); + if (authSecurity > 0) { + address += readString(address, &temp); + setAuthUser(temp); + address += readString(address, &temp); + setAuthPassword(temp); + } else { + clearAuth(); + } + + int i; + address += readInt(address, &i); + setMeterType(i); + address += readInt(address, &i); + setDistributionSystem(i); + address += readInt(address, &i); + setMainFuse(i); + address += readInt(address, &i); + setProductionCapacity(i); + + ackWifiChange(); + + return true; +} + +bool AmsConfiguration::loadConfig81(int address) { + char* temp; + + address += readString(address, &temp); + setWifiSsid(temp); + address += readString(address, &temp); + setWifiPassword(temp); + address += readString(address, &temp); + setWifiIp(temp); + address += readString(address, &temp); + setWifiGw(temp); + address += readString(address, &temp); + setWifiSubnet(temp); + + bool mqtt = false; + address += readBool(address, &mqtt); + if(mqtt) { + address += readString(address, &temp); + setMqttHost(temp); + int port; + address += readInt(address, &port); + setMqttPort(port); + address += readString(address, &temp); + setMqttClientId(temp); + address += readString(address, &temp); + setMqttPublishTopic(temp); + address += readString(address, &temp); + setMqttSubscribeTopic(temp); + + bool secure = false; + address += readBool(address, &secure); + if (secure) + { + address += readString(address, &temp); + setMqttUser(temp); + address += readString(address, &temp); + setMqttPassword(temp); + } else { + setMqttUser(""); + setMqttPassword(""); + } + int payloadFormat; + address += readInt(address, &payloadFormat); + setMqttPayloadFormat(payloadFormat); + } else { + clearMqtt(); + } address += readByte(address, &authSecurity); if (authSecurity > 0) { @@ -455,6 +543,7 @@ bool AmsConfiguration::save() { } else { address += saveBool(address, false); } + address += saveInt(address, mqttPayloadFormat); } else { address += saveBool(address, false); } diff --git a/src/AmsConfiguration.h b/src/AmsConfiguration.h index d0282779..1fbf779b 100644 --- a/src/AmsConfiguration.h +++ b/src/AmsConfiguration.h @@ -38,6 +38,8 @@ public: void setMqttUser(String mqttUser); String getMqttPassword(); void setMqttPassword(String mqttPassword); + int getMqttPayloadFormat(); + void setMqttPayloadFormat(int mqttPayloadFormat); void clearMqtt(); bool isMqttChanged(); @@ -79,6 +81,7 @@ private: String mqttSubscribeTopic; String mqttUser; String mqttPassword; + int mqttPayloadFormat; bool mqttChanged; byte authSecurity; @@ -88,12 +91,13 @@ private: int meterType, distributionSystem, mainFuse, productionCapacity; const int EEPROM_SIZE = 512; - const int EEPROM_CHECK_SUM = 80; // Used to check if config is stored. Change if structure changes + const int EEPROM_CHECK_SUM = 81; // Used to check if config is stored. Change if structure changes const int EEPROM_CONFIG_ADDRESS = 0; bool loadConfig72(int address); bool loadConfig75(int address); bool loadConfig80(int address); + bool loadConfig81(int address); int saveString(int pAddress, const char* pString); int readString(int pAddress, char* pString[]); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 04d21a91..dc8d4719 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -239,6 +239,9 @@ void loop() { if(!mqtt.connected() || config.isMqttChanged()) { MQTT_connect(); } + if(config.getMqttPayloadFormat() == 1) { + sendSystemStatusToMqtt(); + } } else if(mqtt.connected()) { mqtt.disconnect(); } @@ -366,17 +369,43 @@ void readHanPort() { ws.setData(data); if(!config.getMqttHost().isEmpty() && !config.getMqttPublishTopic().isEmpty()) { - StaticJsonDocument<512> json; - hanToJson(json, data, hw, temperature); - if (debugger) { - debugger->print("Sending data to MQTT: "); - serializeJsonPretty(json, *debugger); - debugger->println(); - } + if(config.getMqttPayloadFormat() == 0) { + StaticJsonDocument<512> json; + hanToJson(json, data, hw, temperature); + if (debugger) { + debugger->print("Sending data to MQTT: "); + serializeJsonPretty(json, *debugger); + debugger->println(); + } - String msg; - serializeJson(json, msg); - mqtt.publish(config.getMqttPublishTopic(), msg.c_str()); + String msg; + serializeJson(json, msg); + mqtt.publish(config.getMqttPublishTopic(), msg.c_str()); + } else if(config.getMqttPayloadFormat() == 1) { + mqtt.publish(config.getMqttPublishTopic() + "/meter/dlms/timestamp", String(data.getPackageTimestamp())); + switch(data.getListType()) { + case 3: + mqtt.publish(config.getMqttPublishTopic() + "/meter/clock", String(data.getMeterTimestamp())); + mqtt.publish(config.getMqttPublishTopic() + "/meter/import/reactive/accumulated", String(data.getReactiveImportCounter(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/import/active/accumulated", String(data.getActiveImportCounter(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/export/reactive/accumulated", String(data.getReactiveExportCounter(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/export/active/accumulated", String(data.getActiveExportCounter(), 2)); + case 2: + mqtt.publish(config.getMqttPublishTopic() + "/meter/id", data.getMeterId()); + mqtt.publish(config.getMqttPublishTopic() + "/meter/type", data.getMeterType()); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l1/current", String(data.getL1Current(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l1/voltage", String(data.getL1Voltage(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l2/current", String(data.getL2Current(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l2/voltage", String(data.getL2Voltage(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l3/current", String(data.getL3Current(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/l3/voltage", String(data.getL3Voltage(), 2)); + mqtt.publish(config.getMqttPublishTopic() + "/meter/export/reactive", String(data.getReactiveExportPower())); + mqtt.publish(config.getMqttPublishTopic() + "/meter/export/active", String(data.getActiveExportPower())); + mqtt.publish(config.getMqttPublishTopic() + "/meter/import/reactive", String(data.getReactiveImportPower())); + case 1: + mqtt.publish(config.getMqttPublishTopic() + "/meter/import/active", String(data.getActiveImportPower())); + } + } mqtt.loop(); delay(10); } @@ -512,8 +541,12 @@ void MQTT_connect() { mqtt.subscribe(config.getMqttSubscribeTopic()); if (debugger) debugger->printf(" Subscribing to [%s]\r\n", config.getMqttSubscribeTopic().c_str()); } - - sendMqttData("Connected!"); + + if(config.getMqttPayloadFormat() == 0) { + sendMqttData("Connected!"); + } else if(config.getMqttPayloadFormat() == 1) { + sendSystemStatusToMqtt(); + } } else { if (debugger) { debugger->print(" failed, "); @@ -539,9 +572,7 @@ void sendMqttData(String data) if(vcc > 0) { json["vcc"] = vcc; } - float rssi = WiFi.RSSI(); - rssi = isnan(rssi) ? -100.0 : rssi; - json["rssi"] = rssi; + json["rssi"] = hw.getWifiRssi(); // Stringify the json String msg; @@ -554,6 +585,26 @@ void sendMqttData(String data) if (debugger) debugger->println(data); } +unsigned long lastSystemDataSent = -10000; +void sendSystemStatusToMqtt() { + if (config.getMqttPublishTopic().isEmpty()) + return; + if(millis() - lastSystemDataSent < 10000) + return; + lastSystemDataSent = millis(); + + mqtt.publish(config.getMqttPublishTopic() + "/id", WiFi.macAddress()); + mqtt.publish(config.getMqttPublishTopic() + "/uptime", String((unsigned long) millis64()/1000)); + double vcc = hw.getVcc(); + if(vcc > 0) { + mqtt.publish(config.getMqttPublishTopic() + "/vcc", String(vcc, 2)); + } + mqtt.publish(config.getMqttPublishTopic() + "/rssi", String(hw.getWifiRssi())); + if(temperature != DEVICE_DISCONNECTED_C) { + mqtt.publish(config.getMqttPublishTopic() + "/vcc", String(temperature, 2)); + } +} + void rgb_led(int color, int mode) { // Activate red and green LEDs if RGB LED is present (HAS_RGB_LED=1) // If no RGB LED present (HAS_RGB_LED=0 or not defined), all output goes to ESP onboard LED diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 02e865b3..cd9b8362 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -226,12 +226,17 @@ void AmsWebServer::configMqttHtml() { html.replace("${config.mqtt}", config->getMqttHost() == 0 ? "" : "checked"); html.replace("${config.mqttHost}", config->getMqttHost()); - html.replace("${config.mqttPort}", String(config->getMqttPort())); + if(config->getMqttPort() > 0) { + html.replace("${config.mqttPort}", String(config->getMqttPort())); + } else { + html.replace("${config.mqttPort}", String(1883)); + } html.replace("${config.mqttClientId}", config->getMqttClientId()); html.replace("${config.mqttPublishTopic}", config->getMqttPublishTopic()); html.replace("${config.mqttSubscribeTopic}", config->getMqttSubscribeTopic()); html.replace("${config.mqttUser}", config->getMqttUser()); html.replace("${config.mqttPassword}", config->getMqttPassword()); + html.replace("${config.mqttPayloadFormat}", String(config->getMqttPayloadFormat())); server.setContentLength(html.length()); server.send(200, "text/html", html); @@ -459,14 +464,14 @@ void AmsWebServer::handleSave() { if(server.hasArg("mqttConfig") && server.arg("mqttConfig") == "true") { if(server.hasArg("mqtt") && server.arg("mqtt") == "true") { config->setMqttHost(server.arg("mqttHost")); - config->setMqttPort(server.arg("mqttPort").toInt()); + int port = server.arg("mqttPort").toInt(); + config->setMqttPort(port == 0 ? 1883 : port); config->setMqttClientId(server.arg("mqttClientId")); config->setMqttPublishTopic(server.arg("mqttPublishTopic")); config->setMqttSubscribeTopic(server.arg("mqttSubscribeTopic")); config->setMqttUser(server.arg("mqttUser")); config->setMqttPassword(server.arg("mqttPassword")); - config->setAuthUser(server.arg("authUser")); - config->setAuthPassword(server.arg("authPassword")); + config->setMqttPayloadFormat(server.arg("mqttPayloadFormat").toInt()); } else { config->clearMqtt(); } diff --git a/web/configmqtt.html b/web/configmqtt.html index e9607059..ac1383e4 100644 --- a/web/configmqtt.html +++ b/web/configmqtt.html @@ -39,17 +39,24 @@
-
+
+
+ +
+ +
+
-
-
-
+
@@ -63,7 +70,7 @@
-
+
@@ -77,7 +84,7 @@
-
+