diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f880600..9f8b7c36 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## [0.7.1] - 2024-01-29
+### Fix
+- Patched new version wer server issues accessing correct paths
+
## [0.7.0] - 2024-01-28
### Improvement
- Added a new feature to provide operating time windows for deferrable loads. Thanks to @michaelpiron
diff --git a/docs/conf.py b/docs/conf.py
index 6b06bc42..2101526f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -22,7 +22,7 @@
author = 'David HERNANDEZ'
# The full version, including alpha/beta/rc tags
-release = '0.7.0'
+release = '0.7.1'
# -- General configuration ---------------------------------------------------
diff --git a/options.json b/options.json
index fb207379..a7c25e55 100644
--- a/options.json
+++ b/options.json
@@ -1,66 +1,57 @@
-{
- "hass_url": "empty",
+{
+ "hass_url": "empty",
"long_lived_token": "empty",
"logging_level": "INFO",
- "costfun": "profit",
- "optimization_time_step": 30,
- "historic_days_to_retrieve": 2,
+ "costfun": "profit",
+ "optimization_time_step": 30,
+ "historic_days_to_retrieve": 2,
"method_ts_round": "nearest",
"optional_solcast_api_key": "empty",
"optional_solcast_rooftop_id": "empty",
- "optional_solar_forecast_kwp": 0,
- "set_total_pv_sell": false,
- "lp_solver": "COIN_CMD",
- "lp_solver_path": "/usr/bin/cbc",
- "set_nocharge_from_grid": false,
+ "optional_solar_forecast_kwp": 0,
+ "set_total_pv_sell": false,
+ "lp_solver": "COIN_CMD",
+ "lp_solver_path": "/usr/bin/cbc",
+ "set_nocharge_from_grid": false,
"set_nodischarge_to_grid": true,
"set_battery_dynamic": false,
"battery_dynamic_max": 0.9,
"battery_dynamic_min": -0.9,
"weight_battery_discharge": 1.0,
"weight_battery_charge": 1.0,
- "sensor_power_photovoltaics": "sensor.power_photovoltaics",
- "sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
- "load_negative": false,
- "set_zero_min": true,
- "number_of_deferrable_loads": 3,
- "list_nominal_power_of_deferrable_loads": [
- {
- "nominal_power_of_deferrable_loads": 3000
- },
- {
- "nominal_power_of_deferrable_loads": 750
- },
- {
- "nominal_power_of_deferrable_loads": 2500
- }
- ],
- "list_operating_hours_of_each_deferrable_load": [
- {
- "operating_hours_of_each_deferrable_load": 4
- },
- {
- "operating_hours_of_each_deferrable_load": 0
- },
- {
- "operating_hours_of_each_deferrable_load": 5
- }
+ "sensor_power_photovoltaics": "sensor.power_photovoltaics",
+ "sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
+ "load_negative": false,
+ "set_zero_min": true,
+ "number_of_deferrable_loads": 2,
+ "list_nominal_power_of_deferrable_loads": [
+ {
+ "nominal_power_of_deferrable_loads": 3000
+ },
+ {
+ "nominal_power_of_deferrable_loads": 750
+ }
+ ],
+ "list_operating_hours_of_each_deferrable_load": [
+ {
+ "operating_hours_of_each_deferrable_load": 4
+ },
+ {
+ "operating_hours_of_each_deferrable_load": 0
+ }
],
"weather_forecast_method": "scrapper",
"time_zone": "Europe/Paris",
"Latitude": 45.83,
"Longitude": 6.86,
"Altitude": 4807.8,
- "load_forecast_method": "naive",
+ "load_forecast_method": "naive",
"delta_forecast_daily": 1,
- "load_cost_forecast_method": "hp_hc_periods",
+ "load_cost_forecast_method": "hp_hc_periods",
"list_start_timesteps_of_each_deferrable_load": [
{
"start_timesteps_of_each_deferrable_load": 0
},
- {
- "start_timesteps_of_each_deferrable_load": 0
- },
{
"start_timesteps_of_each_deferrable_load": 0
}
@@ -71,31 +62,25 @@
},
{
"end_timesteps_of_each_deferrable_load": 0
+ }
+ ],
+ "list_peak_hours_periods_start_hours": [
+ {
+ "peak_hours_periods_start_hours": "02:54"
},
{
- "end_timesteps_of_each_deferrable_load": 0
+ "peak_hours_periods_start_hours": "17:24"
}
],
- "list_peak_hours_periods_start_hours": [
- {
- "peak_hours_periods_start_hours": "02:54"
- },
- {
- "peak_hours_periods_start_hours": "17:24"
- }
- ],
- "list_peak_hours_periods_end_hours": [
- {
- "peak_hours_periods_end_hours": "15:24"
- },
- {
- "peak_hours_periods_end_hours": "20:54"
- }
- ],
- "list_treat_deferrable_load_as_semi_cont": [
+ "list_peak_hours_periods_end_hours": [
{
- "treat_deferrable_load_as_semi_cont": true
+ "peak_hours_periods_end_hours": "15:24"
},
+ {
+ "peak_hours_periods_end_hours": "20:54"
+ }
+ ],
+ "list_treat_deferrable_load_as_semi_cont": [
{
"treat_deferrable_load_as_semi_cont": true
},
@@ -107,17 +92,14 @@
{
"set_deferrable_load_single_constant": false
},
- {
- "set_deferrable_load_single_constant": false
- },
{
"set_deferrable_load_single_constant": false
}
],
- "load_peak_hours_cost": 0.1907,
- "load_offpeak_hours_cost": 0.1419,
- "production_price_forecast_method": "constant",
- "photovoltaic_production_sell_price": 0.1419,
+ "load_peak_hours_cost": 0.1907,
+ "load_offpeak_hours_cost": 0.1419,
+ "production_price_forecast_method": "constant",
+ "photovoltaic_production_sell_price": 0.1419,
"maximum_power_from_grid": 9000,
"list_pv_module_model": [
{
diff --git a/setup.py b/setup.py
index bf7c643d..240849ae 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@
setup(
name='emhass', # Required
- version='0.7.0', # Required
+ version='0.7.1', # Required
description='An Energy Management System for Home Assistant', # Optional
long_description=long_description, # Optional
long_description_content_type='text/markdown', # Optional (see note above)
diff --git a/src/emhass/utils.py b/src/emhass/utils.py
index 384e79a4..803aca12 100644
--- a/src/emhass/utils.py
+++ b/src/emhass/utils.py
@@ -503,7 +503,7 @@ def get_injection_dict(df: pd.DataFrame, plot_size: Optional[int] = 1366) -> dic
injection_dict['figure_2'] = image_path_2
injection_dict['subsubtitle1'] = '
Last run optimization results table
'
injection_dict['table1'] = table1
- injection_dict['subsubtitle2'] = 'Cost totals for latest optimization results
'
+ injection_dict['subsubtitle2'] = 'Summary table for latest optimization results
'
injection_dict['table2'] = table2
return injection_dict
@@ -555,6 +555,139 @@ def get_injection_dict_forecast_model_tune(df_pred_optim: pd.DataFrame, mlf: MLF
injection_dict['figure_0'] = image_path_0
return injection_dict
+def build_params(params: dict, params_secrets: dict, options: dict, addon: int, logger: logging.Logger) -> dict:
+ """
+ Build the main params dictionary from the loaded options.json when using the add-on.
+
+ :param params: The main params dictionary
+ :type params: dict
+ :param params_secrets: The dictionary containing the secret protected variables
+ :type params_secrets: dict
+ :param options: The load dictionary from options.json
+ :type options: dict
+ :param addon: A "bool" to select if we are using the add-on
+ :type addon: int
+ :param logger: The logger object
+ :type logger: logging.Logger
+ :return: The builded dictionary
+ :rtype: dict
+ """
+ if addon == 1:
+ # Updating variables in retrieve_hass_conf
+ params['retrieve_hass_conf']['freq'] = options.get('optimization_time_step',params['retrieve_hass_conf']['freq'])
+ params['retrieve_hass_conf']['days_to_retrieve'] = options.get('historic_days_to_retrieve',params['retrieve_hass_conf']['days_to_retrieve'])
+ params['retrieve_hass_conf']['var_PV'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_PV'])
+ params['retrieve_hass_conf']['var_load'] = options.get('sensor_power_load_no_var_loads',params['retrieve_hass_conf']['var_load'])
+ params['retrieve_hass_conf']['load_negative'] = options.get('load_negative',params['retrieve_hass_conf']['load_negative'])
+ params['retrieve_hass_conf']['set_zero_min'] = options.get('set_zero_min',params['retrieve_hass_conf']['set_zero_min'])
+ params['retrieve_hass_conf']['var_replace_zero'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_replace_zero'])
+ params['retrieve_hass_conf']['var_interp'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_PV']), options.get('sensor_power_load_no_var_loads',params['retrieve_hass_conf']['var_load'])
+ params['retrieve_hass_conf']['method_ts_round'] = options.get('method_ts_round',params['retrieve_hass_conf']['method_ts_round'])
+ # Update params Secrets if specified
+ params['params_secrets'] = params_secrets
+ params['params_secrets']['time_zone'] = options.get('time_zone',params_secrets['time_zone'])
+ params['params_secrets']['lat'] = options.get('Latitude',params_secrets['lat'])
+ params['params_secrets']['lon'] = options.get('Longitude',params_secrets['lon'])
+ params['params_secrets']['alt'] = options.get('Altitude',params_secrets['alt'])
+ # Updating variables in optim_conf
+ params['optim_conf']['set_use_battery'] = options.get('set_use_battery',params['optim_conf']['set_use_battery'])
+ params['optim_conf']['num_def_loads'] = options.get('number_of_deferrable_loads',params['optim_conf']['num_def_loads'])
+ try:
+ params['optim_conf']['P_deferrable_nom'] = [i['nominal_power_of_deferrable_loads'] for i in options.get('list_nominal_power_of_deferrable_loads')]
+ except:
+ logger.debug("no list_nominal_power_of_deferrable_loads, defaulting to config file")
+ try:
+ params['optim_conf']['def_total_hours'] = [i['operating_hours_of_each_deferrable_load'] for i in options.get('list_operating_hours_of_each_deferrable_load')]
+ except:
+ logger.debug("no list_operating_hours_of_each_deferrable_load, defaulting to config file")
+ try:
+ params['optim_conf']['treat_def_as_semi_cont'] = [i['treat_deferrable_load_as_semi_cont'] for i in options.get('list_treat_deferrable_load_as_semi_cont')]
+ except:
+ logger.debug("no list_treat_deferrable_load_as_semi_cont, defaulting to config file")
+ params['optim_conf']['weather_forecast_method'] = options.get('weather_forecast_method',params['optim_conf']['weather_forecast_method'])
+ if params['optim_conf']['weather_forecast_method'] == "solcast":
+ params['retrieve_hass_conf']['solcast_api_key'] = options.get('optional_solcast_api_key',params['retrieve_hass_conf']['solcast_api_key'])
+ params['retrieve_hass_conf']['solcast_rooftop_id'] = options.get('optional_solcast_rooftop_id',params['retrieve_hass_conf']['solcast_rooftop_id'])
+ elif params['optim_conf']['weather_forecast_method'] == "solar.forecast":
+ params['retrieve_hass_conf']['solar_forecast_kwp'] = options.get('optional_solar_forecast_kwp',params['retrieve_hass_conf']['solar_forecast_kwp'])
+ params['optim_conf']['load_forecast_method'] = options.get('load_forecast_method',params['optim_conf']['load_forecast_method'])
+ params['optim_conf']['delta_forecast'] = options.get('delta_forecast_daily',params['optim_conf']['delta_forecast'])
+ params['optim_conf']['load_cost_forecast_method'] = options.get('load_cost_forecast_method',params['optim_conf']['load_cost_forecast_method'])
+ try:
+ params['optim_conf']['set_def_constant'] = [i['set_deferrable_load_single_constant'] for i in options.get('list_set_deferrable_load_single_constant')]
+ except:
+ logger.debug("no list_set_deferrable_load_single_constant, defaulting to config file")
+ try:
+ start_hours_list = [i['peak_hours_periods_start_hours'] for i in options['list_peak_hours_periods_start_hours']]
+ end_hours_list = [i['peak_hours_periods_end_hours'] for i in options['list_peak_hours_periods_end_hours']]
+ num_peak_hours = len(start_hours_list)
+ list_hp_periods_list = [{'period_hp_'+str(i+1):[{'start':start_hours_list[i]},{'end':end_hours_list[i]}]} for i in range(num_peak_hours)]
+ params['optim_conf']['list_hp_periods'] = list_hp_periods_list
+ except:
+ logger.debug("no list_peak_hours_periods_start_hours, defaulting to config file")
+ params['optim_conf']['load_cost_hp'] = options.get('load_peak_hours_cost',params['optim_conf']['load_cost_hp'])
+ params['optim_conf']['load_cost_hc'] = options.get('load_offpeak_hours_cost', params['optim_conf']['load_cost_hc'])
+ params['optim_conf']['prod_price_forecast_method'] = options.get('production_price_forecast_method', params['optim_conf']['prod_price_forecast_method'])
+ params['optim_conf']['prod_sell_price'] = options.get('photovoltaic_production_sell_price',params['optim_conf']['prod_sell_price'])
+ params['optim_conf']['set_total_pv_sell'] = options.get('set_total_pv_sell',params['optim_conf']['set_total_pv_sell'])
+ params['optim_conf']['lp_solver'] = options.get('lp_solver',params['optim_conf']['lp_solver'])
+ params['optim_conf']['lp_solver_path'] = options.get('lp_solver_path',params['optim_conf']['lp_solver_path'])
+ params['optim_conf']['set_nocharge_from_grid'] = options.get('set_nocharge_from_grid',params['optim_conf']['set_nocharge_from_grid'])
+ params['optim_conf']['set_nodischarge_to_grid'] = options.get('set_nodischarge_to_grid',params['optim_conf']['set_nodischarge_to_grid'])
+ params['optim_conf']['set_battery_dynamic'] = options.get('set_battery_dynamic',params['optim_conf']['set_battery_dynamic'])
+ params['optim_conf']['battery_dynamic_max'] = options.get('battery_dynamic_max',params['optim_conf']['battery_dynamic_max'])
+ params['optim_conf']['battery_dynamic_min'] = options.get('battery_dynamic_min',params['optim_conf']['battery_dynamic_min'])
+ params['optim_conf']['weight_battery_discharge'] = options.get('weight_battery_discharge',params['optim_conf']['weight_battery_discharge'])
+ params['optim_conf']['weight_battery_charge'] = options.get('weight_battery_charge',params['optim_conf']['weight_battery_charge'])
+ try:
+ params['optim_conf']['def_start_timestep'] = [i['start_timesteps_of_each_deferrable_load'] for i in options.get('list_start_timesteps_of_each_deferrable_load')]
+ except:
+ logger.debug("no list_start_timesteps_of_each_deferrable_load, defaulting to config file")
+ try:
+ params['optim_conf']['def_end_timestep'] = [i['end_timesteps_of_each_deferrable_load'] for i in options.get('list_end_timesteps_of_each_deferrable_load')]
+ except:
+ logger.debug("no list_end_timesteps_of_each_deferrable_load, defaulting to config file")
+ # Updating variables in plant_con
+ params['plant_conf']['P_grid_max'] = options.get('maximum_power_from_grid',params['plant_conf']['P_grid_max'])
+ try:
+ params['plant_conf']['module_model'] = [i['pv_module_model'] for i in options.get('list_pv_module_model')]
+ except:
+ logger.debug("no list_pv_module_model, defaulting to config file")
+ try:
+ params['plant_conf']['inverter_model'] = [i['pv_inverter_model'] for i in options.get('list_pv_inverter_model')]
+ except:
+ logger.debug("no list_pv_inverter_model, defaulting to config file")
+ try:
+ params['plant_conf']['surface_tilt'] = [i['surface_tilt'] for i in options.get('list_surface_tilt')]
+ except:
+ logger.debug("no list_surface_tilt, defaulting to config file")
+ try:
+ params['plant_conf']['surface_azimuth'] = [i['surface_azimuth'] for i in options.get('list_surface_azimuth')]
+ except:
+ logger.debug("no list_surface_azimuth, defaulting to config file")
+ try:
+ params['plant_conf']['modules_per_string'] = [i['modules_per_string'] for i in options.get('list_modules_per_string')]
+ except:
+ logger.debug("no list_modules_per_string, defaulting to config file")
+ try:
+ params['plant_conf']['strings_per_inverter'] = [i['strings_per_inverter'] for i in options.get('list_strings_per_inverter')]
+ except:
+ logger.debug("no list_strings_per_inverter, defaulting to config file")
+ params['plant_conf']['Pd_max'] = options.get('battery_discharge_power_max',params['plant_conf']['Pd_max'])
+ params['plant_conf']['Pc_max'] = options.get('battery_charge_power_max',params['plant_conf']['Pc_max'])
+ params['plant_conf']['eta_disch'] = options.get('battery_discharge_efficiency',params['plant_conf']['eta_disch'])
+ params['plant_conf']['eta_ch'] = options.get('battery_charge_efficiency',params['plant_conf']['eta_ch'])
+ params['plant_conf']['Enom'] = options.get('battery_nominal_energy_capacity',params['plant_conf']['Enom'])
+ params['plant_conf']['SOCmin'] = options.get('battery_minimum_state_of_charge',params['plant_conf']['SOCmin'])
+ params['plant_conf']['SOCmax'] = options.get('battery_maximum_state_of_charge',params['plant_conf']['SOCmax'])
+ params['plant_conf']['SOCtarget'] = options.get('battery_target_state_of_charge',params['plant_conf']['SOCtarget'])
+ else:
+ params['params_secrets'] = params_secrets
+ # The params dict
+ params['passed_data'] = {'pv_power_forecast':None,'load_power_forecast':None,'load_cost_forecast':None,'prod_price_forecast':None,
+ 'prediction_horizon':None,'soc_init':None,'soc_final':None,'def_total_hours':None,'def_start_timestep':None,'def_end_timestep':None,'alpha':None,'beta':None}
+ return params
+
def get_days_list(days_to_retrieve: int) -> pd.date_range:
"""
Get list of past days from today to days_to_retrieve.
diff --git a/src/emhass/web_server.py b/src/emhass/web_server.py
index 2ea846b0..52e3051c 100644
--- a/src/emhass/web_server.py
+++ b/src/emhass/web_server.py
@@ -16,129 +16,13 @@
from emhass.command_line import perfect_forecast_optim, dayahead_forecast_optim, naive_mpc_optim
from emhass.command_line import forecast_model_fit, forecast_model_predict, forecast_model_tune
from emhass.command_line import publish_data
-from emhass.utils import get_injection_dict, get_injection_dict_forecast_model_fit, get_injection_dict_forecast_model_tune
+from emhass.utils import get_injection_dict, get_injection_dict_forecast_model_fit, \
+ get_injection_dict_forecast_model_tune, build_params
# Define the Flask instance
app = Flask(__name__)
-def build_params(params, params_secrets, options, addon):
- if addon == 1:
- # Updating variables in retrieve_hass_conf
- params['retrieve_hass_conf']['freq'] = options.get('optimization_time_step',params['retrieve_hass_conf']['freq'])
- params['retrieve_hass_conf']['days_to_retrieve'] = options.get('historic_days_to_retrieve',params['retrieve_hass_conf']['days_to_retrieve'])
- params['retrieve_hass_conf']['var_PV'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_PV'])
- params['retrieve_hass_conf']['var_load'] = options.get('sensor_power_load_no_var_loads',params['retrieve_hass_conf']['var_load'])
- params['retrieve_hass_conf']['load_negative'] = options.get('load_negative',params['retrieve_hass_conf']['load_negative'])
- params['retrieve_hass_conf']['set_zero_min'] = options.get('set_zero_min',params['retrieve_hass_conf']['set_zero_min'])
- params['retrieve_hass_conf']['var_replace_zero'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_replace_zero'])
- params['retrieve_hass_conf']['var_interp'] = options.get('sensor_power_photovoltaics',params['retrieve_hass_conf']['var_PV']), options.get('sensor_power_load_no_var_loads',params['retrieve_hass_conf']['var_load'])
- params['retrieve_hass_conf']['method_ts_round'] = options.get('method_ts_round',params['retrieve_hass_conf']['method_ts_round'])
- # Update params Secrets if specified
- params['params_secrets'] = params_secrets
- params['params_secrets']['time_zone'] = options.get('time_zone',params_secrets['time_zone'])
- params['params_secrets']['lat'] = options.get('Latitude',params_secrets['lat'])
- params['params_secrets']['lon'] = options.get('Longitude',params_secrets['lon'])
- params['params_secrets']['alt'] = options.get('Altitude',params_secrets['alt'])
- # Updating variables in optim_conf
- params['optim_conf']['set_use_battery'] = options.get('set_use_battery',params['optim_conf']['set_use_battery'])
- params['optim_conf']['num_def_loads'] = options.get('number_of_deferrable_loads',params['optim_conf']['num_def_loads'])
- try:
- params['optim_conf']['P_deferrable_nom'] = [i['nominal_power_of_deferrable_loads'] for i in options.get('list_nominal_power_of_deferrable_loads')]
- except:
- app.logger.debug("no list_nominal_power_of_deferrable_loads, defaulting to config file")
- try:
- params['optim_conf']['def_total_hours'] = [i['operating_hours_of_each_deferrable_load'] for i in options.get('list_operating_hours_of_each_deferrable_load')]
- except:
- app.logger.debug("no list_operating_hours_of_each_deferrable_load, defaulting to config file")
- try:
- params['optim_conf']['treat_def_as_semi_cont'] = [i['treat_deferrable_load_as_semi_cont'] for i in options.get('list_treat_deferrable_load_as_semi_cont')]
- except:
- app.logger.debug("no list_treat_deferrable_load_as_semi_cont, defaulting to config file")
- params['optim_conf']['weather_forecast_method'] = options.get('weather_forecast_method',params['optim_conf']['weather_forecast_method'])
- if params['optim_conf']['weather_forecast_method'] == "solcast":
- params['retrieve_hass_conf']['solcast_api_key'] = options.get('optional_solcast_api_key',params['retrieve_hass_conf']['solcast_api_key'])
- params['retrieve_hass_conf']['solcast_rooftop_id'] = options.get('optional_solcast_rooftop_id',params['retrieve_hass_conf']['solcast_rooftop_id'])
- elif params['optim_conf']['weather_forecast_method'] == "solar.forecast":
- params['retrieve_hass_conf']['solar_forecast_kwp'] = options.get('optional_solar_forecast_kwp',params['retrieve_hass_conf']['solar_forecast_kwp'])
- params['optim_conf']['load_forecast_method'] = options.get('load_forecast_method',params['optim_conf']['load_forecast_method'])
- params['optim_conf']['delta_forecast'] = options.get('delta_forecast_daily',params['optim_conf']['delta_forecast'])
- params['optim_conf']['load_cost_forecast_method'] = options.get('load_cost_forecast_method',params['optim_conf']['load_cost_forecast_method'])
- try:
- params['optim_conf']['set_def_constant'] = [i['set_deferrable_load_single_constant'] for i in options.get('list_set_deferrable_load_single_constant')]
- except:
- app.logger.debug("no list_set_deferrable_load_single_constant, defaulting to config file")
- try:
- start_hours_list = [i['peak_hours_periods_start_hours'] for i in options['list_peak_hours_periods_start_hours']]
- end_hours_list = [i['peak_hours_periods_end_hours'] for i in options['list_peak_hours_periods_end_hours']]
- num_peak_hours = len(start_hours_list)
- list_hp_periods_list = [{'period_hp_'+str(i+1):[{'start':start_hours_list[i]},{'end':end_hours_list[i]}]} for i in range(num_peak_hours)]
- params['optim_conf']['list_hp_periods'] = list_hp_periods_list
- except:
- app.logger.debug("no list_peak_hours_periods_start_hours, defaulting to config file")
- params['optim_conf']['load_cost_hp'] = options.get('load_peak_hours_cost',params['optim_conf']['load_cost_hp'])
- params['optim_conf']['load_cost_hc'] = options.get('load_offpeak_hours_cost', params['optim_conf']['load_cost_hc'])
- params['optim_conf']['prod_price_forecast_method'] = options.get('production_price_forecast_method', params['optim_conf']['prod_price_forecast_method'])
- params['optim_conf']['prod_sell_price'] = options.get('photovoltaic_production_sell_price',params['optim_conf']['prod_sell_price'])
- params['optim_conf']['set_total_pv_sell'] = options.get('set_total_pv_sell',params['optim_conf']['set_total_pv_sell'])
- params['optim_conf']['lp_solver'] = options.get('lp_solver',params['optim_conf']['lp_solver'])
- params['optim_conf']['lp_solver_path'] = options.get('lp_solver_path',params['optim_conf']['lp_solver_path'])
- params['optim_conf']['set_nocharge_from_grid'] = options.get('set_nocharge_from_grid',params['optim_conf']['set_nocharge_from_grid'])
- params['optim_conf']['set_nodischarge_to_grid'] = options.get('set_nodischarge_to_grid',params['optim_conf']['set_nodischarge_to_grid'])
- params['optim_conf']['set_battery_dynamic'] = options.get('set_battery_dynamic',params['optim_conf']['set_battery_dynamic'])
- params['optim_conf']['battery_dynamic_max'] = options.get('battery_dynamic_max',params['optim_conf']['battery_dynamic_max'])
- params['optim_conf']['battery_dynamic_min'] = options.get('battery_dynamic_min',params['optim_conf']['battery_dynamic_min'])
- params['optim_conf']['weight_battery_discharge'] = options.get('weight_battery_discharge',params['optim_conf']['weight_battery_discharge'])
- params['optim_conf']['weight_battery_charge'] = options.get('weight_battery_charge',params['optim_conf']['weight_battery_charge'])
- try:
- params['optim_conf']['def_start_timestep'] = [i['start_timesteps_of_each_deferrable_load'] for i in options.get('list_start_timesteps_of_each_deferrable_load')]
- except:
- app.logger.debug("no list_start_timesteps_of_each_deferrable_load, defaulting to config file")
- try:
- params['optim_conf']['def_end_timestep'] = [i['end_timesteps_of_each_deferrable_load'] for i in options.get('list_end_timesteps_of_each_deferrable_load')]
- except:
- app.logger.debug("no list_end_timesteps_of_each_deferrable_load, defaulting to config file")
- # Updating variables in plant_con
- params['plant_conf']['P_grid_max'] = options.get('maximum_power_from_grid',params['plant_conf']['P_grid_max'])
- try:
- params['plant_conf']['module_model'] = [i['pv_module_model'] for i in options.get('list_pv_module_model')]
- except:
- app.logger.debug("no list_pv_module_model, defaulting to config file")
- try:
- params['plant_conf']['inverter_model'] = [i['pv_inverter_model'] for i in options.get('list_pv_inverter_model')]
- except:
- app.logger.debug("no list_pv_inverter_model, defaulting to config file")
- try:
- params['plant_conf']['surface_tilt'] = [i['surface_tilt'] for i in options.get('list_surface_tilt')]
- except:
- app.logger.debug("no list_surface_tilt, defaulting to config file")
- try:
- params['plant_conf']['surface_azimuth'] = [i['surface_azimuth'] for i in options.get('list_surface_azimuth')]
- except:
- app.logger.debug("no list_surface_azimuth, defaulting to config file")
- try:
- params['plant_conf']['modules_per_string'] = [i['modules_per_string'] for i in options.get('list_modules_per_string')]
- except:
- app.logger.debug("no list_modules_per_string, defaulting to config file")
- try:
- params['plant_conf']['strings_per_inverter'] = [i['strings_per_inverter'] for i in options.get('list_strings_per_inverter')]
- except:
- app.logger.debug("no list_strings_per_inverter, defaulting to config file")
- params['plant_conf']['Pd_max'] = options.get('battery_discharge_power_max',params['plant_conf']['Pd_max'])
- params['plant_conf']['Pc_max'] = options.get('battery_charge_power_max',params['plant_conf']['Pc_max'])
- params['plant_conf']['eta_disch'] = options.get('battery_discharge_efficiency',params['plant_conf']['eta_disch'])
- params['plant_conf']['eta_ch'] = options.get('battery_charge_efficiency',params['plant_conf']['eta_ch'])
- params['plant_conf']['Enom'] = options.get('battery_nominal_energy_capacity',params['plant_conf']['Enom'])
- params['plant_conf']['SOCmin'] = options.get('battery_minimum_state_of_charge',params['plant_conf']['SOCmin'])
- params['plant_conf']['SOCmax'] = options.get('battery_maximum_state_of_charge',params['plant_conf']['SOCmax'])
- params['plant_conf']['SOCtarget'] = options.get('battery_target_state_of_charge',params['plant_conf']['SOCtarget'])
- else:
- params['params_secrets'] = params_secrets
- # The params dict
- params['passed_data'] = {'pv_power_forecast':None,'load_power_forecast':None,'load_cost_forecast':None,'prod_price_forecast':None,
- 'prediction_horizon':None,'soc_init':None,'soc_final':None,'def_total_hours':None,'def_start_timestep':None,'def_end_timestep':None,'alpha':None,'beta':None}
- return params
-
@app.route('/')
def index():
app.logger.info("EMHASS server online, serving index.html...")
@@ -332,7 +216,7 @@ def action_call(action_name):
hass_url = params_secrets['hass_url']
# Build params
- params = build_params(params, params_secrets, options, args.addon)
+ params = build_params(params, params_secrets, options, args.addon, app.logger)
with open(str(data_path / 'params.pkl'), "wb") as fid:
pickle.dump((config_path, params), fid)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index d8367c51..8b0e6949 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -221,6 +221,39 @@ def test_treat_runtimeparams_failed(self):
self.assertIsInstance(runtimeparams['load_power_forecast'], str)
self.assertIsInstance(runtimeparams['load_cost_forecast'], str)
self.assertIsInstance(runtimeparams['prod_price_forecast'], str)
+
+ def test_build_params(self):
+ config_path = root / pathlib.Path("config_emhass.yaml")
+ with open(config_path, 'r') as file:
+ config = yaml.load(file, Loader=yaml.FullLoader)
+ retrieve_hass_conf = config['retrieve_hass_conf']
+ optim_conf = config['optim_conf']
+ plant_conf = config['plant_conf']
+ params = {}
+ params['retrieve_hass_conf'] = retrieve_hass_conf
+ params['optim_conf'] = optim_conf
+ params['plant_conf'] = plant_conf
+ options_json = root / pathlib.Path("options.json")
+ # Read options info
+ with options_json.open('r') as data:
+ options = json.load(data)
+ with open(root / pathlib.Path("secrets_emhass(example).yaml"), 'r') as file:
+ params_secrets = yaml.load(file, Loader=yaml.FullLoader)
+ addon = 1
+ params = utils.build_params(params, params_secrets, options, addon, logger)
+ expected_keys = ['retrieve_hass_conf', 'params_secrets', 'optim_conf', 'plant_conf', 'passed_data']
+ for key in expected_keys:
+ self.assertTrue(key in params.keys())
+ self.assertTrue(params['params_secrets']['time_zone'] == "Europe/Paris")
+ params = {}
+ params['retrieve_hass_conf'] = retrieve_hass_conf
+ params['optim_conf'] = optim_conf
+ params['plant_conf'] = plant_conf
+ addon = 0
+ params = utils.build_params(params, params_secrets, options, addon, logger)
+ for key in expected_keys:
+ self.assertTrue(key in params.keys())
+ self.assertTrue(params['params_secrets']['time_zone'] == "Europe/Paris")
if __name__ == '__main__':
unittest.main()