Skip to content
Merged
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
14 changes: 10 additions & 4 deletions packages/control/chargelog/chargelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from control import data
from dataclass_utils import asdict
from helpermodules.measurement_logging.process_log import (
FILE_ERRORS, CalculationType, _analyse_energy_source,
_process_entries, analyse_percentage, get_log_from_date_until_now, get_totals)
FILE_ERRORS, CalculationType, _analyse_energy_source, _process_entries, get_totals)
from helpermodules.pub import Pub
from helpermodules import timecheck
from helpermodules.utils.json_file_handler import write_and_check
Expand Down Expand Up @@ -203,6 +202,13 @@ def _get_range_charged(log_data, charging_ev) -> float:
return None


def _calc_power_source_percentages(log_data) -> Dict[str, float]:
power_source = {}
for source in ENERGY_SOURCES:
power_source[source] = log_data.charged_energy_by_source[source] / log_data.imported_since_mode_switch
Comment on lines +206 to +208
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_calc_power_source_percentages can raise ZeroDivisionError when log_data.imported_since_mode_switch is 0/0.0 (e.g., export-only sessions, or very small imports that were rounded to 0.0 in _create_entry). Right now this is only handled indirectly via get_value_or_default, which will emit a full exception log for a normal/expected scenario. Consider explicitly guarding on imported_since_mode_switch <= 0 and returning the zero-dict without raising, and optionally rounding the ratios (e.g., to 4 decimals) to keep the JSON output stable/consistent with other energy-mix calculations.

Suggested change
power_source = {}
for source in ENERGY_SOURCES:
power_source[source] = log_data.charged_energy_by_source[source] / log_data.imported_since_mode_switch
"""Calculate share of each energy source in imported energy.
Returns a dict mapping each source to its fraction of the total imported
energy since the last mode switch. If the imported energy is zero or
negative (e.g. export-only session), all fractions are returned as 0.0.
"""
# Avoid ZeroDivisionError in export-only or zero-import sessions.
if getattr(log_data, "imported_since_mode_switch", 0) <= 0:
return {source: 0.0 for source in ENERGY_SOURCES}
total_imported = log_data.imported_since_mode_switch
power_source: Dict[str, float] = {}
for source in ENERGY_SOURCES:
# Use .get to be robust if a source key is missing.
charged_by_source = log_data.charged_energy_by_source.get(source, 0.0)
ratio = charged_by_source / total_imported
# Round to keep JSON output stable/consistent with other energy-mix calculations.
power_source[source] = round(ratio, 4)

Copilot uses AI. Check for mistakes.
return power_source


def save_data(chargepoint, charging_ev):
""" json-Objekt für den Log-Eintrag erstellen, an die Datei anhängen und die Daten, die sich auf den Ladevorgang
beziehen, löschen.
Expand Down Expand Up @@ -245,8 +251,8 @@ def _create_entry(chargepoint, charging_ev):
# log_data.imported_since_mode_switch / (duration / 3600)
power = get_value_or_default(lambda: round(log_data.imported_since_mode_switch / (time_charged / 3600), 2))
calc_energy_costs(chargepoint, True)
energy_source = get_value_or_default(lambda: analyse_percentage(get_log_from_date_until_now(
log_data.timestamp_mode_switch)["totals"])["energy_source"])
energy_source = get_value_or_default(lambda: _calc_power_source_percentages(log_data), {
source: 0 for source in ENERGY_SOURCES})
Comment on lines +254 to +255
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The energy-mix for the charge log entry now comes from charged_energy_by_source / imported_since_mode_switch, which is a behavioral change from using the measurement-log totals. Since this file already has unit tests for cost/source calculations (chargelog_test.py), please add coverage for the new log-entry mix calculation (including edge cases like imported_since_mode_switch == 0 and small rounded values) to prevent regressions.

Copilot uses AI. Check for mistakes.
costs = round(log_data.costs, 2)

new_entry = {
Expand Down