Skip to content
This repository was archived by the owner on Jun 28, 2024. It is now read-only.

Commit bbad5c7

Browse files
Add thermostats.set_mode (#102)
* Remove thermostats.delete * Add set_mode method * Test /set_mode
1 parent 841d436 commit bbad5c7

File tree

3 files changed

+66
-26
lines changed

3 files changed

+66
-26
lines changed

seamapi/thermostats.py

+52-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from seamapi.types import (
22
AbstractThermostats,
3+
ActionAttempt,
34
ConnectWebview,
45
ConnectWebviewId,
56
ConnectedAccount,
@@ -50,7 +51,9 @@ def __init__(self, seam: Seam):
5051
"""
5152

5253
self.seam = seam
53-
self.climate_setting_schedules = ClimateSettingSchedules(seam=self.seam)
54+
self.climate_setting_schedules = ClimateSettingSchedules(
55+
seam=self.seam
56+
)
5457

5558
@report_error
5659
def list(
@@ -91,7 +94,7 @@ def list(
9194
connect_webview
9295
)
9396
if device_ids is not None:
94-
params["device_ids"] = [to_device_id(d) for d in device_ids]
97+
params["device_ids"] = [to_device_id(d) for d in device_ids]
9598

9699
res = self.seam.make_request(
97100
"GET",
@@ -183,13 +186,28 @@ def update(
183186
return True
184187

185188
@report_error
186-
def delete(self, device: Union[DeviceId, Device]) -> bool:
187-
"""Deletes a device.
189+
def set_mode(
190+
self,
191+
device: Union[DeviceId, Device],
192+
automatic_heating_enabled: Optional[bool] = None,
193+
automatic_cooling_enabled: Optional[bool] = None,
194+
hvac_mode_setting: Optional[str] = None,
195+
wait_for_action_attempt: Optional[bool] = True,
196+
) -> ActionAttempt:
197+
"""Sets a thermostat to a given mode.
188198
189199
Parameters
190200
----------
191201
device : DeviceId or Device
192-
Device id or Device to delete
202+
Device id or Device to update
203+
automatic_heating_enabled : bool, optional
204+
Enable automatic heating
205+
automatic_cooling_enabled : bool, optional
206+
Enable cooling heating
207+
hvac_mode_setting : str, optional
208+
HVAC mode eg. "heat", "cool", "heatcool" or "off"
209+
wait_for_action_attempt: bool, optional
210+
Should wait for action attempt to resolve
193211
194212
Raises
195213
------
@@ -198,17 +216,38 @@ def delete(self, device: Union[DeviceId, Device]) -> bool:
198216
199217
Returns
200218
------
201-
None
219+
ActionAttempt
202220
"""
203221

204222
if not device:
205-
raise Exception("device is required")
223+
raise Exception("Device is required")
206224

207-
delete_payload = {"device_id": to_device_id(device)}
208-
self.seam.make_request(
209-
"DELETE",
210-
"/thermostats/delete",
211-
json=delete_payload,
225+
params = {
226+
"device_id": to_device_id(device),
227+
}
228+
229+
arguments = {
230+
"automatic_heating_enabled": automatic_heating_enabled,
231+
"automatic_cooling_enabled": automatic_cooling_enabled,
232+
"hvac_mode_setting": hvac_mode_setting,
233+
}
234+
235+
for name in arguments:
236+
if arguments[name]:
237+
params.update({name: arguments[name]})
238+
239+
res = self.seam.make_request(
240+
"POST",
241+
"/thermostats/set_mode",
242+
json=params,
243+
)
244+
action_attempt = res["action_attempt"]
245+
246+
if not wait_for_action_attempt:
247+
return ActionAttempt.from_dict(action_attempt)
248+
249+
updated_action_attempt = self.seam.action_attempts.poll_until_ready(
250+
action_attempt["action_attempt_id"]
212251
)
213252

214-
return None
253+
return ActionAttempt.from_dict(updated_action_attempt)

seamapi/types.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ class ActionAttempt:
137137
action_attempt_id: str
138138
action_type: str
139139
status: str
140-
result: Optional[Any]
141-
error: Optional[ActionAttemptError]
140+
result: Optional[Any] = None
141+
error: Optional[ActionAttemptError] = None
142142

143143

144144
@dataclass_json
@@ -620,10 +620,6 @@ def update(
620620
) -> None:
621621
raise NotImplementedError
622622

623-
@abc.abstractmethod
624-
def delete(self, device: Union[DeviceId, Device]) -> None:
625-
raise NotImplementedError
626-
627623

628624
@dataclass
629625
class AbstractRoutes(abc.ABC):

tests/thermostats/test_thermostats.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from seamapi import Seam
22
from tests.fixtures.run_nest_factory import run_nest_factory
33

4+
45
def test_thermostats(seam: Seam):
56
run_nest_factory(seam)
67

@@ -24,14 +25,18 @@ def test_thermostats(seam: Seam):
2425
"hvac_mode_setting": "cool",
2526
"cooling_set_point_celsius": 20,
2627
"manual_override_allowed": True,
27-
}
28+
},
2829
)
2930

3031
assert result == True
3132

32-
# Test Delete
33-
result = seam.thermostats.delete(thermostat)
34-
assert result == None
35-
36-
thermostats = seam.thermostats.list()
37-
assert len(thermostats) == 2
33+
assert (
34+
thermostat.properties.current_climate_setting.hvac_mode_setting
35+
== "heatcool"
36+
)
37+
seam.thermostats.set_mode(device=thermostat, hvac_mode_setting="heat")
38+
updated_thermostat = seam.thermostats.get(thermostat.device_id)
39+
assert (
40+
updated_thermostat.properties.current_climate_setting.hvac_mode_setting
41+
== "heat"
42+
)

0 commit comments

Comments
 (0)