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:
Andreas
2026-07-15 14:19:46 +02:00
co-authored by Claude Opus 4.8
parent c59bf1b486
commit 67cf6f7d8a
21 changed files with 2505 additions and 1094 deletions
+250 -203
View File
@@ -111,12 +111,10 @@
0,
0,
0,
0,
1,
0,
0,
0,
1,
0,
1,
1,
@@ -147,6 +145,8 @@
1,
1,
1,
1,
1,
1
],
"battery_grid_export_allowed": [],
@@ -162,15 +162,15 @@
0.0,
0.0,
0.375,
0.375,
0.875,
0.5,
0.75,
0.75,
1.0,
1.0,
0.875,
0.625,
0.375,
0.375,
0.375,
0.1,
0.6,
0.0,
0.0,
0.0,
0.0,
0.0,
@@ -203,15 +203,15 @@
"result": {
"Last_Wh_pro_Stunde": [
4986.07,
4996.91,
12997.56,
14120.029999999999,
10340.67,
7731.82,
6307.91,
9186.56,
8998.03,
11651.67,
11664.82,
5149.22,
5036.78,
5062.12,
2227.51,
7396.579999999999,
1129.12,
1178.71,
1050.98,
988.56,
912.38,
@@ -236,22 +236,22 @@
1158.03,
1222.72,
1221.04,
949.99,
987.01,
3449.99,
3487.01,
733.99,
592.97
],
"EAuto_SoC_pro_Stunde": [
5.0,
11.555,
18.11,
20.294999999999998,
33.405,
50.885000000000005,
66.18,
77.105,
83.66,
90.215,
96.77,
46.515,
63.995000000000005,
81.475,
88.03,
98.518,
98.518,
98.518,
98.518,
98.518,
@@ -321,59 +321,101 @@
0.0,
0.0
],
"Gesamt_Verluste": 8404.44594732788,
"Gesamtbilanz_Euro": 7.836546975121494,
"Gesamt_Verluste": 9242.679077117135,
"Gesamtbilanz_Euro": 6.793576335409896,
"Gesamteinnahmen_Euro": 0.0,
"Gesamtkosten_Euro": 7.836546975121494,
"Gesamtkosten_Euro": 6.793576335409896,
"Home_appliance_wh_per_hour": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
2500.0,
2500.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"home_appliance_energy_wh": {
"dishwasher1": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
2500.0,
2500.0,
0.0,
0.0
]
},
"Kosten_Euro_pro_Stunde": [
0.9248695241652183,
0.8749092776800845,
1.5678286259999998,
2.4348720859999995,
0.8528744919675278,
0.5282751491259897,
0.19137741085396395,
1.691123530177008,
1.4724745282943246,
1.0809335963311613,
1.2680155994326825,
0.0,
0.4965507655670841,
0.008761738662872717,
0.0,
0.0,
0.0,
@@ -389,14 +431,14 @@
0.0,
0.0,
0.0,
0.11338560853163265,
0.11522756438372463,
0.04079284310894048,
0.0,
0.0,
0.0,
4.179128154646605e-17,
0.0,
0.0,
0.0021886029750169123,
0.0,
0.0,
0.0,
@@ -407,13 +449,13 @@
],
"Netzbezug_Wh_pro_Stunde": [
4056.445281426396,
3955.2860654615033,
7490.82,
12958.339999999998,
4640.231185895146,
2636.103538552843,
865.1781684175585,
8079.902198647912,
7836.479660959684,
5881.031536078136,
6327.4231508616895,
0.0,
2187.4483064629258,
38.597967677853376,
0.0,
0.0,
0.0,
@@ -429,14 +471,14 @@
0.0,
0.0,
0.0,
466.6074425170068,
474.1875077519532,
178.91597854798454,
0.0,
0.0,
0.0,
2.2737367544323206e-13,
0.0,
0.0,
9.957247384062384,
0.0,
0.0,
0.0,
@@ -487,15 +529,15 @@
],
"Verluste_Pro_Stunde": [
207.07863377116755,
207.1951278553804,
1083.0,
552.0,
521.2057423074175,
395.8024246263412,
876.0621802101069,
414.00986383774955,
414.016759315162,
581.7817843293763,
573.8007781034028,
458.55183787620945,
227.23539677555112,
640.3849261442235,
253.88850337853552,
938.3973561213433,
142.6574983015977,
108.98319763338179,
106.80230977350088,
133.7321802766326,
124.41545454545451,
@@ -509,47 +551,47 @@
69.12409090909085,
109.07302361034766,
116.99491129525349,
31.990721833371907,
30.957076574061034,
73.82223834331725,
123.8591383343284,
171.42744837680007,
116.9350623689079,
538.2984000000001,
441.9538395103232,
261.1952696860876,
262.55307614755066,
184.66788225469543,
131.21108264656203,
111.78035844493081,
90.18403329253945,
134.59227272727276,
418.18661420587983,
475.50136363636375,
100.08954545454549,
80.85954545454547
],
"akku_soc_pro_stunde": [
80.0,
80.00218427142131,
80.00760448962633,
61.06821055023239,
61.06821055023239,
62.12948116988288,
63.5406596317257,
58.120614791285504,
58.682709146161926,
45.22651624410048,
39.85140827675753,
36.67674043670639,
32.45548217808278,
28.528226668440908,
25.495297949432643,
23.27263093841336,
19.53618982271088,
16.54746737092025,
13.926986999019423,
11.532401943923004,
9.428020056870663,
7.2460727428210765,
3.8031825018727887,
0.30551238333016156,
61.0645175600859,
61.06479155557894,
61.065257092111224,
61.892528879038345,
62.498106048577306,
57.07806120813711,
38.33859382766936,
40.88136845531483,
39.81878058549141,
36.64411274544027,
32.422854486816654,
28.495598977174787,
25.46267025816652,
23.240003247147236,
19.503562131444756,
16.514839679654123,
13.894359307753296,
11.499774252656877,
9.395392365604536,
7.21344505155495,
3.7705548106066624,
0.2728846920640356,
0.6197802647075666,
1.5052110988161542,
2.736047696034607,
@@ -557,13 +599,13 @@
7.346947276543289,
22.29968060987662,
34.57523424809509,
41.83065840604197,
46.49642400356206,
47.884563842022054,
46.48524430245792,
43.99708508544073,
39.74859162814045,
36.5891994105096
41.7877983535968,
46.45356395111689,
47.841703789576876,
46.44238425001274,
33.24209404468744,
18.23258130364061,
15.073189086009755
],
"Electricity_price": [
0.000228,
@@ -661,15 +703,15 @@
0.0,
0.0,
0.375,
0.375,
0.875,
0.5,
0.75,
0.75,
1.0,
1.0,
0.875,
0.625,
0.375,
0.375,
0.375,
0.1,
0.6,
0.0,
0.0,
0.0,
0.0,
0.0,
@@ -757,103 +799,108 @@
"initial_soc_percentage": 5
},
"start_solution": [
2.0,
2.0,
2.0,
1.0,
1.0,
0.0,
2.0,
2.0,
2.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
5.0,
2.0,
0.0,
2.0,
0.0,
1.0,
2.0,
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
0.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
5.0,
6.0,
1.0,
0.0,
6.0,
1.0,
3.0,
5.0,
1.0,
1.0,
1.0,
5.0,
6.0,
5.0,
3.0,
1.0,
1.0,
1.0,
4.0,
1.0,
4.0,
2.0,
6.0,
5.0,
5.0,
3.0,
1.0,
2.0,
2.0,
6.0,
5.0,
2.0,
5.0,
4.0,
0.0,
4.0,
6.0,
6.0,
1.0,
4.0,
6.0,
3.0,
1.0,
4.0,
5.0,
2.0,
1.0,
6.0,
4.0,
2.0,
4.0,
1.0,
0.0,
0.0,
5.0,
0.0,
0.0,
2.0,
3.0,
4.0,
4.0,
2.0,
5.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
4.0,
6.0,
3.0,
12.0
1.0,
1.0,
3.0,
34.0
],
"washingstart": 12
"washingstart": 44,
"appliance_starts": {
"dishwasher1": [
"2026-07-16 20:00:00+02:00"
]
}
}