Просмотр исходного кода

config_flow: protect against cloud info missing some fields

In particular, local_product_key may not be added if local discovery fails,
so this should not be assumed to be available. But it is probably better
to assume everything might be missing, as it has been observed with local_key
in the past, where sub devices do not have their own.

Issue #2643
Jason Rumney 1 год назад
Родитель
Сommit
6413edc615
1 измененных файлов с 21 добавлено и 21 удалено
  1. 21 21
      custom_components/tuya_local/config_flow.py

+ 21 - 21
custom_components/tuya_local/config_flow.py

@@ -280,12 +280,12 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
             # will just leave the IP address blank and hope the user can discover the IP by other
             # means such as router device IP assignments.
             _LOGGER.debug(
-                f"Scanning network to get IP address for {self.__cloud_device['id']}."
+                f"Scanning network to get IP address for {self.__cloud_device.get('id', 'DEVICE_KEY_UNAVAILABLE')}."
             )
             self.__cloud_device["ip"] = ""
             try:
                 local_device = await self.hass.async_add_executor_job(
-                    scan_for_device, self.__cloud_device["id"]
+                    scan_for_device, self.__cloud_device.get("id")
                 )
             except OSError:
                 local_device = {"ip": None, "version": ""}
@@ -296,7 +296,9 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
                 self.__cloud_device["version"] = local_device.get("version")
                 self.__cloud_device["local_product_id"] = local_device.get("productKey")
             else:
-                _LOGGER.warning(f"Could not find device: {self.__cloud_device['id']}")
+                _LOGGER.warning(
+                    f"Could not find device: {self.__cloud_device.get('id', 'DEVICE_KEY_UNAVAILABLE')}"
+                )
             return await self.async_step_local()
 
         return self.async_show_form(
@@ -314,13 +316,13 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
 
         if self.__cloud_device is not None:
             # We already have some or all of the device settings from the cloud flow. Set them into the defaults.
-            devid_opts = {"default": self.__cloud_device["id"]}
-            host_opts = {"default": self.__cloud_device["ip"]}
-            key_opts = {"default": self.__cloud_device[CONF_LOCAL_KEY]}
-            if self.__cloud_device["version"] is not None:
-                proto_opts = {"default": float(self.__cloud_device["version"])}
-            if self.__cloud_device[CONF_DEVICE_CID] is not None:
-                devcid_opts = {"default": self.__cloud_device[CONF_DEVICE_CID]}
+            devid_opts = {"default": self.__cloud_device.get("id")}
+            host_opts = {"default": self.__cloud_device.get("ip")}
+            key_opts = {"default": self.__cloud_device.get(CONF_LOCAL_KEY)}
+            if self.__cloud_device.get("version"):
+                proto_opts = {"default": float(self.__cloud_device.get("version"))}
+            if self.__cloud_device.get(CONF_DEVICE_CID):
+                devcid_opts = {"default": self.__cloud_device.get(CONF_DEVICE_CID)}
 
         if user_input is not None:
             self.device = await async_test_connection(user_input, self.hass)
@@ -329,11 +331,11 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
                 if self.__cloud_device:
                     if self.__cloud_device.get("product_id"):
                         self.device.set_detected_product_id(
-                            self.__cloud_device["product_id"]
+                            self.__cloud_device.get("product_id")
                         )
                     if self.__cloud_device.get("local_product_id"):
                         self.device.set_detected_product_id(
-                            self.__cloud_device["local_product_id"]
+                            self.__cloud_device.get("local_product_id")
                         )
 
                 return await self.async_step_select_type()
@@ -389,22 +391,20 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
         if self.__cloud_device:
             _LOGGER.warning(
                 "Adding %s device with product id %s",
-                self.__cloud_device["product_name"],
-                self.__cloud_device["product_id"],
+                self.__cloud_device.get("product_name", "UNKNOWN"),
+                self.__cloud_device.get("product_id", "UNKNOWN"),
             )
-            if (
-                self.__cloud_device["local_product_id"]
-                and self.__cloud_device["local_product_id"]
-                != self.__cloud_device["product_id"]
-            ):
+            if self.__cloud_device.get("local_product_id") and self.__cloud_device.get(
+                "local_product_id"
+            ) != self.__cloud_device.get("product_id"):
                 _LOGGER.warning(
                     "Local product id differs from cloud: %s",
-                    self.__cloud_device["local_product_id"],
+                    self.__cloud_device.get("local_product_id"),
                 )
             # try:
             #     self.init_cloud()
             #     model = await self.cloud.async_get_datamodel(
-            #         self.__cloud_device["id"],
+            #         self.__cloud_device.get("id"),
             #     )
             #     if model:
             #         _LOGGER.warning(