@@ -62,6 +62,23 @@ def __init__(self, config: Config):
6262 def token_store (self ) -> str :
6363 return os .path .join (self .config .conf_path , ".mi.token" )
6464
65+ @staticmethod
66+ def _has_basic_token (account : MiAccount | None ) -> bool :
67+ token = getattr (account , "token" , None ) or {}
68+ return bool (token .get ("userId" ) and token .get ("passToken" ))
69+
70+ def _describe_login_failure (self , exc : Exception | None = None ) -> str :
71+ text = str (exc or "" )
72+ code = self .extract_error_code (text )
73+ lowered = text .lower ()
74+ if code == "87001" or "captcha" in lowered :
75+ return "Xiaomi login requires captcha verification; account/password is not supported in this state. Please use fresh cookies instead."
76+ if code == "70016" :
77+ return "Xiaomi login verification failed. Please use fresh cookies instead of account/password."
78+ if "userid" in lowered :
79+ return "Xiaomi account requires additional security verification. Please use fresh cookies instead."
80+ return "Account/password login failed or requires Xiaomi security verification. Please use fresh cookies instead."
81+
6582 async def login (self ):
6683 async with self ._login_lock :
6784 if (
@@ -89,12 +106,19 @@ async def login(self):
89106 "userId" : token_data ["userId" ],
90107 "passToken" : token_data ["passToken" ],
91108 "deviceId" : "miplay_device" ,
92- "ssecurity" : "" ,
93- "serviceToken" : "" ,
94109 }
95110 self ._cookie_loaded = True
96- self ._logged_in = False
97- log .info ("Loaded Xiaomi cookie credentials; waiting for API validation" )
111+ try :
112+ await self .account .login ("micoapi" )
113+ self ._logged_in = self ._has_basic_token (self .account )
114+ if not self ._logged_in :
115+ raise DeviceListError ("Cookie login failed: Xiaomi token is incomplete after login" )
116+ log .info ("Xiaomi cookie login succeeded" )
117+ except Exception as exc :
118+ self ._logged_in = False
119+ raise DeviceListError (
120+ f"Cookie login failed: { exc } "
121+ ) from exc
98122 else :
99123 self ._cookie_loaded = False
100124 self .account = MiAccount (
@@ -105,11 +129,13 @@ async def login(self):
105129 )
106130 try :
107131 await self .account .login ("micoapi" )
108- self ._logged_in = True
109- log .info ("Xiaomi account login succeeded" )
110132 except Exception as exc :
111- self ._logged_in = False
112133 log .error (f"Xiaomi login failed: { exc } " )
134+ raise DeviceListError (self ._describe_login_failure (exc )) from exc
135+ self ._logged_in = self ._has_basic_token (self .account )
136+ if not self ._logged_in :
137+ raise DeviceListError (self ._describe_login_failure ())
138+ log .info ("Xiaomi account login succeeded" )
113139
114140 self .mina_service = MiNAService (self .account )
115141 self .miio_service = MiIOService (self .account )
0 commit comments