Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CoverDevice don't close #498

Open
fdaforno opened this issue May 16, 2024 · 3 comments
Open

CoverDevice don't close #498

fdaforno opened this issue May 16, 2024 · 3 comments

Comments

@fdaforno
Copy link

fdaforno commented May 16, 2024

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
Copy link
Owner

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.

import tinytuya
import time
# tinytuya.set_debug(True)
# Setting the address to 'Auto' or None will trigger a scan which will auto-detect both the address and version, but this can take up to 8 seconds
d = tinytuya.OutletDevice('DEVICEID', 'Auto', 'DEVICEKEY', persist=True)
# If you know both the address and version then supplying them is a lot quicker
# d = tinytuya.OutletDevice('DEVICEID', 'DEVICEIP', 'DEVICEKEY', version=DEVICEVERSION, persist=True)
STATUS_TIMER = 30
KEEPALIVE_TIMER = 12
print(" > Send Request for Status < ")
data = d.status()
print('Initial Status: %r' % data)
if data and 'Err' in data:
print("Status request returned an error, is version %r and local key %r correct?" % (d.version, d.local_key))
print(" > Begin Monitor Loop <")
heartbeat_time = time.time() + KEEPALIVE_TIMER
status_time = None
# Uncomment if you want the monitor to constantly request status - otherwise you
# will only get updates when state changes
#status_time = time.time() + STATUS_TIMER
while(True):
if status_time and time.time() >= status_time:
# Uncomment if your device provides power monitoring data but it is not updating
# Some devices require a UPDATEDPS command to force measurements of power.
# print(" > Send DPS Update Request < ")
# Most devices send power data on DPS indexes 18, 19 and 20
# d.updatedps(['18','19','20'], nowait=True)
# Some Tuya devices will not accept the DPS index values for UPDATEDPS - try:
# payload = d.generate_payload(tinytuya.UPDATEDPS)
# d.send(payload)
# poll for status
print(" > Send Request for Status < ")
data = d.status()
status_time = time.time() + STATUS_TIMER
heartbeat_time = time.time() + KEEPALIVE_TIMER
elif time.time() >= heartbeat_time:
# send a keep-alive
data = d.heartbeat(nowait=False)
heartbeat_time = time.time() + KEEPALIVE_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)

@fdaforno
Copy link
Author

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
Copy link
Owner

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')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants