emhass 0.11.4__py3-none-any.whl → 0.15.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,108 @@
1
+ import asyncio
2
+ import logging
3
+
4
+ from emhass.websocket_client import AsyncWebSocketClient, ConnectionError
5
+
6
+ _global_client: AsyncWebSocketClient | None = None
7
+ _lock = asyncio.Lock()
8
+
9
+
10
+ async def _create_and_start_client(
11
+ hass_url: str, token: str, logger: logging.Logger | None
12
+ ) -> AsyncWebSocketClient:
13
+ """Helper to create and start a new WebSocket client."""
14
+ if logger:
15
+ logger.debug(f"Creating new WebSocket client for {hass_url}")
16
+ client = AsyncWebSocketClient(hass_url=hass_url, long_lived_token=token, logger=logger)
17
+ try:
18
+ await asyncio.wait_for(client.startup(), timeout=15.0)
19
+ if logger:
20
+ logger.info("WebSocket client started successfully")
21
+ return client
22
+ except TimeoutError:
23
+ if logger:
24
+ logger.error("WebSocket startup timed out")
25
+ raise ConnectionError("WebSocket startup timed out") from None
26
+ except Exception as e:
27
+ if logger:
28
+ logger.error(f"WebSocket startup failed: {e}")
29
+ raise
30
+
31
+
32
+ async def _reconnect_client(client: AsyncWebSocketClient, logger: logging.Logger | None) -> None:
33
+ """Helper to reconnect an existing WebSocket client."""
34
+ if logger:
35
+ logger.debug("WebSocket client exists but not connected, attempting reconnect")
36
+ try:
37
+ await asyncio.wait_for(client.reconnect(), timeout=15.0)
38
+ if logger:
39
+ logger.info("WebSocket client reconnected successfully")
40
+ except TimeoutError:
41
+ if logger:
42
+ logger.error("WebSocket reconnect timed out")
43
+ raise ConnectionError("WebSocket reconnect timed out") from None
44
+ except Exception as e:
45
+ if logger:
46
+ logger.error(f"WebSocket reconnect failed: {e}")
47
+ raise
48
+
49
+
50
+ async def get_websocket_client(
51
+ hass_url: str, token: str, logger: logging.Logger | None = None
52
+ ) -> AsyncWebSocketClient:
53
+ """
54
+ Get or create a global WebSocket client connection.
55
+
56
+ :param hass_url: The Home Assistant URL
57
+ :type hass_url: str
58
+ :param token: Long-lived token for authentication
59
+ :type token: str
60
+ :param logger: Logger instance for logging
61
+ :type logger: logging.Logger | None
62
+ :return: Connected AsyncWebSocketClient instance
63
+ :rtype: AsyncWebSocketClient
64
+ :raises ConnectionError: If connection cannot be established
65
+ """
66
+ global _global_client
67
+ async with _lock:
68
+ if _global_client is None:
69
+ # Logic extracted to helper
70
+ _global_client = await _create_and_start_client(hass_url, token, logger)
71
+ elif not _global_client.connected:
72
+ # Logic extracted to helper
73
+ try:
74
+ await _reconnect_client(_global_client, logger)
75
+ except Exception:
76
+ # Ensure global is reset if reconnect fails
77
+ _global_client = None
78
+ raise
79
+ elif logger:
80
+ logger.debug("Using existing connected WebSocket client")
81
+ return _global_client
82
+
83
+
84
+ async def close_global_connection():
85
+ """
86
+ Close the global WebSocket connection if it exists.
87
+ """
88
+ global _global_client
89
+
90
+ async with _lock:
91
+ if _global_client is not None:
92
+ try:
93
+ await _global_client.shutdown()
94
+ except Exception:
95
+ # Ignore errors during shutdown
96
+ pass
97
+ finally:
98
+ _global_client = None
99
+
100
+
101
+ def is_connected() -> bool:
102
+ """
103
+ Check if the global WebSocket client is connected.
104
+
105
+ :return: True if connected, False otherwise
106
+ :rtype: bool
107
+ """
108
+ return _global_client is not None and _global_client.connected
@@ -1,23 +1,41 @@
1
- config_categorie,legacy_parameter_name,parameter,list_name
1
+ config_categorie,legacy_parameter_name,parameter,list_name
2
2
  retrieve_hass_conf,freq,optimization_time_step
3
3
  retrieve_hass_conf,days_to_retrieve,historic_days_to_retrieve
4
4
  retrieve_hass_conf,var_PV,sensor_power_photovoltaics
5
+ retrieve_hass_conf,var_PV_forecast,sensor_power_photovoltaics_forecast
5
6
  retrieve_hass_conf,var_load,sensor_power_load_no_var_loads
6
7
  retrieve_hass_conf,load_negative,load_negative
7
8
  retrieve_hass_conf,set_zero_min,set_zero_min
8
9
  retrieve_hass_conf,var_replace_zero,sensor_replace_zero,list_sensor_replace_zero
9
10
  retrieve_hass_conf,var_interp,sensor_linear_interp,list_sensor_linear_interp
11
+ retrieve_hass_conf,use_influxdb,use_influxdb
12
+ retrieve_hass_conf,influxdb_host,influxdb_host
13
+ retrieve_hass_conf,influxdb_port,influxdb_port
14
+ retrieve_hass_conf,influxdb_username,influxdb_username
15
+ retrieve_hass_conf,influxdb_password,influxdb_password
16
+ retrieve_hass_conf,influxdb_database,influxdb_database
17
+ retrieve_hass_conf,influxdb_measurement,influxdb_measurement
18
+ retrieve_hass_conf,influxdb_retention_policy,influxdb_retention_policy
19
+ retrieve_hass_conf,influxdb_use_ssl,influxdb_use_ssl
20
+ retrieve_hass_conf,influxdb_verify_ssl,influxdb_verify_ssl
10
21
  retrieve_hass_conf,method_ts_round,method_ts_round
11
22
  retrieve_hass_conf,continual_publish,continual_publish
23
+ retrieve_hass_conf,use_websocket,use_websocket
12
24
  params_secrets,time_zone,time_zone
13
25
  params_secrets,lat,Latitude
14
26
  params_secrets,lon,Longitude
15
27
  params_secrets,alt,Altitude
16
28
  optim_conf,costfun,costfun
17
29
  optim_conf,logging_level,logging_level
30
+ optim_conf,set_use_pv,set_use_pv
31
+ optim_conf,set_use_adjusted_pv,set_use_adjusted_pv
32
+ optim_conf,adjusted_pv_regression_model,adjusted_pv_regression_model
33
+ optim_conf,adjusted_pv_solar_elevation_threshold,adjusted_pv_solar_elevation_threshold
34
+ optim_conf,adjusted_pv_model_max_age,adjusted_pv_model_max_age
18
35
  optim_conf,set_use_battery,set_use_battery
19
36
  optim_conf,num_def_loads,number_of_deferrable_loads
20
37
  optim_conf,P_deferrable_nom,nominal_power_of_deferrable_loads,list_nominal_power_of_deferrable_loads
38
+ optim_conf,minimum_power_of_deferrable_loads,minimum_power_of_deferrable_loads
21
39
  optim_conf,def_total_hours,operating_hours_of_each_deferrable_load,list_operating_hours_of_each_deferrable_load
22
40
  optim_conf,treat_def_as_semi_cont,treat_deferrable_load_as_semi_cont,list_treat_deferrable_load_as_semi_cont
23
41
  optim_conf,set_def_constant,set_deferrable_load_single_constant,list_set_deferrable_load_single_constant
@@ -32,6 +50,8 @@ optim_conf,prod_sell_price,photovoltaic_production_sell_price
32
50
  optim_conf,set_total_pv_sell,set_total_pv_sell
33
51
  optim_conf,lp_solver,lp_solver
34
52
  optim_conf,lp_solver_path,lp_solver_path
53
+ optim_conf,lp_solver_timeout,lp_solver_timeout
54
+ optim_conf,num_threads,num_threads
35
55
  optim_conf,set_nocharge_from_grid,set_nocharge_from_grid
36
56
  optim_conf,set_nodischarge_to_grid,set_nodischarge_to_grid
37
57
  optim_conf,set_battery_dynamic,set_battery_dynamic
@@ -40,9 +60,16 @@ optim_conf,battery_dynamic_min,battery_dynamic_min
40
60
  optim_conf,weight_battery_discharge,weight_battery_discharge
41
61
  optim_conf,weight_battery_charge,weight_battery_charge
42
62
  optim_conf,weather_forecast_method,weather_forecast_method
63
+ optim_conf,open_meteo_cache_max_age,open_meteo_cache_max_age
43
64
  optim_conf,def_start_timestep,start_timesteps_of_each_deferrable_load,list_start_timesteps_of_each_deferrable_load
44
65
  optim_conf,def_end_timestep,end_timesteps_of_each_deferrable_load,list_end_timesteps_of_each_deferrable_load
45
66
  optim_conf,list_hp_periods,load_peak_hour_periods
67
+ optim_conf,model_type,model_type
68
+ optim_conf,var_model,var_model
69
+ optim_conf,sklearn_model,sklearn_model
70
+ optim_conf,num_lags,num_lags
71
+ optim_conf,split_date_delta,split_date_delta
72
+ optim_conf,perform_backtest,perform_backtest
46
73
  plant_conf,P_from_grid_max,maximum_power_from_grid
47
74
  plant_conf,P_to_grid_max,maximum_power_to_grid
48
75
  plant_conf,module_model,pv_module_model,list_pv_module_model
@@ -52,6 +79,12 @@ plant_conf,surface_azimuth,surface_azimuth,list_surface_azimuth
52
79
  plant_conf,modules_per_string,modules_per_string,list_modules_per_string
53
80
  plant_conf,strings_per_inverter,strings_per_inverter,list_strings_per_inverter
54
81
  plant_conf,inverter_is_hybrid,inverter_is_hybrid
82
+ plant_conf,inverter_ac_output_max,inverter_ac_output_max
83
+ plant_conf,inverter_ac_input_max,inverter_ac_input_max
84
+ plant_conf,inverter_efficiency_dc_ac,inverter_efficiency_dc_ac
85
+ plant_conf,inverter_efficiency_ac_dc,inverter_efficiency_ac_dc
86
+ plant_conf,inverter_stress_cost,inverter_stress_cost
87
+ plant_conf,inverter_stress_segments,inverter_stress_segments
55
88
  plant_conf,compute_curtailment,compute_curtailment
56
89
  plant_conf,Pd_max,battery_discharge_power_max
57
90
  plant_conf,Pc_max,battery_charge_power_max
@@ -60,4 +93,6 @@ plant_conf,eta_ch,battery_charge_efficiency
60
93
  plant_conf,Enom,battery_nominal_energy_capacity
61
94
  plant_conf,SOCmin,battery_minimum_state_of_charge
62
95
  plant_conf,SOCmax,battery_maximum_state_of_charge
63
- plant_conf,SOCtarget,battery_target_state_of_charge
96
+ plant_conf,SOCtarget,battery_target_state_of_charge
97
+ plant_conf,battery_stress_cost,battery_stress_cost
98
+ plant_conf,battery_stress_segments,battery_stress_segments
Binary file
Binary file
@@ -2,52 +2,60 @@
2
2
  "logging_level": "INFO",
3
3
  "costfun": "profit",
4
4
  "optimization_time_step": 30,
5
- "historic_days_to_retrieve": 2,
5
+ "historic_days_to_retrieve": 9,
6
6
  "method_ts_round": "nearest",
7
7
  "continual_publish": false,
8
8
  "data_path": "default",
9
9
  "set_total_pv_sell": false,
10
10
  "lp_solver": "default",
11
11
  "lp_solver_path": "empty",
12
+ "lp_solver_timeout": 45,
13
+ "num_threads": 0,
12
14
  "set_nocharge_from_grid": false,
13
15
  "set_nodischarge_to_grid": true,
14
16
  "set_battery_dynamic": false,
15
17
  "battery_dynamic_max": 0.9,
16
18
  "battery_dynamic_min": -0.9,
17
- "weight_battery_discharge": 1.0,
18
- "weight_battery_charge": 1.0,
19
+ "weight_battery_discharge": 0.0,
20
+ "weight_battery_charge": 0.0,
19
21
  "sensor_power_photovoltaics": "sensor.power_photovoltaics",
22
+ "sensor_power_photovoltaics_forecast": "sensor.p_pv_forecast",
20
23
  "sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
21
- "sensor_replace_zero": [
22
- "sensor.power_photovoltaics"
23
- ],
24
+ "sensor_replace_zero": ["sensor.power_photovoltaics", "sensor.p_pv_forecast"],
24
25
  "sensor_linear_interp": [
25
26
  "sensor.power_photovoltaics",
26
27
  "sensor.power_load_no_var_loads"
27
28
  ],
29
+ "use_websocket": false,
30
+ "use_influxdb": false,
31
+ "influxdb_host": "localhost",
32
+ "influxdb_port": 8086,
33
+ "influxdb_username": "",
34
+ "influxdb_password": "",
35
+ "influxdb_database": "homeassistant",
36
+ "influxdb_measurement": "W",
37
+ "influxdb_retention_policy": "autogen",
38
+ "influxdb_use_ssl": false,
39
+ "influxdb_verify_ssl": false,
28
40
  "load_negative": false,
29
41
  "set_zero_min": true,
30
42
  "number_of_deferrable_loads": 2,
31
- "nominal_power_of_deferrable_loads": [
32
- 3000.0,
33
- 750.0
34
- ],
35
- "operating_hours_of_each_deferrable_load": [
36
- 4,
37
- 0
38
- ],
39
- "weather_forecast_method": "scrapper",
43
+ "nominal_power_of_deferrable_loads": [3000.0, 750.0],
44
+ "minimum_power_of_deferrable_loads": [0.0, 0.0],
45
+ "operating_hours_of_each_deferrable_load": [4, 0],
46
+ "weather_forecast_method": "open-meteo",
47
+ "open_meteo_cache_max_age": 30,
40
48
  "load_forecast_method": "naive",
49
+ "model_type": "load_forecast",
50
+ "var_model": "sensor.power_load_no_var_loads",
51
+ "sklearn_model": "KNeighborsRegressor",
52
+ "num_lags": 48,
53
+ "split_date_delta": "48h",
54
+ "perform_backtest": false,
41
55
  "delta_forecast_daily": 1,
42
56
  "load_cost_forecast_method": "hp_hc_periods",
43
- "start_timesteps_of_each_deferrable_load": [
44
- 0,
45
- 0
46
- ],
47
- "end_timesteps_of_each_deferrable_load": [
48
- 0,
49
- 0
50
- ],
57
+ "start_timesteps_of_each_deferrable_load": [0, 0],
58
+ "end_timesteps_of_each_deferrable_load": [0, 0],
51
59
  "load_peak_hour_periods": {
52
60
  "period_hp_1": [
53
61
  {
@@ -66,43 +74,37 @@
66
74
  }
67
75
  ]
68
76
  },
69
- "treat_deferrable_load_as_semi_cont": [
70
- true,
71
- true
72
- ],
73
- "set_deferrable_load_single_constant": [
74
- false,
75
- false
76
- ],
77
- "set_deferrable_startup_penalty": [
78
- 0.0,
79
- 0.0
80
- ],
77
+ "treat_deferrable_load_as_semi_cont": [true, true],
78
+ "set_deferrable_load_single_constant": [false, false],
79
+ "set_deferrable_startup_penalty": [0.0, 0.0],
81
80
  "load_peak_hours_cost": 0.1907,
82
81
  "load_offpeak_hours_cost": 0.1419,
83
82
  "production_price_forecast_method": "constant",
84
83
  "photovoltaic_production_sell_price": 0.1419,
85
84
  "maximum_power_from_grid": 9000,
86
85
  "maximum_power_to_grid": 9000,
86
+ "set_use_pv": false,
87
+ "set_use_adjusted_pv": false,
88
+ "adjusted_pv_regression_model": "LassoRegression",
89
+ "adjusted_pv_solar_elevation_threshold": 10,
90
+ "adjusted_pv_model_max_age": 24,
87
91
  "pv_module_model": [
88
92
  "CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M"
89
93
  ],
90
94
  "pv_inverter_model": [
91
95
  "Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_"
92
96
  ],
93
- "surface_tilt": [
94
- 30
95
- ],
96
- "surface_azimuth": [
97
- 205
98
- ],
99
- "modules_per_string": [
100
- 16
101
- ],
102
- "strings_per_inverter": [
103
- 1
104
- ],
97
+ "surface_tilt": [30],
98
+ "surface_azimuth": [205],
99
+ "modules_per_string": [16],
100
+ "strings_per_inverter": [1],
105
101
  "inverter_is_hybrid": false,
102
+ "inverter_ac_output_max": 5000,
103
+ "inverter_ac_input_max": 5000,
104
+ "inverter_efficiency_dc_ac": 1.0,
105
+ "inverter_efficiency_ac_dc": 1.0,
106
+ "inverter_stress_cost": 0.0,
107
+ "inverter_stress_segments": 10,
106
108
  "compute_curtailment": false,
107
109
  "set_use_battery": false,
108
110
  "battery_discharge_power_max": 1000,
@@ -112,5 +114,7 @@
112
114
  "battery_nominal_energy_capacity": 5000,
113
115
  "battery_minimum_state_of_charge": 0.3,
114
116
  "battery_maximum_state_of_charge": 0.9,
115
- "battery_target_state_of_charge": 0.6
116
- }
117
+ "battery_target_state_of_charge": 0.6,
118
+ "battery_stress_cost": 0.0,
119
+ "battery_stress_segments": 10
120
+ }