EMHASS: An Energy Management for Home Assistant

Thanks!

It does work. Only thing I don’t understand is the logic behind the number of strings per inverter.

I have 4 strings and two inverters (equal models), each inverter has two strings attach.

But it seems that I have to set 4 inverter entries and for each inverter strings attached = 1.
I would have expected to have two inverter entries in the inverter list and two strings per inverter entries set to 2. But that gives an invalid index error when executing the day_ahead optimization?

this runs, but seems wrong?

list_pv_module_model:
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
list_pv_inverter_model:
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
list_surface_tilt:
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 32
list_surface_azimuth:
  - surface_azimuth: 107
  - surface_azimuth: 287
  - surface_azimuth: 107
  - surface_azimuth: 287
list_modules_per_string:
  - modules_per_string: 18
  - modules_per_string: 16
  - modules_per_string: 12
  - modules_per_string: 12
list_strings_per_inverter:
  - strings_per_inverter: 1
  - strings_per_inverter: 1
  - strings_per_inverter: 1
  - strings_per_inverter: 1

this gives errors:

list_pv_module_model:
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
list_pv_inverter_model:
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
list_surface_tilt:
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 32
list_surface_azimuth:
  - surface_azimuth: 107
  - surface_azimuth: 287
  - surface_azimuth: 107
  - surface_azimuth: 287
list_modules_per_string:
  - modules_per_string: 18
  - modules_per_string: 16
  - modules_per_string: 12
  - modules_per_string: 12
list_strings_per_inverter:
  - strings_per_inverter: 2
  - strings_per_inverter: 2

Log file:

2024-07-18 14:32:20,808 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2024-07-18 14:32:25,733 - web_server - ERROR - Exception on /action/dayahead-optim [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1473, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 882, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 880, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 865, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 122, in action_call
    input_data_dict = set_input_data_dict(emhass_conf, costfun,
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 102, in set_input_data_dict
    P_PV_forecast = fcst.get_power_from_weather(df_weather)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/forecast.py", line 493, in get_power_from_weather
    inverter = cec_inverters[self.plant_conf['inverter_model'][i]]
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

seems like I do not understand those parameters correctly?

You have broken this configurator with that complex install :rofl: :sweat_smile:
Ok I propose you this. This is almost the correct configuration. So yeah each of these lists need 4 items as you have 4 roofs.
The problem is with the nominal power of your inverter. I propose a kind of dirty solution. You need to find an inverter in the database that is half your current nominal power. So in reality you have 2 times 10 kW right? Then pick 4 times a 5 kW inverter model. You can go with the inverter that is in the default configuration, it is a 5 kW model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_.
Then it should be good.
Once that have finished your setup and it works, then let it run for a day or two and compare the PV forecast with your real measurements, that’s the real validation of this.

1 Like

Is there any variable that causes the battery not to charge in or out
if the price is below xx sek?

you’re welcome :slight_smile:

I tend to do that with most systems, software and configurations I touch :wink:

that should be good enough, I’ll do that :slight_smile:

Has anyone else noticed an issue where EMHASS will forcast P_grid to its maximum (& P_hybrid_inverter to some large negative) when the unit_load_cost goes negative?

For example tomorrow the forecast in the afternoon is negative unit_load_cost and I end up with rows like this

2024-07-20 11:00:00+09:30 2887 1632 0 45000 0 45000 -7900 0.237 -43368 -0.04 -0.12 0.900 0.900
2024-07-20 11:30:00+09:30 3244 1632 0 45000 0 45000 -7900 0.373 -43368 -0.04 -0.12 0.900 0.900

I can work around this by setting negatives to 0 but that seems like a hack.

just a perhaps stupid question: why go through all theat hassle finding suitable panels and inverters when all that is needed is the nominal power of the solar panel and the maximum power of the inverter?

Wouldn’t two numerical input fields do the same trick? Or am I missing something?

No problem:

YAML doesn’t help as it just references deviceID.

Sorry for the resolution, hard to get each on into one screen shot, but you should get the general idea.

Try and call these each individually to verify the behaviour before you automate.

1 Like

Using the scrapper method will fetch the needed weather forecast. Then this forecast is converted into effective solar irradiance. This is finally converted to Watts using a well stablished PV simulation module called PVlib and provided by the NREL. The module and inverter names that are then used to search their database are inputs to this simulation module. I understand your point and we need to think on ways to simplify all this setup hassle. But if we switch to simple numerical inputs then the conversion to a suitable database name will require extra development and difficulty. And for similar database entries we cannot assure to pick a correct real equipment present in the database, so it’s debatable.

1 Like

Optimization runs no without throwing errors - but I always get Status: Infeasible

stdout: "HTTP/1.1 201 CREATED\r\nContent-Length: 45\r\nContent-Type: text/html; charset=utf-8\r\nDate: Fri, 19 Jul 2024 13:29:37 GMT\r\nServer: waitress\r\n\r\nEMHASS >> Action dayahead-optim executed..."
stderr: "% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100   236    0     0  100   236      0    196  0:00:01  0:00:01 --:--:--   196\r100   236    0     0  100   236      0    107  0:00:02  0:00:02 --:--:--   107\r100   236    0     0  100   236      0     73  0:00:03  0:00:03 --:--:--    73\r100   236    0     0  100   236      0     56  0:00:04  0:00:04 --:--:--    56\r100   236    0     0  100   236      0     45  0:00:05  0:00:05 --:--:--    45\r100   236    0     0  100   236      0     38  0:00:06  0:00:06 --:--:--     0\r100   236    0     0  100   236      0     32  0:00:07  0:00:07 --:--:--     0\r100   236    0     0  100   236      0     28  0:00:08  0:00:08 --:--:--     0\r100   236    0     0  100   236      0     25  0:00:09  0:00:09 --:--:--     0\r100   236    0     0  100   236      0     23  0:00:10  0:00:10 --:--:--     0\r100   236    0     0  100   236      0     21  0:00:11  0:00:11 --:--:--     0\r100   236    0     0  100   236      0     19  0:00:12  0:00:12 --:--:--     0\r100   236    0     0  100   236      0     17  0:00:13  0:00:13 --:--:--     0\r100   236    0     0  100   236      0     16  0:00:14  0:00:14 --:--:--     0\r100   236    0     0  100   236      0     15  0:00:15  0:00:15 --:--:--     0\r100   281  100    45  100   236      2     14  0:00:22  0:00:16  0:00:06     9\r100   281  100    45  100   236      2     14  0:00:22  0:00:16  0:00:06    11"
returncode: 0
2024-07-19 15:28:29,984 - web_server - INFO - Status: Infeasible
2024-07-19 15:28:29,985 - web_server - INFO - Total value of the Cost function = -1629.64
2024-07-19 15:29:37,175 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.24352, 0.26881, 0.28493, 0.30191, 0.33691, 0.41955, 0.3357, 0.32006, 0.30184, 0.30563, 0.2993, 0.29792, 0.29986, 0.30504, 0.30452, 0.30177, 0.29523, 0.27406, 0.25216, 0.19903, 0.1929, 0.18737, 0.18779, 0.18947]}
2024-07-19 15:29:37,175 - web_server - INFO -  >> Setting input data dict
2024-07-19 15:29:37,176 - web_server - INFO - Setting up needed data
2024-07-19 15:29:37,182 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2024-07-19 15:29:39,656 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-07-19 15:29:39,657 - web_server - INFO - Retrieve hass get data method initiated...
2024-07-19 15:29:52,322 - web_server - INFO -  >> Performing dayahead optimization...
2024-07-19 15:29:52,323 - web_server - INFO - Performing day-ahead forecast optimization
2024-07-19 15:29:52,344 - web_server - INFO - Perform optimization for the day-ahead
2024-07-19 15:29:52,639 - web_server - WARNING - Solver default unknown, using default
Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

command line - /usr/local/lib/python3.11/dist-packages/pulp/solverdir/cbc/linux/64/cbc /tmp/6e13cd391afd49f7a3780c36b519bc9e-pulp.mps -max -timeMode elapsed -branch -printingOptions all -solution /tmp/6e13cd391afd49f7a3780c36b519bc9e-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 693 COLUMNS
At line 4117 RHS
At line 4806 BOUNDS
At line 5311 ENDATA
Problem MODEL has 688 rows, 480 columns and 2847 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Problem is infeasible - 0.01 seconds
Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.02   (Wallclock seconds):       0.02

2024-07-19 15:29:52,837 - web_server - INFO - Status: Infeasible
2024-07-19 15:29:52,838 - web_server - INFO - Total value of the Cost function = -1629.64


Last run optimization results table
index 	P_PV 	P_Load 	P_deferrable0 	P_deferrable1 	P_deferrable2 	P_grid_pos 	P_grid_neg 	P_grid 	P_batt 	SOC_opt 	P_hybrid_inverter 	unit_load_cost 	unit_prod_price 	cost_profit 	cost_fun_selfcons
2024-07-19 15:00:00+02:00 	6191 	1098 	0 	0 	0 	1223 	0 	1223 	-6315 	1.000 	-124 	0.244 	0.074 	-0.298 	-0.298
2024-07-19 16:00:00+02:00 	5283 	1090 	2500 	1000 	2500 	1807 	0 	1807 	0 	1.000 	5283 	0.269 	0.074 	-0.486 	-0.486
2024-07-19 17:00:00+02:00 	4418 	1303 	1200 	0 	1913 	0 	0 	0 	0 	1.000 	4418 	0.285 	0.074 	-0.000 	-0.000
2024-07-19 18:00:00+02:00 	2855 	1665 	0 	1000 	188 	0 	0 	0 	0 	1.000 	2855 	0.302 	0.074 	-0.000 	-0.000
2024-07-19 19:00:00+02:00 	1703 	1304 	1 	0 	397 	0 	0 	0 	0 	1.000 	1703 	0.337 	0.074 	-0.000 	-0.000
2024-07-19 20:00:00+02:00 	588 	952 	0 	0 	0 	0 	0 	0 	364 	0.974 	952 	0.420 	0.074 	-0.000 	-0.000
2024-07-19 21:00:00+02:00 	-4 	2313 	0 	0 	0 	0 	0 	0 	2317 	0.812 	2313 	0.336 	0.074 	-0.000 	-0.000
2024-07-19 22:00:00+02:00 	-4 	1013 	0 	0 	0 	0 	0 	0 	1017 	0.740 	1013 	0.320 	0.074 	-0.000 	-0.000
2024-07-19 23:00:00+02:00 	-4 	1050 	0 	0 	0 	0 	0 	0 	1054 	0.666 	1050 	0.302 	0.074 	-0.000 	-0.000
2024-07-20 00:00:00+02:00 	-4 	1051 	0 	0 	0 	0 	0 	0 	1055 	0.592 	1051 	0.306 	0.074 	-0.000 	-0.000
2024-07-20 01:00:00+02:00 	-4 	1016 	0 	0 	0 	0 	0 	0 	1020 	0.521 	1016 	0.299 	0.074 	-0.000 	-0.000
2024-07-20 02:00:00+02:00 	-4 	1045 	0 	0 	0 	233 	0 	233 	816 	0.463 	812 	0.298 	0.074 	-0.070 	-0.070
2024-07-20 03:00:00+02:00 	-4 	1143 	0 	0 	0 	0 	0 	0 	1147 	0.383 	1143 	0.300 	0.074 	-0.000 	-0.000
2024-07-20 04:00:00+02:00 	-4 	1241 	0 	0 	0 	0 	0 	0 	1245 	0.295 	1241 	0.305 	0.074 	-0.000 	-0.000
2024-07-20 05:00:00+02:00 	-4 	1339 	0 	0 	0 	0 	0 	0 	1343 	0.201 	1339 	0.305 	0.074 	-0.000 	-0.000
2024-07-20 06:00:00+02:00 	-4 	1437 	0 	0 	0 	0 	0 	0 	1441 	0.100 	1437 	0.302 	0.074 	-0.000 	-0.000
2024-07-20 07:00:00+02:00 	1404 	1535 	0 	0 	0 	131 	0 	131 	0 	0.100 	1404 	0.295 	0.074 	-0.039 	-0.039
2024-07-20 08:00:00+02:00 	3726 	1633 	1297 	998 	2500 	2703 	0 	2703 	0 	0.100 	3726 	0.274 	0.074 	-0.741 	-0.741
2024-07-20 09:00:00+02:00 	5592 	1731 	0 	0 	0 	0 	-3861 	-3861 	0 	0.100 	5592 	0.252 	0.074 	0.287 	0.287
2024-07-20 10:00:00+02:00 	10072 	1829 	0 	0 	0 	0 	-8243 	-8243 	0 	0.100 	10072 	0.199 	0.074 	0.613 	0.613
2024-07-20 11:00:00+02:00 	11770 	1927 	0 	0 	0 	0 	-9843 	-9843 	0 	0.100 	11770 	0.193 	0.074 	0.732 	0.732
2024-07-20 12:00:00+02:00 	13164 	2025 	0 	0 	0 	0 	-11138 	-11138 	0 	0.100 	13164 	0.187 	0.074 	0.829 	0.829
2024-07-20 13:00:00+02:00 	13954 	2123 	0 	0 	0 	0 	-11830 	-11830 	0 	0.100 	13954 	0.188 	0.074 	0.880 	0.880
2024-07-20 14:00:00+02:00 	13596 	3555 	0 	0 	0 	0 	-2146 	-2146 	-7894 	0.600 	5701 	0.189 	0.074 	0.160 	0.160
Summary table for latest optimization results
Variable 	Value
cost_profit 	1.867
cost_fun_selfcons 	1.867
optim_status 	Infeasible

Is this result to be expected or am I doing something wrong?

shell_command:
  dayahead_optim: 'curl -i -H "Content-Type:application/json" -X POST -d ''{"load_cost_forecast":{{((state_attr(''sensor.nordpool_tibber_de_price_day_ahead'', ''raw_today'') | map(attribute=''value'') | list  + state_attr(''sensor.nordpool_tibber_de_price_day_ahead'', ''raw_tomorrow'') | map(attribute=''value'') | list))[now().hour:][:24] }}}'' http://localhost:5000/action/dayahead-optim'
  perfect_optim: 'curl -i -H "Content-Type:application/json" -X POST -d ''{"load_cost_forecast":{{((state_attr(''sensor.nordpool_tibber_de_price_day_ahead'', ''raw_today'') | map(attribute=''value'') | list  + state_attr(''sensor.nordpool_tibber_de_price_day_ahead'', ''raw_tomorrow'') | map(attribute=''value'') | list))[now().hour:][:24] }}}'' http://localhost:5000/action/perfect-optim'
  publish_data: 'curl -i -H "Content-Type:application/json" -X POST -d ''{}'' http://localhost:5000/action/publish-data'
logging_level: INFO
data_path: /share/
costfun: self-consumption
sensor_power_photovoltaics: sensor.wr_deye_1_pv_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: true
maximum_power_from_grid: 65000
maximum_power_to_grid: 20000
number_of_deferrable_loads: 3
list_nominal_power_of_deferrable_loads:
  - nominal_power_of_deferrable_loads: 2500
  - nominal_power_of_deferrable_loads: 1000
  - nominal_power_of_deferrable_loads: 2500
list_operating_hours_of_each_deferrable_load:
  - operating_hours_of_each_deferrable_load: 2
  - operating_hours_of_each_deferrable_load: 3
  - operating_hours_of_each_deferrable_load: 3
list_start_timesteps_of_each_deferrable_load:
  - start_timesteps_of_each_deferrable_load: 1
  - start_timesteps_of_each_deferrable_load: 1
  - start_timesteps_of_each_deferrable_load: 1
list_end_timesteps_of_each_deferrable_load:
  - end_timesteps_of_each_deferrable_load: 18
  - end_timesteps_of_each_deferrable_load: 18
  - end_timesteps_of_each_deferrable_load: 18
list_peak_hours_periods_start_hours:
  - peak_hours_periods_start_hours: "05:00"
  - peak_hours_periods_start_hours: "18:00"
list_peak_hours_periods_end_hours:
  - peak_hours_periods_end_hours: "10:00"
  - peak_hours_periods_end_hours: "03:00"
list_treat_deferrable_load_as_semi_cont:
  - treat_deferrable_load_as_semi_cont: true
  - 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: true
  - set_deferrable_load_single_constant: true
  - set_deferrable_load_single_constant: true
list_set_deferrable_startup_penalty:
  - set_deferrable_startup_penalty: 0
  - set_deferrable_startup_penalty: 0
  - set_deferrable_startup_penalty: 0
load_peak_hours_cost: 0.37
load_offpeak_hours_cost: 0.179
photovoltaic_production_sell_price: 0.0744
list_pv_module_model:
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
  - pv_module_model: Risen_Energy_Co__Ltd__RSM144_7_430BMDG
list_pv_inverter_model:
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
  - pv_inverter_model: Ginlong_Technologies_Co___Ltd___RHI_1P10K_HVES_5G__240V_
list_surface_tilt:
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 41
  - surface_tilt: 32
list_surface_azimuth:
  - surface_azimuth: 107
  - surface_azimuth: 287
  - surface_azimuth: 107
  - surface_azimuth: 287
list_modules_per_string:
  - modules_per_string: 18
  - modules_per_string: 16
  - modules_per_string: 12
  - modules_per_string: 12
list_strings_per_inverter:
  - strings_per_inverter: 1
  - strings_per_inverter: 1
  - strings_per_inverter: 1
  - strings_per_inverter: 1
inverter_is_hybrid: true
compute_curtailment: false
set_use_battery: true
battery_nominal_energy_capacity: 15000
method_ts_round: first
continual_publish: true
battery_discharge_power_max: 10000
battery_charge_power_max: 10000
battery_minimum_state_of_charge: 0.1
battery_maximum_state_of_charge: 1
time_zone: Europe/Berlin
prod_price_forecast_method: constant
days_to_retrieve: 7
freq: 60
optimization_time_step: 60

Issue found: the specified inverter in the configuration was not correct (although I pass my own preprocessed solar forecast list, so I didn’t think this was relevant).

1 Like

This became relevant recently because the information about your inverter is used to compute PV curtailment (if that option is activated)

Very good approach!

I had a lot of recurring timeout log entries previously:

2024-07-21 08:22:30.648 ERROR (MainThread) [homeassistant.components.automation.emhass_naive_mpc_optim_forecast] EMHASS - naive mpc optim forecast: Error executing script. Error for call_service at pos 1: Timeout when calling resource "http://localhost:5000/action/naive-mpc-optim"

I will monitor if this issue is reduced by your solution.

But now I’m running into a new issue:

* EMHASS - naive mpc optim forecast: Error executing script. Error for call_service at pos 1: Timeout when calling resource "http://localhost:5000/action/naive-mpc-optim"
* EMHASS - naive mpc optim forecast: If at step 2: Error executing script. Error for call_service at pos 1: Error rendering data template: UndefinedError: 'rest_response' is undefined
* EMHASS - naive mpc optim forecast: Error executing script. Error for if at pos 2: Error rendering data template: UndefinedError: 'rest_response' is undefined

Edit:

Above issue is already fixed: Wrong service name - I have a slightly different rest name, but the timeout errors are popping up regulary.

My automation code:

alias: EMHASS - naive mpc optim forecast
description: EMHASS - naive mpc optimization - upto 48 hours forecast.
trigger:
  - platform: time_pattern
    minutes: /1
    enabled: true
action:
  - continue_on_error: true
    service: rest_command.emhass_naive_mpc_optim_forecast
    metadata: {}
    data: {}
    enabled: true
    response_variable: rest_response
  - if:
      - condition: template
        value_template: "{{ rest_response['status'] < 400  }}"
    then:
      - service: rest_command.emhass_publish_data
        data:
          prefix: all
    else:
      - service: system_log.write
        metadata: {}
        data:
          level: warning
          message: "{{ rest_response['content'] }}"
          logger: EMHASS.MINUTE
mode: single

My rest_command:

  emhass_naive_mpc_optim_forecast:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: "application/json"
    timeout: 30
    payload: >-
      {% set em_prediction_horizon = states('sensor.em_prediction_horizon')|int(0) %}
      {
        "pv_power_forecast": {{
          ([states('sensor.inverter_input_power')|float(0)] +
          (state_attr('sensor.epex_spot_data_net_quantile_forcast', 'data')|map(attribute='p_pv_forecast')|list)[1:-1]
          )|tojson
        }},
        "load_cost_forecast": {{
          ([states('sensor.epex_spot_data_net_price')|float(0)|round(2)/100] +
          (state_attr('sensor.epex_spot_data_net_quantile_forcast', 'data')|map(attribute='price_eur_per_kwh')|list)[1:-1] 
          )|tojson 
        }},
        "prediction_horizon": {{em_prediction_horizon}},
        "soc_init": {{states('sensor.batteries_state_of_capacity')|float(0)/100}},
        "soc_final": 1.0,
        "def_total_hours": [0,0],
        "alpha": 1,
        "beta": 0,
        "continual_publish":false
      }

Isn’t this a bit strange that EMHASS chooses not to charge the battery at 14:00 when the electricity price is at its worst -0.60 SEK

It worked out when it got close to two o’clock

Anyone having issues with the solcast intergration no longer working?
using this intergration HACS BJReplay/ha-solcast-solar

I am using the scrapper but the data seems way off (very low), I have 2 5kw inverters with panels in 2 directions with 2 different types

list_pv_module_model:
  - pv_module_model: Trina_Solar_TSM_500DE18M_II_
  - pv_module_model: Trina_Solar_TSM_330DD06H_II_
list_pv_inverter_model:
  - pv_inverter_model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_
  - pv_inverter_model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_
list_surface_tilt:
  - surface_tilt: 30
  - surface_tilt: 30
  - surface_tilt: 30
  - surface_tilt: 30
list_surface_azimuth:
  - surface_azimuth: 185
  - surface_azimuth: 270
  - surface_azimuth: 185
  - surface_azimuth: 270
list_modules_per_string:
  - modules_per_string: 4
  - modules_per_string: 9
  - modules_per_string: 7
  - modules_per_string: 13
list_strings_per_inverter:
  - strings_per_inverter: 2
  - strings_per_inverter: 2

I’m seeing this exact same issue.
P_deferrable_nom for deferrable 0 is 3650. Yet every day it schedules insanely high values? Today is 7.3kw?

I think it has something to do with restricting the start and stop intervals.

Agreed, I think there is a logic error in the stop intervals code that it tries to squeeze in all the power required in the time remaining before the stop interval without consideration of the p_nom restriction.

I have raised an issue on github, so please feel free to include your experience there:

Don’t know if this is related to the same issue, but all of a sudden the optimisation is infeasible. I see that the grid-power > defined max power.

Is there someone who made the thermal model already available via NodeRed? Still no idea how to start to be honest and looking for some examples.