It is not an easy question to answer. It depends on what suits well for your case and it depends on the size of that time step.
Remember that this is a discrete representation of something that is continuous in reality: the battery SOC.
If it were me then I would just use mean values and for your example I will try to reach a SOC of 0.71 at 15.30. I would test that and if it allows for a correct SOC following for a complete day then it is settled, otherwise try the “first” or “last” options and see how it goes.
How/Which strategy do you use to make sure the optimization process has ended before you publish data?
I see many of you just call the services in sequence in the same automation but in my case, as I expected, the publish service is executed too soon (11 s) and the optim has not ended yet.
So if I check the log the two activities get mixed (actually publish is performed before optim).
Should I just add a wait? Any better suggestion?
Thank you!
PS:
I’m using the REST command integration, not using Node-Red
I have another question about MPC, hope somebody can give me good advice.
I’m planning to run the optimization every hour. I have an optimization time step of 30 minutes. So for a 24h optimization I am passing 48 data points, as mentioned several times in the thread and in the documentation. Also the prediction horizon is progressively reduced (according to documentation) to keep the 24h prediction: so at 00:00 it is 48 datapoints, at 01:00 it is 46 and so on. So I’m passing the load_cost_forecast
and prod_price_forecast
datapoints accordingly (while the PV forecast is taken from scraping/solar.forecast).
Tonight I was testing and ran the optimization at 23:00, which implied a prediction of 1h with 2 datapoints. I got an error mentioning that the prediction_horizon
should be at least 5 times the optimization time step (true, it’s also in the documentation).
The problem now is that I have to stay within the same day for the prediction (so in my example 1h), I can’t modify the optimization time step (and I’ve seen nobody in this thread doing this)… so I’m a bit out of options.
Can anybody tell me what I’m doing wrong and if I’ve not understood how this should work?
Thank you!
Is there a reason you need to stay within the same day. I’m running MPC and often roll over between one day and the next with my forecasts.
Which forecasts are you injecting into MPC and can you roll them over into the next day? Even if you just copies the values from he current day as a proxy for the next day.
My understanding you have to (or should) cover one day comes from the EMHASS optimisations section of the documentation, where it’s used in combination with the dayahead optim (then from previous messages I understood some of us are using MPC alone, for its flexibility that allows continuous fine tuning), and then from the the MPC section below, where it is explained the horizon is progressively reduced to keep the one-day optimisation notion.
That was also making sense in my head as if I define the final Soc I need to know when I want to reach it (especially for profit) otherwise I would keep postponing it and then I may find myself running the optim at midday and requiring to reach 20% SOC at the same time of the following (maybe sunny) day (which may probably turn to be infeasible or not desired).
How are you approaching this aspect and what is your strategy?
Maybe I totally misunderstood the sense of this.
Thanks!
PS
Values or forecasts are not a problem (I’m using either solar.forecast or scrapping - I’m also passing the cost datapoints according to the horizon), I need to understand what the right approach is and how many datapoints I have to pass depending on the time.
No I think that you understood this correctly. The sense of MPC that is described in the documentation is the receding horizon approach. For me this is the form of MPC that makes more sense here in our context and that is why I presented it like that in the documentation. In this form you think for complete days and the horizon is constantly shrinking for each MPC call. For this to work you will need call a first day-ahead optimization that will give you the optimal SOC trajectory for the day, then constantly call the MPC to try to meet that SOC trajectory providing SOC min and max for each MPC call. Also for each MPC call you will need to pass the remaining number of working hours for each deferrable load. At least this is how I would have implemented this and this is what I thought when I designed this. I myself I’m just using day-ahead call at my home because with almost constant pricing there is not much at risk.
Most people here are using this MPC functionality in a secondary manner. This is without receding horizon and just using the MPC as a small intra-day sliding window of optimizations. Which is ok I guess because either way you are constantly optimizing. However, like I said, the first option makes more sense to me for complete day optimizations. The first option needs more template working and tweaking though.
I was thinking… Is there maybe the possibility to get a shell/rest command answer (the one you would see in the terminal maybe) through a restful sensor (or similar)?
That would allow to perform a text search to understand if the optim was successful or not.
Or is there maybe another method? Access the addon-log? … ?
Yes this is in the makings. I’ll work on this in the next dev sessions.
Here is the github tag for this FR: Feature request: Add a published parameter with the status of latest optimization · Issue #109 · davidusb-geek/emhass · GitHub
I have done this, how have you provided the EMHASS the visabilty of the export limiting?
i have mine see the total average production or the solaredge values usuing templates, these are verry acurate and 90% of time are the same as my app, but yet the EMHASS doesnt realise i export most days and this is common and tries to export battery rather then calculate this.
That’s how I use MPC. Or, actually as a combination of those. The reason behind this is that my electricity prices for the next day are updated daily at 13:00. Prices have an hourly resolution and change much from day to day.
So at the beginning of a day, I have 24 hours of forecasts for prices, solar power and consumption. As the day progresses, I have to reduce the MPC horizon until at 13:00, when it’s at its shortest 11 hours. At 14:00 (or just before), I receive updated Nordpool prices and can then use a full 24 hour sliding window horizon until midnight.
The advantage for me is that I can quickly adapt to changes in solar power if the forecast turned out inaccurate, or unpredictable electricity usage, so I can frequently recalculate my optimizations based on current soc. I always use a target SOC of 50%. Not that it really matters, because those 50% are always at least 11 hours away, so I can still optimize the battery use up to that point.
In progress/TODO in my setup:
Make a better solar power prediction based on local weather cloud density data.
Start making use of deferable loads. Just the PHEV, but still good to know when’s a good time to charge it.
Make a more “natural” battery control logic to use more of the inverter’s automatic setting
Can you perhaps share your prediction_horizon code, still looking to solve this. ThankS
Optimisation with negative sell price and buy costs
We are fairly lucky in Australia with an abundance of renewable energy which means most days the grid has an oversupply issue which drives the prices down, often negative. Today for example I have negative production prices until 16:00
I have a very light load today and my home battery will be full by 14:00, so what happens then. EMHASS optimisation addresses this by selling into a negative price market at the cheapest times to minimise the total negative pricing.
In reality what I do is turn on export control (zero export) in my solar inverter so I don’t actually export anything when the prices are negative. When the costs are negative (rarely) I switch my inverter to production control (zero production) as I am getting paid to consume energy from the grid.
So the current EMHASS optimisation is correct but there is a more optimal solution available by considering export and production control. Now I could just artificially set my solar forecast during these windows to my forecast load, but I still want to encourage EMHASS to switch on any additional loads as the energy is available for free.
I realise this is a ‘nice’ problem to have but am interested in thoughts from others?
I’m wondering if this is because of the target SOC, which is a strict requirement, so it tries to minimise the impact of negative prices to reach that value, even though in this case it’s not optimal.
As you are runing the optim very often maybe being able to switch the “no grid export” on when you have negative prices ahead could be helpful?
How are you running EMHASS? profit/cost/self-consumption?
EMHASS is making the correct calculations, in the absence of curtailment. I’m optimising for profit.
If I have to export 20 kWh, it maximises profit to export now at -1¢/ kWh rather than later at -6¢/ kWh.
This isn’t dependent on my battery SOC final, rather the best way to maximise profit when I have an oversupply of solar production for the day.
Hi
I seem to be getting an error with EMHASS:
2023-09-30 20:40:17,173 - 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 204, in action_call
opt_res = naive_mpc_optim(input_data_dict, app.logger)
File "/usr/local/lib/python3.9/dist-packages/emhass/command_line.py", line 265, in naive_mpc_optim
df_input_data_dayahead = input_data_dict['fcst'].get_load_cost_forecast(
File "/usr/local/lib/python3.9/dist-packages/emhass/forecast.py", line 705, in get_load_cost_forecast
forecast_out = self.get_forecast_out_from_csv(
File "/usr/local/lib/python3.9/dist-packages/emhass/forecast.py", line 522, in get_forecast_out_from_csv
forecast_out = pd.DataFrame(
File "/usr/local/lib/python3.9/dist-packages/pandas/core/frame.py", line 694, in __init__
mgr = ndarray_to_mgr(
File "/usr/local/lib/python3.9/dist-packages/pandas/core/internals/construction.py", line 351, in ndarray_to_mgr
_check_values_indices_shape_match(values, index, columns)
File "/usr/local/lib/python3.9/dist-packages/pandas/core/internals/construction.py", line 422, in _check_values_indices_shape_match
raise ValueError(f"Shape of passed values is {passed}, indices imply {implied}")
ValueError: Shape of passed values is (9, 1), indices imply (7, 1)
Any idea what the cause might be?
Thanks
Rob
It would help if you could post your MPC payload that causes this error.
@davidusb it would also help debugging if the payload received for MPC was printed in the logs.
Thanks Mark
{"load_cost_forecast":[0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.16, 0.13, 0.13, 0.13, 0.13, 0.12, 0.12, 0.12, 0.12, 0.12, 0.1, 0.04, 0.03, 0.03, 0.02, 0.02, -0.01, -0.02, -0.04, -0.04, -0.05, -0.05, -0.02, -0.01, 0.27, 0.28, 0.28, 0.28, 0.29, 0.3, 0.32, 0.39, 0.42, 0.51, 0.48, 0.51, 0.26, 0.26, 0.2, 0.18, 0.18],"prod_price_forecast":[0.06, 0.06, 0.07, 0.06, 0.06, 0.06, 0.06, 0.06, 0.04, 0.04, 0.04, 0.03, 0.03, 0.02, 0.03, 0.02, 0.02, 0.01, -0.05, -0.05, -0.06, -0.06, -0.07, -0.11, -0.12, -0.14, -0.14, -0.15, -0.15, -0.12, -0.11, 0.19, 0.2, 0.2, 0.21, 0.21, 0.22, 0.24, 0.3, 0.33, 0.41, 0.39, 0.42, 0.15, 0.15, 0.1, 0.08, 0.08],"pv_power_forecast":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 160, 627, 1147, 1697, 2249, 2685, 3066, 3385, 3632, 3800, 3903, 3929, 3905, 3827, 3701, 3498, 3237, 2904, 2499, 1909, 1366, 828, 302, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],"prediction_horizon":48,"soc_init":0.19,"soc_final":0.11,"num_def_loads":2,"def_total_hours":[3,4],"P_deferrable_nom":[1300,7360],"treat_def_as_semi_cont":[1, 0],"set_def_constant": [0, 0]}
I’ve been having trouble with reading Tesla data. Would only register 5kW charging to day when actual was 7kW. I’ve now upgraded the Tesla HACS in the hope that fixes the issue.
Still using solcast 3.1.6. Haven’t upgraded to 4.0.8.
I basically just take the shortest length of the available forecast lists.
{%- set horizon = [nordpool_sell.values|length, nordpool_buy.values|length, solcast|length]|min %}
I already know the lists are at most 24 values. If you don’t, just add the constant 24 to the min
filter.
Im failry certian the tesla can not charge at 7kw. It has the function for constant of 5kw and 7kw surge load only,
Is your app showing 7kw charge??
Ive been install about 2 a week since the rebate and ive never seen a 7kw charge. And i have over 40 sites i manage.
I almost always see charging at 5 kW per powerwall, I think I have only seen it surge to 7 kW for a few seconds.