diff --git a/src/app.cpp b/src/app.cpp index c32ad918..eb591307 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -85,7 +85,7 @@ void app::loop(void) { if (mFlagSendDiscoveryConfig) { mFlagSendDiscoveryConfig = false; - sendMqttDiscoveryConfig(); + mMqtt.sendMqttDiscoveryConfig(mSys, mConfig.mqtt.topic, mMqttInterval); } mSys->Radio.loop(); @@ -524,60 +524,6 @@ void app::getAvailNetworks(JsonObject obj) { mWifi->getAvailNetworks(obj); } -//----------------------------------------------------------------------------- -void app::sendMqttDiscoveryConfig(void) { - DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); - - char stateTopic[64], discoveryTopic[64], buffer[512], name[32], uniq_id[32]; - for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { - Inverter<> *iv = mSys->getInverterByPos(id); - if (NULL != iv) { - record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); - DynamicJsonDocument deviceDoc(128); - deviceDoc["name"] = iv->name; - deviceDoc["ids"] = String(iv->serial.u64, HEX); - deviceDoc["cu"] = F("http://") + String(WiFi.localIP().toString()); - deviceDoc["mf"] = "Hoymiles"; - deviceDoc["mdl"] = iv->name; - JsonObject deviceObj = deviceDoc.as(); - DynamicJsonDocument doc(384); - - for (uint8_t i = 0; i < rec->length; i++) { - if (rec->assign[i].ch == CH0) { - snprintf(name, 32, "%s %s", iv->name, iv->getFieldName(i, rec)); - } else { - snprintf(name, 32, "%s CH%d %s", iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); - } - snprintf(stateTopic, 64, "%s/%s/ch%d/%s", mConfig.mqtt.topic, iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); - snprintf(discoveryTopic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); - snprintf(uniq_id, 32, "ch%d_%s", rec->assign[i].ch, iv->getFieldName(i, rec)); - const char *devCls = getFieldDeviceClass(rec->assign[i].fieldId); - const char *stateCls = getFieldStateClass(rec->assign[i].fieldId); - - doc["name"] = name; - doc["stat_t"] = stateTopic; - doc["unit_of_meas"] = iv->getUnit(i, rec); - doc["uniq_id"] = String(iv->serial.u64, HEX) + "_" + uniq_id; - doc["dev"] = deviceObj; - doc["exp_aft"] = mMqttInterval + 5; // add 5 sec if connection is bad or ESP too slow - if (devCls != NULL) - doc["dev_cla"] = devCls; - if (stateCls != NULL) - doc["stat_cla"] = stateCls; - - serializeJson(doc, buffer); - mMqtt.sendMsg2(discoveryTopic, buffer, true); - // DPRINTLN(DBG_INFO, F("mqtt sent")); - doc.clear(); - } - - // TODO: remove this field, obsolete? - mMqttConfigSendState[id] = true; - - yield(); - } - } -} //----------------------------------------------------------------------------- void app::sendMqtt(void) { @@ -691,26 +637,6 @@ void app::sendMqtt(void) { } } -//----------------------------------------------------------------------------- -const char *app::getFieldDeviceClass(uint8_t fieldId) { - uint8_t pos = 0; - for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { - if (deviceFieldAssignment[pos].fieldId == fieldId) - break; - } - return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : deviceClasses[deviceFieldAssignment[pos].deviceClsId]; -} - -//----------------------------------------------------------------------------- -const char *app::getFieldStateClass(uint8_t fieldId) { - uint8_t pos = 0; - for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { - if (deviceFieldAssignment[pos].fieldId == fieldId) - break; - } - return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId]; -} - //----------------------------------------------------------------------------- void app::resetSystem(void) { mUptimeSecs = 0; diff --git a/src/app.h b/src/app.h index ab731b3d..2dd48f62 100644 --- a/src/app.h +++ b/src/app.h @@ -32,6 +32,7 @@ #define ACOS(x) (degrees(acos(x))) typedef HmSystem HmSystemType; +typedef mqtt MqttType; typedef struct { uint8_t txCmd; @@ -177,7 +178,6 @@ class app { void loadEEpconfig(void); void setupMqtt(void); - void sendMqttDiscoveryConfig(void); void sendMqtt(void); void setupLed(void); @@ -186,9 +186,6 @@ class app { bool buildPayload(uint8_t id); void processPayload(bool retransmit); - const char* getFieldDeviceClass(uint8_t fieldId); - const char* getFieldStateClass(uint8_t fieldId); - inline uint16_t buildEEpCrc(uint32_t start, uint32_t length) { DPRINTLN(DBG_VERBOSE, F("main.h:buildEEpCrc")); uint8_t buf[32]; @@ -286,11 +283,10 @@ class app { uint32_t mRxTicker; // mqtt - mqtt mMqtt; + MqttType mMqtt; uint16_t mMqttTicker; uint16_t mMqttInterval; bool mMqttActive; - bool mMqttConfigSendState[MAX_NUM_INVERTERS]; std::queue mMqttSendList; // serial diff --git a/src/defines.h b/src/defines.h index 5ae2f8bb..b8f5a43c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 32 +#define VERSION_PATCH 33 //------------------------------------- typedef struct { diff --git a/src/web/html/convert.py b/src/web/html/convert.py index 2f2ac24b..9745254d 100644 --- a/src/web/html/convert.py +++ b/src/web/html/convert.py @@ -65,7 +65,6 @@ def convert2Header(inFile, compress): # delete all files in the 'h' dir, but ignore 'favicon_ico_gz.h' dir = 'h' -print(os.getcwd()) if os.getcwd()[-4:] != "html": dir = "web/html/" + dir diff --git a/src/web/mqtt.h b/src/web/mqtt.h index eb042f33..3d18b45a 100644 --- a/src/web/mqtt.h +++ b/src/web/mqtt.h @@ -16,9 +16,14 @@ #undef F #define F(sl) (sl) #endif + +#include "../utils/dbg.h" #include #include "../defines.h" +#include "../hm/hmSystem.h" +#include +template class mqtt { public: mqtt() { @@ -89,6 +94,78 @@ class mqtt { return mTxCnt; } + void sendMqttDiscoveryConfig(HMSYSTEM *sys, const char *topic, uint32_t invertval) { + DPRINTLN(DBG_VERBOSE, F("app::sendMqttDiscoveryConfig")); + + char stateTopic[64], discoveryTopic[64], buffer[512], name[32], uniq_id[32]; + for (uint8_t id = 0; id < sys->getNumInverters(); id++) { + Inverter<> *iv = sys->getInverterByPos(id); + if (NULL != iv) { + record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); + DynamicJsonDocument deviceDoc(128); + deviceDoc["name"] = iv->name; + deviceDoc["ids"] = String(iv->serial.u64, HEX); + deviceDoc["cu"] = F("http://") + String(WiFi.localIP().toString()); + deviceDoc["mf"] = "Hoymiles"; + deviceDoc["mdl"] = iv->name; + JsonObject deviceObj = deviceDoc.as(); + DynamicJsonDocument doc(384); + + for (uint8_t i = 0; i < rec->length; i++) { + if (rec->assign[i].ch == CH0) { + snprintf(name, 32, "%s %s", iv->name, iv->getFieldName(i, rec)); + } else { + snprintf(name, 32, "%s CH%d %s", iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); + } + snprintf(stateTopic, 64, "%s/%s/ch%d/%s", topic, iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); + snprintf(discoveryTopic, 64, "%s/sensor/%s/ch%d_%s/config", MQTT_DISCOVERY_PREFIX, iv->name, rec->assign[i].ch, iv->getFieldName(i, rec)); + snprintf(uniq_id, 32, "ch%d_%s", rec->assign[i].ch, iv->getFieldName(i, rec)); + const char *devCls = getFieldDeviceClass(rec->assign[i].fieldId); + const char *stateCls = getFieldStateClass(rec->assign[i].fieldId); + + doc["name"] = name; + doc["stat_t"] = stateTopic; + doc["unit_of_meas"] = iv->getUnit(i, rec); + doc["uniq_id"] = String(iv->serial.u64, HEX) + "_" + uniq_id; + doc["dev"] = deviceObj; + doc["exp_aft"] = invertval + 5; // add 5 sec if connection is bad or ESP too slow @TODO: stimmt das wirklich als expire!? + if (devCls != NULL) + doc["dev_cla"] = devCls; + if (stateCls != NULL) + doc["stat_cla"] = stateCls; + + serializeJson(doc, buffer); + sendMsg2(discoveryTopic, buffer, true); + // DPRINTLN(DBG_INFO, F("mqtt sent")); + doc.clear(); + } + + yield(); + } + } +} + + +//----------------------------------------------------------------------------- +const char *getFieldDeviceClass(uint8_t fieldId) { + uint8_t pos = 0; + for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { + if (deviceFieldAssignment[pos].fieldId == fieldId) + break; + } + return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : deviceClasses[deviceFieldAssignment[pos].deviceClsId]; +} + +//----------------------------------------------------------------------------- +const char *getFieldStateClass(uint8_t fieldId) { + uint8_t pos = 0; + for (; pos < DEVICE_CLS_ASSIGN_LIST_LEN; pos++) { + if (deviceFieldAssignment[pos].fieldId == fieldId) + break; + } + return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId]; +} + private: void reconnect(void) { DPRINTLN(DBG_DEBUG, F("mqtt.h:reconnect"));