Skip to content

Commit a82bc39

Browse files
committed
Allow for a external session.
1 parent cdbca62 commit a82bc39

6 files changed

Lines changed: 551 additions & 1477 deletions

File tree

openevsehttp/__main__.py

Lines changed: 86 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,18 @@
8484
class OpenEVSE:
8585
"""Represent an OpenEVSE charger."""
8686

87-
def __init__(self, host: str, user: str = "", pwd: str = "") -> None:
87+
def __init__(
88+
self,
89+
host: str,
90+
user: str = "",
91+
pwd: str = "",
92+
session: aiohttp.ClientSession | None = None,
93+
) -> None:
8894
"""Connect to an OpenEVSE charger equipped with wifi or ethernet."""
8995
self._user = user
9096
self._pwd = pwd
9197
self.url = f"http://{host}/"
98+
self._session = session
9299
self._status: dict = {}
93100
self._config: dict = {}
94101
self._override = None
@@ -98,6 +105,13 @@ def __init__(self, host: str, user: str = "", pwd: str = "") -> None:
98105
self._loop = None
99106
self.tasks = None
100107

108+
@property
109+
def session(self) -> aiohttp.ClientSession:
110+
"""Return the aiohttp session, creating one if needed."""
111+
if self._session is None:
112+
self._session = aiohttp.ClientSession()
113+
return self._session
114+
101115
async def process_request(
102116
self,
103117
url: str,
@@ -113,61 +127,57 @@ async def process_request(
113127
if self._user and self._pwd:
114128
auth = aiohttp.BasicAuth(self._user, self._pwd)
115129

116-
async with aiohttp.ClientSession() as session:
117-
http_method = getattr(session, method)
118-
_LOGGER.debug(
119-
"Connecting to %s with data: %s rapi: %s using method %s",
130+
http_method = getattr(self.session, method)
131+
_LOGGER.debug(
132+
"Connecting to %s with data: %s rapi: %s using method %s",
133+
url,
134+
data,
135+
rapi,
136+
method,
137+
)
138+
try:
139+
async with http_method(
120140
url,
121-
data,
122-
rapi,
123-
method,
124-
)
125-
try:
126-
async with http_method(
127-
url,
128-
data=rapi,
129-
json=data,
130-
auth=auth,
131-
) as resp:
132-
try:
133-
message = await resp.text()
134-
except UnicodeDecodeError:
135-
_LOGGER.debug("Decoding error")
136-
message = await resp.read()
137-
message = message.decode(errors="replace")
138-
139-
try:
140-
message = json.loads(message)
141-
except ValueError:
142-
_LOGGER.warning("Non JSON response: %s", message)
143-
144-
if resp.status == 400:
145-
index = ""
146-
if "msg" in message.keys():
147-
index = "msg"
148-
elif "error" in message.keys():
149-
index = "error"
150-
_LOGGER.error("Error 400: %s", message[index])
151-
raise ParseJSONError
152-
if resp.status == 401:
153-
_LOGGER.error("Authentication error: %s", message)
154-
raise AuthenticationError
155-
if resp.status in [404, 405, 500]:
156-
_LOGGER.warning("%s", message)
157-
158-
if method == "post" and "config_version" in message:
159-
await self.update()
160-
return message
161-
162-
except (TimeoutError, ServerTimeoutError) as err:
163-
_LOGGER.error("%s: %s", ERROR_TIMEOUT, url)
164-
raise err
165-
except ContentTypeError as err:
166-
_LOGGER.error("Content error: %s", err.message)
167-
raise err
168-
169-
await session.close()
170-
return message
141+
data=rapi,
142+
json=data,
143+
auth=auth,
144+
) as resp:
145+
try:
146+
message = await resp.text()
147+
except UnicodeDecodeError:
148+
_LOGGER.debug("Decoding error")
149+
message = await resp.read()
150+
message = message.decode(errors="replace")
151+
152+
try:
153+
message = json.loads(message)
154+
except ValueError:
155+
_LOGGER.warning("Non JSON response: %s", message)
156+
157+
if resp.status == 400:
158+
index = ""
159+
if "msg" in message.keys():
160+
index = "msg"
161+
elif "error" in message.keys():
162+
index = "error"
163+
_LOGGER.error("Error 400: %s", message[index])
164+
raise ParseJSONError
165+
if resp.status == 401:
166+
_LOGGER.error("Authentication error: %s", message)
167+
raise AuthenticationError
168+
if resp.status in [404, 405, 500]:
169+
_LOGGER.warning("%s", message)
170+
171+
if method == "post" and "config_version" in message:
172+
await self.update()
173+
return message
174+
175+
except (TimeoutError, ServerTimeoutError) as err:
176+
_LOGGER.error("%s: %s", ERROR_TIMEOUT, url)
177+
raise err
178+
except ContentTypeError as err:
179+
_LOGGER.error("Content error: %s", err.message)
180+
raise err
171181

172182
async def send_command(self, command: str) -> tuple:
173183
"""Send a RAPI command to the charger and parses the response."""
@@ -204,7 +214,11 @@ async def update(self) -> None:
204214
if not self.websocket:
205215
# Start Websocket listening
206216
self.websocket = OpenEVSEWebsocket(
207-
self.url, self._update_status, self._user, self._pwd
217+
self.url,
218+
self._update_status,
219+
self._user,
220+
self._pwd,
221+
session=self.session,
208222
)
209223

210224
async def test_and_get(self) -> dict:
@@ -573,23 +587,22 @@ async def firmware_check(self) -> dict | None:
573587
return None
574588

575589
try:
576-
async with aiohttp.ClientSession() as session:
577-
http_method = getattr(session, method)
578-
_LOGGER.debug(
579-
"Connecting to %s using method %s",
580-
url,
581-
method,
582-
)
583-
async with http_method(url) as resp:
584-
if resp.status != 200:
585-
return None
586-
message = await resp.text()
587-
message = json.loads(message)
588-
response = {}
589-
response["latest_version"] = message["tag_name"]
590-
response["release_notes"] = message["body"]
591-
response["release_url"] = message["html_url"]
592-
return response
590+
http_method = getattr(self.session, method)
591+
_LOGGER.debug(
592+
"Connecting to %s using method %s",
593+
url,
594+
method,
595+
)
596+
async with http_method(url) as resp:
597+
if resp.status != 200:
598+
return None
599+
message = await resp.text()
600+
message = json.loads(message)
601+
response = {}
602+
response["latest_version"] = message["tag_name"]
603+
response["release_notes"] = message["body"]
604+
response["release_url"] = message["html_url"]
605+
return response
593606

594607
except (TimeoutError, ServerTimeoutError):
595608
_LOGGER.error("%s: %s", ERROR_TIMEOUT, url)

openevsehttp/websocket.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ def __init__(
3131
callback,
3232
user=None,
3333
password=None,
34+
session=None,
3435
):
3536
"""Initialize a OpenEVSEWebsocket instance."""
36-
self.session = aiohttp.ClientSession()
37+
self._session = session
3738
self.uri = self._get_uri(server)
3839
self._user = user
3940
self._password = password
@@ -45,6 +46,13 @@ def __init__(
4546
self._ping = None
4647
self._pong = None
4748

49+
@property
50+
def session(self):
51+
"""Return the aiohttp session, creating one if needed."""
52+
if self._session is None:
53+
self._session = aiohttp.ClientSession()
54+
return self._session
55+
4856
@property
4957
def state(self):
5058
"""Return the current state."""
@@ -141,7 +149,8 @@ async def listen(self):
141149
async def close(self):
142150
"""Close the listening websocket."""
143151
await OpenEVSEWebsocket.state.fset(self, STATE_STOPPED)
144-
await self.session.close()
152+
if self._client:
153+
await self._client.close()
145154

146155
async def keepalive(self):
147156
"""Send ping requests to websocket."""

0 commit comments

Comments
 (0)