diff --git a/custom_components/robovac/config_flow.py b/custom_components/robovac/config_flow.py index 45826bd..c9339e5 100644 --- a/custom_components/robovac/config_flow.py +++ b/custom_components/robovac/config_flow.py @@ -41,9 +41,11 @@ from homeassistant.const import ( CONF_MAC, CONF_LOCATION, CONF_CLIENT_ID, + CONF_REGION, + CONF_TIME_ZONE, ) -from .const import DOMAIN, CONF_VACS, CONF_PHONE_CODE +from .const import DOMAIN, CONF_VACS from .tuyawebapi import TuyaAPISession from .eufywebapi import EufyLogon @@ -77,8 +79,19 @@ def get_eufy_vacuums(self): ) device_response = response.json() + + response = eufy_session.get_user_settings( + user_response["user_info"]["request_host"], + user_response["user_info"]["id"], + user_response["access_token"], + ) + settings_response = response.json() + self[CONF_CLIENT_ID] = user_response["user_info"]["id"] - self[CONF_PHONE_CODE] = user_response["user_info"]["phone_code"] + self[CONF_REGION] = settings_response["setting"]["home_setting"]["tuya_home"][ + "tuya_region_code" + ] + self[CONF_TIME_ZONE] = user_response["user_info"]["timezone"] # self[CONF_VACS] = {} items = device_response["items"] @@ -97,7 +110,7 @@ def get_eufy_vacuums(self): self[CONF_VACS] = allvacs tuya_client = TuyaAPISession( - username="eh-" + self[CONF_CLIENT_ID], country_code=self[CONF_PHONE_CODE] + username="eh-" + self[CONF_CLIENT_ID], region=self[CONF_REGION], timezone=self[CONF_TIME_ZONE] ) for home in tuya_client.list_homes(): for device in tuya_client.list_devices(home["groupId"]): diff --git a/custom_components/robovac/const.py b/custom_components/robovac/const.py index a95a06d..2b21c74 100644 --- a/custom_components/robovac/const.py +++ b/custom_components/robovac/const.py @@ -2,4 +2,3 @@ DOMAIN = "robovac" CONF_VACS = "vacuums" -CONF_PHONE_CODE = "phone_code" diff --git a/custom_components/robovac/eufywebapi.py b/custom_components/robovac/eufywebapi.py index 72345f8..1cbbfab 100644 --- a/custom_components/robovac/eufywebapi.py +++ b/custom_components/robovac/eufywebapi.py @@ -30,12 +30,16 @@ class EufyLogon: "password": self.password, } - return requests.post( - login_url, json=login_auth, headers=eufyheaders, timeout=1.5 - ) + return requests.post(login_url, json=login_auth, headers=eufyheaders) + + def get_user_settings(self, url, userid, token): + setting_url = url + "/v1/user/setting" + eufyheaders["token"] = token + eufyheaders["id"] = userid + return requests.request("GET", setting_url, headers=eufyheaders, timeout=1.5) def get_device_info(self, url, userid, token): device_url = url + "/v1/device/list/devices-and-groups" eufyheaders["token"] = token eufyheaders["id"] = userid - return requests.request("GET", device_url, headers=eufyheaders, timeout=1.5) + return requests.request("GET", device_url, headers=eufyheaders) diff --git a/custom_components/robovac/tuyawebapi.py b/custom_components/robovac/tuyawebapi.py index e44fb2a..94226c5 100644 --- a/custom_components/robovac/tuyawebapi.py +++ b/custom_components/robovac/tuyawebapi.py @@ -78,7 +78,7 @@ DEFAULT_TUYA_QUERY_PARAMS = { "lang": "en", "osSystem": "12", "os": "Android", - "timeZoneId": "Europe/London", + "timeZoneId": "", "ttid": "android", "et": "0.0.1", "sdkVersion": "3.0.8cAnker", @@ -86,19 +86,22 @@ DEFAULT_TUYA_QUERY_PARAMS = { class TuyaAPISession: - username = None country_code = None session_id = None - def __init__(self, username, country_code): + def __init__(self, username, region, timezone): self.session = requests.session() self.session.headers = DEFAULT_TUYA_HEADERS.copy() self.default_query_params = DEFAULT_TUYA_QUERY_PARAMS.copy() self.default_query_params["deviceId"] = self.generate_new_device_id() self.username = username - self.country_code = country_code - self.base_url = TUYA_INITIAL_BASE_URL + self.country_code = self.getCountryCode(region) + self.base_url = { + "EU": "https://a1.tuyaeu.com", + "AY": "https://a1.tuyacn.com", + }.get(region, "https://a1.tuyaus.com") + DEFAULT_TUYA_QUERY_PARAMS["timeZoneId"] = timezone @staticmethod def generate_new_device_id(): @@ -183,8 +186,7 @@ class TuyaAPISession: encrypted_uid += encryptor.finalize() return md5(encrypted_uid.hex().upper().encode("utf-8")).hexdigest() - def request_session(self, username, country_code): - password = self.determine_password(username) + def request_session(self, username, password, country_code): token_response = self.request_token(username, country_code) encrypted_password = unpadded_rsa( key_exponent=int(token_response["exponent"]), @@ -200,17 +202,33 @@ class TuyaAPISession: "options": '{"group": 1}', "token": token_response["token"], } - session_response = self._request( - action="tuya.m.user.uid.password.login.reg", - data=data, - _requires_session=False, - ) - return session_response + + try: + return self._request( + action="tuya.m.user.uid.password.login.reg", + data=data, + _requires_session=False, + ) + except Exception as e: + error_password = md5("12345678".encode("utf8")).hexdigest() + + if password != error_password: + return self.request_session(username, error_password, country_code) + else: + raise e def acquire_session(self): - session_response = self.request_session(self.username, self.country_code) + password = self.determine_password(self.username) + session_response = self.request_session( + self.username, password, self.country_code + ) self.session_id = self.default_query_params["sid"] = session_response["sid"] self.base_url = session_response["domain"]["mobileApiUrl"] + self.country_code = ( + session_response["phoneCode"] + if session_response["phoneCode"] + else self.getCountryCode(session_response["domain"]["regionCode"]) + ) def list_homes(self): return self._request(action="tuya.m.location.list", version="2.1") @@ -221,3 +239,6 @@ class TuyaAPISession: version="1.0", query_params={"gid": home_id}, ) + + def getCountryCode(self, region_code): + return {"EU": "44", "AY": "86"}.get(region_code, "1")