roborock.data.code_mappings
1import logging 2from collections import namedtuple 3from enum import Enum, IntEnum, StrEnum 4from typing import Any, Self 5 6_LOGGER = logging.getLogger(__name__) 7completed_warnings = set() 8 9 10class RoborockEnum(IntEnum): 11 """Roborock Enum for codes with int values""" 12 13 _display_name_: str | None 14 15 def __new__(cls, value: int, display_name: str | None = None) -> Self: 16 member = int.__new__(cls, value) 17 member._value_ = value 18 member._display_name_ = display_name 19 return member 20 21 @property 22 def name(self) -> str: 23 return super().name.lower() 24 25 @property 26 def display_name(self) -> str: 27 return self._display_name_ or self.name 28 29 @classmethod 30 def _missing_(cls: type[Self], key) -> Self: 31 if hasattr(cls, "unknown"): 32 warning = f"Missing {cls.__name__} code: {key} - defaulting to 'unknown'" 33 if warning not in completed_warnings: 34 completed_warnings.add(warning) 35 _LOGGER.warning(warning) 36 return cls.unknown # type: ignore 37 default_value = next(item for item in cls) 38 warning = f"Missing {cls.__name__} code: {key} - defaulting to {default_value}" 39 if warning not in completed_warnings: 40 completed_warnings.add(warning) 41 _LOGGER.warning(warning) 42 return default_value 43 44 @classmethod 45 def as_dict(cls: type[Self]) -> dict[str, int]: 46 result: dict[str, int] = {} 47 for item in cls: 48 if item.name == "missing": 49 continue 50 result.setdefault(item.display_name, item.value) 51 return result 52 53 @classmethod 54 def as_enum_dict(cls: type[Self]): 55 return {i.value: i for i in cls if i.name != "missing"} 56 57 @classmethod 58 def values(cls: type[Self]) -> list[int]: 59 return list(cls.as_dict().values()) 60 61 @classmethod 62 def keys(cls: type[Self]) -> list[str]: 63 return list(cls.as_dict().keys()) 64 65 @classmethod 66 def items(cls: type[Self]): 67 return cls.as_dict().items() 68 69 70class RoborockModeEnum(StrEnum): 71 """A custom StrEnum that also stores an integer code for each member.""" 72 73 code: int 74 """The integer code associated with the enum member.""" 75 76 def __new__(cls, value: str, code: int) -> Self: 77 """Creates a new enum member.""" 78 member = str.__new__(cls, value) 79 member._value_ = value 80 member.code = code 81 return member 82 83 @classmethod 84 def from_code(cls, code: int) -> Self: 85 for member in cls: 86 if member.code == code: 87 return member 88 message = f"{code} is not a valid code for {cls.__name__}" 89 if message not in completed_warnings: 90 completed_warnings.add(message) 91 _LOGGER.warning(message) 92 raise ValueError(message) 93 94 @classmethod 95 def from_code_optional(cls, code: int) -> Self | None: 96 """Gracefully return None if the code does not exist. 97 98 This is the silent counterpart to :meth:`from_code`: callers use it when 99 an unknown code is expected and tolerable (e.g. decoding a device push 100 that may include data points this library does not model yet), so it must 101 not emit the "not a valid code" warning that ``from_code`` logs. 102 """ 103 for member in cls: 104 if member.code == code: 105 return member 106 return None 107 108 @classmethod 109 def from_value(cls, value: str) -> Self: 110 """Find enum member by string value (case-insensitive).""" 111 for member in cls: 112 if member.value.lower() == value.lower(): 113 return member 114 raise ValueError(f"{value} is not a valid value for {cls.__name__}") 115 116 @classmethod 117 def from_name(cls, name: str) -> Self: 118 """Find enum member by name (case-insensitive).""" 119 for member in cls: 120 if member.name.lower() == name.lower(): 121 return member 122 raise ValueError(f"{name} is not a valid name for {cls.__name__}") 123 124 @classmethod 125 def from_any_optional(cls, value: str | int) -> Self | None: 126 """Resolve a string or int to an enum member. 127 128 Tries to look up by enum name, string value, or integer code 129 and returns None if no match is found. 130 """ 131 # Try enum name lookup (e.g. "SEEK") 132 try: 133 return cls.from_name(str(value)) 134 except ValueError: 135 pass 136 # Try DP string value lookup (e.g. "dpSeek") 137 try: 138 return cls.from_value(str(value)) 139 except ValueError: 140 pass 141 # Try integer code lookup (e.g. "11"). Use the silent optional variant so 142 # a value that is neither a name, a DP string, nor a known code resolves 143 # to None without logging a spurious "not a valid code" warning. 144 try: 145 int_code = int(value) 146 except (ValueError, TypeError): 147 return None 148 return cls.from_code_optional(int_code) 149 150 @classmethod 151 def keys(cls) -> list[str]: 152 """Returns a list of all member values.""" 153 return [member.value for member in cls] 154 155 def __eq__(self, other: Any) -> bool: 156 if isinstance(other, str): 157 return self.value == other or self.name == other 158 if isinstance(other, int): 159 return self.code == other 160 return super().__eq__(other) 161 162 def __hash__(self) -> int: 163 """Hash a RoborockModeEnum. 164 165 It is critical that you do not mix RoborockModeEnums with raw strings or ints in hashed situations 166 (i.e. sets or keys in dictionaries) 167 """ 168 return hash((self.code, self._value_)) 169 170 171ProductInfo = namedtuple("ProductInfo", ["nickname", "short_models"]) 172 173 174class RoborockProductNickname(Enum): 175 # Coral Series 176 CORAL = ProductInfo(nickname="Coral", short_models=("a20", "a21")) 177 CORALPRO = ProductInfo(nickname="CoralPro", short_models=("a143", "a144")) 178 179 # Pearl Series 180 PEARL = ProductInfo(nickname="Pearl", short_models=("a74", "a75")) 181 PEARLC = ProductInfo(nickname="PearlC", short_models=("a103", "a104")) 182 PEARLE = ProductInfo(nickname="PearlE", short_models=("a167", "a168")) 183 PEARLELITE = ProductInfo(nickname="PearlELite", short_models=("a169", "a170")) 184 PEARLPLUS = ProductInfo(nickname="PearlPlus", short_models=("a86", "a87")) 185 PEARLPLUSS = ProductInfo(nickname="PearlPlusS", short_models=("a116", "a117", "a136")) 186 PEARLS = ProductInfo(nickname="PearlS", short_models=("a100", "a101")) 187 PEARLSLITE = ProductInfo(nickname="PearlSLite", short_models=("a122", "a123")) 188 189 # Ruby Series 190 RUBYPLUS = ProductInfo(nickname="RubyPlus", short_models=("t4", "s4")) 191 RUBYSC = ProductInfo(nickname="RubySC", short_models=("p5", "a08")) 192 RUBYSE = ProductInfo(nickname="RubySE", short_models=("a19",)) 193 RUBYSLITE = ProductInfo(nickname="RubySLite", short_models=("p6", "s5e", "a05")) 194 195 # Tanos Series 196 TANOS = ProductInfo(nickname="Tanos", short_models=("t6", "s6")) 197 TANOSE = ProductInfo(nickname="TanosE", short_models=("t7", "a11")) 198 TANOSS = ProductInfo(nickname="TanosS", short_models=("a14", "a15")) 199 TANOSSC = ProductInfo(nickname="TanosSC", short_models=("a39", "a40")) 200 TANOSSE = ProductInfo(nickname="TanosSE", short_models=("a33", "a34")) 201 TANOSSMAX = ProductInfo(nickname="TanosSMax", short_models=("a52",)) 202 TANOSSLITE = ProductInfo(nickname="TanosSLite", short_models=("a37", "a38")) 203 TANOSSPLUS = ProductInfo(nickname="TanosSPlus", short_models=("a23", "a24")) 204 TANOSV = ProductInfo(nickname="TanosV", short_models=("t7p", "a09", "a10")) 205 206 # Topaz Series 207 TOPAZS = ProductInfo(nickname="TopazS", short_models=("a29", "a30", "a76")) 208 TOPAZSC = ProductInfo(nickname="TopazSC", short_models=("a64", "a65")) 209 TOPAZSPLUS = ProductInfo(nickname="TopazSPlus", short_models=("a46", "a47", "a66")) 210 TOPAZSPOWER = ProductInfo(nickname="TopazSPower", short_models=("a62",)) 211 TOPAZSV = ProductInfo(nickname="TopazSV", short_models=("a26", "a27")) 212 213 # Ultron Series 214 ULTRON = ProductInfo(nickname="Ultron", short_models=("a50", "a51")) 215 ULTRONE = ProductInfo(nickname="UltronE", short_models=("a72", "a84")) 216 ULTRONLITE = ProductInfo(nickname="UltronLite", short_models=("a73", "a85")) 217 ULTRONSC = ProductInfo(nickname="UltronSC", short_models=("a94", "a95")) 218 ULTRONSE = ProductInfo(nickname="UltronSE", short_models=("a124", "a125", "a139", "a140")) 219 ULTRONSPLUS = ProductInfo(nickname="UltronSPlus", short_models=("a68", "a69", "a70")) 220 ULTRONSV = ProductInfo(nickname="UltronSV", short_models=("a96", "a97")) 221 222 # Verdelite Series 223 VERDELITE = ProductInfo(nickname="Verdelite", short_models=("a146", "a147")) 224 225 # Vivian Series 226 VIVIAN = ProductInfo(nickname="Vivian", short_models=("a134", "a135", "a155", "a156")) 227 VIVIANC = ProductInfo(nickname="VivianC", short_models=("a158", "a159")) 228 229 230SHORT_MODEL_TO_ENUM = {model: product for product in RoborockProductNickname for model in product.value.short_models} 231 232 233class RoborockCategory(Enum): 234 """Describes the category of the device.""" 235 236 WET_DRY_VAC = "roborock.wetdryvac" 237 VACUUM = "robot.vacuum.cleaner" 238 WASHING_MACHINE = "roborock.wm" 239 MOWER = "roborock.mower" 240 UNKNOWN = "UNKNOWN" 241 242 @classmethod 243 def _missing_(cls, value): 244 _LOGGER.warning("Missing code %s from category", value) 245 return RoborockCategory.UNKNOWN
completed_warnings =
set()
class
RoborockEnum(enum.IntEnum):
11class RoborockEnum(IntEnum): 12 """Roborock Enum for codes with int values""" 13 14 _display_name_: str | None 15 16 def __new__(cls, value: int, display_name: str | None = None) -> Self: 17 member = int.__new__(cls, value) 18 member._value_ = value 19 member._display_name_ = display_name 20 return member 21 22 @property 23 def name(self) -> str: 24 return super().name.lower() 25 26 @property 27 def display_name(self) -> str: 28 return self._display_name_ or self.name 29 30 @classmethod 31 def _missing_(cls: type[Self], key) -> Self: 32 if hasattr(cls, "unknown"): 33 warning = f"Missing {cls.__name__} code: {key} - defaulting to 'unknown'" 34 if warning not in completed_warnings: 35 completed_warnings.add(warning) 36 _LOGGER.warning(warning) 37 return cls.unknown # type: ignore 38 default_value = next(item for item in cls) 39 warning = f"Missing {cls.__name__} code: {key} - defaulting to {default_value}" 40 if warning not in completed_warnings: 41 completed_warnings.add(warning) 42 _LOGGER.warning(warning) 43 return default_value 44 45 @classmethod 46 def as_dict(cls: type[Self]) -> dict[str, int]: 47 result: dict[str, int] = {} 48 for item in cls: 49 if item.name == "missing": 50 continue 51 result.setdefault(item.display_name, item.value) 52 return result 53 54 @classmethod 55 def as_enum_dict(cls: type[Self]): 56 return {i.value: i for i in cls if i.name != "missing"} 57 58 @classmethod 59 def values(cls: type[Self]) -> list[int]: 60 return list(cls.as_dict().values()) 61 62 @classmethod 63 def keys(cls: type[Self]) -> list[str]: 64 return list(cls.as_dict().keys()) 65 66 @classmethod 67 def items(cls: type[Self]): 68 return cls.as_dict().items()
Roborock Enum for codes with int values
class
RoborockModeEnum(enum.StrEnum):
71class RoborockModeEnum(StrEnum): 72 """A custom StrEnum that also stores an integer code for each member.""" 73 74 code: int 75 """The integer code associated with the enum member.""" 76 77 def __new__(cls, value: str, code: int) -> Self: 78 """Creates a new enum member.""" 79 member = str.__new__(cls, value) 80 member._value_ = value 81 member.code = code 82 return member 83 84 @classmethod 85 def from_code(cls, code: int) -> Self: 86 for member in cls: 87 if member.code == code: 88 return member 89 message = f"{code} is not a valid code for {cls.__name__}" 90 if message not in completed_warnings: 91 completed_warnings.add(message) 92 _LOGGER.warning(message) 93 raise ValueError(message) 94 95 @classmethod 96 def from_code_optional(cls, code: int) -> Self | None: 97 """Gracefully return None if the code does not exist. 98 99 This is the silent counterpart to :meth:`from_code`: callers use it when 100 an unknown code is expected and tolerable (e.g. decoding a device push 101 that may include data points this library does not model yet), so it must 102 not emit the "not a valid code" warning that ``from_code`` logs. 103 """ 104 for member in cls: 105 if member.code == code: 106 return member 107 return None 108 109 @classmethod 110 def from_value(cls, value: str) -> Self: 111 """Find enum member by string value (case-insensitive).""" 112 for member in cls: 113 if member.value.lower() == value.lower(): 114 return member 115 raise ValueError(f"{value} is not a valid value for {cls.__name__}") 116 117 @classmethod 118 def from_name(cls, name: str) -> Self: 119 """Find enum member by name (case-insensitive).""" 120 for member in cls: 121 if member.name.lower() == name.lower(): 122 return member 123 raise ValueError(f"{name} is not a valid name for {cls.__name__}") 124 125 @classmethod 126 def from_any_optional(cls, value: str | int) -> Self | None: 127 """Resolve a string or int to an enum member. 128 129 Tries to look up by enum name, string value, or integer code 130 and returns None if no match is found. 131 """ 132 # Try enum name lookup (e.g. "SEEK") 133 try: 134 return cls.from_name(str(value)) 135 except ValueError: 136 pass 137 # Try DP string value lookup (e.g. "dpSeek") 138 try: 139 return cls.from_value(str(value)) 140 except ValueError: 141 pass 142 # Try integer code lookup (e.g. "11"). Use the silent optional variant so 143 # a value that is neither a name, a DP string, nor a known code resolves 144 # to None without logging a spurious "not a valid code" warning. 145 try: 146 int_code = int(value) 147 except (ValueError, TypeError): 148 return None 149 return cls.from_code_optional(int_code) 150 151 @classmethod 152 def keys(cls) -> list[str]: 153 """Returns a list of all member values.""" 154 return [member.value for member in cls] 155 156 def __eq__(self, other: Any) -> bool: 157 if isinstance(other, str): 158 return self.value == other or self.name == other 159 if isinstance(other, int): 160 return self.code == other 161 return super().__eq__(other) 162 163 def __hash__(self) -> int: 164 """Hash a RoborockModeEnum. 165 166 It is critical that you do not mix RoborockModeEnums with raw strings or ints in hashed situations 167 (i.e. sets or keys in dictionaries) 168 """ 169 return hash((self.code, self._value_))
A custom StrEnum that also stores an integer code for each member.
@classmethod
def
from_code(cls, code: int) -> Self:
84 @classmethod 85 def from_code(cls, code: int) -> Self: 86 for member in cls: 87 if member.code == code: 88 return member 89 message = f"{code} is not a valid code for {cls.__name__}" 90 if message not in completed_warnings: 91 completed_warnings.add(message) 92 _LOGGER.warning(message) 93 raise ValueError(message)
@classmethod
def
from_code_optional(cls, code: int) -> Optional[Self]:
95 @classmethod 96 def from_code_optional(cls, code: int) -> Self | None: 97 """Gracefully return None if the code does not exist. 98 99 This is the silent counterpart to :meth:`from_code`: callers use it when 100 an unknown code is expected and tolerable (e.g. decoding a device push 101 that may include data points this library does not model yet), so it must 102 not emit the "not a valid code" warning that ``from_code`` logs. 103 """ 104 for member in cls: 105 if member.code == code: 106 return member 107 return None
Gracefully return None if the code does not exist.
This is the silent counterpart to from_code(): callers use it when
an unknown code is expected and tolerable (e.g. decoding a device push
that may include data points this library does not model yet), so it must
not emit the "not a valid code" warning that from_code logs.
@classmethod
def
from_value(cls, value: str) -> Self:
109 @classmethod 110 def from_value(cls, value: str) -> Self: 111 """Find enum member by string value (case-insensitive).""" 112 for member in cls: 113 if member.value.lower() == value.lower(): 114 return member 115 raise ValueError(f"{value} is not a valid value for {cls.__name__}")
Find enum member by string value (case-insensitive).
@classmethod
def
from_name(cls, name: str) -> Self:
117 @classmethod 118 def from_name(cls, name: str) -> Self: 119 """Find enum member by name (case-insensitive).""" 120 for member in cls: 121 if member.name.lower() == name.lower(): 122 return member 123 raise ValueError(f"{name} is not a valid name for {cls.__name__}")
Find enum member by name (case-insensitive).
@classmethod
def
from_any_optional(cls, value: str | int) -> Optional[Self]:
125 @classmethod 126 def from_any_optional(cls, value: str | int) -> Self | None: 127 """Resolve a string or int to an enum member. 128 129 Tries to look up by enum name, string value, or integer code 130 and returns None if no match is found. 131 """ 132 # Try enum name lookup (e.g. "SEEK") 133 try: 134 return cls.from_name(str(value)) 135 except ValueError: 136 pass 137 # Try DP string value lookup (e.g. "dpSeek") 138 try: 139 return cls.from_value(str(value)) 140 except ValueError: 141 pass 142 # Try integer code lookup (e.g. "11"). Use the silent optional variant so 143 # a value that is neither a name, a DP string, nor a known code resolves 144 # to None without logging a spurious "not a valid code" warning. 145 try: 146 int_code = int(value) 147 except (ValueError, TypeError): 148 return None 149 return cls.from_code_optional(int_code)
Resolve a string or int to an enum member.
Tries to look up by enum name, string value, or integer code and returns None if no match is found.
class
ProductInfo(builtins.tuple):
ProductInfo(nickname, short_models)
class
RoborockProductNickname(enum.Enum):
175class RoborockProductNickname(Enum): 176 # Coral Series 177 CORAL = ProductInfo(nickname="Coral", short_models=("a20", "a21")) 178 CORALPRO = ProductInfo(nickname="CoralPro", short_models=("a143", "a144")) 179 180 # Pearl Series 181 PEARL = ProductInfo(nickname="Pearl", short_models=("a74", "a75")) 182 PEARLC = ProductInfo(nickname="PearlC", short_models=("a103", "a104")) 183 PEARLE = ProductInfo(nickname="PearlE", short_models=("a167", "a168")) 184 PEARLELITE = ProductInfo(nickname="PearlELite", short_models=("a169", "a170")) 185 PEARLPLUS = ProductInfo(nickname="PearlPlus", short_models=("a86", "a87")) 186 PEARLPLUSS = ProductInfo(nickname="PearlPlusS", short_models=("a116", "a117", "a136")) 187 PEARLS = ProductInfo(nickname="PearlS", short_models=("a100", "a101")) 188 PEARLSLITE = ProductInfo(nickname="PearlSLite", short_models=("a122", "a123")) 189 190 # Ruby Series 191 RUBYPLUS = ProductInfo(nickname="RubyPlus", short_models=("t4", "s4")) 192 RUBYSC = ProductInfo(nickname="RubySC", short_models=("p5", "a08")) 193 RUBYSE = ProductInfo(nickname="RubySE", short_models=("a19",)) 194 RUBYSLITE = ProductInfo(nickname="RubySLite", short_models=("p6", "s5e", "a05")) 195 196 # Tanos Series 197 TANOS = ProductInfo(nickname="Tanos", short_models=("t6", "s6")) 198 TANOSE = ProductInfo(nickname="TanosE", short_models=("t7", "a11")) 199 TANOSS = ProductInfo(nickname="TanosS", short_models=("a14", "a15")) 200 TANOSSC = ProductInfo(nickname="TanosSC", short_models=("a39", "a40")) 201 TANOSSE = ProductInfo(nickname="TanosSE", short_models=("a33", "a34")) 202 TANOSSMAX = ProductInfo(nickname="TanosSMax", short_models=("a52",)) 203 TANOSSLITE = ProductInfo(nickname="TanosSLite", short_models=("a37", "a38")) 204 TANOSSPLUS = ProductInfo(nickname="TanosSPlus", short_models=("a23", "a24")) 205 TANOSV = ProductInfo(nickname="TanosV", short_models=("t7p", "a09", "a10")) 206 207 # Topaz Series 208 TOPAZS = ProductInfo(nickname="TopazS", short_models=("a29", "a30", "a76")) 209 TOPAZSC = ProductInfo(nickname="TopazSC", short_models=("a64", "a65")) 210 TOPAZSPLUS = ProductInfo(nickname="TopazSPlus", short_models=("a46", "a47", "a66")) 211 TOPAZSPOWER = ProductInfo(nickname="TopazSPower", short_models=("a62",)) 212 TOPAZSV = ProductInfo(nickname="TopazSV", short_models=("a26", "a27")) 213 214 # Ultron Series 215 ULTRON = ProductInfo(nickname="Ultron", short_models=("a50", "a51")) 216 ULTRONE = ProductInfo(nickname="UltronE", short_models=("a72", "a84")) 217 ULTRONLITE = ProductInfo(nickname="UltronLite", short_models=("a73", "a85")) 218 ULTRONSC = ProductInfo(nickname="UltronSC", short_models=("a94", "a95")) 219 ULTRONSE = ProductInfo(nickname="UltronSE", short_models=("a124", "a125", "a139", "a140")) 220 ULTRONSPLUS = ProductInfo(nickname="UltronSPlus", short_models=("a68", "a69", "a70")) 221 ULTRONSV = ProductInfo(nickname="UltronSV", short_models=("a96", "a97")) 222 223 # Verdelite Series 224 VERDELITE = ProductInfo(nickname="Verdelite", short_models=("a146", "a147")) 225 226 # Vivian Series 227 VIVIAN = ProductInfo(nickname="Vivian", short_models=("a134", "a135", "a155", "a156")) 228 VIVIANC = ProductInfo(nickname="VivianC", short_models=("a158", "a159"))
CORAL =
<RoborockProductNickname.CORAL: ProductInfo(nickname='Coral', short_models=('a20', 'a21'))>
CORALPRO =
<RoborockProductNickname.CORALPRO: ProductInfo(nickname='CoralPro', short_models=('a143', 'a144'))>
PEARL =
<RoborockProductNickname.PEARL: ProductInfo(nickname='Pearl', short_models=('a74', 'a75'))>
PEARLC =
<RoborockProductNickname.PEARLC: ProductInfo(nickname='PearlC', short_models=('a103', 'a104'))>
PEARLE =
<RoborockProductNickname.PEARLE: ProductInfo(nickname='PearlE', short_models=('a167', 'a168'))>
PEARLELITE =
<RoborockProductNickname.PEARLELITE: ProductInfo(nickname='PearlELite', short_models=('a169', 'a170'))>
PEARLPLUS =
<RoborockProductNickname.PEARLPLUS: ProductInfo(nickname='PearlPlus', short_models=('a86', 'a87'))>
PEARLPLUSS =
<RoborockProductNickname.PEARLPLUSS: ProductInfo(nickname='PearlPlusS', short_models=('a116', 'a117', 'a136'))>
PEARLS =
<RoborockProductNickname.PEARLS: ProductInfo(nickname='PearlS', short_models=('a100', 'a101'))>
PEARLSLITE =
<RoborockProductNickname.PEARLSLITE: ProductInfo(nickname='PearlSLite', short_models=('a122', 'a123'))>
RUBYPLUS =
<RoborockProductNickname.RUBYPLUS: ProductInfo(nickname='RubyPlus', short_models=('t4', 's4'))>
RUBYSC =
<RoborockProductNickname.RUBYSC: ProductInfo(nickname='RubySC', short_models=('p5', 'a08'))>
RUBYSE =
<RoborockProductNickname.RUBYSE: ProductInfo(nickname='RubySE', short_models=('a19',))>
RUBYSLITE =
<RoborockProductNickname.RUBYSLITE: ProductInfo(nickname='RubySLite', short_models=('p6', 's5e', 'a05'))>
TANOS =
<RoborockProductNickname.TANOS: ProductInfo(nickname='Tanos', short_models=('t6', 's6'))>
TANOSE =
<RoborockProductNickname.TANOSE: ProductInfo(nickname='TanosE', short_models=('t7', 'a11'))>
TANOSS =
<RoborockProductNickname.TANOSS: ProductInfo(nickname='TanosS', short_models=('a14', 'a15'))>
TANOSSC =
<RoborockProductNickname.TANOSSC: ProductInfo(nickname='TanosSC', short_models=('a39', 'a40'))>
TANOSSE =
<RoborockProductNickname.TANOSSE: ProductInfo(nickname='TanosSE', short_models=('a33', 'a34'))>
TANOSSMAX =
<RoborockProductNickname.TANOSSMAX: ProductInfo(nickname='TanosSMax', short_models=('a52',))>
TANOSSLITE =
<RoborockProductNickname.TANOSSLITE: ProductInfo(nickname='TanosSLite', short_models=('a37', 'a38'))>
TANOSSPLUS =
<RoborockProductNickname.TANOSSPLUS: ProductInfo(nickname='TanosSPlus', short_models=('a23', 'a24'))>
TANOSV =
<RoborockProductNickname.TANOSV: ProductInfo(nickname='TanosV', short_models=('t7p', 'a09', 'a10'))>
TOPAZS =
<RoborockProductNickname.TOPAZS: ProductInfo(nickname='TopazS', short_models=('a29', 'a30', 'a76'))>
TOPAZSC =
<RoborockProductNickname.TOPAZSC: ProductInfo(nickname='TopazSC', short_models=('a64', 'a65'))>
TOPAZSPLUS =
<RoborockProductNickname.TOPAZSPLUS: ProductInfo(nickname='TopazSPlus', short_models=('a46', 'a47', 'a66'))>
TOPAZSPOWER =
<RoborockProductNickname.TOPAZSPOWER: ProductInfo(nickname='TopazSPower', short_models=('a62',))>
TOPAZSV =
<RoborockProductNickname.TOPAZSV: ProductInfo(nickname='TopazSV', short_models=('a26', 'a27'))>
ULTRON =
<RoborockProductNickname.ULTRON: ProductInfo(nickname='Ultron', short_models=('a50', 'a51'))>
ULTRONE =
<RoborockProductNickname.ULTRONE: ProductInfo(nickname='UltronE', short_models=('a72', 'a84'))>
ULTRONLITE =
<RoborockProductNickname.ULTRONLITE: ProductInfo(nickname='UltronLite', short_models=('a73', 'a85'))>
ULTRONSC =
<RoborockProductNickname.ULTRONSC: ProductInfo(nickname='UltronSC', short_models=('a94', 'a95'))>
ULTRONSE =
<RoborockProductNickname.ULTRONSE: ProductInfo(nickname='UltronSE', short_models=('a124', 'a125', 'a139', 'a140'))>
ULTRONSPLUS =
<RoborockProductNickname.ULTRONSPLUS: ProductInfo(nickname='UltronSPlus', short_models=('a68', 'a69', 'a70'))>
ULTRONSV =
<RoborockProductNickname.ULTRONSV: ProductInfo(nickname='UltronSV', short_models=('a96', 'a97'))>
VERDELITE =
<RoborockProductNickname.VERDELITE: ProductInfo(nickname='Verdelite', short_models=('a146', 'a147'))>
VIVIAN =
<RoborockProductNickname.VIVIAN: ProductInfo(nickname='Vivian', short_models=('a134', 'a135', 'a155', 'a156'))>
VIVIANC =
<RoborockProductNickname.VIVIANC: ProductInfo(nickname='VivianC', short_models=('a158', 'a159'))>
SHORT_MODEL_TO_ENUM =
{'a20': <RoborockProductNickname.CORAL: ProductInfo(nickname='Coral', short_models=('a20', 'a21'))>, 'a21': <RoborockProductNickname.CORAL: ProductInfo(nickname='Coral', short_models=('a20', 'a21'))>, 'a143': <RoborockProductNickname.CORALPRO: ProductInfo(nickname='CoralPro', short_models=('a143', 'a144'))>, 'a144': <RoborockProductNickname.CORALPRO: ProductInfo(nickname='CoralPro', short_models=('a143', 'a144'))>, 'a74': <RoborockProductNickname.PEARL: ProductInfo(nickname='Pearl', short_models=('a74', 'a75'))>, 'a75': <RoborockProductNickname.PEARL: ProductInfo(nickname='Pearl', short_models=('a74', 'a75'))>, 'a103': <RoborockProductNickname.PEARLC: ProductInfo(nickname='PearlC', short_models=('a103', 'a104'))>, 'a104': <RoborockProductNickname.PEARLC: ProductInfo(nickname='PearlC', short_models=('a103', 'a104'))>, 'a167': <RoborockProductNickname.PEARLE: ProductInfo(nickname='PearlE', short_models=('a167', 'a168'))>, 'a168': <RoborockProductNickname.PEARLE: ProductInfo(nickname='PearlE', short_models=('a167', 'a168'))>, 'a169': <RoborockProductNickname.PEARLELITE: ProductInfo(nickname='PearlELite', short_models=('a169', 'a170'))>, 'a170': <RoborockProductNickname.PEARLELITE: ProductInfo(nickname='PearlELite', short_models=('a169', 'a170'))>, 'a86': <RoborockProductNickname.PEARLPLUS: ProductInfo(nickname='PearlPlus', short_models=('a86', 'a87'))>, 'a87': <RoborockProductNickname.PEARLPLUS: ProductInfo(nickname='PearlPlus', short_models=('a86', 'a87'))>, 'a116': <RoborockProductNickname.PEARLPLUSS: ProductInfo(nickname='PearlPlusS', short_models=('a116', 'a117', 'a136'))>, 'a117': <RoborockProductNickname.PEARLPLUSS: ProductInfo(nickname='PearlPlusS', short_models=('a116', 'a117', 'a136'))>, 'a136': <RoborockProductNickname.PEARLPLUSS: ProductInfo(nickname='PearlPlusS', short_models=('a116', 'a117', 'a136'))>, 'a100': <RoborockProductNickname.PEARLS: ProductInfo(nickname='PearlS', short_models=('a100', 'a101'))>, 'a101': <RoborockProductNickname.PEARLS: ProductInfo(nickname='PearlS', short_models=('a100', 'a101'))>, 'a122': <RoborockProductNickname.PEARLSLITE: ProductInfo(nickname='PearlSLite', short_models=('a122', 'a123'))>, 'a123': <RoborockProductNickname.PEARLSLITE: ProductInfo(nickname='PearlSLite', short_models=('a122', 'a123'))>, 't4': <RoborockProductNickname.RUBYPLUS: ProductInfo(nickname='RubyPlus', short_models=('t4', 's4'))>, 's4': <RoborockProductNickname.RUBYPLUS: ProductInfo(nickname='RubyPlus', short_models=('t4', 's4'))>, 'p5': <RoborockProductNickname.RUBYSC: ProductInfo(nickname='RubySC', short_models=('p5', 'a08'))>, 'a08': <RoborockProductNickname.RUBYSC: ProductInfo(nickname='RubySC', short_models=('p5', 'a08'))>, 'a19': <RoborockProductNickname.RUBYSE: ProductInfo(nickname='RubySE', short_models=('a19',))>, 'p6': <RoborockProductNickname.RUBYSLITE: ProductInfo(nickname='RubySLite', short_models=('p6', 's5e', 'a05'))>, 's5e': <RoborockProductNickname.RUBYSLITE: ProductInfo(nickname='RubySLite', short_models=('p6', 's5e', 'a05'))>, 'a05': <RoborockProductNickname.RUBYSLITE: ProductInfo(nickname='RubySLite', short_models=('p6', 's5e', 'a05'))>, 't6': <RoborockProductNickname.TANOS: ProductInfo(nickname='Tanos', short_models=('t6', 's6'))>, 's6': <RoborockProductNickname.TANOS: ProductInfo(nickname='Tanos', short_models=('t6', 's6'))>, 't7': <RoborockProductNickname.TANOSE: ProductInfo(nickname='TanosE', short_models=('t7', 'a11'))>, 'a11': <RoborockProductNickname.TANOSE: ProductInfo(nickname='TanosE', short_models=('t7', 'a11'))>, 'a14': <RoborockProductNickname.TANOSS: ProductInfo(nickname='TanosS', short_models=('a14', 'a15'))>, 'a15': <RoborockProductNickname.TANOSS: ProductInfo(nickname='TanosS', short_models=('a14', 'a15'))>, 'a39': <RoborockProductNickname.TANOSSC: ProductInfo(nickname='TanosSC', short_models=('a39', 'a40'))>, 'a40': <RoborockProductNickname.TANOSSC: ProductInfo(nickname='TanosSC', short_models=('a39', 'a40'))>, 'a33': <RoborockProductNickname.TANOSSE: ProductInfo(nickname='TanosSE', short_models=('a33', 'a34'))>, 'a34': <RoborockProductNickname.TANOSSE: ProductInfo(nickname='TanosSE', short_models=('a33', 'a34'))>, 'a52': <RoborockProductNickname.TANOSSMAX: ProductInfo(nickname='TanosSMax', short_models=('a52',))>, 'a37': <RoborockProductNickname.TANOSSLITE: ProductInfo(nickname='TanosSLite', short_models=('a37', 'a38'))>, 'a38': <RoborockProductNickname.TANOSSLITE: ProductInfo(nickname='TanosSLite', short_models=('a37', 'a38'))>, 'a23': <RoborockProductNickname.TANOSSPLUS: ProductInfo(nickname='TanosSPlus', short_models=('a23', 'a24'))>, 'a24': <RoborockProductNickname.TANOSSPLUS: ProductInfo(nickname='TanosSPlus', short_models=('a23', 'a24'))>, 't7p': <RoborockProductNickname.TANOSV: ProductInfo(nickname='TanosV', short_models=('t7p', 'a09', 'a10'))>, 'a09': <RoborockProductNickname.TANOSV: ProductInfo(nickname='TanosV', short_models=('t7p', 'a09', 'a10'))>, 'a10': <RoborockProductNickname.TANOSV: ProductInfo(nickname='TanosV', short_models=('t7p', 'a09', 'a10'))>, 'a29': <RoborockProductNickname.TOPAZS: ProductInfo(nickname='TopazS', short_models=('a29', 'a30', 'a76'))>, 'a30': <RoborockProductNickname.TOPAZS: ProductInfo(nickname='TopazS', short_models=('a29', 'a30', 'a76'))>, 'a76': <RoborockProductNickname.TOPAZS: ProductInfo(nickname='TopazS', short_models=('a29', 'a30', 'a76'))>, 'a64': <RoborockProductNickname.TOPAZSC: ProductInfo(nickname='TopazSC', short_models=('a64', 'a65'))>, 'a65': <RoborockProductNickname.TOPAZSC: ProductInfo(nickname='TopazSC', short_models=('a64', 'a65'))>, 'a46': <RoborockProductNickname.TOPAZSPLUS: ProductInfo(nickname='TopazSPlus', short_models=('a46', 'a47', 'a66'))>, 'a47': <RoborockProductNickname.TOPAZSPLUS: ProductInfo(nickname='TopazSPlus', short_models=('a46', 'a47', 'a66'))>, 'a66': <RoborockProductNickname.TOPAZSPLUS: ProductInfo(nickname='TopazSPlus', short_models=('a46', 'a47', 'a66'))>, 'a62': <RoborockProductNickname.TOPAZSPOWER: ProductInfo(nickname='TopazSPower', short_models=('a62',))>, 'a26': <RoborockProductNickname.TOPAZSV: ProductInfo(nickname='TopazSV', short_models=('a26', 'a27'))>, 'a27': <RoborockProductNickname.TOPAZSV: ProductInfo(nickname='TopazSV', short_models=('a26', 'a27'))>, 'a50': <RoborockProductNickname.ULTRON: ProductInfo(nickname='Ultron', short_models=('a50', 'a51'))>, 'a51': <RoborockProductNickname.ULTRON: ProductInfo(nickname='Ultron', short_models=('a50', 'a51'))>, 'a72': <RoborockProductNickname.ULTRONE: ProductInfo(nickname='UltronE', short_models=('a72', 'a84'))>, 'a84': <RoborockProductNickname.ULTRONE: ProductInfo(nickname='UltronE', short_models=('a72', 'a84'))>, 'a73': <RoborockProductNickname.ULTRONLITE: ProductInfo(nickname='UltronLite', short_models=('a73', 'a85'))>, 'a85': <RoborockProductNickname.ULTRONLITE: ProductInfo(nickname='UltronLite', short_models=('a73', 'a85'))>, 'a94': <RoborockProductNickname.ULTRONSC: ProductInfo(nickname='UltronSC', short_models=('a94', 'a95'))>, 'a95': <RoborockProductNickname.ULTRONSC: ProductInfo(nickname='UltronSC', short_models=('a94', 'a95'))>, 'a124': <RoborockProductNickname.ULTRONSE: ProductInfo(nickname='UltronSE', short_models=('a124', 'a125', 'a139', 'a140'))>, 'a125': <RoborockProductNickname.ULTRONSE: ProductInfo(nickname='UltronSE', short_models=('a124', 'a125', 'a139', 'a140'))>, 'a139': <RoborockProductNickname.ULTRONSE: ProductInfo(nickname='UltronSE', short_models=('a124', 'a125', 'a139', 'a140'))>, 'a140': <RoborockProductNickname.ULTRONSE: ProductInfo(nickname='UltronSE', short_models=('a124', 'a125', 'a139', 'a140'))>, 'a68': <RoborockProductNickname.ULTRONSPLUS: ProductInfo(nickname='UltronSPlus', short_models=('a68', 'a69', 'a70'))>, 'a69': <RoborockProductNickname.ULTRONSPLUS: ProductInfo(nickname='UltronSPlus', short_models=('a68', 'a69', 'a70'))>, 'a70': <RoborockProductNickname.ULTRONSPLUS: ProductInfo(nickname='UltronSPlus', short_models=('a68', 'a69', 'a70'))>, 'a96': <RoborockProductNickname.ULTRONSV: ProductInfo(nickname='UltronSV', short_models=('a96', 'a97'))>, 'a97': <RoborockProductNickname.ULTRONSV: ProductInfo(nickname='UltronSV', short_models=('a96', 'a97'))>, 'a146': <RoborockProductNickname.VERDELITE: ProductInfo(nickname='Verdelite', short_models=('a146', 'a147'))>, 'a147': <RoborockProductNickname.VERDELITE: ProductInfo(nickname='Verdelite', short_models=('a146', 'a147'))>, 'a134': <RoborockProductNickname.VIVIAN: ProductInfo(nickname='Vivian', short_models=('a134', 'a135', 'a155', 'a156'))>, 'a135': <RoborockProductNickname.VIVIAN: ProductInfo(nickname='Vivian', short_models=('a134', 'a135', 'a155', 'a156'))>, 'a155': <RoborockProductNickname.VIVIAN: ProductInfo(nickname='Vivian', short_models=('a134', 'a135', 'a155', 'a156'))>, 'a156': <RoborockProductNickname.VIVIAN: ProductInfo(nickname='Vivian', short_models=('a134', 'a135', 'a155', 'a156'))>, 'a158': <RoborockProductNickname.VIVIANC: ProductInfo(nickname='VivianC', short_models=('a158', 'a159'))>, 'a159': <RoborockProductNickname.VIVIANC: ProductInfo(nickname='VivianC', short_models=('a158', 'a159'))>}
class
RoborockCategory(enum.Enum):
234class RoborockCategory(Enum): 235 """Describes the category of the device.""" 236 237 WET_DRY_VAC = "roborock.wetdryvac" 238 VACUUM = "robot.vacuum.cleaner" 239 WASHING_MACHINE = "roborock.wm" 240 MOWER = "roborock.mower" 241 UNKNOWN = "UNKNOWN" 242 243 @classmethod 244 def _missing_(cls, value): 245 _LOGGER.warning("Missing code %s from category", value) 246 return RoborockCategory.UNKNOWN
Describes the category of the device.
WET_DRY_VAC =
<RoborockCategory.WET_DRY_VAC: 'roborock.wetdryvac'>
VACUUM =
<RoborockCategory.VACUUM: 'robot.vacuum.cleaner'>
WASHING_MACHINE =
<RoborockCategory.WASHING_MACHINE: 'roborock.wm'>
MOWER =
<RoborockCategory.MOWER: 'roborock.mower'>
UNKNOWN =
<RoborockCategory.UNKNOWN: 'UNKNOWN'>