Skip to content

Commit 3bfe87e

Browse files
committed
🐛 fix blocking call, fix ssl error
1 parent 387507b commit 3bfe87e

File tree

1 file changed

+26
-86
lines changed

1 file changed

+26
-86
lines changed

custom_components/weback_vacuum/webackapi.py

Lines changed: 26 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
"""
44

55
import asyncio
6-
import configparser
76
import hashlib
87
import json
98
import logging
10-
import os
119
import threading
1210
import time
1311
from datetime import datetime, timedelta
1412

1513
import httpx
1614
import websocket
15+
import ssl
1716

1817
from .vacmap import VacMap
1918

@@ -38,10 +37,6 @@
3837
ACK_TIMEOUT = 5
3938
HTTP_TIMEOUT = 5
4039

41-
# ROOT DIR
42-
CREDS_FILE = "wb_creds"
43-
COMPONENT_DIR = os.path.dirname(os.path.abspath(__file__))
44-
4540

4641
class WebackApi:
4742
"""
@@ -92,16 +87,12 @@ async def login(self) -> bool:
9287
},
9388
}
9489

95-
# Checking if there is cached token and is still valid
96-
if self.verify_cached_creds():
97-
return True
98-
9990
# Checking if the region is China to use the Chinese Auth URL
10091
if self.region == "86":
10192
auth_url_selected = AUTH_URL_CHINA
10293
else:
10394
auth_url_selected = AUTH_URL
104-
95+
10596
resp = await self.send_http(auth_url_selected, **params)
10697

10798
if resp is None:
@@ -125,7 +116,6 @@ async def login(self) -> bool:
125116
self.token_exp = now_date + timedelta(seconds=self.token_duration)
126117
_LOGGER.debug("WebackApi login successful")
127118

128-
self.save_token_file()
129119
return True
130120
if result_msg == SERVICE_ERROR:
131121
# Wrong APP
@@ -147,67 +137,6 @@ async def login(self) -> bool:
147137
_LOGGER.error("WebackApi can't login (reason is: %s)", result_msg)
148138
return False
149139

150-
def verify_cached_creds(self):
151-
"""
152-
Check if cached creds are not outdated
153-
"""
154-
creds_data = self.get_token_file()
155-
if "weback_token" in creds_data:
156-
weback_token = creds_data["weback_token"]
157-
if self.check_token_is_valid(
158-
weback_token.get("token_exp"),
159-
) and self.user == weback_token.get("user"):
160-
# Valid creds to use, loading it
161-
self.jwt_token = weback_token.get("jwt_token")
162-
self.region_name = weback_token.get("region_name")
163-
self.wss_url = weback_token.get("wss_url")
164-
self.api_url = weback_token.get("api_url")
165-
self.token_exp = weback_token.get("token_exp")
166-
_LOGGER.debug("WebackApi use cached creds.")
167-
return True
168-
_LOGGER.debug("WebackApi has no or invalid cached creds, renew it...")
169-
return False
170-
171-
@staticmethod
172-
def get_token_file() -> dict:
173-
"""
174-
Open token file and get all data.
175-
"""
176-
creds_data = {}
177-
try:
178-
config = configparser.ConfigParser()
179-
config.read(os.path.join(COMPONENT_DIR, CREDS_FILE))
180-
creds_data = config._sections
181-
except Exception as get_err:
182-
_LOGGER.debug(
183-
"WebackApi not found or invalid weback creds file error=%s",
184-
get_err,
185-
)
186-
return creds_data
187-
188-
def save_token_file(self):
189-
"""
190-
Save token file with all information
191-
"""
192-
try:
193-
config = configparser.ConfigParser()
194-
config.add_section("weback_token")
195-
config.set("weback_token", "user", str(self.user))
196-
config.set("weback_token", "jwt_token", str(self.jwt_token))
197-
config.set("weback_token", "token_exp", str(self.token_exp))
198-
config.set("weback_token", "api_url", str(self.api_url))
199-
config.set("weback_token", "wss_url", str(self.wss_url))
200-
config.set("weback_token", "region_name", str(self.region_name))
201-
with open(
202-
os.path.join(COMPONENT_DIR, CREDS_FILE),
203-
"w",
204-
encoding="utf-8",
205-
) as configfile:
206-
config.write(configfile)
207-
_LOGGER.debug("WebackApi saved new creds")
208-
except Exception as excpt_msg:
209-
_LOGGER.debug("WebackApi failed to saved new creds details=%s", excpt_msg)
210-
211140
@staticmethod
212141
def check_token_is_valid(token) -> bool:
213142
"""
@@ -277,9 +206,20 @@ async def send_http(url, **params):
277206
"""
278207
_LOGGER.debug("Send HTTP request Url=%s Params=%s", url, params)
279208
timeout = httpx.Timeout(HTTP_TIMEOUT, connect=15.0)
209+
210+
# Create an SSL context that uses asyncio
211+
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
212+
213+
# Load default certs in a non-blocking way
214+
loop = asyncio.get_running_loop()
215+
await loop.run_in_executor(None, ssl_context.load_default_certs)
216+
280217
for attempt in range(N_RETRY):
281218
try:
282-
async with httpx.AsyncClient(timeout=timeout) as client:
219+
async with httpx.AsyncClient(
220+
timeout=timeout,
221+
verify=ssl_context,
222+
) as client:
283223
req = await client.post(url, **params)
284224
if req.status_code == 200:
285225
# Server status OK
@@ -288,7 +228,8 @@ async def send_http(url, **params):
288228
return req.json()
289229
# Server status NOK
290230
_LOGGER.warning(
291-
"WebackApi : Bad server response (status code=%s) retry... (%s/%s)",
231+
"WebackApi : Bad server response (status code=%s) "
232+
"retry... (%s/%s)",
292233
req.status_code,
293234
attempt,
294235
N_RETRY,
@@ -483,9 +424,6 @@ def __init__(self, user, password, region, country, app, client_id, api_version)
483424
self._last_refresh = 0
484425
self.sent_counter = 0
485426

486-
# Reloading cached creds
487-
self.verify_cached_creds()
488-
489427
async def check_credentials(self):
490428
"""
491429
Check if credentials for WSS link are OK
@@ -540,12 +478,13 @@ async def open_wss_thread(self):
540478
if self.wst.is_alive():
541479
_LOGGER.debug("WebackApi (WSS) Thread was init")
542480
return True
543-
_LOGGER.error("WebackApi (WSS) Thread connection init has FAILED")
544-
return False
481+
else:
482+
_LOGGER.error("WebackApi (WSS) Thread connection init has FAILED")
483+
return False
545484

546485
except Exception as e:
547486
self.socket_state = SOCK_ERROR
548-
_LOGGER.debug("WebackApi (WSS) Error while opening socket", e)
487+
_LOGGER.debug("WebackApi (WSS) Error while opening socket %s", e)
549488
return False
550489

551490
async def connect_wss(self):
@@ -616,7 +555,6 @@ def on_message(self, ws, message):
616555
self.map = VacMap(wss_data["map_data"])
617556
else:
618557
self.map.wss_update(wss_data["map_data"])
619-
# self.render_map()
620558
except Exception as msg_excpt:
621559
_LOGGER.error(
622560
"WebackApi (WSS) Error during on_message (map_data) (details=%s)",
@@ -631,7 +569,8 @@ def on_message(self, ws, message):
631569
wss_data,
632570
)
633571

634-
# Close WSS link if we don't need it anymore or it will get closed by remote side
572+
# Close WSS link if we don't need it anymore
573+
# or it will get closed by remote side
635574
if self._refresh_time == 120:
636575
_LOGGER.debug("WebackApi (WSS) Closing WSS...")
637576
self.ws.close()
@@ -654,7 +593,7 @@ async def publish_wss(self, dict_message):
654593
self.ws.close()
655594
self.socket_state = SOCK_CLOSE
656595

657-
for attempt in range(N_RETRY):
596+
for _ in range(N_RETRY):
658597
if self.socket_state == SOCK_CONNECTED:
659598
try:
660599
self.ws.send(json_message)
@@ -669,7 +608,8 @@ async def publish_wss(self, dict_message):
669608
)
670609
else:
671610
_LOGGER.debug(
672-
"WebackApi (WSS) Can't publish message socket_state=%s, reconnecting...",
611+
"WebackApi (WSS) Can't publish message socket_state=%s"
612+
", reconnecting...",
673613
self.socket_state,
674614
)
675615
await self.connect_wss()
@@ -702,7 +642,7 @@ async def send_command(self, thing_name, sub_type, working_payload):
702642
async def force_cmd_refresh(self, thing_name, sub_type):
703643
"""Force refresh"""
704644
_LOGGER.debug("WebackApi (WSS) force refresh after sending cmd...")
705-
for i in range(4):
645+
for _ in range(4):
706646
await asyncio.sleep(0.6)
707647
await self.update_status(thing_name, sub_type)
708648

0 commit comments

Comments
 (0)