rospogrigio / localtuya

local handling for Tuya devices
GNU General Public License v3.0
2.85k stars 546 forks source link

NOT AN ISSUE: Bseed switches unsupported protocol #229

Open ovid-io opened 3 years ago

ovid-io commented 3 years ago

Hi,

First of all I want to thank devs for putting so much effort into this integration, I have configured 10+ various tuya lights and switches and everything works like a charm!

Only stuff I have not integrated so far are these switches that I bought almost two years ago:

image

I've quite a few of them and I suspect they are running a different protocol than 3.1/3.3 When I try to add one the protocol automatic selection stays blank:

image

If I try with protocol 3.1 I get the following error in UI and HA log:

UI: An unknown error occurred. See log for details.

2020-12-08 19:53:29 ERROR (MainThread) [custom_components.localtuya.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/config/custom_components/localtuya/config_flow.py", line 260, in async_step_basic_info
    self.dps_strings = await validate_input(self.hass, user_input)
  File "/config/custom_components/localtuya/config_flow.py", line 173, in validate_input
    detected_dps = await interface.detect_available_dps()
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 499, in detect_available_dps
    data = await self.status()
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 461, in status
    status = await self.exchange(STATUS)
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 446, in exchange
    payload = self._decode_payload(msg.payload)
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 543, in _decode_payload
    raise Exception(f"Unexpected payload={payload}")
Exception: Unexpected payload=b'json obj data unvalid'

With protocol 3.3 I get the following errors in UI and HA log:

UI: Failed to authenticate with device. Verify that device id and local key are correct.

2020-12-08 19:54:57 ERROR (MainThread) [custom_components.localtuya.pytuya] [bfb...u68] Failed to get status: The length of the provided data is not a multiple of the block length.
Traceback (most recent call last):
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 499, in detect_available_dps
    data = await self.status()
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 461, in status
    status = await self.exchange(STATUS)
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 446, in exchange
    payload = self._decode_payload(msg.payload)
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 533, in _decode_payload
    payload = self.cipher.decrypt(payload, False)
  File "/config/custom_components/localtuya/pytuya/__init__.py", line 196, in decrypt
    return self._unpad(decryptor.update(enc) + decryptor.finalize()).decode()
  File "/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 164, in finalize
    data = self._ctx.finalize()
  File "/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 181, in finalize
    raise ValueError(
ValueError: The length of the provided data is not a multiple of the block length.

Local key etc. should be correct as I obtained then via tuya-cli and every other device worked. I suspect it could be protocol 3.2 or lower and there is no update for these switches via tuya app.

Is there anything I can do to investigate further/facilitate someone to do it? Unfortunately I've no dev experience with python but am full time node developer.

ultratoto14 commented 3 years ago

If you use tuya-cli, can you check that you can get DPs from it ?

tuya-cli get --ip 192.168.1.163 --id 63226301c44f33cdb908 --key 141f2e4e6e74e77c -a --protocol-version 3.3
ovid-io commented 3 years ago

Above just gives me "data format error" and "Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('json obj data unvalid')" with protocols 3.3 and 3.1 respectively

Edit: with 3.1 it seems to timeout waiting for response:

json obj data unvalid

(node:2856) UnhandledPromiseRejectionWarning: Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('Timeout waiting for status respo
nse from device id: bfbd0e01ac7ba66218ou68')

    at TuyaDevice.emit (events.js:187:17)

    at pTimeout (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/tuyapi/index.js:257:12)

    at Timeout.setTimeout [as _onTimeout] (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/p-timeout/index.js:25:13)

    at ontimeout (timers.js:436:11)

    at tryOnTimeout (timers.js:300:5)

    at listOnTimeout (timers.js:263:5)
 
   at Timer.processTimers (timers.js:223:10)

But it also does same with lights and switches that do work with localtuya so not sure what the deal is there

ovid-io commented 3 years ago

test.py gives same results:

INFO:localtuya:localtuya version 1.0.0
INFO:localtuya:Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
INFO:localtuya:Using pytuya version '8.1.0'
INFO:localtuya:Detecting list of available DPS of device bfbd0e01ac7ba66218ou68 [192.168
.1.161], protocol 3.1.
DEBUG:localtuya.pytuya:Sending command status (device type: type_0a)
DEBUG:localtuya.pytuya:paylod=b'{"gwId":"bfbd0e01ac7ba66218ou68","devId":"bfbd0e01ac7ba6
6218ou68"}'
DEBUG:localtuya.pytuya:DATA RECEIVED!
DEBUG:localtuya.pytuya:decode payload=b'data format error'
DEBUG:localtuya.pytuya:Failed to connect to 192.168.1.161. Raising Exception.
WARNING:localtuya.pytuya:Failed to get status: The length of the provided data is not a 
multiple of the block length.
INFO:localtuya:Detecting list of available DPS of device bfbd0e01ac7ba66218ou68 [192.168
.1.161], protocol 3.1.
DEBUG:localtuya.pytuya:Sending command status (device type: type_0a)
DEBUG:localtuya.pytuya:paylod=b'{"gwId":"bfbd0e01ac7ba66218ou68","devId":"bfbd0e01ac7ba6
6218ou68"}'
DEBUG:localtuya.pytuya:DATA RECEIVED!
DEBUG:localtuya.pytuya:decode payload=b'data format error'
DEBUG:localtuya.pytuya:Failed to connect to 192.168.1.161. Raising Exception.
WARNING:localtuya.pytuya:Failed to get status: The length of the provided data is not a 
multiple of the block length.
INFO:localtuya:Detecting list of available DPS of device bfbd0e01ac7ba66218ou68 [192.168
.1.161], protocol 3.1.
DEBUG:localtuya.pytuya:Sending command status (device type: type_0a)
DEBUG:localtuya.pytuya:paylod=b'{"gwId":"bfbd0e01ac7ba66218ou68","devId":"bfbd0e01ac7ba6
6218ou68"}'
DEBUG:localtuya.pytuya:DATA RECEIVED!
DEBUG:localtuya.pytuya:decode payload=b'data format error'
DEBUG:localtuya.pytuya:Failed to connect to 192.168.1.161. Raising Exception.
WARNING:localtuya.pytuya:Failed to get status: The length of the provided data is not a 
multiple of the block length.
INFO:localtuya:TIMEOUT: No response from device bfbd0e01ac7ba66218ou68 [192.168.1.161] a
fter 2 attempts.

When pytuya logs data received, this is the data that it receives:

b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x1d\x00
\x00\x00\x01data format errorM\xdf\x82\xac\x00\x00\xaaU'
postlund commented 3 years ago

If you enable debug logging, you will be able to see the discovery messages which include the version. That way we can conclude which version it is. We currently don't support version 3.2 and I haven't found anyone else supporting it either, so at this point we're stuck unless you want to help figuring out how it works.

logger:
  default: warning
  logs:
    custom_components.localtuya: debug
grandchamp commented 3 years ago

@postlund I've got the same issue with two bulbs that were working before I went into holidays.

This is the debug when selecting 3.3 protocol:

home-assistant   | 2021-01-15 10:47:55 DEBUG (MainThread) [custom_components.localtuya.discovery] Listening to broadcasts on UDP port 6666 and 6667
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Started heartbeat loop
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Sending command heartbeat (device type: type_0a)
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Send payload: b'{}'
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Waiting for sequence number -100
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Sending command status (device type: type_0a)
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Send payload: b'{"gwId":"03272457b4e62d4c7680","devId":"03272457b4e62d4c7680"}'
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Waiting for sequence number 1
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Got heartbeat response
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Dispatching message TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b'data format error', crc=1908367780)
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Dispatching sequence number 1
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Decrypted payload: {}
home-assistant   | 2021-01-15 10:48:27 ERROR (MainThread) [custom_components.localtuya.pytuya] [032...680] Failed to get status: The length of the provided data is not a multiple of the block length.
home-assistant   | Traceback (most recent call last):
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 510, in detect_available_dps
home-assistant   |     data = await self.status()
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 472, in status
home-assistant   |     status = await self.exchange(STATUS)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 457, in exchange
home-assistant   |     payload = self._decode_payload(msg.payload)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 544, in _decode_payload
home-assistant   |     payload = self.cipher.decrypt(payload, False)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 196, in decrypt
home-assistant   |     return self._unpad(decryptor.update(enc) + decryptor.finalize()).decode()
home-assistant   |   File "/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/ciphers/base.py", line 164, in finalize
home-assistant   |     data = self._ctx.finalize()
home-assistant   |   File "/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 181, in finalize
home-assistant   |     raise ValueError(
home-assistant   | ValueError: The length of the provided data is not a multiple of the block length.
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Closing connection
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Stopped heartbeat loop
home-assistant   | 2021-01-15 10:48:27 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Connection lost: None

And this is when selecting 3.1:

home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Started heartbeat loop
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Sending command heartbeat (device type: type_0a)
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Send payload: b'{}'
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Waiting for sequence number -100
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Sending command status (device type: type_0a)
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Send payload: b'{"gwId":"03272457b4e62d4c7680","devId":"03272457b4e62d4c7680"}'
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Waiting for sequence number 1
home-assistant   | 2021-01-15 10:51:18 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Connection lost: [Errno 104] Connection reset by peer
home-assistant   | 2021-01-15 10:51:23 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Heartbeat failed due to timeout, disconnecting
home-assistant   | 2021-01-15 10:51:23 ERROR (MainThread) [custom_components.localtuya.pytuya] [032...680] Failed to get status:
home-assistant   | Traceback (most recent call last):
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 510, in detect_available_dps
home-assistant   |     data = await self.status()
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 472, in status
home-assistant   |     status = await self.exchange(STATUS)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 451, in exchange
home-assistant   |     msg = await self.dispatcher.wait_for(seqno)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 240, in wait_for
home-assistant   |     await asyncio.wait_for(self.listeners[seqno].acquire(), timeout=timeout)
home-assistant   |   File "/usr/local/lib/python3.8/asyncio/tasks.py", line 501, in wait_for
home-assistant   |     raise exceptions.TimeoutError()
home-assistant   | asyncio.exceptions.TimeoutError
home-assistant   | 2021-01-15 10:51:23 DEBUG (MainThread) [custom_components.localtuya.pytuya] [032...680] Closing connection
home-assistant   | 2021-01-15 10:51:23 ERROR (MainThread) [custom_components.localtuya.config_flow] Unexpected exception
home-assistant   | Traceback (most recent call last):
home-assistant   |   File "/config/custom_components/localtuya/config_flow.py", line 279, in async_step_basic_info
home-assistant   |     self.dps_strings = await validate_input(self.hass, user_input)
home-assistant   |   File "/config/custom_components/localtuya/config_flow.py", line 192, in validate_input
home-assistant   |     detected_dps = await interface.detect_available_dps()
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 510, in detect_available_dps
home-assistant   |     data = await self.status()
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 472, in status
home-assistant   |     status = await self.exchange(STATUS)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 451, in exchange
home-assistant   |     msg = await self.dispatcher.wait_for(seqno)
home-assistant   |   File "/config/custom_components/localtuya/pytuya/__init__.py", line 240, in wait_for
home-assistant   |     await asyncio.wait_for(self.listeners[seqno].acquire(), timeout=timeout)
home-assistant   |   File "/usr/local/lib/python3.8/asyncio/tasks.py", line 501, in wait_for
home-assistant   |     raise exceptions.TimeoutError()
home-assistant   | asyncio.exceptions.TimeoutError