Just run the fit
routine and provide whatever number of lags you want using the num_lags
parameters. If you don’t want to optimize the number of lags then don’t run the tune
routine.
Brilliant, will try, thank you!
Once again naive-mpc-optim POST is failing with ValueError: could not convert string to float: ‘NOTRUN’ error after rebooting Home Assistant?!
I can use either the shell command or a node-red flow so testing both.
The output from the shell command and the output from the node-red ‘Rendor Template’ node is the same (apart from slash before quote):
{\"load_cost_forecast\":[0.17, 0.16, 0.12, 0.13, 0.11, 0.09, 0.11, 0.12, 0.38, 0.39, 0.39, 0.39, 0.42, 0.45, 0.55, 0.59, 0.69, 0.69, 0.69, 0.69, 0.44, 0.42, 0.29, 0.2, 0.22, 0.23, 0.24, 0.23, 0.23, 0.23, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16],\"prod_price_forecast\":[0.05, 0.04, 0.0, 0.02, -0.0, -0.02, -0.0, 0.0, 0.29, 0.3, 0.3, 0.3, 0.33, 0.36, 0.45, 0.48, 0.58, 0.58, 0.58, 0.58, 0.31, 0.3, 0.18, 0.09, 0.12, 0.13, 0.14, 0.13, 0.13, 0.12, 0.09, 0.09, 0.07, 0.07, 0.07, 0.06],\"pv_power_forecast\":[3267, 3496, 3570, 3764, 3773, 3703, 3577, 3381, 3101, 2752, 2362, 1890, 1340, 759, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 385, 893, 1408, 1861, 2353, 2794, 3177, 3403, 3615, 3803, 3873, 3835, 3722, 3538, 3230, 2796, 2275, 1835, 1277, 724, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\"prediction_horizon\":36,\"soc_init\":0.28,\"soc_final\":0.05,\"def_total_hours\":[2,1]}
and
{"load_cost_forecast":[0.17, 0.16, 0.12, 0.13, 0.11, 0.09, 0.11, 0.12, 0.38, 0.39, 0.39, 0.39, 0.42, 0.45, 0.55, 0.59, 0.69, 0.69, 0.69, 0.69, 0.44, 0.42, 0.29, 0.2, 0.22, 0.23, 0.24, 0.23, 0.23, 0.23, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16],"prod_price_forecast":[0.05, 0.04, 0.0, 0.02, -0.0, -0.02, -0.0, 0.0, 0.29, 0.3, 0.3, 0.3, 0.33, 0.36, 0.45, 0.48, 0.58, 0.58, 0.58, 0.58, 0.31, 0.3, 0.18, 0.09, 0.12, 0.13, 0.14, 0.13, 0.13, 0.12, 0.09, 0.09, 0.07, 0.07, 0.07, 0.06],"pv_power_forecast":[3247, 3496, 3570, 3764, 3773, 3703, 3577, 3381, 3101, 2752, 2362, 1890, 1340, 759, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 385, 893, 1408, 1861, 2353, 2794, 3177, 3403, 3615, 3803, 3873, 3835, 3722, 3538, 3230, 2796, 2275, 1835, 1277, 724, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":36,"soc_init":0.27,"soc_final":0.05,"def_total_hours":[2,1]}
or:
{
"load_cost_forecast": [0.17, 0.16, 0.12, 0.13, 0.11, 0.09, 0.11, 0.12, 0.38, 0.39, 0.39, 0.39, 0.42, 0.45, 0.55, 0.59, 0.69, 0.69, 0.69, 0.69, 0.44, 0.42, 0.29, 0.2, 0.22, 0.23, 0.24, 0.23, 0.23, 0.23, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16],
"prod_price_forecast": [0.05, 0.04, 0.0, 0.02, -0.0, -0.02, -0.0, 0.0, 0.29, 0.3, 0.3, 0.3, 0.33, 0.36, 0.45, 0.48, 0.58, 0.58, 0.58, 0.58, 0.31, 0.3, 0.18, 0.09, 0.12, 0.13, 0.14, 0.13, 0.13, 0.12, 0.09, 0.09, 0.07, 0.07, 0.07, 0.06],
"pv_power_forecast": [3247, 3496, 3570, 3764, 3773, 3703, 3577, 3381, 3101, 2752, 2362, 1890, 1340, 759, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 385, 893, 1408, 1861, 2353, 2794, 3177, 3403, 3615, 3803, 3873, 3835, 3722, 3538, 3230, 2796, 2275, 1835, 1277, 724, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"prediction_horizon": 36,
"soc_init": 0.27,
"soc_final": 0.05,
"def_total_hours": [2, 1]
}
The output from both are valid JSON.
The prediction horizon of 36 is correct, there are 36 elements in the load_cost_forecast and prod_price_forecast data, more in the pv_power_forecast data.
But after rebooting the system I’m getting the following error from both methods of POSTing and also if I take this output and run a curl command from a terminal on a separate Mac PC:
2023-08-17 09:53:37,000 - web_server - INFO - Setting up needed data
2023-08-17 09:53:37,003 - web_server - INFO - Retrieve hass get data method initiated...
2023-08-17 09:53:37,688 - web_server - ERROR - Exception on /action/naive-mpc-optim [POST]
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1486, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1469, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/usr/local/lib/python3.9/dist-packages/emhass/web_server.py", line 174, in action_call
input_data_dict = set_input_data_dict(config_path, str(data_path), costfun,
File "/usr/local/lib/python3.9/dist-packages/emhass/command_line.py", line 110, in set_input_data_dict
rh.get_data(days_list, var_list,
File "/usr/local/lib/python3.9/dist-packages/emhass/retrieve_hass.py", line 140, in get_data
df_tp = df_raw.copy()[['state']].replace(
File "/usr/local/lib/python3.9/dist-packages/pandas/core/generic.py", line 5920, in astype
new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/internals/managers.py", line 419, in astype
return self.apply("astype", dtype=dtype, copy=copy, errors=errors)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/internals/managers.py", line 304, in apply
applied = getattr(b, f)(**kwargs)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/internals/blocks.py", line 580, in astype
new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/dtypes/cast.py", line 1292, in astype_array_safe
new_values = astype_array(values, dtype, copy=copy)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/dtypes/cast.py", line 1237, in astype_array
values = astype_nansafe(values, dtype, copy=copy)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/dtypes/cast.py", line 1098, in astype_nansafe
result = astype_nansafe(flat, dtype, copy=copy, skipna=skipna)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/dtypes/cast.py", line 1181, in astype_nansafe
return arr.astype(dtype, copy=True)
ValueError: could not convert string to float: 'NOTRUN'
I’ve been looing at it for a while and can’t see why?
Thanks
Rob
Hi Mark, as always, I love your contributions.
I have been working on something similar with Josh, and I derived the below:
{{(((state_attr('sensor.forecast_today', 'detailedForecast') +(state_attr('sensor.forecast_tomorrow', 'detailedForecast'))) |selectattr('period_start', 'ge', now() - timedelta(minutes=29.99)) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list)[:48])}}
So, the only real different is that I am looking at the current 30 min forecast, whereas you’re taking the next 30 min forecast. I did the current 30min period I am in, as thats how Amber’s API works (from my understanding). 5:00 data runs from 5:00 to 5:29.
Keen to grab your understanding and thoughts on this.
you should multiply by 2000.
solcast detailedForecast reports energy (kWh) forecast for each 30 minute block, EMHASS is expecting the power (W) for the timewindow.
1 kWh delivered in 30 minutes is 1 kWh / 0.5 h * 1000 W/ Kw = 1 * 2000 = 2000 W
With that amendment both templates deliver exactly the same results, except for the first element, where mine is the current measured power and yours is the solcast forecast for the current period.
You can reformat your curl POST to call from a linux command line, you need to escape differently on the command line ;-(, so that way you can debug each element in real time and find out which element fails.
The other way to debug is to use the rest_command integration method, which like your nodered will provide better error logging:
I have been using both float and int here with the expected results.
Hi Mark,
Thanks for that. Yes I’m testing curl commands from a mac which should be the same as linux.
Have some issues with solcast integration at the moment. Tried upgrading to the latest (3.1.6) but now the integration is not working at all so I have to fix that first. Trying to delete it altogether and reinstall but it won’t delete.
Will look into rest_command integration method as well.
Thanks
Rob
Ok so I’ve been looking at this for two days now. This is the template:
{"load_cost_forecast":{{(([states('sensor.cecil_st_general_price')|float(0)]+state_attr('sensor.cecil_st_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
}},"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)[:48])
}},"pv_power_forecast":{{([states('sensor.sonnenbatterie_84324_production_w')|int(0)]+state_attr('sensor.forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list+state_attr('sensor.forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list)|tojson
}},"prediction_horizon":{{min(48, (state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},"soc_init":{{(states('sensor.sonnenbatterie_84324_state_charge_user')|float(0))/100
}},"soc_final":0.1,"def_total_hours":[2,1]}
This is the output:
{"load_cost_forecast":[0.43, 0.19, 0.2, 0.19, 0.19, 0.19, 0.2, 0.2, 0.2, 0.2, 0.19, 0.17, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.17, 0.17, 0.16, 0.16, 0.16, 0.13, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.05, 0.35, 0.36, 0.39, 0.36, 0.4, 0.43, 0.48, 0.56, 0.56, 0.59, 0.54],"prod_price_forecast":[0.34, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.04, 0.02, 0.0, -0.01, -0.01, -0.02, -0.02, -0.04, -0.04, -0.06, 0.27, 0.28, 0.3, 0.28, 0.31, 0.34, 0.38, 0.46, 0.46, 0.49, 0.44],"pv_power_forecast":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 579, 1140, 1672, 2173, 2602, 2981, 3281, 3497, 3666, 3743, 3744, 3674, 3548, 3347, 3095, 2733, 2200, 1721, 1211, 592, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":48,"soc_init":0.45,"soc_final":0.1,"def_total_hours":[2,1]}
Appears to be valid JSON format:
{
"load_cost_forecast": [0.43, 0.19, 0.2, 0.19, 0.19, 0.19, 0.2, 0.2, 0.2, 0.2, 0.19, 0.17, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.17, 0.17, 0.16, 0.16, 0.16, 0.13, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.05, 0.35, 0.36, 0.39, 0.36, 0.4, 0.43, 0.48, 0.56, 0.56, 0.59, 0.54],
"prod_price_forecast": [0.34, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.04, 0.02, 0.0, -0.01, -0.01, -0.02, -0.02, -0.04, -0.04, -0.06, 0.27, 0.28, 0.3, 0.28, 0.31, 0.34, 0.38, 0.46, 0.46, 0.49, 0.44],
"pv_power_forecast": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 579, 1140, 1672, 2173, 2602, 2981, 3281, 3497, 3666, 3743, 3744, 3674, 3548, 3347, 3095, 2733, 2200, 1721, 1211, 592, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"prediction_horizon": 48,
"soc_init": 0.45,
"soc_final": 0.1,
"def_total_hours": [2, 1]
}
Appears to be 48 elements in the two amber price lists which matches the prediction horison and more than 48 elements in the PV forecast list.
Deferabe loads seem to be correct:
number_of_deferrable_loads: 2
list_nominal_power_of_deferrable_loads:
- nominal_power_of_deferrable_loads: 1300
- nominal_power_of_deferrable_loads: 7360
list_operating_hours_of_each_deferrable_load:
- operating_hours_of_each_deferrable_load: 2
- operating_hours_of_each_deferrable_load: 1
list_peak_hours_periods_start_hours:
- peak_hours_periods_start_hours: "10:00"
- peak_hours_periods_start_hours: "10:00"
list_peak_hours_periods_end_hours:
- peak_hours_periods_end_hours: "16:00"
- peak_hours_periods_end_hours: "16:00"
list_treat_deferrable_load_as_semi_cont:
- treat_deferrable_load_as_semi_cont: true
- treat_deferrable_load_as_semi_cont: false
I’ve looked at rest_command and tried this template:
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.cecil_st_feed_in_price')|float(0)] +
(state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list))
| tojson
}},
"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
}},
"pv_power_forecast": {{
([states('sensor.sonnenbatterie_84324_production_w')|int(0)] +
state_attr('sensor.forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list +
state_attr('sensor.forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list
)| tojson
}},
"prediction_horizon": {{
min(48, (state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},
"def_total_hours": [2,1],
"soc_init": {{(states('sensor.sonnenbatterie_84324_state_charge_user')|float(0))/100 }},
"soc_final": 0.0
}
publish_data:
url: http://localhost:5000/action/publish-data
method: POST
content_type: 'application/json'
payload: '{}'
And also translated that into node-red http request node:
{
"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
}},
"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
}},
"pv_power_forecast": {{
([states('sensor.sonnenbatterie_84324_production_w')|int(0)] +
state_attr('sensor.forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list +
state_attr('sensor.forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list
)| tojson
}},
"prediction_horizon": {{
min(48, (state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},
"def_total_hours": [2,1],
"soc_init": {{(states('sensor.sonnenbatterie_84324_state_charge_user')|float(0))/100 }},
"soc_final": 0.1
}
Output is also valid JSON. Although I note that ther eare 49 amber price elements when the prediction horizon is 48, but that should be ok?
But still I get a NOTRUN error when POSTing via node-red, rest_command or curl command from Mac terminal or linux terminal.
However dayahead is working ok (at least when there’s enough amber data, sometime drops below the required 48).
What chould be wrong with this structure? What are the other data structure requirements I don’t know about?
Thanks
Rob
Can you upload a curl command that is failing for you and I can try it here?
ok try this:
curl -i -H "Content-Type: application/json" -X POST -d '{"load_cost_forecast":[0.19, 0.2, 0.19, 0.23, 0.23, 0.21, 0.2, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.17, 0.17, 0.16, 0.16, 0.16, 0.13, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.05, 0.35, 0.36, 0.39, 0.36, 0.39, 0.43, 0.45, 0.55, 0.6, 0.59, 0.52, 0.51, 0.31, 0.35],"prod_price_forecast":[0.09, 0.1, 0.09, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.04, 0.02, 0.0, -0.01, -0.01, -0.02, -0.02, -0.04, -0.04, -0.06, 0.27, 0.28, 0.3, 0.28, 0.3, 0.34, 0.36, 0.44, 0.49, 0.49, 0.43, 0.42, 0.2, 0.23],"pv_power_forecast":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 579, 1140, 1672, 2173, 2602, 2981, 3281, 3497, 3666, 3743, 3744, 3674, 3548, 3347, 3095, 2733, 2200, 1721, 1211, 592, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":48,"soc_init":0.18,"soc_final":0.1,"def_total_hours":[2,1]}' http://192.168.99.17:5000/action/naive-mpc-optim
robert@tablet2:~ $ curl -i -H "Content-Type: application/json" -X POST -d '{"load_cost_forecast":[0.19, 0.2, 0.19, 0.23, 0.23, 0.21, 0.2, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.17, 0.17, 0.16, 0.16, 0.16, 0.13, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.05, 0.35, 0.36, 0.39, 0.36, 0.39, 0.43, 0.45, 0.55, 0.6, 0.59, 0.52, 0.51, 0.31, 0.35],"prod_price_forecast":[0.09, 0.1, 0.09, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.04, 0.02, 0.0, -0.01, -0.01, -0.02, -0.02, -0.04, -0.04, -0.06, 0.27, 0.28, 0.3, 0.28, 0.3, 0.34, 0.36, 0.44, 0.49, 0.49, 0.43, 0.42, 0.2, 0.23],"pv_power_forecast":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 579, 1140, 1672, 2173, 2602, 2981, 3281, 3497, 3666, 3743, 3744, 3674, 3548, 3347, 3095, 2733, 2200, 1721, 1211, 592, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":48,"soc_init":0.18,"soc_final":0.1,"def_total_hours":[2,1]}' http://192.168.99.17:5000/action/naive-mpc-optim
HTTP/1.1 500 INTERNAL SERVER ERROR
Content-Length: 265
Content-Type: text/html; charset=utf-8
Date: Sat, 19 Aug 2023 11:30:05 GMT
Server: waitress
<!doctype html>
<html lang=en>
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
robert@tablet2:~ $
That works here for me ;-(
mark@odroid:~$ curl -i -H "Content-Type: application/json" -X POST -d '{"load_cost_forecast":[0.19, 0.2, 0.19, 0.23, 0.23, 0.21, 0.2, 0.2, 0.19, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.17, 0.17, 0.16, 0.16, 0.16, 0.13, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.05, 0.35, 0.36, 0.39, 0.36, 0.39, 0.43, 0.45, 0.55, 0.6, 0.59, 0.52, 0.51, 0.31, 0.35],"prod_price_forecast":[0.09, 0.1, 0.09, 0.12, 0.12, 0.1, 0.1, 0.09, 0.09, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.07, 0.04, 0.02, 0.0, -0.01, -0.01, -0.02, -0.02, -0.04, -0.04, -0.06, 0.27, 0.28, 0.3, 0.28, 0.3, 0.34, 0.36, 0.44, 0.49, 0.49, 0.43, 0.42, 0.2, 0.23],"prediction_horizon":48,"soc_init":0.18,"soc_final":0.1,"def_total_hours":[2,1],"num_def_loads":2,"P_deferrable_nom":[1300,1700]}' http://odroid.local:5000/action/naive-mpc-optim
HTTP/1.1 201 CREATED
Content-Length: 46
Content-Type: text/html; charset=utf-8
Date: Sat, 19 Aug 2023 23:02:56 GMT
Server: waitress
EMHASS >> Action naive-mpc-optim executed...
You can see I have added to the payload to make it explicit.
"num_def_loads":2,"P_deferrable_nom":[1300,1700]
So I think the error isn’t in your payload, but rather something else in your EMHASS config that is causing these errors.
I would suggest maybe increased logging within the EMHASS container with some debug statements (which are not currently there) would be the next step.
The other alternative is to go back to a very fundamental mpc call and then introduce one key value at a time:
curl -i -H "Content-Type:application/json" -X POST -d '{"solar_forecast_kwp":5}' http://localhost:5000/action/naive-mpc-optim
That’s it. I added the two deferrable load configurations to the template and it works. Thankyou so much. Seems there is some corruption in the EMHASS configuration file.
Must be this:
Seems when you look at the configuration form there a linefeed after the second nominal_power line.
You can’t see it when looking at the raw yaml:
It must be that?
Thanks
Rob
Hi,
I have some question, I have a hybrid car mostly it’s charging 2x a day. somewhere in the afternoon and at the evening. But it’s not always on the same time. Thats why i’m using this in my post_mpc_optim:
\"def_total_hours\":[{% set hours = (5 - states('sensor.volvo_xc60_battery_charge_level')|float(0) / 20) * (states('sensor.laadpaal_status_2')|float(0))|int(0) %} {{- hours -}}]
This looks to the level of the battery and if the car is plugged in to my charger or not.
I tried before with some static def_total_hours, than the system chosed the best time of the day to charge, but it’s not always possible to charging that time. Is this the correct way to handel this problem? Or have someone else some better solution?
thx
So this linefeed is not the cause of this issue. When I open the EMHASS UI configuration editor the extra line is still there.
I got this system all working again yesterday with the extra two data in the template (“num_def_loads”:2,“P_deferrable_nom”:[1300,7360]).
I had cause to reboot the system this morning after adding browser-mod from HACS (which is what caused the last reboot and failure) and its not working again?
No changes to EMHASS. Still has the same template:
{"load_cost_forecast":{{(([states('sensor.cecil_st_general_price')|float(0)]+state_attr('sensor.cecil_st_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
}},"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)[:48])
}},"pv_power_forecast":{{([states('sensor.sonnenbatterie_84324_production_w')|int(0)]+state_attr('sensor.forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list+state_attr('sensor.forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list)|tojson
}},"prediction_horizon":{{min(48, (state_attr('sensor.cecil_st_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}},"soc_init":{{(states('sensor.sonnenbatterie_84324_state_charge_user')|float(0))/100
}},"soc_final":0.1,"def_total_hours":[2,2],"num_def_loads":2,"P_deferrable_nom":[1300,7360]}
producing the following curl command:
curl -i -H "Content-Type: application/json" -X POST -d '{"load_cost_forecast":[0.18, 0.18, 0.16, 0.16, 0.15, 0.13, 0.11, 0.09, 0.05, 0.04, 0.04, 0.04, 0.04, 0.39, 0.39, 0.39, 0.39, 0.39, 0.46, 0.7, 1.2, 1.2, 1.2, 0.97, 0.7, 0.44, 0.44, 0.43, 0.23, 0.27, 0.33, 0.43, 0.43, 0.43, 0.23, 0.2, 0.2, 0.2, 0.17, 0.16, 0.16],"prod_price_forecast":[0.08, 0.08, 0.07, 0.07, 0.05, 0.02, -0.0, -0.02, -0.06, -0.07, -0.07, -0.06, -0.06, 0.3, 0.3, 0.3, 0.3, 0.3, 0.37, 0.59, 1.04, 1.04, 1.04, 0.83, 0.59, 0.32, 0.32, 0.3, 0.13, 0.16, 0.21, 0.31, 0.31, 0.31, 0.12, 0.1, 0.09, 0.09, 0.07, 0.07, 0.07],"pv_power_forecast":[1490, 1394, 1903, 2477, 2942, 3254, 3450, 3596, 3735, 3756, 3681, 3551, 3352, 3081, 2681, 2148, 1666, 1113, 538, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 413, 932, 1438, 1885, 2390, 2865, 3160, 3377, 3522, 3598, 3592, 3461, 3308, 3078, 2710, 2271, 1835, 1381, 872, 349, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":41,"soc_init":0.24,"soc_final":0.1,"def_total_hours":[2,2],"num_def_loads":2,"P_deferrable_nom":[1300,7360]}' http://192.168.99.17:5000/action/naive-mpc-optim
But getting a NOTRUN error again?
This happens every time I reboot the system and I have to add something to the template to make it work again?
What are the other elements I can add to the template? They don’t seem to be documented?
Thanks
Rob
Edit:
This is the output catured in the error handling:
{\"load_cost_forecast\":[0.17, 0.16, 0.16, 0.15, 0.13, 0.11, 0.09, 0.05, 0.04, 0.04, 0.04, 0.04, 0.39, 0.39, 0.39, 0.39, 0.39, 0.46, 0.7, 1.2, 1.2, 1.2, 0.97, 0.7, 0.44, 0.44, 0.43, 0.23, 0.27, 0.33, 0.43, 0.43, 0.43, 0.23, 0.2, 0.2, 0.2, 0.17, 0.16, 0.16],\"prod_price_forecast\":[0.07, 0.07, 0.07, 0.05, 0.02, -0.0, -0.02, -0.06, -0.07, -0.07, -0.06, -0.06, 0.3, 0.3, 0.3, 0.3, 0.3, 0.37, 0.59, 1.04, 1.04, 1.04, 0.83, 0.59, 0.32, 0.32, 0.3, 0.13, 0.16, 0.21, 0.31, 0.31, 0.31, 0.12, 0.1, 0.09, 0.09, 0.07, 0.07, 0.07],\"pv_power_forecast\":[1688, 1903, 2477, 2942, 3254, 3450, 3596, 3735, 3756, 3681, 3551, 3352, 3081, 2681, 2148, 1666, 1113, 538, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 413, 932, 1438, 1885, 2390, 2865, 3160, 3377, 3522, 3598, 3592, 3461, 3308, 3078, 2710, 2271, 1835, 1381, 872, 349, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\"prediction_horizon\":40,\"soc_init\":0.24,\"soc_final\":0.1,\"def_total_hours\":[2,2],\"num_def_loads\":2,\"P_deferrable_nom\":[1300,7360]}
There are 40 elements in the amber data with a prediction horison of 40.
But there are 80 elements in the pv_power_forecast? I guess this is today and tomorrows forecast.
They are very well documented:
https://emhass.readthedocs.io/en/latest/intro.html#passing-other-data
Here is my payload:
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.APF_Generation_Entity')|int(0)] +
state_attr('sensor.solcast_forecast_today', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|map('int')|list +
state_attr('sensor.solcast_forecast_tomorrow', 'detailedForecast')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',2000)|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": [1300,
4600,
{% if state_attr('sensor.duka_charger_power','charger_phases') | int(0) == 2 %}
{{240*16*3}}
{% else -%}
{{240*15*1}}
{% endif %},
4000,
600,
{% if state_attr('sensor.charger_power','charger_phases') | int(0) == 2 %}
{{240*16*3}}
{% else -%}
{{240*15*1}}
{% endif %}],
"treat_def_as_semi_cont": [1, 1, 0, 0, 1, 0],
"set_def_constant": [0, 0, 0, 0, 0, 0],
"soc_init": {{ (states('sensor.filtered_powerwall_soc')|int(0))/100 }},
"soc_final": 0.0
}
That is what I use, Amber had the shortest forecast horizon so I set prediction horizon based on that.
Having additional elements in PV forecast doesn’t seem to cause me issues:
Ok I’m using a PDF of the manual that mustn’t be the latest version. Will use the unline version. Thanks
I’ll cut the PV to 40 and see what happens