EMHASS: An Energy Management for Home Assistant

There is an auto update switch available on the add on page.

For EMHASS I have this switched to off.

1 Like

Me too; have it turned off for all addons. think its the new HA version. This pushes a “you are not on the latest version message” in your face. Must have clicked through it unintentionally

Thanks for this feature.

This now makes sense if the penalty is in [€,$]/ kWh.

Agreed have the default as 1 [€,$]/ kWh is too harsh and does dramatically effect the scheduling, setting the default to 0, which mirrors current behaviour would be a good default.

I have the same issue as above.
EMHASS is continuously charging and discharging.
I reverted to 0.5.3 and deleted this temporary pkl files. (and restart)
No effect.

I assume it has to do with the new HA 2024.01

When I change back to “Naive”, it is fine again (only on 0.5.3.)

Question: is EMHASS capable of working with forecasts that go beyond 24h from now?

Context:
In Belgium, the day-ahead market prices are published around 14h on day D-1. From that point on, I have all price information until end of the next day (day D), so I could envision to optimize a time window of max 34h:

I tried to run a naive MPC optimization, providing all required input timeseries as runtime parameters:
image
Note: I use 30min timesteps, which explains why prediction horizon is that long.
This is taken at 20h50 on day D-1, so there are 55 remaining half hours until end of day D. For each of these half hours, I provided price and power inputs.

Running the naive MPC optimization results in following output:

2024-01-04 20:38:58,064 - web_server - INFO - Setting up needed data
2024-01-04 20:38:58,069 - web_server - INFO - Retrieve hass get data method initiated…
2024-01-04 20:39:55,330 - web_server - INFO - Retrieving weather forecast data using method = list
2024-01-04 20:39:55,341 - 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 1455, in wsgi_app
response = self.full_dispatch_request()

File “/usr/local/lib/python3.11/dist-packages/flask/app.py”, line 869, in full_dispatch_request
rv = self.handle_user_exception(e)

File “/usr/local/lib/python3.11/dist-packages/flask/app.py”, line 867, in full_dispatch_request
rv = self.dispatch_request()

File “/usr/local/lib/python3.11/dist-packages/flask/app.py”, line 852, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)

File “/usr/local/lib/python3.11/dist-packages/emhass/web_server.py”, line 181, 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 127, in set_input_data_dict
df_input_data_dayahead = copy.deepcopy(df_input_data_dayahead
[df_input_data_dayahead.index[0]:df_input_data_dayahead.index[prediction_horizon-1]]

File “/usr/local/lib/python3.11/dist-packages/pandas/core/indexes/base.py”, line 5175, in getitem
return getitem(key)

File “/usr/local/lib/python3.11/dist-packages/pandas/core/arrays/datetimelike.py”, line 370, in getitem
“Union[DatetimeLikeArrayT, DTScalarOrNaT]”, super().getitem(key)

File “/usr/local/lib/python3.11/dist-packages/pandas/core/arrays/_mixins.py”, line 272, in getitem
result = self._ndarray[key]

IndexError: index 54 is out of bounds for axis 0 with size 48

It seems that the dataframe “df_input_data_dayahead” only has a size of 48, even though the provided input timeseries for load and PV power forecast were sufficiently long for the prediction_horizon of 55.

Why doesn’t the optimizer accept prediction horizons longer than 24 hours?

Mine is ok again. I changed the new charges option from 1 to 0 and that solved it. Dont have time for further tweaking today but suspect this triggered the weird behavior.

Am on 2024.01 and emhass 5.4

I believe you can run the day-ahead optimisation with more than 24 hours (48 entries), but the MPC is limited to 48 entries.

So in your case, I would suggest when you receive the full 34 hour forecast run the day-ahead optimisation with your full data and then run your MPC optimisation with a shorter time frame.

My half hour prices (Amber Electric) are updated every 5 minutes, are your half hour prices updated after the initial publication?

Another strategy you may want to try (if not already doing - I am) in addition to Marks’s suggestion is to run MPC on a rolling 48-timestamps window.

1 Like

David,

What value EMHASS assign to PV that top’s up battery?

I am trying to establish why EMHASS trying to trade power at loss. It seem to purchase at higher price than selling back to grid. Charge/Discharge Weights set to +0.1

Thanks. Great work. I think that fixed it.
Now I can get back to figuring out how to load my peak and low tariff hours.
I have trouble understanding how to do it.

1 Like

Indeed that fixed it.

I don’t understand this weight.

If I try to understand, it adds 1 unit/kwh for the costs.
So if my electricity price is 0.25 euro/kwh, it will make it 1.25 euro/kwh? Or is for each cycle.

But then if it is as pre-configured 1 and 1, it should not start to charge and discharge all the time. Or does it has to be negative values?

I added

"curl -i -H \"Content-Type:application/json\" -X POST -d '{\"set_def_constant\":[true, true], \"load_cost_forecast\":[{{(
          ([states('sensor.energy_buy_price')|float(0)] +
          state_attr('sensor.energy_buy_price', 'forecasts') |map(attribute='per_kwh')|list)[:24])
          }}]}' http://localhost:5000/action/dayahead-optim"

to the config and wanted to adapt the sensor.energy_buy_price to

- platform: template
  sensors:
    energy_buy_price:
      friendly_name: "Energy buy price"
      unit_of_measurement: "€"
      value_template: >-
        {% set weekdays = [0, 1, 2, 3, 4] %}
        {% set entry1_to_7 = [0.1777] * 7 %}
        {% set entry8_to_23 = [0.2162] * 16 %}
        {% set entry24 = [0.1777] * 1 %}

        {% if now().weekday() in weekdays %}
          {% if now().hour < 8 %}
            {{ entry1_to_7 }}
          {% elif now().hour > 22 %}
            {{ entry24 }}
          {% else %}
            {{ entry1_to_7 + entry8_to_23 }}
          {% endif %}
        {% else %}
          {{ [0.1777] * 24 }}
        {% endif %}

But that doesn’t work. What am I doing wrong? In the development section this seems to work but the sensor doesn’t return a list if I implement it.

I am at an equal point… still trying to figure this out! :slight_smile:

You are trying to create a sensor that is meant to hold a single value as state but actually you are trying to make it contain a list, which is not intended for. And in any case there is a strict limit on the amount of characters a sensor state can contain, which will soon make this approach fail.
In the previous examples people were mapping the information contained in the attributes, from a sensor that actually contained it.
You can’t copy-paste the same code and just change the name of the sensor as it will not work.
What you could do is to create a sensor that contains the current cost and in the attributes the forecast if this is the approach you want to take.

I whish I’ld understand what you mean by this.

What you could do is to create a sensor that contains the current cost and in the attributes the forecast if this is the approach you want to take.

I had this sensor but I don’t know how to get the data into a list for emhass.

- platform: template
  sensors:
    energy_buy_price:
      friendly_name: "Energy buy price"
      unit_of_measurement: "€"
      value_template: >
          {% if states('sensor.electricity_meter_active_tariff')|string == 'low' %}
              0.1777
          {% else %}
              0.2162
          {% endif %}

Dear all,

I am testing EMHASS as an add-on to HA and I am seeing some weird behaviour of my battery. It looks like it’s charging although I am having almost no production from my PV here in dark Europe :frowning: these days. If there is some production this is instantly consumed by the current home loads I have active.

Below are extracts from my config file showing the battery parameters and some graphs of the result of todays dah ahead optimisation.

“hass_url”: “empty”,

“long_lived_token”: “empty”,

“costfun”: “cost”,

“logging_level”: “DEBUG”,

“optimization_time_step”: 60,

“historic_days_to_retrieve”: 2,

“method_ts_round”: “nearest”,

“set_total_pv_sell”: false,

“lp_solver”: “COIN_CMD”,

“lp_solver_path”: “/usr/bin/cbc”,

“set_nocharge_from_grid”: true,

“set_nodischarge_to_grid”: true,

“set_battery_dynamic”: false,

“battery_dynamic_max”: 0.9,

“battery_dynamic_min”: -0.9,

“weight_battery_discharge”: 1.0,

“weight_battery_charge”: 1.0,

“load_forecast_method”: “naive”,

….

“set_use_battery”: true,

“battery_discharge_power_max”: 3840,

“battery_charge_power_max”: 3840,

“battery_discharge_efficiency”: 0.95,

“battery_charge_efficiency”: 0.95,

“battery_nominal_energy_capacity”: 10515,

“battery_minimum_state_of_charge”: 0.05,

“battery_maximum_state_of_charge”: 1.0,

“battery_target_state_of_charge”: 0.05

ts P_PV P_Load P_deferrable0 P_deferrable1 P_grid_pos P_grid_neg P_grid P_batt SOC_opt unit_load_cost unit_prod_price cost_profit cost_fun_cost optim_status
2024-01-06 00:00:00+01:00 0 1656.0 0.0 0.0 1656.0 0.0 1656.0 0.0 0.05 0.21 0.09 -0.34 -0.34 Optimal
2024-01-06 01:00:00+01:00 0 1765.0 0.0 0.0 1765.0 0.0 1765.0 0.0 0.05 0.20 0.08 -0.36 -0.36 Optimal
2024-01-06 02:00:00+01:00 0 1716.0 0.0 0.0 1716.0 0.0 1716.0 0.0 0.05 0.20 0.08 -0.34 -0.34 Optimal
2024-01-06 03:00:00+01:00 0 1737.0 0.0 0.0 1737.0 0.0 1737.0 0.0 0.05 0.20 0.08 -0.34 -0.34 Optimal
2024-01-06 04:00:00+01:00 0 1666.0 2300.0 700.0 4666.0 0.0 4666.0 0.0 0.05 0.19 0.07 -0.90 -0.90 Optimal
2024-01-06 05:00:00+01:00 0 1705.0 2300.0 700.0 4705.0 0.0 4705.0 0.0 0.05 0.19 0.07 -0.91 -0.91 Optimal
2024-01-06 06:00:00+01:00 0 1701.0 2300.0 0.0 4001.0 0.0 4001.0 0.0 0.05 0.19 0.07 -0.78 -0.78 Optimal
2024-01-06 07:00:00+01:00 0 2122.0 0.0 0.0 2122.0 0.0 2122.0 0.0 0.05 0.19 0.08 -0.41 -0.41 Optimal
2024-01-06 08:00:00+01:00 0 2072.0 0.0 0.0 2072.0 0.0 2072.0 0.0 0.05 0.20 0.08 -0.42 -0.42 Optimal
2024-01-06 09:00:00+01:00 140 1914.0 0.0 0.0 1914.0 0.0 1914.0 -140.0 0.06 0.21 0.09 -0.40 -0.40 Optimal
2024-01-06 10:00:00+01:00 502 1905.0 0.0 0.0 1905.0 0.0 1905.0 -502.0 0.11 0.21 0.09 -0.41 -0.41 Optimal
2024-01-06 11:00:00+01:00 990 2004.0 0.0 0.0 2004.0 0.0 2004.0 -990.0 0.20 0.22 0.10 -0.44 -0.44 Optimal
2024-01-06 12:00:00+01:00 1203 2184.0 0.0 0.0 2184.0 0.0 2184.0 -1203.0 0.31 0.22 0.10 -0.48 -0.48 Optimal
2024-01-06 13:00:00+01:00 1203 1946.0 0.0 0.0 1946.0 0.0 1946.0 -1203.0 0.41 0.22 0.10 -0.43 -0.43 Optimal
2024-01-06 14:00:00+01:00 941 1911.0 0.0 0.0 1911.0 0.0 1911.0 -941.0 0.50 0.21 0.09 -0.41 -0.41 Optimal
2024-01-06 15:00:00+01:00 456 1876.0 0.0 0.0 1876.0 0.0 1876.0 -456.0 0.54 0.21 0.09 -0.40 -0.40 Optimal
2024-01-06 16:00:00+01:00 93 1841.0 0.0 0.0 1841.0 0.0 1841.0 -93.0 0.55 0.21 0.09 -0.39 -0.39 Optimal
2024-01-06 17:00:00+01:00 0 1817.0 0.0 0.0 1817.0 0.0 1817.0 0.0 0.55 0.21 0.09 -0.38 -0.38 Optimal
2024-01-06 18:00:00+01:00 0 1850.0 0.0 0.0 0.0 0.0 0.0 1850.0 0.36 0.23 0.10 -0.00 -0.00 Optimal
2024-01-06 19:00:00+01:00 0 2018.0 0.0 0.0 0.0 0.0 0.0 2018.0 0.16 0.22 0.10 -0.00 -0.00 Optimal
2024-01-06 20:00:00+01:00 0 2657.0 0.0 0.0 1538.0 0.0 1538.0 1119.0 0.05 0.22 0.10 -0.34 -0.34 Optimal
2024-01-06 21:00:00+01:00 0 2192.0 0.0 0.0 2192.0 0.0 2192.0 0.0 0.05 0.21 0.09 -0.47 -0.47 Optimal
2024-01-06 22:00:00+01:00 0 2023.0 0.0 0.0 2023.0 0.0 2023.0 0.0 0.05 0.21 0.09 -0.42 -0.42 Optimal
2024-01-06 23:00:00+01:00 0 2029.0 0.0 0.0 2029.0 0.0 2029.0 0.0 0.05 0.21 0.09 -0.42 -0.42 Optimal


So bottom line I don’t understand why my battery charges to 50%, which explains the discharge around 18h.

Thanks
Yves

You forecast a decent amount of pv generation. Your system assumes to store this for usage later in the day deu to price differential. Tweak your efficiency (eg to 90% instead of 95%) this way the algorithm will not optimize at a mere 2 c difference.

Alternatively you can play with the weight, bot are now at 1, would put discharge to 0 and charge to for example 0.05 or 0.1, assuming a cost of 5c or 10c to charge the battery.

That should result in the PV being used directly to load instead of storing it.

3 Likes

@davidusb
Additional function for consideration somewhere in battery settings “Maximize battery life” switch.
This can include activation of following constrains:

  • Limit battery MAX discharge to 10%
  • Limit battery max charge to 90%
  • Include compulsory 10 min pause between charge/discharge mode switches. This allows battery chemistry to stabilise (applicable for Li chemistry) between current reversal.
  • Charge current reduction to 50% after battery reaches 80% (this one not as critical)