EOS/src/akkudoktoreos/prediction/elecpriceabc.py
Bobby Noelte d4e31d556a
Add Documentation 2 (#334)
Add documentation that covers:

- configuration
- prediction

Add Python scripts that support automatic documentation generation for
configuration data defined with pydantic.

Adapt EOS configuration to provide more methods for REST API and
automatic documentation generation.

Adapt REST API to allow for EOS configuration file load and save.
Sort REST API on generation of openapi markdown for docs.

Move logutil to core/logging to allow configuration of logging by standard config.

Make Akkudoktor predictions always start extraction of prediction data at start of day.
Previously extraction started at actual hour. This is to support the code that assumes
prediction data to start at start of day.

Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
2025-01-05 14:41:07 +01:00

75 lines
2.8 KiB
Python

"""Abstract and base classes for electricity price predictions.
Notes:
- Ensure appropriate API keys or configurations are set up if required by external data sources.
"""
from abc import abstractmethod
from typing import List, Optional
from pydantic import Field, computed_field
from akkudoktoreos.core.logging import get_logger
from akkudoktoreos.prediction.predictionabc import PredictionProvider, PredictionRecord
logger = get_logger(__name__)
class ElecPriceDataRecord(PredictionRecord):
"""Represents a electricity price data record containing various price attributes at a specific datetime.
Attributes:
date_time (Optional[AwareDatetime]): The datetime of the record.
"""
elecprice_marketprice_wh: Optional[float] = Field(
None, description="Electricity market price per Wh (€/Wh)"
)
# Computed fields
@computed_field # type: ignore[prop-decorator]
@property
def elecprice_marketprice_kwh(self) -> Optional[float]:
"""Electricity market price per kWh (€/kWh).
Convenience attribute calculated from `elecprice_marketprice_wh`.
"""
if self.elecprice_marketprice_wh is None:
return None
return self.elecprice_marketprice_wh * 1000.0
class ElecPriceProvider(PredictionProvider):
"""Abstract base class for electricity price providers.
WeatherProvider is a thread-safe singleton, ensuring only one instance of this class is created.
Configuration variables:
electricity price_provider (str): Prediction provider for electricity price.
Attributes:
prediction_hours (int, optional): The number of hours into the future for which predictions are generated.
prediction_historic_hours (int, optional): The number of past hours for which historical data is retained.
latitude (float, optional): The latitude in degrees, must be within -90 to 90.
longitude (float, optional): The longitude in degrees, must be within -180 to 180.
start_datetime (datetime, optional): The starting datetime for predictions, defaults to the current datetime if unspecified.
end_datetime (datetime, computed): The datetime representing the end of the prediction range,
calculated based on `start_datetime` and `prediction_hours`.
keep_datetime (datetime, computed): The earliest datetime for retaining historical data, calculated
based on `start_datetime` and `prediction_historic_hours`.
"""
# overload
records: List[ElecPriceDataRecord] = Field(
default_factory=list, description="List of ElecPriceDataRecord records"
)
@classmethod
@abstractmethod
def provider_id(cls) -> str:
return "ElecPriceProvider"
def enabled(self) -> bool:
return self.provider_id() == self.config.elecprice_provider