EMHASS: An Energy Management for Home Assistant

The variable set_def_constant is available to be changed at runtime when executing the shell command.

Like this:

curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim

You should be able to pass a bunch of other data and parameters if needed. See here: Intro / Quick start — emhass 0.3.20 documentation

Unfortunately not, semi continuous false allows the device power setting to be between 0 and the nominal value. I use that for charging my EV at different charging rates depending on my Solar production.

Correction: the variable needs to be passed at runtime.

It may be easy to create a custom template sensor for what you want to do.

Here is an example where I add the value 100 to each element of my original list:

{%- set power = state_attr('sensor.solcast_forecast_data', 'forecasts') | map(attribute='pv_estimate') | list %}
{%- set values_all = namespace(all=[]) %}
{% for i in range(power | length) %}
  {%- set v = (power[i] | float ) %}
  {%- set values_all.all = values_all.all + [ v + 100 ] %}
{%- endfor %} {{ (values_all.all)[:5] }}

The original list was:

[1.4217, 1.8679, 2.2476, 2.59, 2.8162]

The resulting list:

[101.4217, 101.8679, 102.2476, 102.59, 102.8162]
1 Like

Thanks for help @markpurcell and @davidusb.

1 Like

Is there any way I can see the current settings for ‘set_def_constant’? If this does not exist then it would be nice if we could have it. I get no feedback in the emhass log when I run the service shell_command “publish_def_true”.

shell_command:
  publish_data: "curl -i -H 'Content-Type:application/json' -X POST -d '{}' http://localhost:5000/action/publish-data"
  publish_def_true: "curl -i -H 'Content-Type:application/json' -X POST -d '{'set_def_constant':True}' http://localhost:5000/action/dayahead-optim"

Is it correct that ‘publish_def_true’ applies to all deferrable loads. What do you do if there is a need for a deferrable loads that you need ‘set_def_constant’:False? As an example, the water heater can heat up over several periods, instead of having a long continuous heating.

It should be a list of boolean, exactly as in the example that I posted before.

This is for two (2) deferrable loads:

{"set_def_constant":[True, False]}

I need som help with the shell_command.
I have tried publishing the variable “set_def_constant” many times with the shell_command and the webserver says “400 Bad Request”. I tried with and without tickets (“curl -i …”).

shell_command:
  publish_data: "curl -i -H 'Content-Type:application/json' -X POST -d '{}' http://localhost:5000/action/publish-data"
  publish_def_true: "curl -i -H 'Content-Type:application/json' -X POST -d '{\"set_def_constant\":[True, False]}' http://localhost:5000/action/dayahead-optim"
2022-10-18 18:33:23.804 DEBUG (MainThread) [homeassistant.components.shell_command] Stdout of command: `curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim`, return code: 0:

b'HTTP/1.1 400 BAD REQUEST\r\nContent-Length: 167\r\nContent-Type: text/html; charset=utf-8\r\nDate: Tue, 18 Oct 2022 16:33:23 GMT\r\nServer: waitress\r\n\r\n<!doctype html>\n<html lang=en>\n<title>400 Bad Request</title>\n<h1>Bad Request</h1>\n<p>The browser (or proxy) sent a request that this server could not understand.</p>\n'

2022-10-18 18:33:23.804 DEBUG (MainThread) [homeassistant.components.shell_command] Stderr of command: `curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim`, return code: 0:

b' % 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 201 100 167 100 34 28912 5886 --:--:-- --:--:-- --:--:-- 40200\n'
shell_command:
  publish_data: "curl -i -H 'Content-Type:application/json' -X POST -d '{}' http://localhost:5000/action/publish-data"
  publish_def_true: curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim
2022-10-18 18:26:00.836 INFO (MainThread) [homeassistant.components.script.varmekabler_nystue_gmlstue_kjokken_og_gang_lav_temperatur] Varmekabler nystue, gmlstue, kjokken og gang: Lav temperatur: Repeat at step 1: Executing step delay 0:00:10

2022-10-18 18:26:01.018 DEBUG (MainThread) [homeassistant.components.shell_command] Stdout of command: `curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim`, return code: 0:

b'HTTP/1.1 400 BAD REQUEST\r\nContent-Length: 167\r\nContent-Type: text/html; charset=utf-8\r\nDate: Tue, 18 Oct 2022 16:26:00 GMT\r\nServer: waitress\r\n\r\n<!doctype html>\n<html lang=en>\n<title>400 Bad Request</title>\n<h1>Bad Request</h1>\n<p>The browser (or proxy) sent a request that this server could not understand.</p>\n'

2022-10-18 18:26:01.018 DEBUG (MainThread) [homeassistant.components.shell_command] Stderr of command: `curl -i -H 'Content-Type:application/json' -X POST -d '{"set_def_constant":[True, False]}' http://localhost:5000/action/dayahead-optim`, return code: 0:

b' % 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 201 100 167 100 34 23564 4797 --:--:-- --:--:-- --:--:-- 33500\n'

Thank you @davidusb!

I actually figured it out using the example with the solcast forecast. It appears to work well for me as well.

One thing I’ve been meaning to discuss with you and possible inject as a feature request is to differentiate the cost for production by discharging an energy storage solution from solar power production. My thinking is that it would make sense to be able to add the cost per kWh for wear of the batteries when using them.

One way of handling this until my solar panels are installed would be to subtract the cost per kWh usage of the batteries from the production_price_forecast. However, this solution will not work when we install solar panels since it will always make sense to produce when the sun delivers.

Do you think that adding a third price forecast or even better a fixed cost per kWh under the battery settings would add value to your project?

I estimate that my energy storage solution costs around 1.03 SEK/kWh when I take capacity, efficiency and number of cycles into account. This means that I’d like to see price differences above 1.03 SEK + 0.119 SEK (difference in cost for transportation over the power grid) for it to make sense to discharge relative to when it was charged.

Let me know what you think about the idea and whether your framework would allow for it!

Warmly, Per

Penalizing the battery usage is an option.

But with the current code this is also possible by using the battery SOC min/max limitations. By using these you should be able to constraint the battery depth of discharge (DOD) which is a direct function of the total number of cycles of a battery in its lifetime. This is the way to go.

Another option is to add a penalty on battery number of cycles, but this will just add more equations and more burden on the open source linear programming solvers that we rely on. So this a no go.

Thank you for the quick reply!

It sounds like I got my point across, but I don’t quite understand how to use SOC min/max limitations to determine when to charge/discharge taking cost for the battery into account. Can you elaborate on how to achieve this so that it corresponds to what I’m after?

My understanding of the SOC that is published to HA is that I’m supposed to write automations that make sure that my SOC follows what EMHASS has found to be optimal. If the cost for usage is not taken into account when optimizing it seems hard to know when to refrain from discharging or am I missing something?

I agree that adding a penalty to the number of cycles does not seem like the way to go. Forgive me for making a statement without knowing the complexity of your code, but to me it seems reasonable that different sources of energy can have different cost/profit principles that should govern how they are utilized.

Let me know if you find this suggestion good enough to consider! If not I will attempt to figure out some logic that I can use in the automations that control discharge/charge from HA that prevent non-profitable discharge cycles.

Warmly, Per Takman :slightly_smiling_face:

What I meant is that instead of applying a different cost for a battery discharge, you can directly use the available SOC limits to affect the battery ageing. As I said at the end the battery ageing is direct function of the DOD which in turn depends on SOC min/max limitations. So instead of applying a “cost” we can use these parameters to improve the battery ageing. For higher DOD’s the battery will provide less lifetime cycles. For lower DOD’s the battery will achieve higher lifetime number of cycles. Fixing SOC_min = 0 and SOC_max = 100 will give you the higher possible DOD. If you want to be more conservative and save your battery life then just change that to more constrained values, say SOC_min = 30 and SOC_max = 90. So if you want to save your battery life then constraint the DOD.

I understand your point and that’s why I said that penalizing the battery usage could be an option. But also as I said we should focus on solutions that will minimize the number of equations to solve. If we add a different cost for battery discharge the this will just add more equation to solve. Some user with more than two deferrable load are very close to the open source solver limits, so adding more equations is really not a viable option. This will be a very different story if we relied on commercial LP solvers like CPLEX or Gurobi, but the problem is that these are REALLY expensive.

I agree that adding a penalty to the number of cycles does not seem like the way to go. Forgive me for making a statement without knowing the complexity of your code, but to me it seems reasonable that different sources of energy can have different cost/profit principles that should govern how they are utilized.

Let me know if you find this suggestion good enough to consider! If not I will attempt to figure out some logic that I can use in the automations that control discharge/charge from HA that prevent non-profitable discharge cycles.

This correct, you can and should use some simple rules to directly control your battery based on the provided optimized schedule. You can the apply some basic automations to further constraint your battery in order to slow its ageing.

Thank you for elaborating! I will attempt to use SOC_min/max to dynamically adjust the behavior based on profitability. Possibly by looking at price delta during the day.

I don’t have the domain knowledge required to understand the limits. But I appreciate that you’ve taken the time to make the world a better place by providing this add-on for HA.

Cheers, Per

1 Like

The list of boolean values needs lowercase letters {“set_def_constant”:[true, false]}.

The shell command:

shell_command:
  publish_def_true: curl -i -X POST http://localhost:5000/action/dayahead-optim -H "Content-Type:application/json" -d '{"set_def_constant":[true,true]}'
1 Like

Hi again,

I discovered a problem with my value_template that took some effort to debug. It turns out that the maximum number of characters is 255 for a list. If you pay attention to round off the numbers after adding/subtracting a float you sometimes exceed maximum length for the list. This cause the sensor to become unavailable.

The code below takes care of that!

    electricity_production_price:
      friendly_name: "Electricity production price"
      value_template: >-
        {%- set data = state_attr('sensor.tibber_prices', 'today') | map(attribute='total') | list %}
        {%- set values = namespace(all=[]) %}
        {% for i in range(data | length) %}
          {%- set v = ((data[i] | float + 0.63 - 1.03) |round(4)) %}
          {%- set values.all = values.all + [ v ] %}
        {%- endfor %} {{ (values.all)[:24] }}
      availability_template: >
        {{states('sensor.tibber_prices') in ['Ok']}}
2 Likes

Hi David,

with new forecast.solar in 0.3.20 there are some “approximation” of values which should be zeroed (solar forecast from dusk till dawn. Current situation:

image

Last “correct” value is for 17:00 than it goes up on linear trend till 8:00+ when forecast.solar prediction begins for my coordinates.

image

Did i miss some new option to zero values in forecast.solar? set_zero_min is True.

With the scrape method values are ok.

Thanks
Mirek

1 Like

Well this seems like a bug that needs to be solved. I didn’t see this behavior when I tested this. It will be solved on the next version. Switch to another method for now and thanks for reporting this.

1 Like

Hi and thanks for EMHASS :wink:
This might be a more of a general HASS question but is there a way to retain the data that have been generated from EMHASS ?
When my system reboots after an update or whatever the data is lost and the way it is setup in my system I need to wait until 23:xx until I generate a new optimization.
I guess it could be solved by a smarter list that takes the time into account but I’m not that good.

Hi. This is a known problem. Another user posted about the same issue some time ago.
I haven’t taken the time to put an automation that could solve this, it seems feasible. If anyone else can put this together it would be awesome.
One solution is to trigger an automation after a system restart to reuse the forecast values stored as attributes in the sensors published by emhass. This can be done with templates.
Another solution is to relaunch the optimization task after a system restart, this will regenerate the optimization results file used to publish the sensors data.
There may be other possible solutions…

1 Like

Ok I have putted together two possible automation to contour this problem with the easiest (and laziest) way.

A first option is just to relaunch the optimization task after a Home Assistant restart, like this:

- alias: Relaunch EMHASS tasks after HASS restart (option1)
  trigger:
    - platform: homeassistant
      event: start
  action:
  - service: shell_command.dayahead_optim

A second option is that I now use is fitted to my case as I have putted some automations to control my deferrable loads based on two modes on an input_select: “Auto” and “Optim” modes. In my case the “Auto” mode will just use a predefined manual schedule for my load. The “Optim” mode is using the results from EMHASS. So when Home Assistant restart I can fallback to the “manual” mode and sendd me a notification to alert me from this. Like this:

- alias: Relaunch EMHASS tasks after HASS restart (option2)
  trigger:
    - platform: homeassistant
      event: start
  action:
    - service: input_select.select_option
      target:
        entity_id: input_select.water_heater_mode
      data:
        option: Auto
    - service: notify.sms_free
      data_template:
        title: Changed water_heater_mode to Auto
        message: Home assistant restarted and automatically changed water_heater_mode to Auto mode, launch EMHASS optimization and set back to Optim mode

A more complete and neat solution can be to reuse the forecast values stored as attributes in the sensors published by emhass as I said before using templates.

1 Like

Yeah the reuse of the forecast values or in my case with my provider:
It lists all the values for the current and next day in two different attributes, so if it somehow possible to write a template that takes the two lists and subtracts the historical values for the current day so that the list starts with the current time.
All that is however beyond my copy and pasting skills :wink:

1 Like