Skip to content

Commit f6bd4f5

Browse files
committed
Add event listeners test
1 parent c7cc039 commit f6bd4f5

3 files changed

Lines changed: 76 additions & 21 deletions

File tree

tahoma_api/client.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ def __init__(self, username, password, api_url=API_URL):
3030
self.password = password
3131
self.api_url = api_url
3232

33-
self._devices = None
34-
35-
self.__roles = []
33+
self.__cookies = None
34+
self.__devices = None
35+
self.__roles = None
3636

3737
async def login(self):
3838

@@ -51,6 +51,7 @@ async def login(self):
5151

5252
if "Too many requests" in result["error"]:
5353
print(result["error"])
54+
raise Exception
5455

5556
if (
5657
"Your setup cannot be accessed through this application"
@@ -83,25 +84,64 @@ async def login(self):
8384
print(result)
8485

8586
async def get_devices(self, refresh=False) -> List[Device]:
86-
87-
if self._devices and refresh == False:
87+
if self.__devices and refresh == False:
8888
return self._devices
8989

90-
cookies = self.__cookies
90+
response = await self.__make_http_request("GET", "setup/devices")
9191

92-
# TODO add retry logic for unauthorized?
93-
async with aiohttp.ClientSession() as session:
94-
async with session.get(
95-
self.api_url + "setup/devices", cookies=cookies
96-
) as response:
92+
devices = [Device(**d) for d in response]
93+
self.__devices = devices
9794

98-
result = await response.json()
95+
return devices
96+
97+
async def register_event_listener(self) -> str:
98+
"""
99+
Register a new setup event listener on the current session and return a new listener id.
100+
Only one listener may be registered on a given session.
101+
Registering an new listener will invalidate the previous one if any.
102+
Note that registering an event listener drastically reduces the session timeout : listening sessions are expected to call the /events/{listenerId}/fetch API on a regular basis.
103+
"""
104+
response = await self.__make_http_request("POST", "events/register")
105+
listener_id = response.get("id")
99106

100-
# for device in result.items()
107+
return listener_id
101108

102-
if response.status is 200:
103-
devices = [Device(**d) for d in result]
104-
self._devices = devices
109+
async def fetch_event_listener(self, listener_id: str) -> List[Any]:
110+
"""
111+
Fetch new events from a registered event listener. Fetched events are removed from the listener buffer. Return an empty response if no event is available.
112+
Per-session rate-limit : 1 calls per 1 SECONDS period for this particular operation (polling)
113+
"""
114+
response = await self.__make_http_request("POST", f"events/{listener_id}/fetch")
105115

106-
return devices
116+
return response
117+
118+
async def __make_http_request(
119+
self, method: str, endpoint: str, payload: Optional[Any] = None
120+
) -> Any:
121+
"""Make a request to the TaHoma API"""
122+
cookies = self.__cookies
123+
supported_methods = ["GET", "POST"]
124+
125+
if method not in supported_methods:
126+
raise Exception
127+
128+
async with aiohttp.ClientSession() as session:
129+
if method == "GET":
130+
async with session.get(
131+
self.api_url + endpoint, cookies=cookies
132+
) as response:
133+
result = await response.json()
134+
135+
if method == "POST":
136+
async with session.post(
137+
self.api_url + endpoint, cookies=cookies, data=payload
138+
) as response:
139+
result = await response.json()
140+
141+
if response.status == 200:
142+
return result
143+
144+
if response.status > 400 and response.status < 500:
145+
# implement retry logic
146+
print("TODO")
107147

tahoma_api/models.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# TODO Rewrite camelCase to snake_case
44
class Device:
55
__slots__ = (
6+
"id",
67
"creationTime",
78
"lastUpdateTime",
89
"label",
@@ -12,7 +13,10 @@ class Device:
1213
"definition",
1314
"states",
1415
"dataProperties",
16+
"available",
17+
"enabled",
1518
"widgetName",
19+
"widget",
1620
"uiClass",
1721
"qualifiedName",
1822
"type",
@@ -24,7 +28,7 @@ def __init__(
2428
label: str,
2529
deviceURL: str,
2630
controllableName: str,
27-
definition: Dict[List[Any]],
31+
# definition: Dict[List[Any]],
2832
states: List[Dict[str, Any]],
2933
dataProperties: Optional[List[Dict[str, Any]]] = None,
3034
widgetName: Optional[str] = None,
@@ -33,7 +37,9 @@ def __init__(
3337
type: str,
3438
**kwargs: Any
3539
):
40+
self.id = deviceURL
3641
self.deviceURL = deviceURL
42+
self.label = label
3743
self.controllableName = controllableName
3844
self.states = [State(**s) for s in states]
3945

test.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import asyncio
22
from tahoma_api import TahomaClient
3+
import time
34

45
username = ""
56
password = ""
67

8+
79
async def main():
810
client = TahomaClient(username, password)
9-
11+
1012
try:
1113
login = await client.login()
12-
devices = await client.get_states()
14+
devices = await client.get_devices()
15+
16+
for device in devices:
17+
print(f"{device.label} ({device.id})")
1318

14-
print(devices)
19+
listener_id = await client.register_event_listener()
1520

21+
while True:
22+
events = await client.fetch_event_listener(listener_id)
23+
print(events)
24+
time.sleep(2)
1625

1726
except Exception as exception:
1827
print(exception)

0 commit comments

Comments
 (0)