diff --git a/packages/helpermodules/measurement_logging/process_log.py b/packages/helpermodules/measurement_logging/process_log.py index b7259bbe3f..60feb03e6a 100644 --- a/packages/helpermodules/measurement_logging/process_log.py +++ b/packages/helpermodules/measurement_logging/process_log.py @@ -408,6 +408,19 @@ def calc_energy_imported_by_source(energy_imported, energy_source): pv = entry["pv"]["all"]["energy_exported"] if "all" in entry["pv"].keys() else 0 grid_imported, grid_exported = get_grid_from(entry) consumption = grid_imported - grid_exported + pv + bat_exported - bat_imported + cp_exported + for type in ("bat", "cp"): + if entry[type]["all"]["energy_imported"] > consumption: + consumption += entry[type]["all"]["energy_imported"] - consumption + grid_imported += entry[type]["all"]["energy_imported"] - grid_imported + log.debug(f"Angepasste Verbrauchswerte für {type} um " + f"{entry[type]['all']['energy_imported'] - consumption} kWh") + for counter in entry["counter"].values(): + if counter["grid"] is False: + if counter["energy_imported"] > consumption: + consumption += counter["energy_imported"] - consumption + grid_imported += counter["energy_imported"] - grid_imported + log.debug(f"Angepasste Verbrauchswerte für {type} um " + f"{entry[type]['all']['energy_imported'] - consumption} kWh") try: if grid_exported > pv: # Ins Netz eingespeiste Leistung kam nicht von der PV-Anlage sondern aus dem Speicher diff --git a/packages/helpermodules/measurement_logging/process_log_test.py b/packages/helpermodules/measurement_logging/process_log_test.py index cd969fc8ee..0bf4e53d52 100644 --- a/packages/helpermodules/measurement_logging/process_log_test.py +++ b/packages/helpermodules/measurement_logging/process_log_test.py @@ -1,4 +1,8 @@ from copy import deepcopy +from unittest.mock import Mock +import pytest + +from helpermodules.measurement_logging import process_log from helpermodules.measurement_logging.process_log import ( analyse_percentage, _calculate_average_power, @@ -6,6 +10,11 @@ get_totals, CalculationType) +from helpermodules.measurement_logging.process_log_testdata import (counter_jumps_forward, + counter_jumps_forward_processed, + regular_daily_log_entry, + regular_daily_log_entry_processed) + def test_get_totals(daily_log_sample, daily_log_totals): # setup and execution @@ -52,3 +61,19 @@ def test_convert(daily_log_entry_kw, daily_log_sample): # evaluation assert entry == daily_log_entry_kw + + +@pytest.mark.parametrize("data, expected", [ + pytest.param(counter_jumps_forward, counter_jumps_forward_processed, id="counter jumps forward"), + pytest.param(regular_daily_log_entry, regular_daily_log_entry_processed, id="regular daily log entry") +]) +def test_get_daily_log(data, expected, monkeypatch): + # setup + collect_daily_log_data_mock = Mock(return_value=data) + monkeypatch.setattr(process_log, "_collect_daily_log_data", collect_daily_log_data_mock) + + # execution + daily_log_processed = process_log.get_daily_log("20250616") + + # evaluation + assert daily_log_processed == expected diff --git a/packages/helpermodules/measurement_logging/process_log_testdata.py b/packages/helpermodules/measurement_logging/process_log_testdata.py new file mode 100644 index 0000000000..147b6f3765 --- /dev/null +++ b/packages/helpermodules/measurement_logging/process_log_testdata.py @@ -0,0 +1,415 @@ +# Wenn ein Zwischenzähler nicht auslesbar war, soll beim Sprung der Anteil auf das Netz gerechnet werden. +counter_jumps_forward = {'entries': [{'bat': {'all': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}, + 'bat2': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}}, + 'counter': {'counter0': {'exported': 26029.945, + 'grid': True, + 'imported': 2728.572}, + 'counter2': {'exported': 26029.945, + 'grid': False, + 'imported': 0}}, + 'cp': {'all': {'exported': 0, 'imported': 12639.11}, + 'cp3': {'exported': 0, 'imported': 12639.11}, + 'cp4': {'exported': 0, 'imported': 0}, + 'cp5': {'exported': 0, 'imported': 0}}, + 'date': '14:25', + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'imported': 2324.001611140539}}, + 'prices': {'bat': 0.0002, 'grid': 0.0003, 'pv': 0.00015}, + 'pv': {'all': {'exported': 35827}, 'pv1': {'exported': 35827}}, + 'sh': {}, + 'timestamp': 1750767902}, + {'bat': {'all': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}, + 'bat2': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}}, + 'counter': {'counter0': {'exported': 26802.355, + 'grid': True, + 'imported': 2728.572}, + 'counter2': {'exported': 26029.945, + 'grid': True, + 'imported': 2728.572}}, + 'cp': {'all': {'exported': 0, 'imported': 12639.11}, + 'cp3': {'exported': 0, 'imported': 12639.11}, + 'cp4': {'exported': 0, 'imported': 0}, + 'cp5': {'exported': 0, 'imported': 0}}, + 'date': '14:30', + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'imported': 2361.178611303703}}, + 'prices': {'bat': 0.0002, 'grid': 0.0003, 'pv': 0.00015}, + 'pv': {'all': {'exported': 36636}, 'pv1': {'exported': 36636}}, + 'sh': {}, + 'timestamp': 1750768201}], + 'names': {'bat2': 'MQTT-Speicher', + 'counter0': 'MQTT-Zähler', + 'counter2': 'Test-Zähler', + 'cp3': 'MQTT-Ladepunkt', + 'cp4': 'MQTT-Ladepunkt', + 'cp5': 'MQTT-Ladepunkt', + 'ev0': 'Standard-Fahrzeug', + 'pv1': 'MQTT-Wechselrichter'}} + +counter_jumps_forward_processed = {'entries': [{'bat': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'exported': 3195.13, + 'imported': 629.37, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0, + 'soc': 48}, + 'bat2': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'exported': 3195.13, + 'imported': 629.37, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0, + 'soc': 48}}, + 'counter': {'counter0': {'energy_exported': 0.772, + 'energy_imported': 0.0, + 'exported': 26029.945, + 'grid': True, + 'imported': 2728.572, + 'power_average': -9.3, + 'power_exported': 9.3, + 'power_imported': 0}, + 'counter2': {'energy_exported': 0.0, + 'energy_imported': 2.729, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 2.729, + 'energy_imported_pv': 0.0, + 'exported': 26029.945, + 'grid': False, + 'imported': 0, + 'power_average': 32.852, + 'power_exported': 0, + 'power_imported': 32.852}}, + 'cp': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 12639.11, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp3': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 12639.11, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp4': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 0, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp5': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 0, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}}, + 'date': '14:25', + 'energy_source': {'bat': 0.0, 'cp': 0.0, 'grid': 1.0, 'pv': 0.0}, + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.037, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.037, + 'energy_imported_pv': 0.0, + 'imported': 2324.001611140539, + 'power_average': 0.448, + 'power_exported': 0, + 'power_imported': 0.448}}, + 'prices': {'bat': 0.0002, 'grid': 0.0003, 'pv': 0.00015}, + 'pv': {'all': {'energy_exported': 0.809, + 'energy_imported': 0.0, + 'exported': 35827, + 'power_average': -9.74, + 'power_exported': 9.74, + 'power_imported': 0}, + 'pv1': {'energy_exported': 0.809, + 'energy_imported': 0.0, + 'exported': 35827, + 'power_average': -9.74, + 'power_exported': 9.74, + 'power_imported': 0}}, + 'sh': {}, + 'timestamp': 1750767902}], + 'names': {'bat2': 'MQTT-Speicher', + 'counter0': 'MQTT-Zähler', + 'counter2': 'Test-Zähler', + 'cp3': 'MQTT-Ladepunkt', + 'cp4': 'MQTT-Ladepunkt', + 'cp5': 'MQTT-Ladepunkt', + 'ev0': 'Standard-Fahrzeug', + 'pv1': 'MQTT-Wechselrichter'}, + 'totals': {'bat': {'all': {'energy_exported': 0.0, 'energy_imported': 0.0}, + 'bat2': {'energy_exported': 0.0, 'energy_imported': 0.0}}, + 'counter': {'counter0': {'energy_exported': 772.0, + 'energy_imported': 0.0, + 'grid': True}, + 'counter2': {'energy_exported': 0.0, + 'energy_imported': 2729.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 2729.0, + 'energy_imported_pv': 0.0, + 'grid': False}}, + 'cp': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp3': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp4': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp5': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}}, + 'hc': {'all': {'energy_imported': 37.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 37.0, + 'energy_imported_pv': 0.0}}, + 'pv': {'all': {'energy_exported': 809.0}, + 'pv1': {'energy_exported': 809.0}}, + 'sh': {}}} + +regular_daily_log_entry = {'entries': [{'bat': {'all': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}, + 'bat2': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}}, + 'counter': {'counter0': {'exported': 26029.945, + 'grid': True, + 'imported': 2728.572}}, + 'cp': {'all': {'exported': 0, 'imported': 12639.11}, + 'cp3': {'exported': 0, 'imported': 12639.11}, + 'cp4': {'exported': 0, 'imported': 0}, + 'cp5': {'exported': 0, 'imported': 0}}, + 'date': '14:25', + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'imported': 2324.001611140539}}, + 'prices': {'bat': 0.0002, 'grid': 0.0003, 'pv': 0.00015}, + 'pv': {'all': {'exported': 35827}, 'pv1': {'exported': 35827}}, + 'sh': {}, + 'timestamp': 1750767902}, + {'bat': {'all': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}, + 'bat2': {'exported': 3195.13, + 'imported': 629.37, + 'soc': 48}}, + 'counter': {'counter0': {'exported': 26802.355, + 'grid': True, + 'imported': 2728.572}}, + 'cp': {'all': {'exported': 0, 'imported': 12639.11}, + 'cp3': {'exported': 0, 'imported': 12639.11}, + 'cp4': {'exported': 0, 'imported': 0}, + 'cp5': {'exported': 0, 'imported': 0}}, + 'date': '14:30', + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'imported': 2361.178611303703}}, + 'prices': {'bat': 0.0002, 'grid': 0.0003, 'pv': 0.00015}, + 'pv': {'all': {'exported': 36636}, 'pv1': {'exported': 36636}}, + 'sh': {}, + 'timestamp': 1750768201}], + 'names': {'bat2': 'MQTT-Speicher', + 'counter0': 'MQTT-Zähler', + 'counter2': 'Test-Zähler', + 'cp3': 'MQTT-Ladepunkt', + 'cp4': 'MQTT-Ladepunkt', + 'cp5': 'MQTT-Ladepunkt', + 'ev0': 'Standard-Fahrzeug', + 'pv1': 'MQTT-Wechselrichter'}} + +regular_daily_log_entry_processed = {'entries': [{'bat': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'exported': 3195.13, + 'imported': 629.37, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0, + 'soc': 48}, + 'bat2': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'exported': 3195.13, + 'imported': 629.37, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0, + 'soc': 48}}, + 'counter': {'counter0': {'energy_exported': 0.772, + 'energy_imported': 0.0, + 'exported': 26029.945, + 'grid': True, + 'imported': 2728.572, + 'power_average': -9.3, + 'power_exported': 9.3, + 'power_imported': 0}}, + 'cp': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 12639.11, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp3': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 12639.11, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp4': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 0, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}, + 'cp5': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0, + 'exported': 0, + 'imported': 0, + 'power_average': 0.0, + 'power_exported': 0, + 'power_imported': 0.0}}, + 'date': '14:25', + 'energy_source': {'bat': 0.0, + 'cp': 0.0, + 'grid': 0.0, + 'pv': 1.0}, + 'ev': {'ev0': {'soc': None}}, + 'hc': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.037, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.037, + 'imported': 2324.001611140539, + 'power_average': 0.448, + 'power_exported': 0, + 'power_imported': 0.448}}, + 'prices': {'bat': 0.0002, + 'grid': 0.0003, + 'pv': 0.00015}, + 'pv': {'all': {'energy_exported': 0.809, + 'energy_imported': 0.0, + 'exported': 35827, + 'power_average': -9.74, + 'power_exported': 9.74, + 'power_imported': 0}, + 'pv1': {'energy_exported': 0.809, + 'energy_imported': 0.0, + 'exported': 35827, + 'power_average': -9.74, + 'power_exported': 9.74, + 'power_imported': 0}}, + 'sh': {}, + 'timestamp': 1750767902}], + 'names': {'bat2': 'MQTT-Speicher', + 'counter0': 'MQTT-Zähler', + 'counter2': 'Test-Zähler', + 'cp3': 'MQTT-Ladepunkt', + 'cp4': 'MQTT-Ladepunkt', + 'cp5': 'MQTT-Ladepunkt', + 'ev0': 'Standard-Fahrzeug', + 'pv1': 'MQTT-Wechselrichter'}, + 'totals': {'bat': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0}, + 'bat2': {'energy_exported': 0.0, + 'energy_imported': 0.0}}, + 'counter': {'counter0': {'energy_exported': 772.0, + 'energy_imported': 0.0, + 'grid': True}}, + 'cp': {'all': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp3': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp4': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}, + 'cp5': {'energy_exported': 0.0, + 'energy_imported': 0.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 0.0}}, + 'hc': {'all': {'energy_imported': 37.0, + 'energy_imported_bat': 0.0, + 'energy_imported_cp': 0.0, + 'energy_imported_grid': 0.0, + 'energy_imported_pv': 37.0}}, + 'pv': {'all': {'energy_exported': 809.0}, + 'pv1': {'energy_exported': 809.0}}, + 'sh': {}}, + }