From 16f5b0e6047ee22e3ba7f81caa3727eecfa49c89 Mon Sep 17 00:00:00 2001 From: "Paul.Cavill" Date: Mon, 4 Sep 2023 23:17:27 +1200 Subject: [PATCH 1/3] Pull in PR #1256 --- custom_components/localtuya/cloud_api.py | 15 +++++++++++++ custom_components/localtuya/config_flow.py | 25 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/custom_components/localtuya/cloud_api.py b/custom_components/localtuya/cloud_api.py index 680217187..19901f5aa 100644 --- a/custom_components/localtuya/cloud_api.py +++ b/custom_components/localtuya/cloud_api.py @@ -134,3 +134,18 @@ async def async_get_devices_list(self): # _LOGGER.debug("DEV_LIST: %s", self.device_list) return "ok" + +async def async_get_device_specifications(self, device_id): + """Obtain the DP ID mappings for a device.""" + resp = await self.async_make_request( + "GET", url=f"/v1.1/devices/{device_id}/specifications" + ) + + if not resp.ok: + return {}, "Request failed, status " + str(resp.status) + + r_json = resp.json() + if not r_json["success"]: + return {}, f"Error {r_json['code']}: {r_json['msg']}" + + return r_json["result"], "ok" \ No newline at end of file diff --git a/custom_components/localtuya/config_flow.py b/custom_components/localtuya/config_flow.py index 5c87e2547..b1c53a2b4 100644 --- a/custom_components/localtuya/config_flow.py +++ b/custom_components/localtuya/config_flow.py @@ -172,9 +172,15 @@ def schema_defaults(schema, dps_list=None, **defaults): return copy -def dps_string_list(dps_data): +def dps_string_list(dps_data, cloud_dp_codes): """Return list of friendly DPS values.""" - return [f"{id} (value: {value})" for id, value in dps_data.items()] + strs = [] + for dp, value in dps_data.items(): + if dp in cloud_dp_codes: + strs.append(f"{dp} (code: {cloud_dp_codes[dp]}, value: {value})") + else: + strs.append(f"{dp} (value: {value})") + return strs def gen_dps_strings(): @@ -299,7 +305,20 @@ async def validate_input(hass: core.HomeAssistant, data): _LOGGER.debug("Total DPS: %s", detected_dps) - return dps_string_list(detected_dps) + # Get DP descriptions from the cloud, if the device is there. + cloud_dp_codes = {} + if data[CONF_DEVICE_ID] in hass.data[DOMAIN][DATA_CLOUD].device_list: + cloud_device_specs, res = await hass.data[DOMAIN][ + DATA_CLOUD + ].async_get_device_specifications(data[CONF_DEVICE_ID]) + if res != "ok": + _LOGGER.error("Cloud DP specification request failed: %s", res) + else: + for category in ("functions", "status"): + cloud_dp_codes.update( + {str(e["dp_id"]): e["code"] for e in cloud_device_specs[category]} + ) + return dps_string_list(detected_dps, cloud_dp_codes) async def attempt_cloud_connection(hass, user_input): From 580994923c41b3053308e2251b5438be96e8dbc2 Mon Sep 17 00:00:00 2001 From: "Paul.Cavill" Date: Mon, 4 Sep 2023 23:28:55 +1200 Subject: [PATCH 2/3] pull in PR #1465 --- custom_components/localtuya/__init__.py | 5 +++-- custom_components/localtuya/cloud_api.py | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/custom_components/localtuya/__init__.py b/custom_components/localtuya/__init__.py index 9a996c31f..a72b842f0 100644 --- a/custom_components/localtuya/__init__.py +++ b/custom_components/localtuya/__init__.py @@ -255,8 +255,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): res = await tuya_api.async_get_access_token() if res != "ok": _LOGGER.error("Cloud API connection failed: %s", res) - _LOGGER.info("Cloud API connection succeeded.") - res = await tuya_api.async_get_devices_list() + else: + _LOGGER.info("Cloud API connection succeeded.") + res = await tuya_api.async_get_devices_list() hass.data[DOMAIN][DATA_CLOUD] = tuya_api async def setup_entities(device_ids): diff --git a/custom_components/localtuya/cloud_api.py b/custom_components/localtuya/cloud_api.py index 19901f5aa..a4960f53c 100644 --- a/custom_components/localtuya/cloud_api.py +++ b/custom_components/localtuya/cloud_api.py @@ -101,8 +101,11 @@ async def async_make_request(self, method, url, body=None, headers={}): async def async_get_access_token(self): """Obtain a valid access token.""" - resp = await self.async_make_request("GET", "/v1.0/token?grant_type=1") - + try: + resp = await self.async_make_request("GET", "/v1.0/token?grant_type=1") + except requests.exceptions.ConnectionError: + return "Request failed, status ConnectionError" + if not resp.ok: return "Request failed, status " + str(resp.status) From 34d5981a64e6be04b29345736a759e321dfcf81c Mon Sep 17 00:00:00 2001 From: "Paul.Cavill" Date: Wed, 11 Oct 2023 23:14:48 +1300 Subject: [PATCH 3/3] Fix padding --- custom_components/localtuya/cloud_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/localtuya/cloud_api.py b/custom_components/localtuya/cloud_api.py index 19901f5aa..daf464c61 100644 --- a/custom_components/localtuya/cloud_api.py +++ b/custom_components/localtuya/cloud_api.py @@ -135,7 +135,7 @@ async def async_get_devices_list(self): return "ok" -async def async_get_device_specifications(self, device_id): + async def async_get_device_specifications(self, device_id): """Obtain the DP ID mappings for a device.""" resp = await self.async_make_request( "GET", url=f"/v1.1/devices/{device_id}/specifications"