mirror of
https://github.com/home-assistant/core.git
synced 2025-12-08 08:58:05 +00:00
Compare commits
3 Commits
knx-data-s
...
epenet-202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a76c3a6864 | ||
|
|
3ae8f5d955 | ||
|
|
bbd21876e6 |
@@ -51,7 +51,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TuyaConfigEntry) -> bool
|
||||
raise ConfigEntryAuthFailed("Authentication failed. Please re-authenticate.")
|
||||
|
||||
token_listener = TokenListener(hass, entry)
|
||||
manager = Manager(
|
||||
manager = CustomManager(
|
||||
TUYA_CLIENT_ID,
|
||||
entry.data[CONF_USER_CODE],
|
||||
entry.data[CONF_TERMINAL_ID],
|
||||
@@ -243,3 +243,32 @@ class TokenListener(SharingTokenListener):
|
||||
self.hass.config_entries.async_update_entry(self.entry, data=data)
|
||||
|
||||
self.hass.add_job(async_update_entry)
|
||||
|
||||
|
||||
# Workaround for https://github.com/home-assistant/core/issues/151239
|
||||
# When a status update is received with a dpId not present in the
|
||||
# local_strategy, all subsequent dpId are ignored resulting in
|
||||
# missing update in Home Assistant.
|
||||
# Can be removed when fix is implemented in library
|
||||
# - https://github.com/tuya/tuya-device-sharing-sdk/pull/39
|
||||
|
||||
|
||||
class CustomManager(Manager):
|
||||
"""Workaround for device status update issue #151239.
|
||||
|
||||
Can be removed when fix is implemented in library
|
||||
https://github.com/tuya/tuya-device-sharing-sdk/pull/39
|
||||
"""
|
||||
|
||||
def _on_device_report(self, device_id: str, status: list[dict[str, Any]]) -> None:
|
||||
# Patch start
|
||||
if (device := self.device_map.get(device_id)) and device.support_local:
|
||||
new_status = []
|
||||
for item in status:
|
||||
if (dpId := item.get("dpId")) and dpId not in device.local_strategy:
|
||||
LOGGER.debug("Ignoring dpId %s missing from local_strategy", dpId)
|
||||
continue
|
||||
new_status.append(item)
|
||||
status = new_status
|
||||
# Patch end
|
||||
super()._on_device_report(device_id, status)
|
||||
|
||||
@@ -319,6 +319,8 @@ async def initialize_entry(
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
# Initialize the component
|
||||
with patch("homeassistant.components.tuya.Manager", return_value=mock_manager):
|
||||
with patch(
|
||||
"homeassistant.components.tuya.CustomManager", return_value=mock_manager
|
||||
):
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -73,8 +73,8 @@ async def mock_loaded_entry(
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
# Initialize the component
|
||||
with (
|
||||
patch("homeassistant.components.tuya.Manager", return_value=mock_manager),
|
||||
with patch(
|
||||
"homeassistant.components.tuya.CustomManager", return_value=mock_manager
|
||||
):
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
from tuya_sharing import CustomerDevice, Manager
|
||||
|
||||
from homeassistant.components.tuya import CustomManager
|
||||
from homeassistant.components.tuya.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
@@ -65,3 +68,108 @@ async def test_fixtures_valid(hass: HomeAssistant) -> None:
|
||||
assert key not in details, (
|
||||
f"Please remove data[`'{key}']` from {device_code}.json"
|
||||
)
|
||||
|
||||
|
||||
async def test_manager_fix() -> None:
|
||||
"""Test manager fix for Tuya SDK.
|
||||
|
||||
See https://github.com/home-assistant/core/issues/151239
|
||||
|
||||
dpId `101` is present in the status update but not in the local_strategy, causing
|
||||
all subsequent dpId (`3`, `15`, `5`, `9`) in the message to be ignored.
|
||||
"""
|
||||
with patch("tuya_sharing.manager.CustomerTokenInfo"):
|
||||
manager = CustomManager("test", "test", "test", "test")
|
||||
|
||||
device = CustomerDevice(
|
||||
support_local=True,
|
||||
local_strategy={
|
||||
3: {
|
||||
"value_convert": "default",
|
||||
"status_code": "humidity",
|
||||
"config_item": {
|
||||
"statusFormat": '{"humidity":"$"}',
|
||||
"valueDesc": '{"unit":"%","min":0,"max":100,"scale":0,"step":1}',
|
||||
"valueType": "Integer",
|
||||
"enumMappingMap": {},
|
||||
"pid": "rknwi0ctbbghzgla",
|
||||
},
|
||||
},
|
||||
5: {
|
||||
"value_convert": "default",
|
||||
"status_code": "temp_current",
|
||||
"config_item": {
|
||||
"statusFormat": '{"temp_current":"$"}',
|
||||
"valueDesc": '{"unit":"℃","min":0,"max":1000,"scale":1,"step":1}',
|
||||
"valueType": "Integer",
|
||||
"enumMappingMap": {},
|
||||
"pid": "rknwi0ctbbghzgla",
|
||||
},
|
||||
},
|
||||
9: {
|
||||
"value_convert": "default",
|
||||
"status_code": "temp_unit_convert",
|
||||
"config_item": {
|
||||
"statusFormat": '{"temp_unit_convert":"$"}',
|
||||
"valueDesc": '{"range":["c","f"]}',
|
||||
"valueType": "Enum",
|
||||
"enumMappingMap": {},
|
||||
"pid": "rknwi0ctbbghzgla",
|
||||
},
|
||||
},
|
||||
15: {
|
||||
"value_convert": "default",
|
||||
"status_code": "battery_percentage",
|
||||
"config_item": {
|
||||
"statusFormat": '{"battery_percentage":"$"}',
|
||||
"valueDesc": '{"unit":"%","min":0,"max":100,"scale":0,"step":1}',
|
||||
"valueType": "Integer",
|
||||
"enumMappingMap": {},
|
||||
"pid": "rknwi0ctbbghzgla",
|
||||
},
|
||||
},
|
||||
},
|
||||
status={
|
||||
"humidity": 321,
|
||||
"temp_current": 321,
|
||||
"temp_unit_convert": "f",
|
||||
"battery_percentage": 321,
|
||||
},
|
||||
)
|
||||
manager.device_map = {"bfe251cfa8882fae3cpvup": device}
|
||||
|
||||
manager.on_message(
|
||||
{
|
||||
"protocol": 20,
|
||||
"data": {
|
||||
"bizCode": "online",
|
||||
"bizData": {"devId": "bfe251cfa8882fae3cpvup", "time": 1759226706159},
|
||||
"ts": 1759226706408,
|
||||
},
|
||||
"t": 1759226706408,
|
||||
}
|
||||
)
|
||||
manager.on_message(
|
||||
{
|
||||
"protocol": 4,
|
||||
"data": {
|
||||
"devId": "bfe251cfa8882fae3cpvup",
|
||||
"dataId": "2711cd0c-c215-48f4-b535-243640e3b5b3",
|
||||
"productKey": "rknwi0ctbbghzgla",
|
||||
"status": [
|
||||
{"dpId": 101, "t": 1759226706567, "value": 456},
|
||||
{"dpId": 3, "t": 1759226706567, "value": 87},
|
||||
{"dpId": 15, "t": 1759226706567, "value": 40},
|
||||
{"dpId": 5, "t": 1759226706567, "value": 76},
|
||||
{"dpId": 9, "t": 1759226706567, "value": "c"},
|
||||
],
|
||||
},
|
||||
"t": 1759226707104,
|
||||
}
|
||||
)
|
||||
assert device.status == {
|
||||
"humidity": 87,
|
||||
"temp_current": 76,
|
||||
"temp_unit_convert": "c",
|
||||
"battery_percentage": 40,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user