Skip to content

Commit 0670262

Browse files
committed
Starting to work on Atrium Integration. Pending https://discord.com/channels/@me/1044623052366950501/1340787352397811862
1 parent bfd395a commit 0670262

1 file changed

Lines changed: 201 additions & 0 deletions

File tree

AtriumControl/AtriumIntegration.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import hashlib
2+
import datetime
3+
import urllib
4+
import pprint
5+
from cgi import escape
6+
import xml.etree.ElementTree as ET
7+
8+
class Atrium:
9+
def __init__(self, base_url):
10+
self.base_url = base_url
11+
self.timeout = None
12+
self.serial = None
13+
self.username = None
14+
self.session_id = None
15+
self.session_key = None
16+
17+
def __str__(self):
18+
return str({
19+
'base_url': self.base_url,
20+
'timeout': self.timeout,
21+
'serial': self.serial,
22+
'username': self.username
23+
})
24+
25+
def get_temp_session_key(self):
26+
response = model.RestGet("{}/login_sdk.xml".format(self.base_url), {})
27+
xml = ET.fromstring(response)
28+
29+
print "<h2>RestGet Login</h2>"
30+
print "<pre>" + escape(response) + "</pre>"
31+
32+
self.session_id = xml.find(".//CONNECTION").get("session")
33+
self.serial = xml.find(".//DEVICE").get("serial")
34+
timeout_secs = int(xml.find(".//CONNECTION").get("timeout"))
35+
self.timeout = datetime.datetime.now() + datetime.timedelta(seconds=timeout_secs)
36+
self.session_key = hashlib.md5((self.serial + self.session_id).encode()).hexdigest().upper()
37+
38+
print self.session_key
39+
40+
def http_post(self, url, data):
41+
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
42+
data = urllib.urlencode(data)
43+
print "<h2>RestPost</h2>"
44+
print "<pre>" + escape(data) + "</pre>"
45+
response = model.RestPostJson(url, headers, data)
46+
# response = model.RestPost(url, headers, data)
47+
print "<pre>" + escape(response) + "</pre>"
48+
# response = None
49+
return response
50+
51+
@staticmethod
52+
def rc4(key, text):
53+
s = list(range(256))
54+
j = 0
55+
for i in range(256):
56+
j = (j + s[i] + ord(key[i % len(key)])) % 256
57+
s[i], s[j] = s[j], s[i]
58+
59+
i = j = 0
60+
ct = ''
61+
for y in range(len(text)):
62+
i = (i + 1) % 256
63+
j = (j + s[i]) % 256
64+
s[i], s[j] = s[j], s[i]
65+
ct += '{:02X}'.format(ord(text[y]) ^ s[(s[i] + s[j]) % 256])
66+
67+
return ct
68+
69+
def authenticate(self, user, password):
70+
self.get_temp_session_key()
71+
72+
data = {
73+
'sid': self.session_id,
74+
'cmd': 'login',
75+
'login_user': self.rc4(self.session_key, user),
76+
'login_pass': hashlib.md5((self.session_key + password).encode()).hexdigest().upper()
77+
}
78+
79+
post_response = self.http_post("{}/login_sdk.xml".format(self.base_url), data)
80+
xml = ET.fromstring(post_response)
81+
82+
self.session_id = xml.find(".//CONNECTION").get("session")
83+
self.serial = xml.find(".//DEVICE").get("serial")
84+
timeout_secs = int(xml.find(".//CONNECTION").get("timeout"))
85+
86+
self.username = xml.find(".//SDK_CFG").get("username")
87+
88+
try:
89+
self.timeout = datetime.datetime.now() + datetime.timedelta(seconds=timeout_secs)
90+
except Exception:
91+
self.timeout = datetime.datetime.now()
92+
93+
print(self)
94+
95+
self.session_key = hashlib.md5((self.serial + self.session_id).encode()).hexdigest().upper()
96+
return True
97+
98+
def get_users(self):
99+
"""Retrieves a list of all current users."""
100+
data = {
101+
'sid': self.session_id,
102+
'cmd': 'list_users',
103+
}
104+
response = self.http_post("{}/users_sdk.xml".format(self.base_url), data)
105+
106+
try:
107+
xml = ET.fromstring(response)
108+
except Exception:
109+
pprint.pprint(response)
110+
return None
111+
112+
users = []
113+
for user in xml.findall(".//USER"):
114+
users.append({
115+
"id": user.get("id"),
116+
"name": user.get("name"),
117+
"role": user.get("role"),
118+
})
119+
return users
120+
121+
def get_schedules(self):
122+
"""Retrieves a list of all schedules."""
123+
data = {
124+
'sid': self.session_id,
125+
'cmd': 'list_schedules',
126+
}
127+
response = self.http_post("{}/schedules_sdk.xml".format(self.base_url), data)
128+
xml = ET.fromstring(response)
129+
130+
schedules = []
131+
for schedule in xml.findall(".//SCHEDULE"):
132+
schedules.append({
133+
"id": schedule.get("id"),
134+
"name": schedule.get("name"),
135+
})
136+
return schedules
137+
138+
def get_events(self, schedule_id):
139+
"""Retrieves a list of all events for a given schedule."""
140+
data = {
141+
'sid': self.session_id,
142+
'cmd': 'list_events',
143+
'schedule_id': schedule_id,
144+
}
145+
response = self.http_post("{}/events_sdk.xml".format(self.base_url), data)
146+
xml = ET.fromstring(response)
147+
148+
events = []
149+
for event in xml.findall(".//EVENT"):
150+
events.append(AtriumEvent(
151+
event_id=event.get("id"),
152+
name=event.get("name"),
153+
start_time=event.get("start_time"),
154+
end_time=event.get("end_time"),
155+
))
156+
return events
157+
158+
def add_events(self, schedule_id, events):
159+
"""Adds one or more events to a schedule."""
160+
if not isinstance(events, list):
161+
events = [events]
162+
163+
event_data = []
164+
for event in events:
165+
event_data.append({
166+
"event_id": event.event_id,
167+
"name": event.name,
168+
"start_time": event.start_time,
169+
"end_time": event.end_time,
170+
})
171+
172+
data = {
173+
'sid': self.session_id,
174+
'cmd': 'add_events',
175+
'schedule_id': schedule_id,
176+
'events': event_data,
177+
}
178+
response = self.http_post("{}/events_sdk.xml".format(self.base_url), data)
179+
return "SUCCESS" in response
180+
181+
def remove_events(self, schedule_id, event_ids):
182+
"""Removes one or more events from a schedule."""
183+
if not isinstance(event_ids, list):
184+
event_ids = [event_ids]
185+
186+
data = {
187+
'sid': self.session_id,
188+
'cmd': 'remove_events',
189+
'schedule_id': schedule_id,
190+
'event_ids': event_ids,
191+
}
192+
response = self.http_post("{}/events_sdk.xml".format(self.base_url), data)
193+
return "SUCCESS" in response
194+
195+
# Example usage:
196+
a = Atrium("http://publicUrlForAtrium")
197+
a.authenticate("admin", "admin")
198+
199+
pprint.pprint(a.get_users())
200+
201+
# pprint.pprint(a.get_schedules())

0 commit comments

Comments
 (0)