emhass 0.10.6__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
@@ -0,0 +1,98 @@
1
+ config_categorie,legacy_parameter_name,parameter,list_name
2
+ retrieve_hass_conf,freq,optimization_time_step
3
+ retrieve_hass_conf,days_to_retrieve,historic_days_to_retrieve
4
+ retrieve_hass_conf,var_PV,sensor_power_photovoltaics
5
+ retrieve_hass_conf,var_PV_forecast,sensor_power_photovoltaics_forecast
6
+ retrieve_hass_conf,var_load,sensor_power_load_no_var_loads
7
+ retrieve_hass_conf,load_negative,load_negative
8
+ retrieve_hass_conf,set_zero_min,set_zero_min
9
+ retrieve_hass_conf,var_replace_zero,sensor_replace_zero,list_sensor_replace_zero
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
21
+ retrieve_hass_conf,method_ts_round,method_ts_round
22
+ retrieve_hass_conf,continual_publish,continual_publish
23
+ retrieve_hass_conf,use_websocket,use_websocket
24
+ params_secrets,time_zone,time_zone
25
+ params_secrets,lat,Latitude
26
+ params_secrets,lon,Longitude
27
+ params_secrets,alt,Altitude
28
+ optim_conf,costfun,costfun
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
35
+ optim_conf,set_use_battery,set_use_battery
36
+ optim_conf,num_def_loads,number_of_deferrable_loads
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
39
+ optim_conf,def_total_hours,operating_hours_of_each_deferrable_load,list_operating_hours_of_each_deferrable_load
40
+ optim_conf,treat_def_as_semi_cont,treat_deferrable_load_as_semi_cont,list_treat_deferrable_load_as_semi_cont
41
+ optim_conf,set_def_constant,set_deferrable_load_single_constant,list_set_deferrable_load_single_constant
42
+ optim_conf,def_start_penalty,set_deferrable_startup_penalty,list_set_deferrable_startup_penalty
43
+ optim_conf,delta_forecast,delta_forecast_daily
44
+ optim_conf,load_forecast_method,load_forecast_method
45
+ optim_conf,load_cost_forecast_method,load_cost_forecast_method
46
+ optim_conf,load_cost_hp,load_peak_hours_cost
47
+ optim_conf,load_cost_hc,load_offpeak_hours_cost
48
+ optim_conf,prod_price_forecast_method,production_price_forecast_method
49
+ optim_conf,prod_sell_price,photovoltaic_production_sell_price
50
+ optim_conf,set_total_pv_sell,set_total_pv_sell
51
+ optim_conf,lp_solver,lp_solver
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
55
+ optim_conf,set_nocharge_from_grid,set_nocharge_from_grid
56
+ optim_conf,set_nodischarge_to_grid,set_nodischarge_to_grid
57
+ optim_conf,set_battery_dynamic,set_battery_dynamic
58
+ optim_conf,battery_dynamic_max,battery_dynamic_max
59
+ optim_conf,battery_dynamic_min,battery_dynamic_min
60
+ optim_conf,weight_battery_discharge,weight_battery_discharge
61
+ optim_conf,weight_battery_charge,weight_battery_charge
62
+ optim_conf,weather_forecast_method,weather_forecast_method
63
+ optim_conf,open_meteo_cache_max_age,open_meteo_cache_max_age
64
+ optim_conf,def_start_timestep,start_timesteps_of_each_deferrable_load,list_start_timesteps_of_each_deferrable_load
65
+ optim_conf,def_end_timestep,end_timesteps_of_each_deferrable_load,list_end_timesteps_of_each_deferrable_load
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
73
+ plant_conf,P_from_grid_max,maximum_power_from_grid
74
+ plant_conf,P_to_grid_max,maximum_power_to_grid
75
+ plant_conf,module_model,pv_module_model,list_pv_module_model
76
+ plant_conf,inverter_model,pv_inverter_model,list_pv_inverter_model
77
+ plant_conf,surface_tilt,surface_tilt,list_surface_tilt
78
+ plant_conf,surface_azimuth,surface_azimuth,list_surface_azimuth
79
+ plant_conf,modules_per_string,modules_per_string,list_modules_per_string
80
+ plant_conf,strings_per_inverter,strings_per_inverter,list_strings_per_inverter
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
88
+ plant_conf,compute_curtailment,compute_curtailment
89
+ plant_conf,Pd_max,battery_discharge_power_max
90
+ plant_conf,Pc_max,battery_charge_power_max
91
+ plant_conf,eta_disch,battery_discharge_efficiency
92
+ plant_conf,eta_ch,battery_charge_efficiency
93
+ plant_conf,Enom,battery_nominal_energy_capacity
94
+ plant_conf,SOCmin,battery_minimum_state_of_charge
95
+ plant_conf,SOCmax,battery_maximum_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
@@ -0,0 +1,120 @@
1
+ {
2
+ "logging_level": "INFO",
3
+ "costfun": "profit",
4
+ "optimization_time_step": 30,
5
+ "historic_days_to_retrieve": 9,
6
+ "method_ts_round": "nearest",
7
+ "continual_publish": false,
8
+ "data_path": "default",
9
+ "set_total_pv_sell": false,
10
+ "lp_solver": "default",
11
+ "lp_solver_path": "empty",
12
+ "lp_solver_timeout": 45,
13
+ "num_threads": 0,
14
+ "set_nocharge_from_grid": false,
15
+ "set_nodischarge_to_grid": true,
16
+ "set_battery_dynamic": false,
17
+ "battery_dynamic_max": 0.9,
18
+ "battery_dynamic_min": -0.9,
19
+ "weight_battery_discharge": 0.0,
20
+ "weight_battery_charge": 0.0,
21
+ "sensor_power_photovoltaics": "sensor.power_photovoltaics",
22
+ "sensor_power_photovoltaics_forecast": "sensor.p_pv_forecast",
23
+ "sensor_power_load_no_var_loads": "sensor.power_load_no_var_loads",
24
+ "sensor_replace_zero": ["sensor.power_photovoltaics", "sensor.p_pv_forecast"],
25
+ "sensor_linear_interp": [
26
+ "sensor.power_photovoltaics",
27
+ "sensor.power_load_no_var_loads"
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,
40
+ "load_negative": false,
41
+ "set_zero_min": true,
42
+ "number_of_deferrable_loads": 2,
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,
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,
55
+ "delta_forecast_daily": 1,
56
+ "load_cost_forecast_method": "hp_hc_periods",
57
+ "start_timesteps_of_each_deferrable_load": [0, 0],
58
+ "end_timesteps_of_each_deferrable_load": [0, 0],
59
+ "load_peak_hour_periods": {
60
+ "period_hp_1": [
61
+ {
62
+ "start": "02:54"
63
+ },
64
+ {
65
+ "end": "15:24"
66
+ }
67
+ ],
68
+ "period_hp_2": [
69
+ {
70
+ "start": "17:24"
71
+ },
72
+ {
73
+ "end": "20:24"
74
+ }
75
+ ]
76
+ },
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],
80
+ "load_peak_hours_cost": 0.1907,
81
+ "load_offpeak_hours_cost": 0.1419,
82
+ "production_price_forecast_method": "constant",
83
+ "photovoltaic_production_sell_price": 0.1419,
84
+ "maximum_power_from_grid": 9000,
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,
91
+ "pv_module_model": [
92
+ "CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M"
93
+ ],
94
+ "pv_inverter_model": [
95
+ "Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_"
96
+ ],
97
+ "surface_tilt": [30],
98
+ "surface_azimuth": [205],
99
+ "modules_per_string": [16],
100
+ "strings_per_inverter": [1],
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,
108
+ "compute_curtailment": false,
109
+ "set_use_battery": false,
110
+ "battery_discharge_power_max": 1000,
111
+ "battery_charge_power_max": 1000,
112
+ "battery_discharge_efficiency": 0.95,
113
+ "battery_charge_efficiency": 0.95,
114
+ "battery_nominal_energy_capacity": 5000,
115
+ "battery_minimum_state_of_charge": 0.3,
116
+ "battery_maximum_state_of_charge": 0.9,
117
+ "battery_target_state_of_charge": 0.6,
118
+ "battery_stress_cost": 0.0,
119
+ "battery_stress_segments": 10
120
+ }