jasonacox / tinytuya

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

TCP packet not decoded #505

Open leweafan opened 6 months ago

leweafan commented 6 months ago

Hi all, I'm trying to figure out why tinytuay can't get my device status and localtuya can. I see that tinytuya decodes only UDP packets and ignores TCP packet and in case of localtuya TCP packet decoded. DP_QUERY makes the same request as localtuya does but also ignores TCP packet.

Can you help me to understand why I can't get my device status from TCP packet. May be I'm missing some config parameter.

Using tinytuya I get the following output.

python3 -m tinytuya snapshot -debug
/Library/Python/3.9/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
  warnings.warn(
Parsed args: Namespace(debug=False, command='snapshot', debug2=True, nocolor=False, yes=False, no_poll=False, device_file='devices.json', snapshot_file='snapshot.json')
DEBUG:TinyTuya [1.14.0]

DEBUG:Python 3.9.6 (default, May  7 2023, 23:32:44) 
[Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
DEBUG:Using pyca/cryptography 42.0.7 for crypto, GCM is supported

TinyTuya (Tuya device scanner) [1.14.0]

Loaded snapshot.json - 1 devices:

Name                      ID                       IP              Key               Version

bfc6d450d7e2a0b4322mkq    bfc6d450d7e2a0b4322mkq   192.168.1.129   xxx               3.3  

Poll local devices? (Y/n): 

Polling 1 local devices from last snapshot...
DEBUG:Listening for Tuya devices on UDP ports 6666, 6667 and 7000
DEBUG:Starting brute force network scan 192.168.1.129/32
DEBUG:final payload_dict for 'bfc6d450d7e2a0b4322mkq' ('v3.3'/'default'): {1: {'command': {'gwId': '', 'devId': '', 'uid': '', 't': ''}}, 7: {'command': {'devId': '', 'uid': '', 't': ''}}, 8: {'command': {'gwId': '', 'devId': ''}}, 9: {'command': {'gwId': '', 'devId': ''}}, 10: {'command': {'gwId': '', 'devId': '', 'uid': '', 't': ''}}, 13: {'command': {'devId': '', 'uid': '', 't': ''}}, 16: {'command': {'devId': '', 'uid': '', 't': ''}}, 18: {'command': {'dpId': [18, 19, 20]}}, 64: {'command': {'reqType': '', 'data': {}}}}
DEBUG:building command 10 payload=b'{"gwId":"bfc6d450d7e2a0b4322mkq","devId":"bfc6d450d7e2a0b4322mkq","uid":"bfc6d450d7e2a0b4322mkq","t":"1717532171"}'
DEBUG:payload encrypted=b'000055aa000000010000000a00000088dc40fff63637ebe1bb53989b3b59f8bc290478a70639e4612f8e03ca9828291671d4a5cb65c969d1e392e89f3350fb852bdf55fc1ce2e32cb823afd939ca7ae1a64fe2bafce8105731d5d7cae0d3d0db290478a70639e4612f8e03ca982829166311eaa071ee1f5707787a4a36fdffc10d2128a1c02b2b2ed26bf4435d68ff6cedfcd0bf0000aa55'
DEBUG:PollDevice: raw unpacked message = TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x01\x81\xf0\x00\x00\x00\x01U\xe1\xe1\x18+\x0e\x89\xaf[2\xackG^\x9e\xc0w\xf4\x10\x85\xde\x80#\xbfN\xd8\xfb.\xd8\xab\xd5r\xfb\x9et\xeb"\xe3\xe5\x0f>0\x89\x95\x9c-\x1d9', crc=975962185, crc_good=True, prefix=21930, iv=None)
DEBUG:decode payload=b'3.3\x00\x00\x00\x00\x00\x01\x81\xf0\x00\x00\x00\x01U\xe1\xe1\x18+\x0e\x89\xaf[2\xackG^\x9e\xc0w\xf4\x10\x85\xde\x80#\xbfN\xd8\xfb.\xd8\xab\xd5r\xfb\x9et\xeb"\xe3\xe5\x0f>0\x89\x95\x9c-\x1d9'
DEBUG:removing 3.x=b'U\xe1\xe1\x18+\x0e\x89\xaf[2\xackG^\x9e\xc0w\xf4\x10\x85\xde\x80#\xbfN\xd8\xfb.\xd8\xab\xd5r\xfb\x9et\xeb"\xe3\xe5\x0f>0\x89\x95\x9c-\x1d9'
DEBUG:decrypting=b'U\xe1\xe1\x18+\x0e\x89\xaf[2\xackG^\x9e\xc0w\xf4\x10\x85\xde\x80#\xbfN\xd8\xfb.\xd8\xab\xd5r\xfb\x9et\xeb"\xe3\xe5\x0f>0\x89\x95\x9c-\x1d9'
DEBUG:decrypted 3.x payload='{"dps":{"114":"AwMDAw=="},"t":1717532170}'
DEBUG:payload type = <class 'str'>
DEBUG:decoded results='{"dps":{"114":"AwMDAw=="},"t":1717532170}'
DEBUG:Scan complete with 1 devices found
    [bfc6d450d7e2a0b4322mkq   ] 192.168.1.129      - DPS: {'114': 'AwMDAw=='}

As you can see from debug only UDP ports listned: DEBUG:Listening for Tuya devices on UDP ports 6666, 6667 and 7000

Using localtuya I get the following output where all DPS are presented:

2024-06-04 19:06:35.347 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc...mkq] Sending command 10 (device type: type_0a)
2024-06-04 19:06:35.347 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc...mkq] Sending payload: b'{"gwId":"bfc6d450d7e2a0b4322mkq","devId":"bfc6d450d7e2a0b4322mkq","uid":"bfc6d450d7e2a0b4322mkq","t":"1717517195"}'
2024-06-04 19:06:35.358 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc...mkq] Command 10 waiting for seq. number 1
2024-06-04 19:06:35.378 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc...mkq] Dispatching message CMD 10 TuyaMessage(seqno=1, cmd=10, retcode=0, payload=b'\xbc\x14\xb8\x03\xee/\x80\x0c\xf7\x1c\xae\x1d\x8f\xe4"0\x9f#\xa2\xf7\xad\xb0S\x03\xed\xab\x8d`8\xab\x1dM\x81\xa8\xf2\x08\xc3\xc8^\xcc\xae\xf0\x98\xa1>\x9d\xaawI\x82\xdcvn.J!\x8d\xf0\xbf\x0e\xa6Y\x93I\xc7\xa8\x1f\xd0\x92]\x1d\xe8\xae\r\xafP\x84[D\xe8\xb7\xa2Z\xc9\xc3\xc9\x85l\xba\xa2\xde\xbd\xf5\xe99\xaa\x93\x04\xa24\xd2Z\x0b\x10\xaa\x06\xd5H\xe5\xb7\xadL=\x87nwj\x9bm\xbd\x16H\x99(^\x87\xac\x00-I\xf7\x8e\xc6\xb1\xb2\xbd\xce\xcejg\xf1\x8e\xa0\xa8C\xc5\xca\xa0\xbd4\xb8w\xec&\x87\r\xa3@\x91S\xfdI\xa5\xa2\xecNi\xf5\xf7\x02WS\xf9\xae\x8e\xe3\x0e\xbc\xd5\x86uR\xda\x93|=+\'\x17*\xa8\xab\xc1\xf9\xddo\\\x86\x90\xbdO\xee\x9e\xbb<\xd2\x02\xb3\xe1<3}\x1b\xccq\xd2\x8eM=n\xe9\x06\xae\xa1(m\x19\xbcV+\x96.m\x8e\xfa\x8ahx\x89\xfe\xd7n\xad\x0e\x10\xa5\x11\x01\x93\xbf\xa4\xc8\n\xe0s\x87\xf5\xf6rk\x90\x19\x86\x85\xcf\xa3\xb4\xcd\x9f\xd5+eY\x1d\xe4\xacS^\xdb]\xb3p\xb9\xa8\x9f\x8d\x00\x8b6\xf6\xecQ/\xd8So\x97\x8d\x88\xc9;A\xaaGHd[gs8\x94\xb4*\xfd\x7f\xb5\xbd\xf5\xd3\n\x85s4B\xaf\xbeQ\xd9\x92ASp\x90\x8b\x14\xab\x83\xa9\xe1\xa9f#\xb5&\xec\xd8\x8f\xb8&\x83\x97\xe5D\xc6Z\xca\xc9@M{\x0c#\x80^\xe8 \xc5\xd2+{c\xb0\x01\n\xde\xd9P\x92\t. X\x80\x9b\xa6\xc9\xafc\x89\x156\xfb\x13\x11\\}\x17C5x\xa9w\xa6\xf5\x03?\xa7\x9fjB\x1d\xa5\xf4X\x12\xb0B\xdb\xc4\xa1\x80\xcf\x00>.\xa49p\xcd\r\x14\xd5\x14(\xef\x9a\t\xcb#\xa6\x16\xdeEC\x04\x83\xbe\xf8\xb9p\xdci\x06a\x9c\xf7\x88\xa9\xb9;h#O\xd0G\x8be-\x8cI1\xb2n\xe5\xe0\xc1\xa6\xd68"\x16C\xca\x08\x9ffsA\xe0\xcc\xb46sM\xcdw\x9b\xc1\xa7}1\xcf\xea\xa0N\xd6\xb9P\xe6q\xd3\x0e(!\x91\x8b\x14Q"I%F\x12\x90\x15\x9f\xd7hK\x93\xbb\xeb.T\xbdn\xba\x98\xe2h\x95\xb0\x02\x8f\x99Q\x96\x95\xc1\xf4\xcb\xac(\xaf\xc3\t\x92\r\x83\xc8\x12D|q\x92\xc0\xf4~\x85\xb4^\xb8\x93@S\x17\xae\x87\xd8U\xf0\xfb\\\x9bf\xa8\xdb\x11Ld\x14\xc1\xbb\xf4\xa6/(\x9b\xcf\xf3m4\x14\x9aM\xe7\xb9\xc5\x02\x02\xfb\x19\xaa?Oo\xf6J\xf0\xbc8\xa4\xf4\xd7\xcf|\x81\x1c\xbc\x93\x9f\x00m=\x1e*}\xe8n\xf5?\xebIN\'\xaeH\x05&!V\xd4X\xf9\xb8\x81\xd9\xcf\xd4\x87\xb6\xef\xc3\\\xec\xe6L\x12\xf4\xb2\xd4\xb1\xe6YT\x82\xd7\'\xa4\xd3S!\xf7\xdc%8\xc2_]u\xf45\x080)\xe1\xfe\xdc-\x96{\x04\xaaU\xcb\x853\x9b*1\xe8>\xe2O\xc5\xa4\xd1N)\xe1\nh}\xa8\xc53\xa4q\xcd\x99\xc8\xaf\xee\xa6\xda/%r\xa1\xcb\xa2\x02\x10&\x8a8P\xf2\xc2\x8f\xfa]g\xbc\x12=\x00m@b%\xdfqv\xac5\x7fW\xdb\xa6HiwT/\x07\xd7\x1b\xcd/5\xf9mc,=\x01\xa1h!\x97\xf9\x1e\'\x06\x12\xcb\xe1w\x18e\xbb\xfe\x8f\xbb\x00Q\xa9[`\x8cf\x9c/I0\x16km\xd4E\xf9\xcd\xa6\xda\xcd\x83j\x91\x86&\x04\x8by\x8d\xf4\x8f_u\x01k\xfbP\xf9\xff\xe0\xbd,\x90\x90\xab\xc9\x18\r\xe7\x19\xea\xf3\xd14\xf3|\x82\x14[\xdd\xaa\x82\xc1\xae\xab\x10y\xa7|\x84x\xddhe1^u\xd6(L$*\x82\x9c\xf9\xd8\x0b)C\xa4\xa9\xd7L\xd8\xa2\x96\xc2i\xed\x0c\xcfR\xf7\xff\xa5\t\xc1\x16\xe4\x07\x11TG_e8\x19m\x1b,\xb7|\x94Z\x12M\xf2\x9b(B7Gf\x80\xd9\xf5\xfa`HJI\xf6s\xda\xed\xa9v*1p\xab\x00\xeamR2\x00\xb4/}\xafE\xd6g\xd6[bv\xa4\xd6+\xc9\xa8N\x9bk\x14w\xb3\x8df\xc0i\xe5g\xa6h\xce:\xb7\x11\x81\xc8"\xfcU\xa4\xb1\xf4r\xbd\x8f\x82s\xe4\t!\x9f\x93\xed\xae\xb6\xd1\xb5\xf6\xbe=`\x1f\xf2l\xe4~\xb8\x16\xbf4\xf7\xf3H\xa8\xf56;\xed]\x19\x86`p6\xb4\x1e\xc1?\x9a\xe1\xd1\xf7:\xc0\xd4dq\x18 \x8c\x8e\x19\x1a\x8a\x1e\x1c\xd0\xd6\x0b\x89G;_\xdc\xba\x8eZ\xc1\xbf\x9e_\x9d\xa0\x1b=\xe4\xf6XM\x19\x1e\xbf\xfe\xd2^\xd0\x9f\xads\xbf\xfd', crc=3218256607, crc_good=True)
2024-06-04 19:06:35.382 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc...mkq] Deciphered data = '{"dps":{"101":false,"108":false,"109":true,"110":true,"111":false,"112":false,"113":false,"115":0,"116":3,"117":240,"118":"9600","119":0,"123":0,"124":"RF Sensor  1,RF Sensor  2,RF Sensor  3,RF Sensor  4,RF Sensor  5,","125":"RF Sensor  6,RF Sensor  7,RF Sensor  8,RF Sensor  9,RF Sensor 10,","126":"RF Sensor 11,RF Sensor 12,RF Sensor 13,RF Sensor 14,RF Sensor 15,","127":"RF Sensor 16,RF Sensor 17,RF Sensor 18,RF Sensor 19,RF Sensor 20,","128":"RF Sensor 21,RF Sensor 22,RF Sensor 23,RF Sensor 24,RF Sensor 25,","129":"RF Sensor 26,RF Sensor 27,RF Sensor 28,RF Sensor 29,RF Sensor 30,","130":"RF Sensor 31,RF Sensor 32,RF Sensor 33,RF Sensor 34,RF Sensor 35,","131":"RF Sensor 36,RF Sensor 37,RF Sensor 38,RF Sensor 39,RF Sensor 40,","132":"RF Sensor 41,RF Sensor 42,RF Sensor 43,RF Sensor 44,RF Sensor 45,","133":"RF Sensor 46,RF Sensor 47,RF Sensor 48,RF Sensor 49,RF Sensor 50,","134":"Line 1,Line 2,Line 3,Line 4","135":"Zone 1,Zone 2","136":"Counter 1,Counter 2,Counter 3,Counter 4,Counter 5,Counter 6,Counter 7,Counter 8,","137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0}}'

TCPDUMP flow:

22:46:47.159279 IP 192.168.1.129.49155 > broadcasthost.6667: UDP, length 172
22:46:51.408624 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [S], seq 2711958239, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3372608596 ecr 0,sackOK,eol], length 0
22:46:51.495773 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [S.], seq 55448216, ack 2711958240, win 2920, options [mss 1460], length 0
22:46:51.495945 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [.], ack 1, win 65535, length 0
22:46:51.524135 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [P.], seq 1:153, ack 1, win 65535, length 152
22:46:51.541550 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [P.], seq 1:1133, ack 153, win 2768, length 1132
22:46:51.541682 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [.], ack 1133, win 65535, length 0
22:46:52.106741 IP 192.168.1.129.49155 > broadcasthost.6667: UDP, length 172
22:46:55.799895 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [P.], seq 1133:1224, ack 153, win 2768, length 91
22:46:55.800044 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [.], ack 1224, win 65535, length 0
22:46:55.812233 IP 192.168.1.83.54312 > 192.168.1.129.6668: Flags [F.], seq 153, ack 1224, win 65535, length 0
22:46:55.820266 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [.], ack 154, win 2767, length 0
22:46:55.829875 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [R.], seq 1224, ack 154, win 2920, length 0

The TCP packet I've mentioned: 22:46:51.541550 IP 192.168.1.129.6668 > 192.168.1.83.54312: Flags [P.], seq 1:1133, ack 153, win 2768, length 1132

jasonacox commented 6 months ago

Hi @leweafan ,

Thanks for opening this. Wow, that is a big payload!

only UDP ports are listened

That's correct, but only for discovery. Tuya devices announce themselves on the network via UDP broadcasts. TinyTuya listens to those to discover devices. But that isn't related to the issue you are seeing. The debug you have shows TCP traffic which is how TinyTuya and localtuya both communicate with Tuya devices.

I notice that in your example, TinyTuya gets a response packet with just one DPS (114) however, localtuya gets a response with everything BUT 114. That means that the device seems to be sending back two different payloads. You will likely need to keep monitoring to get all the DPS payloads (or query it multiple times).

You can try this script which will keep monitoring the device and print everything that comes back from it:

https://github.com/jasonacox/tinytuya/blob/a75324b1c5abcaf0ccba98ca1ae6171b651c24f9/examples/monitor.py#L10-L66

leweafan commented 6 months ago

Hello @jasonacox!

Actually I have tried it cause seen in other issues.

All I can catch using this script is DPS of counters (137-144).

 > Begin Monitor Loop <
Received Payload: {'dps': {'122': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='}, 't': 1717564981}
Received Payload: {'dps': {'137': 0}, 't': 1717564981}
Received Payload: {'dps': {'138': 0}, 't': 1717564981}
Received Payload: {'dps': {'139': 0}, 't': 1717564981}
Received Payload: {'dps': {'140': 0}, 't': 1717564981}
Received Payload: {'dps': {'141': 0}, 't': 1717564981}
Received Payload: {'dps': {'142': 0}, 't': 1717564981}
Received Payload: {'dps': {'143': 0}, 't': 1717564981}
Received Payload: {'dps': {'144': 0}, 't': 1717564981}
Received Payload: {'dps': {'145': 'Bf///w=='}, 't': 1717564981}
Received Payload: None
Received Payload: None
Received Payload: {'dps': {'114': 'AwMDAw=='}, 't': 1717564996}
Received Payload: {'dps': {'122': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='}, 't': 1717564996}
Received Payload: {'dps': {'137': 0}, 't': 1717564996}
Received Payload: {'dps': {'138': 0}, 't': 1717564996}
Received Payload: {'dps': {'139': 0}, 't': 1717564996}
Received Payload: {'dps': {'140': 0}, 't': 1717564996}
Received Payload: {'dps': {'141': 0}, 't': 1717564996}
Received Payload: {'dps': {'142': 0}, 't': 1717564996}
Received Payload: {'dps': {'143': 0}, 't': 1717564996}
Received Payload: {'dps': {'144': 0}, 't': 1717564996}
Received Payload: {'dps': {'145': 'Bf///w=='}, 't': 1717564996}
Received Payload: None
Received Payload: None
...

I've also used tinytuya wizard and got only DP 114.

Can I get data from TCP packet using tinytuya?

jasonacox commented 6 months ago

Can I get data from TCP packet using tinytuya?

I'm not following what you mean. These are all TCP packets. Do you mean running a packet capture?

What is this device and can you send a link to it? I may have to try to buy one to help you debug.

I suspect it has something to do with the seqno (sequence number). It looks like Tinytuya is only picking up seqno = 0 and localtuya is only picking up seqno = 1 and avoiding seqno = 0. Do you know the function/meaning of DPS 114?

leweafan commented 6 months ago

I'm not following what you mean. These are all TCP packets. Do you mean running a packet capture?

Yes I would like to get device DPs (reads state) and seems its all in TCP packet only.

What is this device and can you send a link to it? I may have to try to buy one to help you debug.

I suppose it's not available worldwide. It's tuya code "sfkzq" - "Water valve controller". It supports 50+ wireless sensors that's is why TCP packet so big IMHO.

I suspect it has something to do with the seqno (sequence number). It looks like Tinytuya is only picking up seqno = 0 and localtuya is only picking up seqno = 1 and avoiding seqno = 0.

Do you know where I can read more about Tuya API sequence number?

Do you know the function/meaning of DPS 114?

{
   "abilityId":114,
   "accessMode":"rw",
   "code":"line_settings",
   "description":"Settings for four lines.\n{input_type_1, control_group_1 },\n{input_type_2, control_group_2 },\n{input_type_3, control_group_3 },\n{input_type_4, control_group_4 }\n\ninput_type - byte, ref. as (0-sensor/1-key)\ncontrol_group - byte, ref. as (1-control group 1; 2-control group 2; 3-control both group)\n",
   "name":"Line settings",
   "typeSpec":{
      "type":"raw",
      "maxlen":128
   }
}

I have created device config using localtuya and want to share it with community but seems that localtuya do not use yaml configs anymore and switched to config flow (UI) as I understood. That's why I decided to create config for tuya-local project but seems that it's using tinytuya and can't discover and manage my device.

uzlonewolf commented 6 months ago

Try this modified version of the above script (don't forget to replace DEVICEKEY with your key):

key = 'DEVICEKEY'

######### Don't change anything below here ##########

import tinytuya
import time

d = tinytuya.Device('bfc6d450d7e2a0b4322mkq', '192.168.1.129', key, version=3.3, persist=True)

STATUS_TIMER = 3
status_time = time.time() + STATUS_TIMER - 2

print(" > Begin Monitor Loop <")

while(True):
    if status_time and time.time() >= status_time:
        # poll for status
        print(" > Send Request for Status < ")
        data = d.status()
        status_time = time.time() + STATUS_TIMER
    else:
        # no need to send anything, just listen for an asynchronous update
        data = d.receive()

    print('Received Payload: %r' % data)

    if data and 'Err' in data:
        print("Received error!")
        # rate limit retries so we don't hammer the device
        time.sleep(5)
leweafan commented 6 months ago

Nothing changed only counters broadcasted all other DP should be polled.

 > Begin Monitor Loop <
Received Payload: {'dps': {'114': 'AwMDAw=='}, 't': 1717624282}
 > Send Request for Status < 
Received Payload: {'dps': {'122': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='}, 't': 1717624283}
Received Payload: {'dps': {'137': 0}, 't': 1717624283}
Received Payload: {'dps': {'138': 0}, 't': 1717624283}
Received Payload: {'dps': {'139': 0}, 't': 1717624283}
Received Payload: {'dps': {'140': 0}, 't': 1717624283}
Received Payload: {'dps': {'141': 0}, 't': 1717624283}
Received Payload: {'dps': {'142': 0}, 't': 1717624283}
Received Payload: {'dps': {'143': 0}, 't': 1717624283}
Received Payload: {'dps': {'144': 0}, 't': 1717624283}
Received Payload: {'dps': {'145': 'Bf///w=='}, 't': 1717624283}
Received Payload: None
 > Send Request for Status < 
Received Payload: {'dps': {'114': 'AwMDAw=='}, 't': 1717624297}
Received Payload: {'dps': {'122': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='}, 't': 1717624298}
Received Payload: {'dps': {'137': 0}, 't': 1717624298}
Received Payload: {'dps': {'138': 0}, 't': 1717624298}
Received Payload: {'dps': {'139': 0}, 't': 1717624298}
Received Payload: {'dps': {'140': 0}, 't': 1717624298}
Received Payload: {'dps': {'141': 0}, 't': 1717624298}
Received Payload: {'dps': {'142': 0}, 't': 1717624298}
Received Payload: {'dps': {'143': 0}, 't': 1717624298}
Received Payload: {'dps': {'144': 0}, 't': 1717624298}
Received Payload: {'dps': {'145': 'Bf///w=='}, 't': 1717624298}
Received Payload: None 
...

I think you are right and localtuya does the trick using seqno=1 to get all DPS from device.

P.S. Added KEEPALIVE_TIMER = 12

Thanks for your time @jasonacox

jasonacox commented 5 months ago

I need to do more investigation on this. Thanks for raising it @leweafan

jasonacox commented 5 months ago

Hi @leweafan I have something for you to test. I have released a dev version that simply ignores seqno=0.

pip install tinytuya==1.14.1.dev0

You can use the python -m tinytuya scan and also try to poll your one device with a simple:

import tinytuya

key = 'DEVICEKEY'
d = tinytuya.Device('bfc6d450d7e2a0b4322mkq', '192.168.1.129', key, version=3.3)
print(d.status())
uzlonewolf commented 5 months ago

You can give it a shot, but I find it highly unlikely to help; a non-zero sequence number would have been picked up in the modified monitor script I posted above.

leweafan commented 5 months ago

Hello @jasonacox!

Sorry for delay. I have tested a new version and got nothing. Scan is working fine but the new script and old ones don't work. Made rollback to the previous version.

jasonacox commented 5 months ago

Thanks @leweafan - As @uzlonewolf predicted, no difference. Thanks for trying. Without the device, I'm not sure what more we can try. Sorry about that.