From e255e971419f1f5ac85910da16fb47336655a89b Mon Sep 17 00:00:00 2001 From: Bobby Noelte Date: Tue, 21 Jan 2025 17:02:48 +0100 Subject: [PATCH] Fix Gesamtlast (#398) Make Gesamtlast endpoint understand the legacy load mesaurement data format. Signed-off-by: Bobby Noelte --- src/akkudoktoreos/core/dataabc.py | 27 +++++++++++++++++++++++++++ src/akkudoktoreos/server/eos.py | 23 +++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/akkudoktoreos/core/dataabc.py b/src/akkudoktoreos/core/dataabc.py index 23051fd..a1d55b7 100644 --- a/src/akkudoktoreos/core/dataabc.py +++ b/src/akkudoktoreos/core/dataabc.py @@ -759,6 +759,33 @@ class DataSequence(DataBase, MutableSequence): return dates, values + def key_from_lists(self, key: str, dates: List[DateTime], values: List[float]) -> None: + """Update the DataSequence from lists of datetime and value elements. + + The dates list should represent the date_time of each DataRecord, and the values list + should represent the corresponding data values for the specified key. + + Args: + key (str): The field name in the DataRecord that corresponds to the values in the Series. + dates: List of datetime elements. + values: List of values corresponding to the specified key in the data records. + """ + self._validate_key_writable(key) + + for i, date_time in enumerate(dates): + # Ensure datetime objects are normalized + date_time = to_datetime(date_time, to_maxtime=False) if date_time else None + # Check if there's an existing record for this date_time + existing_record = next((r for r in self.records if r.date_time == date_time), None) + if existing_record: + # Update existing record's specified key + setattr(existing_record, key, values[i]) + else: + # Create a new DataRecord if none exists + new_record = self.record_class()(date_time=date_time, **{key: values[i]}) + self.records.append(new_record) + self.sort_by_datetime() + def key_to_series( self, key: str, diff --git a/src/akkudoktoreos/server/eos.py b/src/akkudoktoreos/server/eos.py index 72194f5..6a3052b 100755 --- a/src/akkudoktoreos/server/eos.py +++ b/src/akkudoktoreos/server/eos.py @@ -616,19 +616,30 @@ def fastapi_gesamtlast(request: GesamtlastRequest) -> list[float]: measurement_key = "measurement_load0_mr" measurement_eos.key_delete_by_datetime(key=measurement_key) # delete all load0_mr measurements energy = {} - for data_dict in request.measured_data: - for date_time, value in data_dict.items(): - dt_str = to_datetime(date_time, as_string=True) + try: + for data_dict in request.measured_data: + dt_str = to_datetime(data_dict["time"], as_string=True) + value = float(data_dict["Last"]) energy[dt_str] = value - energy_mr = 0 + except Exception as e: + raise HTTPException( + status_code=404, + detail=f"Invalid measured data: {e}.", + ) + energy_mr_dates = [] + energy_mr_values = [] + energy_mr = 0.0 for i, key in enumerate(sorted(energy)): energy_mr += energy[key] dt = to_datetime(key) if i == 0: # first element, add start value before dt_before = dt - to_duration("1 hour") - measurement_eos.update_value(date=dt_before, key=measurement_key, value=0.0) - measurement_eos.update_value(date=dt, key=measurement_key, value=energy_mr) + energy_mr_dates.append(dt_before) + energy_mr_values.append(0.0) + energy_mr_dates.append(dt) + energy_mr_values.append(energy_mr) + measurement_eos.key_from_lists(measurement_key, energy_mr_dates, energy_mr_values) # Create load forecast prediction_eos.update_data(force_update=True)