diff --git a/src/app.cpp b/src/app.cpp
index eb591307..cd222136 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -170,7 +170,7 @@ void app::loop(void) {
 
         if ((++mMqttTicker >= mMqttInterval) && (mMqttInterval != 0xffff) && mMqttActive) {
             mMqttTicker = 0;
-            sendMqtt();
+            mMqtt.sendIvData(mSys, mUtcTimestamp, mMqttSendList);
         }
 
         if (mConfig.serialShowIv) {
@@ -525,118 +525,6 @@ void app::getAvailNetworks(JsonObject obj) {
 }
 
 
-//-----------------------------------------------------------------------------
-void app::sendMqtt(void) {
-    mMqtt.isConnected(true);  // really needed? See comment from HorstG-57 #176
-    char topic[32 + MAX_NAME_LENGTH], val[32];
-    float total[4];
-    bool sendTotal = false;
-    bool totalIncomplete = false;
-    snprintf(val, 32, "%ld", millis() / 1000);
-
-    mMqtt.sendMsg("uptime", val);
-
-    if(mMqttSendList.empty())
-        return;
-
-    while(!mMqttSendList.empty()) {
-        memset(total, 0, sizeof(float) * 4);
-        for (uint8_t id = 0; id < mSys->getNumInverters(); id++) {
-            Inverter<> *iv = mSys->getInverterByPos(id);
-            if (NULL == iv)
-                continue; // skip to next inverter
-
-            record_t<> *rec = iv->getRecordStruct(mMqttSendList.front());
-
-            if(mMqttSendList.front() == RealTimeRunData_Debug) {
-                // inverter status
-                uint8_t status = MQTT_STATUS_AVAIL_PROD;
-                if (!iv->isAvailable(mUtcTimestamp, rec)) {
-                    status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
-                    totalIncomplete = true;
-                }
-                else if (!iv->isProducing(mUtcTimestamp, rec)) {
-                    if (MQTT_STATUS_AVAIL_PROD == status)
-                        status = MQTT_STATUS_AVAIL_NOT_PROD;
-                }
-                snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
-                snprintf(val, 32, "%s%s%s%s",
-                    (MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not yet " : "",
-                    "available and ",
-                    (MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
-                    (MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "" : "producing"
-                );
-                mMqtt.sendMsg(topic, val);
-
-                snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->name);
-                snprintf(val, 32, "%d", status);
-                mMqtt.sendMsg(topic, val);
-
-                snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->name);
-                snprintf(val, 48, "%i", iv->getLastTs(rec) * 1000);
-                mMqtt.sendMsg(topic, val);
-            }
-
-            // data
-            if(iv->isAvailable(mUtcTimestamp, rec)) {
-                for (uint8_t i = 0; i < rec->length; i++) {
-                    snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
-                    snprintf(val, 10, "%.3f", iv->getValue(i, rec));
-                    mMqtt.sendMsg(topic, val);
-
-                    // calculate total values for RealTimeRunData_Debug
-                    if (mMqttSendList.front() == RealTimeRunData_Debug) {
-                        if (CH0 == rec->assign[i].ch) {
-                            switch (rec->assign[i].fieldId) {
-                                case FLD_PAC:
-                                    total[0] += iv->getValue(i, rec);
-                                    break;
-                                case FLD_YT:
-                                    total[1] += iv->getValue(i, rec);
-                                    break;
-                                case FLD_YD:
-                                    total[2] += iv->getValue(i, rec);
-                                    break;
-                                case FLD_PDC:
-                                    total[3] += iv->getValue(i, rec);
-                                    break;
-                            }
-                        }
-                        sendTotal = true;
-                    }
-                    yield();
-                }
-            }
-        }
-
-        mMqttSendList.pop(); // remove from list once all inverters were processed
-
-        if ((true == sendTotal) && (false == totalIncomplete)) {
-            uint8_t fieldId;
-            for (uint8_t i = 0; i < 4; i++) {
-                switch (i) {
-                    default:
-                    case 0:
-                        fieldId = FLD_PAC;
-                        break;
-                    case 1:
-                        fieldId = FLD_YT;
-                        break;
-                    case 2:
-                        fieldId = FLD_YD;
-                        break;
-                    case 3:
-                        fieldId = FLD_PDC;
-                        break;
-                }
-                snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
-                snprintf(val, 10, "%.3f", total[i]);
-                mMqtt.sendMsg(topic, val);
-            }
-        }
-    }
-}
-
 //-----------------------------------------------------------------------------
 void app::resetSystem(void) {
     mUptimeSecs = 0;
diff --git a/src/web/mqtt.h b/src/web/mqtt.h
index 3d18b45a..f778e2be 100644
--- a/src/web/mqtt.h
+++ b/src/web/mqtt.h
@@ -95,76 +95,184 @@ class mqtt {
         }
 
         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<JsonObject>();
-            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));
+            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<JsonObject>();
+                    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();
                 }
-                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();
         }
-    }
-}
 
+        void sendIvData(HMSYSTEM *sys, uint32_t mUtcTs, std::queue<uint8_t> list) {
+            isConnected(true);  // really needed? See comment from HorstG-57 #176
+            char topic[32 + MAX_NAME_LENGTH], val[32];
+            float total[4];
+            bool sendTotal = false;
+            bool totalIncomplete = false;
+            snprintf(val, 32, "%ld", millis() / 1000);
+
+            sendMsg("uptime", val);
+
+            if(list.empty())
+                return;
+
+            while(!list.empty()) {
+                memset(total, 0, sizeof(float) * 4);
+                for (uint8_t id = 0; id < sys->getNumInverters(); id++) {
+                    Inverter<> *iv = sys->getInverterByPos(id);
+                    if (NULL == iv)
+                        continue; // skip to next inverter
+
+                    record_t<> *rec = iv->getRecordStruct(list.front());
+
+                    if(list.front() == RealTimeRunData_Debug) {
+                        // inverter status
+                        uint8_t status = MQTT_STATUS_AVAIL_PROD;
+                        if (!iv->isAvailable(mUtcTs, rec)) {
+                            status = MQTT_STATUS_NOT_AVAIL_NOT_PROD;
+                            totalIncomplete = true;
+                        }
+                        else if (!iv->isProducing(mUtcTs, rec)) {
+                            if (MQTT_STATUS_AVAIL_PROD == status)
+                                status = MQTT_STATUS_AVAIL_NOT_PROD;
+                        }
+                        snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available_text", iv->name);
+                        snprintf(val, 32, "%s%s%s%s",
+                            (MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "not yet " : "",
+                            "available and ",
+                            (MQTT_STATUS_AVAIL_NOT_PROD) ? "not " : "",
+                            (MQTT_STATUS_NOT_AVAIL_NOT_PROD) ? "" : "producing"
+                        );
+                        sendMsg(topic, val);
+
+                        snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->name);
+                        snprintf(val, 32, "%d", status);
+                        sendMsg(topic, val);
+
+                        snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->name);
+                        snprintf(val, 48, "%i", iv->getLastTs(rec) * 1000);
+                        sendMsg(topic, val);
+                    }
 
-//-----------------------------------------------------------------------------
-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];
-}
+                    // data
+                    if(iv->isAvailable(mUtcTs, rec)) {
+                        for (uint8_t i = 0; i < rec->length; i++) {
+                            snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]);
+                            snprintf(val, 10, "%.3f", iv->getValue(i, rec));
+                            sendMsg(topic, val);
+
+                            // calculate total values for RealTimeRunData_Debug
+                            if (list.front() == RealTimeRunData_Debug) {
+                                if (CH0 == rec->assign[i].ch) {
+                                    switch (rec->assign[i].fieldId) {
+                                        case FLD_PAC:
+                                            total[0] += iv->getValue(i, rec);
+                                            break;
+                                        case FLD_YT:
+                                            total[1] += iv->getValue(i, rec);
+                                            break;
+                                        case FLD_YD:
+                                            total[2] += iv->getValue(i, rec);
+                                            break;
+                                        case FLD_PDC:
+                                            total[3] += iv->getValue(i, rec);
+                                            break;
+                                    }
+                                }
+                                sendTotal = true;
+                            }
+                            yield();
+                        }
+                    }
+                }
 
-//-----------------------------------------------------------------------------
-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];
-}
+                list.pop(); // remove from list once all inverters were processed
+
+                if ((true == sendTotal) && (false == totalIncomplete)) {
+                    uint8_t fieldId;
+                    for (uint8_t i = 0; i < 4; i++) {
+                        switch (i) {
+                            default:
+                            case 0:
+                                fieldId = FLD_PAC;
+                                break;
+                            case 1:
+                                fieldId = FLD_YT;
+                                break;
+                            case 2:
+                                fieldId = FLD_YD;
+                                break;
+                            case 3:
+                                fieldId = FLD_PDC;
+                                break;
+                        }
+                        snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]);
+                        snprintf(val, 10, "%.3f", total[i]);
+                        sendMsg(topic, val);
+                    }
+                }
+            }
+        }
+
+        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) {