diff --git a/pyhon/api.py b/pyhon/api.py index 14f67ba..a936c95 100644 --- a/pyhon/api.py +++ b/pyhon/api.py @@ -3,6 +3,7 @@ import json import logging import secrets from datetime import datetime +from pprint import pprint from typing import List import aiohttp as aiohttp @@ -94,6 +95,48 @@ class HonConnection: return {} return result["payload"]["history"] + async def last_activity(self, device: HonDevice): + url = f"{const.API_URL}/commands/v1/retrieve-last-activity" + params = {"macAddress": device.mac_address} + async with self._session.get(url, params=params, headers=await self._headers) as response: + result = await response.json() + if result and (activity := result.get("attributes")): + return activity + return {} + + async def appliance_configuration(self): + url = f"{const.API_URL}/config/v1/appliance-configuration" + headers = {"x-api-key": const.API_KEY, "content-type": "application/json"} + async with self._session.get(url, headers=headers) as response: + result = await response.json() + if result and (data := result.get("payload")): + return data + return {} + + async def app_config(self, language="en", beta=True): + headers = {"x-api-key": const.API_KEY, "content-type": "application/json"} + url = f"{const.API_URL}/app-config" + payload = { + "languageCode": language, + "beta": beta, + "appVersion": const.APP_VERSION, + "os": const.OS + } + payload = json.dumps(payload, separators=(',', ':')) + async with self._session.post(url, headers=headers, data=payload) as response: + if (result := await response.json()) and (data := result.get("payload")): + return data + return {} + + async def translation_keys(self): + headers = {"x-api-key": const.API_KEY, "content-type": "application/json"} + config = await self.app_config() + if url := config.get("language", {}).get("jsonPath"): + async with self._session.get(url, headers=headers) as response: + if result := await response.json(): + return result + return {} + async def load_attributes(self, device: HonDevice, loop=False): params = { "macAddress": device.mac_address, diff --git a/pyhon/auth.py b/pyhon/auth.py index eed4a49..1baca58 100644 --- a/pyhon/auth.py +++ b/pyhon/auth.py @@ -47,7 +47,6 @@ class HonAuth: "scope": "api openid refresh_token web", "nonce": nonce } - headers = {"user-agent": "Chrome/110.0.5481.153"} params = "&".join([f"{k}={v}" for k, v in params.items()]) async with session.get(f"{const.AUTH_API}/services/oauth2/authorize/expid_Login?{params}") as resp: if not (login_url := re.findall("url = '(.+?)'", await resp.text())): @@ -58,7 +57,7 @@ class HonAuth: async with session.get(url, allow_redirects=False) as redirect2: if not (url := redirect2.headers.get("Location") + "&System=IoT_Mobile_App&RegistrationSubChannel=hOn"): return False - async with session.get(URL(url, encoded=True), headers=headers) as login_screen: + async with session.get(URL(url, encoded=True)) as login_screen: if context := re.findall('"fwuid":"(.*?)","loaded":(\\{.*?})', await login_screen.text()): fw_uid, loaded_str = context[0] loaded = json.loads(loaded_str) @@ -134,8 +133,12 @@ class HonAuth: return True async def authorize(self, email, password, mobile_id): - async with aiohttp.ClientSession() as session: - fw_uid, loaded, login_url = await self._load_login(session) + headers = {"user-agent": const.USER_AGENT} + async with aiohttp.ClientSession(headers=headers) as session: + if login_site := await self._load_login(session): + fw_uid, loaded, login_url = login_site + else: + return False if not (url := await self._login(session, email, password, fw_uid, loaded, login_url)): return False if not await self._get_token(session, url): diff --git a/pyhon/const.py b/pyhon/const.py index a9034d2..86749d8 100644 --- a/pyhon/const.py +++ b/pyhon/const.py @@ -1,5 +1,6 @@ AUTH_API = "https://he-accounts.force.com/SmartHome" API_URL = "https://api-iot.he.services" +API_KEY = "GRCqFhC6Gk@ikWXm1RmnSmX1cm,MxY-configuration" APP = "hon" # All seen id's (different accounts, different devices) are the same, so I guess this hash is static CLIENT_ID = "3MVG9QDx8IX8nP5T2Ha8ofvlmjLZl5L_gvfbT9.HJvpHGKoAS_dcMN8LYpTSYeVFCraUnV.2Ag1Ki7m4znVO6" @@ -7,4 +8,4 @@ APP_VERSION = "1.53.7" OS_VERSION = 31 OS = "android" DEVICE_MODEL = "exynos9820" -LANGUAGE = "en" +USER_AGENT = "Chrome/110.0.5481.153"