EMHASS Add‐on - heinemannj/huawei_solar_hems GitHub Wiki

Energy Management for Home Assistant (EMHASS)

Introduction

EMHASS is a powerful energy management and optimization tool designed for residential households connected to Home Assistant (HA).

EMHASS uses a Linear Programming approach to optimize energy usage while considering factors such as electricity prices, power generation from solar panels and energy storage from batteries.

EMHASS


With EMHASS, households can define their energy management objectives and constraints, such as maximizing self-consumption and/or minimizing energy costs, and EMHASS will generate an optimization plan accordingly.

EMHASS_optimization

allowing households to create a fully customized and optimized energy management solution.

Overall, the integration of reliable forecast data, Huawei Solar HEMS, EMHASS and Home Assistant offers a comprehensive energy management solution including a machine learning forecaster, a machine learning regressor and an deferrable load thermal model that provides significant cost savings, increased energy efficiency, and greater sustainability for households. By leveraging advanced energy management features and automation capabilities, households can achieve their energy management objectives while enjoying the benefits of more efficient and sustainable energy usage, including optimized EV charging schedules.

EMHASS_deferrable_timewindow_evexample

Forecast data

Huawei Solar HEMS assist you

  • to collect all required forecast data,
  • to adjust them,
  • to add the data as a list of values to an EMHASS data dictionary,
  • to automate EMHASS optimization calls,
  • to pass the data dictionary and all required optimization constraints

using the EMHASS runtimeparams option.

Used dictionary keys to pass your customized forecast data at runtime:

Input Output Forecast data Integration
Hourly Weather forecasts by the usage of DWD Weather integration.
This custom component adds hourly weather data from Deutscher Wetterdienst ( DWD ) into HA.
Deutscher Wetterdienst
Sunrise, Sunset and Solar Noon forecasts by the usage of ha-sun2 integration.
This custom component adds sensors that provide information about various sun related events into HA.
Additional info: NOAA Solar Calculator
Sun2
pv_power_forecast PV Solar forecasts (in Watts) by the usage of Solcast integration.
This custom component integrates the Solcast Hobby PV Forecast API into HA.
Solcast
load_cost_forecast EPEXSpot electricity price forecasts (in EUR/kWh) by the usage of EPEXSpot integration.
This custom component adds electricity prices from the European Power EXchange ( EPEXSpot ) into HA.
EPEXSpot
p_load_forecast House load forecast (in Watts) by the usage of the EMHASS Add-on. EMHASS
soc_batt_forecast Batteries Status Of Charge (SOC) forecast (in %) by the usage of the EMHASS Add-on. EMHASS
p_grid_forecast Grid Import/Export forecast (in Watts) by the usage of the EMHASS Add-on.
Forecasted net power flow between your home and the grid.
A positive value indicates net export, while a negative value indicates net import.
EMHASS
huawei_solar_hems_dashboard_2

For a complete list of EMHASS computed variables and published data please look at EMHASS documentation.

Optimization plan

Sun2

The prediction horizon used by Huawei Solar HEMS is following the sun by the usage of Sun2 integration, taking into account your specific location parameters.

Check points

Key Default Description
Latitude HA location parameters The location's latitude (in degrees).
Longitude HA location parameters The location's longitude (in degrees).
Observer elevation 10m Observer's elevation above ground level (not sea level) in meters.
What affects sunrise & sunset as defined here.
Time zone HA location parameters The location's time zone (including Daylight Saving Time (DST).
(See the "TZ database name" column at http://en.wikipedia.org/wiki/List_of_tz_database_time_zones.)
Season What affects sunrise & sunset.
Additional info: NOAA Solar Calculator
Midnight Midnight local time.
Start of new optimization cycle.
Daylight The amount of time between sunrise and sunset (in hours).
Sunrise today The time in the morning when the sun is 0.833 degrees below the horizon.
This is to account for refraction.
PV excess start time today 15% The time at 15% rising offset.
= sunrise + daylight * 0.15
Start of Batteries charging under normal conditions.
Solar noon today The time when the sun is at its highest point.
Prediction end time today 20% The time at 20% setting offset.
= sunset - daylight * 0.20
Batteries SOC target: 100%
PV excess end time today 15% The time at 15% setting offset.
= sunset - daylight * 0.15
Start of Batteries discharging under normal conditions.
Sunset today The time in the evening when the sun is 0.833 degrees below the horizon.
This is to account for refraction.
Prediction end time tomorrow 20% The time at 20% setting offset.
= sunset - daylight * 0.20
End of actual optimization cycle.
Batteries SOC target: 100%
huawei_solar_hems_dashboard_2

sensor.emhass_prediction_horizon: [96 - 1]

state: 43
prediction_end_time_today: 2024-10-31 15:10:44.841695+01:00
prediction_end_time_tomorrow: 2024-11-01 15:09:39.014056+01:00
prediction_time_step: 30

Dependencies

Hourly EPEXSpot electricity price forecasts for the next day are normally availiable every day after ~13:00 CET.

To enable an extended optimization cycle, the current day's EPEXSpot forecasts will also be used for the next day until the next day's data is officially provided. At first glance, this approach looks risky, but in reality, this quick and dirty workaround works well.

Solcast integration produce three solar PV generation estimates, broken down by 30 minute and hourly invervals across the day, available for seven days:

  • central or 50% or most likely to occur PV forecast (or the forecast)
  • 10% or 1 in 10 'worst case' PV forecast assuming more cloud coverage (forecast10)
  • 90% or 1 in 10 'best case' PV forecast assuming less cloud coverage (forecast90)

Definition of the main data entering EMHASS Add-on:

  • Use sensor.inverter_input_power (Huawei Solar Integration) as the photovoltaic produced power sensor (sensor_power_photovoltaics).
    Note: 7 days of historical data must be available within HA!
  • Use sensor.house_consumption_power (Huawei Solar HEMS) as the household power consumption sensor without any substraction of deferrable loads (sensor_power_load_no_var_loads).
    Note: 7 days of historical data must be available within HA!
  • Use sensor.batteries_state_of_capacity (Huawei Solar Integration) as the sensor for the current Battieries SOC used by the optimization plan.
  • Use sensor.epex_spot_data_net_price (EPEXSpot integration) as the sensor for the current EPEXSpot price used by the optimization plan.
  • Use sensor.emhass_forecast_data (Huawei Solar HEMS) as the sensor for pv_power_forecast (attribute='p_pv_forecast') and load_cost_forecast (attribute='epexspot_price_eur_per_kwh') used by the optimization plan.
  • Use sensor.emhass_prediction_horizon (Huawei Solar HEMS) to calculate all required input for the decreasing prediction horizon used by the optimization plan.

Setup

Automation

automation:
  alias: EMHASS - naive mpc optim forecast
  description: EMHASS - naive mpc optimization - upto 48 hours forecast.
  trigger:
    - platform: time_pattern
      minutes: /1
      enabled: true
  action:
    - metadata: {}
      data: {}
      enabled: true
      continue_on_error: false
      response_variable: rest_response
      action: rest_command.emhass_naive_mpc_optim_forecast
    - if:
        - condition: template
          value_template: "{{ rest_response['status'] < 400  }}"
      then:
        - data:
            prefix: all
          enabled: true
          continue_on_error: true
          response_variable: rest_response
          action: rest_command.emhass_publish_data
      else:
        - metadata: {}
          data:
            level: warning
            message: "{{ rest_response['content'] }}"
            logger: EMHASS.MINUTE
          action: system_log.write
  mode: single
rest_command:
  emhass_naive_mpc_optim_forecast:
    url: http://localhost:5000/action/naive-mpc-optim
    method: POST
    content_type: "application/json"
    timeout: 30
    payload: >-
      {% set prediction_horizon = states('sensor.emhass_prediction_horizon')|int(0) %}
      {
        "pv_power_forecast": {{
          ([states('sensor.inverter_input_power')|float(0)] +
          (state_attr('sensor.emhass_forecast_data', 'data')|map(attribute='p_pv_forecast')|list)[1:-1]
          )|tojson
        }},
        "load_cost_forecast": {{
          ([states('sensor.epex_spot_data_net_price')|float(0)|round(2)/100] +
          (state_attr('sensor.emhass_forecast_data', 'data')|map(attribute='epexspot_price_eur_per_kwh')|list)[1:-1] 
          )|tojson 
        }},
        "prediction_horizon": {{prediction_horizon}},
        "soc_init": {{states('sensor.batteries_state_of_capacity')|float(0)/100}},
        "soc_final": 1.0,
        "def_total_hours": [0,0],
        "alpha": 1,
        "beta": 0,
        "continual_publish":false
      }

Logs

Accessible under:

  • Settings -> Add-ons -> EMHASS -> Log
  • Settings -> System -> Logs -> EMHASS
2024-09-18 11:29:00,087 - web_server - INFO - Passed runtime parameters: {'pv_power_forecast': [1733.0, 1731, 3689, 5519, 5712, 5341, 4897, 4351, 3747, 3057, 2269, 1477, 762, 349, 275, 185, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 297, 1159, 2020, 2741, 3394, 4036, 4662, 5276, 5742, 5905, 5921, 5676, 5321, 4848, 4327, 3678, 2988, 2209, 1451, 778, 396, 295, 186, 76, 0, 0, 0, 0, 0, 0, 0, 0], 'load_cost_forecast': [0.26539999999999997, 0.26544, 0.20614, 0.20614, 0.19961, 0.19961, 0.1995, 0.1995, 0.20085, 0.20085, 0.24727, 0.24727, 0.30376, 0.30376, 0.33516, 0.33516, 0.35422, 0.35422, 0.32837, 0.32837, 0.31058, 0.31058, 0.30662, 0.30662, 0.2942, 0.2942, 0.30095, 0.30095, 0.29593, 0.29593, 0.29923, 0.29923, 0.29918, 0.29918, 0.2978, 0.2978, 0.30662, 0.30662, 0.32467, 0.32467, 0.3685, 0.3685, 0.35796, 0.35796, 0.32151, 0.32151, 0.29362, 0.29362, 0.26544, 0.26544, 0.20614, 0.20614, 0.19961, 0.19961, 0.1995, 0.1995, 0.20085, 0.20085, 0.24727, 0.24727, 0.30376, 0.30376, 0.33516, 0.33516, 0.35422, 0.35422, 0.32837, 0.32837, 0.31058, 0.31058, 0.30662, 0.30662, 0.2942], 'prediction_horizon': 59, 'soc_init': 0.35, 'soc_final': 1.0, 'def_total_hours': [0, 0], 'alpha': 1, 'beta': 0, 'continual_publish': False}
2024-09-18 11:29:00,087 - web_server - INFO -  >> Setting input data dict
2024-09-18 11:29:00,087 - web_server - INFO - Setting up needed data
2024-09-18 11:29:00,089 - web_server - INFO - Retrieve hass get data method initiated...
2024-09-18 11:29:05,927 - web_server - INFO - Retrieving weather forecast data using method = list
2024-09-18 11:29:05,927 - web_server - INFO - Retrieving data from hass for load forecast using method = mlforecaster
2024-09-18 11:29:05,928 - web_server - INFO - Retrieve hass get data method initiated...
2024-09-18 11:29:17,467 - web_server - INFO -  >> Performing naive MPC optimization...
2024-09-18 11:29:17,467 - web_server - INFO - Performing naive MPC optimization
2024-09-18 11:29:17,471 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-09-18 11:29:17,582 - web_server - INFO - Status: Optimal
2024-09-18 11:29:17,582 - web_server - INFO - Total value of the Cost function = 2.05
2024-09-18 11:29:17,709 - web_server - INFO - Passed runtime parameters: {}
2024-09-18 11:29:17,709 - web_server - INFO -  >> Setting input data dict
2024-09-18 11:29:17,709 - web_server - INFO - Setting up needed data
2024-09-18 11:29:17,710 - web_server - INFO -  >> Publishing data...
2024-09-18 11:29:17,710 - web_server - INFO - Publishing data to HASS instance
2024-09-18 11:29:17,718 - web_server - INFO - Successfully posted to sensor.p_pv_forecast = 1733.0
2024-09-18 11:29:17,724 - web_server - INFO - Successfully posted to sensor.p_load_forecast = 899.31
2024-09-18 11:29:17,728 - web_server - INFO - Successfully posted to sensor.p_pv_curtailment = 0.0
2024-09-18 11:29:17,734 - web_server - INFO - Successfully posted to sensor.p_hybrid_inverter = 899.31
2024-09-18 11:29:17,739 - web_server - INFO - Successfully posted to sensor.p_deferrable0 = 0.0
2024-09-18 11:29:17,744 - web_server - INFO - Successfully posted to sensor.p_batt_forecast = -833.69
2024-09-18 11:29:17,750 - web_server - INFO - Successfully posted to sensor.soc_batt_forecast = 37.5
2024-09-18 11:29:17,755 - web_server - INFO - Successfully posted to sensor.p_grid_forecast = 0.0
2024-09-18 11:29:17,760 - web_server - INFO - Successfully posted to sensor.total_cost_fun_value = 2.05
2024-09-18 11:29:17,764 - web_server - INFO - Successfully posted to sensor.optim_status = Optimal
2024-09-18 11:29:17,768 - web_server - INFO - Successfully posted to sensor.unit_load_cost = 0.2654
2024-09-18 11:29:17,773 - web_server - INFO - Successfully posted to sensor.unit_prod_price = 0.08

Configuration parameters

EMHASS

Below are the needed configuration parameters to correctly use the EMHASS-Add-on.
This add-on uses the EMHASS core module.

EMHASS configuration parameters are detailed in the EMHASS documentation.

YAML export of configuration parameters.

Home Assistant (HA) integration

Parameter Description Options Default Value
hass_url URL of your HA instance. empty empty
long_lived_token A Long-Lived Access Token that can be created from the Lovelace profile page. empty empty
data_path Set folder path where EMHASS data will be stored.
Selecting /data/ will store data in an enclosed folder, only assessable by the addon itself. Select /share/ to store data in the mounted share folder, accessible outside of the Addon.
default
/data/
/share/
default default
logging_level Set the logger level.
Change to WARNING or ERROR to reduce logging if needed.
DEBUG
INFO
WARNING
ERROR
INFO INFO
optimization_time_step The time step (in mins) to resample retrieved data from HA.
It should not be defined too low or you will run into memory problems when defining the Linear Programming optimization.
30 30
historic_days_to_retrieve We will retrieve data from now and up to 'historic_days_to_retrieve' days.
This will be used for the perfect-optim task.
2 7
delta_forecast_daily Number of days for forecasted data (1 day = 1). 1 2
method_ts_round Method for timestamp rounding. first
last
nearest
nearest first
lp_solver Name of the linear programming solver. PULP_CBC_CMD
GLPK_CMD
COIN_CMD
COIN_CMD COIN_CMD
lp_solver_path Path to the LP solver. /usr/bin/cbc /usr/bin/cbc
load_forecast_method Load forecast method.
Select 'mlforecaster' to use the machine learning forecaster.
naive
csv
list
mlforecaster
naive mlforecaster

Deferrable Load

Parameter Description Options Default Value
number_of_deferrable_loads Number of deferrable loads to consider. 2 1
nominal_power_of_deferrable_loads Nominal power for each deferrable load (in Watts).
Note: Number of items = Number_of_deferrable_loads
0
0
0
0
operating_hours_of_each_deferrable_load Total number of hours that each deferrable load should operate.
Note: Number of items = Number_of_deferrable_loads
0
0
0
0
start_timesteps_of_each_deferrable_load The timestep as from which each deferrable load is allowed to operate. Operation before this timestep is not allowed.
If value 0 is given, the deferrable load will be optimized as from the beginning of the complete prediction horizon window.
Note: Number of items = Number_of_deferrable_loads
0
0
0
0
end_timesteps_of_each_deferrable_load The timestep before which each deferrable load should operate. Operation after this timestep is not allowed.
If value 0 is given, the deferrable load optimization window will extend up to the end of the prediction horizon window.
Note: Number of items = Number_of_deferrable_loads
0
0
0
0
peak_hours_periods_start_hours Start hours of peak hours periods (in 24h HH:MM format).
Note: Number of items = Number_of_deferrable_loads
0
0
"05:54"
"17:54"
peak_hours_periods_end_hours End hours of peak hours periods (in 24h HH:MM format).
Note: Number of items = Number_of_deferrable_loads
0
0
"09:24"
"20:24"
treat_deferrable_load_as_semi_cont Define if we should treat each deferrable load as a semi-continuous variable. Semi-continuous variables are variables that can take either their nominal value or zero.
Note: Number of items = Number_of_deferrable_loads
true
false
true
true
true
true
set_deferrable_load_single_constant Set each deferrable load as a constant fixed value variable with just one startup for each optimization task (ex. each 24h)
Note: Number of items = Number_of_deferrable_loads
true
false
false
false
false
false
set_deferrable_startup_penalty Add a penalty P (Power) each time the deferrable load turns on.
The deferrable load turns on will incur an additional cost of P * list_nominal_power_of_deferrable_loads * cost_of_electricity at that time.
Note: Number of items = Number_of_deferrable_loads
0
0
0
0

Electricity spot price forecast

Parameter Description Options Default Value Entity Setting
load_cost_forecast_method Define the method that will be used for load cost forecast.
The options are 'hp_hc_periods' for peak and non-peak hours contracts and 'csv' to load custom cost from CSV file.
hp_hc_periods
csv
hp_hc_periods hp_hc_periods sensor.emhass_forecast_data attribute='price_eur_per_kwh'
production_price_forecast_method Define the method that will be used for PV power production price forecast. This is the price that is payed by the utility for energy injected to the grid.
The options are 'constant' for constant fixed value or 'csv' to load custom price forecast from a CSV file.
constant
csv
constant constant
load_peak_hours_cost The cost of the electrical energy from the grid during peak hours (in €/kWh). 0.1907 0.36
load_offpeak_hours_cost The cost of the electrical energy from the grid during non-peak hours (in €/kWh). 0.1419 0.28
photovoltaic_production_sell_price The paid price for energy injected to the grid from excedent PV production (in €/kWh). 0.065 0.08

PV power production forecast

Although Huawei Solar HEMS uses the HA Solcast integration for PV power production forecasts, all parameters below must be properly configured because for some modeling task EMHASS relies on the PVLib Python package.

EMHASS PV lib database - dedicated web app is useful for finding your inverter and solar panel models used by the PVLib module.

More info at:

Attention: The knowledge about below technical parameters is crusial for reliable forcasting whatever tool or service you will use!

Parameter Description Options Default Value Entity Setting
weather_forecast_method Weather forecast method. scrapper (ClearOutside)
Solcast
solar.forecast
csv
scrapper scrapper sensor.emhass_forecast_data attribute='p_pv_forecast'
pv_module_model PV module model.
Note: This parameter can be a list of strings to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
Trina_Solar_TSM_390DE09_05
pv_inverter_model PV inverter model.
Note: This parameter can be a list of strings to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
SolaX_Power_Network_Technology__
Zhe_jiang__Co___Ltd___A1_Hybrid_7_0_US__240V_
surface_tilt Tilt angle of your solar panels.
Note: This parameter can be a list of integers to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
[0 - 90] 30 45
surface_azimuth Azimuth of your PV installation.
Note: This parameter can be a list of integers to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
[0 - 360] 205 139
modules_per_string Number of modules per string.
Note: This parameter can be a list of integers to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
16 10
strings_per_inverter Number of used strings per inverter.
Note: This parameter can be a list of integers to enable the simulation of mixed orientation systems, for example one east-facing array (azimuth=90) and one west-facing array (azimuth=270).
1 2

Huawei Smart Energy Controller

Parameter Description Options Default Value Entity Setting
sensor_power_photovoltaics Name of the photovoltaic produced power sensor from Home Assistant (in Watts). sensor.inverter_input_power sensor.inverter_input_power
sensor_power_load_no_var_loads Name of the household power consumption sensor from Home Assistant (in Watts).
The deferrable loads that we will want to include in the optimization problem should be substracted from this sensor in HASS.
sensor.house_consumption_power sensor.house_consumption_power
load_negative If the retrived load variable is negative by convention true
false
false false sensor.house_consumption_power
set_zero_min To give a special treatment for a minimum value saturation to zero for power consumption data.
Values below zero are replaced by nans.
true
false
true true sensor.house_consumption_power
maximum_power_from_grid The maximum power that can be supplied by the utility grid (consumption in Watts). 9000 9000
maximum_power_to_grid The maximum power that can be supplied to the utility grid (injection in Watts). 9000 6600 sensor.inverter_power
inverter_is_hybrid Set to True to consider that the inverter is hybrid for PV and batteries.
A special parameter to consider that the inverter is hybrid for PV and batteries.
true
false
false true
compute_curtailment Set to True to compute a PV curtailment variable.
A special parameter to define if we will compute a PV curtailment variable.
true
false
false true

Huawei Smart String ESS

Parameter Description Options Default Value Entity Setting
set_use_battery Battery is present.
Set to True if we should consider an energy storage device such as a Li-Ion battery.
true
false
false true
costfun Type of cost function (optional). profit
cost
self-consumption
profit self-consumption select.batteries_working_mode Maximise self consumption
set_total_pv_sell Set this parameter to true to consider that all the PV power produced is injected to the grid (No direct self-consumption).
The default is false, for a system with direct self-consumption.
true
false
false false select.batteries_working_mode Maximise self consumption
set_nocharge_from_grid Set this to true if you want to forbidden to charge the battery from the grid. The battery will only be charged from excess PV. true
false
false false switch.batteries_charge_from_grid on/off
by HA automation
set_nodischarge_to_grid Set this to true if you want to forbidden to discharge the battery power to the grid. true
false
false true select.batteries_excess_pv_energy_use_in_tou Charge
set_battery_dynamic Set a power dynamic limiting condition to the battery power.
This is an additional constraint on the battery dynamic in power per unit of time.
true
false
false false
battery_dynamic_max The maximum positive battery power dynamic.
This is the power variation in percentage of battery maximum power.
0.9 1
battery_dynamic_min The minimum negative battery power dynamic.
This is the power variation in percentage of battery maximum power.
-0.9 -1
weight_battery_discharge An additional weight applied in cost function to battery usage for discharge (currency/kWh). 0.0 0.0
weight_battery_charge An additional weight applied in cost function to battery usage for charge (currency/kWh). 0.0 0.0
battery_discharge_power_max Maximum discharge power (in Watts). 1000 6600 sensor.batteries_maximum_discharge_power
battery_charge_power_max Maximum charge power (in Watts). 1000 7500 sensor.batteries_maximum_charge_power
battery_discharge_efficiency Discharge efficiency. 0.95 0.9 ???
battery_charge_efficiency Charge efficiency. 0.95 0.9 ???
battery_nominal_energy_capacity Total capacity of the battery stack (in Wh). 5000 15000 sensor.batteries_rated_capacity
battery_minimum_state_of_charge Minimum allowable battery state of charge. 0.3. 0.05 number.batteries_end_of_discharge_soc 5%
battery_maximum_state_of_charge Maximum allowable battery state of charge. 0.9. 1.0 number.batteries_end_of_charge_soc 100%
battery_target_state_of_charge Desired battery state of charge at the end of each optimization cycle. 0.6. 1.0 number.batteries_end_of_charge_soc 100%
⚠️ **GitHub.com Fallback** ⚠️