jasonacox / tinytuya

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

Wizzard does not find any devices but I can still control them manually, is the wizzard broken? #117

Closed frodeheg closed 1 year ago

frodeheg commented 2 years ago

If I run

python3 -m tinytuya scan Then I get the response: Scan Complete! Found 0 devices.

But if I create the following program:

#!/usr/bin/python
import tinytuya

print("TinyTuya (Tuya Interface) [%s]\n"%tinytuya.__version__)
tinytuya.set_debug(True)
DEVICEID = ".....my_id......"
DEVICEIP = "192.168.1.115"
DEVICEKEY = "....my_key...."
DEVICEVERS = "3.3"

a = tinytuya.BulbDevice(DEVICEID, DEVICEIP, DEVICEKEY)
a.set_version(3.3)
a.set_colour(255,0,0)

The colour changes correctly. Why cannot the scanner find the devices? The ID and key was found in the devices.json file after running the wizzard, but this was pulled from the cloud, as the wizzard could not find the device either. That is I got the following message from the wizzard:

Polling local devices... [my_light] - 0 - Error: No IP found

Instead I had to find the IP address by performing a network scan.

Not sure how the wizzard finds devices but could it be that the device I have does not respond to the search mechanism? I have "Conecto Home Smart Led Bulb": https://www.power.no/smarte-hjem/smart-belysning/smarte-lyspaerer/conecto-wrgb-smart-led-paere-gu10-5w/p-1049287/ Apparently it is a Tuya device as a network scan lists it with Brand "Tuya"

frodeheg commented 2 years ago

Note that on https://eu.iot.tuya.com my_light is listed with a different ip: 88.90.xxx.xxx (for some reason) and if I ping this address I don't get any response. If I ping the local ip-address of the light 192.168.1.115 I get a response (My firewall blocks all incoming accesses) Could this be the reason?

jasonacox commented 2 years ago

HI @frodeheg - Tuya devices broadcast their ID on the local network via the UDP protocol. Your firewall may be blocking that on your network. I have also seen cases where the WiFi signal was not strong in the bulb location so that broadcast packets were not making it. Try to expand the retry value for scanning:

python3 -m tinytuya scan 50

Keep in mind that scanning is not required to control the devices. Status and control commands are TCP so as long as you are able to change the color of the bulb, everything else should work.

frodeheg commented 2 years ago

I think I see the problem, tinytuya only scan on UDP ports 6666 and 6667 for devices, however my device only has one port open and that is 6668.... Is it possible for to expand the number of ports to search for devices? (and no, scan 50 did not help)

jasonacox commented 2 years ago

Actually TCP port 6668 is open for all Tuya devices. However, the UDP broadcast is on port 6666 and 6667 (here is a diagram that show the network communication in the Tuya ecosystem).

A few more things I thought of:

frodeheg commented 2 years ago

Seems like not all Tuya devices announces their presence after they have been paired with the app, I guess I have one of those. Maybe it would be better to search for devices by doing a network scan on the local subnet (on linux run: "nmap -sP 192.168.1.0/24") and then check if the MAC addresses start with "10:D5:61" (on linux run: "arp -a") as all Tuya smart devices start with this ( https://macaddress.io/mac-address-lookup/1pRKDz3D2w ). Running the commands above goes faster on my local computer than to run "python3 -m tinytuya scan"

jasonacox commented 2 years ago

Very clever @frodeheg - you are right, that nmap search would work to find Tuya devices (IP addresses) in a brute force way. Unfortunately that only gives you the IP address of the device. To connect to the device, it requires that you also know its device ID.

The reason scan listens for the UDP broadcast is because that payload contains an encrypted message that includes the IP, Product SKU, firmware version and most importantly, Device ID. I haven't found a way to pull the Device ID locally by just having the IP address. Technically we could go through the list of IDs we get back from TuyaCloud (in devices.json) and brute force each ID with each IP address we find to do the mapping. That may be a nice option to add. I'll add it to my backlog unless you want to work on it. :)

frodeheg commented 2 years ago

In my case I got the device id from devices.json (I think it was fetched from the cloud as scan didn't work)

frodeheg commented 2 years ago

Maybe I will get some time to write an extension later. Going to make a disco - controller for all my Tuya lights first :-) I'll let you know if I get time.

jasonacox commented 2 years ago

Please share the disco controller too! I'm in! ;)

jasonacox commented 2 years ago

@frodeheg thank you for the PR and code to do the local scanning! I merged your code and updated it to make it a selectable option via -force and logic to handle errors (e.g. missing modules or Tuya devices without IP addresses). I also added a warning that the scanning will take a while.

python -m tinytuya wizard -force

Thank you!

robthepaper commented 1 year ago

Hi, thanks for this! Just wanted to make a comment on the fact that it doesn't give the right MAC address if you use a wifi repeater. It gives you the repeater MAC address instead.

mrdvt92 commented 1 year ago

firewall - see if you can turn it off to test (or allow port 6666 and 6667 UDP traffic),

firewall blocking inbound UDP was my issue. I was surprised that opening the firewall was not on the front page. The following commands open the needed UDP ports on CentOS 7.

sudo firewall-cmd --permanent --add-port=6666/udp
sudo firewall-cmd --permanent --add-port=6667/udp
sudo firewall-cmd --reload
jasonacox commented 1 year ago

firewall blocking inbound UDP was my issue. I was surprised that opening the firewall was not on the front page.

Thanks for the suggestion @mrdvt92 ! I'll add a note.