No problem, as soc_final is so far away it has little impact on the initial forecasts, so I set it to zero to see the maximum that EMHASS could return over the full 24 hours.
Warning. My full mpc_optimisation call is quite complex and I don’t recommend people start here with this level of complexity. I actually have five different shell commands that I can set from the straight forward day-ahead to the complex MPC, so if things go wrong I can easily roll back to a working configuration.
post_mpc_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{\"load_cost_forecast\":{{(
([states('sensor.amber_general_price')|float(0)] +
state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
}}, \"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:]
}}, \"prod_price_forecast\":{{(
([states('sensor.amber_feed_in_price')|float(0)] +
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)))
}}, \"pv_power_forecast\":{{[min(15000,(states('sensor.APF_Generation_Entity')|int(0)
/(states('sensor.solaredge_i1_active_power_limit')|int(0)
+states('sensor.solaredge_i2_active_power_limit')|int(0))*200)|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
}}, \"prediction_horizon\":{{min(48,
(state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
}}, \"alpha\":1, \"beta\":0, \"soc_init\":{{(states('sensor.filtered_powerwall_soc')|int(0))/100
}}, \"soc_final\":0.0, \"def_total_hours\":[{{states('sensor.def_total_hours_pool_filter')
}},{{states('sensor.def_total_hours_pool_heatpump')
}},{{states('sensor.def_total_hours_ev')
}},{{states('sensor.def_total_hours_hvac')
}},{{states('sensor.def_total_hours_hws')
}}]}' http://localhost:5000/action/naive-mpc-optim"
Here’s a breakdown of each part of the JSON payload:
- load_cost_forecast: This is a list of the current electricity price from the ‘amber_general_price’ sensor, plus a list of future prices extracted from the ‘amber_general_forecast’ sensor. The list is trimmed or extended to have exactly 48 elements.
- load_power_forecast: This is a list starting with the current load from the ‘power_load_no_var_loads’ sensor, followed by values extracted from the ‘fi_fo_buffer’ input text, which are multiplied by 1000 and converted to integers.
- prod_price_forecast: This is a list of the current feed-in electricity price from the ‘amber_feed_in_price’ sensor, plus a list of future prices extracted from the ‘amber_feed_in_forecast’ sensor.
- pv_power_forecast: This starts with the current generation from the ‘APF_Generation_Entity’ sensor, normalized to a maximum of 15000 and a minimum of 0. This is followed by the solar forecasts for today and tomorrow extracted from the ‘solcast_forecast_today’ and ‘solcast_forecast_tomorrow’ sensors, which are multiplied by 2000 and converted to integers.
- prediction_horizon: This is the minimum of 48 and one more than the number of forecasts in the ‘amber_feed_in_forecast’ sensor.
- alpha: This is a fixed value of 1.
- beta: This is a fixed value of 0.
- soc_init: This is the current state of charge of the Powerwall, obtained from the ‘filtered_powerwall_soc’ sensor and divided by 100.
- soc_final: This is a fixed value of 0.0.
- def_total_hours: This is a list of values obtained from the ‘def_total_hours_pool_filter’, ‘def_total_hours_pool_heatpump’, ‘def_total_hours_ev’, ‘def_total_hours_hvac’, and ‘def_total_hours_hws’ sensors.