@@ -36,19 +36,24 @@ class ParseJSONError(Exception):
3636 """Exception for JSON parsing errors."""
3737
3838
39+ class HTTPError (Exception ):
40+ """Exception for HTTP errors."""
41+
42+
3943class OpenEVSE :
4044 """Represent an OpenEVSE charger."""
4145
4246 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."""
4448 self ._user = user
4549 self ._pwd = pwd
4650 self ._url = f"http://{ host } "
4751 self ._status = None
4852 self ._config = None
53+ self ._override = None
4954
5055 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."""
5257 url = f"{ self ._url } /r"
5358 data = {"json" : 1 , "rapi" : command }
5459
@@ -90,6 +95,94 @@ def update(self) -> None:
9095 else :
9196 self ._config = value .json ()
9297
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+
93186 @property
94187 def hostname (self ) -> str :
95188 """Return charger hostname."""
@@ -214,6 +307,12 @@ def status(self) -> str:
214307 return self ._status ["status" ]
215308 return states [int (self ._status ["state" ])]
216309
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+
217316 @property
218317 def charge_time_elapsed (self ) -> int :
219318 """Return elapsed charging time."""
@@ -315,6 +414,18 @@ def protocol_version(self) -> str:
315414 assert self ._config is not None
316415 return self ._config ["protocol" ]
317416
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+
318429 # There is currently no min/max amps JSON data
319430 # available via HTTP API methods
320431 @property
0 commit comments