mirror of
https://github.com/home-assistant/core.git
synced 2025-04-28 19:27:51 +00:00
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
@ -4,6 +4,8 @@ from __future__ import annotations
|
|||||||
import functools
|
import functools
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import zigpy.types as t
|
||||||
|
from zigpy.zcl.clusters.general import OnOff
|
||||||
from zigpy.zcl.clusters.security import IasZone
|
from zigpy.zcl.clusters.security import IasZone
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
@ -119,11 +121,21 @@ class Occupancy(BinarySensor):
|
|||||||
|
|
||||||
@STRICT_MATCH(channel_names=CHANNEL_ON_OFF)
|
@STRICT_MATCH(channel_names=CHANNEL_ON_OFF)
|
||||||
class Opening(BinarySensor):
|
class Opening(BinarySensor):
|
||||||
"""ZHA BinarySensor."""
|
"""ZHA OnOff BinarySensor."""
|
||||||
|
|
||||||
SENSOR_ATTR = "on_off"
|
SENSOR_ATTR = "on_off"
|
||||||
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.OPENING
|
_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)
|
@MULTI_MATCH(channel_names=CHANNEL_BINARY_INPUT)
|
||||||
class BinaryInput(BinarySensor):
|
class BinaryInput(BinarySensor):
|
||||||
@ -144,10 +156,9 @@ class BinaryInput(BinarySensor):
|
|||||||
manufacturers="Philips",
|
manufacturers="Philips",
|
||||||
models={"SML001", "SML002"},
|
models={"SML001", "SML002"},
|
||||||
)
|
)
|
||||||
class Motion(BinarySensor):
|
class Motion(Opening):
|
||||||
"""ZHA BinarySensor."""
|
"""ZHA OnOff BinarySensor with motion device class."""
|
||||||
|
|
||||||
SENSOR_ATTR = "on_off"
|
|
||||||
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.MOTION
|
_attr_device_class: BinarySensorDeviceClass = BinarySensorDeviceClass.MOTION
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import zigpy.profiles.zha
|
import zigpy.profiles.zha
|
||||||
|
import zigpy.zcl.clusters.general as general
|
||||||
import zigpy.zcl.clusters.measurement as measurement
|
import zigpy.zcl.clusters.measurement as measurement
|
||||||
import zigpy.zcl.clusters.security as security
|
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)
|
@pytest.fixture(autouse=True)
|
||||||
def binary_sensor_platform_only():
|
def binary_sensor_platform_only():
|
||||||
"""Only set up the binary_sensor and required base platforms to speed up tests."""
|
"""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 entity_id is not None
|
||||||
assert hass.states.get(entity_id).state == STATE_ON # matches attribute cache
|
assert hass.states.get(entity_id).state == STATE_ON # matches attribute cache
|
||||||
assert hass.states.get(entity_id).attributes["migrated_to_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…
x
Reference in New Issue
Block a user