That was my understanding also
Do you run this as an separate rest command?
This how I did it, not sure if the second rest command is really necessary:
emhass_mpc_optim_30min_fi_fo_buffer_mpc_prefix_dynamic_deferrable_loads_state_weight_battery_thermal_load:
url: "http://localhost:5000/action/naive-mpc-optim"
method: POST
timeout: 15
content_type: "application/json"
payload: >-
{
"entity_save": "{{ entity_save }}",
"publish_prefix": "{{ publish_prefix }}",
"prediction_horizon": {{ prediction_horizon }},
"pv_power_forecast": {{ pv_power_forecast | tojson }},
"num_def_loads": {{ num_def_loads }},
"nominal_power_of_deferrable_loads": {{ nominal_power_of_deferrable_loads | tojson }},
"operating_hours_of_each_deferrable_load": {{ operating_hours_of_each_deferrable_load | tojson }},
"treat_deferrable_load_as_semi_cont": {{ treat_deferrable_load_as_semi_cont | tojson }},
"set_deferrable_load_single_constant": {{ set_deferrable_load_single_constant | tojson }},
"start_timesteps_of_each_deferrable_load": {{ start_timesteps_of_each_deferrable_load | tojson }},
"end_timesteps_of_each_deferrable_load": {{ end_timesteps_of_each_deferrable_load | tojson }},
"def_current_state": {{ def_current_state | tojson }},
"soc_init": {{ soc_init }},
"soc_final": {{ soc_final }},
"load_cost_forecast": {{ load_cost_forecast | tojson }},
"prod_price_forecast": {{ prod_price_forecast | tojson }},
"alpha": {{ alpha }},
"beta": {{ beta }},
"load_power_forecast": {{ load_power_forecast | tojson }},
"weight_battery_charge": {{ weight_battery_charge | tojson }},
"weight_battery_discharge": {{ weight_battery_discharge | tojson }},
"def_load_config": {{ def_load_config | tojson }},
"outdoor_temperature_forecast": {{ outdoor_temperature_forecast | tojson }}
}
emhass_publish_data_thermal_load:
url: http://localhost:5000/action/publish-data
method: POST
content_type: 'application/json'
payload: >-
{"publish_prefix": {{ '"' ~ publish_prefix ~ '"' }},
"def_load_config": {{ def_load_config | tojson }}
}
Here is my full rest command and payload script, there is a lot here to unpack:
My 7 loads are as follows:
load0 is pool filter pump (440 W)
load1 is pool heat pump (5 kW) - thermal load (heating)
load2 is EV1 charger (11 kW) variable
load3 is HVAC (11 kW) - thermal load (cooling)
load4 is Hot Water Heat Pump (600 W) - thermal load (heating)
load5 is EV2 charger (11 kW) variable
load6 is heater (660W) - fixed
sequence:
- action: rest_command.mpc_servicecall_rest
metadata: {}
data:
payload: |
{{ payload}}
enabled: true
- action: rest_command.publish_data_rest
enabled: true
data: {}
alias: EMHASS Payload Script (Thermal)
variables:
payload: |-
{
{% set count = state_attr('sensor.amber_30min_forecasts_feed_in_price','Forecasts')| selectattr('advanced_price_predicted','is_number') |list|count -%}
{% set countML = state_attr('sensor.price_forecast_custom_model','scheduled_forecast')|list|count -%}
{% set horizon = min(146,countML) -%}
"prediction_horizon": {{horizon}},
"prod_price_forecast": {{
(
[states('sensor.amber_5min_current_feed_in_price')|float(0)]
+ (state_attr('sensor.amber_30min_forecasts_feed_in_price','Forecasts')
| selectattr('advanced_price_predicted','is_number')
| map(attribute='advanced_price_predicted')
| map('multiply', -1)
|list)
+ (state_attr('sensor.price_forecast_custom_model','scheduled_forecast')
| map(attribute='price_forecast_custom_model')
| map('float')|list)[count+1:]
)
}},
"load_cost_forecast": {{
([states('sensor.amber_5min_current_general_price')|float(0)]
+ (state_attr('sensor.amber_30min_forecasts_general_price','Forecasts')
| selectattr('advanced_price_predicted','is_number')
| map(attribute='advanced_price_predicted')
|list)
+ (state_attr('sensor.cost_forecast_custom_model','scheduled_forecast')
| map(attribute='cost_forecast_custom_model')
| map('float')|list)[count+1:]
)
}},
"def_load_config": [{},
{
{%- if is_state('automation.p_deferable1_automation','on') -%}
"thermal_config":
{ "heating_rate": 2.0,
"sense": "heat",
"cooling_constant": 0.007,
"overshoot_temperature": 33.0,
"start_temperature": {{states('sensor.ibs_th2_p01b_08ae_temperature')|float(0)}},
{%- set set = states('sensor.emhass_sun_next_setting_timesteps')|int -%}
{%- set total_blocks = horizon -%}
{%- set max_heating_blocks = 6 -%}
{# Calculate if heating is possible today #}
{%- set heating_today = max(0, min(max_heating_blocks, set - 6)) -%}
{%- set first_start = set - 9 -%}
{# For second day, always schedule 6 blocks #}
{%- set heating_tomorrow = max_heating_blocks -%}
{%- set second_start = first_start + 48 -%}
{# Calculate fill blocks #}
{%- set before_first = max(0, first_start) -%}
{%- set between = max(0, second_start - (first_start + heating_today)) -%}
{%- set remaining = max(0, total_blocks - (second_start + heating_tomorrow)) -%}
{%- set temps =
[20]*before_first +
[30]*heating_today +
[24]*between +
[30]*heating_tomorrow +
[24]*remaining +
[30]*heating_tomorrow +
[24]*remaining
-%}
"desired_temperatures": {{ (temps)[:horizon] }}
}
{%- endif -%}
},
{},
{
{%- if is_state('automation.p_deferrable3_hvac_v2','on') -%}
"thermal_config":
{ "heating_rate": -3.0,
"sense": "cool",
"cooling_constant": 0.2,
"overshoot_temperature": 20.0,
"start_temperature": {{states('sensor.tewantin_temp')|float(0)}},
"desired_temperatures": {{[states('input_number.emhass_deferrable3_set_point')|int(0)]*horizon}}
}
{%- endif -%}
},
{
"thermal_config":
{ "heating_rate": 6.0,
"sense": "heat",
"cooling_constant": 0.007,
"overshoot_temperature": 65.0,
"start_temperature": {{states('sensor.hws_power_based_sensor')|float(0)}},
{%- set set = states('sensor.emhass_sun_next_setting_timesteps')|int -%}
{%- set total_blocks = horizon -%}
{%- set max_heating_blocks = 10 -%}
{# Calculate if heating is possible today #}
{%- set heating_today = max(0, min(max_heating_blocks, set - 10)) -%}
{%- set first_start = set - 12 -%}
{# For second day, always schedule 6 blocks #}
{%- set heating_tomorrow = max_heating_blocks -%}
{%- set second_start = first_start + 48 -%}
{# Calculate fill blocks #}
{%- set before_first = max(0, first_start) -%}
{%- set between = max(0, second_start - (first_start + heating_today)) -%}
{%- set remaining = max(0, total_blocks - (second_start + heating_tomorrow)) -%}
{%- set temps =
[50]*before_first +
[60]*heating_today +
[50]*between +
[60]*heating_tomorrow +
[50]*remaining +
[60]*heating_tomorrow +
[50]*remaining
-%}
"desired_temperatures": {{ (temps)[:horizon] }}
}
},
{},
{}],
"outdoor_temperature_forecast": {{state_attr('sensor.outdoor_temperature_forecast','forecasts')[:horizon]}},
"alpha": 0,
"beta": 1,
"num_def_loads": 7,
"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),
40]}},
"def_current_state": {{[
iif(states('sensor.p_deferrable0')|int(0),1,0),
iif(states('sensor.p_deferrable1')|int(0),1,0),
iif(states('sensor.p_deferrable2')|int(0),1,0),
iif(states('sensor.p_deferrable3')|int(0),1,0),
iif(states('sensor.p_deferrable4')|int(0),1,0),
iif(states('sensor.p_deferrable5')|int(0),1,0),
iif(states('sensor.p_deferrable6')|int(0),1,0)
]}},
"def_start_timestep": {{
[0,
0,
max(0,states('sensor.emhass_deferrable2_start_timesteps')|int(0)),
0,
0,
max(0,states('sensor.emhass_deferrable5_start_timesteps')|int(0)),
0]
}},
"def_end_timestep": {{
[0,
0,
max(0,states('sensor.emhass_deferrable2_end_timeslots')|int(0)),
0,
0,
max(0,states('sensor.emhass_p_deferable_5_end_timeslots')|int(0)),
0]
}},
"P_deferrable_nom": [440,
5500,
{{ states('sensor.p_nom_ev')}},
{{ states('input_number.p_nom_hvac')}},
600,
{{ states('sensor.p_nom_ev2')}},
660],
"treat_def_as_semi_cont": [1, 1, 0, 0, 1, 0, 1],
"set_def_constant": [0, 0, 0, 0, 0, 0, 0],
"def_start_penalty": [1, 0, 1, 1, 1, 1, 0],
"weight_battery_charge": {{states('input_number.weight_battery_charge')}},
"weight_battery_discharge": {{states('input_number.weight_battery_discharge')}},
"battery_nominal_energy_capacity": {{ states('input_number.battery_nominal_energy_capacity')|int(0)*1000 }},
"battery_discharge_power_max": {{ states('input_number.battery_discharge_power_max')|int(0)*1000}},
"soc_final": {{states('input_number.soc_final')|int(0)/100}},
"weather_forecast_cache_only": true,
"optimization_time_step": 30,
"set_nodischarge_to_grid": 0,
"soc_init":
{% set primary = states('sensor.gateway_teslemetry_percentage_charged') %}
{% set fallback = states('sensor.powerwall_charge') %}
{% if primary not in ['unavailable', 'unknown'] %}
{{ (primary | float/100) | round(2) }}
{% elif fallback not in ['unavailable', 'unknown'] %}
{{ (fallback | float /100) | round (2)}}
{% else %}
0
{% endif %}
}
mode: single
description: ""
Hi there, I am pretty new to Home Assistant and EMHASS as well. I have been using a commercial EMS for some years (energybase here in Germany) which is no longer supported.
I decided to give EMHASS a try and it looks very promising.
For now I am just trying to push the battery load to PV peak hours.
Iâve set up a defferabl load with 0 hours and configured battery as well as a inverter close to mine.
So inverter AC limit is 10KW, battery charge/discharg is around 10KW, battery capacity is 7.7KWh. Battery should be a 5% SOC at end of the forecast window (using day-ahead).
I configured the battery load as 7700 Wh in EMHASS.
Running the optimization gives me this:
Looks like the battery capacity is wrong.
Setting it to 77000Wh in EMHASS it looks more reasonable.
Am I doing something wrong?
I was thinking here, isnât it possible to attach a temperature sensor to your DHW outlet from the waterpumpboiler? Or maybe your approach is good enough already.
I would check if all P parameters are in W and Wh and take it from there.
Thanks, this is my config:
"adjusted_pv_regression_model": "LassoRegression",
"adjusted_pv_solar_elevation_threshold": 10,
"battery_charge_efficiency": 0.98,
"battery_charge_power_max": 10000,
"battery_discharge_efficiency": 0.98,
"battery_discharge_power_max": 10000,
"battery_dynamic_max": 0.9,
"battery_dynamic_min": -0.9,
"battery_maximum_state_of_charge": 0.1,
"battery_minimum_state_of_charge": 0,
"battery_nominal_energy_capacity": 7700,
"battery_target_state_of_charge": 0.05,
"compute_curtailment": false,
"continual_publish": false,
"costfun": "self-consumption",
"delta_forecast_daily": 1,
"end_timesteps_of_each_deferrable_load": [
0
Should be fine I guess.
Checking the optimization forecast re battery discharge, I am getting this:
|index|P_PV|P_Load|P_deferrable0|P_grid_pos|P_grid_neg|P_grid|P_batt|SOC_opt|
|2025-06-05 22:30:00+02:00|0|196|0|0|0|0|196|0.087|
|2025-06-06 02:00:00+02:00|0|281|0|0|0|0|281|0.068|
|2025-06-06 04:30:00+02:00|0|342|0|0|0|0|342|0.046|
|2025-06-06 05:30:00+02:00|0|366|0|0|0|0|366|0.021|
|2025-06-06 06:30:00+02:00|86|390|0|0|0|0|304|0.001|
So from 100 to 1% it is around 700Wh only.
And charging from 72% to 100%
index P_PV P_Load P_deferrable0 P_grid_pos P_grid_neg P_grid P_batt SOC_opt
2025-06-05 18:30:00+02:00 786 327 0 0 -113 -113 -346 0.072
2025-06-05 19:00:00+02:00 760 321 0 0 0 0 -439 0.100
Thatâs around 200Wh.
Edit, uhm. Problem between screen and chair.
Maximum should be 1 and not 0.1 :-(
Problem solved
Good to hear.
But what about the internal control of your DHW heat pump? You leave the setpoint always at 50 degrees celsius, so no time program.
I am currently working towards this, my shelly relay (which provides the SG ready signal) also has an input for a temperature sensor, so I will attach that to the hot water supply at the top which will enable the optimisation to be more accurate.
Unfortunately my DHW system doesnât have a timer program.
The set point is 50 deg C normally and 65 deg C when the dry contact (SG ready) signal is set.
Hi Mark,
I am working on the Hot water heat pump.
Looking at you setup, start and end timesteps for your def_4 are both 0. EMHASS looks whatâs the best window for closing the PV contact on your hot water pump. I tried the same with these results (with 10 heating blocks)
Next I tried set start and end timestep to match the 60 degrees desired temp with these results:
Isnât this what you are after? I am trying to understand whatâs the best way to implement this. For the last optimization I had to lower the heating_rate from 6 to 5, but I donât know the real value I need. I donât have the hot waterpump yet. Just simulating and understanding the way the model works.
Can you explain a little more why you choose option 1?
Is you switch on debug you will see which loads are characterised as thermal or non-thermal loads.
I try not to constrain the solution with start/ end timesteps and just allow the optimization based on thermal performance.
In your example 1, the water heater switches on âearlyâ for two reasons:
- At the start it is below the desired 50 deg C, so it needs to start heating immediately. (13:00-)
- It is also attempting to get to the desired temp of 60 Dec C by 16:00, so it needs to run flat out and doesnât quite get there.
You can also see it switches off early 18:30 as it has achieved the setpoint > 60 deg C.
In your example 2 your timestep constraints have it not achieving the 50 deg setpoint specified before 15:30 and it doesnât achieve the required pre-heat to achieve 60 deg C specified for 15:30.
Got it! That makes sense.
A pratical question, for normal deferrable loads I use a countdown timer for the operating hours which decreases every hour by 1 until the def has finished. I feed the declining values to the runtime in my rolling window setup.
For the thermal load this doesnât work, but I think itâs working automatically when temp increases. If at some timestep the desired temp is reached the def is reduced, but for the second start before the evening it is added as we defined 10 heating blocks. Hope I am correct. Or is there something else what I should do?
Hello,
I have EMHASS: v0.13.3 add-on
iâm trying to change Solar System (PV)
I have enphase solar system.1 micro inverter per panel
I found this:
and put it in te config.
But get this error
> Traceback (most recent call last):
> File "/app/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py", line 3805, in get_loc
> return self._engine.get_loc(casted_key)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc
> File "index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc
> File "pandas/_libs/hashtable_class_helper.pxi", line 7081, in pandas._libs.hashtable.PyObjectHashTable.get_item
> File "pandas/_libs/hashtable_class_helper.pxi", line 7089, in pandas._libs.hashtable.PyObjectHashTable.get_item
> KeyError: 'REC_Solar_REC365AA'
> The above exception was the direct cause of the following exception:
> Traceback (most recent call last):
> File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 1511, in wsgi_app
> response = self.full_dispatch_request()
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 919, in full_dispatch_request
> rv = self.handle_user_exception(e)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 917, in full_dispatch_request
> rv = self.dispatch_request()
> ^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/.venv/lib/python3.12/site-packages/flask/app.py", line 902, in dispatch_request
> return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/src/emhass/web_server.py", line 411, in action_call
> input_data_dict = set_input_data_dict(
> ^^^^^^^^^^^^^^^^^^^^
> File "/app/src/emhass/command_line.py", line 287, in set_input_data_dict
> P_PV_forecast = fcst.get_power_from_weather(df_weather)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/src/emhass/forecast.py", line 749, in get_power_from_weather
> module = cec_modules[self.plant_conf["pv_module_model"][i]]
> ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/.venv/lib/python3.12/site-packages/pandas/core/frame.py", line 4102, in __getitem__
> indexer = self.columns.get_loc(key)
> ^^^^^^^^^^^^^^^^^^^^^^^^^
> File "/app/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py", line 3812, in get_loc
> raise KeyError(key) from err
> KeyError: 'REC_Solar_REC365AA
What went wrong?
REC_Solar_REC365AA is in the PVLib database for EMHASS
I have enphase solar system.1micro inverter per panel
Number of strings per inverter is set to 1
Adding in the yaml file is working
+/- (green arrow is not working)
My yaml file
{
"optimization_time_step": 30,
"historic_days_to_retrieve": 2,
"sensor_power_photovoltaics": "sensor.envoy_122023077603_current_power_production",
"sensor_power_photovoltaics_forecast": "sensor.p_pv_forecast",
"sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
"load_negative": false,
"set_zero_min": true,
"sensor_replace_zero": [
"sensor.power_photovoltaics",
"sensor.p_pv_forecast"
],
"sensor_linear_interp": [
"sensor.power_photovoltaics",
"sensor.power_load_no_var_loads"
],
"method_ts_round": "nearest",
"continual_publish": false,
"costfun": "profit",
"logging_level": "INFO",
"set_use_pv": true,
"set_use_adjusted_pv": false,
"adjusted_pv_regression_model": "LassoRegression",
"adjusted_pv_solar_elevation_threshold": 10,
"set_use_battery": true,
"number_of_deferrable_loads": 2,
"nominal_power_of_deferrable_loads": [
3000,
750
],
"minimum_power_of_deferrable_loads": [
0,
0
],
"operating_hours_of_each_deferrable_load": [
4,
5
],
"treat_deferrable_load_as_semi_cont": [
true,
true
],
"set_deferrable_load_single_constant": [
false,
false
],
"set_deferrable_startup_penalty": [
0,
0
],
"delta_forecast_daily": 1,
"load_forecast_method": "naive",
"load_cost_forecast_method": "hp_hc_periods",
"load_peak_hours_cost": 0.1907,
"load_offpeak_hours_cost": 0.1419,
"production_price_forecast_method": "constant",
"photovoltaic_production_sell_price": 0.1419,
"set_total_pv_sell": false,
"lp_solver": "default",
"lp_solver_path": "empty",
"lp_solver_timeout": 45,
"num_threads": 0,
"set_nocharge_from_grid": false,
"set_nodischarge_to_grid": true,
"set_battery_dynamic": false,
"battery_dynamic_max": 0.9,
"battery_dynamic_min": -0.9,
"weight_battery_discharge": 0,
"weight_battery_charge": 0,
"weather_forecast_method": "open-meteo",
"open_meteo_cache_max_age": 30,
"start_timesteps_of_each_deferrable_load": [
0,
0
],
"end_timesteps_of_each_deferrable_load": [
0,
0
],
"load_peak_hour_periods": {
"period_hp_1": [
{
"start": "02:54"
},
{
"end": "15:24"
}
],
"period_hp_2": [
{
"start": "17:24"
},
{
"end": "20:24"
}
]
},
"maximum_power_from_grid": 9000,
"maximum_power_to_grid": 9000,
"pv_module_model": [
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M",
"CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M"
],
"pv_inverter_model": [
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_",
"Enphase_Energy_Inc___IQ7PLUS_72_2_US__240V_"
],
"surface_tilt": [
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15,
15
],
"surface_azimuth": [
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
220,
140,
140,
140,
140,
140,
140,
140,
140,
140,
140,
140,
140
],
"modules_per_string": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"strings_per_inverter": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
],
"inverter_is_hybrid": false,
"compute_curtailment": false,
"battery_discharge_power_max": 1000,
"battery_charge_power_max": 1000,
"battery_discharge_efficiency": 0.95,
"battery_charge_efficiency": 0.95,
"battery_nominal_energy_capacity": 5000,
"battery_minimum_state_of_charge": 0.3,
"battery_maximum_state_of_charge": 0.9,
"battery_target_state_of_charge": 0.6
}
Hi,
I want to use âoperating_timesteps_of_each_deferrable_loadâ to pass at runtime. I run 30 min optimization, 1h deferrable = 2 timesteps.
The Optimization runs âOptimalâ . Looking at the EMHASS graph I get this:
Is this a bug?
[2025-06-15 13:45:02 +0200] [21] [INFO] >> Obtaining params:
[2025-06-15 13:45:02 +0200] [21] [INFO] Passed runtime parameters: {'entity_save': 'True', 'publish_prefix': 'mpc_', 'prediction_horizon': 48, 'pv_power_forecast': [3883, 2094, 2024, 1922, 1807, 1664, 1490, 1315, 1179, 1072, 943, 794, 629, 430, 234, 90, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 77, 207, 403, 656, 983, 1432, 1992, 2636, 3253, 3679, 3931, 4011, 3979, 3870, 3435, 2751, 2334, 2246, 2251, 2253, 2197, 2032, 1782, 1468, 1175, 912, 708, 556, 389, 215, 84, 21, 0, 0, 0, 0], 'num_def_loads': 3, 'nominal_power_of_deferrable_loads': [0, 2000, 0], 'operating_timesteps_of_each_deferrable_load': [0, 1, 0], 'treat_deferrable_load_as_semi_cont': [False, False, False], 'set_deferrable_load_single_constant': [True, True, True], 'start_timesteps_of_each_deferrable_load': [-8, -8, 6], 'end_timesteps_of_each_deferrable_load': [12, 14, 14], 'def_current_state': [False, True, False], 'soc_init': 0.6, 'soc_final': 0.23, 'load_cost_forecast': [0.1451, 0.1458, 0.1458, 0.1489, 0.1489, 0.1511, 0.1511, 0.1914, 0.1914, 0.2374, 0.2374, 0.2546, 0.2546, 0.281, 0.281, 0.2965, 0.2965, 0.2931, 0.2931, 0.2676, 0.2676, 0.2959, 0.2959, 0.2677, 0.2677, 0.2519, 0.2519, 0.2421, 0.2421, 0.2363, 0.2363, 0.2537, 0.2537, 0.2702, 0.2702, 0.282, 0.282, 0.292, 0.292, 0.2691, 0.2691, 0.2096, 0.2096, 0.1666, 0.1666, 0.1548, 0.1548, 0.1535], 'prod_price_forecast': [-0.0147, -0.014, -0.014, -0.0111, -0.0111, -0.0091, -0.0091, 0.029, 0.029, 0.0724, 0.0724, 0.0886, 0.0886, 0.1135, 0.1135, 0.1282, 0.1282, 0.125, 0.125, 0.1008, 0.1008, 0.1276, 0.1276, 0.1009, 0.1009, 0.0861, 0.0861, 0.0769, 0.0769, 0.0714, 0.0714, 0.0878, 0.0878, 0.1034, 0.1034, 0.1144, 0.1144, 0.1239, 0.1239, 0.1023, 0.1023, 0.0462, 0.0462, 0.0056, 0.0056, -0.0055, -0.0055, -0.0067], 'alpha': 0.5, 'beta': 0.466, 'load_power_forecast': [555, 700, 800, 800, 600, 200, 600, 500, 500, 3200, 1300, 1000, 700, 800, 700, 900, 500, 400, 300, 400, 400, 300, 600, 500, 500, 400, 500, 0, 600, 700, 300, 600, 500, 500, 600, 500, 600, 200, 400, 400, 200, 400, 300, 400, 200, 800, 1000, 700], 'weight_battery_charge': 0.041, 'weight_battery_discharge': 0.009}
[2025-06-15 13:45:02 +0200] [21] [INFO] >> Setting input data dict
[2025-06-15 13:45:02 +0200] [21] [INFO] Setting up needed data
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Initialized Optimization with retrieve_hass_conf: {'optimization_time_step': Timedelta('0 days 00:30:00'), 'historic_days_to_retrieve': 10, 'sensor_power_photovoltaics': 'sensor.inverter_ingangsvermogen', 'sensor_power_photovoltaics_forecast': 'sensor.p_pv_forecast', 'sensor_power_load_no_var_loads': 'sensor.power_load_no_var_loads', 'load_negative': False, 'set_zero_min': True, 'sensor_replace_zero': ['sensor.inverter_ingangsvermogen'], 'sensor_linear_interp': ['sensor.inverter_ingangsvermogen', 'sensor.power_load_no_var_loads'], 'method_ts_round': 'first', 'continual_publish': False, 'hass_url': 'http://supervisor/core/api', 'long_lived_token': '4a653cd73437817aa25835895766b233a4f4fb77ce6eaa1ea5ad42337de7bfd955616ee0c9c95b4e2829ff13d5b6cefe51f1801618726893', 'time_zone': <DstTzInfo 'Europe/Brussels' LMT+0:18:00 STD>, 'Latitude': 50.789456233171535, 'Longitude': 5.592577457427979, 'Altitude': 110}
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Optimization configuration: {'costfun': 'self-consumption', 'logging_level': 'INFO', 'set_use_pv': True, 'set_use_adjusted_pv': False, 'adjusted_pv_regression_model': 'LassoRegression', 'adjusted_pv_solar_elevation_threshold': 10, 'set_use_battery': True, 'number_of_deferrable_loads': 3, 'nominal_power_of_deferrable_loads': [0, 2000, 0], 'minimum_power_of_deferrable_loads': [0, 0, 0, 0], 'operating_hours_of_each_deferrable_load': [2, 2, 2, 2], 'treat_deferrable_load_as_semi_cont': [False, False, False], 'set_deferrable_load_single_constant': [True, True, True], 'set_deferrable_startup_penalty': [3, 5, 5, 0], 'delta_forecast_daily': Timedelta('1 days 00:00:00'), 'load_forecast_method': 'list', 'load_cost_forecast_method': 'list', 'load_peak_hours_cost': 0.1907, 'load_offpeak_hours_cost': 0.1419, 'production_price_forecast_method': 'list', 'photovoltaic_production_sell_price': 0.065, 'set_total_pv_sell': False, 'lp_solver': 'COIN_CMD', 'lp_solver_path': '/usr/bin/cbc', 'lp_solver_timeout': 45, 'num_threads': 0, 'set_nocharge_from_grid': False, 'set_nodischarge_to_grid': False, 'set_battery_dynamic': True, 'battery_dynamic_max': 0.85, 'battery_dynamic_min': -0.5, 'weight_battery_discharge': 0.009, 'weight_battery_charge': 0.041, 'weather_forecast_method': 'list', 'open_meteo_cache_max_age': 30, 'start_timesteps_of_each_deferrable_load': [-8, -8, 6], 'end_timesteps_of_each_deferrable_load': [12, 14, 14], 'load_peak_hour_periods': {'period_hp_1': [{'start': '08:00'}, {'end': '17:00'}], 'period_hp_2': [{'start': '08:00'}, {'end': '17:00'}]}, 'operating_timesteps_of_each_deferrable_load': [0, 1, 0], 'def_current_state': [False, True, False]}
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Plant configuration: {'maximum_power_from_grid': 4000, 'maximum_power_to_grid': 6000, 'pv_module_model': ['JA_Solar_JAM72S01_385_PR', 'JA_Solar_JAM72S01_385_PR', 'JA_Solar_JAM72S01_385_PR'], 'pv_inverter_model': ['Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_', 'Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_', 'Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_'], 'surface_tilt': [35, 35, 15], 'surface_azimuth': [90, 270, 180], 'modules_per_string': [6, 6, 13], 'strings_per_inverter': [1, 1, 1], 'inverter_is_hybrid': True, 'compute_curtailment': True, 'battery_discharge_power_max': 5000, 'battery_charge_power_max': 5000, 'battery_discharge_efficiency': 1, 'battery_charge_efficiency': 0.95, 'battery_nominal_energy_capacity': 15000, 'battery_minimum_state_of_charge': 0.12, 'battery_maximum_state_of_charge': 1, 'battery_target_state_of_charge': 0.12}
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Solver configuration: lp_solver=COIN_CMD, lp_solver_path=/usr/bin/cbc
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Number of threads: 2
[2025-06-15 13:45:02 +0200] [21] [INFO] Retrieving weather forecast data using method = list
[2025-06-15 13:45:02 +0200] [21] [DEBUG] get_weather_forecast returning:
yhat
ts
2025-06-15 13:30:00+02:00 3883
2025-06-15 14:00:00+02:00 2094
2025-06-15 14:30:00+02:00 2024
2025-06-15 15:00:00+02:00 1922
2025-06-15 15:30:00+02:00 1807
2025-06-15 16:00:00+02:00 1664
2025-06-15 16:30:00+02:00 1490
2025-06-15 17:00:00+02:00 1315
2025-06-15 17:30:00+02:00 1179
2025-06-15 18:00:00+02:00 1072
2025-06-15 18:30:00+02:00 943
2025-06-15 19:00:00+02:00 794
2025-06-15 19:30:00+02:00 629
2025-06-15 20:00:00+02:00 430
2025-06-15 20:30:00+02:00 234
2025-06-15 21:00:00+02:00 90
2025-06-15 21:30:00+02:00 22
2025-06-15 22:00:00+02:00 0
2025-06-15 22:30:00+02:00 0
2025-06-15 23:00:00+02:00 0
2025-06-15 23:30:00+02:00 0
2025-06-16 00:00:00+02:00 0
2025-06-16 00:30:00+02:00 0
2025-06-16 01:00:00+02:00 0
2025-06-16 01:30:00+02:00 0
2025-06-16 02:00:00+02:00 0
2025-06-16 02:30:00+02:00 0
2025-06-16 03:00:00+02:00 0
2025-06-16 03:30:00+02:00 0
2025-06-16 04:00:00+02:00 0
2025-06-16 04:30:00+02:00 0
2025-06-16 05:00:00+02:00 0
2025-06-16 05:30:00+02:00 16
2025-06-16 06:00:00+02:00 77
2025-06-16 06:30:00+02:00 207
2025-06-16 07:00:00+02:00 403
2025-06-16 07:30:00+02:00 656
2025-06-16 08:00:00+02:00 983
2025-06-16 08:30:00+02:00 1432
2025-06-16 09:00:00+02:00 1992
2025-06-16 09:30:00+02:00 2636
2025-06-16 10:00:00+02:00 3253
2025-06-16 10:30:00+02:00 3679
2025-06-16 11:00:00+02:00 3931
2025-06-16 11:30:00+02:00 4011
2025-06-16 12:00:00+02:00 3979
2025-06-16 12:30:00+02:00 3870
2025-06-16 13:00:00+02:00 3435
[2025-06-15 13:45:02 +0200] [21] [DEBUG] get_power_from_weather returning:
ts
2025-06-15 13:30:00+02:00 3883
2025-06-15 14:00:00+02:00 2094
2025-06-15 14:30:00+02:00 2024
2025-06-15 15:00:00+02:00 1922
2025-06-15 15:30:00+02:00 1807
2025-06-15 16:00:00+02:00 1664
2025-06-15 16:30:00+02:00 1490
2025-06-15 17:00:00+02:00 1315
2025-06-15 17:30:00+02:00 1179
2025-06-15 18:00:00+02:00 1072
2025-06-15 18:30:00+02:00 943
2025-06-15 19:00:00+02:00 794
2025-06-15 19:30:00+02:00 629
2025-06-15 20:00:00+02:00 430
2025-06-15 20:30:00+02:00 234
2025-06-15 21:00:00+02:00 90
2025-06-15 21:30:00+02:00 22
2025-06-15 22:00:00+02:00 0
2025-06-15 22:30:00+02:00 0
2025-06-15 23:00:00+02:00 0
2025-06-15 23:30:00+02:00 0
2025-06-16 00:00:00+02:00 0
2025-06-16 00:30:00+02:00 0
2025-06-16 01:00:00+02:00 0
2025-06-16 01:30:00+02:00 0
2025-06-16 02:00:00+02:00 0
2025-06-16 02:30:00+02:00 0
2025-06-16 03:00:00+02:00 0
2025-06-16 03:30:00+02:00 0
2025-06-16 04:00:00+02:00 0
2025-06-16 04:30:00+02:00 0
2025-06-16 05:00:00+02:00 0
2025-06-16 05:30:00+02:00 16
2025-06-16 06:00:00+02:00 77
2025-06-16 06:30:00+02:00 207
2025-06-16 07:00:00+02:00 403
2025-06-16 07:30:00+02:00 656
2025-06-16 08:00:00+02:00 983
2025-06-16 08:30:00+02:00 1432
2025-06-16 09:00:00+02:00 1992
2025-06-16 09:30:00+02:00 2636
2025-06-16 10:00:00+02:00 3253
2025-06-16 10:30:00+02:00 3679
2025-06-16 11:00:00+02:00 3931
2025-06-16 11:30:00+02:00 4011
2025-06-16 12:00:00+02:00 3979
2025-06-16 12:30:00+02:00 3870
2025-06-16 13:00:00+02:00 3435
dtype: int64
[2025-06-15 13:45:02 +0200] [21] [DEBUG] get_load_forecast returning:
2025-06-15 13:30:00+02:00 555
2025-06-15 14:00:00+02:00 700
2025-06-15 14:30:00+02:00 800
2025-06-15 15:00:00+02:00 800
2025-06-15 15:30:00+02:00 600
2025-06-15 16:00:00+02:00 200
2025-06-15 16:30:00+02:00 600
2025-06-15 17:00:00+02:00 500
2025-06-15 17:30:00+02:00 500
2025-06-15 18:00:00+02:00 3200
2025-06-15 18:30:00+02:00 1300
2025-06-15 19:00:00+02:00 1000
2025-06-15 19:30:00+02:00 700
2025-06-15 20:00:00+02:00 800
2025-06-15 20:30:00+02:00 700
2025-06-15 21:00:00+02:00 900
2025-06-15 21:30:00+02:00 500
2025-06-15 22:00:00+02:00 400
2025-06-15 22:30:00+02:00 300
2025-06-15 23:00:00+02:00 400
2025-06-15 23:30:00+02:00 400
2025-06-16 00:00:00+02:00 300
2025-06-16 00:30:00+02:00 600
2025-06-16 01:00:00+02:00 500
2025-06-16 01:30:00+02:00 500
2025-06-16 02:00:00+02:00 400
2025-06-16 02:30:00+02:00 500
2025-06-16 03:00:00+02:00 0
2025-06-16 03:30:00+02:00 600
2025-06-16 04:00:00+02:00 700
2025-06-16 04:30:00+02:00 300
2025-06-16 05:00:00+02:00 600
2025-06-16 05:30:00+02:00 500
2025-06-16 06:00:00+02:00 500
2025-06-16 06:30:00+02:00 600
2025-06-16 07:00:00+02:00 500
2025-06-16 07:30:00+02:00 600
2025-06-16 08:00:00+02:00 200
2025-06-16 08:30:00+02:00 400
2025-06-16 09:00:00+02:00 400
2025-06-16 09:30:00+02:00 200
2025-06-16 10:00:00+02:00 400
2025-06-16 10:30:00+02:00 300
2025-06-16 11:00:00+02:00 400
2025-06-16 11:30:00+02:00 200
2025-06-16 12:00:00+02:00 800
2025-06-16 12:30:00+02:00 1000
2025-06-16 13:00:00+02:00 700
Name: yhat, dtype: int64
[2025-06-15 13:45:02 +0200] [21] [INFO] >> Performing naive MPC optimization...
[2025-06-15 13:45:02 +0200] [21] [INFO] Performing naive MPC optimization
[2025-06-15 13:45:02 +0200] [21] [DEBUG] get_load_cost_forecast returning:
P_PV_forecast P_load_forecast unit_load_cost
2025-06-15 13:30:00+02:00 3883 555 0.1451
2025-06-15 14:00:00+02:00 2094 700 0.1458
2025-06-15 14:30:00+02:00 2024 800 0.1458
2025-06-15 15:00:00+02:00 1922 800 0.1489
2025-06-15 15:30:00+02:00 1807 600 0.1489
2025-06-15 16:00:00+02:00 1664 200 0.1511
2025-06-15 16:30:00+02:00 1490 600 0.1511
2025-06-15 17:00:00+02:00 1315 500 0.1914
2025-06-15 17:30:00+02:00 1179 500 0.1914
2025-06-15 18:00:00+02:00 1072 3200 0.2374
2025-06-15 18:30:00+02:00 943 1300 0.2374
2025-06-15 19:00:00+02:00 794 1000 0.2546
2025-06-15 19:30:00+02:00 629 700 0.2546
2025-06-15 20:00:00+02:00 430 800 0.2810
2025-06-15 20:30:00+02:00 234 700 0.2810
2025-06-15 21:00:00+02:00 90 900 0.2965
2025-06-15 21:30:00+02:00 22 500 0.2965
2025-06-15 22:00:00+02:00 0 400 0.2931
2025-06-15 22:30:00+02:00 0 300 0.2931
2025-06-15 23:00:00+02:00 0 400 0.2676
2025-06-15 23:30:00+02:00 0 400 0.2676
2025-06-16 00:00:00+02:00 0 300 0.2959
2025-06-16 00:30:00+02:00 0 600 0.2959
2025-06-16 01:00:00+02:00 0 500 0.2677
2025-06-16 01:30:00+02:00 0 500 0.2677
2025-06-16 02:00:00+02:00 0 400 0.2519
2025-06-16 02:30:00+02:00 0 500 0.2519
2025-06-16 03:00:00+02:00 0 0 0.2421
2025-06-16 03:30:00+02:00 0 600 0.2421
2025-06-16 04:00:00+02:00 0 700 0.2363
2025-06-16 04:30:00+02:00 0 300 0.2363
2025-06-16 05:00:00+02:00 0 600 0.2537
2025-06-16 05:30:00+02:00 16 500 0.2537
2025-06-16 06:00:00+02:00 77 500 0.2702
2025-06-16 06:30:00+02:00 207 600 0.2702
2025-06-16 07:00:00+02:00 403 500 0.2820
2025-06-16 07:30:00+02:00 656 600 0.2820
2025-06-16 08:00:00+02:00 983 200 0.2920
2025-06-16 08:30:00+02:00 1432 400 0.2920
2025-06-16 09:00:00+02:00 1992 400 0.2691
2025-06-16 09:30:00+02:00 2636 200 0.2691
2025-06-16 10:00:00+02:00 3253 400 0.2096
2025-06-16 10:30:00+02:00 3679 300 0.2096
2025-06-16 11:00:00+02:00 3931 400 0.1666
2025-06-16 11:30:00+02:00 4011 200 0.1666
2025-06-16 12:00:00+02:00 3979 800 0.1548
2025-06-16 12:30:00+02:00 3870 1000 0.1548
2025-06-16 13:00:00+02:00 3435 700 0.1535
[2025-06-15 13:45:02 +0200] [21] [DEBUG] get_prod_price_forecast returning:
P_PV_forecast ... unit_prod_price
2025-06-15 13:30:00+02:00 3883 ... -0.0147
2025-06-15 14:00:00+02:00 2094 ... -0.0140
2025-06-15 14:30:00+02:00 2024 ... -0.0140
2025-06-15 15:00:00+02:00 1922 ... -0.0111
2025-06-15 15:30:00+02:00 1807 ... -0.0111
2025-06-15 16:00:00+02:00 1664 ... -0.0091
2025-06-15 16:30:00+02:00 1490 ... -0.0091
2025-06-15 17:00:00+02:00 1315 ... 0.0290
2025-06-15 17:30:00+02:00 1179 ... 0.0290
2025-06-15 18:00:00+02:00 1072 ... 0.0724
2025-06-15 18:30:00+02:00 943 ... 0.0724
2025-06-15 19:00:00+02:00 794 ... 0.0886
2025-06-15 19:30:00+02:00 629 ... 0.0886
2025-06-15 20:00:00+02:00 430 ... 0.1135
2025-06-15 20:30:00+02:00 234 ... 0.1135
2025-06-15 21:00:00+02:00 90 ... 0.1282
2025-06-15 21:30:00+02:00 22 ... 0.1282
2025-06-15 22:00:00+02:00 0 ... 0.1250
2025-06-15 22:30:00+02:00 0 ... 0.1250
2025-06-15 23:00:00+02:00 0 ... 0.1008
2025-06-15 23:30:00+02:00 0 ... 0.1008
2025-06-16 00:00:00+02:00 0 ... 0.1276
2025-06-16 00:30:00+02:00 0 ... 0.1276
2025-06-16 01:00:00+02:00 0 ... 0.1009
2025-06-16 01:30:00+02:00 0 ... 0.1009
2025-06-16 02:00:00+02:00 0 ... 0.0861
2025-06-16 02:30:00+02:00 0 ... 0.0861
2025-06-16 03:00:00+02:00 0 ... 0.0769
2025-06-16 03:30:00+02:00 0 ... 0.0769
2025-06-16 04:00:00+02:00 0 ... 0.0714
2025-06-16 04:30:00+02:00 0 ... 0.0714
2025-06-16 05:00:00+02:00 0 ... 0.0878
2025-06-16 05:30:00+02:00 16 ... 0.0878
2025-06-16 06:00:00+02:00 77 ... 0.1034
2025-06-16 06:30:00+02:00 207 ... 0.1034
2025-06-16 07:00:00+02:00 403 ... 0.1144
2025-06-16 07:30:00+02:00 656 ... 0.1144
2025-06-16 08:00:00+02:00 983 ... 0.1239
2025-06-16 08:30:00+02:00 1432 ... 0.1239
2025-06-16 09:00:00+02:00 1992 ... 0.1023
2025-06-16 09:30:00+02:00 2636 ... 0.1023
2025-06-16 10:00:00+02:00 3253 ... 0.0462
2025-06-16 10:30:00+02:00 3679 ... 0.0462
2025-06-16 11:00:00+02:00 3931 ... 0.0056
2025-06-16 11:30:00+02:00 4011 ... 0.0056
2025-06-16 12:00:00+02:00 3979 ... -0.0055
2025-06-16 12:30:00+02:00 3870 ... -0.0055
2025-06-16 13:00:00+02:00 3435 ... -0.0067
[48 rows x 4 columns]
[2025-06-15 13:45:02 +0200] [21] [INFO] Perform an iteration of a naive MPC controller
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Battery usage enabled. Initial SOC: 0.6, Final SOC: 0.23
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Processing deferrable load 0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 0: Proposed optimization window: -8 --> 12
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 0: Validated optimization window: 0 --> 12
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Processing deferrable load 1
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Load 1 is standard/non-thermal.
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Load 1: Using total timesteps constraint: 1
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Load 1: Standard load constraints set.
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 1: Proposed optimization window: -8 --> 14
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 1: Validated optimization window: 0 --> 14
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Processing deferrable load 2
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 2: Proposed optimization window: 6 --> 14
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load 2: Validated optimization window: 6 --> 14
[2025-06-15 13:45:02 +0200] [21] [INFO] Status: Optimal
[2025-06-15 13:45:02 +0200] [21] [INFO] Total value of the Cost function = 0.06
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Battery usage enabled. Initial SOC: 0.6, Final SOC: 0.23
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load operating hours: [0, 0, 0, 0]
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load timesteps: [0, 1, 0]
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load start timesteps: [-8, -8, 6]
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Deferrable load end timesteps: [12, 14, 14]
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Selected cost function type: self-consumption
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Solver selected: COIN_CMD
[2025-06-15 13:45:02 +0200] [21] [INFO] Optimization status: Optimal
[2025-06-15 13:45:02 +0200] [21] [INFO] Publishing data to HASS instance
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_pv_forecast = 3883
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_pv_forecast to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_load_forecast = 555
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_load_forecast to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_pv_curtailment = 0.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_pv_curtailment to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_hybrid_inverter = 2552.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_hybrid_inverter to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable0 = 0.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_deferrable0 to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable1 = 1997.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_deferrable1 to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable2 = 0.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_deferrable2 to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_batt_forecast = -1331.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_batt_forecast to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_soc_batt_forecast = 64.21
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_soc_batt_forecast to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_grid_forecast = 0.0
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_p_grid_forecast to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_total_cost_fun_value = 1.16
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_total_cost_fun_value to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_optim_status = Optimal
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_optim_status to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_unit_load_cost = 0.1451
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_unit_load_cost to json file
[2025-06-15 13:45:02 +0200] [21] [INFO] Successfully posted to sensor.mpc_unit_prod_price = -0.0147
[2025-06-15 13:45:02 +0200] [21] [DEBUG] Saved sensor.mpc_unit_prod_price to json file
[2025-06-15 13:45:03 +0200] [21] [INFO] >> Obtaining params:
[2025-06-15 13:45:03 +0200] [21] [INFO] Passed runtime parameters: {'publish_prefix': 'mpc_'}
[2025-06-15 13:45:03 +0200] [21] [INFO] >> Setting input data dict
[2025-06-15 13:45:03 +0200] [21] [INFO] Setting up needed data
[2025-06-15 13:45:03 +0200] [21] [DEBUG] Initialized Optimization with retrieve_hass_conf: {'optimization_time_step': Timedelta('0 days 00:30:00'), 'historic_days_to_retrieve': 10, 'sensor_power_photovoltaics': 'sensor.inverter_ingangsvermogen', 'sensor_power_photovoltaics_forecast': 'sensor.p_pv_forecast', 'sensor_power_load_no_var_loads': 'sensor.power_load_no_var_loads', 'load_negative': False, 'set_zero_min': True, 'sensor_replace_zero': ['sensor.inverter_ingangsvermogen'], 'sensor_linear_interp': ['sensor.inverter_ingangsvermogen', 'sensor.power_load_no_var_loads'], 'method_ts_round': 'first', 'continual_publish': False, 'hass_url': 'http://supervisor/core/api', 'long_lived_token': '4a653cd73437817aa25835895766b233a4f4fb77ce6eaa1ea5ad42337de7bfd955616ee0c9c95b4e2829ff13d5b6cefe51f1801618726893', 'time_zone': <DstTzInfo 'Europe/Brussels' LMT+0:18:00 STD>, 'Latitude': 50.789456233171535, 'Longitude': 5.592577457427979, 'Altitude': 110}
[2025-06-15 13:45:03 +0200] [21] [DEBUG] Optimization configuration: {'costfun': 'self-consumption', 'logging_level': 'INFO', 'set_use_pv': True, 'set_use_adjusted_pv': False, 'adjusted_pv_regression_model': 'LassoRegression', 'adjusted_pv_solar_elevation_threshold': 10, 'set_use_battery': True, 'number_of_deferrable_loads': 4, 'nominal_power_of_deferrable_loads': [2150, 2000, 3000, 3000], 'minimum_power_of_deferrable_loads': [0, 0, 0, 0], 'operating_hours_of_each_deferrable_load': [2, 2, 2, 2], 'treat_deferrable_load_as_semi_cont': [False, False, False, False], 'set_deferrable_load_single_constant': [False, False, False, False], 'set_deferrable_startup_penalty': [3, 5, 5, 0], 'delta_forecast_daily': Timedelta('1 days 00:00:00'), 'load_forecast_method': 'naive', 'load_cost_forecast_method': 'hp_hc_periods', 'load_peak_hours_cost': 0.1907, 'load_offpeak_hours_cost': 0.1419, 'production_price_forecast_method': 'constant', 'photovoltaic_production_sell_price': 0.065, 'set_total_pv_sell': False, 'lp_solver': 'COIN_CMD', 'lp_solver_path': '/usr/bin/cbc', 'lp_solver_timeout': 45, 'num_threads': 0, 'set_nocharge_from_grid': False, 'set_nodischarge_to_grid': False, 'set_battery_dynamic': True, 'battery_dynamic_max': 0.85, 'battery_dynamic_min': -0.5, 'weight_battery_discharge': 0.05, 'weight_battery_charge': 0.01, 'weather_forecast_method': 'open-meteo', 'open_meteo_cache_max_age': 30, 'start_timesteps_of_each_deferrable_load': [0, 0, 0, 0], 'end_timesteps_of_each_deferrable_load': [0, 0, 0, 0], 'load_peak_hour_periods': {'period_hp_1': [{'start': '08:00'}, {'end': '17:00'}], 'period_hp_2': [{'start': '08:00'}, {'end': '17:00'}]}}
[2025-06-15 13:45:03 +0200] [21] [DEBUG] Plant configuration: {'maximum_power_from_grid': 4000, 'maximum_power_to_grid': 6000, 'pv_module_model': ['JA_Solar_JAM72S01_385_PR', 'JA_Solar_JAM72S01_385_PR', 'JA_Solar_JAM72S01_385_PR'], 'pv_inverter_model': ['Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_', 'Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_', 'Huawei_Technologies_Co___Ltd___SUN2000_9KTL_USL0__240V_'], 'surface_tilt': [35, 35, 15], 'surface_azimuth': [90, 270, 180], 'modules_per_string': [6, 6, 13], 'strings_per_inverter': [1, 1, 1], 'inverter_is_hybrid': True, 'compute_curtailment': True, 'battery_discharge_power_max': 5000, 'battery_charge_power_max': 5000, 'battery_discharge_efficiency': 1, 'battery_charge_efficiency': 0.95, 'battery_nominal_energy_capacity': 15000, 'battery_minimum_state_of_charge': 0.12, 'battery_maximum_state_of_charge': 1, 'battery_target_state_of_charge': 0.12}
[2025-06-15 13:45:03 +0200] [21] [DEBUG] Solver configuration: lp_solver=COIN_CMD, lp_solver_path=/usr/bin/cbc
[2025-06-15 13:45:03 +0200] [21] [DEBUG] Number of threads: 2
[2025-06-15 13:45:03 +0200] [21] [INFO] >> Publishing data...
[2025-06-15 13:45:03 +0200] [21] [INFO] Publishing data to HASS instance
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_optim_status = Optimal
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable2 = 0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_unit_load_cost = 0.1451
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_soc_batt_forecast = 64.21
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_grid_forecast = 0.0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_total_cost_fun_value = 1.16
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_batt_forecast = -1331.0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_load_forecast = 555
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable3 = 0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_pv_curtailment = 0.0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_hybrid_inverter = 2552.0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_temp_predicted3 = 36.67
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable0 = 0
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_unit_prod_price = -0.0147
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_deferrable1 = 1997
[2025-06-15 13:45:03 +0200] [21] [INFO] Successfully posted to sensor.mpc_p_pv_forecast = 3883
[2025-06-15 13:46:48 +0200] [21] [INFO] EMHASS server online, serving index.html...
Would someone be able to assist me on this. I have no idea where to start looking but esentially the p_load forecast values are out of sync with current time.
The parameters being passed are as follows:
Blockquote
ml_forecast_model_fit:
url: http://localhost:5050/action/forecast-model-fit
method: POST
content_type: âapplication/jsonâ
payload: >-
{
âdays_to_retrieveâ: 9,
âmodel_typeâ: âload_forecastâ,
âvar_modelâ: âsensor.power_load_no_varâ,
âsklearn_modelâ: âKNeighborsRegressorâ,
ânum_lagsâ: 48,
âsplit_date_deltaâ: â48hâ,
âperform_backtestâ: âTrueâ
}
My power_load_no_var_loads looks something like this.
Seems like a timezone issue but Iâve set it in the EMHASS config
Running HA supervisor & its set to the same zoneâŚ
There is a TZ issue with the forecasts, please include some comments here:
Thanks, is there a workaround youâre implementing at the moment. Im thinking of just loading the sensor with previous days values?












