From 592337800ec0afaeed43f5aba4718541c92de037 Mon Sep 17 00:00:00 2001 From: DanielR92 Date: Sun, 20 Oct 2024 11:35:02 +0200 Subject: [PATCH] =?UTF-8?q?M=C3=B6gliche=20verbesserung=20in=20ZE-Loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/zeroExport/powermeter.h | 116 +++++++++++++++++++--------- 1 file changed, 81 insertions(+), 35 deletions(-) diff --git a/src/plugins/zeroExport/powermeter.h b/src/plugins/zeroExport/powermeter.h index 17bce333..77e8d0d4 100644 --- a/src/plugins/zeroExport/powermeter.h +++ b/src/plugins/zeroExport/powermeter.h @@ -57,82 +57,128 @@ class powermeter { return true; } - /** loop - * Arbeitsschleife - * @param void - * @returns void - * @todo emergency + /** + * @brief Main loop function for processing power meter data and publishing to MQTT. + * + * This function performs the following tasks: + * - Checks if the interval since the last execution is sufficient. + * - Updates the timestamp of the last execution. + * - Checks if the MQTT connection is active. + * - Iterates through all configured power meter groups. + * - For each group, checks if it is enabled and not in sleep mode. + * - Avoids unnecessary calculations if the refresh interval has not passed. + * - Depending on the power meter type, retrieves the current power consumption. + * - Writes the power data to a buffer and updates the group's power value. + * - If MQTT is connected, publishes the power data to the MQTT broker. + * + * @note This function assumes that the following macros and functions are defined: + * - ZEROEXPORT_DEBUG + * - ZEROEXPORT_MAX_GROUPS + * - ZEROEXPORT_POWERMETER_SHELLY + * - ZEROEXPORT_POWERMETER_TASMOTA + * - ZEROEXPORT_POWERMETER_HICHI + * - ZEROEXPORT_POWERMETER_TIBBER + * - ZEROEXPORT_POWERMETER_SHRDZM + * - millis() + * - DBGPRINTLN() + * - getPowermeterWattsShelly() + * - getPowermeterWattsTasmota() + * - getPowermeterWattsHichi() + * - getPowermeterWattsTibber() + * - getPowermeterWattsShrdzm() + * - bufferWrite() + * - ah::round1() + * + * @param void No parameters. + * @return void No return value. */ void loop(void) { - if (millis() - mPreviousTsp <= 1000) return; // skip when it is to fast - mPreviousTsp = millis(); + constexpr uint32_t interval = 1000; // Konstante für das Intervall + constexpr uint8_t bufferSize = 5; // Puffergröße + + uint32_t currentMillis = millis(); // Einmal die aktuelle Zeit abrufen + if (currentMillis - mPreviousTsp <= interval) return; // Bei zu kurzem Intervall überspringen + mPreviousTsp = currentMillis; #ifdef ZEROEXPORT_DEBUG if (mCfg->debug) DBGPRINTLN(F("pm Takt:")); - #endif /*ZEROEXPORT_DEBUG*/ + #endif - bool result = false; - float power = 0.0; + // Überprüfen, ob die MQTT-Verbindung einmalig aktiv ist + const bool mqttConnected = mMqtt->isConnected(); + + char topic[64]; // Puffer für das Topic + char payload[16]; // Puffer für das Payload - for (u_short group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { - if ((!mCfg->groups[group].enabled) || (mCfg->groups[group].sleep)) continue; + for (u_short group = 0; group < ZEROEXPORT_MAX_GROUPS; ++group) { + auto& groupCfg = mCfg->groups[group]; + if (!groupCfg.enabled || groupCfg.sleep) continue; - if ((millis() - mCfg->groups[group].pm_peviousTsp) < ((uint16_t)mCfg->groups[group].pm_refresh * 1000)) continue; - mCfg->groups[group].pm_peviousTsp = millis(); + // Optimierung: Berechnungen vermeiden, wenn keine Aktualisierung nötig ist + uint32_t refreshInterval = static_cast(groupCfg.pm_refresh) * interval; + if (currentMillis - groupCfg.pm_peviousTsp < refreshInterval) continue; + groupCfg.pm_peviousTsp = currentMillis; #ifdef ZEROEXPORT_DEBUG if (mCfg->debug) DBGPRINTLN(F("pm Do:")); - #endif /*ZEROEXPORT_DEBUG*/ + #endif - result = false; - power = 0.0; + bool result = false; + float power = 0.0; - switch (mCfg->groups[group].pm_type) { -#if defined(ZEROEXPORT_POWERMETER_SHELLY) + // Verwenden von `switch-case`, um abhängig vom Powermeter-Typ zu entscheiden + switch (groupCfg.pm_type) { + #if defined(ZEROEXPORT_POWERMETER_SHELLY) case zeroExportPowermeterType_t::Shelly: result = getPowermeterWattsShelly(group, &power); break; -#endif -#if defined(ZEROEXPORT_POWERMETER_TASMOTA) + #endif + #if defined(ZEROEXPORT_POWERMETER_TASMOTA) case zeroExportPowermeterType_t::Tasmota: result = getPowermeterWattsTasmota(*mLog, group, &power); break; -#endif -#if defined(ZEROEXPORT_POWERMETER_HICHI) + #endif + #if defined(ZEROEXPORT_POWERMETER_HICHI) case zeroExportPowermeterType_t::Hichi: result = getPowermeterWattsHichi(*mLog, group, &power); break; -#endif -#if defined(ZEROEXPORT_POWERMETER_TIBBER) + #endif + #if defined(ZEROEXPORT_POWERMETER_TIBBER) /* Anscheinend nutzt bei mir Tibber auch diese Freq. 862.75 MHz - keine Verbindung 863.00 MHz - geht (standard) jedoch hat Tibber dann Probleme... => 4 & 5 Balken 863.25 MHz - geht (ohne Tibber Probleme) => 3 & 4 Balken */ case zeroExportPowermeterType_t::Tibber: - if (mCfg->groups[group].pm_refresh < 3) mCfg->groups[group].pm_refresh = 3; + // Mindestens 3 Sekunden Refresh für Tibber + if (groupCfg.pm_refresh < 3) groupCfg.pm_refresh = 3; result = getPowermeterWattsTibber(group, &power); break; -#endif -#if defined(ZEROEXPORT_POWERMETER_SHRDZM) + #endif + #if defined(ZEROEXPORT_POWERMETER_SHRDZM) case zeroExportPowermeterType_t::Shrdzm: result = getPowermeterWattsShrdzm(group, &power); break; -#endif + #endif + default: + continue; // Ungültiger Powermeter-Typ, überspringen } if (result) { - bufferWrite(power, group); - mCfg->groups[group].power = power; - - // MQTT - Powermeter - if (mMqtt->isConnected()) { - mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), String(ah::round1(power)).c_str(), false); + bufferWrite(power, group); // Power in den Puffer schreiben + groupCfg.power = power; // Aktualisiere die Gruppenleistung + + // Nur wenn MQTT verbunden ist, eine Nachricht senden + if (mqttConnected) { + snprintf(topic, sizeof(topic), "zero/state/groups/%d/powermeter/P", group); + snprintf(payload, sizeof(payload), "%.1f", ah::round1(power)); + mMqtt->publish(topic, payload, false); } } } } + /** getDataAVG * Holt die Daten vom Powermeter * @param group