xZetsubou / hass-localtuya

šŸ”¹ A Home Assistant integration to handle Tuya devices locally "fork from localtuya"
https://xzetsubou.github.io/hass-localtuya/
GNU General Public License v3.0
399 stars 48 forks source link

[Bug]: Many Errors #213

Closed milandzuris closed 4 months ago

milandzuris commented 5 months ago

LocalTuya Version

No response

Home Assistant Version

2024.5.0b1

Environment

What happened?

A bug happened!

Steps to reproduce.

*

Relevant log output

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/localtuya/core/pytuya/__init__.py:380
integration: LocalTuya (documentation, issues)
First occurred: April 27, 2024 at 16:29:16 (87 occurrences)
Last logged: 00:24:54

Error doing job: Fatal error: protocol.data_received() call failed.
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 1017, in _read_ready__data_received
    self._protocol.data_received(data)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 872, in data_received
    self.dispatcher.add_data(data)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 631, in add_data
    msg = unpack_message(
          ^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 380, in unpack_message
    raise DecodeError(f"Not enough data to unpack payload: {data}")
custom_components.localtuya.core.pytuya.DecodeError: Not enough data to unpack payload: b'\x00\x00U\xaa\x00\x00\x16x\x00\x00\x00\x10\x00\x00\x00\xe8\x00\x00\x00\x00\xdf\x1b\x1f\x0c\x1d\x19\'\xe2\x89\xcbj\x07Z.\xaez@f\xfc\x17i\tt\xf8\xe3\xb8C\xe9}"\xb3\x13I\xbdj-\xa0\xaf\x04\x18\xb2C\xc8\xf2\xc4Cg\x84\x97:\xb6\xda|\xcd`N\x7f\xc3\xc4!\x08\xc5\xf4\x98\x81%\t.\x02\x0e\xa4=\xd0\x8f\xd4\xa5\x95\x12\xa0]\xfa\x0b\x8dX\xd4\x93mE\x8c\xd1Y\x0b\xbf\xfc*B= v\x02v\\rNW\xdc\'\xee\xac&\x13f\xe4m\x17[J^)_\x1c\xb7\xba\x81\xad\x8cT\x8c\xac\xd7\xe6\xd5\xfe\xa2\xce\t\xf2y6\xf3\r\xd4\x14\x9dg\x81\x94PYM.\\\xf8p\xa6c\x82\xec\xd8{\x17\x92\x87\xdeOQEY\xefv\xcb\xf1;\x07\x19`\x86B\xbe\x1cL\x0erP<n\x8d\xc5:t\xaf\x1d\xa5\x0f\x91\x86\xe1M\x99a'

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/localtuya/core/pytuya/__init__.py:600
integration: LocalTuya (documentation, issues)
First occurred: April 27, 2024 at 16:25:11 (794071 occurrences)
Last logged: 00:24:48

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/locks.py", line 386, in acquire
    await fut
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/localtuya/coordinator.py", line 390, in _async_refresh
    await self._interface.update_dps(cid=self._node_id)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1034, in update_dps
    await self.detect_available_dps(cid=cid)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1075, in detect_available_dps
    data = await self.status(cid=cid)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 997, in status
    status: dict = await self.exchange(command=DP_QUERY, nodeID=cid, delay=False)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 971, in exchange
    msg = await self.dispatcher.wait_for(seqno, payload.cmd)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 600, in wait_for
    await asyncio.wait_for(self.listeners[seqno].acquire(), timeout=timeout)
  File "/usr/local/lib/python3.12/asyncio/tasks.py", line 519, in wait_for
    async with timeouts.timeout(timeout):
  File "/usr/local/lib/python3.12/asyncio/timeouts.py", line 115, in __aexit__
    raise TimeoutError from exc_val
TimeoutError

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/localtuya/core/pytuya/__init__.py:595
integration: LocalTuya (documentation, issues)
First occurred: April 27, 2024 at 16:25:36 (1148 occurrences)
Last logged: 00:24:36

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/localtuya/coordinator.py", line 390, in _async_refresh
    await self._interface.update_dps(cid=self._node_id)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1034, in update_dps
    await self.detect_available_dps(cid=cid)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1075, in detect_available_dps
    data = await self.status(cid=cid)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 997, in status
    status: dict = await self.exchange(command=DP_QUERY, nodeID=cid, delay=False)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 971, in exchange
    msg = await self.dispatcher.wait_for(seqno, payload.cmd)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 595, in wait_for
    raise Exception(f"listener exists for {seqno}")
Exception: listener exists for 49523

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/localtuya/core/pytuya/__init__.py:838
integration: LocalTuya (documentation, issues)
First occurred: April 27, 2024 at 16:37:05 (4874 occurrences)
Last logged: 00:23:53

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/localtuya/coordinator.py", line 390, in _async_refresh
    await self._interface.update_dps(cid=self._node_id)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1034, in update_dps
    await self.detect_available_dps(cid=cid)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 1075, in detect_available_dps
    data = await self.status(cid=cid)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 997, in status
    status: dict = await self.exchange(command=DP_QUERY, nodeID=cid, delay=False)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 970, in exchange
    await self.transport_write(enc_payload, delay)
  File "/config/custom_components/localtuya/core/pytuya/__init__.py", line 838, in transport_write
    self.transport.write(data)
    ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'write'

Diagnostics information.

No response

xZetsubou commented 5 months ago

I think this already been handled in master.

Lurker00 commented 5 months ago

I think this already been handled in master.

I'm not sure. The buffer:

b'\x00\x00U\xaa\x00\x00\x16x\x00\x00\x00\x10\x00\x00\x00\xe8\x00\x00\x00\x00\xdf\x1b\x1f\x0c\x1d\x19\'\xe2\x89\xcbj\x07Z.\xaez@f\xfc\x17i\tt\xf8\xe3\xb8C\xe9}"\xb3\x13I\xbdj-\xa0\xaf\x04\x18\xb2C\xc8\xf2\xc4Cg\x84\x97:\xb6\xda|\xcd`N\x7f\xc3\xc4!\x08\xc5\xf4\x98\x81%\t.\x02\x0e\xa4=\xd0\x8f\xd4\xa5\x95\x12\xa0]\xfa\x0b\x8dX\xd4\x93mE\x8c\xd1Y\x0b\xbf\xfc*B= v\x02v\\rNW\xdc\'\xee\xac&\x13f\xe4m\x17[J^)_\x1c\xb7\xba\x81\xad\x8cT\x8c\xac\xd7\xe6\xd5\xfe\xa2\xce\t\xf2y6\xf3\r\xd4\x14\x9dg\x81\x94PYM.\\\xf8p\xa6c\x82\xec\xd8{\x17\x92\x87\xdeOQEY\xefv\xcb\xf1;\x07\x19`\x86B\xbe\x1cL\x0erP<n\x8d\xc5:t\xaf\x1d\xa5\x0f\x91\x86\xe1M\x99a'

looks like a valid 55AA message without a tail. Its length is 0xe8=232, then retcode=0. The trailing bytes are not 9966, as they would be if it was a tail of 6699 message ('a'=0x61).

My point of view that this is the example that messages may come fragmented! To work it out, another check should be implemented in add_data, like this:

            header = parse_header(self.buffer, logger=self)
            if header.total_length < len(self.buffer):
                break # waiting for the tail of the message
            hmac_key = self.local_key if self.version >= 3.4 else None

"Header claims the packet size is over" exceptions were results of the wrong parser, which is already fixed.

xZetsubou commented 5 months ago

This a a CMD 16 with the total length 248 so it bigger then the length of buffer it won't break.

The check should be the opposite right?

            header = parse_header(self.buffer, logger=self)
            if len(self.buffer) < header.total_length:
                break # waiting for the tail of the message
            hmac_key = self.local_key if self.version >= 3.4 else None
Lurker00 commented 5 months ago

The check should be the opposite right?

My bad šŸ˜ž You are right!

github-actions[bot] commented 4 months ago

This issue was closed because it was resolved on the release: []()