Skip to content

Commit

Permalink
Improve caching.
Browse files Browse the repository at this point in the history
Move the caching module to core.

Add an in memory cache that for caching function and method results
during an energy management run (optimization run). Two decorators
are provided for methods and functions.

Improve the file cache store by load and save functions.

Make EOS load the cache file store on startup and save it on shutdown.
Add a cyclic task that cleans the cache file store from outdated cache files.

Signed-off-by: Bobby Noelte <[email protected]>
  • Loading branch information
b0661 committed Jan 28, 2025
1 parent 1bb74ed commit 3909e3d
Show file tree
Hide file tree
Showing 25 changed files with 1,516 additions and 824 deletions.
35 changes: 29 additions & 6 deletions docs/_generated/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ Validators:
| ---- | -------------------- | ---- | --------- | ------- | ----------- |
| data_folder_path | `EOS_GENERAL__DATA_FOLDER_PATH` | `Optional[pathlib.Path]` | `rw` | `None` | Path to EOS data directory. |
| data_output_subpath | `EOS_GENERAL__DATA_OUTPUT_SUBPATH` | `Optional[pathlib.Path]` | `rw` | `output` | Sub-path for the EOS output data directory. |
| data_cache_subpath | `EOS_GENERAL__DATA_CACHE_SUBPATH` | `Optional[pathlib.Path]` | `rw` | `cache` | Sub-path for the EOS cache data directory. |
| latitude | `EOS_GENERAL__LATITUDE` | `Optional[float]` | `rw` | `52.52` | Latitude in decimal degrees, between -90 and 90, north is positive (ISO 19115) (°) |
| longitude | `EOS_GENERAL__LONGITUDE` | `Optional[float]` | `rw` | `13.405` | Longitude in decimal degrees, within -180 to 180 (°) |
| timezone | | `Optional[str]` | `ro` | `N/A` | Compute timezone based on latitude and longitude. |
| data_output_path | | `Optional[pathlib.Path]` | `ro` | `N/A` | Compute data_output_path based on data_folder_path. |
| data_cache_path | | `Optional[pathlib.Path]` | `ro` | `N/A` | Compute data_cache_path based on data_folder_path. |
| config_folder_path | | `Optional[pathlib.Path]` | `ro` | `N/A` | Path to EOS configuration directory. |
| config_file_path | | `Optional[pathlib.Path]` | `ro` | `N/A` | Path to EOS configuration file. |
:::
Expand All @@ -46,7 +44,6 @@ Validators:
"general": {
"data_folder_path": null,
"data_output_subpath": "output",
"data_cache_subpath": "cache",
"latitude": 52.52,
"longitude": 13.405
}
Expand All @@ -62,18 +59,41 @@ Validators:
"general": {
"data_folder_path": null,
"data_output_subpath": "output",
"data_cache_subpath": "cache",
"latitude": 52.52,
"longitude": 13.405,
"timezone": "Europe/Berlin",
"data_output_path": null,
"data_cache_path": null,
"config_folder_path": "/home/user/.config/net.akkudoktoreos.net",
"config_file_path": "/home/user/.config/net.akkudoktoreos.net/EOS.config.json"
}
}
```

## Cache Configuration

:::{table} cache
:widths: 10 20 10 5 5 30
:align: left

| Name | Environment Variable | Type | Read-Only | Default | Description |
| ---- | -------------------- | ---- | --------- | ------- | ----------- |
| subpath | `EOS_CACHE__SUBPATH` | `Optional[pathlib.Path]` | `rw` | `cache` | Sub-path for the EOS cache data directory. |
| cleanup_intervall | `EOS_CACHE__CLEANUP_INTERVALL` | `float` | `rw` | `300` | Intervall in seconds for EOS file cache cleanup. |
:::

### Example Input/Output

```{eval-rst}
.. code-block:: json
{
"cache": {
"subpath": "cache",
"cleanup_intervall": 300.0
}
}
```

## Logging Configuration

:::{table} logging
Expand Down Expand Up @@ -889,10 +909,13 @@ Attributes:
"general": {
"data_folder_path": null,
"data_output_subpath": "output",
"data_cache_subpath": "cache",
"latitude": 52.52,
"longitude": 13.405
},
"cache": {
"subpath": "cache",
"cleanup_intervall": 300.0
},
"logging": {
"level": "INFO"
},
Expand Down
485 changes: 249 additions & 236 deletions openapi.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cachebox==4.4.2
numpy==2.2.2
numpydantic==1.6.7
matplotlib==3.10.0
Expand Down
83 changes: 58 additions & 25 deletions src/akkudoktoreos/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

# settings
from akkudoktoreos.config.configabc import SettingsBaseModel
from akkudoktoreos.core.cachesettings import CacheCommonSettings
from akkudoktoreos.core.coreabc import SingletonMixin
from akkudoktoreos.core.decorators import classproperty
from akkudoktoreos.core.logging import get_logger
Expand Down Expand Up @@ -96,10 +97,6 @@ class GeneralSettings(SettingsBaseModel):
default="output", description="Sub-path for the EOS output data directory."
)

data_cache_subpath: Optional[Path] = Field(
default="cache", description="Sub-path for the EOS cache data directory."
)

latitude: Optional[float] = Field(
default=52.52,
ge=-90.0,
Expand Down Expand Up @@ -128,12 +125,6 @@ def data_output_path(self) -> Optional[Path]:
"""Compute data_output_path based on data_folder_path."""
return get_absolute_path(self.data_folder_path, self.data_output_subpath)

@computed_field # type: ignore[prop-decorator]
@property
def data_cache_path(self) -> Optional[Path]:
"""Compute data_cache_path based on data_folder_path."""
return get_absolute_path(self.data_folder_path, self.data_cache_subpath)

@computed_field # type: ignore[prop-decorator]
@property
def config_folder_path(self) -> Optional[Path]:
Expand All @@ -153,18 +144,58 @@ class SettingsEOS(BaseSettings):
Used by updating the configuration with specific settings only.
"""

general: Optional[GeneralSettings] = None
logging: Optional[LoggingCommonSettings] = None
devices: Optional[DevicesCommonSettings] = None
measurement: Optional[MeasurementCommonSettings] = None
optimization: Optional[OptimizationCommonSettings] = None
prediction: Optional[PredictionCommonSettings] = None
elecprice: Optional[ElecPriceCommonSettings] = None
load: Optional[LoadCommonSettings] = None
pvforecast: Optional[PVForecastCommonSettings] = None
weather: Optional[WeatherCommonSettings] = None
server: Optional[ServerCommonSettings] = None
utils: Optional[UtilsCommonSettings] = None
general: Optional[GeneralSettings] = Field(
default=None,
description="General Settings",
)
cache: Optional[CacheCommonSettings] = Field(
default=None,
description="Cache Settings",
)
logging: Optional[LoggingCommonSettings] = Field(
default=None,
description="Logging Settings",
)
devices: Optional[DevicesCommonSettings] = Field(
default=None,
description="Devices Settings",
)
measurement: Optional[MeasurementCommonSettings] = Field(
default=None,
description="Measurement Settings",
)
optimization: Optional[OptimizationCommonSettings] = Field(
default=None,
description="Optimization Settings",
)
prediction: Optional[PredictionCommonSettings] = Field(
default=None,
description="Prediction Settings",
)
elecprice: Optional[ElecPriceCommonSettings] = Field(
default=None,
description="Electricity Price Settings",
)
load: Optional[LoadCommonSettings] = Field(
default=None,
description="Load Settings",
)
pvforecast: Optional[PVForecastCommonSettings] = Field(
default=None,
description="PV Forecast Settings",
)
weather: Optional[WeatherCommonSettings] = Field(
default=None,
description="Weather Settings",
)
server: Optional[ServerCommonSettings] = Field(
default=None,
description="Server Settings",
)
utils: Optional[UtilsCommonSettings] = Field(
default=None,
description="Utilities Settings",
)

model_config = SettingsConfigDict(
env_nested_delimiter="__", nested_model_default_partial_update=True, env_prefix="EOS_"
Expand All @@ -178,6 +209,7 @@ class SettingsEOSDefaults(SettingsEOS):
"""

general: GeneralSettings = GeneralSettings()
cache: CacheCommonSettings = CacheCommonSettings()
logging: LoggingCommonSettings = LoggingCommonSettings()
devices: DevicesCommonSettings = DevicesCommonSettings()
measurement: MeasurementCommonSettings = MeasurementCommonSettings()
Expand Down Expand Up @@ -327,13 +359,14 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
"""
if hasattr(self, "_initialized"):
return
super().__init__(*args, **kwargs)
self._create_initial_config_file()
self._update_data_folder_path()
self._setup(self, *args, **kwargs)

def _setup(self, *args: Any, **kwargs: Any) -> None:
"""Re-initialize global settings."""
# Assure settings base knows EOS configuration
SettingsBaseModel.config = self
SettingsEOSDefaults.__init__(self, *args, **kwargs)
# Init config file and data folder pathes
self._create_initial_config_file()
self._update_data_folder_path()

Expand Down
5 changes: 4 additions & 1 deletion src/akkudoktoreos/config/configabc.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""Abstract and base classes for configuration."""

from typing import Any, ClassVar

from akkudoktoreos.core.pydantic import PydanticBaseModel


class SettingsBaseModel(PydanticBaseModel):
"""Base model class for all settings configurations."""

pass
# EOS configuration - set by ConfigEOS
config: ClassVar[Any] = None
Loading

0 comments on commit 3909e3d

Please sign in to comment.