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

Commit f7c5762

Browse files
feat: Add Thermostats and Climate Settings (#95)
1 parent 2438210 commit f7c5762

File tree

8 files changed

+799
-0
lines changed

8 files changed

+799
-0
lines changed

seamapi/climate_setting_schedules.py

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
from typing import List, Optional, Union
2+
3+
from seamapi.types import AbstractClimateSettingSchedules
4+
from seamapi.types import AbstractSeam as Seam
5+
from seamapi.types import (ClimateSettingSchedule,
6+
ClimateSettingScheduleId, Device, DeviceId)
7+
from seamapi.utils.convert_to_id import (to_climate_setting_schedule_id,
8+
to_device_id)
9+
from seamapi.utils.report_error import report_error
10+
11+
class ClimateSettingSchedules(AbstractClimateSettingSchedules):
12+
"""
13+
A class used to interact with Climate Setting Schedules for Thermostats
14+
15+
Attributes
16+
----------
17+
seam : Seam
18+
Initial seam class
19+
20+
Methods
21+
-------
22+
list(device=Union[DeviceId, Device])
23+
Gets a list of climate setting schedules for a device
24+
get(climate_setting_schedule: Union[ClimateSettingScheduleId, ClimateSettingSchedule])
25+
Gets a climate setting schedule
26+
create(
27+
device,
28+
device: Union[DeviceId, Device],
29+
schedule_starts_at: str,
30+
schedule_ends_at: str,
31+
name: Optional[str],
32+
automatic_heating_enabled: Optional[bool],
33+
automatic_cooling_enabled: Optional[bool],
34+
hvac_mode_setting: Optional[str],
35+
cooling_set_point_celsius: Optional[float],
36+
heating_set_point_celsius: Optional[float],
37+
cooling_set_point_fahrenheit: Optional[float],
38+
heating_set_point_fahrenheit: Optional[float],
39+
manual_override_allowed: Optional[bool],
40+
schedule_type: Optional[str],
41+
)
42+
Creates a climate setting schedule for a Device
43+
update(
44+
climate_setting_schedule,
45+
self,
46+
climate_setting_schedule: Union[str, ClimateSettingSchedule],
47+
schedule_starts_at: Optional[str],
48+
schedule_ends_at: Optional[str],
49+
name: Optional[str],
50+
automatic_heating_enabled: Optional[bool],
51+
automatic_cooling_enabled: Optional[bool],
52+
hvac_mode_setting: Optional[str],
53+
cooling_set_point_celsius: Optional[float],
54+
heating_set_point_celsius: Optional[float],
55+
cooling_set_point_fahrenheit: Optional[float],
56+
heating_set_point_fahrenheit: Optional[float],
57+
manual_override_allowed: Optional[bool],
58+
schedule_type: Optional[str],
59+
)
60+
Updates a climate setting schedule
61+
delete(climate_setting_schedule)
62+
Deletes a climate setting schedule
63+
"""
64+
65+
seam: Seam
66+
67+
def __init__(self, seam: Seam):
68+
"""
69+
Parameters
70+
----------
71+
seam : Seam
72+
Intial seam class
73+
"""
74+
75+
self.seam = seam
76+
77+
@report_error
78+
def list(
79+
self,
80+
device: Union[DeviceId, Device],
81+
) -> List[ClimateSettingSchedule]:
82+
"""Gets a list of Climate Setting Schedules.
83+
84+
Parameters
85+
----------
86+
device : DeviceId or Device
87+
Device id or Device to get the climate setting schedules of
88+
89+
Raises
90+
------
91+
Exception
92+
If the API request wasn't successful.
93+
94+
Returns
95+
------
96+
A list of climate setting schedules.
97+
"""
98+
device_id = to_device_id(device)
99+
100+
res = self.seam.make_request(
101+
"GET",
102+
"/thermostats/climate_setting_schedules/list",
103+
params={
104+
"device_id": device_id
105+
},
106+
)
107+
climate_setting_schedules = res["climate_setting_schedules"]
108+
109+
return [ClimateSettingSchedule.from_dict(d) for d in climate_setting_schedules]
110+
111+
@report_error
112+
def get(
113+
self,
114+
climate_setting_schedule: Union[ClimateSettingScheduleId, ClimateSettingSchedule]
115+
) -> ClimateSettingSchedule:
116+
"""Gets a Climate Setting Schedule.
117+
118+
Parameters
119+
----------
120+
climate_setting_schedule : Id or ClimateSettingSchedule
121+
Id or ClimateSettingSchedule to get the state of
122+
123+
Raises
124+
------
125+
Exception
126+
If the API request wasn't successful.
127+
128+
Returns
129+
------
130+
ClimateSettingSchedule
131+
"""
132+
133+
climate_setting_schedule_id = to_climate_setting_schedule_id(climate_setting_schedule)
134+
135+
res = self.seam.make_request("GET", "/thermostats/climate_setting_schedules/get", params={
136+
"climate_setting_schedule_id": climate_setting_schedule_id
137+
})
138+
json_response = res["climate_setting_schedule"]
139+
return ClimateSettingSchedule.from_dict(json_response)
140+
141+
@report_error
142+
def create(
143+
self,
144+
device: Union[DeviceId, Device],
145+
schedule_starts_at: str,
146+
schedule_ends_at: str,
147+
name: Optional[str] = None,
148+
automatic_heating_enabled: Optional[bool] = None,
149+
automatic_cooling_enabled: Optional[bool] = None,
150+
hvac_mode_setting: Optional[str] = None,
151+
cooling_set_point_celsius: Optional[float] = None,
152+
heating_set_point_celsius: Optional[float] = None,
153+
cooling_set_point_fahrenheit: Optional[float] = None,
154+
heating_set_point_fahrenheit: Optional[float] = None,
155+
manual_override_allowed: Optional[bool] = None,
156+
schedule_type: Optional[str] = None,
157+
) -> ClimateSettingSchedule:
158+
"""Creates a Climate Setting Schedule.
159+
160+
Parameters
161+
----------
162+
device : DeviceId or Device
163+
Device id or Device to create the climate setting schedule for
164+
properties : ClimateSettingScheduleBase
165+
Properties to update
166+
167+
Raises
168+
------
169+
Exception
170+
If the API request wasn't successful.
171+
172+
Returns
173+
------
174+
Boolean
175+
"""
176+
device_id = to_device_id(device)
177+
178+
params = climate_setting_params(
179+
automatic_heating_enabled,
180+
automatic_cooling_enabled,
181+
hvac_mode_setting,
182+
cooling_set_point_celsius,
183+
heating_set_point_celsius,
184+
cooling_set_point_fahrenheit,
185+
heating_set_point_fahrenheit,
186+
manual_override_allowed,
187+
schedule_type,
188+
name,
189+
schedule_starts_at,
190+
schedule_ends_at,
191+
)
192+
193+
params["device_id"] = device_id
194+
195+
res = self.seam.make_request(
196+
"POST",
197+
"/thermostats/climate_setting_schedules/create",
198+
json=params
199+
)
200+
json_response = res["climate_setting_schedule"]
201+
return ClimateSettingSchedule.from_dict(json_response)
202+
203+
@report_error
204+
def update(
205+
self,
206+
climate_setting_schedule: Union[str, ClimateSettingSchedule],
207+
schedule_starts_at: Optional[str] = None,
208+
schedule_ends_at: Optional[str] = None,
209+
name: Optional[str] = None,
210+
automatic_heating_enabled: Optional[bool] = None,
211+
automatic_cooling_enabled: Optional[bool] = None,
212+
hvac_mode_setting: Optional[str] = None,
213+
cooling_set_point_celsius: Optional[float] = None,
214+
heating_set_point_celsius: Optional[float] = None,
215+
cooling_set_point_fahrenheit: Optional[float] = None,
216+
heating_set_point_fahrenheit: Optional[float] = None,
217+
manual_override_allowed: Optional[bool] = None,
218+
schedule_type: Optional[str] = None,
219+
) -> ClimateSettingSchedule:
220+
"""Updates a Climate Setting Schedule.
221+
222+
Parameters
223+
----------
224+
climate_setting_schedule : ClimateSettingScheduleId or ClimateSettingSchedule
225+
ClimateSettingSchedule to update
226+
properties : ClimateSettingScheduleBase
227+
Properties to update
228+
229+
Raises
230+
------
231+
Exception
232+
If the API request wasn't successful.
233+
234+
Returns
235+
------
236+
Boolean
237+
"""
238+
239+
climate_setting_schedule_id = to_climate_setting_schedule_id(climate_setting_schedule)
240+
241+
params = climate_setting_params(
242+
automatic_heating_enabled,
243+
automatic_cooling_enabled,
244+
hvac_mode_setting,
245+
cooling_set_point_celsius,
246+
heating_set_point_celsius,
247+
cooling_set_point_fahrenheit,
248+
heating_set_point_fahrenheit,
249+
manual_override_allowed,
250+
schedule_type,
251+
name,
252+
schedule_starts_at,
253+
schedule_ends_at,
254+
)
255+
256+
params["climate_setting_schedule_id"] = climate_setting_schedule_id
257+
258+
res = self.seam.make_request(
259+
"POST",
260+
"/thermostats/climate_setting_schedules/update",
261+
json=params,
262+
)
263+
264+
json_response = res["climate_setting_schedule"]
265+
return ClimateSettingSchedule.from_dict(json_response)
266+
267+
@report_error
268+
def delete(
269+
self,
270+
climate_setting_schedule: Union[ClimateSettingScheduleId, ClimateSettingSchedule]
271+
) -> None:
272+
"""Deletes a climate setting schedule.
273+
274+
Parameters
275+
----------
276+
climate_setting_schedule : Id or ClimateSettingSchedule
277+
Id or ClimateSettingSchedule to delete
278+
279+
Raises
280+
------
281+
Exception
282+
If the API request wasn't successful.
283+
284+
Returns
285+
------
286+
None
287+
"""
288+
289+
climate_setting_schedule_id = to_climate_setting_schedule_id(climate_setting_schedule)
290+
291+
delete_payload = {
292+
"climate_setting_schedule_id": climate_setting_schedule_id
293+
}
294+
295+
self.seam.make_request(
296+
"DELETE",
297+
"/thermostats/climate_setting_schedules/delete",
298+
json=delete_payload,
299+
)
300+
301+
return None
302+
303+
def climate_setting_params(
304+
automatic_heating_enabled: Optional[bool] = None,
305+
automatic_cooling_enabled: Optional[bool] = None,
306+
hvac_mode_setting: Optional[str] = None,
307+
cooling_set_point_celsius: Optional[float] = None,
308+
heating_set_point_celsius: Optional[float] = None,
309+
cooling_set_point_fahrenheit: Optional[float] = None,
310+
heating_set_point_fahrenheit: Optional[float] = None,
311+
manual_override_allowed: Optional[bool] = None,
312+
schedule_type: Optional[str] = None,
313+
name: Optional[str] = None,
314+
schedule_starts_at: Optional[str] = None,
315+
schedule_ends_at: Optional[str] = None,
316+
):
317+
params = {}
318+
319+
if automatic_heating_enabled is not None:
320+
params["automatic_heating_enabled"] = automatic_heating_enabled
321+
if automatic_cooling_enabled is not None:
322+
params["automatic_cooling_enabled"] = automatic_cooling_enabled
323+
if hvac_mode_setting is not None:
324+
params["hvac_mode_setting"] = hvac_mode_setting
325+
if cooling_set_point_celsius is not None:
326+
params["cooling_set_point_celsius"] = cooling_set_point_celsius
327+
if heating_set_point_celsius is not None:
328+
params["heating_set_point_celsius"] = heating_set_point_celsius
329+
if cooling_set_point_fahrenheit is not None:
330+
params["cooling_set_point_fahrenheit"] = cooling_set_point_fahrenheit
331+
if heating_set_point_fahrenheit is not None:
332+
params["heating_set_point_fahrenheit"] = heating_set_point_fahrenheit
333+
if manual_override_allowed is not None:
334+
params["manual_override_allowed"] = manual_override_allowed
335+
if schedule_type is not None:
336+
params["schedule_type"] = schedule_type
337+
if name is not None:
338+
params["name"] = name
339+
if schedule_starts_at is not None:
340+
params["schedule_starts_at"] = schedule_starts_at
341+
if schedule_ends_at is not None:
342+
params["schedule_ends_at"] = schedule_ends_at
343+
344+
return params

seamapi/routes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .locks import Locks
99
from .access_codes import AccessCodes
1010
from .action_attempts import ActionAttempts
11+
from .thermostats import Thermostats
1112

1213
class Routes(AbstractRoutes):
1314
def __init__(self):
@@ -20,6 +21,7 @@ def __init__(self):
2021
self.access_codes = AccessCodes(seam=self)
2122
self.action_attempts = ActionAttempts(seam=self)
2223
self.noise_sensors = NoiseSensors(seam=self)
24+
self.thermostats = Thermostats(seam=self)
2325

2426
def make_request(self):
2527
raise NotImplementedError()

0 commit comments

Comments
 (0)