aioWiserHeatAPI 1.5.5__tar.gz → 1.5.7__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.5 → aioWiserHeatAPI-1.5.7}/PKG-INFO +11 -2
  2. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/README.md +10 -1
  3. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/__init__.py +1 -1
  4. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/const.py +1 -0
  5. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/devices.py +50 -13
  6. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/heating.py +4 -2
  7. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/automations.py +16 -6
  8. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/device.py +2 -0
  9. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/rest_controller.py +10 -5
  10. aioWiserHeatAPI-1.5.7/aioWiserHeatAPI/smokealarm.py +137 -0
  11. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/wiserhub.py +12 -9
  12. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/PKG-INFO +11 -2
  13. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/SOURCES.txt +1 -0
  14. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/LICENSE +0 -0
  15. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/cli.py +0 -0
  16. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/discovery.py +0 -0
  17. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/exceptions.py +0 -0
  18. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/heating_actuator.py +0 -0
  19. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/__init__.py +0 -0
  20. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/battery.py +0 -0
  21. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/capabilities.py +0 -0
  22. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/cloud.py +0 -0
  23. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/equipment.py +0 -0
  24. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/extra_config.py +0 -0
  25. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/firmware.py +0 -0
  26. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/gps.py +0 -0
  27. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/misc.py +0 -0
  28. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/network.py +0 -0
  29. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/opentherm.py +0 -0
  30. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/signal.py +0 -0
  31. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/special_times.py +0 -0
  32. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/status.py +0 -0
  33. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/temp.py +0 -0
  34. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/helpers/zigbee.py +0 -0
  35. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/hot_water.py +0 -0
  36. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/light.py +0 -0
  37. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/moments.py +0 -0
  38. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/pte.py +0 -0
  39. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/room.py +0 -0
  40. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/roomstat.py +0 -0
  41. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/schedule.py +0 -0
  42. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/shutter.py +0 -0
  43. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/smartplug.py +0 -0
  44. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/smartvalve.py +0 -0
  45. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/system.py +0 -0
  46. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI/ufh.py +0 -0
  47. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/dependency_links.txt +0 -0
  48. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/entry_points.txt +0 -0
  49. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/requires.txt +0 -0
  50. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/aioWiserHeatAPI.egg-info/top_level.txt +0 -0
  51. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/setup.cfg +0 -0
  52. {aioWiserHeatAPI-1.5.5 → aioWiserHeatAPI-1.5.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioWiserHeatAPI
3
- Version: 1.5.5
3
+ Version: 1.5.7
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.1
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.5
21
+ # Drayton Wiser Hub API Async v1.5.7
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.7
76
+
77
+ * Fixed issue whereby lower target temp for passive mode was not being set correctly
78
+ * Added support for smoke alarm
79
+
80
+ ### v1.5.6
81
+
82
+ * Added improved error handling for json decode errors
83
+
75
84
  ### v1.5.5
76
85
 
77
86
  * Added addtional v2 hub attributes and switches
@@ -1,4 +1,4 @@
1
- # Drayton Wiser Hub API Async v1.5.5
1
+ # Drayton Wiser Hub API Async v1.5.7
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.7
56
+
57
+ * Fixed issue whereby lower target temp for passive mode was not being set correctly
58
+ * Added support for smoke alarm
59
+
60
+ ### v1.5.6
61
+
62
+ * Added improved error handling for json decode errors
63
+
55
64
  ### v1.5.5
56
65
 
57
66
  * Added addtional v2 hub attributes and switches
@@ -3,6 +3,6 @@ import logging
3
3
  name = "aioWiserHeatAPI"
4
4
  __all__ = ["wiserAPI", "wiserDiscovery"]
5
5
 
6
- __VERSION__ = "1.5.5"
6
+ __VERSION__ = "1.5.7"
7
7
 
8
8
  _LOGGER = logging.getLogger(__name__)
@@ -85,6 +85,7 @@ WISERUFHCONTROLLER = "UnderFloorHeating/{}"
85
85
  WISERSHUTTER = "Shutter/{}"
86
86
  WISERLIGHT = "Light/{}"
87
87
  WISERPOWERTAGENERGY = "PTE/{}"
88
+ WISERSMOKEALARM = "SmokeAlarmDevice/{}"
88
89
 
89
90
 
90
91
  # Enums
@@ -13,9 +13,13 @@ from .const import (
13
13
  WISERSHUTTER,
14
14
  WISERSMARTPLUG,
15
15
  WISERSMARTVALVE,
16
+ WISERSMOKEALARM,
16
17
  WISERUFHCONTROLLER,
17
18
  )
18
- from .heating_actuator import _WiserHeatingActuator, _WiserHeatingActuatorCollection
19
+ from .heating_actuator import (
20
+ _WiserHeatingActuator,
21
+ _WiserHeatingActuatorCollection,
22
+ )
19
23
  from .light import _WiserDimmableLight, _WiserLight, _WiserLightCollection
20
24
  from .pte import _WiserPowerTagEnergy, _WiserPowerTagEnergyCollection
21
25
  from .rest_controller import _WiserRestController
@@ -24,6 +28,7 @@ from .schedule import WiserScheduleTypeEnum, _WiserScheduleCollection
24
28
  from .shutter import _WiserShutter, _WiserShutterCollection
25
29
  from .smartplug import _WiserSmartPlug, _WiserSmartPlugCollection
26
30
  from .smartvalve import _WiserSmartValve, _WiserSmartValveCollection
31
+ from .smokealarm import _WiserSmokeAlarm, _WiserSmokeAlarmCollection
27
32
  from .ufh import _WiserUFHController, _WiserUFHControllerCollection
28
33
 
29
34
 
@@ -37,6 +42,7 @@ class _WiserDeviceTypeEnum(enum.Enum):
37
42
  OnOffLight = "Light"
38
43
  DimmableLight = "Light"
39
44
  PowerTagE = "PTE"
45
+ SmokeAlarmDevice = "SmokeAlarmDevice"
40
46
 
41
47
 
42
48
  PRODUCT_TYPE_CONFIG = {
@@ -100,6 +106,12 @@ PRODUCT_TYPE_CONFIG = {
100
106
  "device_id_field": "DeviceId",
101
107
  "has_v2_equipment": True,
102
108
  },
109
+ "SmokeAlarmDevice": {
110
+ "class": _WiserSmokeAlarm,
111
+ "collection": _WiserSmokeAlarmCollection,
112
+ "endpoint": WISERSMOKEALARM,
113
+ "device_id_field": "DeviceId",
114
+ },
103
115
  }
104
116
 
105
117
 
@@ -115,7 +127,9 @@ class _WiserDeviceCollection:
115
127
  self._wiser_rest_controller = wiser_rest_controller
116
128
  self._device_data = domain_data.get("Device", {})
117
129
  self._domain_data = domain_data
118
- self._equipment_data = domain_data.get("Equipment", {}) # Supported by v2 hub
130
+ self._equipment_data = domain_data.get(
131
+ "Equipment", {}
132
+ ) # Supported by v2 hub
119
133
  self._schedules = schedules
120
134
  self._device_collection = {}
121
135
 
@@ -139,9 +153,9 @@ class _WiserDeviceCollection:
139
153
  device_type.value not in self._device_collection
140
154
  and device_type.name in PRODUCT_TYPE_CONFIG
141
155
  ):
142
- self._device_collection[device_type.value] = PRODUCT_TYPE_CONFIG[
143
- device_type.name
144
- ].get("collection")()
156
+ self._device_collection[
157
+ device_type.value
158
+ ] = PRODUCT_TYPE_CONFIG[device_type.name].get("collection")()
145
159
 
146
160
  # Iterate device data for all known device types
147
161
  if self._device_data:
@@ -154,16 +168,22 @@ class _WiserDeviceCollection:
154
168
  for device_info in self._domain_data.get(
155
169
  _WiserDeviceTypeEnum[device_type].value
156
170
  )
157
- if device_info.get(device_config.get("device_id_field", "id"))
171
+ if device_info.get(
172
+ device_config.get("device_id_field", "id")
173
+ )
158
174
  == device.get("id")
159
175
  ]
160
176
 
161
177
  # Get class to create and collection to append for device
162
- device_class = PRODUCT_TYPE_CONFIG[device_type].get("class")
178
+ device_class = PRODUCT_TYPE_CONFIG[device_type].get(
179
+ "class"
180
+ )
163
181
 
164
182
  # If heating device add room id
165
183
  if device_config.get("heating"):
166
- device_info[0]["RoomId"] = self._get_temp_device_room_id(
184
+ device_info[0][
185
+ "RoomId"
186
+ ] = self._get_temp_device_room_id(
167
187
  self._domain_data, device.get("id")
168
188
  )
169
189
 
@@ -181,7 +201,9 @@ class _WiserDeviceCollection:
181
201
 
182
202
  # If has equipment entry, add equipment to device info data
183
203
  if device_config.get("has_v2_equipment"):
184
- device_info[0]["EquipmentData"] = self._get_equipment_data(
204
+ device_info[0][
205
+ "EquipmentData"
206
+ ] = self._get_equipment_data(
185
207
  device_info[0].get("EquipmentId")
186
208
  )
187
209
 
@@ -198,7 +220,9 @@ class _WiserDeviceCollection:
198
220
  )
199
221
  )
200
222
 
201
- def _get_temp_device_room_id(self, domain_data: dict, device_id: int) -> int:
223
+ def _get_temp_device_room_id(
224
+ self, domain_data: dict, device_id: int
225
+ ) -> int:
202
226
  rooms = domain_data.get("Room")
203
227
  for room in rooms:
204
228
  room_device_list = []
@@ -258,6 +282,11 @@ class _WiserDeviceCollection:
258
282
  """Return all smart valves (iTRVs)"""
259
283
  return self._device_collection["SmartValve"]
260
284
 
285
+ @property
286
+ def smokealarms(self):
287
+ """Return all smoke alarms"""
288
+ return self._device_collection["SmokeAlarmDevice"]
289
+
261
290
  @property
262
291
  def ufh_controllers(self):
263
292
  """Return all UFH controllers"""
@@ -292,7 +321,9 @@ class _WiserDeviceCollection:
292
321
  return: Device type class
293
322
  """
294
323
  try:
295
- return [device for device in self.all if device.node_id == node_id][0]
324
+ return [
325
+ device for device in self.all if device.node_id == node_id
326
+ ][0]
296
327
  except IndexError:
297
328
  return None
298
329
 
@@ -304,7 +335,9 @@ class _WiserDeviceCollection:
304
335
  """
305
336
  try:
306
337
  return [
307
- device for device in self.all if device.serial_number == serial_number
338
+ device
339
+ for device in self.all
340
+ if device.serial_number == serial_number
308
341
  ][0]
309
342
  except IndexError:
310
343
  return None
@@ -316,6 +349,10 @@ class _WiserDeviceCollection:
316
349
  return: Device type class
317
350
  """
318
351
  try:
319
- return [device for device in self.all if device.parent_node_id == node_id]
352
+ return [
353
+ device
354
+ for device in self.all
355
+ if device.parent_node_id == node_id
356
+ ]
320
357
  except IndexError:
321
358
  return None
@@ -39,7 +39,7 @@ class _WiserHeatingChannel(object):
39
39
  return self._data.get("PercentageDemand", 0)
40
40
 
41
41
  @property
42
- def room_ids(self) -> list:
42
+ def room_ids(self) -> list | None:
43
43
  """Get a list of the room ids attached to this heating channel"""
44
44
  return self._data.get("RoomIds", None)
45
45
 
@@ -47,7 +47,9 @@ class _WiserHeatingChannel(object):
47
47
  class _WiserHeatingChannelCollection(object):
48
48
  """Class holding all wiser heating channel objects"""
49
49
 
50
- def __init__(self, heating_channel_data: dict, rooms: _WiserRoomCollection):
50
+ def __init__(
51
+ self, heating_channel_data: dict, rooms: _WiserRoomCollection
52
+ ):
51
53
  self._heating_channels = []
52
54
  self._heating_channel_data = heating_channel_data
53
55
  self._rooms = rooms
@@ -1,8 +1,8 @@
1
1
  import logging
2
2
 
3
- from ..rest_controller import _WiserRestController
4
3
  from ..const import WiserHeatingModeEnum
5
4
  from ..heating import _WiserHeatingChannelCollection
5
+ from ..rest_controller import _WiserRestController
6
6
 
7
7
  _LOGGER = logging.getLogger(__name__)
8
8
 
@@ -22,7 +22,9 @@ class _WiserHeatingChannelAutomations:
22
22
 
23
23
  async def passive_mode_control(self) -> bool:
24
24
  hub_updated: bool = False
25
-
25
+ passive_mode_increment = (
26
+ self._wiser_rest_controller._api_parameters.passive_mode_increment
27
+ )
26
28
  # iterate each heating channel
27
29
  for heating_channel in self._heating_channels:
28
30
  passive_rooms = [
@@ -55,12 +57,13 @@ class _WiserHeatingChannelAutomations:
55
57
  for room in passive_rooms:
56
58
  # If room is boosted do not override
57
59
  if not room.is_boosted:
58
- # Set target temp to heat passive room in increments of passive_temperature_increment (default 0.5)
60
+ # Set target temp to heat passive room in
61
+ # increments of passive_temperature_increment (default 0.5)
59
62
  target_temp = min(
60
63
  round(
61
64
  (
62
65
  room.current_temperature
63
- + self._wiser_rest_controller._api_parameters.passive_mode_increment
66
+ + passive_mode_increment
64
67
  )
65
68
  * 2
66
69
  )
@@ -72,6 +75,10 @@ class _WiserHeatingChannelAutomations:
72
75
  else room.passive_mode_upper_temp
73
76
  ),
74
77
  )
78
+
79
+ if target_temp < room.passive_mode_lower_temp:
80
+ target_temp = room.passive_mode_lower_temp
81
+
75
82
  if target_temp != room.current_target_temperature:
76
83
  _LOGGER.debug(
77
84
  f"Setting {room.name} to {target_temp}C caused by active rooms on heating channel {heating_channel.id}"
@@ -82,12 +89,15 @@ class _WiserHeatingChannelAutomations:
82
89
  # Stop any passive rooms heating by setting to min temp
83
90
  for room in passive_rooms:
84
91
  if (
85
- room.current_target_temperature > room.passive_mode_lower_temp
92
+ room.current_target_temperature
93
+ != room.passive_mode_lower_temp
86
94
  ) and not room.is_boosted:
87
95
  _LOGGER.debug(
88
96
  f"Setting {room.name} to {room.passive_mode_lower_temp}C caused by no active rooms on heating channel {heating_channel.id}"
89
97
  )
90
- await room.set_target_temperature(room.passive_mode_lower_temp)
98
+ await room.set_target_temperature(
99
+ room.passive_mode_lower_temp
100
+ )
91
101
  hub_updated = True
92
102
 
93
103
  return hub_updated
@@ -270,6 +270,8 @@ class _WiserElectricalDevice(_WiserDevice):
270
270
 
271
271
  @property
272
272
  def name(self) -> str:
273
+ if self._data.get("Name"):
274
+ return self._data.get("Name")
273
275
  return self._device_type_data.get("Name", TEXT_UNKNOWN)
274
276
 
275
277
  async def set_name(self, name: str) -> bool:
@@ -1,4 +1,5 @@
1
1
  """Module to manage rest commands of Wiser hub"""
2
+
2
3
  import asyncio
3
4
  import enum
4
5
  import json
@@ -95,14 +96,12 @@ class _WiserRestController(object):
95
96
  )
96
97
 
97
98
  kwargs = {}
98
-
99
99
  kwargs["headers"] = {
100
100
  "SECRET": self._wiser_connection_info.secret,
101
101
  "Content-Type": "application/json;charset=UTF-8",
102
102
  }
103
103
 
104
104
  if data is not None:
105
- # print(data)
106
105
  kwargs["json"] = data
107
106
  if self._timeout is not None:
108
107
  kwargs["timeout"] = self._timeout
@@ -123,9 +122,15 @@ class _WiserRestController(object):
123
122
  content = await response.read()
124
123
  if len(content) > 0:
125
124
  response = content.decode("utf-8", "ignore")
126
- return json.loads(
127
- self.remove_control_characters(response),
128
- )
125
+ try:
126
+ return json.loads(
127
+ self.remove_control_characters(response),
128
+ )
129
+ except json.decoder.JSONDecodeError as ex:
130
+ raise WiserHubRESTError(
131
+ f"""JSON decoding error from {url}. Error is - {ex}.
132
+ Data is - {content}""",
133
+ ) from ex
129
134
  else:
130
135
  return {}
131
136
  return {}
@@ -0,0 +1,137 @@
1
+ from .helpers.battery import _WiserBattery
2
+ from .helpers.device import _WiserElectricalDevice
3
+ from .helpers.temp import _WiserTemperatureFunctions as tf
4
+
5
+
6
+ class _WiserSmokeAlarm(_WiserElectricalDevice):
7
+ """Class representing a Wiser Smoke Alarm device"""
8
+
9
+ @property
10
+ def alarm_sound_level(self) -> int:
11
+ """Get the alarm sound level"""
12
+ return self._device_type_data.get("AlarmSoundLevel")
13
+
14
+ @property
15
+ def alarm_sound_mode(self) -> int:
16
+ """Get the alarm sound mode"""
17
+ return self._device_type_data.get("AlarmSoundMode")
18
+
19
+ @property
20
+ def battery(self):
21
+ """Get battery information for smoke alarm"""
22
+ return _WiserBattery(self._data)
23
+
24
+ @property
25
+ def current_temperature(self) -> float:
26
+ """Get the current temperature measured by the smoke alarm"""
27
+ return tf._from_wiser_temp(
28
+ self._device_type_data.get("MeasuredTemperature"), "current"
29
+ )
30
+
31
+ @property
32
+ def led_brightness(self) -> int:
33
+ """Get the led brightness"""
34
+ return self._device_type_data.get("LEDBrightness")
35
+
36
+ @property
37
+ def life_time(self) -> int:
38
+ """Get the life time"""
39
+ return self._device_type_data.get("LifeTime")
40
+
41
+ @property
42
+ def hush_duration(self) -> int:
43
+ """Get the hush duration"""
44
+ return self._device_type_data.get("HushDuration")
45
+
46
+ @property
47
+ def smoke_alarm(self) -> bool:
48
+ """Get if smoke alarm active"""
49
+ return self._device_type_data.get("SmokeAlarm", False)
50
+
51
+ @property
52
+ def heat_alarm(self) -> bool:
53
+ """Get if heat alarm active"""
54
+ return self._device_type_data.get("HeatAlarm", False)
55
+
56
+ @property
57
+ def tamper_alarm(self) -> bool:
58
+ """Get if tamper alarm active"""
59
+ return self._device_type_data.get("Tamper", False)
60
+
61
+ @property
62
+ def fault_warning(self) -> bool:
63
+ """Get if fault warning active"""
64
+ return self._device_type_data.get("FaultWarning", False)
65
+
66
+ @property
67
+ def ac_mains(self) -> bool:
68
+ """Get if on ac mains power"""
69
+ return self._device_type_data.get("ACMains", False)
70
+
71
+ @property
72
+ def test_mode(self) -> bool:
73
+ """Get if in test mode"""
74
+ return self._device_type_data.get("TestMode", False)
75
+
76
+ @property
77
+ def battery_defect(self) -> bool:
78
+ """Get if battery defect detected"""
79
+ return self._device_type_data.get("BatteryDefect", False)
80
+
81
+ @property
82
+ def remote_alarm(self) -> bool:
83
+ """Get if remote alarm active"""
84
+ return self._device_type_data.get("RemoteAlarm", False)
85
+
86
+ @property
87
+ def hush_mode(self) -> bool:
88
+ """Get if in hush mode"""
89
+ return self._device_type_data.get("HushMode", False)
90
+
91
+ @property
92
+ def report_count(self) -> int:
93
+ """Get the report count"""
94
+ return self._device_type_data.get("ReportCount")
95
+
96
+ @property
97
+ def notificaitions(self) -> bool:
98
+ """Get if notifications active"""
99
+ return self._device_type_data.get("EnableNotification", False)
100
+
101
+ @property
102
+ def supervision_notify(self) -> bool:
103
+ """Get if supervision notify active"""
104
+ return self._device_type_data.get("SupervisionNotify", False)
105
+
106
+ @property
107
+ def restore_notify(self) -> bool:
108
+ """Get if restore notify active"""
109
+ return self._device_type_data.get("RestoreNotify", False)
110
+
111
+
112
+ class _WiserSmokeAlarmCollection(object):
113
+ """Class holding all wiser smoke alarms"""
114
+
115
+ def __init__(self):
116
+ self._items = []
117
+
118
+ @property
119
+ def all(self) -> dict:
120
+ return list(self._items)
121
+
122
+ @property
123
+ def count(self) -> int:
124
+ return len(self.all)
125
+
126
+ def get_by_id(self, id: int) -> _WiserSmokeAlarm:
127
+ """
128
+ Gets a smoke alarm object from the smoke alarms id
129
+ param id: id of smoke alarm
130
+ return: _WiserSmokeAlarm object
131
+ """
132
+ try:
133
+ return [
134
+ smokealarm for smokealarm in self.all if smokealarm.id == id
135
+ ][0]
136
+ except IndexError:
137
+ return None
@@ -249,42 +249,42 @@ class WiserAPI(object):
249
249
  return self._wiser_rest_controller._api_parameters
250
250
 
251
251
  @property
252
- def devices(self):
252
+ def devices(self) -> _WiserDeviceCollection:
253
253
  """List of device entities attached to the Wiser Hub"""
254
254
  return self._devices
255
255
 
256
256
  @property
257
- def heating_channels(self):
257
+ def heating_channels(self) -> _WiserHeatingChannelCollection:
258
258
  """List of heating channel entities on the Wiser Hub"""
259
259
  return self._heating_channels
260
260
 
261
261
  @property
262
- def hotwater(self):
262
+ def hotwater(self) -> _WiserHotwater:
263
263
  """List of hot water entities on the Wiser Hub"""
264
264
  return self._hotwater
265
265
 
266
266
  @property
267
- def moments(self):
267
+ def moments(self) -> _WiserMomentCollection:
268
268
  """List of moment entities on the Wiser Hub"""
269
269
  return self._moments
270
270
 
271
271
  @property
272
- def rooms(self):
272
+ def rooms(self) -> _WiserRoomCollection:
273
273
  """List of room entities configured on the Wiser Hub"""
274
274
  return self._rooms
275
275
 
276
276
  @property
277
- def schedules(self):
277
+ def schedules(self) -> _WiserScheduleCollection:
278
278
  """List of schedules"""
279
279
  return self._schedules
280
280
 
281
281
  @property
282
- def status(self):
282
+ def status(self) -> WiserStatus:
283
283
  """Hub status info"""
284
284
  return WiserStatus(self._status_data)
285
285
 
286
286
  @property
287
- def system(self):
287
+ def system(self) -> _WiserSystem:
288
288
  """Entity of the Wiser Hub"""
289
289
  return self._system
290
290
 
@@ -299,15 +299,18 @@ class WiserAPI(object):
299
299
 
300
300
  @property
301
301
  def version(self):
302
+ """Return api version."""
302
303
  return __VERSION__
303
304
 
304
305
  @property
305
- def _raw_hub_data(self):
306
+ def raw_hub_data(self):
307
+ """Return raw hub data."""
306
308
  return {
307
309
  "Domain": self._domain_data,
308
310
  "Network": self._network_data,
309
311
  "Schedule": self._schedule_data,
310
312
  "OpenTherm": self._opentherm_data,
313
+ "Status": self._status_data,
311
314
  }
312
315
 
313
316
  def output_raw_hub_data(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioWiserHeatAPI
3
- Version: 1.5.5
3
+ Version: 1.5.7
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.1
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.5
21
+ # Drayton Wiser Hub API Async v1.5.7
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.7
76
+
77
+ * Fixed issue whereby lower target temp for passive mode was not being set correctly
78
+ * Added support for smoke alarm
79
+
80
+ ### v1.5.6
81
+
82
+ * Added improved error handling for json decode errors
83
+
75
84
  ### v1.5.5
76
85
 
77
86
  * Added addtional v2 hub attributes and switches
@@ -21,6 +21,7 @@ aioWiserHeatAPI/schedule.py
21
21
  aioWiserHeatAPI/shutter.py
22
22
  aioWiserHeatAPI/smartplug.py
23
23
  aioWiserHeatAPI/smartvalve.py
24
+ aioWiserHeatAPI/smokealarm.py
24
25
  aioWiserHeatAPI/system.py
25
26
  aioWiserHeatAPI/ufh.py
26
27
  aioWiserHeatAPI/wiserhub.py
File without changes