// firmware 2.0 changes the protocol between tuya_app<->devices // the version number when it appears in some packets is 3.3 instead of 3.1 // to obtain the key with Android // In wireshark start record of packets // Start Tuya app // Stop record // the localKey and Id appear vot coded in the most big packet $key = "469c2bdefd481c25"; // key to cypher/decypher //from tuya app -> device // examples of data from tuya app -> device array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x33, 0x2e, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x01, 0xf6, 0x45, 0x4d, 0x72, 0xf8, 0x7b, 0x9b, 0xba, 0xa8, 0x0d, 0x65, 0xc3, 0xd5, 0x61, 0x5c, 0x63, 0x86, 0x32, 0x52, 0x6a, 0x48, 0x06, 0xd0, 0x72, 0x58, 0x24, 0xfd, 0x97, 0xfc, 0x23, 0x56, 0x06, 0x6e, 0xd0, 0x32, 0x4d, 0x64, 0xc1, 0xdc, 0x8e, 0xe5, 0x44, 0x74, 0xaa, 0x0e, 0x75, 0xe0, 0xca, 0x10, 0x28, 0xde, 0x4c, 0xa7, 0x37, 0x85, 0xfa, 0xae, 0xaa, 0x82, 0xc3, 0x0a, 0xd9, 0xd0, 0x17, 0x3c, 0x4f, 0x4f, 0x6a, 0x0f, 0x25, 0x70, 0x02, 0x8c, 0x93, 0x9f, 0xad, 0x59, 0x55, 0xa7, 0x4e, 0x80, 0xb8, 0x97, 0xcd, 0x4a, 0x7d, 0x6a, 0x31, 0xa7, 0x0f, 0x2d, 0x90, 0xfd, 0xde, 0xf2, 0x10, 0x5f, 0x0c, 0x29, 0x9e, 0x40, 0x25, 0x00, 0x00, 0xaa, 0x55); -> {devId:836742153c71bf3f7e1f,dps:{2:true},t:1559630870,uid:eu1558566724167h8kfR} array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x65, 0x93, 0x0c, 0x22, 0x00, 0x00, 0xaa, 0x55); -> no data array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x48, 0x4d, 0x72, 0xf8, 0x7b, 0x9b, 0xba, 0xa8, 0x0d, 0x65, 0xc3, 0xd5, 0x61, 0x5c, 0x63, 0x86, 0x32, 0x52, 0x6a, 0x48, 0x06, 0xd0, 0x72, 0x58, 0x24, 0xfd, 0x97, 0xfc, 0x23, 0x56, 0x06, 0x6e, 0xd0, 0xa7, 0xa4, 0x70, 0x40, 0x02, 0xbd, 0x17, 0x53, 0xab, 0x70, 0x3c, 0x9f, 0x92, 0x07, 0xa7, 0xc6, 0x66, 0x86, 0xae, 0xfb, 0xeb, 0xeb, 0x69, 0x57, 0xd1, 0x1e, 0x27, 0x0b, 0xc2, 0xfd, 0x81, 0x03, 0x7d, 0x66, 0x85, 0x70, 0x00, 0x00, 0xaa, 0x55); -> {devId:836742153c71bf3f7e1f,gwId:836742153c71bf3f7e1f} // request state // 3.3 // cmd 0x7 // size end position // prefix : 4c (4) as in 3.1 // counter 4c (8) // 0 0 0 3c (11) always // cmd 1c (12) // size 4c (16) size of the rest of the datagram = 23+length(encode) // version 3c (19) 3.3 // 0 0 0 0 4c (23) always // counter 4c (27) // 0 1 f6 45 2c (31) 4 unknown bytes ???? always the same for the same device (and localkey?) // encoded data without base64_encode + cypher as in 3.1 // CRC 4c as in 3.1 (crc on whole previous data) // suffix 4c as in 3.1 // // cmd 0xa // size end position // prefix : 4c (4) as in 3.1 // counter 4c (8) // 0 0 0 3c (11) always // cmd 1c (12) // size 4c (16) size of the rest of the datagram = 23+length(encode) // encoded data without base64_encode + cypher as in 3.1 // CRC 4c as in 3.1 (crc on whole previous data) // suffix 4c as in 3.1 // // cmd 7 or 9 // size end position // prefix : 4c (4) as in 3.1 // 0 0 0 0 4c (8) always // 0 0 0 3c (11) always // cmd 1c (12) // size 4c (16) from 16 to end of frame // CRC 4c crc of the whole previous data // suffix 4c as in 3.1 //from device -> tuya app // examples of data from tuya app -> device //array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x33, 0x2e, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x4d, 0x72, 0xf8, 0x7b, 0x9b, 0xba, 0xa8, 0x0d, 0x65, 0xc3, 0xd5, 0x61, 0x5c, 0x63, 0x86, 0x32, 0x52, 0x6a, 0x48, 0x06, 0xd0, 0x72, 0x58, 0x24, 0xfd, 0x97, 0xfc, 0x23, 0x56, 0x06, 0x6e, 0xd0, 0x32, 0x4d, 0x64, 0xc1, 0xdc, 0x8e, 0xe5, 0x44, 0x74, 0xaa, 0x0e, 0x75, 0xe0, 0xca, 0x10, 0x28, 0xd6, 0x99, 0xa8, 0x3f, 0xae, 0x32, 0xf3, 0x1f, 0xca, 0x67, 0xfd, 0xc6, 0x77, 0x69, 0x0c, 0xc3, 0x3b, 0x53, 0xc3, 0x0a, 0x00, 0x00, 0xaa, 0x55); // -> {devId:836742153c71bf3f7e1f,dps:{2:true},t:230} //array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x65, 0x93, 0x0c, 0x22, 0x00, 0x00, 0xaa, 0x55); // -> no data //array(0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x72, 0xf8, 0x7b, 0x9b, 0xba, 0xa8, 0x0d, 0x65, 0xc3, 0xd5, 0x61, 0x5c, 0x63, 0x86, 0x32, 0x52, 0x6a, 0x48, 0x06, 0xd0, 0x72, 0x58, 0x24, 0xfd, 0x97, 0xfc, 0x23, 0x56, 0x06, 0x6e, 0xd0, 0x2a, 0x4f, 0x33, 0xd7, 0x1f, 0x04, 0x28, 0x18, 0x59, 0xb8, 0x49, 0xb6, 0xdc, 0xd4, 0x93, 0xb0, 0xa1, 0xd4, 0xfa, 0x67, 0xff, 0xd5, 0x5c, 0x65, 0x19, 0x89, 0x33, 0xc5, 0x87, 0x39, 0xee, 0xe2, 0xf4, 0x99, 0xb6, 0x66, 0x00, 0x00, 0xaa, 0x55); // -> {devId:836742153c71bf3f7e1f,dps:{1:true,2:true}} // 3.3 // cmd =8 // size end position // 0 0 55 aa 0..0 11c as in 3.1 // cmd 1c (12) // 0 0 0 size 4c (16) size = size from size to end of frame // 0000 4c (20) always 0 // version 3c (23) = 3.3 // 0 0 0 0 4c (27) always 0 // 0 0 0 12 4c (31) counter // 0 0 0 1 4c (35) ?? // 4D 72 2c (37) ?? // encode no base64_decode then decypher from 35 to size-27 as in 3.1 // crc 4c crc of the datagram to the end of encode // suffix 4c as in 3.1 // // cmd 7 or 9 // size end position // 00 00 55 aa 4c (4) // count 4c (8) // 0 0 0 3c (11) always // cmd 1c (12) // size 4c (16) // 0 0 0 0 4c (20) always // crc 4c (24) crc of the frame to pos 20 // 00 00 55 aa 4C (28) // // cmd 0x0A // size end position // 00 00 55 aa 4c // counter 4c (8) // 0 0 0 3c (12) always // cmd 1c (12) // 0 0 0 size 4c (16) size = size from size to end of frame // 4D 72 2c (18) ??? // encode nobase64_decode then decypher from 20 to size-12 as in 3.1 // crc 4c crc of the frame to end of encode // suffix 4c as in 3.1 //