EMHASS - Energy Management for Home Assistant
Introductie
EMHASS is een tool voor het optimaliseren van je energieverbruik.Op basis van diverse parameters en wiskundige berekeningen geeft het systeem aan wanneer apparaten (zgn Deferrables) het beste kunnen worden ingeschakeld, op basis van de energieprijs en het aanbod van de eigen PV-installatie.
/f/image/UrV2rCzLKC8Gg01dequWgpw1.png?f=fotoalbum_large)
Doel van dit topic is om te helpen bij het configureren en inspiratie op te doen van anderen die hetzelfde doel hebben. De documentatie van EMHASS bevat een hoop informatie, maar schrikt daardoor ook wel af.
Gebruik
EMHASS is een python applicatie, die ook beschikbaar is gemaakt als add-on.Er is een webinterface met een aantal knoppen en het resultaat van de laatste berekeningen. Indien gewenst kunnen daar wat parameters worden ingegeven en kan er wat worden geëxperimenteerd met de verschillende optimalisaties, het resultaat is direct te zien in de grafieken.
Voor “productie” kan e.e.a. worden bediend via automatiseren en automatische REST calls.
Uitleg terminologie
Deferrables
Bij ‘deferrables’ kun je denken aan een warmtepompboiler of een EV kunnen zo worden uitgespreid over de dag, om optimaal gebruik te maken van de beschikbare zonne-energie, dynamische tarieven en een evt. batterij.Van deferrables kun je aangeven of ze als ‘semi-continuous’ beschouwd moeten worden of dat de belasting nog enigszins regelbaar is.
Een deferrable zou ook een wasmachine of een droger kunnen zijn, maar hoe je deze verbruikspatronen erin krijgt is mij nog niet duidelijk.
Algoritmes
EMHASS kan op verschillende manieren een energieplan voor je maken, door het aanroepen van een REST API. Met behulp van een publish-data kan EMHASS de berekende waarden doorgeven aan Home Assistant en hier kun je op acteren door je warmtepompboiler in of uit te schakelen, of door meer of minder power naar je thuisbatterij of EV te sturen.https://emhass.readthedoc...#the-emhass-optimizations
Perfect optim
Een model op basis van alleen de historische gegevens. Alsof vandaag exact gelijk zal zijn aan de dag ervoor.Dayahead-optim
Een plan voor de komende 24 uur op basis van de weersvooruitzichten, energieprijzen en het verwachte verbruik.Vaak aangevuld met de MPC hieronder. omdat de betrouwbaarheid van de forecasts mogelijk niet helemaal klopt, waardoor de voorspelling steeds verder gaat afwijken van de werkelijkheid.
Naive MPC optim
Als aanvulling op de dayahead-optimization kan met regelmaat een nieuwe MPC-optimalisatie worden uitgevoerd.Daarin is nog een plek voor de waardes alpha en beta. Deze bepalen het gewicht van de forecasts t.o.v. de actuele waarde.
Beide zijn standaard 0.5.
alpha: Het gewicht van de forecast. "A weight for the forecast data side"
beta: Het gewicht van de hudige meting. "A weight for the current/real values side"
https://emhass.readthedoc...rrent-values-in-forecasts
Machine-learning
Een model dat op basis van veel historische data voorspellingen leert maken over de toekomst.Cost functions
EMHASS kan met diverse doelen optimaliseren.* Winst
* Eigen verbruik
Integratie met Home Assistant
Via REST calls van EMHASS kunnen de diverse optimalisaties worden aangeroepen.Een speciale call ‘publish-data’ stuurt de actuele waarden van de optimalisatie naar Home Assistant.
Home Assistant kan dan het opladen van je EV starten, of de batterij laden, met een automation.
Shell Commands
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| emhass_perfect_optim: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/perfect-optim emhass_dayahead_optim: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/dayahead-optim emhass_naive_mpc: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/naive-mpc-optim emhass_publish_data: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/publish-data emhass_ml_model_fit: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/forecast-model-fit emhass_ml_model_predict: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/forecast-model-predict emhass_ml_model_tune: > curl -i -H "Content-Type:application/json" -X POST -d '{{payload}}' http://localhost:5000/action/forecast-model-ptune |
Omdat shell commando’s niet te herladen zijn zonder Home Assistant te herstarten heb ik de payload als variabele in het commando opgenomen. De aanroep in een automation kan dan zorgen voor de juiste invulling van de gegevens. En die zijn wel eenvoudig opnieuw te laden.
Day-ahead Automation
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| id: bbb661ac-2094-4b06-ada2-f93f91ba3a7b alias: "EMHASS: Dayahead optimization" trigger: - platform: time at: "05:34:56" variables: soc_min: 0.05 soc_max: 1 soc_init: > {{ states("sensor.athom_smart_plug_v3_50f110_jbd_bms_state_of_charge") | float(default=0) / 100.0 }} pd_max: 400 pc_max: 350 load_cost_forecast: > {% set time_now = now() %} {% set high = 0.26644 %} {% set low = 0.26402 %} {% set minutes = time_now.minute %} {% set rounded_minutes = (minutes + 15) // 30 * 30 %} {% set rounded_time = time_now.replace(minute=0) + timedelta(minutes=rounded_minutes) %} {% set end_time = time_now + timedelta(hours=24) %} {% set data = namespace(tariffs=[]) %} {% for period_start in range(0, 48) %} {% set t = time_now + timedelta(minutes=30*period_start) %} {% if (23 <= t.hour or 0 <= t.hour < 7) or (t.weekday() >= 5 or t.weekday() <= 1) %} {% set tariff = low %} {% else %} {% set tariff = high %} {% endif %} {% set data.tariffs = data.tariffs + [tariff] %} {% endfor %} {{ data.tariffs[:48] }} pv_p_fc: > {% set today = state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedForecast') | selectattr('period_start', 'gt', utcnow()) | map(attribute='pv_estimate') | map('multiply',1000) | map('int') | list %} {% set tomorrow = state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedForecast') | map(attribute='pv_estimate') | map('multiply', 1000)| map('int') | list %} {{ today + tomorrow[:48] }} action: - service: shell_command.emhass_dayahead_optim data: payload: > {"SOCmax": {{ soc_max }}, "SOCmin": {{ soc_min }}, "SOCtarget": {{ soc_init }}, "Pd_max": {{ pd_max }}, "Pc_max": {{ pc_max }}, "weather_forecast_cache_only": true, "pv_power_forecast": {{ pv_p_fc }}, "load_cost_forecast": {{ load_cost_forecast }} } |
Naive MPC automation (WIP)
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| id: 1ecff611-d460-4713-8b1a-a60dc2ac87a2 alias: "EMHASS: MPC optimization" trigger: - platform: time_pattern minutes: "/5" variables: prediction_horizon: > {% set time = now() %} {% set time = time.replace(minute=0) %} {% set horizon = time.replace(day=time.day + 1, hour=5, minute=35) %} {% set horizon_seconds = horizon - time %} {% set horizon_hours = horizon_seconds.total_seconds() / 60 %} {% set pred_horizon = horizon_hours // 30 %} {% set pred_horizon = pred_horizon | int(0) %} {{ pred_horizon }} prod_price_forecast: > {% set data = namespace(tariffs=[]) %} {% set prod_price = 0.055 %} {% set data = namespace(tariffs=[]) %} {% for i in range(0, 48, 1) %} {% set data.tariffs = data.tariffs + [prod_price] %} {% endfor %} {{ data.tariffs[:prediction_horizon] }} load_cost_forecast: > {% set time_now = now() %} {% set high = 0.26644 %} {% set low = 0.26402 %} {% set minutes = time_now.minute %} {% set rounded_minutes = (minutes + 15) // 30 * 30 %} {% set rounded_time = time_now.replace(minute=0) + timedelta(minutes=rounded_minutes) %} {% set end_time = time_now + timedelta(hours=24) %} {% set data = namespace(tariffs=[]) %} {% for period_start in range(0, 48) %} {% set t = time_now + timedelta(minutes=30*period_start) %} {% if (23 <= t.hour or 0 <= t.hour < 7) or (t.weekday() >= 5 or t.weekday() <= 1) %} {% set tariff = low %} {% else %} {% set tariff = high %} {% endif %} {% set data.tariffs = data.tariffs + [tariff] %} {% endfor %} {{ data.tariffs[:48] }} # TODO: Use average (5min?) for 'now'-value? load_p_fc: > {% set p_load_fc = state_attr('sensor.p_load_forecast', 'forecasts') | map(attribute='p_load_forecast') | list %} {% set p_load_now = [states('sensor.power_load_no_var_loads') ] %} {{ (p_load_now + p_load_fc)[:prediction_horizon] }} soc_min: 0.05 soc_max: 1 soc_init: > {{ states("sensor.athom_smart_plug_v3_50f110_jbd_bms_state_of_charge") | float(default=0) / 100.0 }} num_def_loads: 0 def_total_hours: 0 pv_p_fc: > {% set today = state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedForecast') | selectattr('period_start', 'gt', utcnow()) | map(attribute='pv_estimate') | map('multiply',1000) | map('int') | list %} {% set tomorrow = state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedForecast') | map(attribute='pv_estimate') | map('multiply', 1000)| map('int') | list %} {{ (today + tomorrow)[:prediction_horizon] }} action: - service: shell_command.emhass_naive_mpc data: payload: > { "prediction_horizon": {{ prediction_horizon }}, "prod_price_forecast": {{ prod_price_forecast }}, "soc_final": {{ soc_min }}, "soc_init": {{ soc_init }}, "num_def_loads": 0, "def_total_hours": {{ def_total_hours }}, "pv_power_forecast": {{ pv_p_fc }}, "load_power_forecast": {{ load_p_fc }}, "load_cost_forecast": {{ load_cost_forecast }} } |
Configuratie
De configuratie van EMHASS is een yaml met diverse opties voor je energieprijzen, lijsten deferrables en evt een batterij.YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
| logging_level: DEBUG data_path: default costfun: profit sensor_power_photovoltaics: sensor.solar_panels_total_output_power sensor_power_load_no_var_loads: sensor.power_load_no_var_loads set_total_pv_sell: false set_nocharge_from_grid: false set_nodischarge_to_grid: false maximum_power_from_grid: 9000 maximum_power_to_grid: 9000 number_of_deferrable_loads: 2 list_nominal_power_of_deferrable_loads: - nominal_power_of_deferrable_loads: 0 - nominal_power_of_deferrable_loads: 0 list_operating_hours_of_each_deferrable_load: - operating_hours_of_each_deferrable_load: 0 - operating_hours_of_each_deferrable_load: 0 list_start_timesteps_of_each_deferrable_load: - start_timesteps_of_each_deferrable_load: 0 - start_timesteps_of_each_deferrable_load: 0 list_end_timesteps_of_each_deferrable_load: - end_timesteps_of_each_deferrable_load: 0 - end_timesteps_of_each_deferrable_load: 0 list_peak_hours_periods_start_hours: - peak_hours_periods_start_hours: "00:00" list_peak_hours_periods_end_hours: - peak_hours_periods_end_hours: "00:00" list_treat_deferrable_load_as_semi_cont: - treat_deferrable_load_as_semi_cont: true - treat_deferrable_load_as_semi_cont: true list_set_deferrable_load_single_constant: - set_deferrable_load_single_constant: false - set_deferrable_load_single_constant: false list_set_deferrable_startup_penalty: - set_deferrable_startup_penalty: 0 - set_deferrable_startup_penalty: 0 load_peak_hours_cost: 0.26644 load_offpeak_hours_cost: 0.26402 photovoltaic_production_sell_price: 0.055 list_pv_module_model: - pv_module_model: CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M list_pv_inverter_model: - pv_inverter_model: Shenzhen_Growatt_New_Energy_Co___Ltd___SPH_3600TL_BL_US__240V_ list_surface_tilt: - surface_tilt: 37 list_surface_azimuth: - surface_azimuth: 165 list_modules_per_string: - modules_per_string: 6 list_strings_per_inverter: - strings_per_inverter: 1 inverter_is_hybrid: false compute_curtailment: false set_use_battery: true battery_nominal_energy_capacity: 2500 Pd_max: 400 Pc_max: 320 eta_disch: 0.95 eta_ch: 0.95 Enom: 2600 SOCmin: 0.05 SOCmax: 0.99 SOCtarget: 0.8 |
Interpolatie
Het kan helpen om bepaalde sensoren te interpoleren.YAML:
1
2
3
| var_interp: - sensor.power_photovoltaics - sensor.power_load_no_var_loads |
https://emhass.readthedocs.io/en/latest/config.html
PV-installatie
Er is een mogelijkheid om handmatig je een PV-installatie configureren, met type panelen en omvormer-vermogen. Helaas is de onderliggende database niet up-to-date.Solcast
Een beter alternatief is ‘Solcast’, voor de hobbyist is een gratis API beschikbaar met 10 API calls per dag. Aangezien de informatie maar 1x per 6 uur wordt bijgewerkt is dit ruim voldoende. Solcast heeft ook ondersteuning voor meerdere dak-oriëntaties.Solar.Forecast
Solar.Forecast is ook een gratis API, met een resolutie van 1h, max 12 requests per uur per IP en werkt met het totaal aantal Wp van de installatie.Load
Het verbruik van het huis moet ook bekend zijn, EMHASS heeft tenminste 48h historie nodig op deze sensor.De sensor moet de belasting van het huis zijn, zonder deferrables en volgens mij ook zonder PV of batterij.
Ik heb het verbruik van mijn P1 meter genomen en daar de opbrengst van de panelen bij opgeteld. Evt. opladen van de batterij of juist het ontladen neem ik er ook niet in mee.
YAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
| - name: "Power Consumed by Home" state: "{{ states('sensor.power_from_grid_net_sum') | float(0) + states('sensor.solar_panels_total_output_power') | float(0) }}" unit_of_measurement: "W" - name: "Power load no var loads" unique_id: b699a98f-80bb-480d-bc7d-64489d271b77 unit_of_measurement: W device_class: power state: > {% set powerload = states('sensor.power_consumed_by_home') | float(default=0) %} {% set battery_prod = states('sensor.powerstream_6588_inverter_output_watts') | int(0) %} {% set battery_cons = states('sensor.home_battery_power_usage_corrected') | float(default=0) %} {% set value = ( powerload + battery_prod - battery_cons) | round(1,default=0) %} {{ value }} |
Batterij
Van een batterij configureer je de capaciteit, maar ook de efficientie en de maximale hoeveelheid vermogen waarmee je kunt op- en ontladen. En hoe vol/leeg de batterij mag zijn.YAML:
1
2
3
4
5
6
7
8
9
10
| set_use_battery: true battery_nominal_energy_capacity: 2500 Pd_max: 400 Pc_max: 320 eta_disch: 0.95 eta_ch: 0.95 Enom: 2600 SOCmin: 0.05 SOCmax: 0.99 SOCtarget: 0.8 |
Links
EMHASS:https://github.com/davidusb-geek/emhass
Home Assistant community:
https://community.home-as...for-home-assistant/338126
EMHASS add-on:
https://github.com/davidusb-geek/emhass-add-on
De officiële documentatie vind je hier:
https://emhass.readthedocs.io/en/latest/
Solcast:
https://toolkit.solcast.com.au/register
Solcast Integratie (HACS)
https://github.com/BJReplay/ha-solcast-solar
Document van Robert Cruikshank:
https://cruikshank-my.sha...r2aXqf_6aQB5AO1A?e=5zmaVB
[ Voor 27% gewijzigd door RudolfR op 24-10-2024 19:27 ]