mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-08-31 12:46:38 +00:00
feat(optimization): schedule any number of flexible consumers
Replace the single hourly "dishwasher" home appliance with a list of flexible consumers (home_appliances). Each consumer defines its load either as an explicit power profile (energy-preservingly resampled onto the optimization slot grid, incl. 15-min and non-integer interval ratios) or the flat consumption_wh/duration_h fallback, and runs ONCE or DAILY within its time windows and the optimization horizon. - ConsumerScheduleMode + shared load-definition validation (XOR of profile/fallback, reject negative/NaN/inf, unique device_id) - ApplianceGeneLayout: variable appliance gene block (index into allowed_start_slots), ONCE/DAILY calendar-day based, no snapping - per-device output: result.home_appliance_energy_wh, appliance_starts (absolute local times), per-device solution columns and DDBC RUN/OFF instructions on state transitions only - deprecate dishwasher/washingstart/Home_appliance_wh_per_hour with backward-compatible mapping and explicit conflict rejection - max_home_appliances is now an upper bound only; no demo appliance and no on/off behaviour - docs, openapi.json, CHANGELOG and optimize_result_2* fixtures updated; new tests/test_homeappliance.py covers the mandatory test matrix Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c59bf1b486
commit
67cf6f7d8a
@@ -277,7 +277,7 @@ class TestAcChargingInSimulation:
|
||||
prediction_hours=prediction_hours,
|
||||
inverter=inverter,
|
||||
ev=None,
|
||||
home_appliance=None,
|
||||
home_appliances=None,
|
||||
)
|
||||
return sim, akku, inverter
|
||||
|
||||
@@ -553,7 +553,10 @@ def _run_evaluate_with_mocked_sim(
|
||||
- self.simulation is replaced by mock_sim
|
||||
Then call evaluate() and return the fitness tuple.
|
||||
"""
|
||||
from akkudoktoreos.optimization.genetic.genetic import GeneticOptimization
|
||||
from akkudoktoreos.optimization.genetic.genetic import (
|
||||
ApplianceGeneLayout,
|
||||
GeneticOptimization,
|
||||
)
|
||||
|
||||
config_eos.merge_settings_from_dict(
|
||||
{
|
||||
@@ -572,6 +575,7 @@ def _run_evaluate_with_mocked_sim(
|
||||
optim.optimize_ev = False
|
||||
optim.verbose = False
|
||||
optim.opti_param = {"home_appliance": 0}
|
||||
optim.appliance_layout = ApplianceGeneLayout([])
|
||||
optim.simulation = mock_sim
|
||||
|
||||
# evaluate_inner() just returns the base balance; we test the *additional* penalty
|
||||
@@ -602,7 +606,10 @@ def _run_evaluate_with_mocked_sim(
|
||||
|
||||
def _run_evaluate_with_mocked_ev_soc(config_eos, ev_soc_percentage: float) -> float:
|
||||
"""Return fitness for a mocked EV SoC while EV optimization is active."""
|
||||
from akkudoktoreos.optimization.genetic.genetic import GeneticOptimization
|
||||
from akkudoktoreos.optimization.genetic.genetic import (
|
||||
ApplianceGeneLayout,
|
||||
GeneticOptimization,
|
||||
)
|
||||
|
||||
config_eos.merge_settings_from_dict(
|
||||
{
|
||||
@@ -620,6 +627,7 @@ def _run_evaluate_with_mocked_ev_soc(config_eos, ev_soc_percentage: float) -> fl
|
||||
optim.optimize_ev = True
|
||||
optim.verbose = False
|
||||
optim.opti_param = {"home_appliance": 0}
|
||||
optim.appliance_layout = ApplianceGeneLayout([])
|
||||
|
||||
mock_ev = Mock()
|
||||
mock_ev.current_soc_percentage.return_value = ev_soc_percentage
|
||||
|
||||
Reference in New Issue
Block a user