mirror of
https://github.com/home-assistant/core.git
synced 2026-09-27 18:08:37 -04:00
Refactor write_ha_state logic in Tuya (#163431)
This commit is contained in:
@@ -473,14 +473,16 @@ class TuyaBinarySensorEntity(TuyaEntity, BinarySensorEntity):
|
||||
"""Return true if sensor is on."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
@@ -59,7 +59,33 @@ class TuyaEntity(Entity):
|
||||
updated_status_properties: list[str] | None,
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
self.async_write_ha_state()
|
||||
"""Called when Tuya device sends an update."""
|
||||
if (
|
||||
# If updated_status_properties is None, we should not skip,
|
||||
# as we don't have information on what was updated
|
||||
# This happens for example on online/offline updates, where
|
||||
# we still want to update the entity state but we have nothing
|
||||
# to process
|
||||
updated_status_properties is None
|
||||
# If we have data to process, we check if we should skip the
|
||||
# state_write based on the dpcode wrapper logic
|
||||
or await self._process_device_update(
|
||||
updated_status_properties, dp_timestamps
|
||||
)
|
||||
):
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return True
|
||||
|
||||
async def _async_send_commands(self, commands: list[dict[str, Any]]) -> None:
|
||||
"""Send a list of commands to the device."""
|
||||
|
||||
@@ -215,16 +215,21 @@ class TuyaEventEntity(TuyaEntity, EventEntity):
|
||||
self._dpcode_wrapper = dpcode_wrapper
|
||||
self._attr_event_types = dpcode_wrapper.options
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
) or not (event_data := self._dpcode_wrapper.read_device_status(self.device)):
|
||||
return
|
||||
return False
|
||||
|
||||
event_type, event_attributes = event_data
|
||||
self._trigger_event(event_type, event_attributes)
|
||||
self.async_write_ha_state()
|
||||
return True
|
||||
|
||||
@@ -46,7 +46,7 @@ class DeviceWrapper[T]:
|
||||
def skip_update(
|
||||
self,
|
||||
device: CustomerDevice,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> bool:
|
||||
"""Determine if the wrapper should skip an update.
|
||||
@@ -85,7 +85,7 @@ class DPCodeWrapper(DeviceWrapper):
|
||||
def skip_update(
|
||||
self,
|
||||
device: CustomerDevice,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> bool:
|
||||
"""Determine if the wrapper should skip an update.
|
||||
@@ -252,20 +252,13 @@ class DPCodeDeltaIntegerWrapper(DPCodeIntegerWrapper):
|
||||
def skip_update(
|
||||
self,
|
||||
device: CustomerDevice,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> bool:
|
||||
"""Override skip_update to process delta updates.
|
||||
|
||||
Processes delta accumulation before determining if update should be skipped.
|
||||
"""
|
||||
# If updated_status_properties is None, we should not skip,
|
||||
# as we don't have information on what was updated
|
||||
# This happens for example on online/offline updates, where
|
||||
# we still want to update the entity state but we have nothing
|
||||
# to accumulate, so we return False to not skip the update
|
||||
if updated_status_properties is None:
|
||||
return False
|
||||
if (
|
||||
super().skip_update(device, updated_status_properties, dp_timestamps)
|
||||
or dp_timestamps is None
|
||||
|
||||
@@ -551,17 +551,19 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity):
|
||||
"""Return the entity value to represent the entity state."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
async def async_set_native_value(self, value: float) -> None:
|
||||
"""Set new value."""
|
||||
|
||||
@@ -407,17 +407,19 @@ class TuyaSelectEntity(TuyaEntity, SelectEntity):
|
||||
"""Return the selected entity option to represent the entity state."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
|
||||
@@ -1856,14 +1856,16 @@ class TuyaSensorEntity(TuyaEntity, SensorEntity):
|
||||
"""Return the value reported by the sensor."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
@@ -107,17 +107,19 @@ class TuyaSirenEntity(TuyaEntity, SirenEntity):
|
||||
"""Return true if siren is on."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the siren on."""
|
||||
|
||||
@@ -1040,17 +1040,19 @@ class TuyaSwitchEntity(TuyaEntity, SwitchEntity):
|
||||
"""Return true if switch is on."""
|
||||
return self._read_wrapper(self._dpcode_wrapper)
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
|
||||
@@ -137,17 +137,19 @@ class TuyaValveEntity(TuyaEntity, ValveEntity):
|
||||
return None
|
||||
return not is_open
|
||||
|
||||
async def _handle_state_update(
|
||||
async def _process_device_update(
|
||||
self,
|
||||
updated_status_properties: list[str] | None,
|
||||
updated_status_properties: list[str],
|
||||
dp_timestamps: dict[str, int] | None,
|
||||
) -> None:
|
||||
"""Handle state update, only if this entity's dpcode was actually updated."""
|
||||
if self._dpcode_wrapper.skip_update(
|
||||
) -> bool:
|
||||
"""Called when Tuya device sends an update with updated properties.
|
||||
|
||||
Returns True if the Home Assistant state should be written,
|
||||
or False if the state write should be skipped.
|
||||
"""
|
||||
return not self._dpcode_wrapper.skip_update(
|
||||
self.device, updated_status_properties, dp_timestamps
|
||||
):
|
||||
return
|
||||
self.async_write_ha_state()
|
||||
)
|
||||
|
||||
async def async_open_valve(self) -> None:
|
||||
"""Open the valve."""
|
||||
|
||||
Reference in New Issue
Block a user