From fc4db679fb4c77b9c7ba3b4ecef0f96f0c81798c Mon Sep 17 00:00:00 2001 From: LKuemmel <76958050+LKuemmel@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:58:31 +0200 Subject: [PATCH] fix simcount nan (#1657) * fix simcount nan * fix --- packages/modules/common/simcount/_simcount.py | 14 +++++++++++++- .../modules/common/simcount/_simcounter_store.py | 12 ++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/modules/common/simcount/_simcount.py b/packages/modules/common/simcount/_simcount.py index 66f14d3452..5c07af4a44 100644 --- a/packages/modules/common/simcount/_simcount.py +++ b/packages/modules/common/simcount/_simcount.py @@ -2,12 +2,13 @@ Berechnet die importierte und exportierte Leistung, wenn der Zähler / PV-Modul / Speicher diese nicht liefert. """ import logging +import math import time from control import data as data_module from modules.common.simcount._calculate import calculate_import_export from modules.common.simcount.simcounter_state import SimCounterState -from modules.common.simcount._simcounter_store import get_sim_counter_store +from modules.common.simcount._simcounter_store import get_sim_counter_store, restore_last_energy log = logging.getLogger(__name__) @@ -30,12 +31,21 @@ def sim_count(power_present: float, topic: str = "", data: SimCounterState = Non timestamp_present = time.time() previous_state = store.load(prefix, topic) if data is None else data + if math.isnan(power_present): + raise ValueError("power_present is NaN.") + if isinstance(power_present, (int, float)): if previous_state is None: log.debug("No previous state found. Starting new simulation.") return store.initialize(prefix, topic, power_present, timestamp_present) else: log.debug("Previous state: %s", previous_state) + if math.isnan(previous_state.imported): + log.error("imported is NaN. Reset simcount state.") + previous_state.imported = restore_last_energy(topic, "imported") + if math.isnan(previous_state.exported): + log.error("exported is NaN. Reset simcount state.") + previous_state.exported = restore_last_energy(topic, "exported") control_interval = data_module.data.general_data.data.control_interval if 2 * control_interval < timestamp_present - previous_state.timestamp: log.warning("Time difference between previous state and current state is too large. " @@ -44,6 +54,8 @@ def sim_count(power_present: float, topic: str = "", data: SimCounterState = Non else: hours_since_previous = (timestamp_present - previous_state.timestamp) / 3600 imported, exported = calculate_import_export(hours_since_previous, previous_state.power, power_present) + if math.isnan(imported) or math.isnan(exported): + raise ValueError("imported or exported is NaN. Retain previous state.") current_state = SimCounterState( timestamp_present, power_present, diff --git a/packages/modules/common/simcount/_simcounter_store.py b/packages/modules/common/simcount/_simcounter_store.py index aaaf7b84fe..587a8d1245 100644 --- a/packages/modules/common/simcount/_simcounter_store.py +++ b/packages/modules/common/simcount/_simcounter_store.py @@ -6,7 +6,10 @@ from paho.mqtt.client import Client as MqttClient, MQTTMessage +from control import data from helpermodules import pub, compatibility +from helpermodules.utils.topic_parser import get_index, get_second_index +from modules.common.component_type import type_to_topic_mapping from modules.common.simcount.simcounter_state import SimCounterState from modules.common.store import ramdisk_write, ramdisk_read_float from modules.common.store.ramdisk.io import RamdiskReadError @@ -182,5 +185,14 @@ def save(self, prefix: str, topic: str, state: SimCounterState): pub.Pub().pub(topic + "simulation", vars(state)) +def restore_last_energy(topic: str, value: str): + device_id = get_index(topic) + component_id = get_second_index(topic) + module_type = type_to_topic_mapping( + data.data.system_data[f"device{device_id}"].components[f"component{component_id}"].component_config.type) + module = getattr(data.data, f"{module_type}_data")[f"{module_type}{get_second_index(topic)}"].data.get + return getattr(module, value) + + def get_sim_counter_store() -> SimCounterStore: return SimCounterStoreRamdisk() if compatibility.is_ramdisk_in_use() else SimCounterStoreBroker()