clach04 / python-tuya

Python interface to ESP8266MOD WiFi smart devices from Shenzhen Xenon. NOTE I'm not using any devices with this library so I can't test :-(
MIT License
239 stars 55 forks source link

ValueError() on get_status() - encrypted payload returned (sometimes) #6

Closed clach04 closed 6 years ago

clach04 commented 6 years ago

related to Issue #2

repeated status calls sometimes fail with:

  File "demo_status.py", line 38, in <module>
    data = d.status()
  File "C:\Users\clach04\py\python-tuya_clach04\pytuya\__init__.py", line 234, in status
    result = json.loads(result)
  File "C:\ProgramData\Anaconda2\lib\json\__init__.py", line 339, in loads
    return _default_decoder.decode(s)
  File "C:\ProgramData\Anaconda2\lib\json\decoder.py", line 367, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))

extract of test (after creating switch object):

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']

data = d.set_status(pytuya.ON)
if data:
    print('set_status() result %r' % data)
    print('set_status() extra %r' % data[20:-8])

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']
print('switch_state %r' % switch_state)

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']
print('switch_state %r' % switch_state)

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']
print('switch_state %r' % switch_state)

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']
print('switch_state %r' % switch_state)

data = d.status()
print('Dictionary %r' % data)
switch_state = data['dps']['1']
print('switch_state %r' % switch_state)
clach04 commented 6 years ago

Dumped payload and sometimes switch is returning an encrypted payload. Using similar technique as when sending payload to switch. I'm not sure what triggers this. THe returned payloa donce decrypted looks like a status but with extra elements for "t" and "s", they are both numeric. s is so far 3 digits. t is 10 digits.

Sometimes see a 2nd switch entry in dps, which is zero - wonder if this is timer related?

E.g. (numbers changed.....):

{
    "devId":"0020046560019434492c",
    "dps":{
            "1":true,
            "2":0
            },
    "t":1234567890,
    "s":123
}

and

{
    "devId":"0020046560019434492c",
    "dps":{"1":true},
    "t":1234567890,
    "s":123
}

t looks like its epoch time (i.e. time.time())

clach04 commented 6 years ago

t is epoch time (i.e. time.time()).

clach04 commented 6 years ago

I believed this is resolved by commit 8d70404fb38cf2144c60329678b8f6bb84a8720d.

Leaving open for testing.

nijave commented 6 years ago

Tuya documentation alluded to the devices having time series of data although I can't remember where I saw that and if the device itself maintains that or it's solely the Tuya "cloud"

Does 's' increase or seem to change randomly?

clach04 commented 6 years ago

s - maybe, I don't have a good record of them. Its not increment by one but I'm trying to remember if it jumps around. I'll have to start dumping that info to a file.

I checked t with python time.time() so I'm convinced is epoc time.

clach04 commented 6 years ago

@nijave I spent a while trying to get it to dump a crypted status and it took a really long time before it happened. I only managed to catch a few:

{"devId":"XXXXXXXXXXXXXXX","dps":{"1":true,"2":0},"t":1515131564,"s":569}
{"devId":"XXXXXXXXXXXXXXX","dps":{"1":true,"2":0},"t":1515131566,"s":573}
{"devId":"XXXXXXXXXXXXXXX","dps":{"1":true},"t":1515131582,"s":576}
{"devId":"XXXXXXXXXXXXXXX","dps":{"1":true},"t":1515131584,"s":580}
{"devId":"XXXXXXXXXXXXXXX","dps":{"1":true},"t":1515131594,"s":592}

So yes increasing. These are all the same device. I've no idea why s is missing on the last few.

unparagoned commented 6 years ago

@clach04 @nijave Could this be the same issue I'm having where I get an error response. I'm using tuyapi, and just assumed that the issues was with my glue script since I have pretty much no nodejs knowledge I was messing things up by leaving connections open, etc. IT works most the time but now and then it gets into a tizzy. https://github.com/unparagoned/njsTuya/issues/1

clach04 commented 6 years ago

@unparagoned unlikely - your reported problem looks like a comms disconnect, this is an encrypted payload (that was unexpected until decryption support was added). One way to tell for sure would be to check the error you are seeing. I would say try the new version of python-tuya but its Python not javascript so likely not something you want to do.

One of the things python-tuya does differently is that its deliberately naive in its comms approach. It opens and closes the socket each time (its not that slow to do) which reduces the window for disconnects to occur.

nijave commented 6 years ago

@unparagoned @clach04 that doesn't sound like the issue clach04 was having with the extra/encrypted payload but that sounds like the issue I was hitting running inside HomeAssistant. The TCP RST which sounds like @unparagoned's problem I've only hit running inside HA. I was able to recreate the extra data issue with a constant loop that toggled the device's state and polled in between (after a few loops it returned an encrypted payload).

clach04 commented 6 years ago

@unparagoned issue #2

clach04 commented 6 years ago

Resolved by commit 8d70404fb38cf2144c60329678b8f6bb84a8720d