Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto address detection fails for older device versions in TinyTuya 1.12.9 #478

Open
yokoyama-flogics opened this issue Mar 27, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@yokoyama-flogics
Copy link

Thank you for the wonderful software.
I have a simple question.

Previously, I was able to successfully use the call tinytuya.OutletDevice(dev_id=..., address="Auto", local_key=..., version=3.3) with devices of version 3.3 (with auto detection of the address).

However, when I attempt the same call with a slightly older device (version 3.1), I receive the following error and cannot connect:

Unable to find device on network (specify IP address)

However, everything works fine when I specify the actual IP address:

set_status() result {'devId': 'xxxxxxxx', 'dps': {'1': True, '2': 0}}

Yet, when I use python -m tinytuya scan, I can correctly detect the device as follows:

a_smart_plug Product ID = xxxxxxxx [Valid Broadcast]:
Address = 192.168.xxx.xxx Device ID = xxxxxxxx (len:20) Local Key = xxxxxxx Version = 3.1 Type = default, MAC = xx:xx:xx:xx:xx:xx
Status: {'1': True, '2': 0}

What is the fundamental difference here? Why does python -m tinytuya scan work, but tinytuya.OutletDevice(..., address="Auto", ...) does not?

I am using tinytuya version 1.12.9.

Atsushi

@yokoyama-flogics
Copy link
Author

I'm speculating, but from looking at the output of python -m tinytuya scan, it seems like it detects devices by sending unicast UDP packets to every (?) IP address in the subnet. On the other hand, tinytuya.OutletDevice(address="Auto") seems to perform the scan using broadcast or something similar. Is this assumption correct?

Atsushi

@uzlonewolf
Copy link
Collaborator

Hi @yokoyama-flogics !

It is the device which sends UDP broadcasts, TinyTuya only passively listens for them.

Looking at the code it would seem I broke find_device() at some point for the older v3.1 devices. I'll try to get that fixed soon.

@uzlonewolf uzlonewolf added the bug Something isn't working label Mar 27, 2024
@uzlonewolf
Copy link
Collaborator

Re-reading it I see my last post wasn't very clear. Both python -m tinytuya scan and Device(address='Auto') work the same way: TinyTuya passively listens for a UDP broadcast from the device, and then makes a unicast TCP connection once it's found. TinyTuya does not probe every IP address on the subnet unless you pass the -force flag to the scanner.

@yokoyama-flogics
Copy link
Author

Hi @uzlonewolf,

Thank you for looking into this. I will also try to review the code more closely when I have the time. As a current workaround, I'm using tinytuya.deviceScan() to perform a scan once and then retrieve the IP address (which works for me).

Atsushi

@uzlonewolf
Copy link
Collaborator

Hmm, looking at this a bit more, I'm actually not seeing a problem anywhere. I tested with the 3 v3.1 devices I have and all 3 of them are working fine with address=Auto.

Can you run a scan with debug turned on (python3 -m tinytuya scan -d) and post the DEBUG:Received valid UDP packet: { ... } line for the problem device?

@yokoyama-flogics
Copy link
Author

Hi @uzlonewolf,

I tried it out. Will this information be helpful?

DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}
DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}
DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}
DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}
DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}
DEBUG:Received valid UDP packet: {'ip': '172.21.141.104', 'gwId': '02200286dc4f220ec7d6', 'active': 2, 'ability': 0, 'mode': 0, 'encrypt': True, 'productKey': 'PGEkBctAbtzKOZng', 'version': '3.1'}

Atsushi

@jasonacox
Copy link
Owner

Atsushi, are you still ale to get "Auto" to work on 3.3 devices? And, are you by chance running your script in a container (e.g. docker)?

@yokoyama-flogics
Copy link
Author

Yes, I've confirmed that with the same Python environment (using pyenv), I can get a response with "Auto" for devices that are version 3.3.

set_status() result {'devId': '72363820c4dd5703cd6d', 'dps': {'1': False, '9': 0, '18': 0, '19': 0, '20': 1003, '21': 1, '22': 746, '23': 31250, '24': 21052, '25': 990}}

However, it was necessary to include version=3.3 as an argument in tinytuya.OutletDevice(). Without it, I encountered an error:

set_status() result {'Error': 'Timeout Waiting for Device', 'Err': '902', 'Paylo
ad': 'Check device key or version'}

I tried adding version= (3.1 and 3.3) for the 3.1 devices as well, but there was no change.

For your reference, here is the output of pip freeze:

certifi==2023.7.22
charset-normalizer==3.2.0
colorama==0.4.6
elasticsearch==6.8.2
idna==3.4
paho-mqtt==1.6.1
pycryptodome==3.18.0
requests==2.31.0
schedule==1.2.0
tinytuya==1.12.9
urllib3==1.26.5

Python version is 3.9.11.

Atsushi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants