davidusb-geek / emhass

emhass: Energy Management for Home Assistant, is a Python module designed to optimize your home energy interfacing with Home Assistant.
MIT License
298 stars 59 forks source link

Thermal model 24h limitation #341

Open martinarva opened 2 months ago

martinarva commented 2 months ago

Describe the bug Thermal model has a 24h limitation. I have nordpool prices and my MPC uses dynamic prediction horizon up to 34h when there is data.

To Reproduce Steps to reproduce the behavior

Expected behavior I expect thermal model output would be as long as i feed in the data.

Screenshots If applicable, add screenshots to help explain your problem.

Home Assistant installation type

Your hardware

EMHASS installation type

Additional context Add any other context about the problem here.

martinarva commented 2 months ago

For example at the moment i have only 13h hours of data and thermal will fail:

`2024-08-29 11:56:43,772 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.19452899999999998, 0.182451, 0.14604620000000001, 0.116205, 0.1283684, 0.1868064, 0.2171844, 0.2768912, 0.45420599999999994, 0.5808054, 0.4375408, 0.2498682, 0.20105599999999998], 'prod_price_forecast': [0.08912999999999999, 0.07923, 0.04939, 0.02493, 0.0349, 0.0828, 0.1077, 0.15664, 0.30197999999999997, 0.40575, 0.28832, 0.15839, 0.11838], 'prediction_horizon': 13, 'pv_power_forecast': [5655, 5860, 5965, 5720, 5126, 4143, 3048, 1847, 685, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1057, 2224, 3379, 4357, 5079, 5469, 5580, 5301, 4678, 3793, 2754, 1528, 406, 19, 0, 0, 0], 'soc_init': 0.38, 'def_total_hours': [0, 0, 0], 'def_load_config': [{}, {'thermal_config': {'heating_rate': 5.0, 'cooling_constant': 0.1, 'overshoot_temperature': 26.0, 'start_temperature': 24.0, 'desired_temperatures': [22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22]}}, {}], 'outdoor_temperature_forecast': [20.8, 20.9, 21.2, 21.8, 22.2, 22.6, 22.9, 22.5, 20.8, 18.8, 17.6, 16.8, 15.7, 15.1, 15.1, 14.9, 14.8, 14.8, 14.8, 14.7, 15.5, 17.4, 19.8, 22.3, 24.2, 25.6, 26.4, 27.1, 27.2, 26.9, 26.4, 25.7, 24.6, 22.4, 20.9, 19.9, 20.2, 18.4, 17.4, 17.0, 17.1, 17.2, 17.3, 17.1, 16.6, 14.7, 14.9, 16.0]} 2024-08-29 11:56:43,774 - web_server - INFO - >> Setting input data dict 2024-08-29 11:56:43,774 - web_server - INFO - Setting up needed data 2024-08-29 11:56:43,791 - web_server - INFO - Retrieve hass get data method initiated... 2024-08-29 11:56:47,310 - web_server - INFO - Retrieving weather forecast data using method = list 2024-08-29 11:56:47,312 - web_server - INFO - Retrieving data from hass for load forecast using method = mlforecaster 2024-08-29 11:56:47,313 - web_server - INFO - Retrieve hass get data method initiated... 2024-08-29 11:56:52,640 - web_server - INFO - >> Performing naive MPC optimization... 2024-08-29 11:56:52,641 - web_server - INFO - Performing naive MPC optimization 2024-08-29 11:56:52,652 - web_server - ERROR - Exception on /action/naive-mpc-optim [POST] Traceback (most recent call last): File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 1473, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 882, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 880, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/flask/app.py", line 865, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/emhass/web_server.py", line 168, in action_call opt_res = naive_mpc_optim(input_data_dict, app.logger) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/emhass/command_line.py", line 437, in naive_mpc_optim df_input_data_dayahead["outdoor_temperature_forecast"] = \


  File "/usr/local/lib/python3.11/dist-packages/pandas/core/frame.py", line 3950, in __setitem__
    self._set_item(key, value)
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/frame.py", line 4143, in _set_item
    value = self._sanitize_column(value)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/frame.py", line 4870, in _sanitize_column
    com.require_length_match(value, self.index)
  File "/usr/local/lib/python3.11/dist-packages/pandas/core/common.py", line 576, in require_length_match
    raise ValueError(
ValueError: Length of values (48) does not match length of index (13)`

Same MPC without thermal runs great:
`2024-08-29 11:58:11,736 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.19452899999999998, 0.182451, 0.14604620000000001, 0.116205, 0.1283684, 0.1868064, 0.2171844, 0.2768912, 0.45420599999999994, 0.5808054, 0.4375408, 0.2498682, 0.20105599999999998], 'prod_price_forecast': [0.08912999999999999, 0.07923, 0.04939, 0.02493, 0.0349, 0.0828, 0.1077, 0.15664, 0.30197999999999997, 0.40575, 0.28832, 0.15839, 0.11838], 'prediction_horizon': 13, 'pv_power_forecast': [5655, 5860, 5965, 5720, 5126, 4143, 3048, 1847, 685, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1057, 2224, 3379, 4357, 5079, 5469, 5580, 5301, 4678, 3793, 2754, 1528, 406, 19, 0, 0, 0], 'soc_init': 0.38, 'def_total_hours': [0, 0, 0]}
2024-08-29 11:58:11,737 - web_server - INFO -  >> Setting input data dict
2024-08-29 11:58:11,737 - web_server - INFO - Setting up needed data
2024-08-29 11:58:11,747 - web_server - INFO - Retrieve hass get data method initiated...
2024-08-29 11:58:15,501 - web_server - INFO - Retrieving weather forecast data using method = list
2024-08-29 11:58:15,503 - web_server - INFO - Retrieving data from hass for load forecast using method = mlforecaster
2024-08-29 11:58:15,503 - web_server - INFO - Retrieve hass get data method initiated...
2024-08-29 11:58:20,064 - web_server - INFO -  >> Performing naive MPC optimization...
2024-08-29 11:58:20,065 - web_server - INFO - Performing naive MPC optimization
2024-08-29 11:58:20,081 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-08-29 11:58:20,106 - web_server - WARNING - Solver default unknown, using default
Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 
command line - /usr/local/lib/python3.11/dist-packages/pulp/solverdir/cbc/linux/64/cbc /tmp/6544d0572d474ff9a92f3fe635e5e2a2-pulp.mps -max -timeMode elapsed -branch -printingOptions all -solution /tmp/6544d0572d474ff9a92f3fe635e5e2a2-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 357 COLUMNS
At line 1743 RHS
At line 2096 BOUNDS
At line 2357 ENDATA
Problem MODEL has 352 rows, 247 columns and 1086 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 4.36584 - 0.00 seconds
Cgl0003I 0 fixed, 0 tightened bounds, 12 strengthened rows, 52 substitutions
Cgl0004I processed model has 146 rows, 137 columns (76 integer (76 of which binary)) and 685 elements
Cbc0038I Initial state - 4 integers unsatisfied sum - 0.794174
Cbc0038I Pass   1: suminf.    0.46057 (4) obj. -2.84292 iterations 19
Cbc0038I Solution found of -2.84292
Cbc0038I Relaxing continuous gives -2.97518
Cbc0038I Before mini branch and bound, 70 integers at bound fixed and 40 continuous
Cbc0038I Full problem 146 rows 137 columns, reduced to 12 rows 12 columns
Cbc0038I Mini branch and bound improved solution from -2.97518 to -4.36584 (0.02 seconds)
Cbc0038I After 0.02 seconds - Feasibility pump exiting with objective of -4.36584 - took 0.01 seconds
Cbc0012I Integer solution of -4.3658448 found by feasibility pump after 0 iterations and 0 nodes (0.02 seconds)
Cbc0001I Search completed - best objective -4.365844793151859, took 0 iterations and 0 nodes (0.02 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
Cuts at root node changed objective from -4.36584 to -4.36584
Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Result - Optimal solution found
Objective value:                4.36584479
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.02
Time (Wallclock seconds):       0.02
Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.02   (Wallclock seconds):       0.02
2024-08-29 11:58:20,145 - web_server - INFO - Status: Optimal
2024-08-29 11:58:20,145 - web_server - INFO - Total value of the Cost function = 4.37
`
davidusb-geek commented 1 month ago

Ok I will see what can be done