Skip to content

Commit b669117

Browse files
authored
feat: add product v4 and downloading code (#267)
* feat: add product v4 and downloading code * fix: remove got message
1 parent e42729a commit b669117

File tree

3 files changed

+58
-30
lines changed

3 files changed

+58
-30
lines changed

roborock/containers.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -893,26 +893,28 @@ class RoborockProductSpec(RoborockBase):
893893

894894
@dataclass
895895
class RoborockProduct(RoborockBase):
896-
id: int
897-
name: str
898-
model: str
899-
packagename: str
900-
ssid: str
901-
picurl: str
902-
cardpicurl: str
903-
medium_cardpicurl: str
904-
resetwifipicurl: str
905-
resetwifitext: dict
906-
tuyaid: str
907-
status: int
908-
rriotid: str
909-
cardspec: str
910-
pictures: list
911-
nc_mode: str
912-
scope: None
913-
product_tags: list
914-
agreements: list
915-
plugin_pic_url: None
896+
id: int | None = None
897+
name: str | None = None
898+
model: str | None = None
899+
packagename: str | None = None
900+
ssid: str | None = None
901+
picurl: str | None = None
902+
cardpicurl: str | None = None
903+
mediumCardpicurl: str | None = None
904+
resetwifipicurl: str | None = None
905+
configPicUrl: str | None = None
906+
pluginPicUrl: str | None = None
907+
resetwifitext: dict | None = None
908+
tuyaid: str | None = None
909+
status: int | None = None
910+
rriotid: str | None = None
911+
pictures: list | None = None
912+
ncMode: str | None = None
913+
scope: str | None = None
914+
product_tags: list | None = None
915+
agreements: list | None = None
916+
cardspec: str | None = None
917+
plugin_pic_url: str | None = None
916918
products_specification: RoborockProductSpec | None = None
917919

918920
def __post_init__(self):

roborock/version_1_apis/roborock_client_v1.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,12 @@ def on_message_received(self, messages: list[RoborockMessage]) -> None:
421421
consumable = Consumable.from_dict(value)
422422
for listener in self.listener_model.protocol_handlers.get(data_protocol, []):
423423
listener(consumable)
424+
else:
425+
self._logger.warning(
426+
f"Unknown data protocol {data_point_number}, please create an "
427+
f"issue on the python-roborock repository"
428+
)
429+
self._logger.info(data)
424430
return
425431
except ValueError:
426432
self._logger.warning(

roborock/web_api.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async def _get_base_url(self) -> str:
5454
raise RoborockMissingParameters(
5555
"You are missing parameters for this request, are you sure you " "entered your username?"
5656
)
57-
raise RoborockUrlException(response.get("error"))
57+
raise RoborockUrlException(f"error code: {response_code} msg: {response.get('error')}")
5858
response_data = response.get("data")
5959
if response_data is None:
6060
raise RoborockUrlException("response does not have 'data'")
@@ -276,7 +276,7 @@ async def get_products(self, user_data: UserData) -> ProductResponse:
276276
product_request = PreparedRequest(base_url, {"header_clientid": header_clientid})
277277
product_response = await product_request.request(
278278
"get",
279-
"/api/v3/product",
279+
"/api/v4/product",
280280
headers={"Authorization": user_data.token},
281281
)
282282
if product_response is None:
@@ -288,24 +288,44 @@ async def get_products(self, user_data: UserData) -> ProductResponse:
288288
return ProductResponse.from_dict(result)
289289
raise RoborockException("product result was an unexpected type")
290290

291+
async def download_code(self, user_data: UserData, product_id: int):
292+
base_url = await self._get_base_url()
293+
header_clientid = self._get_header_client_id()
294+
product_request = PreparedRequest(base_url, {"header_clientid": header_clientid})
295+
request = {"apilevel": 99999, "productids": [product_id], "type": 2}
296+
response = await product_request.request(
297+
"post",
298+
"/api/v1/appplugin",
299+
json=request,
300+
headers={"Authorization": user_data.token, "Content-Type": "application/json"},
301+
)
302+
return response["data"][0]["url"]
303+
304+
async def download_category_code(self, user_data: UserData):
305+
base_url = await self._get_base_url()
306+
header_clientid = self._get_header_client_id()
307+
product_request = PreparedRequest(base_url, {"header_clientid": header_clientid})
308+
response = await product_request.request(
309+
"get",
310+
"api/v1/plugins?apiLevel=99999&type=2",
311+
headers={
312+
"Authorization": user_data.token,
313+
},
314+
)
315+
return {r["category"]: r["url"] for r in response["data"]["categoryPluginList"]}
316+
291317

292318
class PreparedRequest:
293319
def __init__(self, base_url: str, base_headers: dict | None = None) -> None:
294320
self.base_url = base_url
295321
self.base_headers = base_headers or {}
296322

297-
async def request(self, method: str, url: str, params=None, data=None, headers=None) -> dict:
323+
async def request(self, method: str, url: str, params=None, data=None, headers=None, json=None) -> dict:
298324
_url = "/".join(s.strip("/") for s in [self.base_url, url])
299325
_headers = {**self.base_headers, **(headers or {})}
300326
async with aiohttp.ClientSession() as session:
301327
try:
302-
async with session.request(
303-
method,
304-
_url,
305-
params=params,
306-
data=data,
307-
headers=_headers,
308-
) as resp:
328+
async with session.request(method, _url, params=params, data=data, headers=_headers, json=json) as resp:
309329
return await resp.json()
310330
except ContentTypeError as err:
311331
"""If we get an error, lets log everything for debugging."""

0 commit comments

Comments
 (0)