jasonacox / tinytuya

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

CoverDevice don't close #498

Open fdaforno opened 1 month ago

fdaforno commented 1 month ago

Hi all i still implementing a http rest service that control my tuya devices at home i have a issue wiht CoverDevices . i'm able to open it send the right command but i'm not able to close What i doing wrong?

this is a snippet of my code

def send_command():
    req_data = request.get_json()

    device_id = req_data.get('device_id')
    local_key = req_data.get('localkey')
    device_ip = req_data.get('device_ip')
    command = req_data.get('command')  # Default to True for opening the blinds

    if not device_id or not local_key:
        return jsonify({'error': 'Missing device_id or localkey'}), 400

    d = tinytuya.CoverDevice(device_id, device_ip, local_key)
    d.set_version(3.3)
    if command == "open":
        print("Open the windows")
        d.open_cover(switch=1)
        return jsonify({'success': True})
    elif command == "close":

        print("Close the windows")
        d.close_cover(switch=1)
        return jsonify({'success': True})
jasonacox commented 1 month ago

Hi @fdaforno that looks valid (I updated your post to format the python). Does it work outside the flask rest app if you just issue the commands as a script? If not, I would check to see if your Tuya cover device is using a different command. Run this monitor script and then use the controls on the device itself or the SmartLIfe app to open/close the cover. It may record and send the updates.

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

fdaforno commented 1 month ago

Hi @jasonacox i tried the monitor, when i send the commnad to close from the app i receive this: Received Payload: {'dps': {'1': 'close'}, 't': 1716151430}

i create a super easy app to test only the close function with debug mode true ad seems OPEN is hardcoded some where :-( look the debug output below

import tinytuya

DEVICEID = "bfd94c4278d08b58a0qqug"
DEVICEIP = "192.168.250.134"
DEVICEKEY = "k1t}o:&Igw.h$>oN"
DEVICEVERS = "3.3"

print("TinyTuya - TEST [%s]\n" % tinytuya.__version__)
print('TESTING: Device %s at %s with key %s version %s' %
      (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))

d = tinytuya.CoverDevice(DEVICEID, DEVICEIP, DEVICEKEY)
tinytuya.set_debug(True)
d.set_version(3.3)
d.close_cover(switch=1)

DEBUG RESULP TinyTuya - TEST [1.13.2]

TESTING: Device bfd94c4278d08b58a0qqug at 192.168.250.134 with key k1t}o:&Igw.h$>oN version 3.3 DEBUG:TinyTuya [1.13.2]

DEBUG:Python 3.9.19 (main, May 14 2024, 09:03:15) [GCC 12.2.0] on linux DEBUG:Using pyca/cryptography 42.0.7 for crypto, GCM is supported DEBUG:final payload_dict for 'bfd94c4278d08b58a0qqug' ('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 7 payload=b'{"devId":"bfd94c4278d08b58a0qqug","uid":"bfd94c4278d08b58a0qqug","t":"1716152779","dps":{"1":"off"}}' DEBUG:sending payload DEBUG:payload encrypted=b'000055aa000000010000000700000087332e330000000000000000000000002ed2f20a839289dc1802ca7887ee2df96ecf09458b430fd6a6b6812714ae2d12d34fbe992ad439dedb2bc1b2e1909f194a76e1a0fd18bdf2c8056902a36a72ee2e5f1d097ed5db8c641c3b88fad8ee0879f57808182e4135d4627c6c2f7b2f2a9983d539ca65f3206772cd7eb6191e7068bbcc4a0000aa55' DEBUG:received data=b'000055aa00000001000000070000000c00000000a505a9140000aa55' DEBUG:received null payload (TuyaMessage(seqno=1, cmd=7, retcode=0, payload=b'', crc=2768611604, crc_good=True, prefix=21930, iv=None)), fetch new one - retry 0 / 5 DEBUG:received data=b'000055aa00000000000000080000004b00000000332e3300000000000077770000000193e1717e0d640d07a2be216fa81280b2f93a9b902d891e14d686cfb31b8e12763364ee388f080b7d88ee33333be3fce3953d6c910000aa55' DEBUG:received message=TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00ww\x00\x00\x00\x01\x93\xe1q~\rd\r\x07\xa2\xbe!o\xa8\x12\x80\xb2\xf9:\x9b\x90-\x89\x1e\x14\xd6\x86\xcf\xb3\x1b\x8e\x12v3d\xee8\x8f\x08\x0b}\x88\xee33;\xe3\xfc\xe3', crc=2503830673, 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\x00ww\x00\x00\x00\x01\x93\xe1q~\rd\r\x07\xa2\xbe!o\xa8\x12\x80\xb2\xf9:\x9b\x90-\x89\x1e\x14\xd6\x86\xcf\xb3\x1b\x8e\x12v3d\xee8\x8f\x08\x0b}\x88\xee33;\xe3\xfc\xe3', crc=2503830673, crc_good=True, prefix=21930, iv=None) DEBUG:decode payload=b'3.3\x00\x00\x00\x00\x00\x00ww\x00\x00\x00\x01\x93\xe1q~\rd\r\x07\xa2\xbe!o\xa8\x12\x80\xb2\xf9:\x9b\x90-\x89\x1e\x14\xd6\x86\xcf\xb3\x1b\x8e\x12v3d\xee8\x8f\x08\x0b}\x88\xee33;\xe3\xfc\xe3' DEBUG:removing 3.x=b'\x93\xe1q~\rd\r\x07\xa2\xbe!o\xa8\x12\x80\xb2\xf9:\x9b\x90-\x89\x1e\x14\xd6\x86\xcf\xb3\x1b\x8e\x12v3d\xee8\x8f\x08\x0b}\x88\xee33;\xe3\xfc\xe3' DEBUG:decrypting=b'\x93\xe1q~\rd\r\x07\xa2\xbe!o\xa8\x12\x80\xb2\xf9:\x9b\x90-\x89\x1e\x14\xd6\x86\xcf\xb3\x1b\x8e\x12v3d\xee8\x8f\x08\x0b}\x88\xee33;\xe3\xfc\xe3' DEBUG:decrypted 3.x payload='{"dps":{"1":"open"},"t":1716152779}' DEBUG:payload type = <class 'str'> DEBUG:decoded results='{"dps":{"1":"open"},"t":1716152779}' DEBUG:set_status received data={'dps': {'1': 'open'}, 't': 1716152779}

jasonacox commented 1 month ago

Yes, I see the problem. The CoverDevice assumes the cover device is closed by setting DPS 1 to "off" but your device wants it to be "close". You can switch to the OutletDevice class and use something like this:


import tinytuya

d = tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
tinytuya.set_debug(True)
d.set_version(3.3)

# Close
d.set_value(1, 'close')

# Open
d.set_value(1, 'open')
ngoduykhanh commented 3 weeks ago

@fdaforno I had the same issue. It turned out the 2nd switch worked. Maybe you can give it a try

d.close_cover(switch=2)