EMHASS: An Energy Management for Home Assistant

They are separate virtual machines. They will communicate via TCP/IP. The traffic will flow through each virtual TCP/IP stack on each virtual machine. If you firewall HA somehow it will not be able to communicate without modification.

You can recreate the Amber usage view in Home Assistant using this project here:

Alternatively you can imbed the Amber web app into your Home Assistant dashboard:

Ok, so the traffic goes trough the router? That might be my issue then. Home assistant is on my IOT subnet where all traffic is blocked unless specifically allowed. I’ll have to look into that, initial googling does is not promesing to find an easy solution.

It shouldn’t need to go through the router, if you have the EMHASS container and Home Assistant on the same physical device.

The simple check is to try and connect through port 5000 using telnet to see if it can connect.

$ telnet localhost 5000
Trying ::1...
Connected to localhost.
Escape character is '^]'.

Simple is relative i guess…
Untitled

telnet command is a windows command. Use your windows 10 pc to test the port.
Write in the search menu: cmd

In command line write:

telnet <ip adresse> 5001

Untitled

Eh…

Edit: Fixed that, telnet client was deactivated. When i run the command the command line just goes empty, not sure what that means?

Edit 2: Telnet to IP gives blank window, telnet to localhost gives “connection failed” error.

This is the correct respons. You have access to TCP port 5001.

This is correct. The ip-adresse for the name localhost is the pc you use telnet from. You must use ip-adresse for accessing Home Assistant server externally.

Ok, so access should not be reason my rest commands does not seem to work. Looks like it’s back to the commands themself then?

If I test the rest command:


I get:

I get no errors (that i can find) when i run the emhass optimizations, but it still pulls the fixed prices from the config.

Currently (the relevant bits of) my configurations.yaml looks like this:


and automations.yaml:
Untitled3

(Posted screenshots in case I’m doing something wrong or have put something in the wrong place, since that is often the case with me.)

You are using mpc optimization variabel “prediction_horizon” in a dayahead forecasting. If you want a dayahead forecasting you do not need this variabel.

Here is a dayahead forecasting example:

  trigger_entsoe_dayahead_forecast:
    url: http://localhost:5001/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] }}
      }

Here is an mpc forecasting example with the variabel “prediction_horizon”:

trigger_entsoe_mpc_forecast:
    url: http://localhost:5001/action/naive-mpc-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": 6
      }

Read also the intro/quick start in the emhass documentation again: [Intro / Quick start — emhass 0.5.0 documentation]
https://emhass.readthedocs.io/en/latest/intro.html#a-naive-model-predictive-controller

Thanks, that looks to have fixed it!

Nope, spoke too soon. EMHASS gets the right prices if i run the command manually from developer tools, but not if i run the tasks from the buttons in the web interface.

I barely understand half of that text, really need the dummies version I guess…

When you run with the buttons in the webinterface no parameteres are passed. The shell_command is like this:

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

You must automate the day-ahead forecast every day with rest_commands. Your automation is using shell_command. Do it like this

alias: "Emhass: Dayahead optimisering klokken 13:45"
description: ""
trigger:
  - platform: time
    at: "13:45:00"
condition: []
action:
  - service: rest_command.trigger_dayahead_1345_forecast
    data: {}
mode: single

Hi all, love the idea of this but really struggling to get it to work!

I have 30min dynamic pricing, solar and battery, with no need to export to the grid (old UK feed in tariff where they assume what you feed in, rather than actually count it).

I have setup the shell commands, and a daily automation to run the dayahead, and a 5min run of publishing, which are successfully populating the UI.

My issues are that the 30min pricing information is not populating, it is only using the peak hours/periods from the config below (but I can’t remove those in that config?). Additionally the battery SOC in the forecast is 60% permanently (I appreciate that that is the target but it isn’t flexing up or down at all?). Also not sure why I need a deferable load - is that meant to be the battery charge?

Assume I’m missing something simple, any help would be appreciated, thanks!

shell_command:
  dayahead_optim: "curl -i -H \"Content-Type:application/json\" -X POST -d '{\"load_cost_forecast\": {{((state_attr('sensor.octopus_energy_electricity_current_rate', 'all_rates')|map(attribute='value_inc_vat')|list)[:48])}}' http://localhost:5000/action/dayahead-optim"
  publish_data: "curl -i -H \"Content-Type:application/json\" -X POST -d '{}' http://localhost:5000/action/publish-data"

Where

{{((state_attr('sensor.octopus_energy_electricity_current_rate', 'all_rates')|map(attribute='value_inc_vat')|list)[:48])}}

is returning 48 30min comma energy prices.

My configuration is currently:

hass_url: empty
long_lived_token: empty
costfun: cost
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: sensor.production_today
sensor_power_load_no_var_loads: sensor.consumed_today
number_of_deferrable_loads: 2
list_nominal_power_of_deferrable_loads:
  - nominal_power_of_deferrable_loads: 3000
  - nominal_power_of_deferrable_loads: 750
list_operating_hours_of_each_deferrable_load:
  - operating_hours_of_each_deferrable_load: 5
  - operating_hours_of_each_deferrable_load: 8
list_peak_hours_periods_start_hours:
  - peak_hours_periods_start_hours: "02:54"
  - peak_hours_periods_start_hours: "17:24"
list_peak_hours_periods_end_hours:
  - peak_hours_periods_end_hours: "15:24"
  - peak_hours_periods_end_hours: "20:24"
list_treat_deferrable_load_as_semi_cont:
  - treat_deferrable_load_as_semi_cont: true
  - treat_deferrable_load_as_semi_cont: true
load_peak_hours_cost: 0.1907
load_offpeak_hours_cost: 0.1419
photovoltaic_production_sell_price: 0
maximum_power_from_grid: 9000
list_pv_module_model:
  - pv_module_model: CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M
list_pv_inverter_model:
  - pv_inverter_model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_
list_surface_tilt:
  - surface_tilt: 30
list_surface_azimuth:
  - surface_azimuth: 205
list_modules_per_string:
  - modules_per_string: 16
list_strings_per_inverter:
  - strings_per_inverter: 1
set_use_battery: true
battery_discharge_power_max: 2000
battery_charge_power_max: 2000
battery_discharge_efficiency: 0.95
battery_charge_efficiency: 0.95
battery_nominal_energy_capacity: 5000
battery_minimum_state_of_charge: 0.1
battery_maximum_state_of_charge: 0.9
battery_target_state_of_charge: 0.6

Oh, fixed that now. If I trigger the automations EMHASS seems to work as it should.

So if I understand this right, the prices will only update if the automation is triggered? I Can not use the buttons in the web interface to test if everything is working? Now wonder I’ve been struggling then…

1 Like

You need to add Rest commands to send the info, Currently your using shell commands to send it.

Change you commands to suit your sensors

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

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.home_feed_in_price')|float(0)] +
          (state_attr('sensor.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
          | tojson 
        }},
        "load_cost_forecast": {{
          ([states('sensor.home_general_price')|float(0)] + 
          state_attr('sensor.home_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
          | tojson 
        }},
        "pv_power_forecast": {{
          ([states('sensor.solar_total')|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.home_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
        }},
        "soc_init": {{(states('sensor.battery_total_2')|int(0))/400 }},
        "soc_final": 0.2
      } 
1 Like

I’ve got some weird results when running this MPC:

curl -i -H "Content-Type: application/json" -X POST -d '{
        "load_cost_forecast": [0.1616, 0.1604, 0.1604, 0.1612, 0.1612, 0.1591, 0.1591, 0.1596, 0.1596, 0.1593, 0.1593, 0.1587, 0.1587, 0.1589, 0.1589, 0.1602, 0.1602, 0.1613, 0.1613, 0.1722, 0.1722, 0.1859, 0.1859, 0.1626, 0.1626, 0.1613, 0.1613, 0.1602, 0.1602, 0.16, 0.16, 0.1597, 0.1597, 0.1612, 0.1612, 0.1621, 0.1621, 0.2413, 0.2413, 0.3016, 0.3016, 0.316, 0.316, 0.2767, 0.2767, 0.2633, 0.2633, 0.2501],
        "prediction_horizon": 48,
        "pv_power_forecast": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 677, 839, 1090, 1311, 1574, 2072, 2605, 3306, 3893, 4433, 4769, 5023, 5196, 5251, 5016, 4708, 3979, 3103, 2079, 1035, 889, 0, 0, 0, 0, 0, 0, 0],
        "alpha": 0.75,
        "beta": 0.25,
        "num_def_loads": 3,
        "def_total_hours": [0,3,0],
        "P_deferrable_nom":  [
            2250,
            2000,2000
          ],
        "treat_def_as_semi_cont": [false, false, false],
        "set_def_constant": [true, true, true]
      }' http://localhost:5000/action/naive-mpc-optim

It splits up the load into more then 3 hours.

This won’t be better if running for two deferrable loads (3h each).

curl -i -H "Content-Type: application/json" -X POST -d '{
        "load_cost_forecast": [0.1616, 0.1604, 0.1604, 0.1612, 0.1612, 0.1591, 0.1591, 0.1596, 0.1596, 0.1593, 0.1593, 0.1587, 0.1587, 0.1589, 0.1589, 0.1602, 0.1602, 0.1613, 0.1613, 0.1722, 0.1722, 0.1859, 0.1859, 0.1626, 0.1626, 0.1613, 0.1613, 0.1602, 0.1602, 0.16, 0.16, 0.1597, 0.1597, 0.1612, 0.1612, 0.1621, 0.1621, 0.2413, 0.2413, 0.3016, 0.3016, 0.316, 0.316, 0.2767, 0.2767, 0.2633, 0.2633, 0.2501],
        "prediction_horizon": 48,
        "pv_power_forecast": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 511, 677, 839, 1090, 1311, 1574, 2072, 2605, 3306, 3893, 4433, 4769, 5023, 5196, 5251, 5016, 4708, 3979, 3103, 2079, 1035, 889, 0, 0, 0, 0, 0, 0, 0],
        "alpha": 0.75,
        "beta": 0.25,
        "num_def_loads": 3,
        "def_total_hours": [0,3,3],
        "P_deferrable_nom":  [
            2250,
            2000,2000
          ],
        "treat_def_as_semi_cont": [false, false, false],
        "set_def_constant": [true, true, true]
      }' http://localhost:5000/action/naive-mpc-optim

If I ran the same command with a prediction_horizon of 36 it seems to produce the right output:

Any ideas?

Furthermore I would expect that one of the loads could already start at 12:30 pm…

Hey, new issue here. Everything seems to be working now, but the entso-e prices are late by one hour. They are correct everywhere else exept in emhass. Any ideas what could cause this?

Try the first/last setting, mine is set to first. Perhaps that helps?

What does your jinja code produce when you test in Developer Tools Template? What does your pricing sensor look like?
My dayahead jinja code looks like this:

{
  "load_cost_forecast": {{
    ([states('sensor.cecil_st_general_price')|float(0)] + 
    state_attr('sensor.cecil_st_general_forecast', 'forecasts') |map(attribute='per_kwh')|list) 
    | tojson 
  }},
  "prod_price_forecast": {{
    ([states('sensor.cecil_st_feed_in_price')|float(0)] +
    (state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
    | tojson 
  }},
  "pv_power_forecast": {{
    ([states('sensor.sonnenbatterie_84324_production_w')|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
  }},
  "num_def_loads": 2,
  "def_total_hours": [3,0],
  "P_deferrable_nom":  [1300, 7360],
  "treat_def_as_semi_cont": [1, 0]  
}

Result from Developer Tools Template looks like this:

{
  "load_cost_forecast": [
    0.16,
    0.16,
    0.16,
    0.16,
    0.16,
    0.16,
    0.16,
    0.15,
    0.13,
    0.13,
    0.13,
    0.16,
    0.16,
    0.16,
    0.16,
    0.13,
    0.11,
    0.1,
    0.1,
    0.1,
    0.1,
    0.08,
    0.04,
    0.03,
    0.03,
    0.02,
    0.02,
    0.02,
    0.02,
    0.27,
    0.27,
    0.28,
    0.29,
    0.3,
    0.32,
    0.35,
    0.36,
    0.38,
    0.42,
    0.42,
    0.45,
    0.19,
    0.16,
    0.16,
    0.16,
    0.15,
    0.13,
    0.15,
    0.13
  ],
  "prod_price_forecast": [
    0.06,
    0.06,
    0.06,
    0.06,
    0.06,
    0.06,
    0.06,
    0.05,
    0.04,
    0.04,
    0.04,
    0.06,
    0.06,
    0.06,
    0.06,
    0.04,
    0.02,
    0.01,
    0.01,
    0.01,
    0.01,
    -0.03,
    -0.07,
    -0.07,
    -0.08,
    -0.08,
    -0.08,
    -0.08,
    -0.09,
    0.2,
    0.2,
    0.21,
    0.21,
    0.22,
    0.24,
    0.27,
    0.28,
    0.29,
    0.33,
    0.33,
    0.36,
    0.09,
    0.06,
    0.06,
    0.06,
    0.06,
    0.04,
    0.06,
    0.04
  ],
  "pv_power_forecast": [
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    5,
    58,
    345,
    861,
    1411,
    1992,
    2500,
    2941,
    3314,
    3608,
    3856,
    4004,
    4049,
    4064,
    4090,
    4020,
    3854,
    3642,
    3354,
    3020,
    2599,
    2130,
    1554,
    1031,
    503,
    89,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
  ],
  "num_def_loads": 2,
  "def_total_hours": [
    3,
    0
  ],
  "P_deferrable_nom": [
    1300,
    7360
  ],
  "treat_def_as_semi_cont": [
    1,
    0
  ]
}

My pricing data looks like this:

Deferrable loads are things like EV charging, hot water, pool pump etc. These loads need to be automated so EMHASS can control them and their consumption subtracted from household consumption.
Maybe this might help my doco

1 Like