Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions roborock/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@
UserData,
WashTowelMode,
)
from .exceptions import RoborockException, RoborockTimeout, VacuumError
from .exceptions import (
RoborockAccountDoesNotExist,
RoborockException,
RoborockInvalidCode,
RoborockInvalidEmail,
RoborockTimeout,
RoborockUrlException,
VacuumError,
)
from .roborock_future import RoborockFuture
from .roborock_message import RoborockMessage
from .typing import DeviceProp, DockSummary, RoborockCommand
Expand Down Expand Up @@ -345,12 +353,15 @@ async def _get_base_url(self) -> str:
params={"email": self._username, "needtwostepauth": "false"},
)
if response is None:
raise RoborockException("get url by email returned None")
if response.get("code") != 200:
raise RoborockException(response.get("error"))
raise RoborockUrlException("get url by email returned None")
response_code = response.get("code")
if response_code != 200:
if response_code == 2003:
raise RoborockInvalidEmail("Your email was incorrectly formatted.")
raise RoborockUrlException(response.get("error"))
response_data = response.get("data")
if response_data is None:
raise RoborockException("response does not have 'data'")
raise RoborockUrlException("response does not have 'data'")
self.base_url = response_data.get("url")
return self.base_url

Expand All @@ -375,8 +386,12 @@ async def request_code(self) -> None:
)
if code_response is None:
raise RoborockException("Failed to get a response from send email code")
if code_response.get("code") != 200:
raise RoborockException(code_response.get("msg"))
response_code = code_response.get("code")
if response_code != 200:
if response_code == 2008:
raise RoborockAccountDoesNotExist("Account does not exist - check your login and try again.")
else:
raise RoborockException(f"{code_response.get('msg')} - response code: {code_response.get('code')}")

async def pass_login(self, password: str) -> UserData:
base_url = await self._get_base_url()
Expand All @@ -395,7 +410,7 @@ async def pass_login(self, password: str) -> UserData:
if login_response is None:
raise RoborockException("Login response is none")
if login_response.get("code") != 200:
raise RoborockException(login_response.get("msg"))
raise RoborockException(f"{login_response.get('msg')} - response code: {login_response.get('code')}")
user_data = login_response.get("data")
if not isinstance(user_data, dict):
raise RoborockException("Got unexpected data type for user_data")
Expand All @@ -417,8 +432,11 @@ async def code_login(self, code) -> UserData:
)
if login_response is None:
raise RoborockException("Login request response is None")
if login_response.get("code") != 200:
raise RoborockException(login_response.get("msg"))
response_code = login_response.get("code")
if response_code != 200:
if response_code == 2018:
raise RoborockInvalidCode("Invalid code - check your code and try again.")
raise RoborockException(f"{login_response.get('msg')} - response code: {response_code}")
user_data = login_response.get("data")
if not isinstance(user_data, dict):
raise RoborockException("Got unexpected data type for user_data")
Expand All @@ -439,7 +457,7 @@ async def get_home_data(self, user_data: UserData) -> HomeData:
if home_id_response is None:
raise RoborockException("home_id_response is None")
if home_id_response.get("code") != 200:
raise RoborockException(home_id_response.get("msg"))
raise RoborockException(f"{home_id_response.get('msg')} - response code: {home_id_response.get('code')}")

home_id = home_id_response["data"].get("rrHomeId")
timestamp = math.floor(time.time())
Expand Down
5 changes: 5 additions & 0 deletions roborock/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Total time in seconds consumables have before Roborock recommends replacing
MAIN_BRUSH_REPLACE_TIME = 1080000
SIDE_BRUSH_REPLACE_TIME = 720000
FILTER_REPLACE_TIME = 540000
SENSOR_DIRTY_REPLACE_TIME = 108000
15 changes: 15 additions & 0 deletions roborock/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
RoborockFanPowerCode,
RoborockMopModeCode,
)
from .const import FILTER_REPLACE_TIME, MAIN_BRUSH_REPLACE_TIME, SENSOR_DIRTY_REPLACE_TIME, SIDE_BRUSH_REPLACE_TIME


def camelize(s: str):
Expand Down Expand Up @@ -279,6 +280,20 @@ class Consumable(RoborockBase):
strainer_work_times: Optional[int] = None
dust_collection_work_times: Optional[int] = None
cleaning_brush_work_times: Optional[int] = None
main_brush_time_left: Optional[int] = None
side_brush_time_left: Optional[int] = None
filter_time_left: Optional[int] = None
sensor_time_left: Optional[int] = None

def __post_init__(self):
self.main_brush_time_left = (
MAIN_BRUSH_REPLACE_TIME - self.main_brush_work_time if self.main_brush_work_time else None
)
self.side_brush_time_left = (
SIDE_BRUSH_REPLACE_TIME - self.side_brush_work_time if self.side_brush_work_time else None
)
self.filter_time_left = FILTER_REPLACE_TIME - self.filter_work_time if self.filter_work_time else None
self.sensor_time_left = SENSOR_DIRTY_REPLACE_TIME - self.sensor_dirty_time if self.sensor_dirty_time else None


@dataclass
Expand Down
16 changes: 16 additions & 0 deletions roborock/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,19 @@ class CommandVacuumError(RoborockException):
def __init__(self, command: str, vacuum_error: VacuumError):
self.message = f"{command}: {str(vacuum_error)}"
super().__init__(self.message)


class RoborockAccountDoesNotExist(RoborockException):
"""Class for Roborock account does not exist exceptions."""


class RoborockUrlException(RoborockException):
"""Class for being unable to get the URL for the Roborock account."""


class RoborockInvalidCode(RoborockException):
"""Class for Roborock invalid code exceptions."""


class RoborockInvalidEmail(RoborockException):
"""Class for Roborock invalid formatted email exceptions."""
14 changes: 14 additions & 0 deletions roborock/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,17 @@ class DeviceProp:
consumable: Optional[Consumable] = None
last_clean_record: Optional[CleanRecord] = None
dock_summary: Optional[DockSummary] = None

def update(self, device_prop: DeviceProp) -> None:
if device_prop.status:
self.status = device_prop.status
if device_prop.dnd_timer:
self.dnd_timer = device_prop.dnd_timer
if device_prop.clean_summary:
self.clean_summary = device_prop.clean_summary
if device_prop.consumable:
self.consumable = device_prop.consumable
if device_prop.last_clean_record:
self.last_clean_record = device_prop.last_clean_record
if device_prop.dock_summary:
self.dock_summary = device_prop.dock_summary