Bladeren bron

Add Tuya cloud assisted setup flow

Pick up the streamlined Tuya cloud login from the official HA cloud Tuya integration. This allows you to get a code from the Smart Life app and then use the app to login to Tuya with a QR code. All available devices for that account can then be select to add locally. Only the IP address still needs to be discovered so a local scan is performed to get that. Just like the final device connection the scan for the IP can fail if other things (including the Smart Life app just used for login!) are connecting to the device when the scan runs so those should be closed before that and the final connection step.

New flow:

Starting page in the config flow allows users to choose to go down the cloud assisted configuration path or the original manual entry path:
Now you need to provide the 'User Code' available from the Smart Life app:
Then you will get presented with a QR code you scan in the Smart Life app:
Once you scan and approve the login in the app, a list of available devices that the cloud account knows about is shown. Now you must select the device you want to add and, if necessary, the gateway it connects through:
Next the local IP address of the device is found by discovery:
Finally the retrieved data is prepopulated into the existing register local device page:

Rebase of PR #1881
Adrian Garside 1 jaar geleden
bovenliggende
commit
8896547f6a

+ 13 - 2
README.md

@@ -112,10 +112,21 @@ After installing, you can easily configure your devices using the Integrations c
 [![Add Integration to your Home Assistant
 [![Add Integration to your Home Assistant
 instance.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=tuya_local)
 instance.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=tuya_local)
 
 
+### Choose your configuration path
+
+There are two options for configuring a device:
+- You can login to Tuya cloud with the Smart Life app and retrieve a list of devices and the necessary local connection data.
+- You can provide all the necessary information manually [as per the instructions below](#finding-your-device-id-and-local-key).
+
+The first choice essentially automates all the manual steps of the second and without needing to create a Tuya IOT developer account. This is especially important now that Tuya has started time limiting access to a key data access capability in the IOT developer portal to only a month with the ability to refresh the trial of that only every 6 months.
+
+The cloud assisted choice will guide you through authenticating, choosing a device to add from the list of devices associated with your Smart Life account, locate the device on your local subnet and then drop you into [Stage One](#stage-one) with fully populated data necessary to move forward to [Stage Two](#stage-two).
+
+Then Smart Life authentication token expires after a small number of hours and so is not saved by the integration. But, as long as you don't restart Home Assistant, this allows you to add multiple devices one after another only needing to authenticate once for the first one.
+
 ### Stage One
 ### Stage One
 
 
-The first stage of configuration is to provide the information needed to
-connect to the device.
+The first stage of configuration is to provide the information needed to connect to the device.
 
 
 You will need to provide your device's IP address or hostname, device
 You will need to provide your device's IP address or hostname, device
 ID and local key; the last two can be found using [the instructions
 ID and local key; the last two can be found using [the instructions

+ 437 - 4
custom_components/tuya_local/config_flow.py

@@ -1,20 +1,51 @@
 import asyncio
 import asyncio
 import logging
 import logging
+from collections import OrderedDict
+from typing import Any
 
 
+import tinytuya
 import voluptuous as vol
 import voluptuous as vol
 from homeassistant import config_entries
 from homeassistant import config_entries
 from homeassistant.const import CONF_HOST, CONF_NAME
 from homeassistant.const import CONF_HOST, CONF_NAME
 from homeassistant.core import HomeAssistant, callback
 from homeassistant.core import HomeAssistant, callback
+from homeassistant.data_entry_flow import FlowResult
+from homeassistant.helpers.selector import (
+    QrCodeSelector,
+    QrCodeSelectorConfig,
+    QrErrorCorrectionLevel,
+    SelectOptionDict,
+    SelectSelector,
+    SelectSelectorConfig,
+    SelectSelectorMode,
+)
+from tuya_sharing import (
+    CustomerDevice,
+    LoginControl,
+    Manager,
+    SharingDeviceListener,
+    SharingTokenListener,
+)
 
 
 from . import DOMAIN
 from . import DOMAIN
 from .const import (
 from .const import (
     API_PROTOCOL_VERSIONS,
     API_PROTOCOL_VERSIONS,
     CONF_DEVICE_CID,
     CONF_DEVICE_CID,
     CONF_DEVICE_ID,
     CONF_DEVICE_ID,
+    CONF_ENDPOINT,
     CONF_LOCAL_KEY,
     CONF_LOCAL_KEY,
     CONF_POLL_ONLY,
     CONF_POLL_ONLY,
     CONF_PROTOCOL_VERSION,
     CONF_PROTOCOL_VERSION,
+    CONF_TERMINAL_ID,
     CONF_TYPE,
     CONF_TYPE,
+    CONF_USER_CODE,
+    DATA_STORE,
+    TUYA_CLIENT_ID,
+    TUYA_RESPONSE_CODE,
+    TUYA_RESPONSE_MSG,
+    TUYA_RESPONSE_QR_CODE,
+    TUYA_RESPONSE_RESULT,
+    TUYA_RESPONSE_SUCCESS,
+    TUYA_SCHEMA,
 )
 )
 from .device import TuyaLocalDevice
 from .device import TuyaLocalDevice
 from .helpers.config import get_device_id
 from .helpers.config import get_device_id
@@ -31,8 +62,334 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
     device = None
     device = None
     data = {}
     data = {}
 
 
+    __user_code: str
+    __qr_code: str
+    __authentication: dict
+    __cloud_devices: dict
+    __cloud_device: dict
+
+    def __init__(self) -> None:
+        """Initialize the config flow."""
+        self.__login_control = LoginControl()
+        self.__cloud_devices = {}
+        self.__cloud_device = None
+
     async def async_step_user(self, user_input=None):
     async def async_step_user(self, user_input=None):
         errors = {}
         errors = {}
+
+        if self.hass.data.get(DOMAIN) is None:
+            self.hass.data[DOMAIN] = {}
+        if self.hass.data[DOMAIN].get(DATA_STORE) is None:
+            self.hass.data[DOMAIN][DATA_STORE] = {}
+        self.__authentication = self.hass.data[DOMAIN][DATA_STORE].get(
+            "authentication", None
+        )
+
+        if user_input is not None:
+            if user_input["setup_mode"] == "cloud":
+                try:
+                    if self.__authentication is not None:
+                        self.__cloud_devices = await self.load_device_info()
+                        return await self.async_step_choose_device(None)
+                except Exception as e:
+                    # Re-authentication is needed.
+                    _LOGGER.warning("Connection test failed with %s %s", type(e), e)
+                    _LOGGER.warning("Re-authentication is required.")
+                return await self.async_step_cloud(None)
+            if user_input["setup_mode"] == "manual":
+                return await self.async_step_local(None)
+
+        # Build form
+        fields: OrderedDict[vol.Marker, Any] = OrderedDict()
+        fields[vol.Required("setup_mode")] = SelectSelector(
+            SelectSelectorConfig(
+                options=["cloud", "manual"],
+                mode=SelectSelectorMode.LIST,
+                translation_key="setup_mode",
+            )
+        )
+
+        return self.async_show_form(
+            step_id="user",
+            data_schema=vol.Schema(fields),
+            errors=errors or {},
+            last_step=False,
+        )
+
+    async def async_step_cloud(
+        self, user_input: dict[str, Any] | None = None
+    ) -> FlowResult:
+        """Step user."""
+        errors = {}
+        placeholders = {}
+
+        if user_input is not None:
+            success, response = await self.__async_get_qr_code(
+                user_input[CONF_USER_CODE]
+            )
+            if success:
+                return await self.async_step_scan(None)
+
+            errors["base"] = "login_error"
+            placeholders = {
+                TUYA_RESPONSE_MSG: response.get(TUYA_RESPONSE_MSG, "Unknown error"),
+                TUYA_RESPONSE_CODE: response.get(TUYA_RESPONSE_CODE, "0"),
+            }
+        else:
+            user_input = {}
+
+        return self.async_show_form(
+            step_id="cloud",
+            data_schema=vol.Schema(
+                {
+                    vol.Required(
+                        CONF_USER_CODE, default=user_input.get(CONF_USER_CODE, "")
+                    ): str,
+                }
+            ),
+            errors=errors,
+            description_placeholders=placeholders,
+        )
+
+    async def async_step_scan(
+        self, user_input: dict[str, Any] | None = None
+    ) -> FlowResult:
+        """Step scan."""
+        if user_input is None:
+            return self.async_show_form(
+                step_id="scan",
+                data_schema=vol.Schema(
+                    {
+                        vol.Optional("QR"): QrCodeSelector(
+                            config=QrCodeSelectorConfig(
+                                data=f"tuyaSmart--qrLogin?token={self.__qr_code}",
+                                scale=5,
+                                error_correction_level=QrErrorCorrectionLevel.QUARTILE,
+                            )
+                        )
+                    }
+                ),
+            )
+
+        ret, info = await self.hass.async_add_executor_job(
+            self.__login_control.login_result,
+            self.__qr_code,
+            TUYA_CLIENT_ID,
+            self.__user_code,
+        )
+        if not ret:
+            # Try to get a new QR code on failure
+            await self.__async_get_qr_code(self.__user_code)
+            return self.async_show_form(
+                step_id="scan",
+                errors={"base": "login_error"},
+                data_schema=vol.Schema(
+                    {
+                        vol.Optional("QR"): QrCodeSelector(
+                            config=QrCodeSelectorConfig(
+                                data=f"tuyaSmart--qrLogin?token={self.__qr_code}",
+                                scale=5,
+                                error_correction_level=QrErrorCorrectionLevel.QUARTILE,
+                            )
+                        )
+                    }
+                ),
+                description_placeholders={
+                    TUYA_RESPONSE_MSG: info.get(TUYA_RESPONSE_MSG, "Unknown error"),
+                    TUYA_RESPONSE_CODE: info.get(TUYA_RESPONSE_CODE, 0),
+                },
+            )
+
+        # Now that we have successfully logged in we can query for devices for the account.
+        self.__authentication = {
+            "user_code": info[CONF_TERMINAL_ID],
+            "terminal_id": info[CONF_TERMINAL_ID],
+            "endpoint": info[CONF_ENDPOINT],
+            "token_info": {
+                "t": info["t"],
+                "uid": info["uid"],
+                "expire_time": info["expire_time"],
+                "access_token": info["access_token"],
+                "refresh_token": info["refresh_token"],
+            },
+        }
+        self.hass.data[DOMAIN][DATA_STORE]["authentication"] = self.__authentication
+        _LOGGER.debug(f"domain_data is {self.hass.data[DOMAIN]}")
+
+        self.__cloud_devices = await self.load_device_info()
+
+        return await self.async_step_choose_device(None)
+
+    async def load_device_info(self) -> dict:
+        token_listener = TokenListener(self.hass)
+        manager = Manager(
+            TUYA_CLIENT_ID,
+            self.__authentication["user_code"],
+            self.__authentication["terminal_id"],
+            self.__authentication["endpoint"],
+            self.__authentication["token_info"],
+            token_listener,
+        )
+
+        listener = DeviceListener(self.hass, manager)
+        manager.add_device_listener(listener)
+
+        # Get all devices from Tuya
+        await self.hass.async_add_executor_job(manager.update_device_cache)
+
+        # Register known device IDs
+        cloud_devices = {}
+        domain_data = self.hass.data.get(DOMAIN)
+        for device in manager.device_map.values():
+            cloud_device = {
+                # TODO - Use constants throughout
+                "category": device.category,
+                "id": device.id,
+                "ip": device.ip,  # This will be the WAN IP address so not usable.
+                CONF_LOCAL_KEY: device.local_key
+                if hasattr(device, CONF_LOCAL_KEY)
+                else "",
+                "model": device.model,
+                "name": device.name,
+                "node_id": device.node_id if hasattr(device, "node_id") else "",
+                "online": device.online,
+                "product_id": device.product_id,
+                "product_name": device.product_name,
+                "uid": device.uid,
+                "uuid": device.uuid,
+                "support_local": device.support_local,  # What does this mean?
+                CONF_DEVICE_CID: None,
+                "version": None,
+            }
+            _LOGGER.debug(f"Found device: {cloud_device}")
+
+            existing_id = domain_data.get(cloud_device["id"]) if domain_data else None
+            existing_uuid = (
+                domain_data.get(cloud_device["uuid"]) if domain_data else None
+            )
+            if existing_id or existing_uuid:
+                _LOGGER.debug("Device is already registered.")
+                continue
+
+            _LOGGER.debug(f"Adding device: {cloud_device['id']}")
+            cloud_devices[cloud_device["id"]] = cloud_device
+
+        return cloud_devices
+
+    async def async_step_choose_device(self, user_input=None):
+        errors = {}
+        if user_input is not None:
+            device_choice = self.__cloud_devices[user_input["device_id"]]
+
+            if device_choice["ip"] != "":
+                # This is a directly addable device.
+                if user_input["hub_id"] == "None":
+                    device_choice["ip"] = ""
+                    self.__cloud_device = device_choice
+                    return await self.async_step_search(None)
+                else:
+                    # Show error if user selected a hub.
+                    errors["base"] = "does_not_need_hub"
+                    # Fall through to reshow the form.
+            else:
+                # This is an indirectly addressable device. Need to know which hub it is connected to.
+                if user_input["hub_id"] != "None":
+                    hub_choice = self.__cloud_devices[user_input["hub_id"]]
+                    # Populate uuid and local_key from the child device to pass on complete information to the local step.
+                    hub_choice["ip"] = ""
+                    hub_choice[CONF_DEVICE_CID] = device_choice["uuid"]
+                    hub_choice[CONF_LOCAL_KEY] = device_choice[CONF_LOCAL_KEY]
+                    self.__cloud_device = hub_choice
+                    return await self.async_step_search(None)
+                else:
+                    # Show error if user did not select a hub.
+                    errors["base"] = "needs_hub"
+                    # Fall through to reshow the form.
+
+        device_list = []
+        for key in self.__cloud_devices.keys():
+            device_entry = self.__cloud_devices[key]
+            if device_entry[CONF_LOCAL_KEY] != "":
+                if device_entry["online"]:
+                    device_list.append(
+                        SelectOptionDict(
+                            value=key,
+                            label=f"{device_entry['name']} ({device_entry['product_name']})",
+                        )
+                    )
+                else:
+                    device_list.append(
+                        SelectOptionDict(
+                            value=key,
+                            label=f"{device_entry['name']} ({device_entry['product_name']}) OFFLINE",
+                        )
+                    )
+
+        _LOGGER.debug(f"Device count: {len(device_list)}")
+        if len(device_list) == 0:
+            return self.async_abort(reason="no_devices")
+
+        device_selector = SelectSelector(
+            SelectSelectorConfig(options=device_list, mode=SelectSelectorMode.DROPDOWN)
+        )
+
+        hub_list = []
+        hub_list.append(SelectOptionDict(value="None", label="None"))
+        for key in self.__cloud_devices.keys():
+            hub_entry = self.__cloud_devices[key]
+            if hub_entry[CONF_LOCAL_KEY] == "":
+                hub_list.append(
+                    SelectOptionDict(
+                        value=key,
+                        label=f"{hub_entry['name']} ({hub_entry['product_name']})",
+                    )
+                )
+
+        _LOGGER.debug(f"Hub count: {len(hub_list) - 1}")
+
+        hub_selector = SelectSelector(
+            SelectSelectorConfig(options=hub_list, mode=SelectSelectorMode.DROPDOWN)
+        )
+
+        # Build form
+        fields: OrderedDict[vol.Marker, Any] = OrderedDict()
+        fields[vol.Required("device_id")] = device_selector
+        fields[vol.Required("hub_id")] = hub_selector
+
+        return self.async_show_form(
+            step_id="choose_device",
+            data_schema=vol.Schema(fields),
+            errors=errors or {},
+            last_step=False,
+        )
+
+    async def async_step_search(self, user_input=None):
+        if user_input is not None:
+            # Current IP is the WAN IP which is of no use. Need to try and discover to the local IP.
+            # This scan will take 18s with the default settings. If we cannot find the device we
+            # 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']}."
+            )
+            self.__cloud_device["ip"] = ""
+            local_device = await self.hass.async_add_executor_job(
+                scan_for_device, self.__cloud_device["id"]
+            )
+            if local_device["ip"] is not None:
+                _LOGGER.debug(f"Found: {local_device}")
+                self.__cloud_device["ip"] = local_device["ip"]
+                self.__cloud_device["version"] = local_device["version"]
+            else:
+                _LOGGER.warn(f"Could not find device: {self.__cloud_device['id']}")
+            return await self.async_step_local(None)
+
+        return self.async_show_form(
+            step_id="search", data_schema=vol.Schema({}), errors={}, last_step=False
+        )
+
+    async def async_step_local(self, user_input=None):
+        errors = {}
         devid_opts = {}
         devid_opts = {}
         host_opts = {"default": ""}
         host_opts = {"default": ""}
         key_opts = {}
         key_opts = {}
@@ -40,10 +397,17 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
         polling_opts = {"default": False}
         polling_opts = {"default": False}
         devcid_opts = {}
         devcid_opts = {}
 
 
-        if user_input is not None:
-            await self.async_set_unique_id(get_device_id(user_input))
-            self._abort_if_unique_id_configured()
+        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]}
 
 
+        if user_input is not None:
             self.device = await async_test_connection(user_input, self.hass)
             self.device = await async_test_connection(user_input, self.hass)
             if self.device:
             if self.device:
                 self.data = user_input
                 self.data = user_input
@@ -59,7 +423,7 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
                 polling_opts["default"] = user_input[CONF_POLL_ONLY]
                 polling_opts["default"] = user_input[CONF_POLL_ONLY]
 
 
         return self.async_show_form(
         return self.async_show_form(
-            step_id="user",
+            step_id="local",
             data_schema=vol.Schema(
             data_schema=vol.Schema(
                 {
                 {
                     vol.Required(CONF_DEVICE_ID, **devid_opts): str,
                     vol.Required(CONF_DEVICE_ID, **devid_opts): str,
@@ -139,6 +503,19 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
     def async_get_options_flow(config_entry):
     def async_get_options_flow(config_entry):
         return OptionsFlowHandler(config_entry)
         return OptionsFlowHandler(config_entry)
 
 
+    async def __async_get_qr_code(self, user_code: str) -> tuple[bool, dict[str, Any]]:
+        """Get the QR code."""
+        response = await self.hass.async_add_executor_job(
+            self.__login_control.qr_code,
+            TUYA_CLIENT_ID,
+            TUYA_SCHEMA,
+            user_code,
+        )
+        if success := response.get(TUYA_RESPONSE_SUCCESS, False):
+            self.__user_code = user_code
+            self.__qr_code = response[TUYA_RESPONSE_RESULT][TUYA_RESPONSE_QR_CODE]
+        return success, response
+
 
 
 class OptionsFlowHandler(config_entries.OptionsFlow):
 class OptionsFlowHandler(config_entries.OptionsFlow):
     def __init__(self, config_entry):
     def __init__(self, config_entry):
@@ -221,3 +598,59 @@ async def async_test_connection(config: dict, hass: HomeAssistant):
         existing["device"].resume()
         existing["device"].resume()
 
 
     return retval
     return retval
+
+
+def scan_for_device(id):
+    return tinytuya.find_device(dev_id=id)
+
+
+class DeviceListener(SharingDeviceListener):
+    """Device Update Listener."""
+
+    def __init__(
+        self,
+        hass: HomeAssistant,
+        manager: Manager,
+    ) -> None:
+        """Init DeviceListener."""
+        self.hass = hass
+        self.manager = manager
+
+    def update_device(self, device: CustomerDevice) -> None:
+        """Update device status."""
+        _LOGGER.debug(
+            "Received update for device %s: %s",
+            device.id,
+            self.manager.device_map[device.id].status,
+        )
+
+    def add_device(self, device: CustomerDevice) -> None:
+        """Add device added listener."""
+        _LOGGER.debug(
+            "Received add device %s: %s",
+            device.id,
+            self.manager.device_map[device.id].status,
+        )
+
+    def remove_device(self, device_id: str) -> None:
+        """Add device removed listener."""
+        _LOGGER.debug(
+            "Received remove device %s: %s",
+            device_id,
+            self.manager.device_map[device_id].status,
+        )
+
+
+class TokenListener(SharingTokenListener):
+    """Token listener for upstream token updates."""
+
+    def __init__(
+        self,
+        hass: HomeAssistant,
+    ) -> None:
+        """Init TokenListener."""
+        self.hass = hass
+
+    def update_token(self, token_info: dict[str, Any]) -> None:
+        """Update token info in config entry."""
+        _LOGGER.debug("update_token")

+ 17 - 0
custom_components/tuya_local/const.py

@@ -1,4 +1,5 @@
 DOMAIN = "tuya_local"
 DOMAIN = "tuya_local"
+DATA_STORE = "store"
 
 
 CONF_DEVICE_ID = "device_id"
 CONF_DEVICE_ID = "device_id"
 CONF_LOCAL_KEY = "local_key"
 CONF_LOCAL_KEY = "local_key"
@@ -7,3 +8,19 @@ CONF_POLL_ONLY = "poll_only"
 CONF_DEVICE_CID = "device_cid"
 CONF_DEVICE_CID = "device_cid"
 CONF_PROTOCOL_VERSION = "protocol_version"
 CONF_PROTOCOL_VERSION = "protocol_version"
 API_PROTOCOL_VERSIONS = [3.3, 3.1, 3.2, 3.4, 3.5]
 API_PROTOCOL_VERSIONS = [3.3, 3.1, 3.2, 3.4, 3.5]
+
+CONF_APP_TYPE = "tuya_app_type"
+CONF_ENDPOINT = "endpoint"
+CONF_TERMINAL_ID = "terminal_id"
+CONF_TOKEN_INFO = "token_info"
+CONF_USER_CODE = "user_code"
+CONF_USERNAME = "username"
+
+TUYA_CLIENT_ID = "HA_3y9q4ak7g4ephrvke"
+TUYA_SCHEMA = "haauthorize"
+
+TUYA_RESPONSE_CODE = "code"
+TUYA_RESPONSE_MSG = "msg"
+TUYA_RESPONSE_QR_CODE = "qrcode"
+TUYA_RESPONSE_RESULT = "result"
+TUYA_RESPONSE_SUCCESS = "success"

+ 2 - 1
custom_components/tuya_local/manifest.json

@@ -11,7 +11,8 @@
     "iot_class": "local_push",
     "iot_class": "local_push",
     "issue_tracker": "https://github.com/make-all/tuya-local/issues",
     "issue_tracker": "https://github.com/make-all/tuya-local/issues",
     "requirements": [
     "requirements": [
-        "tinytuya==1.13.2"
+        "tinytuya==1.13.2",
+        "tuya-device-sharing-sdk==0.1.9"
     ],
     ],
     "version": "2024.5.3"
     "version": "2024.5.3"
 }
 }

+ 43 - 2
custom_components/tuya_local/translations/bg.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Конфигуриране на вашето Tuya Local устройство",
+                "description": "Устройствата могат да се добавят ръчно или с помощта на облак с помощта на приложението Smart Life.",
+                "data": {
+                    "setup_mode": "Избор на настройка:"
+                }
+            },
+            "cloud": {
+                "title": "Влезте в Tuya",
+                "description": "Въведете своя потребителски код за Smart Life или Tuya Smart.\n\nМожете да намерите този код в приложението Smart Life или приложението Tuya Smart в **Настройки** > екран **Акаунт и сигурност** и въведете кода",
+                "data": {
+                    "user_code": "Потребителски код:"
+                }
+            },
+            "scan": {
+                "title": "Завършете влизането",
+                "description": "Използвайте приложението Smart Life или приложението Tuya Smart"
+            },
+            "choose_device": {
+                "title": "Изберете устройството за добавяне",
+                "description": "Моля",
+                "data": {
+                    "device_id": "Изберете устройство:",
+                    "hub_id": "Изберете шлюз:"
+                }
+            },
+            "search": {
+                "title": "Намерете IP адреса на устройството",
+                "description": "Облакът Tuya не предоставя локални IP адреси"
+            },
+            "local": {
                 "title": "Конфигуриране на вашето Tuya Local устройство",
                 "title": "Конфигуриране на вашето Tuya Local устройство",
                 "description": "[Следвайте тези инструкции, за да откриете идентификатора на вашето устройство и локалния ключ] (https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Следвайте тези инструкции, за да откриете идентификатора на вашето устройство и локалния ключ] (https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Устройството с този идентификатор вече е добавено.",
             "already_configured": "Устройството с този идентификатор вече е добавено.",
-            "not_supported": "Съжаляваме, няма поддръжка за това устройство, все още"
+            "not_supported": "Съжаляваме, няма поддръжка за това устройство, все още",
+            "no_devices": "Не могат да бъдат намерени нерегистрирани устройства за акаунта."
         },
         },
         "error": {
         "error": {
-            "connection": "Не може да се свърже с вашето устройство с тези данни. Възможно е да става въпрос за прекъсване или данните да са неправилни."
+            "connection": "Не може да се свърже с вашето устройство с тези данни. Възможно е да става въпрос за прекъсване или данните да са неправилни.",
+            "does_not_need_hub": "Устройството не се нуждае от шлюз и беше избран такъв. ",
+            "needs_hub": "Устройството се нуждае от шлюз и не е избран нито един."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Настройка на устройство",
+                "manual": "Предоставете ръчно информация за връзката на устройството."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 43 - 2
custom_components/tuya_local/translations/cz.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Nastavte sve lokální zařízení",
+                "description": "Zařízení lze přidávat ručně nebo pomocí cloudové podpory pomocí aplikace Smart Life.",
+                "data": {
+                    "setup_mode": "Možnost nastavení:"
+                }
+            },
+            "cloud": {
+                "title": "Přihlaste se do Tuya",
+                "description": "Zadejte svůj uživatelský kód Smart Life nebo Tuya Smart.\n\nTento kód najdete v aplikaci Smart Life nebo Tuya Smart na obrazovce **Nastavení** > **Účet a zabezpečení** a zadejte kód zobrazený na ",
+                "data": {
+                    "user_code": "Uživatelský kód:"
+                }
+            },
+            "scan": {
+                "title": "Dokončete přihlášení",
+                "description": "Pomocí aplikace Smart Life nebo Tuya Smart naskenujte následující QR kód a dokončete přihlášení.\n\nPo dokončení tohoto kroku v aplikaci pokračujte k dalšímu kroku."
+            },
+            "choose_device": {
+                "title": "Vyberte zařízení",
+                "description": "Vyberte zařízení",
+                "data": {
+                    "device_id": "Vyberte zařízení:",
+                    "hub_id": "Vyberte bránu:"
+                }
+            },
+            "search": {
+                "title": "Najděte IP adresu zařízení",
+                "description": "Cloud Tuya neposkytuje místní IP adresy"
+            },
+            "local": {
                 "title": "Nastavte sve lokální zařízení",
                 "title": "Nastavte sve lokální zařízení",
                 "description": "[Postupujte podle tohoto návodu pro získaní identifikátoru zařízení (device_id) a lokálního klíče (local_key).](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Postupujte podle tohoto návodu pro získaní identifikátoru zařízení (device_id) a lokálního klíče (local_key).](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Zařízení s identifikátorem, který již byl přidán.",
             "already_configured": "Zařízení s identifikátorem, který již byl přidán.",
-            "not_supported": "Omlouváme se, toto zažízení není podporováno."
+            "not_supported": "Omlouváme se, toto zažízení není podporováno.",
+            "no_devices": "Nelze najít žádná neregistrovaná zařízení pro účet."
         },
         },
         "error": {
         "error": {
-            "connection": "Není možné připojit se k zařízené s těmito údaji. Může se jednat o dočasný problém, nebo zadané údaje nejsou správné."
+            "connection": "Není možné připojit se k zařízené s těmito údaji. Může se jednat o dočasný problém, nebo zadané údaje nejsou správné.",
+            "does_not_need_hub": "Zařízení nepotřebuje bránu a byla vybrána. ",
+            "needs_hub": "Zařízení potřebuje bránu a žádná nebyla vybrána."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Nastavení zařízení pomocí cloudu Smart Life.",
+                "manual": "Ručně zadejte informace o připojení zařízení."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 48 - 2
custom_components/tuya_local/translations/de.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Konfigurieren Sie Ihr Tuya Local-Gerät",
+                "description": "Geräte können entweder manuell oder cloudgestützt mit Hilfe der Smart Life App hinzugefügt werden.",
+                "data": {
+                    "setup_mode": "Setup-Auswahl:"
+                }
+            },
+            "cloud": {
+                "title": "Melden Sie sich bei Tuya an",
+                "description": "Geben Sie Ihren Smart Life- oder Tuya Smart-Benutzercode ein.\n\nSie finden diesen Code in der Smart Life-App oder Tuya Smart-App im Bildschirm **Einstellungen** > **Konto und Sicherheit** und geben Sie den dort angezeigten Code ein ",
+                "data": {
+                    "user_code": "Benutzercode:"
+                }
+            },
+            "scan": {
+                "title": "Schließen Sie die Anmeldung ab",
+                "description": "Verwenden Sie die Smart Life-App oder die Tuya Smart-App"
+            },
+            "choose_device": {
+                "title": "Wählen Sie das hinzuzufügende Gerät aus",
+                "description": "Bitte wählen Sie das hinzuzufügende Gerät aus der ersten Dropdown-Liste aus. ",
+                "data": {
+                    "device_id": "Gerät auswählen:",
+                    "hub_id": "Gateway wählen:"
+                }
+            },
+            "search": {
+                "title": "Suchen Sie die IP-Adresse des Geräts",
+                "description": "Die Tuya-Cloud stellt keine lokalen IP-Adressen bereit"
+            },
+            "local": {
                 "title": "Konfigurieren Sie Ihr Tuya Local-Gerät",
                 "title": "Konfigurieren Sie Ihr Tuya Local-Gerät",
                 "description": "[Folgen Sie diesen Anweisungen, um Ihre Geräte-ID und Ihren lokalen Schlüssel zu finden.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Folgen Sie diesen Anweisungen, um Ihre Geräte-ID und Ihren lokalen Schlüssel zu finden.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Es wurde bereits ein Gerät mit dieser ID hinzugefügt.",
             "already_configured": "Es wurde bereits ein Gerät mit dieser ID hinzugefügt.",
-            "not_supported": "Dieses Gerät wird leider nicht unterstützt."
+            "not_supported": "Dieses Gerät wird leider nicht unterstützt.",
+            "no_devices": "Für das Konto konnten keine nicht registrierten Geräte gefunden werden."
         },
         },
         "error": {
         "error": {
-            "connection": "Mit diesen Angaben kann keine Verbindung zu Ihrem Gerät hergestellt werden. Es könnte sich um ein intermittierendes Problem handeln, oder die Angaben sind falsch."
+            "connection": "Mit diesen Angaben kann keine Verbindung zu Ihrem Gerät hergestellt werden. Es könnte sich um ein intermittierendes Problem handeln, oder die Angaben sind falsch.",
+            "does_not_need_hub": "Das Gerät benötigt kein Gateway und es wurde eines ausgewählt. ",
+            "needs_hub": "Das Gerät benötigt ein Gateway und es wurde keines ausgewählt."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Cloud-gestützte Geräteeinrichtung von Smart Life.",
+                "manual": "Geben Sie manuell Informationen zur Geräteverbindung an."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -269,6 +310,11 @@
                 }
                 }
             }
             }
         },
         },
+        "sensor": {
+            "time_remaining": {
+                "name": "Verbleibende Zeit"
+            }
+        },
         "switch": {
         "switch": {
             "anti_frost": {
             "anti_frost": {
                 "name": "Anti-Frost"
                 "name": "Anti-Frost"

+ 43 - 2
custom_components/tuya_local/translations/en.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Configure your Tuya Local device",
+                "description": "Devices can either be added manually or cloud-assisted with the help of the Smart Life app.",
+                "data": {
+                    "setup_mode": "Setup choice:"
+                }
+            },
+            "cloud": {
+                "title": "Login to Tuya",
+                "description": "Enter your Smart Life or Tuya Smart user code.\n\nYou can find this code in the Smart Life app or Tuya Smart app in **Settings** > **Account and Security** screen, and enter the code shown on the **User Code** field. The user code is case sensitive, please be sure to enter it exactly as shown in the app.",
+                "data": {
+                    "user_code": "User code:"
+                }
+            },
+            "scan": {
+                "title": "Complete the login",
+                "description": "Use Smart Life app or Tuya Smart app to scan the following QR-code to complete the login.\n\nContinue to the next step once you have completed this step in the app."
+            },
+            "choose_device": {
+                "title": "Choose the device to add",
+                "description": "Please pick the device to add from the first drop-down list. Already added devices are not shown.\n\nIf the device connects through a gateway, select that from the gateway list otherwise choose None.",
+                "data": {
+                    "device_id": "Choose device:",
+                    "hub_id": "Choose gateway:"
+                }
+            },
+            "search": {
+                "title": "Locate the device IP address",
+                "description": "Tuya cloud does not provide local IP addresses so we must now search your local network to find the device. This takes up to 20 seconds.\n\nIf unsuccessful you will need to provide the IP address yourself some other way such as from router DHCP assignment.\n\nFor this step and the following device addition to succeed you must shut down the mobile app or its connections to the device will often block Tuya Local communication with them."
+            },
+            "local": {
                 "title": "Configure your Tuya Local device",
                 "title": "Configure your Tuya Local device",
                 "description": "[Follow these instructions to find your device id and local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Follow these instructions to find your device id and local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "A device with that ID has already been added.",
             "already_configured": "A device with that ID has already been added.",
-            "not_supported": "Sorry, there is no support for this device."
+            "not_supported": "Sorry, there is no support for this device.",
+            "no_devices": "Unable to find any unregistered devices for the account."
         },
         },
         "error": {
         "error": {
-            "connection": "Unable to connect to your device with those details. It could be an intermittent issue, or they may be incorrect."
+            "connection": "Unable to connect to your device with those details. It could be an intermittent issue, or they may be incorrect.",
+            "does_not_need_hub": "Device does not need a gateway and one was selected. Please review your choices.",
+            "needs_hub": "Device needs a gateway and none was selected."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Smart Life cloud-assisted device setup.",
+                "manual": "Manually provide device connection information."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 44 - 3
custom_components/tuya_local/translations/es.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Configura tu dispositivo Tuya Local",
+                "description": "Los dispositivos se pueden agregar manualmente o con la ayuda de la nube con la ayuda de la aplicación Smart Life.",
+                "data": {
+                    "setup_mode": "Elección de configuración:"
+                }
+            },
+            "cloud": {
+                "title": "Iniciar sesión en Tuya",
+                "description": "Ingresa tu código de usuario de Smart Life o Tuya Smart.\n\nPuedes encontrar este código en la aplicación Smart Life o Tuya Smart en la pantalla **Configuración** > **Cuenta y seguridad** e ingresa el código que se muestra en el ",
+                "data": {
+                    "user_code": "Codigo de usuario:"
+                }
+            },
+            "scan": {
+                "title": "Completa el inicio de sesión",
+                "description": "Utilice la aplicación Smart Life o la aplicación Tuya Smart para escanear el siguiente código QR y completar el inicio de sesión.\n\nContinúe con el siguiente paso una vez que haya completado este paso en la aplicación."
+            },
+            "choose_device": {
+                "title": "Elija el dispositivo para agregar",
+                "description": "Elija el dispositivo que desea agregar de la primera lista desplegable. ",
+                "data": {
+                    "device_id": "Elija dispositivo:",
+                    "hub_id": "Elija puerta de enlace:"
+                }
+            },
+            "search": {
+                "title": "Localice la dirección IP del dispositivo",
+                "description": "Tuya Cloud no proporciona direcciones IP locales por lo que ahora debemos buscar en su red local para encontrar el dispositivo. "
+            },
+            "local": {
                 "title": "Configura tu dispositivo Tuya Local",
                 "title": "Configura tu dispositivo Tuya Local",
                 "description": "[Siga estas instrucciones para encontrar la identificación de su dispositivo y la clave local.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Siga estas instrucciones para encontrar la identificación de su dispositivo y la clave local.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Ya se ha agregado un dispositivo con esa ID.",
             "already_configured": "Ya se ha agregado un dispositivo con esa ID.",
-            "not_supported": "Lo sentimos, no hay soporte para este dispositivo."
+            "not_supported": "Lo sentimos, no hay soporte para este dispositivo.",
+            "no_devices": "No se puede encontrar ningún dispositivo no registrado para la cuenta."
         },
         },
         "error": {
         "error": {
-            "connection": "No se puede conectar a su dispositivo con esos detalles. Podría ser un problema intermitente, o pueden ser incorrectos."
+            "connection": "No se puede conectar a su dispositivo con esos detalles. Podría ser un problema intermitente, o pueden ser incorrectos.",
+            "does_not_need_hub": "El dispositivo no necesita una puerta de enlace y se seleccionó una. ",
+            "needs_hub": "El dispositivo necesita una puerta de enlace y no se seleccionó ninguna."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Configuración del dispositivo asistida por la nube Smart Life.",
+                "manual": "Proporcione manualmente información de conexión del dispositivo."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -47,7 +88,7 @@
                     "local_key": "Clave local (Local key)",
                     "local_key": "Clave local (Local key)",
                     "protocol_version": "Versión del protocolo (pruebe automático si no lo sabe)",
                     "protocol_version": "Versión del protocolo (pruebe automático si no lo sabe)",
                     "poll_only": "[es] Poll only (try this if your device does not work fully)",
                     "poll_only": "[es] Poll only (try this if your device does not work fully)",
-                    "device_cid": "[es] Sub device ID (for devices connected via gateway)"                    
+                    "device_cid": "[es] Sub device ID (for devices connected via gateway)"
                 }
                 }
             }
             }
         },
         },

+ 76 - 2
custom_components/tuya_local/translations/fr.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Configurer votre appareil Tuya Local",
+                "description": "Les appareils peuvent être ajoutés manuellement ou assistés par le cloud à l'aide de l'application Smart Life.",
+                "data": {
+                    "setup_mode": "Choix de configuration :"
+                }
+            },
+            "cloud": {
+                "title": "Connectez-vous à Tuya",
+                "description": "Saisissez votre code utilisateur Smart Life ou Tuya Smart.\n\nVous pouvez trouver ce code dans l'application Smart Life ou Tuya Smart dans l'écran **Paramètres** > **Compte et sécurité**",
+                "data": {
+                    "user_code": "Code d'utilisateur:"
+                }
+            },
+            "scan": {
+                "title": "Complétez la connexion",
+                "description": "Utilisez l'application Smart Life ou l'application Tuya Smart pour scanner le code QR suivant afin de terminer la connexion.\n\nContinuez à l'étape suivante une fois que vous avez terminé cette étape dans l'application."
+            },
+            "choose_device": {
+                "title": "Choisissez l'appareil à ajouter",
+                "description": "Veuillez sélectionner l'appareil à ajouter dans la première liste déroulante. ",
+                "data": {
+                    "device_id": "Choisissez l'appareil :",
+                    "hub_id": "Choisissez la passerelle :"
+                }
+            },
+            "search": {
+                "title": "Localisez l'adresse IP de l'appareil",
+                "description": "Tuya cloud ne fournit pas d'adresses IP locales"
+            },
+            "local": {
                 "title": "Configurer votre appareil Tuya Local",
                 "title": "Configurer votre appareil Tuya Local",
                 "description": "[Suivre ces instructions pour trouver le 'device id' et la 'local key'.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Suivre ces instructions pour trouver le 'device id' et la 'local key'.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Un appareil avec cet ID a déjà été ajouté.",
             "already_configured": "Un appareil avec cet ID a déjà été ajouté.",
-            "not_supported": "Désolé, il n'y a pas de support pour cet appareil."
+            "not_supported": "Désolé, il n'y a pas de support pour cet appareil.",
+            "no_devices": "Impossible de trouver des appareils non enregistrés pour le compte."
         },
         },
         "error": {
         "error": {
-            "connection": "Impossible de se connecter à votre appareil avec ces réglages. Il peut s'agir d'un problème intermittent ou les réglages sont incorrects."
+            "connection": "Impossible de se connecter à votre appareil avec ces réglages. Il peut s'agir d'un problème intermittent ou les réglages sont incorrects.",
+            "does_not_need_hub": "L'appareil n'a pas besoin de passerelle et une a été sélectionnée. ",
+            "needs_hub": "L'appareil a besoin d'une passerelle et aucune n'a été sélectionnée."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Configuration de l'appareil assistée par le cloud Smart Life.",
+                "manual": "Fournissez manuellement les informations de connexion de l’appareil."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -188,6 +229,39 @@
                 }
                 }
             }
             }
         },
         },
+        "fan": {
+            "fan_with_presets": {
+                "state_attributes": {
+                    "preset_mode": {
+                        "state": {
+                            "normal": "Normale",
+                            "nature": "Naturel",
+                            "sleep": "Dormir",
+                            "baby": "Bébé",
+                            "fresh": "Frais",
+                            "smart": "Intelligent",
+                            "strong": "Fort",
+                            "displayoff": "Affichage désactivé",
+                            "off": "Désactivé"
+                        }
+                    }
+                }
+            },
+            "ventilation": {
+                "state_attributes": {
+                    "preset_mode": {
+                        "state": {
+                            "fresh": "Air frais",
+                            "circulate": "Circuler",
+                            "sleep": "Dormir",
+                            "auto": "Auto",
+                            "eco": "Écologique",
+                            "anti-condensation": "Anti-condensation"
+                        }
+                    }
+                }
+            }
+        },
         "light": {
         "light": {
             "backlight": {
             "backlight": {
                 "name": "Rétroéclairage"
                 "name": "Rétroéclairage"

+ 44 - 3
custom_components/tuya_local/translations/hu.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Állítsd be a helyi Tuya eszközöd",
+                "description": "Az eszközök manuálisan vagy felhőben is hozzáadhatók a Smart Life alkalmazás segítségével.",
+                "data": {
+                    "setup_mode": "Beállítás választás:"
+                }
+            },
+            "cloud": {
+                "title": "Jelentkezzen be Tuyába",
+                "description": "Adja meg Smart Life vagy Tuya Smart felhasználói kódját.\n\nEzt a kódot a Smart Life alkalmazásban vagy a Tuya Smart alkalmazásban találja meg a **Beállítások** > **Fiók és biztonság** képernyőn",
+                "data": {
+                    "user_code": "Felhasználói kód:"
+                }
+            },
+            "scan": {
+                "title": "Töltse ki a bejelentkezést",
+                "description": "Használja a Smart Life alkalmazást vagy a Tuya Smart alkalmazást a következő QR-kód beolvasásához a bejelentkezés befejezéséhez.\n\nHa befejezte ezt a lépést az alkalmazásban"
+            },
+            "choose_device": {
+                "title": "Válassza ki a hozzáadni kívánt eszközt",
+                "description": "Kérjük",
+                "data": {
+                    "device_id": "Válasszon eszközt:",
+                    "hub_id": "Válasszon átjárót:"
+                }
+            },
+            "search": {
+                "title": "Keresse meg az eszköz IP-címét",
+                "description": "A Tuya felhő nem biztosít helyi IP-címeket"
+            },
+            "local": {
                 "title": "Állítsd be a helyi Tuya eszközöd",
                 "title": "Állítsd be a helyi Tuya eszközöd",
                 "description": "[Kövesd ezeket az utasításokat, hogy megtaláld az eszköz azonosítóját (device_id) és a helyi kulcsot (local_key).](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Kövesd ezeket az utasításokat, hogy megtaláld az eszköz azonosítóját (device_id) és a helyi kulcsot (local_key).](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -12,7 +42,6 @@
                     "protocol_version": "Protokol verzió (hagyd auto-n, ha nem tudod)",
                     "protocol_version": "Protokol verzió (hagyd auto-n, ha nem tudod)",
                     "poll_only": "Csak olvasás (próbáld ki ezt, ha az eszköz nem működik rendesen)",
                     "poll_only": "Csak olvasás (próbáld ki ezt, ha az eszköz nem működik rendesen)",
                     "device_cid": "Aleszköz azonosító (átjárón keresztül használt eszközök esetén)"
                     "device_cid": "Aleszköz azonosító (átjárón keresztül használt eszközök esetén)"
-                    
                 }
                 }
             },
             },
             "select_type": {
             "select_type": {
@@ -32,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Ezzel az azonosítóval már lett hozzáadva eszköz.",
             "already_configured": "Ezzel az azonosítóval már lett hozzáadva eszköz.",
-            "not_supported": "Sajnálom, ez az eszköz nem támogatott."
+            "not_supported": "Sajnálom, ez az eszköz nem támogatott.",
+            "no_devices": "Nem található a fiókhoz nem regisztrált eszköz."
         },
         },
         "error": {
         "error": {
-            "connection": "A megadott adatokkal nem sikerült kapcsolódni az eszközhöz. Lehet ideiglenes a probléma, vagy nem megfelelőek a megadott adatok."
+            "connection": "A megadott adatokkal nem sikerült kapcsolódni az eszközhöz. Lehet ideiglenes a probléma, vagy nem megfelelőek a megadott adatok.",
+            "does_not_need_hub": "Az eszköznek nincs szüksége átjáróra",
+            "needs_hub": "Az eszköznek átjáróra van szüksége"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Smart Life felhő által támogatott eszközbeállítás.",
+                "manual": "Adja meg manuálisan az eszköz csatlakozási adatait."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -201,6 +241,7 @@
                             "fresh": "Friss",
                             "fresh": "Friss",
                             "smart": "Okos",
                             "smart": "Okos",
                             "strong": "Erős",
                             "strong": "Erős",
+                            "displayoff": "Kijelző kikapcsolva",
                             "off": "Ki"
                             "off": "Ki"
                         }
                         }
                     }
                     }

+ 43 - 2
custom_components/tuya_local/translations/id.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Konfigurasikan perangkat Tuya Local Anda",
+                "description": "Perangkat dapat ditambahkan secara manual atau dibantu cloud dengan bantuan aplikasi Smart Life.",
+                "data": {
+                    "setup_mode": "Pilihan pengaturan:"
+                }
+            },
+            "cloud": {
+                "title": "Masuk ke Tuya",
+                "description": "Masukkan kode pengguna Smart Life atau Tuya Smart Anda.\n\nAnda dapat menemukan kode ini di aplikasi Smart Life atau aplikasi Tuya Smart di layar **Setelan** > **Akun dan Keamanan**",
+                "data": {
+                    "user_code": "Kode pengguna:"
+                }
+            },
+            "scan": {
+                "title": "Selesaikan login",
+                "description": "Gunakan aplikasi Smart Life atau aplikasi Tuya Smart untuk memindai kode QR berikut untuk menyelesaikan login.\n\nLanjutkan ke langkah berikutnya setelah Anda menyelesaikan langkah ini di aplikasi."
+            },
+            "choose_device": {
+                "title": "Pilih perangkat yang akan ditambahkan",
+                "description": "Silakan pilih perangkat yang akan ditambahkan dari daftar drop-down pertama. ",
+                "data": {
+                    "device_id": "Pilih perangkat:",
+                    "hub_id": "Pilih gerbang:"
+                }
+            },
+            "search": {
+                "title": "Temukan alamat IP perangkat",
+                "description": "Tuya cloud tidak menyediakan alamat IP lokal jadi sekarang kami harus mencari di jaringan lokal Anda untuk menemukan perangkat. "
+            },
+            "local": {
                 "title": "Konfigurasikan perangkat Tuya Local Anda",
                 "title": "Konfigurasikan perangkat Tuya Local Anda",
                 "description": "[Ikuti petunjuk ini untuk menemukan ID perangkat dan kunci lokal.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Ikuti petunjuk ini untuk menemukan ID perangkat dan kunci lokal.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Perangkat dengan ID tersebut pernah ditambahkan.",
             "already_configured": "Perangkat dengan ID tersebut pernah ditambahkan.",
-            "not_supported": "Maaf, perangkat ini belum didukung."
+            "not_supported": "Maaf, perangkat ini belum didukung.",
+            "no_devices": "Tidak dapat menemukan perangkat yang tidak terdaftar untuk akun tersebut."
         },
         },
         "error": {
         "error": {
-            "connection": "Tidak dapat terkoneksi ke perangkat tersebut. Bisa jadi sementara, atau ada kesalahan."
+            "connection": "Tidak dapat terkoneksi ke perangkat tersebut. Bisa jadi sementara, atau ada kesalahan.",
+            "does_not_need_hub": "Perangkat tidak memerlukan gateway dan satu telah dipilih. ",
+            "needs_hub": "Perangkat memerlukan gateway dan tidak ada yang dipilih."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Penyiapan perangkat berbantuan cloud Smart Life.",
+                "manual": "Berikan informasi koneksi perangkat secara manual."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 43 - 2
custom_components/tuya_local/translations/it.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Configura il tuo dispositivo Tuya Local",
+                "description": "I dispositivi possono essere aggiunti manualmente o tramite cloud con l'aiuto dell'app Smart Life.",
+                "data": {
+                    "setup_mode": "Scelta dell'impostazione:"
+                }
+            },
+            "cloud": {
+                "title": "Accedi a Tuya",
+                "description": "Inserisci il tuo codice utente Smart Life o Tuya Smart.\n\nPuoi trovare questo codice nell'app Smart Life o nell'app Tuya Smart nella schermata **Impostazioni** > **Account e sicurezza** e inserisci il codice mostrato nella schermata ",
+                "data": {
+                    "user_code": "Codice utente:"
+                }
+            },
+            "scan": {
+                "title": "Completa il login",
+                "description": "Utilizza l'app Smart Life o l'app Tuya Smart per scansionare il seguente codice QR per completare l'accesso.\n\nContinua al passaggio successivo una volta completato questo passaggio nell'app."
+            },
+            "choose_device": {
+                "title": "Scegli il dispositivo da aggiungere",
+                "description": "Scegli il dispositivo da aggiungere dal primo elenco a discesa. ",
+                "data": {
+                    "device_id": "Scegli dispositivo:",
+                    "hub_id": "Scegli gateway:"
+                }
+            },
+            "search": {
+                "title": "Individuare l'indirizzo IP del dispositivo",
+                "description": "Tuya cloud non fornisce indirizzi IP locali quindi ora dobbiamo cercare nella rete locale per trovare il dispositivo. "
+            },
+            "local": {
                 "title": "Configura il tuo dispositivo Tuya Local",
                 "title": "Configura il tuo dispositivo Tuya Local",
                 "description": "[Segui queste istruzioni per trovare 'device id' e 'local key'.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Segui queste istruzioni per trovare 'device id' e 'local key'.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "E' già presente un dispositivo con l'ID inserito.",
             "already_configured": "E' già presente un dispositivo con l'ID inserito.",
-            "not_supported": "Spiacente, il dispositivo non è supportato."
+            "not_supported": "Spiacente, il dispositivo non è supportato.",
+            "no_devices": "Impossibile trovare dispositivi non registrati per l'account."
         },
         },
         "error": {
         "error": {
-            "connection": "Impossibile connettersi al dispositivo. Può trattarsi di un problema temporaneo, oppure le informazioni fornite potrebbero non essere corrette."
+            "connection": "Impossibile connettersi al dispositivo. Può trattarsi di un problema temporaneo, oppure le informazioni fornite potrebbero non essere corrette.",
+            "does_not_need_hub": "Il dispositivo non necessita di un gateway e ne è stato selezionato uno. ",
+            "needs_hub": "Il dispositivo necessita di un gateway e non ne è stato selezionato nessuno."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Configurazione del dispositivo Smart Life assistita da cloud.",
+                "manual": "Fornire manualmente le informazioni sulla connessione del dispositivo."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 43 - 2
custom_components/tuya_local/translations/ja.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Tuya Localのデバイスを設定する",
+                "description": "デバイスは手動で追加することも、Smart Life アプリを使用してクラウド支援で追加することもできます。",
+                "data": {
+                    "setup_mode": "セットアップの選択:"
+                }
+            },
+            "cloud": {
+                "title": "Tuyaにログイン",
+                "description": "Smart Life または Tuya Smart のユーザー コードを入力してください。\n\nこのコードは、Smart Life アプリまたは Tuya Smart アプリの [*設定**] > [**アカウントとセキュリティ**] 画面で見つけて、画面に表示されているコードを入力してください。 ",
+                "data": {
+                    "user_code": "ユーザーコード:"
+                }
+            },
+            "scan": {
+                "title": "ログインを完了する",
+                "description": "Smart Life アプリまたは Tuya Smart アプリを使用して次の QR コードをスキャンし、ログインを完了します。\n\nアプリでこの手順を完了したら、次の手順に進みます。"
+            },
+            "choose_device": {
+                "title": "追加するデバイスを選択してください",
+                "description": "最初のドロップダウン リストから追加するデバイスを選択してください。",
+                "data": {
+                    "device_id": "デバイスを選択してください:",
+                    "hub_id": "ゲートウェイを選択します:"
+                }
+            },
+            "search": {
+                "title": "デバイスのIPアドレスを特定する",
+                "description": "Tuya クラウドはローカル IP アドレスを提供しないため、ローカル ネットワークを検索してデバイスを見つける必要があります。"
+            },
+            "local": {
                 "title": "Tuya Localのデバイスを設定する",
                 "title": "Tuya Localのデバイスを設定する",
                 "description": "[ja] [Follow these instructions to find your device id and local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[ja] [Follow these instructions to find your device id and local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "その ID を持つデバイスはすでに構成されています。",
             "already_configured": "その ID を持つデバイスはすでに構成されています。",
-            "not_supported": "申し訳ございませんが、このデバイスはサポートされていません。"
+            "not_supported": "申し訳ございませんが、このデバイスはサポートされていません。",
+            "no_devices": "アカウントに未登録のデバイスが見つかりません。"
         },
         },
         "error": {
         "error": {
-            "connection": "このような詳細ではデバイスに接続できません。 断続的な問題である可能性もありますし、間違っている可能性もあります。"
+            "connection": "このような詳細ではデバイスに接続できません。 断続的な問題である可能性もありますし、間違っている可能性もあります。",
+            "does_not_need_hub": "デバイスにはゲートウェイが必要なく、ゲートウェイが選択されました。",
+            "needs_hub": "デバイスにはゲートウェイが必要ですが、ゲートウェイが選択されていません。"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Smart Life クラウド支援デバイスのセットアップ。",
+                "manual": "デバイスの接続情報を手動で提供します。"
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 59 - 2
custom_components/tuya_local/translations/no-NB.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Konfigurer din lokale Tuya enhet",
+                "description": "Enheter kan enten legges til manuelt eller skyassistert ved hjelp av Smart Life-appen.",
+                "data": {
+                    "setup_mode": "Oppsettvalg:"
+                }
+            },
+            "cloud": {
+                "title": "Logg inn på Tuya",
+                "description": "Skriv inn Smart Life- eller Tuya Smart-brukerkoden din.\n\nDu finner denne koden i Smart Life-appen eller Tuya Smart-appen i **Innstillinger** > **Konto og sikkerhet**-skjermbildet",
+                "data": {
+                    "user_code": "Brukerkode:"
+                }
+            },
+            "scan": {
+                "title": "Fullfør påloggingen",
+                "description": "Bruk Smart Life-appen eller Tuya Smart-appen for å skanne følgende QR-kode for å fullføre påloggingen.\n\nFortsett til neste trinn når du har fullført dette trinnet i appen."
+            },
+            "choose_device": {
+                "title": "Velg enheten du vil legge til",
+                "description": "Velg enheten du vil legge til fra den første rullegardinlisten. ",
+                "data": {
+                    "device_id": "Velg enhet:",
+                    "hub_id": "Velg gateway:"
+                }
+            },
+            "search": {
+                "title": "Finn enhetens IP-adresse",
+                "description": "Tuya cloud gir ikke lokale IP-adresser"
+            },
+            "local": {
                 "title": "Konfigurer din lokale Tuya enhet",
                 "title": "Konfigurer din lokale Tuya enhet",
                 "description": "[Følg instruksjonene her for å finne enhets-id og den lokale nøkkelen.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Følg instruksjonene her for å finne enhets-id og den lokale nøkkelen.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "En enhet med denne ID-en eksisterer allerede.",
             "already_configured": "En enhet med denne ID-en eksisterer allerede.",
-            "not_supported": "Beklager, det er ingen støtte for denne enheten."
+            "not_supported": "Beklager, det er ingen støtte for denne enheten.",
+            "no_devices": "Kan ikke finne noen uregistrerte enheter for kontoen."
         },
         },
         "error": {
         "error": {
-            "connection": "Kunne ikke koble til enheten med de angitte detaljene. Det kan være en midlertidig feil, eller feil med detaljene angitt."
+            "connection": "Kunne ikke koble til enheten med de angitte detaljene. Det kan være en midlertidig feil, eller feil med detaljene angitt.",
+            "does_not_need_hub": "Enheten trenger ikke en gateway",
+            "needs_hub": "Enheten trenger en gateway"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Smart Life sky-assistert enhetsoppsett.",
+                "manual": "Oppgi informasjon om enhetstilkobling manuelt."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -196,13 +237,29 @@
                             "normal": "Normal",
                             "normal": "Normal",
                             "nature": "Nøytral",
                             "nature": "Nøytral",
                             "sleep": "Søvn",
                             "sleep": "Søvn",
+                            "baby": "Baby",
                             "fresh": "Fresh",
                             "fresh": "Fresh",
                             "smart": "Smart",
                             "smart": "Smart",
                             "strong": "Sterk",
                             "strong": "Sterk",
+                            "displayoff": "Skjerm av",
                             "off": "Av"
                             "off": "Av"
                         }
                         }
                     }
                     }
                 }
                 }
+            },
+            "ventilation": {
+                "state_attributes": {
+                    "preset_mode": {
+                        "state": {
+                            "fresh": "Frisk luft",
+                            "circulate": "Sirkulere",
+                            "sleep": "Sove",
+                            "auto": "Auto",
+                            "eco": "Øko",
+                            "anti-condensation": "Anti-kondens"
+                        }
+                    }
+                }
             }
             }
         },
         },
         "light": {
         "light": {

+ 44 - 2
custom_components/tuya_local/translations/pl.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Skonfiguruj swoje urządzenie Tuya Local",
+                "description": "Urządzenia można dodawać ręcznie lub przy pomocy chmury za pomocą aplikacji Smart Life.",
+                "data": {
+                    "setup_mode": "Wybór konfiguracji:"
+                }
+            },
+            "cloud": {
+                "title": "Zaloguj się do Tuyi",
+                "description": "Wprowadź swój kod użytkownika Smart Life lub Tuya Smart.\n\nKod ten znajdziesz w aplikacji Smart Life lub Tuya Smart na ekranie **Ustawienia** > **Konto i bezpieczeństwo** i wprowadź kod widoczny na ekranie ",
+                "data": {
+                    "user_code": "Kod użytkownika:"
+                }
+            },
+            "scan": {
+                "title": "Dokończ logowanie",
+                "description": "Użyj aplikacji Smart Life lub aplikacji Tuya Smart"
+            },
+            "choose_device": {
+                "title": "Wybierz urządzenie",
+                "description": "Wybierz urządzenie do dodania z pierwszej listy rozwijanej. ",
+                "data": {
+                    "device_id": "Wybierz urządzenie:",
+                    "hub_id": "Wybierz bramkę:"
+                }
+            },
+            "search": {
+                "title": "Znajdź adres IP urządzenia",
+                "description": "Chmura Tuya nie udostępnia lokalnych adresów IP"
+            },
+            "local": {
                 "title": "Skonfiguruj swoje urządzenie Tuya Local",
                 "title": "Skonfiguruj swoje urządzenie Tuya Local",
                 "description": "[Postępuj zgodnie z instrukcjami by znaleźć swoje Device ID oraz Local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Postępuj zgodnie z instrukcjami by znaleźć swoje Device ID oraz Local key.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Urządzenie z takim ID już istnieje.",
             "already_configured": "Urządzenie z takim ID już istnieje.",
-            "not_supported": "Przepraszam, to urządzenie nie jest wspierane."
+            "not_supported": "Przepraszam, to urządzenie nie jest wspierane.",
+            "no_devices": "Nie udało się znaleźć żadnych niezarejestrowanych urządzeń dla konta."
         },
         },
         "error": {
         "error": {
-            "connection": "Nie można podłączyć się do urządzenia z tymi danymi. To może być tymczasowy problem lub dane mogą być niewłaściwe."
+            "connection": "Nie można podłączyć się do urządzenia z tymi danymi. To może być tymczasowy problem lub dane mogą być niewłaściwe.",
+            "does_not_need_hub": "Urządzenie nie potrzebuje bramy i taką wybrano. ",
+            "needs_hub": "Urządzenie wymaga bramy"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Konfiguracja urządzenia Smart Life wspomagana chmurą.",
+                "manual": "Ręcznie podaj informacje o połączeniu urządzenia."
+            }
         }
         }
     },
     },
     "options": {
     "options": {
@@ -200,6 +241,7 @@
                             "fresh": "Świeży",
                             "fresh": "Świeży",
                             "smart": "Inteligentny",
                             "smart": "Inteligentny",
                             "strong": "Silny",
                             "strong": "Silny",
+                            "displayoff": "Wyświetlacz wyłączony",
                             "off": "Wyłączony"
                             "off": "Wyłączony"
                         }
                         }
                     }
                     }

+ 43 - 2
custom_components/tuya_local/translations/pt-BR.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Configure seu dispositivo Tuya Local",
+                "description": "Os dispositivos podem ser adicionados manualmente ou assistidos pela nuvem com a ajuda do aplicativo Smart Life.",
+                "data": {
+                    "setup_mode": "Escolha de configuração:"
+                }
+            },
+            "cloud": {
+                "title": "Faça login no Tuya",
+                "description": "Insira seu código de usuário do Smart Life ou Tuya Smart.\n\nVocê pode encontrar esse código no aplicativo Smart Life ou no aplicativo Tuya Smart em **Configurações** > tela **Conta e segurança** e insira o código mostrado na tela ",
+                "data": {
+                    "user_code": "Código de usuário:"
+                }
+            },
+            "scan": {
+                "title": "Conclua o login",
+                "description": "Use o aplicativo Smart Life ou Tuya Smart para digitalizar o seguinte código QR para concluir o login.\n\nContinue para a próxima etapa depois de concluir esta etapa no aplicativo."
+            },
+            "choose_device": {
+                "title": "Escolha o dispositivo a ser adicionado",
+                "description": "Escolha o dispositivo a ser adicionado na primeira lista suspensa. ",
+                "data": {
+                    "device_id": "Escolha o dispositivo:",
+                    "hub_id": "Escolha o gateway:"
+                }
+            },
+            "search": {
+                "title": "Localize o endereço IP do dispositivo",
+                "description": "A nuvem Tuya não fornece endereços IP locais"
+            },
+            "local": {
                 "title": "Configure seu dispositivo Tuya Local",
                 "title": "Configure seu dispositivo Tuya Local",
                 "description": "[Siga estas instruções para encontrar o ID do seu dispositivo e a chave local.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Siga estas instruções para encontrar o ID do seu dispositivo e a chave local.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Um dispositivo com esse ID já foi adicionado.",
             "already_configured": "Um dispositivo com esse ID já foi adicionado.",
-            "not_supported": "Desculpe, não há suporte para este dispositivo."
+            "not_supported": "Desculpe, não há suporte para este dispositivo.",
+            "no_devices": "Não foi possível encontrar nenhum dispositivo não registrado para a conta."
         },
         },
         "error": {
         "error": {
-            "connection": "Não foi possível conectar ao seu dispositivo com esses detalhes. Pode ser um problema intermitente ou eles podem estar incorretos."
+            "connection": "Não foi possível conectar ao seu dispositivo com esses detalhes. Pode ser um problema intermitente ou eles podem estar incorretos.",
+            "does_not_need_hub": "O dispositivo não precisa de gateway e um foi selecionado. ",
+            "needs_hub": "O dispositivo precisa de um gateway e nenhum foi selecionado."
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Configuração do dispositivo assistido pela nuvem Smart Life.",
+                "manual": "Forneça manualmente informações de conexão do dispositivo."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 43 - 2
custom_components/tuya_local/translations/ru.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "Настройка устройства Tuya Local",
+                "description": "Устройства можно добавлять вручную или через облако с помощью приложения Smart Life.",
+                "data": {
+                    "setup_mode": "Выбор установки:"
+                }
+            },
+            "cloud": {
+                "title": "Войти в Тую",
+                "description": "Введите свой код пользователя Smart Life или Tuya Smart.\n\nВы можете найти этот код в приложении Smart Life или Tuya Smart на экране **Настройки** > **Аккаунт и безопасность** и введите код",
+                "data": {
+                    "user_code": "Код пользователя:"
+                }
+            },
+            "scan": {
+                "title": "Завершите вход",
+                "description": "Используйте приложение Smart Life или приложение Tuya Smart"
+            },
+            "choose_device": {
+                "title": "Выберите устройство для добавления",
+                "description": "Пожалуйста",
+                "data": {
+                    "device_id": "Выберите устройство:",
+                    "hub_id": "Выберите шлюз:"
+                }
+            },
+            "search": {
+                "title": "Найдите IP-адрес устройства",
+                "description": "Облако Tuya не предоставляет локальные IP-адреса"
+            },
+            "local": {
                 "title": "Настройка устройства Tuya Local",
                 "title": "Настройка устройства Tuya Local",
                 "description": "[Следуйте этим инструкциям, чтобы найти идентификатор устройства и локальный ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[Следуйте этим инструкциям, чтобы найти идентификатор устройства и локальный ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "Устройство с этим идентификатором уже было добавлено.",
             "already_configured": "Устройство с этим идентификатором уже было добавлено.",
-            "not_supported": "К сожалению, это устройство не поддерживается."
+            "not_supported": "К сожалению, это устройство не поддерживается.",
+            "no_devices": "Не удалось найти незарегистрированные устройства для учетной записи."
         },
         },
         "error": {
         "error": {
-            "connection": "Не удается подключиться к вашему устройству с этими данными. Это может быть временная проблема, или данные могут быть неверными."
+            "connection": "Не удается подключиться к вашему устройству с этими данными. Это может быть временная проблема, или данные могут быть неверными.",
+            "does_not_need_hub": "Устройству не нужен шлюз",
+            "needs_hub": "Устройству нужен шлюз"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Настройка устройства с помощью облака Smart Life.",
+                "manual": "Вручную укажите информацию о подключении устройства."
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 95 - 54
custom_components/tuya_local/translations/uk.json

@@ -1,62 +1,103 @@
 {
 {
     "title": "Tuya Local",
     "title": "Tuya Local",
     "config": {
     "config": {
-	"step": {
-	    "user": {
-		"title": "Налаштуйте свій пристрій Tuya Local",
-		"description": "[Дотримуйтеся цих інструкцій, щоб знайти ідентифікатор пристрою та локальний ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
-		"data": {
-		    "host": "IP-адреса або ім'я хоста",
-		    "device_id": "Ідентифікатор пристрою",
-		    "local_key": "Локальний ключ (local_key)",
-		    "protocol_version": "Версія протоколу (якщо не знаєте, спробуйте 'auto')",
-		    "poll_only": "Виключно опитування (спробуйте це, якщо ваш пристрій не зовсім працює)",
-		    "device_cid": "[uk] Sub device ID (for devices connected via gateway)"
-		}
-	    },
-	    "select_type": {
-		"title": "Оберіть тип пристрою",
-		"description": "Виберіть тип, що відповідає вашому пристрою",
-		"data": {
-		    "type": "Тип пристрою"
-		}
-	    },
-	    "choose_entities": {
-		"title": "Налаштування пристрою",
-		"description": "Оберіть назву для цього пристрою",
-		"data": {
-		    "name": "Назва"
-		}
-	    }
-	},
-	"abort": {
-	    "already_configured": "Пристрій з таким ідентифікатором уже додано.",
-	    "not_supported": "На жаль, цей пристрій не підтримується."
-	},
-	"error": {
-	    "connection": "Неможливо підключитися до пристрою з вказаними налаштуваннями. Це може бути випадковий збій або, можливо, в налаштуваннях є помилки."
-	}
+        "step": {
+            "user": {
+                "title": "Налаштуйте свій пристрій Tuya Local",
+                "description": "Пристрої можна додавати вручну або за допомогою хмари за допомогою програми Smart Life.",
+                "data": {
+                    "setup_mode": "Вибір налаштування:"
+                }
+            },
+            "cloud": {
+                "title": "Увійти в Tuya",
+                "description": "Введіть свій код користувача Smart Life або Tuya Smart.\n\nЦей код можна знайти в програмі Smart Life або Tuya Smart у меню **Налаштування** > екран **Обліковий запис і безпека** та введіть код",
+                "data": {
+                    "user_code": "Код користувача:"
+                }
+            },
+            "scan": {
+                "title": "Завершіть вхід",
+                "description": "Скористайтеся додатком Smart Life або Tuya Smart"
+            },
+            "choose_device": {
+                "title": "Виберіть пристрій для додавання",
+                "description": "Будь ласка",
+                "data": {
+                    "device_id": "Виберіть пристрій:",
+                    "hub_id": "Виберіть шлюз:"
+                }
+            },
+            "search": {
+                "title": "Знайдіть IP-адресу пристрою",
+                "description": "Хмара Tuya не надає локальних IP-адрес"
+            },
+            "local": {
+                "title": "Налаштуйте свій пристрій Tuya Local",
+                "description": "[Дотримуйтеся цих інструкцій, щоб знайти ідентифікатор пристрою та локальний ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
+                "data": {
+                    "host": "IP-адреса або ім'я хоста",
+                    "device_id": "Ідентифікатор пристрою",
+                    "local_key": "Локальний ключ (local_key)",
+                    "protocol_version": "Версія протоколу (якщо не знаєте, спробуйте 'auto')",
+                    "poll_only": "Виключно опитування (спробуйте це, якщо ваш пристрій не зовсім працює)",
+                    "device_cid": "[uk] Sub device ID (for devices connected via gateway)"
+                }
+            },
+            "select_type": {
+                "title": "Оберіть тип пристрою",
+                "description": "Виберіть тип, що відповідає вашому пристрою",
+                "data": {
+                    "type": "Тип пристрою"
+                }
+            },
+            "choose_entities": {
+                "title": "Налаштування пристрою",
+                "description": "Оберіть назву для цього пристрою",
+                "data": {
+                    "name": "Назва"
+                }
+            }
+        },
+        "abort": {
+            "already_configured": "Пристрій з таким ідентифікатором уже додано.",
+            "not_supported": "На жаль, цей пристрій не підтримується.",
+            "no_devices": "Не вдалося знайти незареєстровані пристрої для облікового запису."
+        },
+        "error": {
+            "connection": "Неможливо підключитися до пристрою з вказаними налаштуваннями. Це може бути випадковий збій або, можливо, в налаштуваннях є помилки.",
+            "does_not_need_hub": "Пристрою не потрібен шлюз",
+            "needs_hub": "Для пристрою потрібен шлюз"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "Хмарне налаштування пристрою Smart Life.",
+                "manual": "Вручну надайте інформацію про підключення пристрою."
+            }
+        }
     },
     },
     "options": {
     "options": {
-	"step": {
-	    "user": {
-		"title": "Налаштуйте свій пристрій Tuya Local",
-		"description": "[Дотримуйтеся цих інструкцій, щоб знайти локальний ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
-		"data": {
-		    "host": "IP-адреса або ім'я хоста",
-		    "local_key": "Локальний ключ (local_key)",
-		    "protocol_version": "Версія протоколу (якщо не знаєте, спробуйте 'auto')",
-		    "poll_only": "Виключно опитування (спробуйте це, якщо ваш пристрій не зовсім працює)",
-		    "device_cid": "[uk] Sub device ID (for devices connected via gateway)"
-		}
-	    }
-	},
-	"error": {
-	    "connection": "Неможливо підключитися до пристрою з вказаними налаштуваннями. Це може бути випадковий збій або, можливо, в налаштуваннях є помилки."
-	},
-	"abort": {
-	    "not_supported": "На жаль, цей пристрій не підтримується."
-	}
+        "step": {
+            "user": {
+                "title": "Налаштуйте свій пристрій Tuya Local",
+                "description": "[Дотримуйтеся цих інструкцій, щоб знайти локальний ключ.](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
+                "data": {
+                    "host": "IP-адреса або ім'я хоста",
+                    "local_key": "Локальний ключ (local_key)",
+                    "protocol_version": "Версія протоколу (якщо не знаєте, спробуйте 'auto')",
+                    "poll_only": "Виключно опитування (спробуйте це, якщо ваш пристрій не зовсім працює)",
+                    "device_cid": "[uk] Sub device ID (for devices connected via gateway)"
+                }
+            }
+        },
+        "error": {
+            "connection": "Неможливо підключитися до пристрою з вказаними налаштуваннями. Це може бути випадковий збій або, можливо, в налаштуваннях є помилки."
+        },
+        "abort": {
+            "not_supported": "На жаль, цей пристрій не підтримується."
+        }
     },
     },
     "entity": {
     "entity": {
         "binary_sensor": {
         "binary_sensor": {

+ 43 - 2
custom_components/tuya_local/translations/ur.json

@@ -3,6 +3,36 @@
     "config": {
     "config": {
         "step": {
         "step": {
             "user": {
             "user": {
+                "title": "اپنے ٹویا لوکل ڈیوائس کو ترتیب دیں۔",
+                "description": "اسمارٹ لائف ایپ کی مدد سے آلات یا تو دستی طور پر شامل کیے جا سکتے ہیں یا کلاؤڈ کی مدد سے۔",
+                "data": {
+                    "setup_mode": "سیٹ اپ کا انتخاب:"
+                }
+            },
+            "cloud": {
+                "title": "Tuya میں لاگ ان کریں۔",
+                "description": "اپنا Smart Life یا Tuya Smart صارف کوڈ درج کریں۔\n\nآپ یہ کوڈ Smart Life ایپ یا Tuya Smart ایپ میں **سیٹنگز** > **اکاؤنٹ اور سیکیورٹی** اسکرین میں تلاش کر سکتے ہیں، اور اس پر دکھایا گیا کوڈ درج کریں۔ ",
+                "data": {
+                    "user_code": "صارف کوڈ:"
+                }
+            },
+            "scan": {
+                "title": "لاگ ان مکمل کریں۔",
+                "description": "لاگ ان مکمل کرنے کے لیے درج ذیل QR-کوڈ کو اسکین کرنے کے لیے Smart Life ایپ یا Tuya Smart ایپ استعمال کریں۔\n\nایپ میں یہ مرحلہ مکمل کرنے کے بعد اگلے مرحلے پر جائیں۔"
+            },
+            "choose_device": {
+                "title": "شامل کرنے کے لیے ڈیوائس کا انتخاب کریں۔",
+                "description": "براہ کرم پہلی ڈراپ ڈاؤن فہرست سے شامل کرنے کے لیے آلہ چنیں۔ ",
+                "data": {
+                    "device_id": "ڈیوائس کا انتخاب کریں:",
+                    "hub_id": "گیٹ وے کا انتخاب کریں:"
+                }
+            },
+            "search": {
+                "title": "آلہ کا IP پتہ تلاش کریں۔",
+                "description": "Tuya کلاؤڈ مقامی IP پتے فراہم نہیں کرتا ہے لہذا اب ہمیں آلہ تلاش کرنے کے لیے آپ کے مقامی نیٹ ورک کو تلاش کرنا ہوگا۔ "
+            },
+            "local": {
                 "title": "اپنے ٹویا لوکل ڈیوائس کو ترتیب دیں۔",
                 "title": "اپنے ٹویا لوکل ڈیوائس کو ترتیب دیں۔",
                 "description": "[اپنی ڈیوائس آئی ڈی اور لوکل کلید تلاش کرنے کے لیے ان ہدایات پر عمل کریں۔](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "description": "[اپنی ڈیوائس آئی ڈی اور لوکل کلید تلاش کرنے کے لیے ان ہدایات پر عمل کریں۔](https://github.com/make-all/tuya-local#finding-your-device-id-and-local-key)",
                 "data": {
                 "data": {
@@ -31,10 +61,21 @@
         },
         },
         "abort": {
         "abort": {
             "already_configured": "اس ID کے ساتھ ایک آلہ پہلے ہی شامل کیا جا چکا ہے۔",
             "already_configured": "اس ID کے ساتھ ایک آلہ پہلے ہی شامل کیا جا چکا ہے۔",
-            "not_supported": "معذرت، اس آلہ کے لیے کوئی تعاون نہیں ہے۔"
+            "not_supported": "معذرت، اس آلہ کے لیے کوئی تعاون نہیں ہے۔",
+            "no_devices": "اکاؤنٹ کے لیے کوئی غیر رجسٹرڈ ڈیوائسز تلاش کرنے سے قاصر۔"
         },
         },
         "error": {
         "error": {
-            "connection": "ان تفصیلات کے ساتھ آپ کے آلے سے منسلک ہونے سے قاصر ہے۔ یہ ایک وقفے وقفے سے جاری مسئلہ ہو سکتا ہے، یا وہ غلط ہو سکتے ہیں۔"
+            "connection": "ان تفصیلات کے ساتھ آپ کے آلے سے منسلک ہونے سے قاصر ہے۔ یہ ایک وقفے وقفے سے جاری مسئلہ ہو سکتا ہے، یا وہ غلط ہو سکتے ہیں۔",
+            "does_not_need_hub": "ڈیوائس کو گیٹ وے کی ضرورت نہیں ہے اور ایک کو منتخب کیا گیا تھا۔ ",
+            "needs_hub": "ڈیوائس کو گیٹ وے کی ضرورت ہے اور کوئی بھی منتخب نہیں کیا گیا۔"
+        }
+    },
+    "selector": {
+        "setup_mode": {
+            "options": {
+                "cloud": "اسمارٹ لائف کلاؤڈ اسسٹڈ ڈیوائس سیٹ اپ۔",
+                "manual": "دستی طور پر ڈیوائس کنکشن کی معلومات فراہم کریں۔"
+            }
         }
         }
     },
     },
     "options": {
     "options": {

+ 1 - 0
requirements-dev.txt

@@ -6,4 +6,5 @@ pytest-asyncio
 pytest-cov
 pytest-cov
 ruff
 ruff
 tinytuya~=1.13.2
 tinytuya~=1.13.2
+tuya-device-sharing-sdk==0.1.9
 yamllint
 yamllint

+ 1 - 0
requirements.txt

@@ -1 +1,2 @@
 tinytuya~=1.13.2
 tinytuya~=1.13.2
+tuya-device-sharing-sdk==0.1.9

+ 9 - 5
tests/test_config_flow.py

@@ -224,9 +224,9 @@ async def test_migrate_entry(mock_setup, hass):
 
 
 @pytest.mark.asyncio
 @pytest.mark.asyncio
 async def test_flow_user_init(hass):
 async def test_flow_user_init(hass):
-    """Test the initialisation of the form in the first step of the config flow."""
+    """Test the initialisation of the form in the first page of the manual config flow path."""
     result = await hass.config_entries.flow.async_init(
     result = await hass.config_entries.flow.async_init(
-        DOMAIN, context={"source": "user"}
+        DOMAIN, context={"source": "local"}
     )
     )
     expected = {
     expected = {
         "data_schema": ANY,
         "data_schema": ANY,
@@ -234,7 +234,7 @@ async def test_flow_user_init(hass):
         "errors": {},
         "errors": {},
         "flow_id": ANY,
         "flow_id": ANY,
         "handler": DOMAIN,
         "handler": DOMAIN,
-        "step_id": "user",
+        "step_id": "local",
         "type": "form",
         "type": "form",
         "last_step": ANY,
         "last_step": ANY,
         "preview": ANY,
         "preview": ANY,
@@ -330,7 +330,9 @@ async def test_async_test_connection_invalid(mock_device, hass):
 async def test_flow_user_init_invalid_config(mock_test, hass):
 async def test_flow_user_init_invalid_config(mock_test, hass):
     """Test errors populated when config is invalid."""
     """Test errors populated when config is invalid."""
     mock_test.return_value = None
     mock_test.return_value = None
-    flow = await hass.config_entries.flow.async_init(DOMAIN, context={"source": "user"})
+    flow = await hass.config_entries.flow.async_init(
+        DOMAIN, context={"source": "local"}
+    )
     result = await hass.config_entries.flow.async_configure(
     result = await hass.config_entries.flow.async_configure(
         flow["flow_id"],
         flow["flow_id"],
         user_input={
         user_input={
@@ -362,7 +364,9 @@ async def test_flow_user_init_data_valid(mock_test, hass):
     setup_device_mock(mock_device)
     setup_device_mock(mock_device)
     mock_test.return_value = mock_device
     mock_test.return_value = mock_device
 
 
-    flow = await hass.config_entries.flow.async_init(DOMAIN, context={"source": "user"})
+    flow = await hass.config_entries.flow.async_init(
+        DOMAIN, context={"source": "local"}
+    )
     result = await hass.config_entries.flow.async_configure(
     result = await hass.config_entries.flow.async_configure(
         flow["flow_id"],
         flow["flow_id"],
         user_input={
         user_input={