EMHASS: An Energy Management for Home Assistant

mine is basically the same but significantly more even. my battery can be controlled with call service to predetermined SOC. but at the same time with variable power. Hence my question if you should manipulate power or if you should run with emhas’ suggested effect.

Hi, if you are using the internal EMHASS implementation of forecast.solar then this is a bug that is already fixed here: https://github.com/davidusb-geek/emhass/commit/d99eef80dcc4cedc56c7e7e5f6f1ea26ec380cb7

It will be available in the upcoming release

2 Likes

I would suggest you try both methods and see what works best for your house.

There isn’t one perfect solution and as with most of HA there is generally more than one way to achieve the same outcome.

Try and work out manually how you would control your battery before you try and automate.

Do you have home Assistant controls that allow you to force charge/ discharge battery?

What did the devices tab look like for the Solar?

There is a manual mode to force discharge and charge, that is to / from the grid though, not to the house.

Screenshots incomming:



Is there maybe a youtubevideo that explains a bit the possibilities of this integration?
And how to set up this EMHASS: Energy Management for Home Assistant — emhass 0.9.1 documentation

This was because an update on skforecast. Go to the share folder and erase the ML forecaster pkl file. Then relaunch that model train and finally the optimization

Trying to set up an emhass on my unraid server. Has anyone done this and can guide me, how to proceed?

I did try that and restarting emhass and HA. But it seems with my system there’s always something “stuck” for a while when I change something. Now perfect optimisation and model fit work again. It now only complains about my new sensor when I do dayahead.
Naive does work.

ERROR - web_server - Exception on /action/dayahead-optim [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/indexes/base.py", line 3653, in get_loc
    return self._engine.get_loc(casted_key)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pandas/_libs/index.pyx", line 147, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 176, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 7080, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'sensor.power_load_no_var_loads'

The above exception was the direct cause of the following exception:

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 109, 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 100, in set_input_data_dict
    P_load_forecast = fcst.get_load_forecast(
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/forecast.py", line 673, in get_load_forecast
    forecast_out = mlf.predict(data_last_window)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/machine_learning_forecaster.py", line 207, in predict
    last_window=data_last_window[self.var_model],
                ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/frame.py", line 3761, in __getitem__
    indexer = self.columns.get_loc(key)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/indexes/base.py", line 3655, in get_loc
    raise KeyError(key) from err
KeyError: 'sensor.power_load_no_var_loads'

I had to change the name of the new sensor to the name of the old sensor for things to work again.

Often with our dynamic price market we will see a high price forecast in the future, that collapses as the time gets closer. It is very predictable.

Of course EMHASS views all forecasts as equal and will often delay actions for what looks like a favourable future position, but can miss out on the current opportunity.

My energy retailer, Amber Electric has started using an Advanced Price Forecast that takes the energy regulator (AEMO) published forecasts and generates a new set of pricing based on how this has performed historically.

You can see in the chart below the 18:00 peak is reasonably close to the prediction, but the 22:00 peak is greatly reduced in the Advanced Forecast. In the base case EMHASS would hold off discharge for the 22:00 peak, but it would be better if EMHASS could utilise the Advanced Price Forecasts.

I envisage there is a machine learning model (developed by the CSIRO) at play and was wondering if the EMHASS ML forecaster could generate a similar set of Advanced Price forecasts based on historic performance?

I have previously trained the ML forecaster on historic pricing which gives a reasonable future forecast, but I’m wondering if you can train the ML forecaster on changing future forecasts.

So here is when enters that new ML regression class, that allow you to make predictions on the same timestamps as your input data.
This could be a very nice use case.
So store the history of both the normal prices and the advanced future values of that forecast that you are writing about into a CSV file (there is an example in the ML regressor documentation to do that). With that data from the csv file train a ML regressor that maps from the basic forecast to the advanced. Then use the trained model on new simple forecast to generate a prediction of the advanced forecasts. Finally you inject the latests to EMHASS as runtime lists.

1 Like

Where to find that specific share folder to find ML forecaster pkl file? My share folder is empty? I use the add-on

Hello. I use a hybrid inverter. How i solved this is setting amp charge to battery to what emhass recommends when negative grid forecast. If else grid forecast is 0 i just det my soc to 30 and let the inverter charge the battery full :blush: it works great and almost follows emhass perfectly.

What im missing in home assistant is not positive grid and negative grid sensor to make this automation even better.

Also have a check if there is positive grid then i set charge amps to what emhass recommends and it will buy from grid if electricity is cheap.

Are you able to share an example of your automations?

Is there a possibility to add the option to extend the prediction horizon from 24h to 48h?

Are the people who control the heating/cooling based on the energy price and can provide me a example?

Would be great if I can control the in house temperature when the energy price is low or expensive.

Here is the details of how I’m doing cooling during the day over summer.

Cooling over summer is easier as the hottest part of the day and the cheapest energy costs are aligned. So I set def_total_hours_hvac to match the number of hours each day that exceed my desired setpoint.

Winter heating overnight is more complex as the demand generally doesn’t sign with the cheapest cost of energy. I’m still within up this concept but with the new end_timestep option I am planning on calculating the number of hours overnight that the temp forecast is below my setpoint and then setting the def_end_timestep_hvac to force the HVAC scheduling before the time the temp forecast crosses my setpoint threshold.

The other method I have used for overnight heating which has been quite effective if your heating demand consistent is is to not bother with scheduling my HVAC with EMHASS and just letting the HVAC power consumption accumulate in the load forecast each day as part of power_load_no_vars. This later approach has the disadvantage that your HVAC consumption isn’t modulated by cost variations throughout the night.

Just upgraded HA to 2024.6.0b0 and EMHASS has started failing for me, proceed with caution:

2024-05-30 07:18:00,259 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.24, 0.27, 0.15, 0.13, 0.12, 0.11, 0.11, 0.1, 0.08, 0.06, 0.05, 0.05, 0.05, 0.1, 0.11, 0.12, 0.12, 0.13, 0.29, 0.34, 0.35, 0.35, 0.35, 0.35, 0.33, 0.32, 0.32, 0.29, 0.17, 0.15, 0.17, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.14, 0.14, 0.14, 0.14], 'prod_price_forecast': [0.15, 0.18, 0.06, 0.04, 0.04, 0.04, 0.03, 0.02, 0, -0.01, -0.02, -0.02, -0.02, 0.03, 0.04, 0.04, 0.04, 0.05, 0.06, 0.12, 0.12, 0.12, 0.12, 0.12, 0.11, 0.1, 0.1, 0.07, 0.08, 0.07, 0.08, 0.06, 0.07, 0.07, 0.06, 0.06, 0.06, 0.06, 0.06, 0.05, 0.05, 0.05], 'pv_power_forecast': [841], 'load_power_forecast': [1091, 1500, 1600, 1800, 2100, 1200, 1800, 3100, 700, 900, 800, 1000, 300, 1300, 600, 300, 400, 300, 1100, 1300, 1100, 1100, 1000, 600, 500, 400, 500, 1100, 400, 600, 300, 300, 400, 300, 400, 400, 400, 300, 300, 300, 300, 400, 300, 300, 700, 700, 800, 1100, 1700, 1500, 1600, 1800, 2100, 1200, 1800, 3100, 700, 900, 800, 1000, 300, 1300, 600, 300, 400, 300, 1100, 1300, 1100, 1100, 1000, 600, 500, 400, 500, 1100, 400, 600, 300, 300, 400, 300, 400, 400, 400, 300, 300, 300, 300, 400, 300, 300, 700, 700, 800, 1100], 'prediction_horizon': 42, 'alpha': 1, 'beta': 0, 'num_def_loads': 6, 'def_total_hours': [0, 2, 1, 2, 6, 1], 'def_end_timestep': [0, 0, 17, 0, 0, 17], 'P_deferrable_nom': [1232, 6333, 11520, 2500, 600, 11520], 'treat_def_as_semi_cont': [1, 1, 0, 0, 1, 0], 'set_def_constant': [0, 0, 0, 0, 0, 0], 'soc_init': 0.31, 'soc_final': 0}
2024-05-30 07:18:00,259 - web_server - INFO -  >> Setting input data dict
2024-05-30 07:18:00,259 - web_server - INFO - Setting up needed data
2024-05-30 07:18:00,262 - web_server - ERROR - ERROR: The passed data is either not a list or the length is not correct, length should be 42
2024-05-30 07:18:00,262 - web_server - ERROR - Passed type is <class 'list'> and length is 1
2024-05-30 07:18:00,266 - web_server - INFO - Retrieve hass get data method initiated...
2024-05-30 07:18:00,940 - web_server - INFO - Retrieving weather forecast data using method = scrapper
2024-05-30 07:18:03,511 - web_server - ERROR - Exception on /action/naive-mpc-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 109, 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 142, in set_input_data_dict
    df_weather = fcst.get_weather_forecast(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/forecast.py", line 213, in get_weather_forecast
    raw_data.set_index(forecast_dates_scrap, inplace=True)
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/frame.py", line 5910, in set_index
    raise ValueError(
ValueError: Length mismatch: Expected 24 rows, received array of length 48

It seems like a problem with your data list. The passed length is 1 but expected 42