Door lock control (MK device) - how to locally get state and control
The device is a fob/smart door control which I've been using via the tuya cloud, however the developer account has now expired and so I'm looking to start using local control for it.
The device is a "MK" branded smart door lock:
{
"result": {
"active_time": 1725634908,
"bind_space_id": "153504535",
"category": "mk",
"create_time": 1725612531,
"custom_name": "XX Door Controls",
"icon": "smart/icon/bay1601253790250Rnas/d0a135a289a77ba1d3f3007308b425d0.jpg",
"id": "bfc28e88ad23bc91xxxxxx",
"ip": "62.XX.XX.XX",
"is_online": true,
"lat": "54.XX",
"local_key": "6XXXXXXX",
"lon": "-1.XX",
"model": "T12-Wifi-II",
"name": "Card+PIN",
"product_id": "s7qamihym60z5jro",
"product_name": "门控-II",
"sub": false,
"time_zone": "+01:00",
"update_time": 1727972468,
"uuid": "a5ff34a4121502c2"
},
Under IOT cloud I can query/unlock it, etc, however I want to now talk to it locally. Querying it via scan (after adding the localkey) I get:
Door Controls Product ID = s7qamihym60z5jro [Valid Broadcast]:
Address = 192.168.0.xx Device ID = bfc28e88ad23bc91xxxxxx (len:22) Local Key = xxxxxx Version = 3.3 Type = default, MAC = d8:d6:68:76:xx:xx
Status: {}
So it appears to DPs are reported. using my own basic query (data = d.status()) confirms this, no DPs reported. I've gone onto Tuya IOT cloud and done a DP dump using the guide and got:
{"1":"Add opening method","2":"Delete door opening method","3":"Modify the door opening method","4":"Synchronous local opening method","5":"Add temporary password","6":"Delete temporary password","7":"Modify temporary password","35":"Open and close state","38":"alarm channel"}
But if they aren't visible when querying status, how can I use this information? Is the device not correctly communicating. It's on the wifi, and it's mains powered so it is constantly connected/active.
How can I go about further debugging the device and digging further?
I put tinytuya into debug output and included it below, there do appear to be DPs in this output so how would I go about getting these more exposed?
DEBUG:TinyTuya [1.15.1]
DEBUG:Python 3.7.3 (default, Mar 23 2024, 16:12:05)
[GCC 8.3.0] on linux
DEBUG:Using PyCryptodomex 3.6.1 for crypto, GCM is supported
DEBUG:status() entry (dev_type is default)
DEBUG:final payload_dict for 'bfc28e88ad23bc91xxxxxx' ('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":"bfc28e88ad23bc91xxxxxx","devId":"bfc28e88ad23bc91xxxxxx","uid":"bfc28e88ad23bc91xxxxxx","t":"1731347860"}'
DEBUG:sending payload
DEBUG:payload encrypted=b'000055aa000000010000000a00000088d7419a67bc5ab4d37664d43f01cbc21251f9a7d689c5705ce34bfb7cc1d7935cdbd72dcdaf53fb06e4af1d4eb7272bddec27aa8534462203f65bfc22f0206b617189757e60703a77065b8f886296a07c51f9a7d689c5705ce34bfb7cc1d7935c465eb63c3cbbaf2549644f0012cce4cb673230818ba7c61960aeaaf82416cc3d14b5abb70000aa55'
DEBUG:received data=b'000055aa000000010000000a0000002c000000012b8a6487ca54f3aa7bc88a8a600aa1d7e1e84b6ce810ce8f2a54996d0fe0c04f42d100610000aa55'
DEBUG:received message=TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O', crc=1120993377, crc_good=True, prefix=21930, iv=None)
DEBUG:raw unpacked message = TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O', crc=1120993377, crc_good=True, prefix=21930, iv=None)
DEBUG:decode payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O'
DEBUG:decrypting=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O'
DEBUG:decrypted 3.x payload='json obj data unvalid'
DEBUG:payload type = <class 'str'>
DEBUG:'data unvalid' error detected: switching to dev_type 'device22'
DEBUG:_decode_payload() failed!
DEBUG:Device22 detected and updated (default -> device22) - Update payload and try again
DEBUG:ERROR Device22 Detected: Retry Command - 908 - payload: null
DEBUG:status() received data={'Error': 'Device22 Detected: Retry Command', 'Err': '908', 'Payload': None}
DEBUG:status() rebuilding payload for device22
DEBUG:final payload_dict for 'bfc28e88ad23bc91xxxxxx' ('v3.3'/'device22'): {1: {'command': {'gwId': '', 'devId': '', 'uid': '', 't': ''}}, 7: {'command': {'devId': '', 'uid': '', 't': ''}}, 8: {'command': {'gwId': '', 'devId': ''}}, 9: {'command': {'gwId': '', 'devId': ''}}, 10: {'command': {'devId': '', 'uid': '', 't': ''}, 'command_override': 13}, 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'{"devId":"bfc28e88ad23bc91xxxxxx","uid":"bfc28e88ad23bc91xxxxxx","t":"1731347860","dps":{"1":null}}'
DEBUG:sending payload
DEBUG:payload encrypted=b'000055aa000000020000000d00000087332e330000000000000000000000004f643770e729822eed6b00bf8a8d3c09ec27aa8534462203f65bfc22f0206b617189757e60703a77065b8f886296a07c51f9a7d689c5705ce34bfb7cc1d7935c465eb63c3cbbaf2549644f0012cce4cbb594e885fb6ec35db23c0fba1d409378815182640c12195cce2d660af97ba7989df615f20000aa55'
DEBUG:received data=b'000055aa00000000000000080000004b00000000332e33000000000000b586000000013a66336e8b8d66a4d3a546de62e40562a9952bba8b8720fd31c6fdfbe46012c04b2d8235df5d2b8bffaeb81870fa9eaacee3af900000aa55'
DEBUG:received message=TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x86\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0K-\x825\xdf]+\x8b\xff\xae\xb8\x18p\xfa\x9e\xaa', crc=3471028112, crc_good=True, prefix=21930, iv=None)
DEBUG:raw unpacked message = TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x86\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0K-\x825\xdf]+\x8b\xff\xae\xb8\x18p\xfa\x9e\xaa', crc=3471028112, crc_good=True, prefix=21930, iv=None)
DEBUG:decode payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x86\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0K-\x825\xdf]+\x8b\xff\xae\xb8\x18p\xfa\x9e\xaa'
DEBUG:removing 3.x=b':f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0K-\x825\xdf]+\x8b\xff\xae\xb8\x18p\xfa\x9e\xaa'
DEBUG:decrypting=b':f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0K-\x825\xdf]+\x8b\xff\xae\xb8\x18p\xfa\x9e\xaa'
DEBUG:decrypted 3.x payload='{"dps":{},"type":"query","t":1731347858}'
DEBUG:payload type = <class 'str'>
DEBUG:decoded results='{"dps":{},"type":"query","t":1731347858}'
Device status: {'dps': {}, 'type': 'query', 't': 1731347858}
I also tried setting a DPS: d.set_dpsUsed({"35": None})
DEBUG:TinyTuya [1.15.1]
DEBUG:Python 3.7.3 (default, Mar 23 2024, 16:12:05)
[GCC 8.3.0] on linux
DEBUG:Using PyCryptodomex 3.6.1 for crypto, GCM is supported
DEBUG:status() entry (dev_type is default)
DEBUG:final payload_dict for 'bfc28e88ad23bc91xxxxxx' ('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":"bfc28e88ad23bc91xxxxxx","devId":"bfc28e88ad23bc91xxxxxx","uid":"bfc28e88ad23bc91xxxxxx","t":"1731350715"}'
DEBUG:sending payload
DEBUG:payload encrypted=b'000055aa000000010000000a00000088d7419a67bc5ab4d37664d43f01cbc21251f9a7d689c5705ce34bfb7cc1d7935cdbd72dcdaf53fb06e4af1d4eb7272bddec27aa8534462203f65bfc22f0206b617189757e60703a77065b8f886296a07c51f9a7d689c5705ce34bfb7cc1d7935c33e72395374fc48fe263a4b3614763cc673230818ba7c61960aeaaf82416cc3da79dff700000aa55'
DEBUG:received data=b'000055aa000000010000000a0000002c000000012b8a6487ca54f3aa7bc88a8a600aa1d7e1e84b6ce810ce8f2a54996d0fe0c04f42d100610000aa55'
DEBUG:received message=TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O', crc=1120993377, crc_good=True, prefix=21930, iv=None)
DEBUG:raw unpacked message = TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O', crc=1120993377, crc_good=True, prefix=21930, iv=None)
DEBUG:decode payload=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O'
DEBUG:decrypting=b'+\x8ad\x87\xcaT\xf3\xaa{\xc8\x8a\x8a`\n\xa1\xd7\xe1\xe8Kl\xe8\x10\xce\x8f*T\x99m\x0f\xe0\xc0O'
DEBUG:decrypted 3.x payload='json obj data unvalid'
DEBUG:payload type = <class 'str'>
DEBUG:'data unvalid' error detected: switching to dev_type 'device22'
DEBUG:_decode_payload() failed!
DEBUG:Device22 detected and updated (default -> device22) - Update payload and try again
DEBUG:ERROR Device22 Detected: Retry Command - 908 - payload: null
DEBUG:status() received data={'Error': 'Device22 Detected: Retry Command', 'Err': '908', 'Payload': None}
DEBUG:status() rebuilding payload for device22
DEBUG:final payload_dict for 'bfc28e88ad23bc91xxxxxx' ('v3.3'/'device22'): {1: {'command': {'gwId': '', 'devId': '', 'uid': '', 't': ''}}, 7: {'command': {'devId': '', 'uid': '', 't': ''}}, 8: {'command': {'gwId': '', 'devId': ''}}, 9: {'command': {'gwId': '', 'devId': ''}}, 10: {'command': {'devId': '', 'uid': '', 't': ''}, 'command_override': 13}, 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'{"devId":"bfc28e88ad23bc91xxxxxx","uid":"bfc28e88ad23bc91xxxxxx","t":"1731350715","dps":{"1":null}}'
DEBUG:sending payload
DEBUG:payload encrypted=b'000055aa000000020000000d00000087332e330000000000000000000000004f643770e729822eed6b00bf8a8d3c09ec27aa8534462203f65bfc22f0206b617189757e60703a77065b8f886296a07c51f9a7d689c5705ce34bfb7cc1d7935c33e72395374fc48fe263a4b3614763ccb594e885fb6ec35db23c0fba1d409378815182640c12195cce2d660af97ba798f28db5c00000aa55'
DEBUG:received data=b'000055aa00000000000000080000004b00000000332e33000000000000b588000000013a66336e8b8d66a4d3a546de62e40562a9952bba8b8720fd31c6fdfbe46012c0b0d240a9c0cad1102da79e046b112ef01299fbf10000aa55'
DEBUG:received message=TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x88\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0\xb0\xd2@\xa9\xc0\xca\xd1\x10-\xa7\x9e\x04k\x11.\xf0', crc=312081393, crc_good=True, prefix=21930, iv=None)
DEBUG:raw unpacked message = TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x88\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0\xb0\xd2@\xa9\xc0\xca\xd1\x10-\xa7\x9e\x04k\x11.\xf0', crc=312081393, crc_good=True, prefix=21930, iv=None)
DEBUG:decode payload=b'3.3\x00\x00\x00\x00\x00\x00\xb5\x88\x00\x00\x00\x01:f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0\xb0\xd2@\xa9\xc0\xca\xd1\x10-\xa7\x9e\x04k\x11.\xf0'
DEBUG:removing 3.x=b':f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0\xb0\xd2@\xa9\xc0\xca\xd1\x10-\xa7\x9e\x04k\x11.\xf0'
DEBUG:decrypting=b':f3n\x8b\x8df\xa4\xd3\xa5F\xdeb\xe4\x05b\xa9\x95+\xba\x8b\x87 \xfd1\xc6\xfd\xfb\xe4`\x12\xc0\xb0\xd2@\xa9\xc0\xca\xd1\x10-\xa7\x9e\x04k\x11.\xf0'
DEBUG:decrypted 3.x payload='{"dps":{},"type":"query","t":1731350714}'
DEBUG:payload type = <class 'str'>
DEBUG:decoded results='{"dps":{},"type":"query","t":1731350714}'
Device status: {'dps': {}, 'type': 'query', 't': 1731350714}
It has been my experience that these types of devices do not respond to polls. If you have a monitor script running (i.e. https://github.com/jasonacox/tinytuya/blob/master/examples/monitor.py) you will see async updates as settings are changed, however there is no way that I know of to query the current state. I have one that I've been meaning to add a Contrib module for for like a year now, but it keeps getting pushed back with all the other stuff I'm working on.
Looks like it was #438 . The DP reference at https://developer.tuya.com/en/docs/iot/datapoint-reference?id=Kadhd28uy4rvp still looks valid.
Hi there, I am also trying to implement this myself. I don't care about the state, I only want to be able to unlock the door locally. Any hints or sample code?