@@ -36,19 +36,24 @@ class ParseJSONError(Exception):
36
36
"""Exception for JSON parsing errors."""
37
37
38
38
39
+ class HTTPError (Exception ):
40
+ """Exception for HTTP errors."""
41
+
42
+
39
43
class OpenEVSE :
40
44
"""Represent an OpenEVSE charger."""
41
45
42
46
def __init__ (self , host : str , user : str = None , pwd : str = None ) -> None :
43
- """Connect to an OpenEVSE charger equipped with a wifi or ethernet."""
47
+ """Connect to an OpenEVSE charger equipped with wifi or ethernet."""
44
48
self ._user = user
45
49
self ._pwd = pwd
46
50
self ._url = f"http://{ host } "
47
51
self ._status = None
48
52
self ._config = None
53
+ self ._override = None
49
54
50
55
def send_command (self , command : str ) -> tuple | None :
51
- """Send a command via HTTP to the charger and prases the response."""
56
+ """Send a RAPI command to the charger and parses the response."""
52
57
url = f"{ self ._url } /r"
53
58
data = {"json" : 1 , "rapi" : command }
54
59
@@ -90,6 +95,94 @@ def update(self) -> None:
90
95
else :
91
96
self ._config = value .json ()
92
97
98
+ def get_override (self ) -> None :
99
+ """Get the manual override status."""
100
+ url = f"{ self ._url } /overrride"
101
+
102
+ _LOGGER .debug ("Geting data from %s" , url )
103
+ if self ._user is not None :
104
+ value = requests .get (url , auth = (self ._user , self ._pwd ))
105
+ else :
106
+ value = requests .get (url )
107
+
108
+ if value .status_code == 401 :
109
+ _LOGGER .debug ("Authentication error: %s" , value )
110
+ raise AuthenticationError
111
+
112
+ self ._override = value .json ()
113
+
114
+ def set_override (
115
+ self ,
116
+ state : str ,
117
+ charge_current : int ,
118
+ max_current : int ,
119
+ energy_limit : int ,
120
+ time_limit : int ,
121
+ auto_release : bool = True ,
122
+ ) -> str :
123
+ """Set the manual override status."""
124
+ url = f"{ self ._url } /overrride"
125
+
126
+ if state not in ["active" , "disabled" ]:
127
+ raise ValueError
128
+
129
+ data = {
130
+ "state" : state ,
131
+ "charge_current" : charge_current ,
132
+ "max_current" : max_current ,
133
+ "energy_limit" : energy_limit ,
134
+ "time_limit" : time_limit ,
135
+ "auto_release" : auto_release ,
136
+ }
137
+
138
+ _LOGGER .debug ("Setting override config on %s" , url )
139
+ if self ._user is not None :
140
+ value = requests .post (url , data = data , auth = (self ._user , self ._pwd ))
141
+ else :
142
+ value = requests .post (url , data = data )
143
+
144
+ if value .status_code == 401 :
145
+ _LOGGER .debug ("Authentication error: %s" , value )
146
+ raise AuthenticationError
147
+
148
+ return value ["msg" ]
149
+
150
+ def toggle_override (self ) -> None :
151
+ """Toggle the manual override status."""
152
+ url = f"{ self ._url } /overrride"
153
+
154
+ _LOGGER .debug ("Toggling manual override %s" , url )
155
+ if self ._user is not None :
156
+ value = requests .patch (url , auth = (self ._user , self ._pwd ))
157
+ else :
158
+ value = requests .patch (url )
159
+
160
+ if value .status_code == 401 :
161
+ _LOGGER .debug ("Authentication error: %s" , value )
162
+ raise AuthenticationError
163
+
164
+ if value .status_code != 200 :
165
+ _LOGGER .error ("Problem handling request: %s" , value )
166
+ raise HTTPError
167
+
168
+ def clear_override (self ) -> None :
169
+ """Clear the manual override status."""
170
+ url = f"{ self ._url } /overrride"
171
+
172
+ _LOGGER .debug ("Clearing manual overrride %s" , url )
173
+ if self ._user is not None :
174
+ value = requests .delete (url , auth = (self ._user , self ._pwd ))
175
+ else :
176
+ value = requests .delete (url )
177
+
178
+ if value .status_code == 401 :
179
+ _LOGGER .debug ("Authentication error: %s" , value )
180
+ raise AuthenticationError
181
+
182
+ if value .status_code != 200 :
183
+ _LOGGER .error ("Problem handling request: %s" , value )
184
+ raise HTTPError
185
+
93
186
@property
94
187
def hostname (self ) -> str :
95
188
"""Return charger hostname."""
@@ -214,6 +307,12 @@ def status(self) -> str:
214
307
return self ._status ["status" ]
215
308
return states [int (self ._status ["state" ])]
216
309
310
+ @property
311
+ def state (self ) -> str :
312
+ """Return charger's state."""
313
+ assert self ._status is not None
314
+ return states [int (self ._status ["state" ])]
315
+
217
316
@property
218
317
def charge_time_elapsed (self ) -> int :
219
318
"""Return elapsed charging time."""
@@ -315,6 +414,18 @@ def protocol_version(self) -> str:
315
414
assert self ._config is not None
316
415
return self ._config ["protocol" ]
317
416
417
+ @property
418
+ def vehicle (self ) -> str :
419
+ """Return if a vehicle is connected dto the EVSE."""
420
+ assert self ._status is not None
421
+ return self ._status ["vehicle" ]
422
+
423
+ @property
424
+ def ota_update (self ) -> str :
425
+ """Return if an OTA update is active."""
426
+ assert self ._status is not None
427
+ return self ._status ["ota_update" ]
428
+
318
429
# There is currently no min/max amps JSON data
319
430
# available via HTTP API methods
320
431
@property
0 commit comments