From 617f6686f81971774a585a591e8b198226aa0d6c Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Fri, 7 Jun 2024 14:52:51 +0200 Subject: [PATCH 1/2] fix simcount nan --- packages/modules/common/simcount/_simcount.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/modules/common/simcount/_simcount.py b/packages/modules/common/simcount/_simcount.py index 66f14d3452..996ded6008 100644 --- a/packages/modules/common/simcount/_simcount.py +++ b/packages/modules/common/simcount/_simcount.py @@ -2,6 +2,7 @@ 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 @@ -30,12 +31,16 @@ 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 isinstance(power_present, (int, float)): + if isinstance(power_present, (int, float)) and math.isnan(power_present) is False: 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) or math.isnan(previous_state.exported): + log.error("imported or exported is NaN. Reset simcount state.") + previous_state.imported = 0 + previous_state.exported = 0 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 +49,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, From aae7b7181dc364e31271372b71bf960bf32dbcfd Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Tue, 11 Jun 2024 08:12:33 +0200 Subject: [PATCH 2/2] fix --- packages/modules/common/simcount/_simcount.py | 17 +++++++++++------ .../common/simcount/_simcounter_store.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/modules/common/simcount/_simcount.py b/packages/modules/common/simcount/_simcount.py index 996ded6008..5c07af4a44 100644 --- a/packages/modules/common/simcount/_simcount.py +++ b/packages/modules/common/simcount/_simcount.py @@ -8,7 +8,7 @@ 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__) @@ -31,16 +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 isinstance(power_present, (int, float)) and math.isnan(power_present) is False: + 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) or math.isnan(previous_state.exported): - log.error("imported or exported is NaN. Reset simcount state.") - previous_state.imported = 0 - previous_state.exported = 0 + 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. " 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()