diff --git a/.env b/.env index 35f21dbf..739e0723 100644 --- a/.env +++ b/.env @@ -11,7 +11,7 @@ DOCKER_COMPOSE_DATA_DIR=${HOME}/.local/share/net.akkudoktor.eos # ----------------------------------------------------------------------------- # Image / build # ----------------------------------------------------------------------------- -VERSION=0.3.0.dev2610261491542381 +VERSION=0.3.0.dev2610291327175670 PYTHON_VERSION=3.13.15 # ----------------------------------------------------------------------------- diff --git a/config.yaml b/config.yaml index 88e6eae0..ac29210b 100644 --- a/config.yaml +++ b/config.yaml @@ -6,7 +6,7 @@ # the root directory (no add-on folder as usual). name: "Akkudoktor-EOS" -version: "0.3.0.dev2610261491542381" +version: "0.3.0.dev2610291327175670" slug: "eos" description: "Akkudoktor-EOS add-on" url: "https://github.com/Akkudoktor-EOS/EOS" diff --git a/docs/_generated/configadapter.md b/docs/_generated/configadapter.md index f4ca9376..0023fbfa 100644 --- a/docs/_generated/configadapter.md +++ b/docs/_generated/configadapter.md @@ -140,7 +140,7 @@ e.g. devices/batteries/0/capacity_wh | | device_instruction_entity_ids | `Optional[list[str]]` | `rw` | `None` | Entity IDs for device (resource) instructions to be updated by EOS. The device ids (resource ids) have to be prepended by 'sensor.eos_' to build the entity_id. E.g. The instruction for device id 'battery1' becomes the entity_id 'sensor.eos_battery1'. | -| device_measurement_entity_ids | `Optional[dict[str, str]]` | `rw` | `None` | Mapping of EOS measurement keys used by device (resource) simulations to Home Assistant entity IDs. | +| device_measurement_entity_ids | `Optional[dict[str, str]]` | `rw` | `None` | Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key. | | eos_device_instruction_entity_ids | `list[str]` | `ro` | `N/A` | Entity IDs for energy management instructions available at EOS. | | eos_solution_entity_ids | `list[str]` | `ro` | `N/A` | Entity IDs for optimization solution available at EOS. | | grid_export_emr_entity_ids | `Optional[list[str]]` | `rw` | `None` | Entity ID(s) of export to grid energy meter readings [kWh] | @@ -179,8 +179,8 @@ E.g. solution key 'battery1_idle_op_mode' becomes the entity_id 'sensor.eos_batt "sensor.pv_energy_total_kwh" ], "device_measurement_entity_ids": { - "ev11_soc_factor": "sensor.ev11_soc_factor", - "battery1_soc_factor": "sensor.battery1_soc_factor" + "ev11-soc-factor": "sensor.ev11_soc_factor", + "battery1-soc-factor": "sensor.battery1_soc_factor" }, "device_instruction_entity_ids": [ "sensor.eos_battery1" @@ -219,8 +219,8 @@ E.g. solution key 'battery1_idle_op_mode' becomes the entity_id 'sensor.eos_batt "sensor.pv_energy_total_kwh" ], "device_measurement_entity_ids": { - "ev11_soc_factor": "sensor.ev11_soc_factor", - "battery1_soc_factor": "sensor.battery1_soc_factor" + "ev11-soc-factor": "sensor.ev11_soc_factor", + "battery1-soc-factor": "sensor.battery1_soc_factor" }, "device_instruction_entity_ids": [ "sensor.eos_battery1" diff --git a/docs/_generated/openapi.md b/docs/_generated/openapi.md index c557ccdb..cb54b3f8 100644 --- a/docs/_generated/openapi.md +++ b/docs/_generated/openapi.md @@ -1,6 +1,6 @@ # Akkudoktor-EOS -**Version**: `v0.3.0.dev2610261491542381` +**Version**: `v0.3.0.dev2610291327175670` **Description**: This project provides a comprehensive solution for simulating and optimizing an energy system based on renewable energy sources. With a focus on photovoltaic (PV) systems, battery storage (batteries), load management (consumer requirements), heat pumps, electric vehicles, and consideration of electricity price data, this system enables forecasting and optimization of energy flow and costs over a specified period. @@ -2023,7 +2023,7 @@ Return: **Request Body**: - `application/json`: { - "anyOf": [ + "oneOf": [ { "$ref": "#/components/schemas/PowerMeasurement" }, @@ -2052,6 +2052,20 @@ Return: "$ref": "#/components/schemas/DDBCActuatorStatus" } ], + "discriminator": { + "propertyName": "type", + "mapping": { + "PowerMeasurement": "#/components/schemas/PowerMeasurement", + "EnergyMeasurement": "#/components/schemas/EnergyMeasurement", + "PPBCPowerProfileStatus": "#/components/schemas/PPBCPowerProfileStatus", + "OMBCStatus": "#/components/schemas/OMBCStatus", + "FRBCActuatorStatus": "#/components/schemas/FRBCActuatorStatus", + "FRBCEnergyStatus": "#/components/schemas/FRBCEnergyStatus", + "FRBCStorageStatus": "#/components/schemas/FRBCStorageStatus", + "FRBCTimerStatus": "#/components/schemas/FRBCTimerStatus", + "DDBCActuatorStatus": "#/components/schemas/DDBCActuatorStatus" + } + }, "description": "Resource Status.", "title": "Status" } diff --git a/openapi.json b/openapi.json index b3c49551..0e6b64c6 100644 --- a/openapi.json +++ b/openapi.json @@ -8,7 +8,7 @@ "name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html" }, - "version": "v0.3.0.dev2610261491542381" + "version": "v0.3.0.dev2610291327175670" }, "paths": { "/v1/measurement/battery-capacity/{battery_id}": { @@ -1164,7 +1164,7 @@ "content": { "application/json": { "schema": { - "anyOf": [ + "oneOf": [ { "$ref": "#/components/schemas/PowerMeasurement" }, @@ -1193,6 +1193,20 @@ "$ref": "#/components/schemas/DDBCActuatorStatus" } ], + "discriminator": { + "propertyName": "type", + "mapping": { + "PowerMeasurement": "#/components/schemas/PowerMeasurement", + "EnergyMeasurement": "#/components/schemas/EnergyMeasurement", + "PPBCPowerProfileStatus": "#/components/schemas/PPBCPowerProfileStatus", + "OMBCStatus": "#/components/schemas/OMBCStatus", + "FRBCActuatorStatus": "#/components/schemas/FRBCActuatorStatus", + "FRBCEnergyStatus": "#/components/schemas/FRBCEnergyStatus", + "FRBCStorageStatus": "#/components/schemas/FRBCStorageStatus", + "FRBCTimerStatus": "#/components/schemas/FRBCTimerStatus", + "DDBCActuatorStatus": "#/components/schemas/DDBCActuatorStatus" + } + }, "description": "Resource Status.", "title": "Status" } @@ -10992,11 +11006,11 @@ } ], "title": "Device Measurement Entity Ids", - "description": "Mapping of EOS measurement keys used by device (resource) simulations to Home Assistant entity IDs.", + "description": "Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key.", "examples": [ { - "battery1_soc_factor": "sensor.battery1_soc_factor", - "ev11_soc_factor": "sensor.ev11_soc_factor" + "battery1-soc-factor": "sensor.battery1_soc_factor", + "ev11-soc-factor": "sensor.ev11_soc_factor" } ] }, @@ -11168,11 +11182,11 @@ } ], "title": "Device Measurement Entity Ids", - "description": "Mapping of EOS measurement keys used by device (resource) simulations to Home Assistant entity IDs.", + "description": "Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key.", "examples": [ { - "battery1_soc_factor": "sensor.battery1_soc_factor", - "ev11_soc_factor": "sensor.ev11_soc_factor" + "battery1-soc-factor": "sensor.battery1_soc_factor", + "ev11-soc-factor": "sensor.ev11_soc_factor" } ] }, diff --git a/src/akkudoktoreos/core/databaseabc.py b/src/akkudoktoreos/core/databaseabc.py index 2928cae8..ea5e95b3 100644 --- a/src/akkudoktoreos/core/databaseabc.py +++ b/src/akkudoktoreos/core/databaseabc.py @@ -1601,10 +1601,14 @@ class DatabaseRecordProtocolMixin( await self._db_ensure_initialized() # Deletion is global — ensure we see everything - await self._db_ensure_loaded( - start_timestamp=start_timestamp, - end_timestamp=end_timestamp, - ) + if start_timestamp is None and end_timestamp is None: + # Full wipe — must escalate to FULL, not stop at INITIAL. + await self._db_load_full() + else: + await self._db_ensure_loaded( + start_timestamp=start_timestamp, + end_timestamp=end_timestamp, + ) to_delete: list[DatabaseTimestamp] = [] diff --git a/tests/test_dataabccompact.py b/tests/test_dataabccompact.py index 3db568e2..9e5f517f 100644 --- a/tests/test_dataabccompact.py +++ b/tests/test_dataabccompact.py @@ -672,8 +672,15 @@ class TestDataSequenceCompactIntegrity: seq, _ = dense_energy_seq await seq.db_compact() - dts = [r.date_time for r in seq.records if r.date_time is not None] - assert dts == sorted(dts) + # Use UTC timestamp to account for DST change in records sequence + epochs = [ + int(r.date_time.timestamp()) + for r in seq.records + if r.date_time is not None + ] + assert epochs == sorted(epochs), ( + "Records must be ascending by UTC instant after compaction" + ) async def test_compacted_old_timestamps_on_1h_boundaries(self, dense_energy_seq): """Records older than the floored 2-week cutoff must be on whole-hour UTC boundaries.