EMHASS: An Energy Management for Home Assistant

Don’t give your MPC a rolling window, have it work towards a certain “final” state.

My MPC has a receding horizon, it calculates the remaining number of timeperiods until the next dayahead.

I tried that, but I struggle with the prediction horizon at the end of the day with a receding horizon. Prediction horizon can’t be <5 I encountered. How to cope with this? Or maybe you can show an example?

I added a condition in my automation; to make it stop recalculation, it only publishes the values for the MPC (via another automation that responds to the event)

action:
  - if:
      - condition: template
        value_template: "{{ prediction_horizon < 5 }}"
    then:
      - event: emhass_update
        event_data:
          type: mpc
          prefix: mpc_
      - stop: "Nearing the horizon. Skipping recalculation."

Thank you for the response! In the documentation it’s mentioned that if you use the csv method, that you just have to push a data-file to the data-folder. How would you do that with API? What I’ve done, for example with the ‘load_cost_forecast.csv’ is simply to copy it into the emhass container with the path /app/src/emhass/data.

I loaded the Backup: v0.12.6 → the Problem is not there anymore … before with v0.12.8 I got this: (tried once more to upgrade to v0.12.8 error coming back)

[2025-03-03 10:46:00 +0100] [23] [INFO] >> Obtaining params:
[2025-03-03 10:46:00 +0100] [23] [INFO] Passed runtime parameters: {‘pv_power_forecast’: [9641, 12028, 12202, 11552, 9974, 7521, 4337, 907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1216, 4774, 8035, 10602, 11903, 12162, 11342, 9802, 7314, 4288, 953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1885, 6054, 9058], ‘alpha’: 1, ‘beta’: 0, ‘operating_hours_of_each_deferrable_load’: [48, 12, 0, 2], ‘prediction_horizon’: 48, ‘soc_init’: 0.98, ‘soc_final’: 0.2}
[2025-03-03 10:46:00 +0100] [23] [INFO] >> Setting input data dict
[2025-03-03 10:46:00 +0100] [23] [INFO] Setting up needed data
[2025-03-03 10:46:00 +0100] [23] [INFO] Retrieve hass get data method initiated…
[2025-03-03 10:46:01 +0100] [23] [ERROR] Exception on /action/naive-mpc-optim [POST]
Traceback (most recent call last):
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 1511, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 919, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 917, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/flask/app.py”, line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/src/emhass/web_server.py”, line 414, in action_call
input_data_dict = set_input_data_dict(
^^^^^^^^^^^^^^^^^^^^
File “/app/src/emhass/command_line.py”, line 284, in set_input_data_dict
if not rh.prepare_data(
^^^^^^^^^^^^^^^^
File “/app/src/emhass/retrieve_hass.py”, line 397, in prepare_data
self.df_final[new_var_replace_zero] = self.df_final[
^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/pandas/core/frame.py”, line 4108, in getitem
indexer = self.columns._get_indexer_strict(key, “columns”)[1]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/app/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py”, line 6200, in _get_indexer_strict
self._raise_if_missing(keyarr, indexer, axis_name)
File “/app/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py”, line 6252, in _raise_if_missing
raise KeyError(f"{not_found} not in index")
KeyError: “[‘sensor.inverter_power_kombiniert’] not in index”

@davidusb: Is there a known issue or should i post the error in github?

Hi all,

is anyone using an E3DC S10 with Soluxtec panels w/ EMHASS? None of my components is in the “inverter” and “panel” db. What’s a good way to still get proper PV predictions?

cheers
-tb

What are your settings for these values in the configuration?

I use solcast, but I heard good things about the new open-meteo integration built into EMHASS that replaces the scraper.

Many thanks, works now!

@RudolfRendier yeah, but that’s the PV forecasting. In the setup page both panel types and inverter model need to be set. And neither my panel type nor my e3dc converter is on the list.

Anyone have an idea which inverter I can use for an “SMA Sunny Boy 1.5”. I tried to modify the SMA SB 5.0 => SMA_America__SBS1_5_US_10__240V_ but this gives an error.
The database on https://emhass-pvlib-database.streamlit.app is not easy to search (no output when result > 100 items and no wildcard seems possible).
Many thanks in advance.

I still have those set in the config; but those values don’t reflect my setup.
Would be nice if you could leave them out.

  "pv_inverter_model": [
    "Shenzhen_Growatt_New_Energy_Co___Ltd___SPH_3600TL_BL_US__240V_"
  ],
  "pv_module_model": [
    "CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M"
  ],

Ok, after some try and error I was able to found another inverter. Will try it with the Solar_Power__YS_1500TL__240V_

Got the following error running Day-ahead Optimization:

[2025-03-03 13:21:35 +0000] [23] [INFO] Retrieving weather forecast data using method = open-meteo
[2025-03-03 13:21:38 +0000] [23] [ERROR] Exception on /action/dayahead-optim [POST]
Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 919, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/web_server.py", line 414, in action_call
    input_data_dict = set_input_data_dict(
                      ^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/command_line.py", line 188, in set_input_data_dict
    P_PV_forecast = fcst.get_power_from_weather(df_weather)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/src/emhass/forecast.py", line 665, in get_power_from_weather
    self.plant_conf["pv_inverter_model"][i]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

Config:


    "set_use_pv": true,                                          
    "pv_module_model": [                                         
        "SolarWorld_Industries_GmbH_Sunmodule_Plus_SW_250_poly", 
        "Meyer_Burger__Industries__GmbH_MEYER_BURGER_GLASS_370W",
        "Meyer_Burger__Industries__GmbH_MEYER_BURGER_GLASS_370W" 
    ],                                                           
    "pv_inverter_model": [                                       
        "Solar_Power__YS_1500TL__240V_",                         
        "SMA_America__SBS5_0_US_10__240V_"                       
    ],                                                           
    "surface_tilt": [                                            
        48,                                                      
        24,                                                      
        24                                                       
    ],                                                           
    "surface_azimuth": [                                         
        164,                                                     
        80,                                                      
        260                                                      
    ],                                                           
    "modules_per_string": [                                      
        6,                                                       
        6,                                                       
        12                                                       
    ],                                                           
    "strings_per_inverter": [                                    
        1,                                                       
        2                                                        
    ],                                                           
    "inverter_is_hybrid": false,

Try this:

"set_use_pv": true,                                          
    "pv_module_model": [                                         
        "SolarWorld_Industries_GmbH_Sunmodule_Plus_SW_250_poly", 
        "Meyer_Burger__Industries__GmbH_MEYER_BURGER_GLASS_370W",
        "Meyer_Burger__Industries__GmbH_MEYER_BURGER_GLASS_370W" 
    ],                                                           
    "pv_inverter_model": [                                       
        "Solar_Power__YS_1500TL__240V_",                         
        "SMA_America__SBS5_0_US_10__240V_",
        "SMA_America__SBS5_0_US_10__240V_"    
    ],                                                           
    "surface_tilt": [                                            
        48,                                                      
        24,                                                      
        24                                                       
    ],                                                           
    "surface_azimuth": [                                         
        164,                                                     
        80,                                                      
        260                                                      
    ],                                                           
    "modules_per_string": [                                      
        6,                                                       
        6,                                                       
        12                                                       
    ],                                                           
    "strings_per_inverter": [                                    
        1,                                                       
        1,
        1
    ],                                                           
    "inverter_is_hybrid": false,

Thanks, with this config it works!

Thanks Mark. Verry insightfull. But my point is that you have to start by setting a desired SoC for the car at a certain point in the future to have the load planned.

What I would like to add is some form of “opportunistic” car charging. The car is’t full or needed right away but it is sitting plugged in on the driveway and there is a period with low pricing (low load_cost_forecats) and/or emhass mpc predics solar power being injected in the grid with low compensation (prod_price_forecast).


For example in the chart here you see that the battery will be charging when prod_price_forecast are negative tomorrow afternoon. The red line is predicted grid so there will be quite some injection to the grid and also prices will realy low for a couple of hours. I would like to calculate the opportinuty to put some cheap kwh’s in my car and plan that as deferrable load. I guess I could calculate the availble kwh’s in that period to max out my max_power_from_grid and set that.

Perhaps I misunderstand, but when you use solcast, the PV setup is ignored. In my config I have it disabled, but supply the solcast values in the MPC/dayahead calls.

1 Like

You pass the data in JSON format in the API call. Use Jinja2 Template to format the JSON data from HA sensors. My config

2 Likes