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
260 stars 51 forks source link

MPC optimization KeyError: 'inverter_is_hybrid' #297

Closed martinarva closed 4 weeks ago

martinarva commented 4 weeks ago

Describe the bug Error running MPC optimization - KeyError: 'inverter_is_hybrid'

To Reproduce Steps to reproduce the behavior

Expected behavior No error

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

Home Assistant installation type

Your hardware

EMHASS installation type

Additional context Plant conf:

  plant_conf:
  P_to_grid_max: 13900
  P_from_grid_max: 13900
  module_model: # The PV module model
  - 'CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M'
  inverter_model: # The PV inverter model
  - 'Fronius_International_GmbH__Fronius_Symo_12_0_3_208_240__240V_'
  surface_tilt: # The tilt angle of your solar panels
  - 30
  surface_azimuth: # The azimuth angle of your PV installation
  - 205
  modules_per_string: # The number of modules per string
  - 16 
  strings_per_inverter: # The number of used strings per inverter
  - 2
  inverter_is_hybrid: False # Set if it is a hybrid inverter (PV+batteries) or not
  Pd_max: 12000 # If your system has a battery (set_use_battery=True), the maximum discharge power in Watts
  Pc_max: 12000 # If your system has a battery (set_use_battery=True), the maximum charge power in Watts
  eta_disch: 0.95 # If your system has a battery (set_use_battery=True), the discharge efficiency
  eta_ch: 0.95 # If your system has a battery (set_use_battery=True), the charge efficiency
  Enom: 20000 # If your system has a battery (set_use_battery=True), the total capacity of the battery stack in Wh
  SOCmin: 0.1 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
  SOCmax: 1 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
  SOCtarget: 0.2 # If your system has a battery (set_use_battery=True), the desired battery state of charge at the end of each optimization cycle

Rest command:

  naive_mpc_optim:
    url: http://192.168.1.35:5001/action/naive-mpc-optim
    method: POST
    content_type: 'application/json'
    payload: >-
      {
        "load_cost_forecast": {{
          ((state_attr('sensor.nordpool_import', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_import', 'raw_tomorrow') | map(attribute='value') | list)[now().hour:][:48]) | tojson
        }},
        "prod_price_forecast": {{
          ((state_attr('sensor.nordpool_kwh_ee_eur_99_10_0', 'raw_today') | map(attribute='value') | list  + state_attr('sensor.nordpool_kwh_ee_eur_99_10_0', 'raw_tomorrow') | map(attribute='value') | list)[now().hour:][:48]) | tojson
        }},
        "prediction_horizon": {{
          (min(48, (((state_attr('sensor.nordpool_kwh_ee_eur_99_10_0', 'raw_today')|map(attribute='value')|list + state_attr('sensor.nordpool_kwh_ee_eur_99_10_0', 'raw_tomorrow') | map(attribute='value')| list)[now().hour:][:48]|list|length)))) | tojson
        }},
        "pv_power_forecast": {{
          (([states('sensor.solcast_pv_forecast_power_now')|int(0)] + state_attr('sensor.solcast_pv_forecast_forecast_today', 'detailedHourly')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list + state_attr('sensor.solcast_pv_forecast_forecast_tomorrow', 'detailedHourly')|selectattr('period_start','gt',utcnow()) | map(attribute='pv_estimate')|map('multiply',1000)|map('int')|list) | tojson)
        }}    
      }

Logs:

2024-06-03 12:05:49,548 - web_server - INFO - Passed runtime parameters: {'load_cost_forecast': [0.2337642, 0.20594820000000003, 0.18140179999999997, 0.1716418, 0.1716784, 0.1772172, 0.2174162, 0.246074, 0.3062444, 0.3400994, 0.28909120000000005, 0.23241], 'prod_price_forecast': [0.12129, 0.09849, 0.07837, 0.07037, 0.07039999999999999, 0.07493999999999999, 0.10789, 0.13138, 0.1807, 0.20845, 0.19054000000000001, 0.14407999999999999], 'prediction_horizon': 12, 'pv_power_forecast': [7491, 7681, 6796, 6038, 5371, 4504, 3567, 2479, 1254, 292, 7, 0, 0, 0, 0, 0, 52, 616, 1548, 2421, 3538, 4744, 6038, 6545, 7145, 7816, 7644, 7137, 6333, 5340, 4176, 2915, 1640, 517, 15, 0]}
2024-06-03 12:05:49,548 - web_server - INFO -  >> Setting input data dict
2024-06-03 12:05:49,549 - web_server - INFO - Setting up needed data
2024-06-03 12:05:49,560 - web_server - INFO - Retrieve hass get data method initiated...
2024-06-03 12:05:50,168 - web_server - INFO - Retrieving weather forecast data using method = list
2024-06-03 12:05:50,169 - web_server - INFO - Retrieving data from hass for load forecast using method = mlforecaster
2024-06-03 12:05:50,170 - web_server - INFO - Retrieve hass get data method initiated...
2024-06-03 12:05:51,037 - web_server - INFO -  >> Performing naive MPC optimization...
2024-06-03 12:05:51,037 - web_server - INFO - Performing naive MPC optimization
2024-06-03 12:05:51,048 - web_server - INFO - Perform an iteration of a naive MPC controller
2024-06-03 12:05:51,050 - 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 157, 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 398, in naive_mpc_optim
    opt_res_naive_mpc = input_data_dict["opt"].perform_naive_mpc_optim(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/optimization.py", line 808, in perform_naive_mpc_optim
    self.opt_res = self.perform_optimization(df_input_data, P_PV.values.ravel(), P_load.values.ravel(),
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/emhass/optimization.py", line 215, in perform_optimization
    if self.plant_conf['inverter_is_hybrid']:
       ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'inverter_is_hybrid'
davidusb-geek commented 4 weeks ago

Is your configuration file well indented? Like this:

plant_conf:
  P_from_grid_max: 9000 # The maximum power that can be supplied by the utility grid in Watts
  P_to_grid_max: 9000 # The maximum power that can be supplied to the utility grid in Watts
  module_model: # The PV module model
  - 'CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M'
  inverter_model: # The PV inverter model
  - 'Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_'
  surface_tilt: # The tilt angle of your solar panels
  - 30
  surface_azimuth: # The azimuth angle of your PV installation
  - 205
  modules_per_string: # The number of modules per string
  - 16 
  strings_per_inverter: # The number of used strings per inverter
  - 1
  inverter_is_hybrid: False # Set if it is a hybrid inverter (PV+batteries) or not
davidusb-geek commented 4 weeks ago

And how are you passing your config to the docker run command?

martinarva commented 4 weeks ago

It was a trivial probem. Command + S did now save in Visual Studio, so changes in config_emhass.yaml were not saved. Feeling stupid but it is what it is.