jasonacox / tinytuya

Python API for Tuya WiFi smart devices using a direct local area network (LAN) connection or the cloud (TuyaCloud API).
MIT License
867 stars 157 forks source link

Suggestion: Improved Device Discovery logic #441

Open phrak opened 6 months ago

phrak commented 6 months ago

Hi Devs, I'm in the process of adding my range of Tuya devices into Home Assistant for the first time - This has been quite a time-consuming and frustrating experience for various reasons.

I'd like to suggest a few improvements to the device discovery and workflow that I think would help new users and new devices get started quickly.

Tuya recently introduced a new free subscription tier and "Smart Home Basic" Service API. This appears to be intended to replace the developer subscription. The Smart Home Basic service does not need to be renewed every 6 months.

Goal:

  1. Simplify the discovery of new Tuya WiFi & Zigbee devices for onboarding to various Local Control services (e.g. via LocalTuya and TuyaLocal in HomeAssistant). AND
  2. Retain existing Tuya Cloud integration so current automations and integrations are not disturbed.

Suggested Psuedo-Logic:

1: Pull a list of all Device IDs in the home from the APIs. 2: Match any Device ID's from the Broadcast pings, if available. 3: If the IP is matched, allow the user to add the device. 4: If the IP is not matched, allow the user to enter an IP address manually, then add the device.

  1. Prompt the user to confirm the discovered parameters (or edit as needed), then add the device to Home Assistant with all the parameters pre-filled.

Assumptions:

  1. Devices are online and already paired with Tuya Smart Home app
  2. Devices are normally functional via the app.

Pre-Req's Needed:

  1. Tuya IOT Access ID/Client ID
  2. Tuya IOT Access Secret/Client Secret
  3. Tuya IOT "Smart Home Basic" Service API (Added by default as a free replacement for the IOT Core service) Service: https://iot.tuya.com/cloud/products/detail/?abilityId=1667049392684671055 Docs: https://developer.tuya.com/en/docs/cloud/smart-home-basic-service?id=Kconis1yii4be

API DETAILS

Discover the HOME (location) Info

"Smart Home Basic" Service API > HOME MANAGEMENT > Query user family list Query Home List. Based on the user ID, query the list of homes where the specified user belongs.

GET EU/v1.0/users/{uid}/homes

RESULTS Will return an array of all the homes that the user is part of. The result will usually only be a single array, but good logic would ask the user to confirm, or select their home from a list.

VALUES WANTED Extract and store the _homeid value from the selected home.

Note: home_id = owner_id returned from other APIs.

Discover all devices in the home

"Smart Home Basic" Service API > HOME MANAGEMENT > Query devices in Home Based on the home ID, query a list of devices in the specified home.

GET EU/v1.0/homes/{home_id}/devices

RESULTS Will return an array of all the Devices in the selected home.

VALUES WANTED "id" (Device ID) "local_key" "model" "name" (Friendly Name) "owner_id" "product_id" "product_name"

Discovery Info The "IP" value will show the Public WAN IP address of the home router, not the private LAN address of the Tuya WiFi device, so this (alone) can't be used for auto discovery.

However, all devices will send a UDP 6667 broadcast ping, which carries the IP Address and Device ID as a payload.

Unfortunately, the UDP broadcast will only work if HASS is on the same VLAN as the device. Many users run IOT devices on a separate subnet.

By combining both the broadcast and the API results, we can have a high confidence that the devices information will be as full-featured as possible.

All feedback welcome.

jasonacox commented 6 months ago

Hi @phrak , TinyTuya wizard is doing something very similar to this using the old API to fetch the device list. It combines the discovered devices with the full list of devices from Tuya IoT Cloud and produces a devices.json file that has this full list. It also allows you to download the DP mapping.

then add the device to Home Assistant with all the parameters pre-filled

If your application (or HA) could use devices.json, which we already have, it could import all your devices fairly easily, though I suppose it would need a way to do a mapping to device type since that isn't always clear (Smart Bulb, LED strip, Light are all smart bulbs?).

The TinyTuya wizard uses these to get the devices.

        * Get Token = https://openapi.tuyaus.com/v1.0/token?grant_type=1
        * Get UserID = https://openapi.tuyaus.com/v1.0/devices/{DeviceID}
        * Get Devices = https://openapi.tuyaus.com/v1.0/users/{UserID}/devices

@uzlonewolf Keep me honest. 🙏 Does this make sense or have you seen this yet? I haven't tested the new APIs. It seems that the new API might be able replace a lot of that logic. We should investigate that. I'll flag this as an enhancement.

uzlonewolf commented 5 months ago

I'm not opposed to it, but after getting bitten the last time I tried this I think we should keep the existing way as a fallback if those new endpoints don't return anything.

jasonacox commented 5 months ago

Great point. I'm inclined to say we keep it as is for now until we have time to add this as an option.