Fix handling of attribute reports in ZHA sensors and binary sensors (#32776)

* Update sensor tests.

* Update light tests.

* Update binary_sensor tests.

* Update cover tests.

* Update device tracker tests.

* Update fan tests.

* Update lock tests.

* Update switch tests.

* add sensor attr to sensors

* add sensor attr to binary sensors

* cleanup extra var

Co-authored-by: Alexei Chetroi <alexei.chetroi@outlook.com>
This commit is contained in:
David F. Mulcahey 2020-03-13 19:17:50 -04:00 committed by GitHub
parent 628f77f8f2
commit aa972b0005
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 77 additions and 104 deletions

View File

@ -64,6 +64,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class BinarySensor(ZhaEntity, BinarySensorDevice): class BinarySensor(ZhaEntity, BinarySensorDevice):
"""ZHA BinarySensor.""" """ZHA BinarySensor."""
SENSOR_ATTR = None
DEVICE_CLASS = None DEVICE_CLASS = None
def __init__(self, unique_id, zha_device, channels, **kwargs): def __init__(self, unique_id, zha_device, channels, **kwargs):
@ -105,6 +106,8 @@ class BinarySensor(ZhaEntity, BinarySensorDevice):
@callback @callback
def async_set_state(self, attr_id, attr_name, value): def async_set_state(self, attr_id, attr_name, value):
"""Set the state.""" """Set the state."""
if self.SENSOR_ATTR is None or self.SENSOR_ATTR != attr_name:
return
self._state = bool(value) self._state = bool(value)
self.async_write_ha_state() self.async_write_ha_state()
@ -121,6 +124,7 @@ class BinarySensor(ZhaEntity, BinarySensorDevice):
class Accelerometer(BinarySensor): class Accelerometer(BinarySensor):
"""ZHA BinarySensor.""" """ZHA BinarySensor."""
SENSOR_ATTR = "acceleration"
DEVICE_CLASS = DEVICE_CLASS_MOVING DEVICE_CLASS = DEVICE_CLASS_MOVING
@ -128,6 +132,7 @@ class Accelerometer(BinarySensor):
class Occupancy(BinarySensor): class Occupancy(BinarySensor):
"""ZHA BinarySensor.""" """ZHA BinarySensor."""
SENSOR_ATTR = "occupancy"
DEVICE_CLASS = DEVICE_CLASS_OCCUPANCY DEVICE_CLASS = DEVICE_CLASS_OCCUPANCY
@ -135,6 +140,7 @@ class Occupancy(BinarySensor):
class Opening(BinarySensor): class Opening(BinarySensor):
"""ZHA BinarySensor.""" """ZHA BinarySensor."""
SENSOR_ATTR = "on_off"
DEVICE_CLASS = DEVICE_CLASS_OPENING DEVICE_CLASS = DEVICE_CLASS_OPENING
@ -142,6 +148,8 @@ class Opening(BinarySensor):
class IASZone(BinarySensor): class IASZone(BinarySensor):
"""ZHA IAS BinarySensor.""" """ZHA IAS BinarySensor."""
SENSOR_ATTR = "zone_status"
async def get_device_class(self) -> None: async def get_device_class(self) -> None:
"""Get the HA device class from the channel.""" """Get the HA device class from the channel."""
zone_type = await self._channel.get_attribute_value("zone_type") zone_type = await self._channel.get_attribute_value("zone_type")

View File

@ -83,6 +83,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class Sensor(ZhaEntity): class Sensor(ZhaEntity):
"""Base ZHA sensor.""" """Base ZHA sensor."""
SENSOR_ATTR = None
_decimals = 1 _decimals = 1
_device_class = None _device_class = None
_divisor = 1 _divisor = 1
@ -126,6 +127,8 @@ class Sensor(ZhaEntity):
@callback @callback
def async_set_state(self, attr_id, attr_name, value): def async_set_state(self, attr_id, attr_name, value):
"""Handle state update from channel.""" """Handle state update from channel."""
if self.SENSOR_ATTR is None or self.SENSOR_ATTR != attr_name:
return
if value is not None: if value is not None:
value = self.formatter(value) value = self.formatter(value)
self._state = value self._state = value
@ -154,6 +157,7 @@ class Sensor(ZhaEntity):
class AnalogInput(Sensor): class AnalogInput(Sensor):
"""Sensor that displays analog input values.""" """Sensor that displays analog input values."""
SENSOR_ATTR = "present_value"
pass pass
@ -161,6 +165,7 @@ class AnalogInput(Sensor):
class Battery(Sensor): class Battery(Sensor):
"""Battery sensor of power configuration cluster.""" """Battery sensor of power configuration cluster."""
SENSOR_ATTR = "battery_percentage_remaining"
_device_class = DEVICE_CLASS_BATTERY _device_class = DEVICE_CLASS_BATTERY
_unit = UNIT_PERCENTAGE _unit = UNIT_PERCENTAGE
@ -198,6 +203,7 @@ class Battery(Sensor):
class ElectricalMeasurement(Sensor): class ElectricalMeasurement(Sensor):
"""Active power measurement.""" """Active power measurement."""
SENSOR_ATTR = "active_power"
_device_class = DEVICE_CLASS_POWER _device_class = DEVICE_CLASS_POWER
_divisor = 10 _divisor = 10
_unit = POWER_WATT _unit = POWER_WATT
@ -232,6 +238,7 @@ class Text(Sensor):
class Humidity(Sensor): class Humidity(Sensor):
"""Humidity sensor.""" """Humidity sensor."""
SENSOR_ATTR = "measured_value"
_device_class = DEVICE_CLASS_HUMIDITY _device_class = DEVICE_CLASS_HUMIDITY
_divisor = 100 _divisor = 100
_unit = UNIT_PERCENTAGE _unit = UNIT_PERCENTAGE
@ -241,6 +248,7 @@ class Humidity(Sensor):
class Illuminance(Sensor): class Illuminance(Sensor):
"""Illuminance Sensor.""" """Illuminance Sensor."""
SENSOR_ATTR = "measured_value"
_device_class = DEVICE_CLASS_ILLUMINANCE _device_class = DEVICE_CLASS_ILLUMINANCE
_unit = "lx" _unit = "lx"
@ -254,6 +262,7 @@ class Illuminance(Sensor):
class SmartEnergyMetering(Sensor): class SmartEnergyMetering(Sensor):
"""Metering sensor.""" """Metering sensor."""
SENSOR_ATTR = "instantaneous_demand"
_device_class = DEVICE_CLASS_POWER _device_class = DEVICE_CLASS_POWER
def formatter(self, value): def formatter(self, value):
@ -270,6 +279,7 @@ class SmartEnergyMetering(Sensor):
class Pressure(Sensor): class Pressure(Sensor):
"""Pressure sensor.""" """Pressure sensor."""
SENSOR_ATTR = "measured_value"
_device_class = DEVICE_CLASS_PRESSURE _device_class = DEVICE_CLASS_PRESSURE
_decimals = 0 _decimals = 0
_unit = "hPa" _unit = "hPa"
@ -279,6 +289,7 @@ class Pressure(Sensor):
class Temperature(Sensor): class Temperature(Sensor):
"""Temperature Sensor.""" """Temperature Sensor."""
SENSOR_ATTR = "measured_value"
_device_class = DEVICE_CLASS_TEMPERATURE _device_class = DEVICE_CLASS_TEMPERATURE
_divisor = 100 _divisor = 100
_unit = TEMP_CELSIUS _unit = TEMP_CELSIUS

View File

@ -102,6 +102,23 @@ def make_attribute(attrid, value, status=0):
return attr return attr
def send_attribute_report(hass, cluster, attrid, value):
"""Send a single attribute report."""
return send_attributes_report(hass, cluster, {attrid: value})
async def send_attributes_report(hass, cluster: int, attributes: dict):
"""Cause the sensor to receive an attribute report from the network.
This is to simulate the normal device communication that happens when a
device is paired to the zigbee network.
"""
attrs = [make_attribute(attrid, value) for attrid, value in attributes.items()]
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [attrs])
await hass.async_block_till_done()
async def find_entity_id(domain, zha_device, hass): async def find_entity_id(domain, zha_device, hass):
"""Find the entity id under the testing. """Find the entity id under the testing.

View File

@ -2,7 +2,6 @@
import pytest import pytest
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
import zigpy.zcl.foundation as zcl_f
from homeassistant.components.binary_sensor import DOMAIN from homeassistant.components.binary_sensor import DOMAIN
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
@ -11,8 +10,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
DEVICE_IAS = { DEVICE_IAS = {
@ -36,17 +34,11 @@ DEVICE_OCCUPANCY = {
async def async_test_binary_sensor_on_off(hass, cluster, entity_id): async def async_test_binary_sensor_on_off(hass, cluster, entity_id):
"""Test getting on and off messages for binary sensors.""" """Test getting on and off messages for binary sensors."""
# binary sensor on # binary sensor on
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: 0, 0: 1, 2: 2})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ON assert hass.states.get(entity_id).state == STATE_ON
# binary sensor off # binary sensor off
attr.value.value = 0 await send_attributes_report(hass, cluster, {1: 1, 0: 0, 2: 2})
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF

View File

@ -14,8 +14,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
from tests.common import mock_coro from tests.common import mock_coro
@ -64,19 +63,12 @@ async def test_cover(m1, hass, zha_device_joined_restored, zigpy_cover_device):
await async_enable_traffic(hass, [zha_device]) await async_enable_traffic(hass, [zha_device])
await hass.async_block_till_done() await hass.async_block_till_done()
attr = make_attribute(8, 100)
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
# test that the state has changed from unavailable to off # test that the state has changed from unavailable to off
await send_attributes_report(hass, cluster, {0: 0, 8: 100, 1: 1})
assert hass.states.get(entity_id).state == STATE_CLOSED assert hass.states.get(entity_id).state == STATE_CLOSED
# test to see if it opens # test to see if it opens
attr = make_attribute(8, 0) await send_attributes_report(hass, cluster, {0: 1, 8: 0, 1: 100})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_OPEN assert hass.states.get(entity_id).state == STATE_OPEN
# close from UI # close from UI

View File

@ -4,7 +4,6 @@ import time
import pytest import pytest
import zigpy.zcl.clusters.general as general import zigpy.zcl.clusters.general as general
import zigpy.zcl.foundation as zcl_f
from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER
from homeassistant.components.zha.core.registries import ( from homeassistant.components.zha.core.registries import (
@ -17,8 +16,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -66,12 +64,9 @@ async def test_device_tracker(hass, zha_device_joined_restored, zigpy_device_dt)
assert hass.states.get(entity_id).state == STATE_NOT_HOME assert hass.states.get(entity_id).state == STATE_NOT_HOME
# turn state flip # turn state flip
attr = make_attribute(0x0020, 23) await send_attributes_report(
hdr = make_zcl_header(zcl_f.Command.Report_Attributes) hass, cluster, {0x0000: 0, 0x0020: 23, 0x0021: 200, 0x0001: 2}
cluster.handle_message(hdr, [[attr]]) )
attr = make_attribute(0x0021, 200)
cluster.handle_message(hdr, [[attr]])
zigpy_device_dt.last_seen = time.time() + 10 zigpy_device_dt.last_seen = time.time() + 10
next_update = dt_util.utcnow() + timedelta(seconds=30) next_update = dt_util.utcnow() + timedelta(seconds=30)

View File

@ -3,7 +3,6 @@ from unittest.mock import call
import pytest import pytest
import zigpy.zcl.clusters.hvac as hvac import zigpy.zcl.clusters.hvac as hvac
import zigpy.zcl.foundation as zcl_f
from homeassistant.components import fan from homeassistant.components import fan
from homeassistant.components.fan import ATTR_SPEED, DOMAIN, SERVICE_SET_SPEED from homeassistant.components.fan import ATTR_SPEED, DOMAIN, SERVICE_SET_SPEED
@ -20,8 +19,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
@ -52,16 +50,11 @@ async def test_fan(hass, zha_device_joined_restored, zigpy_device):
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF
# turn on at fan # turn on at fan
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: 2, 0: 1, 2: 3})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ON assert hass.states.get(entity_id).state == STATE_ON
# turn off at fan # turn off at fan
attr.value.value = 0 await send_attributes_report(hass, cluster, {1: 1, 0: 0, 2: 2})
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF
# turn on from HA # turn on from HA

View File

@ -19,8 +19,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
from tests.common import async_fire_time_changed from tests.common import async_fire_time_changed
@ -190,26 +189,18 @@ async def test_light(
async def async_test_on_off_from_light(hass, cluster, entity_id): async def async_test_on_off_from_light(hass, cluster, entity_id):
"""Test on off functionality from the light.""" """Test on off functionality from the light."""
# turn on at light # turn on at light
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: 0, 0: 1, 2: 3})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ON assert hass.states.get(entity_id).state == STATE_ON
# turn off at light # turn off at light
attr.value.value = 0 await send_attributes_report(hass, cluster, {1: 1, 0: 0, 2: 3})
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF
async def async_test_on_from_light(hass, cluster, entity_id): async def async_test_on_from_light(hass, cluster, entity_id):
"""Test on off functionality from the light.""" """Test on off functionality from the light."""
# turn on at light # turn on at light
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: -1, 0: 1, 2: 2})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ON assert hass.states.get(entity_id).state == STATE_ON
@ -316,10 +307,10 @@ async def async_test_level_on_off_from_hass(
async def async_test_dimmer_from_light(hass, cluster, entity_id, level, expected_state): async def async_test_dimmer_from_light(hass, cluster, entity_id, level, expected_state):
"""Test dimmer functionality from the light.""" """Test dimmer functionality from the light."""
attr = make_attribute(0, level)
hdr = make_zcl_header(zcl_f.Command.Report_Attributes) await send_attributes_report(
cluster.handle_message(hdr, [[attr]]) hass, cluster, {1: level + 10, 0: level, 2: level - 10 or 22}
await hass.async_block_till_done() )
assert hass.states.get(entity_id).state == expected_state assert hass.states.get(entity_id).state == expected_state
# hass uses None for brightness of 0 in state attributes # hass uses None for brightness of 0 in state attributes
if level == 0: if level == 0:

View File

@ -10,12 +10,7 @@ import zigpy.zcl.foundation as zcl_f
from homeassistant.components.lock import DOMAIN from homeassistant.components.lock import DOMAIN
from homeassistant.const import STATE_LOCKED, STATE_UNAVAILABLE, STATE_UNLOCKED from homeassistant.const import STATE_LOCKED, STATE_UNAVAILABLE, STATE_UNLOCKED
from .common import ( from .common import async_enable_traffic, find_entity_id, send_attributes_report
async_enable_traffic,
find_entity_id,
make_attribute,
make_zcl_header,
)
from tests.common import mock_coro from tests.common import mock_coro
@ -58,16 +53,11 @@ async def test_lock(hass, lock):
assert hass.states.get(entity_id).state == STATE_UNLOCKED assert hass.states.get(entity_id).state == STATE_UNLOCKED
# set state to locked # set state to locked
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: 0, 0: 1, 2: 2})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_LOCKED assert hass.states.get(entity_id).state == STATE_LOCKED
# set state to unlocked # set state to unlocked
attr.value.value = 2 await send_attributes_report(hass, cluster, {1: 0, 0: 2, 2: 3})
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_UNLOCKED assert hass.states.get(entity_id).state == STATE_UNLOCKED
# lock from HA # lock from HA

View File

@ -6,7 +6,6 @@ import zigpy.zcl.clusters.general as general
import zigpy.zcl.clusters.homeautomation as homeautomation import zigpy.zcl.clusters.homeautomation as homeautomation
import zigpy.zcl.clusters.measurement as measurement import zigpy.zcl.clusters.measurement as measurement
import zigpy.zcl.clusters.smartenergy as smartenergy import zigpy.zcl.clusters.smartenergy as smartenergy
import zigpy.zcl.foundation as zcl_f
from homeassistant.components.sensor import DOMAIN from homeassistant.components.sensor import DOMAIN
import homeassistant.config as config_util import homeassistant.config as config_util
@ -28,38 +27,41 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attribute_report,
make_zcl_header, send_attributes_report,
) )
async def async_test_humidity(hass, cluster, entity_id): async def async_test_humidity(hass, cluster, entity_id):
"""Test humidity sensor.""" """Test humidity sensor."""
await send_attribute_report(hass, cluster, 0, 1000) await send_attributes_report(hass, cluster, {1: 1, 0: 1000, 2: 100})
assert_state(hass, entity_id, "10.0", UNIT_PERCENTAGE) assert_state(hass, entity_id, "10.0", UNIT_PERCENTAGE)
async def async_test_temperature(hass, cluster, entity_id): async def async_test_temperature(hass, cluster, entity_id):
"""Test temperature sensor.""" """Test temperature sensor."""
await send_attribute_report(hass, cluster, 0, 2900) await send_attributes_report(hass, cluster, {1: 1, 0: 2900, 2: 100})
assert_state(hass, entity_id, "29.0", "°C") assert_state(hass, entity_id, "29.0", "°C")
async def async_test_pressure(hass, cluster, entity_id): async def async_test_pressure(hass, cluster, entity_id):
"""Test pressure sensor.""" """Test pressure sensor."""
await send_attribute_report(hass, cluster, 0, 1000) await send_attributes_report(hass, cluster, {1: 1, 0: 1000, 2: 10000})
assert_state(hass, entity_id, "1000", "hPa")
await send_attributes_report(hass, cluster, {0: 1000, 20: -1, 16: 10000})
assert_state(hass, entity_id, "1000", "hPa") assert_state(hass, entity_id, "1000", "hPa")
async def async_test_illuminance(hass, cluster, entity_id): async def async_test_illuminance(hass, cluster, entity_id):
"""Test illuminance sensor.""" """Test illuminance sensor."""
await send_attribute_report(hass, cluster, 0, 10) await send_attributes_report(hass, cluster, {1: 1, 0: 10, 2: 20})
assert_state(hass, entity_id, "1.0", "lx") assert_state(hass, entity_id, "1.0", "lx")
async def async_test_metering(hass, cluster, entity_id): async def async_test_metering(hass, cluster, entity_id):
"""Test metering sensor.""" """Test metering sensor."""
await send_attribute_report(hass, cluster, 1024, 12345) await send_attributes_report(hass, cluster, {1025: 1, 1024: 12345, 1026: 100})
assert_state(hass, entity_id, "12345.0", "unknown") assert_state(hass, entity_id, "12345.0", "unknown")
@ -73,17 +75,17 @@ async def async_test_electrical_measurement(hass, cluster, entity_id):
new_callable=mock.PropertyMock, new_callable=mock.PropertyMock,
) as divisor_mock: ) as divisor_mock:
divisor_mock.return_value = 1 divisor_mock.return_value = 1
await send_attribute_report(hass, cluster, 1291, 100) await send_attributes_report(hass, cluster, {0: 1, 1291: 100, 10: 1000})
assert_state(hass, entity_id, "100", "W") assert_state(hass, entity_id, "100", "W")
await send_attribute_report(hass, cluster, 1291, 99) await send_attributes_report(hass, cluster, {0: 1, 1291: 99, 10: 1000})
assert_state(hass, entity_id, "99", "W") assert_state(hass, entity_id, "99", "W")
divisor_mock.return_value = 10 divisor_mock.return_value = 10
await send_attribute_report(hass, cluster, 1291, 1000) await send_attributes_report(hass, cluster, {0: 1, 1291: 1000, 10: 5000})
assert_state(hass, entity_id, "100", "W") assert_state(hass, entity_id, "100", "W")
await send_attribute_report(hass, cluster, 1291, 99) await send_attributes_report(hass, cluster, {0: 1, 1291: 99, 10: 5000})
assert_state(hass, entity_id, "9.9", "W") assert_state(hass, entity_id, "9.9", "W")
@ -141,18 +143,6 @@ async def test_sensor(
await async_test_rejoin(hass, zigpy_device, [cluster], (report_count,)) await async_test_rejoin(hass, zigpy_device, [cluster], (report_count,))
async def send_attribute_report(hass, cluster, attrid, value):
"""Cause the sensor to receive an attribute report from the network.
This is to simulate the normal device communication that happens when a
device is paired to the zigbee network.
"""
attr = make_attribute(attrid, value)
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
def assert_state(hass, entity_id, state, unit_of_measurement): def assert_state(hass, entity_id, state, unit_of_measurement):
"""Check that the state is what is expected. """Check that the state is what is expected.

View File

@ -12,8 +12,7 @@ from .common import (
async_enable_traffic, async_enable_traffic,
async_test_rejoin, async_test_rejoin,
find_entity_id, find_entity_id,
make_attribute, send_attributes_report,
make_zcl_header,
) )
from tests.common import mock_coro from tests.common import mock_coro
@ -53,16 +52,11 @@ async def test_switch(hass, zha_device_joined_restored, zigpy_device):
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF
# turn on at switch # turn on at switch
attr = make_attribute(0, 1) await send_attributes_report(hass, cluster, {1: 0, 0: 1, 2: 2})
hdr = make_zcl_header(zcl_f.Command.Report_Attributes)
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ON assert hass.states.get(entity_id).state == STATE_ON
# turn off at switch # turn off at switch
attr.value.value = 0 await send_attributes_report(hass, cluster, {1: 1, 0: 0, 2: 2})
cluster.handle_message(hdr, [[attr]])
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_OFF assert hass.states.get(entity_id).state == STATE_OFF
# turn on from HA # turn on from HA