aioWiserHeatAPI 1.5.9__tar.gz → 1.5.11__tar.gz

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.
Files changed (52) hide show
  1. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/PKG-INFO +11 -2
  2. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/README.md +10 -1
  3. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/__init__.py +1 -1
  4. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/const.py +1 -0
  5. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/exceptions.py +4 -0
  6. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/rest_controller.py +59 -13
  7. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/wiserhub.py +120 -93
  8. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/PKG-INFO +11 -2
  9. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/LICENSE +0 -0
  10. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/cli.py +0 -0
  11. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/devices.py +0 -0
  12. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/discovery.py +0 -0
  13. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/heating.py +0 -0
  14. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/heating_actuator.py +0 -0
  15. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/__init__.py +0 -0
  16. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/automations.py +0 -0
  17. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/battery.py +0 -0
  18. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/capabilities.py +0 -0
  19. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/cloud.py +0 -0
  20. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/device.py +0 -0
  21. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/equipment.py +0 -0
  22. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/extra_config.py +0 -0
  23. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/firmware.py +0 -0
  24. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/gps.py +0 -0
  25. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/misc.py +0 -0
  26. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/network.py +0 -0
  27. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/opentherm.py +0 -0
  28. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/signal.py +0 -0
  29. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/special_times.py +0 -0
  30. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/status.py +0 -0
  31. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/temp.py +0 -0
  32. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/helpers/zigbee.py +0 -0
  33. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/hot_water.py +0 -0
  34. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/light.py +0 -0
  35. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/moments.py +0 -0
  36. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/pte.py +0 -0
  37. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/room.py +0 -0
  38. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/roomstat.py +0 -0
  39. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/schedule.py +0 -0
  40. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/shutter.py +0 -0
  41. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/smartplug.py +0 -0
  42. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/smartvalve.py +0 -0
  43. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/smokealarm.py +0 -0
  44. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/system.py +0 -0
  45. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI/ufh.py +0 -0
  46. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/SOURCES.txt +0 -0
  47. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/dependency_links.txt +0 -0
  48. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/entry_points.txt +0 -0
  49. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/requires.txt +0 -0
  50. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/aioWiserHeatAPI.egg-info/top_level.txt +0 -0
  51. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/setup.cfg +0 -0
  52. {aioWiserHeatAPI-1.5.9 → aioWiserHeatAPI-1.5.11}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioWiserHeatAPI
3
- Version: 1.5.9
3
+ Version: 1.5.11
4
4
  Summary: An AsyncIO API for controlling the Drayton Wiser Heating system
5
5
  Home-page: https://github.com/msp1974/aioWiserHeatAPI
6
6
  Author: Mark Parker
@@ -18,7 +18,7 @@ Requires-Dist: aiohttp>=3.9.3
18
18
  Requires-Dist: aiofiles>=23.2.1
19
19
  Requires-Dist: pyyaml>=6.0.1
20
20
 
21
- # Drayton Wiser Hub API Async v1.5.8
21
+ # Drayton Wiser Hub API Async v1.5.11
22
22
 
23
23
  This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.
24
24
 
@@ -72,6 +72,15 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
72
72
 
73
73
  ## Changelog
74
74
 
75
+ ### v1.5.11
76
+
77
+ * Improve error management
78
+ * Add additional debug logging
79
+
80
+ ### v1.5.10
81
+
82
+ * Add retry routine to prevent hub response errors
83
+
75
84
  ### v1.5.9
76
85
 
77
86
  * Force schedules endpoint to use http/1.0
@@ -1,4 +1,4 @@
1
- # Drayton Wiser Hub API Async v1.5.8
1
+ # Drayton Wiser Hub API Async v1.5.11
2
2
 
3
3
  This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.
4
4
 
@@ -52,6 +52,15 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
52
52
 
53
53
  ## Changelog
54
54
 
55
+ ### v1.5.11
56
+
57
+ * Improve error management
58
+ * Add additional debug logging
59
+
60
+ ### v1.5.10
61
+
62
+ * Add retry routine to prevent hub response errors
63
+
55
64
  ### v1.5.9
56
65
 
57
66
  * Force schedules endpoint to use http/1.0
@@ -3,6 +3,6 @@ import logging
3
3
  name = "aioWiserHeatAPI"
4
4
  __all__ = ["wiserAPI", "wiserDiscovery"]
5
5
 
6
- __VERSION__ = "1.5.9"
6
+ __VERSION__ = "1.5.11"
7
7
 
8
8
  _LOGGER = logging.getLogger(__name__)
@@ -30,6 +30,7 @@ TRV_BATTERY_LEVEL_MAPPING = {
30
30
 
31
31
 
32
32
  # Other Constants
33
+ REST_RETRY_BACKOFF = [0.5, 1, 2, 3, 5]
33
34
  REST_BACKOFF_FACTOR = 1
34
35
  REST_RETRIES = 3
35
36
  REST_TIMEOUT = 10
@@ -3,6 +3,10 @@ class WiserHubConnectionError(Exception):
3
3
  pass
4
4
 
5
5
 
6
+ class WiserHubResponseError(Exception):
7
+ """Response error mainly for bad request"""
8
+
9
+
6
10
  class WiserHubAuthenticationError(Exception):
7
11
  pass
8
12
 
@@ -5,12 +5,14 @@ import enum
5
5
  import json
6
6
  import re
7
7
  from dataclasses import dataclass
8
+ from datetime import datetime
8
9
  from typing import Optional
9
10
 
10
11
  import aiohttp
11
12
 
12
13
  from . import _LOGGER
13
14
  from .const import (
15
+ REST_RETRY_BACKOFF,
14
16
  REST_TIMEOUT,
15
17
  WISERHUBDOMAIN,
16
18
  WISERHUBSCHEDULES,
@@ -20,6 +22,7 @@ from .exceptions import (
20
22
  WiserExtraConfigError,
21
23
  WiserHubAuthenticationError,
22
24
  WiserHubConnectionError,
25
+ WiserHubResponseError,
23
26
  WiserHubRESTError,
24
27
  )
25
28
  from .helpers.extra_config import _WiserExtraConfig
@@ -81,17 +84,50 @@ class _WiserRestController(object):
81
84
  url: str,
82
85
  data: dict = None,
83
86
  raise_for_endpoint_error: bool = True,
87
+ ):
88
+ """Function to retry on response errors due to inconsistant isues reading from the hub."""
89
+ http_version = aiohttp.HttpVersion11
90
+ for i in range(0, 5):
91
+ if i > 2:
92
+ http_version = aiohttp.HttpVersion10
93
+ try:
94
+ response = await self._execute_request(
95
+ action,
96
+ url,
97
+ data,
98
+ raise_for_endpoint_error,
99
+ http_version,
100
+ i + 1,
101
+ )
102
+ return response
103
+ except WiserHubResponseError as ex:
104
+ # Last 2 attempts try http 1.0
105
+ _LOGGER.debug(
106
+ "%s. Retrying in %.1fs", ex, REST_RETRY_BACKOFF[i]
107
+ )
108
+ # Backing off pause
109
+ await asyncio.sleep(REST_RETRY_BACKOFF[i])
110
+
111
+ raise WiserHubConnectionError(
112
+ f"Unable to get a valid response from the Wiser hub. "
113
+ f"{self._wiser_connection_info.host} for url {url}"
114
+ )
115
+
116
+ async def _execute_request( # noqa
117
+ self,
118
+ action: WiserRestActionEnum,
119
+ url: str,
120
+ data: dict = None,
121
+ raise_for_endpoint_error: bool = True,
122
+ http_version=aiohttp.HttpVersion11,
123
+ attempt: int = 1,
84
124
  ):
85
125
  """
86
- Send patch update to hub and raise errors if fails
126
+ Send request to hub and raise errors if fails
87
127
  param url: url of hub rest api endpoint
88
128
  param patchData: json object containing command and values to set
89
129
  return: boolean
90
130
  """
91
- if url in [WISERHUBDOMAIN]:
92
- http_version = aiohttp.HttpVersion11
93
- else:
94
- http_version = aiohttp.HttpVersion10
95
131
 
96
132
  url = url.format(
97
133
  self._wiser_connection_info.host,
@@ -101,22 +137,30 @@ class _WiserRestController(object):
101
137
  kwargs = {}
102
138
  kwargs["headers"] = {
103
139
  "SECRET": self._wiser_connection_info.secret,
104
- "Content-Type": "application/json;charset=UTF-8",
105
140
  }
106
141
 
107
- if data is not None:
142
+ # if data is not None:
143
+ if data:
108
144
  kwargs["json"] = data
145
+ kwargs["headers"].update(
146
+ {
147
+ "Content-Type": "application/json;charset=UTF-8",
148
+ }
149
+ )
109
150
  if self._timeout is not None:
110
151
  kwargs["timeout"] = self._timeout
111
152
 
112
153
  try:
154
+ _LOGGER.debug(
155
+ "URL: %s, Attempt: %i, Http: %s", url, attempt, http_version
156
+ )
113
157
  async with aiohttp.ClientSession(
114
158
  version=http_version,
115
159
  ) as session:
116
- async with getattr(session, action.value)(
117
- url,
118
- **kwargs,
160
+ async with session.request(
161
+ action.value, url, **kwargs
119
162
  ) as response:
163
+ # await asyncio.sleep(1)
120
164
  if not response.ok:
121
165
  self._process_nok_response(
122
166
  response, url, data, raise_for_endpoint_error
@@ -149,7 +193,7 @@ class _WiserRestController(object):
149
193
  f"{self._wiser_connection_info.host} for url {url}. Error is {ex}"
150
194
  ) from ex
151
195
  except aiohttp.ClientResponseError as ex:
152
- raise WiserHubConnectionError(
196
+ raise WiserHubResponseError(
153
197
  f"Response error trying to communicate with Wiser Hub "
154
198
  f"{self._wiser_connection_info.host} for url {url}. Error is {ex}"
155
199
  ) from ex
@@ -166,6 +210,8 @@ class _WiserRestController(object):
166
210
  data: dict,
167
211
  raise_for_endpoint_error: bool = True,
168
212
  ):
213
+ if response.status == 400:
214
+ _LOGGER.debug("400 error")
169
215
  if response.status == 401:
170
216
  raise WiserHubAuthenticationError(
171
217
  f"Error authenticating to Wiser Hub "
@@ -188,7 +234,7 @@ class _WiserRestController(object):
188
234
  f"Error code is: {response.status}"
189
235
  )
190
236
 
191
- async def _get_hub_data(
237
+ async def get_hub_data(
192
238
  self, url: str, raise_for_endpoint_error: bool = True
193
239
  ):
194
240
  """Get data from hub"""
@@ -198,7 +244,7 @@ class _WiserRestController(object):
198
244
  raise_for_endpoint_error=raise_for_endpoint_error,
199
245
  )
200
246
 
201
- async def _get_extra_config_data(self):
247
+ async def get_extra_config_data(self):
202
248
  # Load extra config file
203
249
 
204
250
  if self._extra_config_file:
@@ -12,13 +12,10 @@ https://github.com/asantaga/wiserheatingapi
12
12
  This API allows you to get information from and control your wiserhub.
13
13
  """
14
14
 
15
- # TODO: Keep objects and update instead of recreating on hub update
16
- # TODO: Update entity values after commend issued to get current values
17
15
  import pathlib
16
+ from datetime import datetime
18
17
  from typing import Optional
19
18
 
20
- import aiohttp
21
-
22
19
  from . import __VERSION__, _LOGGER
23
20
  from .cli import log_response_to_file
24
21
  from .const import (
@@ -56,7 +53,7 @@ from .schedule import WiserScheduleTypeEnum, _WiserScheduleCollection
56
53
  from .system import _WiserSystem
57
54
 
58
55
 
59
- class WiserAPI(object):
56
+ class WiserAPI:
60
57
  """
61
58
  Main api class to access all entities and attributes of wiser system
62
59
  """
@@ -67,12 +64,10 @@ class WiserAPI(object):
67
64
  secret: str,
68
65
  port: Optional[int] = 80,
69
66
  units: Optional[WiserUnitsEnum] = WiserUnitsEnum.metric,
70
- session: Optional[aiohttp.ClientSession] = None,
71
67
  extra_config_file: Optional[str] = None,
72
68
  enable_automations: Optional[bool] = True,
73
69
  ):
74
70
  # Connection variables
75
- self._session = session
76
71
  self._wiser_api_connection = _WiserConnectionInfo()
77
72
  self._wiser_rest_controller = None
78
73
 
@@ -123,6 +118,7 @@ class WiserAPI(object):
123
118
  )
124
119
 
125
120
  async def read_hub_data(self):
121
+ """Update data objects form the hub."""
126
122
  await self._build_objects()
127
123
 
128
124
  # Run automations
@@ -133,119 +129,150 @@ class WiserAPI(object):
133
129
  if await automations.run_automations():
134
130
  await self._build_objects()
135
131
 
136
- async def _build_objects(self):
137
- """Read all data from hub and populate objects"""
138
-
139
- # Read data from hub
140
- self._domain_data = await self._wiser_rest_controller._get_hub_data(
141
- WISERHUBDOMAIN
142
- )
143
- self._network_data = await self._wiser_rest_controller._get_hub_data(
144
- WISERHUBNETWORK
145
- )
146
- self._schedule_data = await self._wiser_rest_controller._get_hub_data(
147
- WISERHUBSCHEDULES
148
- )
132
+ async def _get_hub_data(self) -> bool:
149
133
  try:
150
- self._status_data = (
151
- await self._wiser_rest_controller._get_hub_data(WISERHUBSTATUS)
134
+ start_time = datetime.now()
135
+ self._domain_data = await self._wiser_rest_controller.get_hub_data(
136
+ WISERHUBDOMAIN
152
137
  )
153
- except WiserHubRESTError:
154
- self._status_data = {}
155
-
156
- # Set hub name on rest controller
157
- self._wiser_rest_controller._hub_name = (
158
- self._network_data.get("Station", {})
159
- .get("NetworkInterface", {})
160
- .get("HostName", "")
161
- )
162
-
163
- # load extra data
164
- self._wiser_rest_controller._extra_config_file = (
165
- self._extra_config_file
166
- )
167
- await self._wiser_rest_controller._get_extra_config_data()
138
+ self._network_data = (
139
+ await self._wiser_rest_controller.get_hub_data(WISERHUBNETWORK)
140
+ )
141
+ self._schedule_data = (
142
+ await self._wiser_rest_controller.get_hub_data(
143
+ WISERHUBSCHEDULES
144
+ )
145
+ )
146
+ try:
147
+ self._status_data = (
148
+ await self._wiser_rest_controller.get_hub_data(
149
+ WISERHUBSTATUS
150
+ )
151
+ )
152
+ except WiserHubRESTError:
153
+ self._status_data = {}
168
154
 
169
- # Only get opentherm data if connected
170
- if (
171
- self._domain_data.get("System", {}).get(
155
+ # Only get opentherm data if connected
156
+ opentherm = self._domain_data.get("System", {}).get(
172
157
  "OpenThermConnectionStatus", ""
173
158
  )
174
- == "Connected"
175
- ):
176
- self._opentherm_data = (
177
- await self._wiser_rest_controller._get_hub_data(
178
- WISERHUBOPENTHERM, False
159
+ if opentherm and opentherm == "Connected":
160
+ self._opentherm_data = (
161
+ await self._wiser_rest_controller.get_hub_data(
162
+ WISERHUBOPENTHERM, False
163
+ )
179
164
  )
165
+ except (
166
+ WiserHubConnectionError,
167
+ WiserHubAuthenticationError,
168
+ WiserHubRESTError,
169
+ ) as ex:
170
+ _LOGGER.debug("Update from Wiser hub failed. %s", ex)
171
+ raise ex
172
+ else:
173
+ # Set hub name on rest controller
174
+ self._wiser_rest_controller._hub_name = (
175
+ self._network_data.get("Station", {})
176
+ .get("NetworkInterface", {})
177
+ .get("HostName", "")
180
178
  )
181
179
 
182
- if self._domain_data != {} and self._network_data != {}:
183
- # System Object
184
- _device_data = self._domain_data.get("Device", [])
185
- self._system = _WiserSystem(
186
- self._wiser_rest_controller,
187
- self._domain_data,
188
- self._network_data,
189
- _device_data,
190
- self._opentherm_data,
180
+ _LOGGER.debug(
181
+ "Update from %s successful and took %ss",
182
+ self._wiser_rest_controller._hub_name,
183
+ (datetime.now() - start_time).total_seconds(),
191
184
  )
185
+ return True
192
186
 
193
- # Schedules Collection
194
- self._schedules = _WiserScheduleCollection(
195
- self._wiser_rest_controller,
196
- self._schedule_data,
197
- self._system.sunrise_times,
198
- self._system.sunset_times,
199
- )
187
+ async def _build_objects(self):
188
+ """Read all data from hub and populate objects"""
200
189
 
201
- # Devices Collection
202
- self._devices = _WiserDeviceCollection(
203
- self._wiser_rest_controller, self._domain_data, self._schedules
204
- )
190
+ # Read data from hub
191
+ try:
192
+ await self._get_hub_data()
205
193
 
206
- # Rooms Collection
207
- room_data = self._domain_data.get("Room", [])
208
- self._rooms = _WiserRoomCollection(
209
- self._wiser_rest_controller,
210
- room_data,
211
- self._schedules.get_by_type(WiserScheduleTypeEnum.heating),
212
- self._devices,
213
- self._enable_automations,
194
+ # load extra data
195
+ self._wiser_rest_controller._extra_config_file = (
196
+ self._extra_config_file
214
197
  )
198
+ await self._wiser_rest_controller.get_extra_config_data()
215
199
 
216
- # Hot Water
217
- if self._domain_data.get("HotWater"):
218
- schedule = self._schedules.get_by_id(
219
- WiserScheduleTypeEnum.onoff,
220
- self._domain_data.get("HotWater")[0].get("ScheduleId", 0),
200
+ if self._domain_data != {} and self._network_data != {}:
201
+ # System Object
202
+ _device_data = self._domain_data.get("Device", [])
203
+ self._system = _WiserSystem(
204
+ self._wiser_rest_controller,
205
+ self._domain_data,
206
+ self._network_data,
207
+ _device_data,
208
+ self._opentherm_data,
221
209
  )
222
- self._hotwater = _WiserHotwater(
210
+
211
+ # Schedules Collection
212
+ self._schedules = _WiserScheduleCollection(
223
213
  self._wiser_rest_controller,
224
- self._domain_data.get("HotWater", {})[0],
225
- schedule,
214
+ self._schedule_data,
215
+ self._system.sunrise_times,
216
+ self._system.sunset_times,
226
217
  )
227
218
 
228
- # Heating Channels
229
- if self._domain_data.get("HeatingChannel"):
230
- self._heating_channels = _WiserHeatingChannelCollection(
231
- self._domain_data.get("HeatingChannel"), self._rooms
219
+ # Devices Collection
220
+ self._devices = _WiserDeviceCollection(
221
+ self._wiser_rest_controller,
222
+ self._domain_data,
223
+ self._schedules,
232
224
  )
233
225
 
234
- # Moments
235
- if self._domain_data.get("Moment"):
236
- self._moments = _WiserMomentCollection(
226
+ # Rooms Collection
227
+ room_data = self._domain_data.get("Room", [])
228
+ self._rooms = _WiserRoomCollection(
237
229
  self._wiser_rest_controller,
238
- self._domain_data.get("Moment"),
230
+ room_data,
231
+ self._schedules.get_by_type(WiserScheduleTypeEnum.heating),
232
+ self._devices,
233
+ self._enable_automations,
239
234
  )
240
235
 
241
- # If gets here with no exceptions then success and return true
242
- return True
236
+ # Hot Water
237
+ if self._domain_data.get("HotWater"):
238
+ schedule = self._schedules.get_by_id(
239
+ WiserScheduleTypeEnum.onoff,
240
+ self._domain_data.get("HotWater")[0].get(
241
+ "ScheduleId", 0
242
+ ),
243
+ )
244
+ self._hotwater = _WiserHotwater(
245
+ self._wiser_rest_controller,
246
+ self._domain_data.get("HotWater", {})[0],
247
+ schedule,
248
+ )
249
+
250
+ # Heating Channels
251
+ if self._domain_data.get("HeatingChannel"):
252
+ self._heating_channels = _WiserHeatingChannelCollection(
253
+ self._domain_data.get("HeatingChannel"), self._rooms
254
+ )
255
+
256
+ # Moments
257
+ if self._domain_data.get("Moment"):
258
+ self._moments = _WiserMomentCollection(
259
+ self._wiser_rest_controller,
260
+ self._domain_data.get("Moment"),
261
+ )
243
262
 
244
- return False
263
+ # If gets here with no exceptions then success and return true
264
+ return True
265
+ except (
266
+ WiserHubConnectionError,
267
+ WiserHubAuthenticationError,
268
+ WiserHubRESTError,
269
+ ) as ex:
270
+ raise ex
245
271
 
246
272
  # API properties
247
273
  @property
248
274
  def api_parameters(self):
275
+ """Rest control api parameters."""
249
276
  return self._wiser_rest_controller._api_parameters
250
277
 
251
278
  @property
@@ -329,7 +356,7 @@ class WiserAPI(object):
329
356
 
330
357
  # Get raw json data
331
358
  if endpoint:
332
- data = self._wiser_rest_controller._get_hub_data(endpoint)
359
+ data = self._wiser_rest_controller.get_hub_data(endpoint)
333
360
  try:
334
361
  if data:
335
362
  # Write out to file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioWiserHeatAPI
3
- Version: 1.5.9
3
+ Version: 1.5.11
4
4
  Summary: An AsyncIO API for controlling the Drayton Wiser Heating system
5
5
  Home-page: https://github.com/msp1974/aioWiserHeatAPI
6
6
  Author: Mark Parker
@@ -18,7 +18,7 @@ Requires-Dist: aiohttp>=3.9.3
18
18
  Requires-Dist: aiofiles>=23.2.1
19
19
  Requires-Dist: pyyaml>=6.0.1
20
20
 
21
- # Drayton Wiser Hub API Async v1.5.8
21
+ # Drayton Wiser Hub API Async v1.5.11
22
22
 
23
23
  This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.
24
24
 
@@ -72,6 +72,15 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
72
72
 
73
73
  ## Changelog
74
74
 
75
+ ### v1.5.11
76
+
77
+ * Improve error management
78
+ * Add additional debug logging
79
+
80
+ ### v1.5.10
81
+
82
+ * Add retry routine to prevent hub response errors
83
+
75
84
  ### v1.5.9
76
85
 
77
86
  * Force schedules endpoint to use http/1.0