EMHASS: An Energy Management for Home Assistant

I use shell command, but see my entso-e syntax:

Shellcommand : "curl -i -H \"Content-Type: application/json\" -X POST -d '{
  \"load_cost_forecast\":{{((state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list))[now().hour:][:24] }},
  \"prod_price_forecast\":{{((state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list))[now().hour:][:24] }},
  \"prediction_horizon\":{{min(24, ((state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.entso_e_api_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list)[now().hour:][:24]|list|length))}},
  \"soc_init\":{{((states('sensor.growatt_growatt_battery_soc') | float(0))) / 100 }},
  \"soc_final\":0.10,
  \"def_total_hours\":[2],
  \"pv_power_forecast\":{{([states('sensor.solcast_pv_forecast_power_now')|int(0)] + state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedHourly')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list + state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedHourly')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list)| tojson}}
  }' http://localhost:5000/action/naive-mpc-optim"

It would help if you could also show the template editor output so we can see what is being fed into EMHASS.

The ā€œpricesā€ attribute of entso-e provides an array with time and prices as ā€œsub attributesā€ for both today and tomorrow, similar to noordpool. If @ThorAlex follows my code that should work.

As you well know the format for yaml is very precise, a comma in the wrong place mucks every thing up.

Here is my rest command:

rest_command:
  naive_mpc_optim:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: 'application/json'
    payload: >-
      {
        "prod_price_forecast": {{
          ([states('sensor.amber_feed_in_price')|float(0)] +
          (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
          | tojson 
        }},
        "load_cost_forecast": {{
          ([states('sensor.amber_general_price')|float(0)] + 
          state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
          | tojson 
        }},
        "load_power_forecast": {{
          ([states('sensor.power_load_no_var_loads')|int] +
          (states('input_text.fi_fo_buffer').split(', ')|map('multiply',1000)|map('int')|list)[1:]
          )| tojson 
        }},
        
        "pv_power_forecast": {{
          ([states('sensor.solaredge_nopowerlimit')|int(0)] +
          state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list +
          state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list
          )| tojson
        }},
        "prediction_horizon": {{
          min(48, (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
        }},
        "alpha": 1,
        "beta": 0,
        "num_def_loads": 6,
        "def_total_hours": {{[states('sensor.def_total_hours_pool_filter')|int(0),
                              states('sensor.def_total_hours_pool_heatpump')|int(0),
                              states('sensor.def_total_hours_ev')|int(0),
                              states('sensor.def_total_hours_hvac')|int(0),
                              states('sensor.def_total_hours_hws')|int(0),
                              states('sensor.def_total_hours_ev2')|int(0)]}},
        "P_deferrable_nom":  [945,5000, 
                              {{ states('sensor.p_nom_ev')}}, 
                              4000, 
                              600, 
                              {{ states('sensor.p_nom_ev2')}}],
        "treat_def_as_semi_cont": [1, 1, 0, 0, 1, 0],
        "set_def_constant": [0, 0, 0, 0, 0, 0],
        "soc_init": {{ (states('sensor.gateway_battery')|int(0))/100 }},
        "soc_final": {{ (states('sensor.gateway_battery')|int(0))/100 }}
      }

and here is the output:

Ok, I updated it with Ronaldā€™s example, still does not seem to work right.

  trigger_entsoe_forecast:
    url: http://localhost:5000/action/dayahead-optim
    method: POST
    content_type: "application/json"
    timeout: 300
    payload: >-
      {
        "load_cost_forecast\":{{((state_attr('sensor.strompriser_entso_e_nettleie_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.strompriser_entso_e_nettleie_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list))[now().hour:][:24] }},
        "prod_price_forecast\":{{((state_attr('sensor.strompriser_entso_e_salg_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.strompriser_entso_e_salg_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list))[now().hour:][:24] }},
        "prediction_horizon\":{{min(24, ((state_attr('sensor.strompriser_entso_e_nettleie_average_electricity_price_today', 'prices_today') | map(attribute='price') | list  + state_attr('sensor.strompriser_entso_e_nettleie_average_electricity_price_today', 'prices_tomorrow') | map(attribute='price') | list)[now().hour:][:24]|list|length))}}
      }

I think you need backslash before and after like this:

\"load_cost_forecast\":
\"prod_price_forecast\":

Do you get the emhass webpage when writing http://localhost:5000 in the browser?

Thanks, I should have seen thatā€¦ No immediate reaction, but it might take a while?

Do you get this webpage when writing http://localhost:5000 in the browser? Try with your Home Assistant server ip-adresse instead.

You can try without the backslash also like this: "load_cost_forecast":

You can also log rest commands in the log. You must first enable debug for rest commands. The you must search in the Home Assistant log for rest command you execute.

logger:
  default: info
  logs:
    homeassistant.components.rest: debug
2 Likes

I came accros this EMHASS project a week ago and I beliefe this might be exactly what iā€™m looking for. Iā€™m in the middle of an ā€œenergy transitionā€: full electric WP for heating just installed, second 3kWp solar system to be installed next month, 5kW battery underway and Iā€™m about to change over from a (Dutch) peak/off-peak electricity contract to a dynamical contract with changing tariffs every hour.

On installing EMHASS I got stuck in the beginning of the proces:
I installed the Add-on via Supervisor. When I tried to start EMHASS I got a pop-up:
ā€œGo to configuration. not a valid value.ā€
So I switched to the configuration UI and made some basic/default settings. Trying to save this configuration returns with an error: "Failed to save add-on configuration, not a valid value. "
Even when I change and unchange any setting in the default configuration and saving it after that I get the same error.

I hope anyone can point me in the right direction to find a solution for this.
Iā€™m running HomeAssistant (2023.10.1) with Supervisor (2023.10) on a Raspberry Pi 4 ( OS 5.10.103)

This is great news, I have been seeing the rest command in the logs when I get an error, but this debug command will greatly assist debugging.

Btw, you can also access the web interface directly from the Add-On Web UI button now, both locally and remotely.

Glad to have you here and let us know how we can help with your setup. It certainly is a game changer with dynamic pricing.

The syntax can get quirky, but there is a reset to defaults option if it isnā€™t behaving.

Hi Mark,
Thanks for the fast reply.
I already tryied your solution to reset to dafaults, but even then EMHASS is not starting and pointing me back to the configuration. It seems the (default) configuration file(s) are not accessable or something like that.

I install the emhass addon from Settings ā†’ Add-ons ā†’ Add-on Store.
First I add the url https://github.com/davidusb-geek/emhass-add-on from here: GitHub - davidusb-geek/emhass-add-on: The Home Assistant Add-on for EMHASS: Energy Management Optimization for Home Assistant
image

Then I install the emhass addon (a docker container):
image

Try to only choose ā€œStart on Bootā€ first:
image

I did not, but changed it ti the IP last night.

Tried that, still no change.

Did that, but canā€™t seem to find anything in the logs. Might be looking in the wrong place?

Also checked the EMHASS logs, nothing there.

I installed EMHASS exactly like you describe. Even with only the default configuration it does not start. I tried activating ā€œStart on bootā€ and then rebooting the complete system: when Home Assistants is up and running again the Emhass addon did not start.
I also tried to uninstall and re-install the addon a few times but still the same: EMPASS does not start.
Only thing a see in the supervisor logs is:

INFO (MainThread) [supervisor.jobs] 'MountManager.reload' blocked from execution, mounting not supported on system

23-10-12 11:36:19 ERROR (MainThread) [supervisor.addons.addon] Add-on 5b918bf2_emhass has invalid options: not a valid value. Got {'hass_url': 'empty', 'long_lived_token': 'empty', 'costfun': 'profit', 'logging_level': 'INFO', 'optimization_time_step': 30, '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': False, 'set_nodischarge_to_grid': False, 'set_battery_dynamic': False, 'battery_dynamic_max': 0.9, 'battery_dynamic_min': -0.9, 'load_forecast_method': 'naive', 'sensor_power_photovoltaics': 'sen...

Iā€™m not a HomeAssistant specialist. So, Iā€™m stuck here.

Hey Mark,

Being on Amber, have you worked out how to add the value of what you generated and profited through the day? Example being my screenshot?

I would take your earnings of $13.45 and add to that the cost of your household consumption multiplied by your default market rate.

If your consumption was about average at 20 kW at a default market offer of 30Ā¢/ kWh, then that is an additional $6 of savings, for a total of $20 savings for the day ~ $600 pre month or ~ $7,000 per year!

If your consumption was 100 kW at a default market offer of 30Ā¢/ kWh, then that is an additional $30 of savings, for a total of $33.45 savings for the day ~ $1000 pre month or ~ $12,000 per year!

If the webserver is not responding on TCP port 5000 the rest command will fail. You can try to change the port to 5001 and see if it works. The web adresse will then be: http://:5001/

I Ment the actual calculator itself,

As amber is variable i wouldnt know how your supposed to add the calculator to a rolling value,

Ive looked around to see on abmber and all that, but im trying to combine everything to too 1 app.

Just to try to understand how things work: Is the rest communicating through my lan/router and not internally in the software on the rpi? In that case Iā€™ll probably have firewall issues, but why would home assistant need to communicate over lan with itā€™s own addon? And why would the port matter if not? Makes no sense to meā€¦

Iā€™ll try anyways, I really appreciate the help!