forked from miniconfig/python-openevse-wifi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
294 lines (253 loc) · 9.05 KB
/
__init__.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
import urllib.request
import urllib.parse
import re
import datetime
_version = '0.1'
states = {
0: 'unknown',
1: 'not connected',
2: 'connected',
3: 'charging',
4: 'vent required',
5: 'diode check failed',
6: 'gfci fault',
7: 'no ground',
8: 'stuck relay',
9: 'gfci self-test failure',
10: 'over temperature',
254: 'sleeping',
255: 'disabled'
}
colors = ['off','red','green','yellow','blue','violet','teal','white']
class Charger:
def __init__(self, host):
"""A connection to an OpenEVSE charging station equipped with the wifi kit."""
self.url = 'http://' + host + '/r?'
def sendCommand(self, command):
"""Sends a command through the web interface of the charger and parses the response"""
data = { 'rapi' : command }
full_url = self.url + urllib.parse.urlencode(data)
data = urllib.request.urlopen(full_url)
response = re.search('\<p>>\$(.+)\<script', data.read().decode('utf-8'))
if response == None:#If we are using version 1 - https://github.com/OpenEVSE/ESP8266_WiFi_v1.x/blob/master/OpenEVSE_RAPI_WiFi_ESP8266.ino#L357
response = re.search('\>\>\$(.+)\<p>', data.read().decode('utf-8'))
return response.group(1).split()
def getStatus(self):
"""Returns the charger's charge status, as a string"""
command = '$GS'
status = self.sendCommand(command)
return states[int(status[1])]
def getChargeTimeElapsed(self):
"""Returns the charge time elapsed (in seconds), or 0 if is not currently charging"""
command = '$GS'
status = self.sendCommand(command)
if int(status[1]) == 3:
return int(status[2])
else:
return 0
def getTimeLimit(self):
"""Returns the time limit in minutes or 0 if no limit is set"""
command = '$G3'
limit = self.sendCommand(command)
return int(limit[1])*15
def getAmmeterScaleFactor(self):
"""Returns the ammeter's current scale factor"""
command = '$GA'
settings = self.sendCommand(command)
return int(settings[1])
def getAmmeterOffset(self):
"""Returns the ammeter's current offset"""
command = '$GA'
settings = self.sendCommand(command)
return int(settings[2])
def getMinAmps(self):
"""Returns the capacity range minimum, in amps"""
command = '$GC'
caprange = self.sendCommand(command)
return int(caprange[1])
def getMaxAmps(self):
"""Returns the capacity range maximum, in amps"""
command = '$GC'
caprange = self.sendCommand(command)
return int(caprange[2])
def getCurrentCapacity(self):
"""Returns the current capacity, in amps"""
command = '$GE'
settings = self.sendCommand(command)
return int(settings[1])
def getServiceLevel(self):
"""Returns the service level"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return (flags & 0x0001) + 1
def getDiodeCheckEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0002)
def getVentRequiredEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0004)
def getGroundCheckEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0008)
def getStuckRelayCheckEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0010)
def getAutoServiceLevelEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0020)
def getAutoStartEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0040)
def getSerialDebugEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0080)
def getLCDType(self):
"""Returns LCD type as a string, either monochrome or rgb"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
if flags & 0x0100:
lcdtype = 'monochrome'
else:
lcdtype = 'rgb'
return lcdtype
def getGFISelfTestEnabled(self):
"""Returns True if enabled, False if disabled"""
command = '$GE'
settings = self.sendCommand(command)
flags = int(settings[2], 16)
return not (flags & 0x0200)
def getGFITripCount(self):
"""Returns GFI Trip Count, as integer"""
command = '$GF'
faults = self.sendCommand(command)
return faults[1]
def getNoGndTripCount(self):
"""Returns No Ground Trip Count, as integer"""
command = '$GF'
faults = self.sendCommand(command)
return faults[2]
def getStuckRelayTripCount(self):
"""Returns Stuck Relay Trip Count, as integer"""
command = '$GF'
faults = self.sendCommand(command)
return faults[3]
def getChargingCurrent(self):
"""Returns the charging current, in amps, or 0.0 of not charging"""
command = '$GG'
currentAndVoltage = self.sendCommand(command)
amps = float(currentAndVoltage[1])/1000
return amps
def getChargingVoltage(self):
"""Returns the charging voltage, in volts, or 0.0 of not charging"""
command = '$GG'
currentAndVoltage = self.sendCommand(command)
volts = float(currentAndVoltage[2])/1000
return volts
def getChargeLimit(self):
"""Returns the charge limit in kWh"""
command = '$GH'
limit = self.sendCommand(command)
return limit[1]
def getVoltMeterScaleFactor(self):
"""Returns the voltmeter scale factor, or 0 if there is no voltmeter"""
command = '$GM'
voltMeterSettings = self.sendCommand(command)
if voltMeterSettings[0] == 'NK':
return 0
else:
return voltMeterSettings[1]
def getVoltMeterOffset(self):
"""Returns the voltmeter offset, or 0 if there is no voltmeter"""
command = '$GM'
voltMeterSettings = self.sendCommand(command)
if voltMeterSettings[0] == 'NK':
return 0
else:
return voltMeterSettings[2]
def getAmbientThreshold(self):
"""Returns the ambient temperature threshold in degrees Celcius, or 0 if no Threshold is set"""
command = '$GO'
threshold = self.sendCommand(command)
if threshold[0] == 'NK':
return 0
else:
return float(threshold[1])/10
def getIRThreshold(self):
"""Returns the IR temperature threshold in degrees Celcius, or 0 if no Threshold is set"""
command = '$GO'
threshold = self.sendCommand(command)
if threshold[0] == 'NK':
return 0
else:
return float(threshold[2])/10
def getRTCTemperature(self):
"""Returns the temperature of the real time clock sensor (DS3231), in degrees Celcius, or 0.0 if sensor is not installed"""
command = '$GP'
temperature = self.sendCommand(command)
return float(temperature[1])/10
def getAmbientTemperature(self):
"""Returns the temperature of the ambient sensor (MCP9808), in degrees Celcius, or 0.0 if sensor is not installed"""
command = '$GP'
temperature = self.sendCommand(command)
return float(temperature[2])/10
def getIRTemperature(self):
"""Returns the temperature of the IR remote sensor (TMP007), in degrees Celcius, or 0.0 if sensor is not installed"""
command = '$GP'
temperature = self.sendCommand(command)
return float(temperature[3])/10
def getTime(self):
"""Get the RTC time. Returns a datetime object, or NULL if the clock is not set"""
command = '$GT'
time = self.sendCommand(command)
if time == ['OK','165', '165', '165', '165', '165', '85']:
return NULL
else:
return datetime.datetime(year = int(time[1])+2000,
month = int(time[2]),
day = int(time[3]),
hour = int(time[4]),
minute = int(time[5]),
second = int(time[6]))
def getUsageSession(self):
"""Get the energy usage for the current charging session. Returns the energy usage in Wh"""
command = '$GU'
usage = self.sendCommand(command)
return float(usage[1])/3600
def getUsageTotal(self):
"""Get the total energy usage. Returns the energy usage in Wh"""
command = '$GU'
usage = self.sendCommand(command)
return float(usage[2])
def getFirmwareVersion(self):
"""Returns the Firmware Version, as a string"""
command = '$GV'
version = self.sendCommand(command)
return version[1]
def getProtocolVersion(self):
"""Returns the Protocol Version, as a string"""
command = '$GV'
version = self.sendCommand(command)
return version[2]