aioWiserHeatAPI 1.5.4__tar.gz → 1.5.5__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.
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/PKG-INFO +6 -2
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/README.md +5 -1
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/__init__.py +1 -1
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/heating_actuator.py +65 -6
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/capabilities.py +8 -6
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/device.py +28 -6
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/light.py +36 -11
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/room.py +115 -24
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/shutter.py +93 -27
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/smartplug.py +3 -1
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/system.py +109 -14
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/PKG-INFO +6 -2
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/LICENSE +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/cli.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/const.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/devices.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/discovery.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/exceptions.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/heating.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/__init__.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/automations.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/battery.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/cloud.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/equipment.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/extra_config.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/firmware.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/gps.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/misc.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/network.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/opentherm.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/signal.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/special_times.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/status.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/temp.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/helpers/zigbee.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/hot_water.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/moments.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/pte.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/rest_controller.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/roomstat.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/schedule.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/smartvalve.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/ufh.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI/wiserhub.py +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/SOURCES.txt +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/dependency_links.txt +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/entry_points.txt +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/requires.txt +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/top_level.txt +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/setup.cfg +0 -0
- {aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aioWiserHeatAPI
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.5
|
|
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.
|
|
21
|
+
# Drayton Wiser Hub API Async v1.5.5
|
|
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,10 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
|
|
|
72
72
|
|
|
73
73
|
## Changelog
|
|
74
74
|
|
|
75
|
+
### v1.5.5
|
|
76
|
+
|
|
77
|
+
* Added addtional v2 hub attributes and switches
|
|
78
|
+
|
|
75
79
|
### v1.5.4
|
|
76
80
|
|
|
77
81
|
* Fixed issue whereby json conversion errors due to control characters in string
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Drayton Wiser Hub API Async v1.5.
|
|
1
|
+
# Drayton Wiser Hub API Async v1.5.5
|
|
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,10 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
|
|
|
52
52
|
|
|
53
53
|
## Changelog
|
|
54
54
|
|
|
55
|
+
### v1.5.5
|
|
56
|
+
|
|
57
|
+
* Added addtional v2 hub attributes and switches
|
|
58
|
+
|
|
55
59
|
### v1.5.4
|
|
56
60
|
|
|
57
61
|
* Fixed issue whereby json conversion errors due to control characters in string
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
from .const import
|
|
1
|
+
from .const import (
|
|
2
|
+
TEMP_OFF,
|
|
3
|
+
TEXT_UNKNOWN,
|
|
4
|
+
WISERHEATINGACTUATOR,
|
|
5
|
+
WiserTempLimitsEnum,
|
|
6
|
+
)
|
|
2
7
|
from .helpers.device import _WiserDevice
|
|
3
8
|
from .helpers.equipment import _WiserEquipment
|
|
4
9
|
from .helpers.temp import _WiserTemperatureFunctions as tf
|
|
@@ -8,7 +13,9 @@ from .rest_controller import _WiserRestController
|
|
|
8
13
|
class _WiserTemperatureSensor:
|
|
9
14
|
"""Data structure for plug in temp sensor"""
|
|
10
15
|
|
|
11
|
-
def __init__(
|
|
16
|
+
def __init__(
|
|
17
|
+
self, data: dict, wiser_rest_controller: _WiserRestController, id
|
|
18
|
+
):
|
|
12
19
|
self._data = data
|
|
13
20
|
self._id = id
|
|
14
21
|
self._wiser_rest_controller = wiser_rest_controller
|
|
@@ -45,7 +52,9 @@ class _WiserTemperatureSensor:
|
|
|
45
52
|
return await self._send_command(
|
|
46
53
|
{
|
|
47
54
|
"FloorTemperatureSensor": {
|
|
48
|
-
"MaximumTemperature": tf._to_wiser_temp(
|
|
55
|
+
"MaximumTemperature": tf._to_wiser_temp(
|
|
56
|
+
temp, "floorHeatingMax"
|
|
57
|
+
)
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
)
|
|
@@ -66,7 +75,9 @@ class _WiserTemperatureSensor:
|
|
|
66
75
|
return await self._send_command(
|
|
67
76
|
{
|
|
68
77
|
"FloorTemperatureSensor": {
|
|
69
|
-
"MinimumTemperature": tf._to_wiser_temp(
|
|
78
|
+
"MinimumTemperature": tf._to_wiser_temp(
|
|
79
|
+
temp, "floorHeatingMin"
|
|
80
|
+
)
|
|
70
81
|
}
|
|
71
82
|
}
|
|
72
83
|
)
|
|
@@ -85,7 +96,9 @@ class _WiserTemperatureSensor:
|
|
|
85
96
|
@property
|
|
86
97
|
def temperature_offset(self) -> float:
|
|
87
98
|
"""Get the temperature offset"""
|
|
88
|
-
return tf._from_wiser_temp(
|
|
99
|
+
return tf._from_wiser_temp(
|
|
100
|
+
self._data.get("Offset", None), "floorHeatingOffset"
|
|
101
|
+
)
|
|
89
102
|
|
|
90
103
|
async def set_temperature_offset(self, temp: float):
|
|
91
104
|
"""Set the temperature offset"""
|
|
@@ -116,7 +129,8 @@ class _WiserHeatingActuator(_WiserDevice):
|
|
|
116
129
|
def current_temperature(self) -> float:
|
|
117
130
|
"""Get the current measured temperature"""
|
|
118
131
|
return tf._from_wiser_temp(
|
|
119
|
-
self._device_type_data.get("MeasuredTemperature", TEMP_OFF),
|
|
132
|
+
self._device_type_data.get("MeasuredTemperature", TEMP_OFF),
|
|
133
|
+
"current",
|
|
120
134
|
)
|
|
121
135
|
|
|
122
136
|
@property
|
|
@@ -158,6 +172,51 @@ class _WiserHeatingActuator(_WiserDevice):
|
|
|
158
172
|
"""Get output type"""
|
|
159
173
|
return self._device_type_data.get("OutputType", TEXT_UNKNOWN)
|
|
160
174
|
|
|
175
|
+
# added by LGO
|
|
176
|
+
@property
|
|
177
|
+
def active_power(self) -> int:
|
|
178
|
+
"""Get active power"""
|
|
179
|
+
return self._device_type_data.get("ActivePower", 0)
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def total_active_power(self) -> int:
|
|
183
|
+
"""Get total active power"""
|
|
184
|
+
return self._device_type_data.get("TotalActivePower", 0)
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def operation_status(self) -> str:
|
|
188
|
+
"""Get Operation status"""
|
|
189
|
+
return self._device_type_data.get("OperationStatus", TEXT_UNKNOWN)
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def fault_status(self) -> str:
|
|
193
|
+
"""Get Fault status"""
|
|
194
|
+
return self._device_type_data.get("FaultStatus", TEXT_UNKNOWN)
|
|
195
|
+
|
|
196
|
+
# equipment for energy management
|
|
197
|
+
@property
|
|
198
|
+
def equipment_type(self) -> str:
|
|
199
|
+
"""Get Equipment type"""
|
|
200
|
+
return self._device_type_data.get("EquipmentType", TEXT_UNKNOWN)
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
def equipment_family(self) -> str:
|
|
204
|
+
"""Get Equipment family"""
|
|
205
|
+
return self._device_type_data.get("EquipmentFamily", TEXT_UNKNOWN)
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
def installation_type(self) -> str:
|
|
209
|
+
"""Get Installation type"""
|
|
210
|
+
return self._device_type_data.get("InstallationType", TEXT_UNKNOWN)
|
|
211
|
+
|
|
212
|
+
@property
|
|
213
|
+
def number_of_phases(self) -> int:
|
|
214
|
+
"""Get Installation type"""
|
|
215
|
+
return self._device_type_data.get("NumberOfPhases", 0)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# End added by LGO
|
|
219
|
+
|
|
161
220
|
|
|
162
221
|
class _WiserHeatingActuatorCollection(object):
|
|
163
222
|
"""Class holding all wiser heating actuators"""
|
|
@@ -177,7 +177,9 @@ class _WiserHubFeatureCapabilitiesInfo:
|
|
|
177
177
|
@property
|
|
178
178
|
def automations(self) -> _WiserHubAutomationCapabilities:
|
|
179
179
|
"""Get automation capabilities"""
|
|
180
|
-
return _WiserHubAutomationCapabilities(
|
|
180
|
+
return _WiserHubAutomationCapabilities(
|
|
181
|
+
self._data.get("Automation", {})
|
|
182
|
+
)
|
|
181
183
|
|
|
182
184
|
@property
|
|
183
185
|
def pte(self) -> _WiserHubPTECapabilities:
|
|
@@ -195,12 +197,12 @@ class _WiserClimateCapabilities(object):
|
|
|
195
197
|
@property
|
|
196
198
|
def heating_supported(self) -> bool:
|
|
197
199
|
"""Get heating supported value"""
|
|
198
|
-
return self._data.get("HeatingSupported")
|
|
200
|
+
return self._data.get("HeatingSupported", False)
|
|
199
201
|
|
|
200
202
|
@property
|
|
201
203
|
def cooling_supported(self) -> bool:
|
|
202
204
|
"""Get cooling supported value"""
|
|
203
|
-
return self._data.get("CoolingSupported")
|
|
205
|
+
return self._data.get("CoolingSupported", False)
|
|
204
206
|
|
|
205
207
|
@property
|
|
206
208
|
def minimum_heat_set_point(self) -> int:
|
|
@@ -240,18 +242,18 @@ class _WiserClimateCapabilities(object):
|
|
|
240
242
|
@property
|
|
241
243
|
def open_window_detection(self) -> bool:
|
|
242
244
|
"""Get open window detection value"""
|
|
243
|
-
return self._data.get("OpenWindowDetection")
|
|
245
|
+
return self._data.get("OpenWindowDetection", False)
|
|
244
246
|
|
|
245
247
|
@property
|
|
246
248
|
def hydronic_channel_selection(self) -> bool:
|
|
247
249
|
"""Get hydronic channel selection value"""
|
|
248
250
|
if self._data:
|
|
249
|
-
return self._data.get("HydronicChannelSelection")
|
|
251
|
+
return self._data.get("HydronicChannelSelection", False)
|
|
250
252
|
return None
|
|
251
253
|
|
|
252
254
|
@property
|
|
253
255
|
def on_off_supported(self) -> bool:
|
|
254
256
|
"""Get on off supported value"""
|
|
255
257
|
if self._data:
|
|
256
|
-
return self._data.get("OnOffSupported")
|
|
258
|
+
return self._data.get("OnOffSupported", False)
|
|
257
259
|
return None
|
|
@@ -25,6 +25,7 @@ class _WiserDevice(object):
|
|
|
25
25
|
device_type_data: dict,
|
|
26
26
|
schedule: dict = None,
|
|
27
27
|
):
|
|
28
|
+
self._away_action = None
|
|
28
29
|
self._data = data
|
|
29
30
|
self._device_type_data = device_type_data
|
|
30
31
|
self._wiser_rest_controller = wiser_rest_controller
|
|
@@ -169,6 +170,26 @@ class _WiserDevice(object):
|
|
|
169
170
|
"""Get zwave network information"""
|
|
170
171
|
return _WiserSignalStrength(self._data)
|
|
171
172
|
|
|
173
|
+
# Added by LGO
|
|
174
|
+
@property
|
|
175
|
+
def endpoint(self) -> int:
|
|
176
|
+
"""Get endpoint"""
|
|
177
|
+
return self._device_type_data.get("Endpoint", 0)
|
|
178
|
+
|
|
179
|
+
# Device type Zigbee
|
|
180
|
+
@property
|
|
181
|
+
def type_comm(self) -> str:
|
|
182
|
+
"""Get type of zigbee device"""
|
|
183
|
+
return self._data.get("Type", TEXT_UNKNOWN)
|
|
184
|
+
|
|
185
|
+
# UUID Zigbee
|
|
186
|
+
@property
|
|
187
|
+
def uuid(self) -> str:
|
|
188
|
+
"""Get UUID zigbee"""
|
|
189
|
+
return self._device_type_data.get("UUID", TEXT_UNKNOWN)
|
|
190
|
+
|
|
191
|
+
# END Added by LGO
|
|
192
|
+
|
|
172
193
|
|
|
173
194
|
class _WiserElectricalDevice(_WiserDevice):
|
|
174
195
|
"""Class representing a wiser electrical device"""
|
|
@@ -209,11 +230,11 @@ class _WiserElectricalDevice(_WiserDevice):
|
|
|
209
230
|
return self._device_type_data.get("AwayAction", TEXT_UNKNOWN)
|
|
210
231
|
|
|
211
232
|
async def set_away_mode_action(
|
|
212
|
-
self,
|
|
233
|
+
self,
|
|
234
|
+
action: Union[WiserAwayActionEnum, WiserShutterAwayActionEnum, str],
|
|
213
235
|
) -> bool:
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
or type(action) == WiserShutterAwayActionEnum
|
|
236
|
+
if isinstance(action, WiserAwayActionEnum) or isinstance(
|
|
237
|
+
action, WiserShutterAwayActionEnum
|
|
217
238
|
):
|
|
218
239
|
action = action.value
|
|
219
240
|
|
|
@@ -223,7 +244,8 @@ class _WiserElectricalDevice(_WiserDevice):
|
|
|
223
244
|
return True
|
|
224
245
|
else:
|
|
225
246
|
raise ValueError(
|
|
226
|
-
f"{action} is not a valid away mode action.
|
|
247
|
+
f"{action} is not a valid away mode action. "
|
|
248
|
+
f"Valid modes are {self.available_away_mode_actions}"
|
|
227
249
|
)
|
|
228
250
|
|
|
229
251
|
@property
|
|
@@ -237,7 +259,7 @@ class _WiserElectricalDevice(_WiserDevice):
|
|
|
237
259
|
return self._device_type_data.get("Mode", TEXT_UNKNOWN)
|
|
238
260
|
|
|
239
261
|
async def set_mode(self, mode: Union[WiserDeviceModeEnum, str]) -> bool:
|
|
240
|
-
if
|
|
262
|
+
if isinstance(mode, WiserDeviceModeEnum):
|
|
241
263
|
mode = mode.value
|
|
242
264
|
if is_value_in_list(mode, self.available_modes):
|
|
243
265
|
return await self._send_command({"Mode": mode.title()})
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from . import _LOGGER
|
|
3
2
|
|
|
4
|
-
from .
|
|
3
|
+
from . import _LOGGER
|
|
4
|
+
from .const import (
|
|
5
|
+
TEXT_OFF,
|
|
6
|
+
TEXT_ON,
|
|
7
|
+
TEXT_UNKNOWN,
|
|
8
|
+
WISERDEVICE,
|
|
9
|
+
WiserDeviceModeEnum,
|
|
10
|
+
)
|
|
5
11
|
from .helpers.device import _WiserElectricalDevice
|
|
6
12
|
|
|
7
13
|
|
|
@@ -49,7 +55,7 @@ class _WiserLight(_WiserElectricalDevice):
|
|
|
49
55
|
self._device_type_data = result
|
|
50
56
|
if result:
|
|
51
57
|
_LOGGER.debug(
|
|
52
|
-
"Wiser
|
|
58
|
+
"Wiser light - {} command successful".format(
|
|
53
59
|
inspect.stack()[1].function
|
|
54
60
|
)
|
|
55
61
|
)
|
|
@@ -69,7 +75,9 @@ class _WiserLight(_WiserElectricalDevice):
|
|
|
69
75
|
@property
|
|
70
76
|
def is_dimmable(self) -> bool:
|
|
71
77
|
"""Get if the light is dimmable"""
|
|
72
|
-
return
|
|
78
|
+
return (
|
|
79
|
+
True if self._device_type_data.get("IsDimmable", False) else False
|
|
80
|
+
)
|
|
73
81
|
|
|
74
82
|
@property
|
|
75
83
|
def is_on(self) -> bool:
|
|
@@ -91,14 +99,18 @@ class _WiserLight(_WiserElectricalDevice):
|
|
|
91
99
|
Turn on the light at current brightness level
|
|
92
100
|
return: boolean
|
|
93
101
|
"""
|
|
94
|
-
return await self._send_command(
|
|
102
|
+
return await self._send_command(
|
|
103
|
+
{"RequestOverride": {"State": TEXT_ON}}
|
|
104
|
+
)
|
|
95
105
|
|
|
96
106
|
async def turn_off(self) -> bool:
|
|
97
107
|
"""
|
|
98
108
|
Turn off the light
|
|
99
109
|
return: boolean
|
|
100
110
|
"""
|
|
101
|
-
return await self._send_command(
|
|
111
|
+
return await self._send_command(
|
|
112
|
+
{"RequestOverride": {"State": TEXT_OFF}}
|
|
113
|
+
)
|
|
102
114
|
|
|
103
115
|
|
|
104
116
|
class _WiserDimmableLight(_WiserLight):
|
|
@@ -118,10 +130,17 @@ class _WiserDimmableLight(_WiserLight):
|
|
|
118
130
|
"""Set current brightness percentage"""
|
|
119
131
|
if percentage >= 0 and percentage <= 100:
|
|
120
132
|
return await self._send_command(
|
|
121
|
-
{
|
|
133
|
+
{
|
|
134
|
+
"RequestOverride": {
|
|
135
|
+
"State": TEXT_ON,
|
|
136
|
+
"Percentage": percentage,
|
|
137
|
+
}
|
|
138
|
+
}
|
|
122
139
|
)
|
|
123
140
|
else:
|
|
124
|
-
raise ValueError(
|
|
141
|
+
raise ValueError(
|
|
142
|
+
f"Brightness level percentage must be between 0 and 100"
|
|
143
|
+
)
|
|
125
144
|
|
|
126
145
|
@property
|
|
127
146
|
def manual_level(self) -> int:
|
|
@@ -137,7 +156,9 @@ class _WiserDimmableLight(_WiserLight):
|
|
|
137
156
|
def output_range(self) -> _WiserOutputRange:
|
|
138
157
|
"""Get output range min/max."""
|
|
139
158
|
# TODO: Add setter for min max values
|
|
140
|
-
return _WiserOutputRange(
|
|
159
|
+
return _WiserOutputRange(
|
|
160
|
+
self._device_type_data.get("OutputRange", None)
|
|
161
|
+
)
|
|
141
162
|
|
|
142
163
|
@property
|
|
143
164
|
def scheduled_percentage(self) -> int:
|
|
@@ -179,7 +200,9 @@ class _WiserLightCollection(object):
|
|
|
179
200
|
@property
|
|
180
201
|
def onoff_lights(self) -> list:
|
|
181
202
|
return list(
|
|
182
|
-
onoff_lights
|
|
203
|
+
onoff_lights
|
|
204
|
+
for onoff_lights in self.all
|
|
205
|
+
if not onoff_lights.is_dimmable
|
|
183
206
|
)
|
|
184
207
|
|
|
185
208
|
def get_by_id(self, id: int) -> _WiserLight:
|
|
@@ -200,7 +223,9 @@ class _WiserLightCollection(object):
|
|
|
200
223
|
return: _WiserLight object
|
|
201
224
|
"""
|
|
202
225
|
try:
|
|
203
|
-
return [light for light in self.all if light.light_id == light_id][
|
|
226
|
+
return [light for light in self.all if light.light_id == light_id][
|
|
227
|
+
0
|
|
228
|
+
]
|
|
204
229
|
except IndexError:
|
|
205
230
|
return None
|
|
206
231
|
|
|
@@ -44,7 +44,9 @@ class _WiserRoom(object):
|
|
|
44
44
|
self._devices = devices
|
|
45
45
|
self._enable_automations = enable_automations
|
|
46
46
|
self._extra_config = (
|
|
47
|
-
self._wiser_rest_controller._extra_config.config(
|
|
47
|
+
self._wiser_rest_controller._extra_config.config(
|
|
48
|
+
"Rooms", str(self.id)
|
|
49
|
+
)
|
|
48
50
|
if self._wiser_rest_controller._extra_config
|
|
49
51
|
else None
|
|
50
52
|
)
|
|
@@ -53,7 +55,12 @@ class _WiserRoom(object):
|
|
|
53
55
|
)
|
|
54
56
|
|
|
55
57
|
self._name = room.get("Name")
|
|
56
|
-
self.
|
|
58
|
+
self._include_in_summer_comfort = room.get(
|
|
59
|
+
"IncludeInSummerComfort", False
|
|
60
|
+
)
|
|
61
|
+
self._window_detection_active = room.get(
|
|
62
|
+
"WindowDetectionActive", TEXT_UNKNOWN
|
|
63
|
+
)
|
|
57
64
|
|
|
58
65
|
self._default_extra_config = {
|
|
59
66
|
"passive_mode": False,
|
|
@@ -66,7 +73,9 @@ class _WiserRoom(object):
|
|
|
66
73
|
|
|
67
74
|
# Add device id to schedule
|
|
68
75
|
if self._schedule:
|
|
69
|
-
self.schedule._assignments.append(
|
|
76
|
+
self.schedule._assignments.append(
|
|
77
|
+
{"id": self.id, "name": self.name}
|
|
78
|
+
)
|
|
70
79
|
|
|
71
80
|
def _effective_heating_mode(self, mode: str, temp: float) -> str:
|
|
72
81
|
if mode.casefold() == TEXT_MANUAL.casefold() and temp == TEMP_OFF:
|
|
@@ -76,7 +85,9 @@ class _WiserRoom(object):
|
|
|
76
85
|
return WiserHeatingModeEnum.auto.value
|
|
77
86
|
|
|
78
87
|
async def _send_command(
|
|
79
|
-
self,
|
|
88
|
+
self,
|
|
89
|
+
cmd: dict,
|
|
90
|
+
method: WiserRestActionEnum = WiserRestActionEnum.PATCH,
|
|
80
91
|
):
|
|
81
92
|
"""
|
|
82
93
|
Send control command to the room
|
|
@@ -135,7 +146,9 @@ class _WiserRoom(object):
|
|
|
135
146
|
def passive_mode_lower_temp(self) -> float:
|
|
136
147
|
if self._extra_config and "min" in self._extra_config:
|
|
137
148
|
return min(self._extra_config["min"], self.passive_mode_upper_temp)
|
|
138
|
-
return min(
|
|
149
|
+
return min(
|
|
150
|
+
self._default_extra_config["min"], self.passive_mode_upper_temp
|
|
151
|
+
)
|
|
139
152
|
|
|
140
153
|
@property
|
|
141
154
|
def passive_mode_upper_temp(self) -> float:
|
|
@@ -155,10 +168,14 @@ class _WiserRoom(object):
|
|
|
155
168
|
if not self.is_away_mode:
|
|
156
169
|
# Set to min of temp range when initialised
|
|
157
170
|
if enable and self.mode != WiserHeatingModeEnum.off.value:
|
|
158
|
-
await self.set_target_temperature(
|
|
171
|
+
await self.set_target_temperature(
|
|
172
|
+
self.passive_mode_lower_temp
|
|
173
|
+
)
|
|
159
174
|
|
|
160
175
|
# Set target temp back to last manual temp if in manual mode
|
|
161
|
-
if (
|
|
176
|
+
if (
|
|
177
|
+
not enable
|
|
178
|
+
) and self.mode == WiserHeatingModeEnum.manual.value:
|
|
162
179
|
await self.set_target_temperature(
|
|
163
180
|
self.stored_manual_target_temperature
|
|
164
181
|
)
|
|
@@ -206,7 +223,9 @@ class _WiserRoom(object):
|
|
|
206
223
|
"""Get boost end timestamp"""
|
|
207
224
|
if self._data.get("OverrideTimeoutUnixTime", 0) == 0:
|
|
208
225
|
return None
|
|
209
|
-
return datetime.fromtimestamp(
|
|
226
|
+
return datetime.fromtimestamp(
|
|
227
|
+
self._data.get("OverrideTimeoutUnixTime", 0)
|
|
228
|
+
)
|
|
210
229
|
|
|
211
230
|
@property
|
|
212
231
|
def boost_time_remaining(self) -> datetime:
|
|
@@ -242,7 +261,9 @@ class _WiserRoom(object):
|
|
|
242
261
|
@property
|
|
243
262
|
def current_target_temperature(self) -> float:
|
|
244
263
|
"""Get current target temperature for the room"""
|
|
245
|
-
return tf._from_wiser_temp(
|
|
264
|
+
return tf._from_wiser_temp(
|
|
265
|
+
self._data.get("DisplayedSetPoint", TEMP_MINIMUM)
|
|
266
|
+
)
|
|
246
267
|
|
|
247
268
|
@property
|
|
248
269
|
def current_temperature(self) -> float:
|
|
@@ -309,7 +330,8 @@ class _WiserRoom(object):
|
|
|
309
330
|
True
|
|
310
331
|
if "Away"
|
|
311
332
|
in self._data.get(
|
|
312
|
-
"SetpointOrigin",
|
|
333
|
+
"SetpointOrigin",
|
|
334
|
+
self._data.get("SetPointOrigin", TEXT_UNKNOWN),
|
|
313
335
|
)
|
|
314
336
|
else False
|
|
315
337
|
)
|
|
@@ -321,7 +343,8 @@ class _WiserRoom(object):
|
|
|
321
343
|
True
|
|
322
344
|
if "Boost"
|
|
323
345
|
in self._data.get(
|
|
324
|
-
"SetpointOrigin",
|
|
346
|
+
"SetpointOrigin",
|
|
347
|
+
self._data.get("SetPointOrigin", TEXT_UNKNOWN),
|
|
325
348
|
)
|
|
326
349
|
else False
|
|
327
350
|
)
|
|
@@ -340,13 +363,17 @@ class _WiserRoom(object):
|
|
|
340
363
|
def is_heating(self) -> bool:
|
|
341
364
|
"""Get if the room is currently heating"""
|
|
342
365
|
return (
|
|
343
|
-
True
|
|
366
|
+
True
|
|
367
|
+
if self._data.get("ControlOutputState", TEXT_OFF) == TEXT_ON
|
|
368
|
+
else False
|
|
344
369
|
)
|
|
345
370
|
|
|
346
371
|
@property
|
|
347
372
|
def manual_target_temperature(self) -> float:
|
|
348
373
|
"""Get current target temperature for manual mode"""
|
|
349
|
-
return tf._from_wiser_temp(
|
|
374
|
+
return tf._from_wiser_temp(
|
|
375
|
+
self._data.get("ManualSetPoint", TEMP_MINIMUM)
|
|
376
|
+
)
|
|
350
377
|
|
|
351
378
|
@property
|
|
352
379
|
def mode(self) -> str:
|
|
@@ -373,7 +400,9 @@ class _WiserRoom(object):
|
|
|
373
400
|
self.stored_manual_target_temperature
|
|
374
401
|
)
|
|
375
402
|
elif mode == WiserHeatingModeEnum.auto.value:
|
|
376
|
-
await self._send_command(
|
|
403
|
+
await self._send_command(
|
|
404
|
+
{"Mode": WiserHeatingModeEnum.auto.value}
|
|
405
|
+
)
|
|
377
406
|
|
|
378
407
|
self._mode = mode
|
|
379
408
|
return True
|
|
@@ -439,8 +468,8 @@ class _WiserRoom(object):
|
|
|
439
468
|
elif preset.lower().startswith(TEXT_BOOST.lower()):
|
|
440
469
|
# Lookup boost duration
|
|
441
470
|
duration = WISER_BOOST_DURATION[preset]
|
|
442
|
-
_LOGGER.
|
|
443
|
-
f"Boosting by {self._boost_temperature_delta} for {duration}"
|
|
471
|
+
_LOGGER.debug(
|
|
472
|
+
f"Boosting by {self._boost_temperature_delta}C for {duration} mins"
|
|
444
473
|
)
|
|
445
474
|
await self.boost(self._boost_temperature_delta, duration)
|
|
446
475
|
else:
|
|
@@ -466,7 +495,9 @@ class _WiserRoom(object):
|
|
|
466
495
|
@property
|
|
467
496
|
def scheduled_target_temperature(self) -> float:
|
|
468
497
|
"""Get the scheduled target temperature for the room"""
|
|
469
|
-
return tf._from_wiser_temp(
|
|
498
|
+
return tf._from_wiser_temp(
|
|
499
|
+
self._data.get("ScheduledSetPoint", TEMP_MINIMUM)
|
|
500
|
+
)
|
|
470
501
|
|
|
471
502
|
@property
|
|
472
503
|
def smartvalve_ids(self) -> list:
|
|
@@ -507,6 +538,55 @@ class _WiserRoom(object):
|
|
|
507
538
|
"""Get the id of the underfloor heating controller relay ids"""
|
|
508
539
|
return sorted(self._data.get("UfhRelayIds", []))
|
|
509
540
|
|
|
541
|
+
# Added by LGO
|
|
542
|
+
@property
|
|
543
|
+
def include_in_summer_comfort(self) -> bool:
|
|
544
|
+
"""Get the status of participate to the summer comfort"""
|
|
545
|
+
return self._data.get("IncludeInSummerComfort")
|
|
546
|
+
|
|
547
|
+
async def set_include_in_summer_comfort(self, enabled: bool):
|
|
548
|
+
"""Set the status of participate to the summer comfort"""
|
|
549
|
+
if await self._send_command({"IncludeInSummerComfort": enabled}):
|
|
550
|
+
self._include_in_summer_comfort = enabled
|
|
551
|
+
return True
|
|
552
|
+
|
|
553
|
+
@property
|
|
554
|
+
def hvac_mode(self) -> str:
|
|
555
|
+
"""Get the HVAC mode of the room"""
|
|
556
|
+
return self._data.get("HVACMode", TEXT_UNKNOWN)
|
|
557
|
+
|
|
558
|
+
@property
|
|
559
|
+
def floor_sensor_state(self) -> str:
|
|
560
|
+
"""Get the state of the floor sensor"""
|
|
561
|
+
return self._data.get("FloorSensorState", TEXT_UNKNOWN)
|
|
562
|
+
|
|
563
|
+
@property
|
|
564
|
+
def occupancy(self) -> str:
|
|
565
|
+
"""Get the occupancy of the room"""
|
|
566
|
+
return self._data.get("Occupancy", TEXT_UNKNOWN)
|
|
567
|
+
|
|
568
|
+
@property
|
|
569
|
+
def occupancy_capable(self) -> bool:
|
|
570
|
+
"""Get the occupancy of the room"""
|
|
571
|
+
return self._data.get("OccupancyCapable", False)
|
|
572
|
+
|
|
573
|
+
@property
|
|
574
|
+
def occupied_heating_set_point(self) -> int:
|
|
575
|
+
"""Get the setpoint when the room is occupied"""
|
|
576
|
+
return self._data.get("OccupiedHeatingSetPoint", 85)
|
|
577
|
+
|
|
578
|
+
@property
|
|
579
|
+
def unoccupied_heating_set_point(self) -> int:
|
|
580
|
+
"""Get the setpoint when the room is unoccupied"""
|
|
581
|
+
return self._data.get("UnoccupiedHeatingSetPoint", 65)
|
|
582
|
+
|
|
583
|
+
@property
|
|
584
|
+
def climate_demand_for_ui(self) -> int:
|
|
585
|
+
"""Get the climate demand for UI"""
|
|
586
|
+
return self._data.get("ClimateDemandForUI", 0)
|
|
587
|
+
|
|
588
|
+
# End Added by LGO
|
|
589
|
+
|
|
510
590
|
@property
|
|
511
591
|
def window_detection_active(self) -> bool:
|
|
512
592
|
"""Get or set if window detection is active"""
|
|
@@ -545,7 +625,9 @@ class _WiserRoom(object):
|
|
|
545
625
|
"RequestOverride": {
|
|
546
626
|
"Type": "Boost",
|
|
547
627
|
"DurationMinutes": duration,
|
|
548
|
-
"IncreaseSetPointBy": tf._to_wiser_temp(
|
|
628
|
+
"IncreaseSetPointBy": tf._to_wiser_temp(
|
|
629
|
+
inc_temp, "boostDelta"
|
|
630
|
+
),
|
|
549
631
|
}
|
|
550
632
|
}
|
|
551
633
|
)
|
|
@@ -592,7 +674,10 @@ class _WiserRoom(object):
|
|
|
592
674
|
return: boolean
|
|
593
675
|
"""
|
|
594
676
|
# Set manual temp in stored config
|
|
595
|
-
if
|
|
677
|
+
if (
|
|
678
|
+
self.mode == WiserHeatingModeEnum.manual.value
|
|
679
|
+
and not self.is_passive_mode
|
|
680
|
+
):
|
|
596
681
|
await self._update_extra_config("manual_temp", temp)
|
|
597
682
|
|
|
598
683
|
return await self._send_command(
|
|
@@ -621,7 +706,9 @@ class _WiserRoom(object):
|
|
|
621
706
|
return: boolean
|
|
622
707
|
"""
|
|
623
708
|
if await self.cancel_boost():
|
|
624
|
-
return await self.set_target_temperature(
|
|
709
|
+
return await self.set_target_temperature(
|
|
710
|
+
self.schedule.next.setting
|
|
711
|
+
)
|
|
625
712
|
|
|
626
713
|
async def cancel_overrides(self) -> bool:
|
|
627
714
|
"""
|
|
@@ -707,9 +794,11 @@ class _WiserRoomCollection:
|
|
|
707
794
|
return: _WiserRoom object
|
|
708
795
|
"""
|
|
709
796
|
try:
|
|
710
|
-
return [
|
|
711
|
-
|
|
712
|
-
|
|
797
|
+
return [
|
|
798
|
+
room
|
|
799
|
+
for room in self._rooms
|
|
800
|
+
if room.name.lower() == name.lower()
|
|
801
|
+
][0]
|
|
713
802
|
except IndexError:
|
|
714
803
|
return None
|
|
715
804
|
|
|
@@ -719,7 +808,9 @@ class _WiserRoomCollection:
|
|
|
719
808
|
param schedule_id: the id of the schedule
|
|
720
809
|
return: _WiserRoom object
|
|
721
810
|
"""
|
|
722
|
-
return [
|
|
811
|
+
return [
|
|
812
|
+
room for room in self._rooms if room.schedule_id == schedule_id
|
|
813
|
+
][0]
|
|
723
814
|
|
|
724
815
|
def get_by_device_id(self, device_id: int) -> _WiserRoom:
|
|
725
816
|
"""
|
|
@@ -38,6 +38,12 @@ class _WiserLiftMovementRange(object):
|
|
|
38
38
|
return self._data.get("LiftCloseTime")
|
|
39
39
|
return None
|
|
40
40
|
|
|
41
|
+
async def set_close_time(self, time: int):
|
|
42
|
+
"""Set close time"""
|
|
43
|
+
return await self._shutter_instance._send_command(
|
|
44
|
+
{"LiftOpenTime": self.open_time, "LiftCloseTime": time}
|
|
45
|
+
)
|
|
46
|
+
|
|
41
47
|
@property
|
|
42
48
|
def tilt_time(self) -> int:
|
|
43
49
|
"""Get tilt time value"""
|
|
@@ -58,7 +64,9 @@ class _WiserLiftMovementRange(object):
|
|
|
58
64
|
|
|
59
65
|
async def set_tilt_angle_closed(self, angle: int):
|
|
60
66
|
"""Set tilt angle closed"""
|
|
61
|
-
return await self._shutter_instance._send_command(
|
|
67
|
+
return await self._shutter_instance._send_command(
|
|
68
|
+
{"TiltAngleClosed": angle}
|
|
69
|
+
)
|
|
62
70
|
|
|
63
71
|
@property
|
|
64
72
|
def tilt_angle_open(self) -> int:
|
|
@@ -69,7 +77,9 @@ class _WiserLiftMovementRange(object):
|
|
|
69
77
|
|
|
70
78
|
async def set_tilt_angle_open(self, angle: int):
|
|
71
79
|
"""Set tilt angle open"""
|
|
72
|
-
return await self._shutter_instance._send_command(
|
|
80
|
+
return await self._shutter_instance._send_command(
|
|
81
|
+
{"TiltAngleOpen": angle}
|
|
82
|
+
)
|
|
73
83
|
|
|
74
84
|
@property
|
|
75
85
|
def tilt_enabled(self) -> bool:
|
|
@@ -82,12 +92,6 @@ class _WiserLiftMovementRange(object):
|
|
|
82
92
|
"""Set tilt enable"""
|
|
83
93
|
return await self._shutter_instance._send_command({"TiltEnabled": en})
|
|
84
94
|
|
|
85
|
-
async def set_close_time(self, time: int):
|
|
86
|
-
"""Set close time"""
|
|
87
|
-
return await self._shutter_instance._send_command(
|
|
88
|
-
{"LiftOpenTime": self.open_time, "LiftCloseTime": time}
|
|
89
|
-
)
|
|
90
|
-
|
|
91
95
|
|
|
92
96
|
class _WiserShutter(_WiserElectricalDevice):
|
|
93
97
|
"""Class representing a Wiser Shutter device"""
|
|
@@ -112,7 +116,7 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
112
116
|
self._device_type_data = result
|
|
113
117
|
if result:
|
|
114
118
|
_LOGGER.debug(
|
|
115
|
-
"Wiser
|
|
119
|
+
"Wiser shutter - {} command successful".format(
|
|
116
120
|
inspect.stack()[1].function
|
|
117
121
|
)
|
|
118
122
|
)
|
|
@@ -141,7 +145,9 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
141
145
|
@property
|
|
142
146
|
def drive_config(self) -> _WiserLiftMovementRange:
|
|
143
147
|
"""Get open and close time drive config"""
|
|
144
|
-
return _WiserLiftMovementRange(
|
|
148
|
+
return _WiserLiftMovementRange(
|
|
149
|
+
self, self._device_type_data.get("DriveConfig")
|
|
150
|
+
)
|
|
145
151
|
|
|
146
152
|
@property
|
|
147
153
|
def is_lift_position_supported(self) -> bool:
|
|
@@ -156,19 +162,28 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
156
162
|
@property
|
|
157
163
|
def is_open(self) -> bool:
|
|
158
164
|
"""Get if the shutter is open"""
|
|
159
|
-
return
|
|
165
|
+
return (
|
|
166
|
+
True
|
|
167
|
+
if self._device_type_data.get("CurrentLift", 0) == 100
|
|
168
|
+
else False
|
|
169
|
+
)
|
|
160
170
|
|
|
161
171
|
@property
|
|
162
172
|
def is_closed(self) -> bool:
|
|
163
173
|
"""Get if the shutter is closed"""
|
|
164
|
-
return
|
|
174
|
+
return (
|
|
175
|
+
True
|
|
176
|
+
if self._device_type_data.get("CurrentLift", 0) == 0
|
|
177
|
+
else False
|
|
178
|
+
)
|
|
165
179
|
|
|
166
180
|
@property
|
|
167
181
|
def is_closing(self) -> bool:
|
|
168
182
|
"""Get if shutter is moving-opening"""
|
|
169
183
|
return (
|
|
170
184
|
True
|
|
171
|
-
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
185
|
+
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
186
|
+
== "Closing"
|
|
172
187
|
else False
|
|
173
188
|
)
|
|
174
189
|
|
|
@@ -177,7 +192,8 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
177
192
|
"""Get if shutter is moving-opening"""
|
|
178
193
|
return (
|
|
179
194
|
True
|
|
180
|
-
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
195
|
+
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
196
|
+
== "Opening"
|
|
181
197
|
else False
|
|
182
198
|
)
|
|
183
199
|
|
|
@@ -186,7 +202,8 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
186
202
|
"""Get if shutter is not moving"""
|
|
187
203
|
return (
|
|
188
204
|
True
|
|
189
|
-
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
205
|
+
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
206
|
+
== "Stopped"
|
|
190
207
|
else False
|
|
191
208
|
)
|
|
192
209
|
|
|
@@ -195,7 +212,8 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
195
212
|
"""Get if shutter is moving"""
|
|
196
213
|
return (
|
|
197
214
|
True
|
|
198
|
-
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
215
|
+
if self._device_type_data.get("LiftMovement", TEXT_UNKNOWN)
|
|
216
|
+
!= "Stopped"
|
|
199
217
|
else False
|
|
200
218
|
)
|
|
201
219
|
|
|
@@ -239,14 +257,51 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
239
257
|
"""Get target tilt of shutter"""
|
|
240
258
|
return self._device_type_data.get("TargetTilt", 0)
|
|
241
259
|
|
|
260
|
+
@property
|
|
261
|
+
def respect_summer_comfort(self) -> bool:
|
|
262
|
+
"""Get if the shutter respect summer comfort"""
|
|
263
|
+
return self._device_type_data.get("RespectSummerComfort", False)
|
|
264
|
+
|
|
265
|
+
async def set_respect_summer_comfort(self, en: bool):
|
|
266
|
+
"""Set respect summer comfort"""
|
|
267
|
+
if await self._send_command({"RespectSummerComfort": en}):
|
|
268
|
+
return True
|
|
269
|
+
|
|
270
|
+
@property
|
|
271
|
+
def summer_comfort_lift(self) -> int:
|
|
272
|
+
"""Get the shutter summer comfort lift"""
|
|
273
|
+
return self._device_type_data.get("SummerComfortLift")
|
|
274
|
+
|
|
275
|
+
async def set_summer_comfort_lift(self, lift: int):
|
|
276
|
+
if await self._send_command({"SummerComfortLift": lift}):
|
|
277
|
+
self._summer_comfort_lift = lift
|
|
278
|
+
return True
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def summer_comfort_tilt(self) -> int:
|
|
282
|
+
"""Get the shutter summer comfort tilt"""
|
|
283
|
+
return self._device_type_data.get("SummerComfortTilt")
|
|
284
|
+
|
|
285
|
+
async def set_summer_comfort_tilt(self, tilt: int):
|
|
286
|
+
if await self._send_command({"SummerComfortTilt": tilt}):
|
|
287
|
+
self._summer_comfort_tilt = tilt
|
|
288
|
+
return True
|
|
289
|
+
|
|
242
290
|
async def open(self, percentage: int = 100):
|
|
243
291
|
"""Fully open shutter"""
|
|
244
292
|
if percentage >= 0 and percentage <= 100:
|
|
245
293
|
return await self._send_command(
|
|
246
|
-
{
|
|
294
|
+
{
|
|
295
|
+
"RequestAction": {
|
|
296
|
+
"Action": "LiftTo",
|
|
297
|
+
"Percentage": percentage,
|
|
298
|
+
}
|
|
299
|
+
}
|
|
247
300
|
)
|
|
248
301
|
else:
|
|
249
|
-
raise ValueError(
|
|
302
|
+
raise ValueError(
|
|
303
|
+
"Shutter open percentage must be between 0 and 100"
|
|
304
|
+
)
|
|
250
305
|
|
|
251
306
|
async def close(self):
|
|
252
307
|
"""Fully close shutter"""
|
|
@@ -258,24 +313,33 @@ class _WiserShutter(_WiserElectricalDevice):
|
|
|
258
313
|
"""Stop shutter during movement"""
|
|
259
314
|
return await self._send_command({"RequestAction": {"Action": "Stop"}})
|
|
260
315
|
|
|
261
|
-
async def open_tilt(self, percentage: int =
|
|
262
|
-
"""Open shutter
|
|
263
|
-
if percentage >= 0 and percentage <=
|
|
316
|
+
async def open_tilt(self, percentage: int = 100):
|
|
317
|
+
"""Open tilt shutter to percentage"""
|
|
318
|
+
if percentage >= 0 and percentage <= 100:
|
|
264
319
|
return await self._send_command(
|
|
265
|
-
{
|
|
320
|
+
{
|
|
321
|
+
"RequestAction": {
|
|
322
|
+
"Action": "TiltTo",
|
|
323
|
+
"Percentage": percentage,
|
|
324
|
+
}
|
|
325
|
+
}
|
|
266
326
|
)
|
|
267
327
|
else:
|
|
268
|
-
raise ValueError(
|
|
328
|
+
raise ValueError(
|
|
329
|
+
"Shutter tilt percentage must be between 0 and 100"
|
|
330
|
+
)
|
|
269
331
|
|
|
270
332
|
async def close_tilt(self):
|
|
271
|
-
"""Fully close shutter
|
|
333
|
+
"""Fully close tilt shutter"""
|
|
272
334
|
return await self._send_command(
|
|
273
335
|
{"RequestAction": {"Action": "TiltTo", "Percentage": 0}}
|
|
274
336
|
)
|
|
275
337
|
|
|
276
338
|
async def stop_tilt(self):
|
|
277
|
-
"""Stop shutter
|
|
278
|
-
return await self._send_command(
|
|
339
|
+
"""Stop tilt shutter during movement"""
|
|
340
|
+
return await self._send_command(
|
|
341
|
+
{"RequestAction": {"Action": "StopTilt"}}
|
|
342
|
+
)
|
|
279
343
|
|
|
280
344
|
|
|
281
345
|
class _WiserShutterCollection(object):
|
|
@@ -315,7 +379,9 @@ class _WiserShutterCollection(object):
|
|
|
315
379
|
"""
|
|
316
380
|
try:
|
|
317
381
|
return [
|
|
318
|
-
shutter
|
|
382
|
+
shutter
|
|
383
|
+
for shutter in self.all
|
|
384
|
+
if shutter.shutter_id == shutter_id
|
|
319
385
|
][0]
|
|
320
386
|
except IndexError:
|
|
321
387
|
return None
|
|
@@ -105,6 +105,8 @@ class _WiserSmartPlugCollection(object):
|
|
|
105
105
|
return: _WiserSmartPlug object
|
|
106
106
|
"""
|
|
107
107
|
try:
|
|
108
|
-
return [smartplug for smartplug in self.all if smartplug.id == id][
|
|
108
|
+
return [smartplug for smartplug in self.all if smartplug.id == id][
|
|
109
|
+
0
|
|
110
|
+
]
|
|
109
111
|
except IndexError:
|
|
110
112
|
return None
|
|
@@ -49,7 +49,8 @@ class _WiserSystem(object):
|
|
|
49
49
|
self._data.get("FeatureCapability", {})
|
|
50
50
|
)
|
|
51
51
|
self._cloud_data = _WiserCloud(
|
|
52
|
-
self._system_data.get("CloudConnectionStatus"),
|
|
52
|
+
self._system_data.get("CloudConnectionStatus"),
|
|
53
|
+
self._data.get("Cloud", {}),
|
|
53
54
|
)
|
|
54
55
|
self._device_data = self._get_system_device(device_data)
|
|
55
56
|
self._network_data = _WiserNetwork(
|
|
@@ -61,7 +62,9 @@ class _WiserSystem(object):
|
|
|
61
62
|
self._system_data.get("OpenThermConnectionStatus", TEXT_UNKNOWN),
|
|
62
63
|
)
|
|
63
64
|
self._signal = _WiserSignalStrength(self._device_data)
|
|
64
|
-
self._upgrade_data = _WiserFirmareUpgradeInfo(
|
|
65
|
+
self._upgrade_data = _WiserFirmareUpgradeInfo(
|
|
66
|
+
self._data.get("UpgradeInfo", {})
|
|
67
|
+
)
|
|
65
68
|
self._zigbee_data = _WiserZigbee(self._data.get("Zigbee", {}))
|
|
66
69
|
|
|
67
70
|
# Variables to hold values for settabel values
|
|
@@ -74,15 +77,41 @@ class _WiserSystem(object):
|
|
|
74
77
|
self._away_mode_target_temperature = self._system_data.get(
|
|
75
78
|
"AwayModeSetPointLimit"
|
|
76
79
|
)
|
|
77
|
-
self._comfort_mode_enabled = self._system_data.get(
|
|
80
|
+
self._comfort_mode_enabled = self._system_data.get(
|
|
81
|
+
"ComfortModeEnabled"
|
|
82
|
+
)
|
|
78
83
|
self._degraded_mode_target_temperature = self._system_data.get(
|
|
79
84
|
"DegradedModeSetpointThreshold"
|
|
80
85
|
)
|
|
81
86
|
self._eco_mode_enabled = self._system_data.get("EcoModeEnabled")
|
|
82
|
-
self._hub_time = datetime.fromtimestamp(
|
|
87
|
+
self._hub_time = datetime.fromtimestamp(
|
|
88
|
+
self._system_data.get("UnixTime")
|
|
89
|
+
)
|
|
83
90
|
self._override_type = self._system_data.get("OverrideType", "")
|
|
84
91
|
self._timezone_offset = self._system_data.get("TimeZoneOffset")
|
|
85
|
-
self._valve_protection_enabled = self._system_data.get(
|
|
92
|
+
self._valve_protection_enabled = self._system_data.get(
|
|
93
|
+
"ValveProtectionEnabled"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Added by LGO
|
|
97
|
+
# Summer comfort
|
|
98
|
+
self._summer_comfort_enabled = self._system_data.get(
|
|
99
|
+
"SummerComfortEnabled"
|
|
100
|
+
)
|
|
101
|
+
self._indoor_discomfort_temperature = self._system_data.get(
|
|
102
|
+
"IndoorDiscomfortTemperature"
|
|
103
|
+
)
|
|
104
|
+
self._outdoor_discomfort_temperature = self._system_data.get(
|
|
105
|
+
"OutdoorDiscomfortTemperature"
|
|
106
|
+
)
|
|
107
|
+
self._summer_comfort_available = self._system_data.get(
|
|
108
|
+
"SummerComfortAvailable"
|
|
109
|
+
)
|
|
110
|
+
self._summer_discomfort_prevention = self._system_data.get(
|
|
111
|
+
"SummerDiscomfortPrevention"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# End Added by LGO
|
|
86
115
|
|
|
87
116
|
def _get_system_device(self, device_data: dict):
|
|
88
117
|
for device in device_data:
|
|
@@ -101,10 +130,14 @@ class _WiserSystem(object):
|
|
|
101
130
|
f"{WISERSYSTEM}/{path}", cmd
|
|
102
131
|
)
|
|
103
132
|
else:
|
|
104
|
-
result = await self._wiser_rest_controller._send_command(
|
|
133
|
+
result = await self._wiser_rest_controller._send_command(
|
|
134
|
+
WISERSYSTEM, cmd
|
|
135
|
+
)
|
|
105
136
|
if result:
|
|
106
137
|
_LOGGER.debug(
|
|
107
|
-
"Wiser hub - {} command successful".format(
|
|
138
|
+
"Wiser hub - {} command successful".format(
|
|
139
|
+
inspect.stack()[1].function
|
|
140
|
+
)
|
|
108
141
|
)
|
|
109
142
|
return True
|
|
110
143
|
return False
|
|
@@ -120,7 +153,9 @@ class _WiserSystem(object):
|
|
|
120
153
|
return self._automatic_daylight_saving
|
|
121
154
|
|
|
122
155
|
async def set_automatic_daylight_saving_enabled(self, enabled: bool):
|
|
123
|
-
if await self._send_command(
|
|
156
|
+
if await self._send_command(
|
|
157
|
+
{"AutomaticDaylightSaving": str(enabled).lower()}
|
|
158
|
+
):
|
|
124
159
|
self._automatic_daylight_saving = enabled
|
|
125
160
|
return True
|
|
126
161
|
|
|
@@ -130,7 +165,9 @@ class _WiserSystem(object):
|
|
|
130
165
|
return True if self._override_type == "Away" else False
|
|
131
166
|
|
|
132
167
|
async def set_away_mode_enabled(self, enabled: bool):
|
|
133
|
-
if await self._send_command(
|
|
168
|
+
if await self._send_command(
|
|
169
|
+
{"RequestOverride": {"Type": 2 if enabled else 0}}
|
|
170
|
+
):
|
|
134
171
|
self._override_type = "Away" if enabled else ""
|
|
135
172
|
return True
|
|
136
173
|
|
|
@@ -140,7 +177,9 @@ class _WiserSystem(object):
|
|
|
140
177
|
return self._away_mode_affects_hotwater
|
|
141
178
|
|
|
142
179
|
async def set_away_mode_affects_hotwater(self, enabled: bool = False):
|
|
143
|
-
if await self._send_command(
|
|
180
|
+
if await self._send_command(
|
|
181
|
+
{"AwayModeAffectsHotWater": str(enabled).lower()}
|
|
182
|
+
):
|
|
144
183
|
self._away_mode_affects_hotwater = enabled
|
|
145
184
|
return True
|
|
146
185
|
|
|
@@ -159,9 +198,9 @@ class _WiserSystem(object):
|
|
|
159
198
|
def boiler_fuel_type(self) -> str:
|
|
160
199
|
"""Get boiler fuel type setting"""
|
|
161
200
|
# TODO: Add ability to set to 1 of 3 types
|
|
162
|
-
return self._system_data.get(
|
|
163
|
-
"FuelType"
|
|
164
|
-
)
|
|
201
|
+
return self._system_data.get(
|
|
202
|
+
"BoilerSettings", {"FuelType": TEXT_UNKNOWN}
|
|
203
|
+
).get("FuelType")
|
|
165
204
|
|
|
166
205
|
@property
|
|
167
206
|
def brand_name(self) -> str:
|
|
@@ -312,6 +351,60 @@ class _WiserSystem(object):
|
|
|
312
351
|
"""Get zwave network information"""
|
|
313
352
|
return self._signal
|
|
314
353
|
|
|
354
|
+
# Added LGO
|
|
355
|
+
@property
|
|
356
|
+
def summer_comfort_enabled(self) -> bool:
|
|
357
|
+
"""Get whether summer comfort mode is enabled"""
|
|
358
|
+
return self._summer_comfort_enabled
|
|
359
|
+
|
|
360
|
+
async def set_summer_comfort_enabled(self, enabled: bool):
|
|
361
|
+
"""Set whether summer comfort mode is enabled"""
|
|
362
|
+
if await self._send_command({"SummerComfortEnabled": enabled}):
|
|
363
|
+
self._summer_comfort_enabled = enabled
|
|
364
|
+
return True
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def indoor_discomfort_temperature(self) -> float:
|
|
368
|
+
"""Get indoor discomfort temperature for summer comfort"""
|
|
369
|
+
return tf._from_wiser_temp(self._indoor_discomfort_temperature)
|
|
370
|
+
|
|
371
|
+
async def set_indoor_discomfort_temperature(self, temp: float):
|
|
372
|
+
"""Set indoor discomfort temperature for summer comfort"""
|
|
373
|
+
temp = tf._to_wiser_temp(temp)
|
|
374
|
+
if await self._send_command({"IndoorDiscomfortTemperature": temp}):
|
|
375
|
+
self._away_mode_target_temperature = tf._to_wiser_temp(temp)
|
|
376
|
+
return True
|
|
377
|
+
|
|
378
|
+
@property
|
|
379
|
+
def outdoor_discomfort_temperature(self) -> float:
|
|
380
|
+
"""Get outdoor discomfort temperature for summer comfort"""
|
|
381
|
+
return tf._from_wiser_temp(self._outdoor_discomfort_temperature)
|
|
382
|
+
|
|
383
|
+
async def set_outdoor_discomfort_temperature(self, temp: float):
|
|
384
|
+
"""Set outdoor discomfort temperature for summer comfort"""
|
|
385
|
+
temp = tf._to_wiser_temp(temp)
|
|
386
|
+
if await self._send_command({"OutdoorDiscomfortTemperature": temp}):
|
|
387
|
+
self._away_mode_target_temperature = tf._to_wiser_temp(temp)
|
|
388
|
+
return True
|
|
389
|
+
|
|
390
|
+
@property
|
|
391
|
+
def summer_comfort_available(self) -> bool:
|
|
392
|
+
"""Get whether summer comfort mode is available"""
|
|
393
|
+
return self._summer_comfort_available
|
|
394
|
+
|
|
395
|
+
@property
|
|
396
|
+
def summer_discomfort_prevention(self) -> bool:
|
|
397
|
+
"""Get summer discomfort prevention"""
|
|
398
|
+
return self._summer_discomfort_prevention
|
|
399
|
+
|
|
400
|
+
async def set_summer_discomfort_prevention(self, enabled: bool):
|
|
401
|
+
"""Set summer discomfort prevention"""
|
|
402
|
+
if await self._send_command({"SummerDiscomfortPrevention": enabled}):
|
|
403
|
+
self._summer_discomfort_prevention = enabled
|
|
404
|
+
return True
|
|
405
|
+
|
|
406
|
+
# End Added LGO
|
|
407
|
+
|
|
315
408
|
@property
|
|
316
409
|
def sunrise_times(self) -> list:
|
|
317
410
|
"""Get sunrise times"""
|
|
@@ -377,7 +470,9 @@ class _WiserSystem(object):
|
|
|
377
470
|
"RequestOverride": {
|
|
378
471
|
"Type": "Boost",
|
|
379
472
|
"DurationMinutes": duration,
|
|
380
|
-
"IncreaseSetPointBy": tf._to_wiser_temp(
|
|
473
|
+
"IncreaseSetPointBy": tf._to_wiser_temp(
|
|
474
|
+
inc_temp, "boostDelta"
|
|
475
|
+
),
|
|
381
476
|
}
|
|
382
477
|
}
|
|
383
478
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aioWiserHeatAPI
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.5
|
|
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.
|
|
21
|
+
# Drayton Wiser Hub API Async v1.5.5
|
|
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,10 @@ Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/b
|
|
|
72
72
|
|
|
73
73
|
## Changelog
|
|
74
74
|
|
|
75
|
+
### v1.5.5
|
|
76
|
+
|
|
77
|
+
* Added addtional v2 hub attributes and switches
|
|
78
|
+
|
|
75
79
|
### v1.5.4
|
|
76
80
|
|
|
77
81
|
* Fixed issue whereby json conversion errors due to control characters in string
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aioWiserHeatAPI-1.5.4 → aioWiserHeatAPI-1.5.5}/aioWiserHeatAPI.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|