EMHASS: An Energy Management for Home Assistant

Thanks for the information.
How do you deal with the hysteresis when both devices are switched on simultanously? Then both devices may be turned on at the same time but EMHASS thinks it cycles between the 2 devices. Therfore it consumes too much power (?) (As the deferrable loads are subtraced from the load measurement and therefore invisible to emhass)
Maybe I try to work on the forced solution as I described in my previous post where once a device is on I force it on for the time it needs to run.

I do a hack with my power_load_no_vars sensor so that case isnā€™t invisible.

Rather than using
load_no_vars = Load - DevicePower

I use
load_no_vars = Load - DeviceForecast

This has the effect that if the device is running when it isnā€™t forecast EMHASS still has visibility that that power is being used by something and doesnā€™t try to allocate to something else. If the device is running when forecast EMHASS just calculates as normal.

Ah that seems a good way to work around that! But for my case that also probably would not work because I want to time some devices which must run for a specified time in the case they get turned on and I donā€™t want to scew the load production forecast.

Yes

I can only assume that the system ā€˜knowsā€™ it has set sensor.p_deferrableX on at whatever Wattage it has set it to. IT doesnā€™t know if HA has triggered the load on or not.
There is no feedback of load activation into EMHASS and even the power consumption of deferrable loads is subtracted from the total household load in the entity used in the EMHASS configuration YAML.

Just upgraded to Home Assistant core 2024.4.3 and I am now having difficultly accessing the EMHASS logs.

The optimisation still seems to be running correctly in the backgroundā€¦

Looks like it is all the looks for all add ins.

1 Like

bleeding edge

Hi Guys,

My EMHASS and Amber integration has been working fine for the past 9 months or more. Iā€™m thinking of moving to OVO (AU) for testing my usage during winter. Is there way in EMHASS to configure different tarrifs below?

00:00 - 06:00 8c
06:00 - 15:00 27c
06:00 - 11:00 : 27c
11:00 - 14:00 : 0c (free energy)
14:00 - 15:00 27c
15:00 - 21:00 : 47c
21:00 - 00-00 : 27c

Also has anyone from from Amber to OVO and regretted it? :smiley:

Thanks very much

You can setup two helper sensors to change the forecasts for both prices.

I presume one is feed in and the other is there import price.

This is what it means.

1 Like

Exctly, there is a good example sensor template code in this discussion: https://github.com/davidusb-geek/emhass/issues/203

For your module this seems like a good match. Same brand same power: Trina_Solar_TSM_465DEG15VC_20_II_

For the inverter this seems like a good match for hybrid and power:
SolaX_Power_Network_Technology__Zhe_jiang__Co___Ltd___A1_Hybrid_7_6_US__240V_

The workaround I have successfully implemented is that I also reduce the def_end_timestep to force the load to the beginning. This seems to be very buggy as the constant load then gets sometimes multiplied or devided by 2! Also the optimzer state then goes to infeasble.

This is a bug:

I have a template to work around this.
Let Deferrable load = x and def_end_timestep = y
If y = 2x the bug occurs. So:
ā€œset_def_constantā€: {{ ā€˜falseā€™ if y <= x * 2) else ā€˜trueā€™ }}

This is not a bug, it is just as this type of optimization work. We canā€™t add constraint upon contraint and expect that it will always go smoothly. As some point there is just too much constraint or constraints that are not compatible.
The problem has been identified but there is not much to do code wise. That issue will be closed soon

1 Like

Very strange. The 2024.4.4 is out, probably got fixed with that. Tried searching at the release notes but I did not found anything related.

Now that a lot of people does optimisation much more frequently than once a day, I was thinking how this could be improved without having to majorly rewrite EMHASS.

An idea would be to allow another parameter to be sent to EMHASS which tells EMHASS the deferrable is currently running so keep it running. EMHASS just has to put that in timeslot 0 and in successive timeslots till the job is finished. It could also send how much hows is left in that particular deferrable as EMHASS doesnā€™t keep state. This would be easy for us to send from HA as its easy to find out of the deferrable > 0W and when it last started. As an added bonus, this could be used to signify a job has completed for the day and not try to schedule it later.

eg.
4 hour job not started
def_remainder_time = [4]

4 hour job midway
def_remainder_time = [2]

4 hour job completed
def_remainder_time = [0]

If this requires too much rewrite, then just a simple flag stating whether the job is currently running and we use existing p_def_total_hours to send remaining hours left.

def_running = [1]

1 Like

Thanks Mark and Davidā€¦

Will calling the day optimisation once whenever price changes over time be enough? unlike in Amber I call it like every 2-5 minutes?

Okey. To me it seem a little odd that you canā€™t use the MPC with def_end_timestep in combination with set_def_constant = true. Is it not the point with ā€œreceding horizon principleā€ ?

If you set set_def_constant = false everything works fine. So I must use the template hack to make my application work.

If this is how it will be I think the documentation needs to be updated so itā€™s clear that if you use set_def_constant = true you canā€™t use def_end_timestep in some cases.

Example:
If I have a load with def_total_hours = 6. If it allocate the 6 hours to the end of the window it will fail, look at the figure below. The spooky thing is that it will say that the optimisation is optimal when itā€™s not.

  • 1 on this. Would really want the ability to tell EMHASS that I have a load running and I want it to run the whole timeslot.

Another thing:
If you run the optimisation every 5 minutes in some cases it can for example run the load 12:25 to 12:30. In my case this leads to 5 min run and 25 is missed. If I want a load to run 1 hour in the period and it does this two times I will get 10 min run instead of 60 min.

1 Like

Hi Mikael,

What I do for my pool pump (needs roughly 8 hours per day running) is calculate the amount it has run. So even if your example would happen, it would just schedule it again because the 8 hours arenā€™t done yet.

Example to calculate the amount of time a switch has been on:

- platform: history_stats
  name: "pool_waterpump_hours_on_today"
  entity_id: switch.eh_zwembad_pump_runstop
  state: "on"
  type: time
  start: "{{ now().replace(hour=0, minute=0, second=0) }}"
  end: "{{ now() }}"

Iā€™m super frustrated by an issue that started out of the blue this morning. My naive-mpc-optim fails with an error stating that my no var loads sensor has no history, but I can for sure say that it does. Iā€™m using emhass 0.8.6 docker standalone. The issue came out of the blue this morning. No restarts, no config changes no nothing.
Iā€™ve restarted both emhass and ha. Can it be that emhass for some reason canā€™t connect to ha? No errors in ha logs.

2024-04-14 19:35:00,617 - web_server - INFO - Passed runtime parameters: {'prediction_horizon': 24, 'soc_init': 0.05, 'soc_final': 0.5, 'def_total_hours': [], 'load_cost_forecast': [0.55, 0.37, 0.35, 0.35, 0.35, 0.32, 0.33, 0.34, 0.35, 0.35, 0.59, 0.94, 2.45, 1.86, 1.07, 1.07, 1.01, 0.97, 0.83, 0.63, 0.78, 0.87, 1.0, 0.99], 'prod_price_forecast': [0.32, 0.14, 0.12, 0.12, 0.12, 0.09, 0.1, 0.11, 0.12, 0.12, 0.36, 0.71, 2.22, 1.63, 0.84, 0.84, 0.78, 0.74, 0.6, 0.4, 0.55, 0.64, 0.77, 0.76], 'pv_power_forecast': [109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 222, 567, 1174, 2092, 3042, 4154, 5169, 6031, 6454, 6285, 5663, 4634, 2908]}
2024-04-14 19:35:00,617 - web_server - INFO -  >> Setting input data dict
2024-04-14 19:35:00,617 - web_server - INFO - Setting up needed data
2024-04-14 19:35:00,620 - web_server - INFO - Retrieve hass get data method initiated...
2024-04-14 19:35:02,155 - web_server - INFO - Retrieving weather forecast data using method = list
2024-04-14 19:35:02,157 - web_server - INFO - Retrieving data from hass for load forecast using method = naive
2024-04-14 19:35:02,157 - web_server - INFO - Retrieve hass get data method initiated...
2024-04-14 19:35:02,227 - web_server - ERROR - The retrieved JSON is empty, A sensor:sensor.template_emhass_no_var_load_2 may have 0 days of history or passed sensor may not be correct
2024-04-14 19:35:02,229 - 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 1463, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 872, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 870, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 855, 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 108, in action_call
    input_data_dict = set_input_data_dict(config_path, str(data_path), costfun,
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 128, in set_input_data_dict
    df_input_data_dayahead = pd.concat([P_PV_forecast, P_load_forecast], axis=1)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/reshape/concat.py", line 372, in concat
    op = _Concatenator(
         ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/reshape/concat.py", line 462, in __init__
    raise TypeError(msg)
TypeError: cannot concatenate object of type '<class 'bool'>'; only Series and DataFrame objs are valid

But the sensor exists and has a long history: