jasonacox / tuyapower

Python module to read status and energy monitoring data from Tuya based WiFi smart devices. This includes state (on/off), current (mA), voltage (V), and power (wattage).
MIT License
140 stars 22 forks source link

scan.py wrong results #3

Closed codeclinic closed 4 years ago

codeclinic commented 4 years ago

The scan.py script gives the seemingly correct IP and ID for each devices. However, the Key and Version are reported as the same for every device (I have a mixture of 3.1 & 3.3 devces).

Along with the output its reporting the note as "Valid payload".

I also tried the scan-enc version and this gives the same result.

jasonacox commented 4 years ago

Wow, that's fascinating! The script is not actually determining the version, it is literally just parsing the version string from the UDP payload. The raw messages in UDP look something like this:

'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x00\x00\x00\x00{"ip":"10.0.1.5","gwId":"01234567891234567890","active":2,"ability":0,"mode":0,"encrypt":true,"productKey":"0123456789abcdef","version":"3.1"}1\x0b\xb1\xf3\x00\x00\xaaU'

Notice the version number after the product key. That seems to indicate that some Tuya devices are just sending out UDP broadcasts that don't match their version (perhaps just a hard coded template).

I added the scan function to the python module that also tries to immediately poll the device after finding it via the UDP broadcast. I would love to see what happens in this situation:

# First upgrade your module
python3 -m pip install --upgrade tuyapower
python3 -m tuyapower

You can get more verbose debug info if you run it via interactive python mode and set DEBUG to True:

import tuyapower
tuyapower.DEBUG=True
tuyapower.scan()

Thanks for your feedback and help!

EDIT: I suspect the newer devices (e.g. 3.3) are broadcasting on UDP 6667 instead of UDP 6666. The payload is encrypted so I need to do some sleuthing.

codeclinic commented 4 years ago

I recall reading somewhere that some devices were using other ports.

I'll give the updated scan script a try later and let you know the results.

codeclinic commented 4 years ago

`Scanning on UDP port 6666 for devices...

Scan Complete! Found 10 devices. `

jasonacox commented 4 years ago

Thanks! This helps. The list shows that all 10 devices are valid 3.1 and it is able to pull the state data (including power) from the smart plugs. I think your 3.3 devices are all going to be advertising on UDP port 6667. I updated my code to scan for both UDP port 6666 and encrypted UDP port 6667 broadcasting devices. Give it a try and see if it now finds your 3.3 devices during the 6667 port polling.

# First upgrade your module
python3 -m pip install --upgrade tuyapower
python3 -m tuyapower

Interesting note: The UDP port 6667 payloads are all encrypted. I found the key and method to decrypt this payload and it appears to be working. Unfortunately for 3.3 devices, a valid device key is required to poll for the state data (e.g. power). The scan will still provide the device ID and IP address.

codeclinic commented 4 years ago

I have 12 devices of which 8 are the same device (but 2 different reseller brands) and a 3rd set of 4, so 12 in total. The script is still seeing 10 of them as 3.1 devices when I'm certain that at least 8 of them are really v3.3.

Also, of the 10 it identifies as 3.1 all are being displayed as having the same product key.

jasonacox commented 4 years ago

The script is really simple. It only listens for UDP traffic on your network broadcasted on UDP port 6666 (newest version is updated to listen for port 6667 traffic). From all I can find poking around on Tuya 3.3, it only broadcasts on UDP port 6667 so the script you ran should only find 3.1. All of the parameters (ID, productKey, version) are coming from the UDP packet that your smart plugs are sending, they are not being determined by the script. The script only passes that JSON value along from the payload to the output.

All that to say, the run you did above found 10 devices (there can be others that just are not broadcasting) that are 3.1 devices with unique IP addresses and Device IDs. Of those 10, it was able to pull state data from all of them (state data being power on/off, wattage, amperage and voltage). Wattage and amperage will be zero if the switch if off (which is a good thing :). My new script also listens for 3.3 Tuya devices and decrypts the UDP payload they send. I suspect you will find 3.3 devices on your network when you run it again.

I still have no idea what the productKey means or how it can be used. However, the fact that all of your devices seem to have the same productKey is interesting.

I edited the data you posted so you can see the 10 devices it found on your network a bit easier (without the debug info):

  1. FOUND Device [Valid payload]: 192.168.178.71 ID = 78345004840d8e9a7d86, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=228.7 [OK]
  2. FOUND Device [Valid payload]: 192.168.178.83 ID = 80631620dc4f2267961c, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=230.8 [OK]
  3. FOUND Device [Valid payload]: 192.168.178.79 ID = 41034600b4e62d6093cc, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=238.7 [OK]
  4. FOUND Device [Valid payload]: 192.168.178.76 ID = 41034600cc50e3d1cbd7, Key = VDy8S..., Version = 3.1 Stats: on=True, W=53.0, mA=239.0, V=226.7 [OK]
  5. FOUND Device [Valid payload]: 192.168.178.70 ID = 78345004840d8e9aba48, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=228.7 [OK]
  6. FOUND Device [Valid payload]: 192.168.178.60 ID = 80631620dc4f22677ef2, Key = VDy8S..., Version = 3.1 Stats: on=True, W=0.0, mA=0.0, V=230.1 [OK]
  7. FOUND Device [Valid payload]: 192.168.178.78 ID = 20856001840d8e9b0c6d, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=228.7 [OK]
  8. FOUND Device [Valid payload]: 192.168.178.84 ID = 80631620dc4f226773ab, Key = VDy8S..., Version = 3.1 Stats: on=True, W=1.1, mA=70.0, V=228.3 [OK]
  9. FOUND Device [Valid payload]: 192.168.178.85 ID = 80631620dc4f226788c9, Key = VDy8S..., Version = 3.1 Stats: on=True, W=53.9, mA=337.0, V=229.0 [OK]
  10. FOUND Device [Valid payload]: 192.168.178.77 ID = 04564850cc50e3d1c62d, Key = VDy8S..., Version = 3.1 Stats: on=False, W=0.0, mA=0.0, V=228.9 [OK]
jasonacox commented 4 years ago

Update: The scan.py tool has been updated to combine scanning of both UDP port 6666 and encrypted UDP port 6667 for Tuya devices of version 3.1 and 3.3. See scan.py.

codeclinic commented 4 years ago

That now finds all 12. Still duplicating the keys though.