2020-05-27 17:02:09 +00:00
|
|
|
"""python-kasa exceptions."""
|
2024-04-16 18:21:20 +00:00
|
|
|
|
2024-04-17 13:39:24 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
from asyncio import TimeoutError as _asyncioTimeoutError
|
2023-12-10 15:41:53 +00:00
|
|
|
from enum import IntEnum
|
2024-06-30 09:49:59 +00:00
|
|
|
from functools import cache
|
2024-04-17 13:39:24 +00:00
|
|
|
from typing import Any
|
2020-05-27 17:02:09 +00:00
|
|
|
|
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
class KasaException(Exception):
|
|
|
|
"""Base exception for library errors."""
|
2023-08-29 13:04:28 +00:00
|
|
|
|
2023-12-20 19:16:23 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
class TimeoutError(KasaException, _asyncioTimeoutError):
|
|
|
|
"""Timeout exception for device errors."""
|
2023-08-29 13:04:28 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return KasaException.__repr__(self)
|
2023-09-13 13:46:38 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
def __str__(self):
|
|
|
|
return KasaException.__str__(self)
|
2023-12-19 12:50:33 +00:00
|
|
|
|
2023-09-13 13:46:38 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
class _ConnectionError(KasaException):
|
|
|
|
"""Connection exception for device errors."""
|
2023-12-10 15:41:53 +00:00
|
|
|
|
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
class UnsupportedDeviceError(KasaException):
|
|
|
|
"""Exception for trying to connect to unsupported devices."""
|
2023-12-10 15:41:53 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
|
|
self.discovery_result = kwargs.get("discovery_result")
|
2024-10-22 17:09:35 +00:00
|
|
|
self.host = kwargs.get("host")
|
2024-02-21 15:52:55 +00:00
|
|
|
super().__init__(*args)
|
2024-01-03 18:26:52 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
|
|
|
|
class DeviceError(KasaException):
|
|
|
|
"""Base exception for device errors."""
|
|
|
|
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
2024-04-17 13:39:24 +00:00
|
|
|
self.error_code: SmartErrorCode | None = kwargs.get("error_code", None)
|
2024-02-21 15:52:55 +00:00
|
|
|
super().__init__(*args)
|
2023-12-10 15:41:53 +00:00
|
|
|
|
2024-01-19 20:06:50 +00:00
|
|
|
def __repr__(self):
|
2024-02-21 15:52:55 +00:00
|
|
|
err_code = self.error_code.__repr__() if self.error_code else ""
|
|
|
|
return f"{self.__class__.__name__}({err_code})"
|
2024-01-19 20:06:50 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
2024-02-21 15:52:55 +00:00
|
|
|
err_code = f" (error_code={self.error_code.name})" if self.error_code else ""
|
|
|
|
return super().__str__() + err_code
|
2024-01-19 20:06:50 +00:00
|
|
|
|
2023-12-10 15:41:53 +00:00
|
|
|
|
2024-02-21 15:52:55 +00:00
|
|
|
class AuthenticationError(DeviceError):
|
|
|
|
"""Base exception for device authentication errors."""
|
|
|
|
|
|
|
|
|
|
|
|
class _RetryableError(DeviceError):
|
|
|
|
"""Retryable exception for device errors."""
|
2024-01-18 09:57:33 +00:00
|
|
|
|
|
|
|
|
2023-12-10 15:41:53 +00:00
|
|
|
class SmartErrorCode(IntEnum):
|
|
|
|
"""Enum for SMART Error Codes."""
|
|
|
|
|
2024-02-15 18:10:34 +00:00
|
|
|
def __str__(self):
|
|
|
|
return f"{self.name}({self.value})"
|
|
|
|
|
2024-06-30 09:49:59 +00:00
|
|
|
@staticmethod
|
|
|
|
@cache
|
|
|
|
def from_int(value: int) -> SmartErrorCode:
|
|
|
|
"""Convert an integer to a SmartErrorCode."""
|
|
|
|
return SmartErrorCode(value)
|
|
|
|
|
2023-12-10 15:41:53 +00:00
|
|
|
SUCCESS = 0
|
|
|
|
|
|
|
|
# Transport Errors
|
|
|
|
SESSION_TIMEOUT_ERROR = 9999
|
|
|
|
MULTI_REQUEST_FAILED_ERROR = 1200
|
|
|
|
HTTP_TRANSPORT_FAILED_ERROR = 1112
|
|
|
|
LOGIN_FAILED_ERROR = 1111
|
|
|
|
HAND_SHAKE_FAILED_ERROR = 1100
|
2024-01-23 23:12:01 +00:00
|
|
|
#: Real description unknown, seen after an encryption-changing fw upgrade
|
|
|
|
TRANSPORT_UNKNOWN_CREDENTIALS_ERROR = 1003
|
2023-12-10 15:41:53 +00:00
|
|
|
TRANSPORT_NOT_AVAILABLE_ERROR = 1002
|
|
|
|
CMD_COMMAND_CANCEL_ERROR = 1001
|
|
|
|
NULL_TRANSPORT_ERROR = 1000
|
|
|
|
|
|
|
|
# Common Method Errors
|
|
|
|
COMMON_FAILED_ERROR = -1
|
|
|
|
UNSPECIFIC_ERROR = -1001
|
|
|
|
UNKNOWN_METHOD_ERROR = -1002
|
|
|
|
JSON_DECODE_FAIL_ERROR = -1003
|
|
|
|
JSON_ENCODE_FAIL_ERROR = -1004
|
|
|
|
AES_DECODE_FAIL_ERROR = -1005
|
|
|
|
REQUEST_LEN_ERROR_ERROR = -1006
|
|
|
|
CLOUD_FAILED_ERROR = -1007
|
|
|
|
PARAMS_ERROR = -1008
|
|
|
|
INVALID_PUBLIC_KEY_ERROR = -1010 # Unverified
|
|
|
|
SESSION_PARAM_ERROR = -1101
|
|
|
|
|
|
|
|
# Method Specific Errors
|
|
|
|
QUICK_SETUP_ERROR = -1201
|
|
|
|
DEVICE_ERROR = -1301
|
|
|
|
DEVICE_NEXT_EVENT_ERROR = -1302
|
|
|
|
FIRMWARE_ERROR = -1401
|
|
|
|
FIRMWARE_VER_ERROR_ERROR = -1402
|
|
|
|
LOGIN_ERROR = -1501
|
|
|
|
TIME_ERROR = -1601
|
|
|
|
TIME_SYS_ERROR = -1602
|
|
|
|
TIME_SAVE_ERROR = -1603
|
|
|
|
WIRELESS_ERROR = -1701
|
|
|
|
WIRELESS_UNSUPPORTED_ERROR = -1702
|
|
|
|
SCHEDULE_ERROR = -1801
|
|
|
|
SCHEDULE_FULL_ERROR = -1802
|
|
|
|
SCHEDULE_CONFLICT_ERROR = -1803
|
|
|
|
SCHEDULE_SAVE_ERROR = -1804
|
|
|
|
SCHEDULE_INDEX_ERROR = -1805
|
|
|
|
COUNTDOWN_ERROR = -1901
|
|
|
|
COUNTDOWN_CONFLICT_ERROR = -1902
|
|
|
|
COUNTDOWN_SAVE_ERROR = -1903
|
|
|
|
ANTITHEFT_ERROR = -2001
|
|
|
|
ANTITHEFT_CONFLICT_ERROR = -2002
|
|
|
|
ANTITHEFT_SAVE_ERROR = -2003
|
|
|
|
ACCOUNT_ERROR = -2101
|
|
|
|
STAT_ERROR = -2201
|
|
|
|
STAT_SAVE_ERROR = -2202
|
|
|
|
DST_ERROR = -2301
|
|
|
|
DST_SAVE_ERROR = -2302
|
|
|
|
|
2024-10-23 19:07:32 +00:00
|
|
|
SYSTEM_ERROR = -40101
|
|
|
|
INVALID_ARGUMENTS = -40209
|
|
|
|
|
|
|
|
# Camera error codes
|
|
|
|
SESSION_EXPIRED = -40401
|
|
|
|
HOMEKIT_LOGIN_FAIL = -40412
|
|
|
|
DEVICE_BLOCKED = -40404
|
|
|
|
DEVICE_FACTORY = -40405
|
|
|
|
OUT_OF_LIMIT = -40406
|
|
|
|
OTHER_ERROR = -40407
|
|
|
|
SYSTEM_BLOCKED = -40408
|
|
|
|
NONCE_EXPIRED = -40409
|
|
|
|
FFS_NONE_PWD = -90000
|
|
|
|
TIMEOUT_ERROR = 40108
|
|
|
|
UNSUPPORTED_METHOD = -40106
|
|
|
|
ONE_SECOND_REPEAT_REQUEST = -40109
|
|
|
|
INVALID_NONCE = -40413
|
|
|
|
PROTOCOL_FORMAT_ERROR = -40210
|
|
|
|
IP_CONFLICT = -40321
|
|
|
|
DIAGNOSE_TYPE_NOT_SUPPORT = -69051
|
|
|
|
DIAGNOSE_TASK_FULL = -69052
|
|
|
|
DIAGNOSE_TASK_BUSY = -69053
|
|
|
|
DIAGNOSE_INTERNAL_ERROR = -69055
|
|
|
|
DIAGNOSE_ID_NOT_FOUND = -69056
|
|
|
|
DIAGNOSE_TASK_NULL = -69057
|
|
|
|
CLOUD_LINK_DOWN = -69060
|
|
|
|
ONVIF_SET_WRONG_TIME = -69061
|
|
|
|
CLOUD_NTP_NO_RESPONSE = -69062
|
|
|
|
CLOUD_GET_WRONG_TIME = -69063
|
|
|
|
SNTP_SRV_NO_RESPONSE = -69064
|
|
|
|
SNTP_GET_WRONG_TIME = -69065
|
|
|
|
LINK_UNCONNECTED = -69076
|
|
|
|
WIFI_SIGNAL_WEAK = -69077
|
|
|
|
LOCAL_NETWORK_POOR = -69078
|
|
|
|
CLOUD_NETWORK_POOR = -69079
|
|
|
|
INTER_NETWORK_POOR = -69080
|
|
|
|
DNS_TIMEOUT = -69081
|
|
|
|
DNS_ERROR = -69082
|
|
|
|
PING_NO_RESPONSE = -69083
|
|
|
|
DHCP_MULTI_SERVER = -69084
|
|
|
|
DHCP_ERROR = -69085
|
|
|
|
STREAM_SESSION_CLOSE = -69094
|
|
|
|
STREAM_BITRATE_EXCEPTION = -69095
|
|
|
|
STREAM_FULL = -69096
|
|
|
|
STREAM_NO_INTERNET = -69097
|
|
|
|
HARDWIRED_NOT_FOUND = -72101
|
|
|
|
|
2024-06-27 14:58:45 +00:00
|
|
|
# Library internal for unknown error codes
|
|
|
|
INTERNAL_UNKNOWN_ERROR = -100_000
|
2024-07-11 15:21:59 +00:00
|
|
|
# Library internal for query errors
|
|
|
|
INTERNAL_QUERY_ERROR = -100_001
|
2024-06-27 14:58:45 +00:00
|
|
|
|
2023-12-10 15:41:53 +00:00
|
|
|
|
|
|
|
SMART_RETRYABLE_ERRORS = [
|
|
|
|
SmartErrorCode.TRANSPORT_NOT_AVAILABLE_ERROR,
|
|
|
|
SmartErrorCode.HTTP_TRANSPORT_FAILED_ERROR,
|
|
|
|
SmartErrorCode.UNSPECIFIC_ERROR,
|
2024-02-21 15:52:55 +00:00
|
|
|
SmartErrorCode.SESSION_TIMEOUT_ERROR,
|
2024-10-23 19:07:32 +00:00
|
|
|
SmartErrorCode.SESSION_EXPIRED,
|
2024-10-25 18:27:40 +00:00
|
|
|
SmartErrorCode.INVALID_NONCE,
|
2023-12-10 15:41:53 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
SMART_AUTHENTICATION_ERRORS = [
|
|
|
|
SmartErrorCode.LOGIN_ERROR,
|
|
|
|
SmartErrorCode.LOGIN_FAILED_ERROR,
|
|
|
|
SmartErrorCode.AES_DECODE_FAIL_ERROR,
|
|
|
|
SmartErrorCode.HAND_SHAKE_FAILED_ERROR,
|
2024-01-23 23:12:01 +00:00
|
|
|
SmartErrorCode.TRANSPORT_UNKNOWN_CREDENTIALS_ERROR,
|
2024-10-23 19:07:32 +00:00
|
|
|
SmartErrorCode.HOMEKIT_LOGIN_FAIL,
|
2023-12-10 15:41:53 +00:00
|
|
|
]
|