From 61aeb30d6750744f76d0e906187a9a80ecac523c Mon Sep 17 00:00:00 2001 From: ohAnd <15704728+ohAnd@users.noreply.github.com> Date: Thu, 6 Jun 2024 22:03:50 +0200 Subject: [PATCH] refactor MQTT interface and extend with autodiscovery + preparing tls support --- include/Config.h | 2 +- include/mqttHandler.h | 32 ++++++ include/version.h | 4 +- include/version.json | 2 +- readme.md | 4 +- src/Config.cpp | 6 +- src/dtuGateway.ino | 220 ++++++++++++++++++++++++++---------------- src/mqttHandler.cpp | 115 ++++++++++++++++++++++ 8 files changed, 296 insertions(+), 89 deletions(-) create mode 100644 include/mqttHandler.h create mode 100644 src/mqttHandler.cpp diff --git a/include/Config.h b/include/Config.h index 842e728..71b7e1a 100644 --- a/include/Config.h +++ b/include/Config.h @@ -30,7 +30,7 @@ struct UserConfig char mqttBrokerUser[64] = "dtuuser"; char mqttBrokerPassword[64] = "dtupass"; char mqttBrokerMainTopic[32] = "dtu1"; - boolean mqttHAautoDiscovery = false; + boolean mqttHAutoDiscoveryON = false; boolean mqttActive = false; uint8_t displayConnected = 0; // OLED default diff --git a/include/mqttHandler.h b/include/mqttHandler.h new file mode 100644 index 0000000..dd16ba6 --- /dev/null +++ b/include/mqttHandler.h @@ -0,0 +1,32 @@ +#ifndef MQTTHANDLER_H +#define MQTTHANDLER_H + +#include +#include +#include + +class MQTTHandler { +public: + MQTTHandler(const char* broker, int port, const char* user, const char* password, bool useTLS, const char* sensorUniqueName); + void setup(bool autoDiscovery); + void loop(bool autoDiscovery); + void publishDiscoveryMessage(const char* sensor_type, const char* location, const char* unit); + void publishSensorData(String typeName, String value); + void publishStandardData(String topicPath, String value); + +private: + const char* mqtt_broker; + int mqtt_port; + const char* mqtt_user; + const char* mqtt_password; + bool useTLS; + const char* sensor_uniqeName; + + WiFiClient wifiClient; + WiFiClientSecure wifiClientSecure; + PubSubClient client; + + void reconnect(bool autoDiscovery); +}; + +#endif // MQTTHANDLER_H \ No newline at end of file diff --git a/include/version.h b/include/version.h index 7e3b5e9..1eefb29 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION "1.6.0_localDev" -#define BUILDTIME "06.06.2024 - 00:11:48" -#define BUILDTIMESTAMP "1717625508" \ No newline at end of file +#define BUILDTIME "06.06.2024 - 22:00:02" +#define BUILDTIMESTAMP "1717704002" \ No newline at end of file diff --git a/include/version.json b/include/version.json index 076361f..b5baead 100644 --- a/include/version.json +++ b/include/version.json @@ -1,6 +1,6 @@ { "version": "1.6.0_localDev", - "versiondate": "06.06.2024 - 00:11:48", + "versiondate": "06.06.2024 - 22:00:02", "linksnapshot": "https://github.com/ohAnd/dtuGateway/releases/download/snapshot/dtuGateway_snapshot_1.6.0_localDev.bin", "link": "https://github.com/ohAnd/dtuGateway//releases/latest/download/dtuGateway_release_1.6.0_localDev.bin" } \ No newline at end of file diff --git a/readme.md b/readme.md index f85f57b..be4f9c0 100644 --- a/readme.md +++ b/readme.md @@ -72,9 +72,11 @@ So I decided to put this abstraction in an **ESP8266** to have a stable abstract #### connections to the environment - serving the readed data per /api/data -- binding configuration with seperate activation and login data setting +- configuration of bindings with seperate activation and login data setting - binding: updating openHab instance with readed data and pulling set data from the instance - binding: updating to a MQTT broker with readed data [OPEN: pulling set power data from the mqtt instance] + - 2 ways to configure - simple mqtt publishing with base topic or HA MQTT AutoDiscovery based + - for all publishing retain flag is set (keeping last seen data in broker) #### display support - selectable (and storable) over advanced web config[^2] or per serial com and at directly at start up coming from factory mode ( [see first-setup-with-access-point](#first-setup-with-access-point) ) diff --git a/src/Config.cpp b/src/Config.cpp index 7218de2..55ba6ca 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -119,7 +119,7 @@ void UserConfigManager::printConfigdata() Serial.print(F("mqtt binding active: \t")); Serial.println(userConfig.mqttActive); Serial.print(F("mqtt HA autoDiscovery: \t")); - Serial.println(userConfig.mqttHAautoDiscovery); + Serial.println(userConfig.mqttHAutoDiscoveryON); Serial.print(F("dtu update time: \t")); Serial.println(userConfig.dtuUpdateTime); @@ -169,7 +169,7 @@ JsonDocument UserConfigManager::mappingStructToJson() doc["mqtt"]["user"] = userConfig.mqttBrokerUser; doc["mqtt"]["pass"] = userConfig.mqttBrokerPassword; doc["mqtt"]["mainTopic"] = userConfig.mqttBrokerMainTopic; - doc["mqtt"]["HAautoDiscovery"] = userConfig.mqttHAautoDiscovery; + doc["mqtt"]["HAutoDiscoveryON"] = userConfig.mqttHAutoDiscoveryON; doc["display"]["type"] = userConfig.displayConnected; @@ -202,7 +202,7 @@ void UserConfigManager::mappingJsonToStruct(JsonDocument doc) String(doc["mqtt"]["user"]).toCharArray(userConfig.mqttBrokerUser, sizeof(userConfig.mqttBrokerUser)); String(doc["mqtt"]["pass"]).toCharArray(userConfig.mqttBrokerPassword, sizeof(userConfig.mqttBrokerPassword)); String(doc["mqtt"]["mainTopic"]).toCharArray(userConfig.mqttBrokerMainTopic, sizeof(userConfig.mqttBrokerMainTopic)); - userConfig.mqttHAautoDiscovery = doc["mqtt"]["HAautoDiscovery"]; + userConfig.mqttHAutoDiscoveryON = doc["mqtt"]["HAutoDiscoveryON"]; userConfig.displayConnected = doc["display"]["type"]; diff --git a/src/dtuGateway.ino b/src/dtuGateway.ino index b78860d..26c685f 100644 --- a/src/dtuGateway.ino +++ b/src/dtuGateway.ino @@ -20,7 +20,9 @@ #include #include -#include "dtuInterface.h" +#include + +#include #include "index_html.h" #include "jquery_min_js.h" @@ -986,73 +988,127 @@ boolean postMessageToMQTTbroker(String topic, String value) { const char *charTopic = topic.c_str(); const char *charValue = value.c_str(); - mqttClient.publish(charTopic, charValue); + + mqttClient.publish(charTopic, charValue, true); // Serial.println("\npostMessageToMQTTbroker - send '" + value + "' to topic: " + topic); return true; } -boolean updateValuesToMqtt() +// boolean updateValuesToMqtt() +// { +// connectCheckMqttClient(); +// if (mqttClient.connected()) +// { +// boolean sendOk = postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/timestamp", (String)timeStampInSecondsDtuSynced); +// if (sendOk) +// { +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/U", (String)globalData.grid.voltage); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/I", (String)globalData.grid.current); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/P", (String)globalData.grid.power); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/dailyEnergy", String(globalData.grid.dailyEnergy, 3)); +// if (globalData.grid.totalEnergy != 0) +// { +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/totalEnergy", String(globalData.grid.totalEnergy, 3)); +// } + +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/U", (String)globalData.pv0.voltage); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/I", (String)globalData.pv0.current); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/P", (String)globalData.pv0.power); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/dailyEnergy", String(globalData.pv0.dailyEnergy, 3)); +// if (globalData.pv0.totalEnergy != 0) +// { +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/totalEnergy", String(globalData.pv0.totalEnergy, 3)); +// } + +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/U", (String)globalData.pv1.voltage); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/I", (String)globalData.pv1.current); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/P", (String)globalData.pv1.power); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/dailyEnergy", String(globalData.pv1.dailyEnergy, 3)); +// if (globalData.pv1.totalEnergy != 0) +// { +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/totalEnergy", String(globalData.pv1.totalEnergy, 3)); +// } + +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/Temp", (String)globalData.inverterTemp); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/PowerLimit", (String)globalData.powerLimit); +// postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/WifiRSSI", (String)globalData.dtuRssi); +// Serial.println("\nsent values to mqtt broker"); +// } +// else +// { +// Serial.println("\nerror during sent values to mqtt broker"); +// } +// } +// else +// { +// Serial.println("\ncould not send to mqtt broker - mqtt not connected"); +// return false; +// } +// return true; +// } + +bool useTLS = String(userConfig.mqttBrokerIpDomain).startsWith("mqtts://"); + +MQTTHandler mqttHandler(userConfig.mqttBrokerIpDomain, userConfig.mqttBrokerPort, userConfig.mqttBrokerUser, userConfig.mqttBrokerPassword, useTLS, espUniqueName.c_str()); + +// publishing data in standard or HA mqtt auto discovery format +void updateValuesToMqtt(boolean haAutoDiscovery = false) { - connectCheckMqttClient(); - if (mqttClient.connected()) + Serial.println("\npublish data to MQTT (HA autoDiscovery = " + String(haAutoDiscovery) + ")"); + std::map keyValueStore; + + keyValueStore["timestamp"] = String(timeStampInSecondsDtuSynced).c_str(); + + keyValueStore["grid_U"] = String(globalData.grid.voltage).c_str(); + keyValueStore["grid_I"] = String(globalData.grid.current).c_str(); + keyValueStore["grid_P"] = String(globalData.grid.power).c_str(); + keyValueStore["grid_dailyEnergy"] = String(globalData.grid.dailyEnergy, 3).c_str(); + if (globalData.grid.totalEnergy != 0) + keyValueStore["grid_totalEnergy"] = String(globalData.grid.totalEnergy, 3).c_str(); + + keyValueStore["pv0_U"] = String(globalData.pv0.voltage).c_str(); + keyValueStore["pv0_I"] = String(globalData.pv0.current).c_str(); + keyValueStore["pv0_P"] = String(globalData.pv0.power).c_str(); + keyValueStore["pv0_dailyEnergy"] = String(globalData.pv0.dailyEnergy, 3).c_str(); + if (globalData.pv0.totalEnergy != 0) + keyValueStore["pv0_totalEnergy"] = String(globalData.pv0.totalEnergy, 3).c_str(); + + keyValueStore["pv1_U"] = String(globalData.pv1.voltage).c_str(); + keyValueStore["pv1_I"] = String(globalData.pv1.current).c_str(); + keyValueStore["pv1_P"] = String(globalData.pv1.power).c_str(); + keyValueStore["pv1_dailyEnergy"] = String(globalData.pv1.dailyEnergy, 3).c_str(); + if (globalData.pv0.totalEnergy != 0) + keyValueStore["pv1_totalEnergy"] = String(globalData.pv1.totalEnergy, 3).c_str(); + + keyValueStore["inverter_Temp"] = String(globalData.inverterTemp).c_str(); + keyValueStore["inverter_PowerLimit"] = String(globalData.powerLimit).c_str(); + keyValueStore["inverter_WifiRSSI"] = String(globalData.dtuRssi).c_str(); + + for (const auto &pair : keyValueStore) { - boolean sendOk = postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/timestamp", (String)timeStampInSecondsDtuSynced); - if (sendOk) + if (haAutoDiscovery) { - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/U", (String)globalData.grid.voltage); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/I", (String)globalData.grid.current); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/P", (String)globalData.grid.power); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/dailyEnergy", String(globalData.grid.dailyEnergy, 3)); - if (globalData.grid.totalEnergy != 0) - { - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/grid/totalEnergy", String(globalData.grid.totalEnergy, 3)); - } - - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/U", (String)globalData.pv0.voltage); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/I", (String)globalData.pv0.current); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/P", (String)globalData.pv0.power); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/dailyEnergy", String(globalData.pv0.dailyEnergy, 3)); - if (globalData.pv0.totalEnergy != 0) - { - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv0/totalEnergy", String(globalData.pv0.totalEnergy, 3)); - } - - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/U", (String)globalData.pv1.voltage); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/I", (String)globalData.pv1.current); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/P", (String)globalData.pv1.power); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/dailyEnergy", String(globalData.pv1.dailyEnergy, 3)); - if (globalData.pv1.totalEnergy != 0) - { - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/pv1/totalEnergy", String(globalData.pv1.totalEnergy, 3)); - } - - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/Temp", (String)globalData.inverterTemp); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/PowerLimit", (String)globalData.powerLimit); - postMessageToMQTTbroker(String(userConfig.mqttBrokerMainTopic) + "/inverter/WifiRSSI", (String)globalData.dtuRssi); - Serial.println("\nsent values to mqtt broker"); + mqttHandler.publishSensorData((pair.first).c_str(), (pair.second).c_str()); } else { - Serial.println("\nerror during sent values to mqtt broker"); + String subtopic = (pair.first).c_str(); + subtopic.replace("_", "/"); + mqttHandler.publishStandardData(String(userConfig.mqttBrokerMainTopic) + "/" + subtopic, (pair.second).c_str()); } } - else - { - Serial.println("\ncould not send to mqtt broker - mqtt not connected"); - return false; - } - return true; } boolean sendHAautoDiscovery() { JsonDocument doc; - String haTopicPath = "homeassistant/sensor/" + String(espUniqueName) + "/config"; + String haConfigTopicPath = "homeassistant/sensor/" + String(espUniqueName) + "/config"; + String haStateTopicPath = "homeassistant/sensor/" + String(espUniqueName) + "/config"; doc["name"] = "HM_Gateway_total-energy"; doc["unique_id"] = espUniqueName; - doc["state_topic"] = haTopicPath; + doc["state_topic"] = haStateTopicPath; doc["unit_of_measurement"] = "kWh"; doc["icon"] = "mdi:sine-wave"; doc["device"]["name"] = "HoymilesGateway"; @@ -1064,27 +1120,29 @@ boolean sendHAautoDiscovery() doc["device"]["configuration_url"] = "http://" + dtuGatewayIP.toString(); // serializeJsonPretty(doc, Serial); - // serializeJson(doc, Serial); - - char mqttPayload[1024]; - size_t len = serializeJson(doc, mqttPayload); - - connectCheckMqttClient(); - if (mqttClient.connected()) - { - if (userConfig.mqttHAautoDiscovery) - { - mqttClient.beginPublish(haTopicPath.c_str(), len, true); - mqttClient.print(mqttPayload); - mqttClient.endPublish(); - Serial.println("\nHA autoDiscovery - send JSON to broker at " + haTopicPath); - } - else - { - postMessageToMQTTbroker(haTopicPath, ""); - Serial.println("\nHA autoDiscovery - send empty payload to broker at " + haTopicPath); - } - } + serializeJson(doc, Serial); + + // char mqttPayload[1024]; + // size_t len = serializeJson(doc, mqttPayload); + + // connectCheckMqttClient(); + // if (mqttClient.connected()) + // { + // if (userConfig.mqttHAutoDiscoveryON) + // { + // mqttClient.beginPublish(haConfigTopicPath.c_str(), len, true); + // mqttClient.print(mqttPayload); + // mqttClient.endPublish(); + // Serial.println("\nHA autoDiscovery - send JSON to broker at " + haConfigTopicPath); + // haAutoDiscoveryLastOff = true; + // } + // else if (!userConfig.mqttHAutoDiscoveryON && !haAutoDiscoveryLastOff) + // { + // mqttClient.publish(haConfigTopicPath.c_str(), 0); + // Serial.println("\nHA autoDiscovery - ONE TIME send empty payload to broker at " + haConfigTopicPath); + // haAutoDiscoveryLastOff = true; + // } + // } return true; } @@ -1217,7 +1275,8 @@ void startServices() WiFi.scanNetworks(true); initializeWebServer(); - initMqttClient(); + Serial.println(F("setup mqtt:")); + mqttHandler.setup(userConfig.mqttHAutoDiscoveryON); } else { @@ -1477,15 +1536,16 @@ void loop() if (updateRunning) return; - // web server runner - server.handleClient(); - // serving domain name - MDNS.update(); - - // runner for mqttClient to hold a already etablished connection - if (userConfig.mqttActive && mqttClient.connected()) + if (WiFi.status() == WL_CONNECTED) { - mqttClient.loop(); + // web server runner + server.handleClient(); + // serving domain name + MDNS.update(); + + // runner for mqttClient to hold a already etablished connection + if (userConfig.mqttActive) + mqttHandler.loop(userConfig.mqttHAutoDiscoveryON); } unsigned long currentMillis = millis(); @@ -1602,8 +1662,6 @@ void loop() if (userConfig.openhabActive) getPowerSetDataFromOpenHab(); } - // if (userConfig.mqttActive && userConfig.mqttHAautoDiscovery) - sendHAautoDiscovery(); } // mid task @@ -1628,7 +1686,7 @@ void loop() if (userConfig.openhabActive) updateValueToOpenhab(); if (userConfig.mqttActive) - updateValuesToMqtt(); + updateValuesToMqtt(userConfig.mqttHAutoDiscoveryON); if (globalControls.dataFormatJSON) { @@ -1660,7 +1718,7 @@ void loop() if (userConfig.openhabActive) updateValueToOpenhab(); if (userConfig.mqttActive) - updateValuesToMqtt(); + updateValuesToMqtt(userConfig.mqttHAutoDiscoveryON); dtuConnection.dtuErrorState = DTU_ERROR_LAST_SEND; Serial.print(F("\n>>>>> TIMEOUT 5 min for DTU -> NIGHT - send zero values\n")); } diff --git a/src/mqttHandler.cpp b/src/mqttHandler.cpp new file mode 100644 index 0000000..9b5ec6e --- /dev/null +++ b/src/mqttHandler.cpp @@ -0,0 +1,115 @@ +#include "MQTTHandler.h" +#include +#include + +MQTTHandler::MQTTHandler(const char *broker, int port, const char *user, const char *password, bool useTLS, const char *sensorUniqueName) + : mqtt_broker(broker), mqtt_port(port), mqtt_user(user), mqtt_password(password), useTLS(useTLS), + client(useTLS ? wifiClientSecure : wifiClient), sensor_uniqeName(sensorUniqueName) {} + +void MQTTHandler::setup(bool autoDiscovery) +{ + client.setServer(mqtt_broker, mqtt_port); + reconnect(autoDiscovery); +} + +void MQTTHandler::loop(bool autoDiscovery) +{ + if (!client.connected()) + { + reconnect(autoDiscovery); + } + client.loop(); +} + +void MQTTHandler::publishDiscoveryMessage(const char *sensor_type, const char *location, const char *unit) +{ + String uniqueID = String(sensor_type) + "_" + String(location); + + JsonDocument doc; + doc["name"] = String(sensor_type) + " " + String(location); + doc["unique_id"] = uniqueID; + doc["state_topic"] = "homeassistant/sensor/" + uniqueID + "/state"; + doc["unit_of_measurement"] = unit; + doc["icon"] = "mdi:sine-wave"; + doc["device"]["name"] = "HoymilesGateway"; + doc["device"]["identifiers"] = "mymqttdevice01"; + doc["device"]["manufacturer"] = "ohAnd"; + doc["device"]["model"] = "ESP8266/ESP32"; + doc["device"]["hw_version"] = "1.0"; + doc["device"]["sw_version"] = String(VERSION); + doc["device"]["configuration_url"] = "http://"; // + dtuGatewayIP.toString(); + + char config_topic[100]; + snprintf(config_topic, sizeof(config_topic), "homeassistant/sensor/%s/config", uniqueID.c_str()); + + char payload[1024]; + size_t len = serializeJson(doc, payload); + + client.beginPublish(config_topic, len, true); + client.print(payload); + client.endPublish(); + // Serial.println("\nHA autoDiscovery - send JSON to broker at " + String(config_topic)); +} + +void MQTTHandler::publishSensorData(String typeName, String value) +{ + char state_topic[100]; + snprintf(state_topic, sizeof(state_topic), "homeassistant/sensor/%s_%s/state", sensor_uniqeName, typeName.c_str()); + + const char *charValue = value.c_str(); + client.publish(state_topic, charValue, true); +} + +void MQTTHandler::publishStandardData(String topicPath, String value) +{ + const char *charTopic = topicPath.c_str(); + const char *charValue = value.c_str(); + client.publish(charTopic, charValue, true); +} + +void MQTTHandler::reconnect(bool autoDiscovery) +{ + if (!client.connected()) + { + Serial.print("Attempting MQTT connection..."); + if (client.connect("dtuGateway", mqtt_user, mqtt_password)) + { + Serial.println("connected"); + + if (autoDiscovery) + { + Serial.println("setup HA MQTT auto Discovery"); + // Publish MQTT auto-discovery messages + publishDiscoveryMessage(sensor_uniqeName, "timestamp", "s"); + publishDiscoveryMessage(sensor_uniqeName, "grid_U", "V"); + publishDiscoveryMessage(sensor_uniqeName, "pv0_U", "V"); + publishDiscoveryMessage(sensor_uniqeName, "pv1_U", "V"); + + publishDiscoveryMessage(sensor_uniqeName, "grid_I", "A"); + publishDiscoveryMessage(sensor_uniqeName, "pv0_I", "A"); + publishDiscoveryMessage(sensor_uniqeName, "pv1_I", "A"); + + publishDiscoveryMessage(sensor_uniqeName, "grid_P", "W"); + publishDiscoveryMessage(sensor_uniqeName, "pv0_P", "W"); + publishDiscoveryMessage(sensor_uniqeName, "pv1_P", "W"); + + publishDiscoveryMessage(sensor_uniqeName, "grid_dailyEnergy", "kWh"); + publishDiscoveryMessage(sensor_uniqeName, "pv0_dailyEnergy", "kWh"); + publishDiscoveryMessage(sensor_uniqeName, "pv1_dailyEnergy", "kWh"); + + publishDiscoveryMessage(sensor_uniqeName, "grid_totalEnergy", "kWh"); + publishDiscoveryMessage(sensor_uniqeName, "pv0_totalEnergy", "kWh"); + publishDiscoveryMessage(sensor_uniqeName, "pv1_totalEnergy", "kWh"); + + publishDiscoveryMessage(sensor_uniqeName, "inverter_Temp", "°C"); + publishDiscoveryMessage(sensor_uniqeName, "inverter_PowerLimit", "%"); + publishDiscoveryMessage(sensor_uniqeName, "inverter_WifiRSSI", "%"); + } + } + else + { + Serial.print("failed, rc="); + Serial.print(client.state()); + } + } +}