Remove unnecessary update_before_add from ZHA (#71010)

* Additional streamlining for ZHA entity init

* fix tests
This commit is contained in:
David F. Mulcahey 2022-04-28 14:57:26 -04:00 committed by GitHub
parent 64fc93ba5f
commit 1eb5316d89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 86 additions and 22 deletions

View File

@ -41,7 +41,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)

View File

@ -54,14 +54,13 @@ async def async_add_entities(
tuple[str, ZHADevice, list[base.ZigbeeChannel]],
]
],
update_before_add: bool = True,
) -> None:
"""Add entities helper."""
if not entities:
return
to_add = [ent_cls.create_entity(*args) for ent_cls, args in entities]
entities_to_add = [entity for entity in to_add if entity is not None]
_async_add_entities(entities_to_add, update_before_add=update_before_add)
_async_add_entities(entities_to_add, update_before_add=False)
entities.clear()

View File

@ -291,6 +291,7 @@ class ZhaGroupEntity(BaseZhaEntity):
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
await self.async_update()
self.async_accept_signal(
None,

View File

@ -67,7 +67,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)

View File

@ -250,7 +250,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from enum import Enum
import functools
import logging
from zigpy.zcl.clusters.general import OnOff
from zigpy.zcl.clusters.security import IasWd
@ -30,6 +31,7 @@ from .entity import ZhaEntity
CONFIG_DIAGNOSTIC_MATCH = functools.partial(
ZHA_ENTITIES.config_diagnostic_match, Platform.SELECT
)
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
@ -47,7 +49,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)
@ -163,7 +164,15 @@ class ZCLEnumSelectEntity(ZhaEntity, SelectEntity):
Return entity if it is a supported configuration, otherwise return None
"""
channel = channels[0]
if cls._select_attr in channel.cluster.unsupported_attributes:
if (
cls._select_attr in channel.cluster.unsupported_attributes
or channel.cluster.get(cls._select_attr) is None
):
_LOGGER.debug(
"%s is not supported - skipping %s entity creation",
cls._select_attr,
cls.__name__,
)
return None
return cls(unique_id, zha_device, channels, **kwargs)

View File

@ -103,7 +103,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)

View File

@ -60,7 +60,6 @@ async def async_setup_entry(
discovery.async_add_entities,
async_add_entities,
entities_to_create,
update_before_add=False,
),
)
config_entry.async_on_unload(unsub)

View File

@ -104,17 +104,14 @@ def zigpy_keen_vent(zigpy_device_mock):
)
@patch(
"homeassistant.components.zha.core.channels.closures.WindowCovering.async_initialize"
)
async def test_cover(m1, hass, zha_device_joined_restored, zigpy_cover_device):
async def test_cover(hass, zha_device_joined_restored, zigpy_cover_device):
"""Test zha cover platform."""
# load up cover domain
cluster = zigpy_cover_device.endpoints.get(1).window_covering
cluster.PLUGGED_ATTR_READS = {"current_position_lift_percentage": 100}
zha_device = await zha_device_joined_restored(zigpy_cover_device)
assert cluster.read_attributes.call_count == 2
assert cluster.read_attributes.call_count == 1
assert "current_position_lift_percentage" in cluster.read_attributes.call_args[0][0]
entity_id = await find_entity_id(Platform.COVER, zha_device, hass)
@ -193,6 +190,7 @@ async def test_cover(m1, hass, zha_device_joined_restored, zigpy_cover_device):
assert cluster.request.call_args[1]["expect_reply"] is True
# test rejoin
cluster.PLUGGED_ATTR_READS = {"current_position_lift_percentage": 0}
await async_test_rejoin(hass, zigpy_cover_device, [cluster], (1,))
assert hass.states.get(entity_id).state == STATE_OPEN

View File

@ -52,7 +52,7 @@ async def test_device_tracker(hass, zha_device_joined_restored, zigpy_device_dt)
entity_id = await find_entity_id(Platform.DEVICE_TRACKER, zha_device, hass)
assert entity_id is not None
assert hass.states.get(entity_id).state == STATE_HOME
assert hass.states.get(entity_id).state == STATE_NOT_HOME
await async_enable_traffic(hass, [zha_device], enabled=False)
# test that the device tracker was created and that it is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE

View File

@ -1,5 +1,7 @@
"""Test ZHA select entities."""
from unittest.mock import call
import pytest
from zigpy.const import SIG_EP_PROFILE
import zigpy.profiles.zha as zha
@ -50,6 +52,7 @@ async def light(hass, zigpy_device_mock):
SIG_EP_OUTPUT: [general.Ota.cluster_id],
}
},
node_descriptor=b"\x02@\x84_\x11\x7fd\x00\x00,d\x00\x00",
)
return zigpy_device
@ -173,15 +176,15 @@ async def test_select_restore_state(
assert state.state == security.IasWd.Warning.WarningMode.Burglar.name
async def test_on_off_select(hass, light, zha_device_joined_restored):
"""Test zha on off select."""
async def test_on_off_select_new_join(hass, light, zha_device_joined):
"""Test zha on off select - new join."""
entity_registry = er.async_get(hass)
on_off_cluster = light.endpoints[1].on_off
on_off_cluster.PLUGGED_ATTR_READS = {
"start_up_on_off": general.OnOff.StartUpOnOff.On
}
zha_device = await zha_device_joined_restored(light)
zha_device = await zha_device_joined(light)
select_name = general.OnOff.StartUpOnOff.__name__
entity_id = await find_entity_id(
Platform.SELECT,
@ -191,12 +194,19 @@ async def test_on_off_select(hass, light, zha_device_joined_restored):
)
assert entity_id is not None
assert on_off_cluster.read_attributes.call_count == 2
assert (
call(["start_up_on_off"], allow_cache=True, only_cache=False, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
assert (
call(["on_off"], allow_cache=False, only_cache=False, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
state = hass.states.get(entity_id)
assert state
if zha_device_joined_restored.name == "zha_device_joined":
assert state.state == general.OnOff.StartUpOnOff.On.name
else:
assert state.state == STATE_UNKNOWN
assert state.state == general.OnOff.StartUpOnOff.On.name
assert state.attributes["options"] == ["Off", "On", "Toggle", "PreviousValue"]
@ -225,6 +235,58 @@ async def test_on_off_select(hass, light, zha_device_joined_restored):
assert state.state == general.OnOff.StartUpOnOff.Off.name
async def test_on_off_select_restored(hass, light, zha_device_restored):
"""Test zha on off select - restored."""
entity_registry = er.async_get(hass)
on_off_cluster = light.endpoints[1].on_off
on_off_cluster.PLUGGED_ATTR_READS = {
"start_up_on_off": general.OnOff.StartUpOnOff.On
}
zha_device = await zha_device_restored(light)
assert zha_device.is_mains_powered
assert on_off_cluster.read_attributes.call_count == 4
# first 2 calls hit cache only
assert (
call(["start_up_on_off"], allow_cache=True, only_cache=True, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
assert (
call(["on_off"], allow_cache=True, only_cache=True, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
# 2nd set of calls can actually read from the device
assert (
call(["start_up_on_off"], allow_cache=True, only_cache=False, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
assert (
call(["on_off"], allow_cache=False, only_cache=False, manufacturer=None)
in on_off_cluster.read_attributes.call_args_list
)
select_name = general.OnOff.StartUpOnOff.__name__
entity_id = await find_entity_id(
Platform.SELECT,
zha_device,
hass,
qualifier=select_name.lower(),
)
assert entity_id is not None
state = hass.states.get(entity_id)
assert state
assert state.state == general.OnOff.StartUpOnOff.On.name
assert state.attributes["options"] == ["Off", "On", "Toggle", "PreviousValue"]
entity_entry = entity_registry.async_get(entity_id)
assert entity_entry
assert entity_entry.entity_category == ENTITY_CATEGORY_CONFIG
async def test_on_off_select_unsupported(hass, light, zha_device_joined_restored):
"""Test zha on off select unsupported."""