Restore state for ZHA OnOff binary sensors (#90749)
* Restore state for ZHA OnOff binary sensors * Let `Motion` extend `Opening` `Motion` is just a specified version of `Opening` that only changes the device class for some motion sensors. Since we have more "special code" in the OnOff/Opening sensor now, we also want to make sure that gets applied to `Motion` binary sensors. * Improve comment and type * Add test to verify that binary sensors restore last HA state
This commit is contained in:
parent
59511cc3f7
commit
a58b3721ed
2 changed files with 53 additions and 4 deletions
|
@ -4,6 +4,8 @@ from __future__ import annotations
|
|||
import functools
|
||||
from typing import Any
|
||||
|
||||
import zigpy.types as t
|
||||
from zigpy.zcl.clusters.general import OnOff
|
||||
from zigpy.zcl.clusters.security import IasZone
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
|
@ -119,11 +121,21 @@ class Occupancy(BinarySensor):
|
|||
|
||||
@STRICT_MATCH(channel_names=CHANNEL_ON_OFF)
|
||||
class Opening(BinarySensor):
|
||||
"""ZHA BinarySensor."""
|
||||
"""ZHA OnOff BinarySensor."""
|
||||
|
||||
SENSOR_ATTR = "on_off"
|
||||
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.OPENING
|
||||
|
||||
# Client/out cluster attributes aren't stored in the zigpy database, but are properly stored in the runtime cache.
|
||||
# We need to manually restore the last state from the sensor state to the runtime cache for now.
|
||||
@callback
|
||||
def async_restore_last_state(self, last_state):
|
||||
"""Restore previous state to zigpy cache."""
|
||||
self._channel.cluster.update_attribute(
|
||||
OnOff.attributes_by_name[self.SENSOR_ATTR].id,
|
||||
t.Bool.true if last_state.state == STATE_ON else t.Bool.false,
|
||||
)
|
||||
|
||||
|
||||
@MULTI_MATCH(channel_names=CHANNEL_BINARY_INPUT)
|
||||
class BinaryInput(BinarySensor):
|
||||
|
@ -144,10 +156,9 @@ class BinaryInput(BinarySensor):
|
|||
manufacturers="Philips",
|
||||
models={"SML001", "SML002"},
|
||||
)
|
||||
class Motion(BinarySensor):
|
||||
"""ZHA BinarySensor."""
|
||||
class Motion(Opening):
|
||||
"""ZHA OnOff BinarySensor with motion device class."""
|
||||
|
||||
SENSOR_ATTR = "on_off"
|
||||
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.MOTION
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from unittest.mock import patch
|
|||
|
||||
import pytest
|
||||
import zigpy.profiles.zha
|
||||
import zigpy.zcl.clusters.general as general
|
||||
import zigpy.zcl.clusters.measurement as measurement
|
||||
import zigpy.zcl.clusters.security as security
|
||||
|
||||
|
@ -40,6 +41,16 @@ DEVICE_OCCUPANCY = {
|
|||
}
|
||||
|
||||
|
||||
DEVICE_ONOFF = {
|
||||
1: {
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SENSOR,
|
||||
SIG_EP_INPUT: [],
|
||||
SIG_EP_OUTPUT: [general.OnOff.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def binary_sensor_platform_only():
|
||||
"""Only set up the binary_sensor and required base platforms to speed up tests."""
|
||||
|
@ -212,3 +223,30 @@ async def test_binary_sensor_migration_already_migrated(
|
|||
assert entity_id is not None
|
||||
assert hass.states.get(entity_id).state == STATE_ON # matches attribute cache
|
||||
assert hass.states.get(entity_id).attributes["migrated_to_cache"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"restored_state",
|
||||
[
|
||||
STATE_ON,
|
||||
STATE_OFF,
|
||||
],
|
||||
)
|
||||
async def test_onoff_binary_sensor_restore_state(
|
||||
hass: HomeAssistant,
|
||||
zigpy_device_mock,
|
||||
core_rs,
|
||||
zha_device_restored,
|
||||
restored_state,
|
||||
) -> None:
|
||||
"""Test ZHA OnOff binary_sensor restores last state from HA."""
|
||||
|
||||
entity_id = "binary_sensor.fakemanufacturer_fakemodel_opening"
|
||||
core_rs(entity_id, state=restored_state, attributes={})
|
||||
|
||||
zigpy_device = zigpy_device_mock(DEVICE_ONOFF)
|
||||
zha_device = await zha_device_restored(zigpy_device)
|
||||
entity_id = await find_entity_id(Platform.BINARY_SENSOR, zha_device, hass)
|
||||
|
||||
assert entity_id is not None
|
||||
assert hass.states.get(entity_id).state == restored_state
|
||||
|
|
Loading…
Add table
Reference in a new issue