Skip to content

Commit c7cc039

Browse files
committed
Add first models
1 parent 8d9e300 commit c7cc039

2 files changed

Lines changed: 113 additions & 37 deletions

File tree

tahoma_api/client.py

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
import json
1111

1212
from .exceptions import *
13+
from .models import *
14+
15+
API_URL = "https://tahomalink.com/enduser-mobile-web/enduserAPI/" # /doc for API doc
1316

14-
API_URL = 'https://tahomalink.com/enduser-mobile-web/enduserAPI/' # /doc for API doc
1517

1618
class TahomaClient(object):
1719
""" Interface class for the Tahoma API """
1820

19-
def __init__(self, username, password):
21+
def __init__(self, username, password, api_url=API_URL):
2022
"""
2123
Constructor
2224
@@ -26,53 +28,52 @@ def __init__(self, username, password):
2628

2729
self.username = username
2830
self.password = password
29-
31+
self.api_url = api_url
3032

3133
self._devices = None
3234

33-
3435
self.__roles = []
3536

3637
async def login(self):
37-
38-
payload = {
39-
'userId': self.username,
40-
'userPassword': self.password
41-
}
38+
39+
payload = {"userId": self.username, "userPassword": self.password}
4240

4341
async with aiohttp.ClientSession() as session:
44-
async with session.post(API_URL + 'login', data=payload) as response:
42+
async with session.post(self.api_url + "login", data=payload) as response:
4543

4644
result = await response.json()
4745

4846
# 401
4947
# {'errorCode': 'AUTHENTICATION_ERROR', 'error': 'Bad credentials'}
5048
# {'errorCode': 'AUTHENTICATION_ERROR', 'error': 'Your setup cannot be accessed through this application'}
5149
if response.status == 401:
52-
if result['errorCode'] == 'AUTHENTICATION_ERROR':
50+
if result["errorCode"] == "AUTHENTICATION_ERROR":
51+
52+
if "Too many requests" in result["error"]:
53+
print(result["error"])
5354

54-
if 'Too many requests' in result['error']:
55-
print(result['error'])
55+
if (
56+
"Your setup cannot be accessed through this application"
57+
in result["error"]
58+
):
59+
print(result["error"])
5660

57-
if 'Your setup cannot be accessed through this application' in result['error']:
58-
print(result['error'])
61+
if "Bad credentials" in result["error"]:
62+
print(result["error"])
5963

60-
if 'Bad credentials' in result['error']:
61-
print(result['error'])
64+
print(result["error"])
6265

63-
print(result['error'])
66+
return False # todo throw error
6467

65-
return False # todo throw error
66-
6768
# 401
6869
# {'errorCode': 'AUTHENTICATION_ERROR', 'error': 'Too many requests, try again later : login with xxx@xxx.tld'}
6970
# TODO Add retry logic on too many requests + for debug, log requests + timespans
70-
71+
7172
# 200
7273
# {'success': True, 'roles': [{'name': 'ENDUSER'}]}
7374
if response.status == 200:
74-
if result['success'] == True:
75-
self.__roles = result['roles']
75+
if result["success"] == True:
76+
self.__roles = result["roles"]
7677
self.__cookies = response.cookies
7778

7879
return True
@@ -81,24 +82,26 @@ async def login(self):
8182
print(response.status)
8283
print(result)
8384

84-
async def get_devices(self, refresh=False):
85+
async def get_devices(self, refresh=False) -> List[Device]:
86+
87+
if self._devices and refresh == False:
88+
return self._devices
8589

86-
if self._devices is None or refresh == True:
90+
cookies = self.__cookies
8791

88-
cookies = self.__cookies
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:
8997

90-
async with aiohttp.ClientSession() as session:
91-
async with session.get(API_URL + 'setup/devices', cookies=cookies) as response:
98+
result = await response.json()
9299

93-
result = await response.json()
100+
# for device in result.items()
94101

95-
if (response.status is 200):
96-
self._devices = result
102+
if response.status is 200:
103+
devices = [Device(**d) for d in result]
104+
self._devices = devices
97105

98-
return result
99-
100-
# TODO add retry logic for unauthorized?
106+
return devices
101107

102-
else:
103-
return []
104-
# TODO Save cookies

tahoma_api/models.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from typing import Any, Dict, List, Optional, Union
2+
3+
# TODO Rewrite camelCase to snake_case
4+
class Device:
5+
__slots__ = (
6+
"creationTime",
7+
"lastUpdateTime",
8+
"label",
9+
"deviceURL",
10+
"shortcut",
11+
"controllableName",
12+
"definition",
13+
"states",
14+
"dataProperties",
15+
"widgetName",
16+
"uiClass",
17+
"qualifiedName",
18+
"type",
19+
)
20+
21+
def __init__(
22+
self,
23+
*,
24+
label: str,
25+
deviceURL: str,
26+
controllableName: str,
27+
definition: Dict[List[Any]],
28+
states: List[Dict[str, Any]],
29+
dataProperties: Optional[List[Dict[str, Any]]] = None,
30+
widgetName: Optional[str] = None,
31+
uiClass: str,
32+
qualifiedName: Optional[str] = None,
33+
type: str,
34+
**kwargs: Any
35+
):
36+
self.deviceURL = deviceURL
37+
self.controllableName = controllableName
38+
self.states = [State(**s) for s in states]
39+
40+
41+
class StateDefinition:
42+
__slots__ = (
43+
"qualifiedName",
44+
"type",
45+
"values",
46+
)
47+
48+
def __init__(
49+
self, qualifiedName: str, type: str, values: Optional[str], **kwargs: Any
50+
):
51+
self.qualifiedName = qualifiedName
52+
self.type = type
53+
self.values = values
54+
55+
56+
class CommandDefinition:
57+
__slots__ = (
58+
"commandName",
59+
"nparams",
60+
)
61+
62+
def __init__(self, commandName: str, nparams: int, **kwargs: Any):
63+
self.commandName = commandName
64+
self.nparams = nparams
65+
66+
67+
class State:
68+
__slots__ = "name", "value", "type"
69+
70+
def __init__(self, name: str, value: str, type: str, **kwargs: Any):
71+
self.name = name
72+
self.value = value
73+
self.type = type

0 commit comments

Comments
 (0)