Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZE-loop improvemt #1772

Open
wants to merge 1 commit into
base: zero-export
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 81 additions & 35 deletions src/plugins/zeroExport/powermeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint32_t>(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
Expand Down