mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-03-15 02:56:17 +00:00
feat: make home assistant add-on run optimization by default (#940)
When running as Home Assistant add-on the only viable usage is running with cyclic optimization. Make this the default to als propvide a better experience for first time users. The optimization will start with demo data, which also helps to configure Akkudoktor-EOS to the personal usage. The disabling of the automatic energy management is now an explicit mode "DISABLED". Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
@@ -23,7 +23,7 @@ from pydantic import Field, computed_field, field_validator
|
||||
|
||||
# settings
|
||||
from akkudoktoreos.adapter.adapter import AdapterCommonSettings
|
||||
from akkudoktoreos.config.configabc import SettingsBaseModel
|
||||
from akkudoktoreos.config.configabc import SettingsBaseModel, is_home_assistant_addon
|
||||
from akkudoktoreos.config.configmigrate import migrate_config_data, migrate_config_file
|
||||
from akkudoktoreos.core.cachesettings import CacheCommonSettings
|
||||
from akkudoktoreos.core.coreabc import SingletonMixin
|
||||
@@ -69,14 +69,6 @@ def get_absolute_path(
|
||||
return None
|
||||
|
||||
|
||||
def is_home_assistant_addon() -> bool:
|
||||
"""Detect Home Assistant add-on environment.
|
||||
|
||||
Home Assistant sets this environment variable automatically.
|
||||
"""
|
||||
return "HASSIO_TOKEN" in os.environ or "SUPERVISOR_TOKEN" in os.environ
|
||||
|
||||
|
||||
def default_data_folder_path() -> Path:
|
||||
"""Provide default data folder path.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Abstract and base classes for configuration."""
|
||||
|
||||
import calendar
|
||||
import os
|
||||
from typing import Any, ClassVar, Iterator, Optional, Union
|
||||
|
||||
import numpy as np
|
||||
@@ -18,6 +19,14 @@ from akkudoktoreos.utils.datetimeutil import (
|
||||
)
|
||||
|
||||
|
||||
def is_home_assistant_addon() -> bool:
|
||||
"""Detect Home Assistant add-on environment.
|
||||
|
||||
Home Assistant sets this environment variable automatically.
|
||||
"""
|
||||
return "HASSIO_TOKEN" in os.environ or "SUPERVISOR_TOKEN" in os.environ
|
||||
|
||||
|
||||
class SettingsBaseModel(PydanticBaseModel):
|
||||
"""Base model class for all settings configurations."""
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ class EnergyManagement(
|
||||
@classmethod
|
||||
def _run(
|
||||
cls,
|
||||
start_datetime: Optional[DateTime] = None,
|
||||
mode: Optional[EnergyManagementMode] = None,
|
||||
start_datetime: DateTime,
|
||||
mode: EnergyManagementMode,
|
||||
genetic_parameters: Optional[GeneticOptimizationParameters] = None,
|
||||
genetic_individuals: Optional[int] = None,
|
||||
genetic_seed: Optional[int] = None,
|
||||
@@ -170,14 +170,11 @@ class EnergyManagement(
|
||||
optimization depending on the selected mode or configuration.
|
||||
|
||||
Args:
|
||||
start_datetime (DateTime, optional): The starting timestamp
|
||||
of the energy management run. Defaults to the current datetime
|
||||
if not provided.
|
||||
mode (EnergyManagementMode, optional): The management mode to use. Must be one of:
|
||||
start_datetime (DateTime): The starting timestamp of the energy management run.
|
||||
mode (EnergyManagementMode): The management mode to use. Must be one of:
|
||||
- "OPTIMIZATION": Runs the optimization process.
|
||||
- "PREDICTION": Updates the forecast without optimization.
|
||||
|
||||
Defaults to the mode defined in the current configuration.
|
||||
- "DISABLED": Does not run.
|
||||
genetic_parameters (GeneticOptimizationParameters, optional): The
|
||||
parameter set for the genetic algorithm. If not provided, it will
|
||||
be constructed based on the current configuration and predictions.
|
||||
@@ -196,8 +193,10 @@ class EnergyManagement(
|
||||
None
|
||||
"""
|
||||
# Ensure there is only one optimization/ energy management run at a time
|
||||
if mode not in (None, "PREDICTION", "OPTIMIZATION"):
|
||||
if not EnergyManagementMode.is_valid(mode):
|
||||
raise ValueError(f"Unknown energy management mode {mode}.")
|
||||
if mode == EnergyManagementMode.DISABLED:
|
||||
return
|
||||
|
||||
logger.info("Starting energy management run.")
|
||||
|
||||
@@ -220,9 +219,7 @@ class EnergyManagement(
|
||||
|
||||
cls._stage = EnergyManagementStage.FORECAST_RETRIEVAL
|
||||
|
||||
if mode is None:
|
||||
mode = cls.config.ems.mode
|
||||
if mode is None or mode == "PREDICTION":
|
||||
if mode == EnergyManagementMode.PREDICTION:
|
||||
# Update the predictions
|
||||
cls.prediction.update_data(force_enable=force_enable, force_update=force_update)
|
||||
logger.info("Energy management run done (predictions updated)")
|
||||
@@ -346,6 +343,10 @@ class EnergyManagement(
|
||||
async with self._run_lock:
|
||||
loop = get_running_loop()
|
||||
# Create a partial function with parameters "baked in"
|
||||
if start_datetime is None:
|
||||
start_datetime = to_datetime()
|
||||
if mode is None:
|
||||
mode = self.config.ems.mode
|
||||
func = partial(
|
||||
EnergyManagement._run,
|
||||
start_datetime=start_datetime,
|
||||
|
||||
@@ -4,19 +4,47 @@ Kept in an extra module to avoid cyclic dependencies on package import.
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
from typing import Optional, Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from akkudoktoreos.config.configabc import SettingsBaseModel
|
||||
from akkudoktoreos.config.configabc import SettingsBaseModel, is_home_assistant_addon
|
||||
|
||||
|
||||
class EnergyManagementMode(str, Enum):
|
||||
"""Energy management mode."""
|
||||
|
||||
DISABLED = "DISABLED"
|
||||
PREDICTION = "PREDICTION"
|
||||
OPTIMIZATION = "OPTIMIZATION"
|
||||
|
||||
@classmethod
|
||||
def is_valid(cls, mode: Union[str, "EnergyManagementMode"]) -> bool:
|
||||
"""Check if value is a valid mode."""
|
||||
try:
|
||||
cls(mode)
|
||||
return True
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def from_value(cls, value: str) -> Optional["EnergyManagementMode"]:
|
||||
"""Safely convert string to enum, return None if invalid."""
|
||||
try:
|
||||
return cls(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def ems_default_mode() -> EnergyManagementMode:
|
||||
"""Provide default EMS mode.
|
||||
|
||||
Returns OPTIMIZATION when running under Home Assistant, else DISABLED.
|
||||
"""
|
||||
if is_home_assistant_addon():
|
||||
return EnergyManagementMode.OPTIMIZATION
|
||||
return EnergyManagementMode.DISABLED
|
||||
|
||||
|
||||
class EnergyManagementCommonSettings(SettingsBaseModel):
|
||||
"""Energy Management Configuration."""
|
||||
@@ -38,10 +66,10 @@ class EnergyManagementCommonSettings(SettingsBaseModel):
|
||||
},
|
||||
)
|
||||
|
||||
mode: Optional[EnergyManagementMode] = Field(
|
||||
default=None,
|
||||
mode: EnergyManagementMode = Field(
|
||||
default_factory=ems_default_mode,
|
||||
json_schema_extra={
|
||||
"description": "Energy management mode [OPTIMIZATION | PREDICTION].",
|
||||
"description": "Energy management mode [DISABLED | OPTIMIZATION | PREDICTION].",
|
||||
"examples": ["OPTIMIZATION", "PREDICTION"],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -139,7 +139,7 @@ class HomeApplianceParameters(DeviceParameters):
|
||||
"description": "List of allowed time windows. Defaults to optimization general time window.",
|
||||
"examples": [
|
||||
[
|
||||
{"start_time": "10:00", "duration": "2 hours"},
|
||||
{"start_time": "10:00", "duration": "3 hours"},
|
||||
],
|
||||
],
|
||||
},
|
||||
|
||||
@@ -727,9 +727,9 @@ def Configuration(
|
||||
# Home Assistant adapter optimization solution entities
|
||||
update_form_factory = make_config_update_list_form(eos_solution_entity_ids)
|
||||
elif config["name"].startswith("ems.mode"):
|
||||
# Energy managemnt mode
|
||||
# Energy management mode
|
||||
update_form_factory = make_config_update_value_form(
|
||||
["OPTIMIZATION", "PREDICTION", "None"]
|
||||
["OPTIMIZATION", "PREDICTION", "DISABLED"]
|
||||
)
|
||||
elif config["name"].endswith("elecpricefixed.time_windows.windows"):
|
||||
update_form_factory = make_config_update_time_windows_windows_form(
|
||||
|
||||
Reference in New Issue
Block a user