-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.py
112 lines (100 loc) · 4.09 KB
/
script.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import os
import requests
from requests.auth import HTTPDigestAuth
import re
import hashlib
import time
# Configuration
base_url = None
username = "technician"
password = None
login_endpoint = "/commands/Login"
timeofuse_endpoint = "/config/timeofuse"
referer_url = None
def set_password(pw):
global password
password = pw
def set_base_url(url):
global base_url
base_url = url
def set_referer_url(url):
global referer_url
referer_url = url
def get_nonce(session, login_url):
initial_response = session.get(login_url, headers={'Referer': referer_url})
if initial_response.status_code == 401 and 'X-WWW-Authenticate' in initial_response.headers:
www_authenticate = initial_response.headers['X-WWW-Authenticate']
nonce = re.search('nonce="([^"]+)"', www_authenticate).group(1)
realm = re.search('realm="([^"]+)"', www_authenticate).group(1)
qop = re.search('qop="([^"]+)"', www_authenticate).group(1)
return nonce, realm, qop
else:
raise Exception("Failed to get nonce")
def create_digest_header(nonce, realm, qop, uri, method, username, password, nc, cnonce):
ha1 = hashlib.md5(f"{username}:{realm}:{password}".encode()).hexdigest()
ha2 = hashlib.md5(f"{method}:{uri}".encode()).hexdigest()
response = hashlib.md5(f"{ha1}:{nonce}:{nc:08x}:{cnonce}:{qop}:{ha2}".encode()).hexdigest()
auth_header = (
f'Digest username="{username}", realm="{realm}", nonce="{nonce}", uri="{uri}", '
f'response="{response}", qop={qop}, nc={nc:08x}, cnonce="{cnonce}"'
)
return auth_header
def set_time_of_use(power=None, remove=False):
if remove:
timeofuse_payload = {"timeofuse": []}
else:
timeofuse_payload = {
"timeofuse": [
{
"Active": True,
"Power": power,
"ScheduleType": "CHARGE_MIN",
"TimeTable": {"Start": "00:00", "End": "23:59"},
"Weekdays": {"Mon": True, "Tue": True, "Wed": True, "Thu": True, "Fri": True, "Sat": True, "Sun": True}
}
]
}
# Step 1: Perform an initial request to get the nonce
session = requests.Session()
login_url = f"{base_url}{login_endpoint}?user={username}"
relative_login_url = f"{login_endpoint}?user={username}"
try:
nonce, realm, qop = get_nonce(session, login_url)
except Exception as e:
print(f"Error: {e}")
exit(1)
# Step 2: Create the Digest authentication header
nc = 1
cnonce = hashlib.md5(str(time.time()).encode()).hexdigest()
auth_header = create_digest_header(nonce, realm, qop, relative_login_url, 'GET', username, password, nc, cnonce)
# Step 3: Perform the login request with Digest Authentication
headers = {
'Referer': referer_url,
'Authorization': auth_header
}
login_response = session.get(login_url, headers=headers)
# Check if login was successful
if login_response.status_code == 200:
# Step 4: Use the session to set the time of use settings
timeofuse_url = f"{base_url}{timeofuse_endpoint}"
relative_timeofuse_url = timeofuse_endpoint
nc += 1
auth_header = create_digest_header(nonce, realm, qop, relative_timeofuse_url, 'POST', username, password, nc, cnonce)
headers = {
'Referer': referer_url,
'Authorization': auth_header,
'Content-Type': 'application/json'
}
timeofuse_response = session.post(timeofuse_url, json=timeofuse_payload, headers=headers)
# Check if setting the time of use was successful
if timeofuse_response.status_code == 200:
if remove:
print("Time of Use settings removed successfully.")
else:
print("Time of Use settings updated successfully.")
else:
print(f"Failed to update Time of Use settings. Status code: {timeofuse_response.status_code}")
print(timeofuse_response.text)
else:
print(f"Login failed. Status code: {login_response.status_code}")
print(login_response.text)