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, discovery.async_add_entities,
async_add_entities, async_add_entities,
entities_to_create, entities_to_create,
update_before_add=False,
), ),
) )
config_entry.async_on_unload(unsub) config_entry.async_on_unload(unsub)

View File

@ -54,14 +54,13 @@ async def async_add_entities(
tuple[str, ZHADevice, list[base.ZigbeeChannel]], tuple[str, ZHADevice, list[base.ZigbeeChannel]],
] ]
], ],
update_before_add: bool = True,
) -> None: ) -> None:
"""Add entities helper.""" """Add entities helper."""
if not entities: if not entities:
return return
to_add = [ent_cls.create_entity(*args) for ent_cls, args in entities] 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] 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() entities.clear()

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from enum import Enum from enum import Enum
import functools import functools
import logging
from zigpy.zcl.clusters.general import OnOff from zigpy.zcl.clusters.general import OnOff
from zigpy.zcl.clusters.security import IasWd from zigpy.zcl.clusters.security import IasWd
@ -30,6 +31,7 @@ from .entity import ZhaEntity
CONFIG_DIAGNOSTIC_MATCH = functools.partial( CONFIG_DIAGNOSTIC_MATCH = functools.partial(
ZHA_ENTITIES.config_diagnostic_match, Platform.SELECT ZHA_ENTITIES.config_diagnostic_match, Platform.SELECT
) )
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry( async def async_setup_entry(
@ -47,7 +49,6 @@ async def async_setup_entry(
discovery.async_add_entities, discovery.async_add_entities,
async_add_entities, async_add_entities,
entities_to_create, entities_to_create,
update_before_add=False,
), ),
) )
config_entry.async_on_unload(unsub) 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 Return entity if it is a supported configuration, otherwise return None
""" """
channel = channels[0] 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 None
return cls(unique_id, zha_device, channels, **kwargs) return cls(unique_id, zha_device, channels, **kwargs)

View File

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

View File

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

View File

@ -104,17 +104,14 @@ def zigpy_keen_vent(zigpy_device_mock):
) )
@patch( async def test_cover(hass, zha_device_joined_restored, zigpy_cover_device):
"homeassistant.components.zha.core.channels.closures.WindowCovering.async_initialize"
)
async def test_cover(m1, hass, zha_device_joined_restored, zigpy_cover_device):
"""Test zha cover platform.""" """Test zha cover platform."""
# load up cover domain # load up cover domain
cluster = zigpy_cover_device.endpoints.get(1).window_covering cluster = zigpy_cover_device.endpoints.get(1).window_covering
cluster.PLUGGED_ATTR_READS = {"current_position_lift_percentage": 100} cluster.PLUGGED_ATTR_READS = {"current_position_lift_percentage": 100}
zha_device = await zha_device_joined_restored(zigpy_cover_device) 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] assert "current_position_lift_percentage" in cluster.read_attributes.call_args[0][0]
entity_id = await find_entity_id(Platform.COVER, zha_device, hass) 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 assert cluster.request.call_args[1]["expect_reply"] is True
# test rejoin # test rejoin
cluster.PLUGGED_ATTR_READS = {"current_position_lift_percentage": 0}
await async_test_rejoin(hass, zigpy_cover_device, [cluster], (1,)) await async_test_rejoin(hass, zigpy_cover_device, [cluster], (1,))
assert hass.states.get(entity_id).state == STATE_OPEN 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) entity_id = await find_entity_id(Platform.DEVICE_TRACKER, zha_device, hass)
assert entity_id is not None 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) await async_enable_traffic(hass, [zha_device], enabled=False)
# test that the device tracker was created and that it is unavailable # test that the device tracker was created and that it is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE assert hass.states.get(entity_id).state == STATE_UNAVAILABLE

View File

@ -1,5 +1,7 @@
"""Test ZHA select entities.""" """Test ZHA select entities."""
from unittest.mock import call
import pytest import pytest
from zigpy.const import SIG_EP_PROFILE from zigpy.const import SIG_EP_PROFILE
import zigpy.profiles.zha as zha import zigpy.profiles.zha as zha
@ -50,6 +52,7 @@ async def light(hass, zigpy_device_mock):
SIG_EP_OUTPUT: [general.Ota.cluster_id], SIG_EP_OUTPUT: [general.Ota.cluster_id],
} }
}, },
node_descriptor=b"\x02@\x84_\x11\x7fd\x00\x00,d\x00\x00",
) )
return zigpy_device return zigpy_device
@ -173,15 +176,15 @@ async def test_select_restore_state(
assert state.state == security.IasWd.Warning.WarningMode.Burglar.name assert state.state == security.IasWd.Warning.WarningMode.Burglar.name
async def test_on_off_select(hass, light, zha_device_joined_restored): async def test_on_off_select_new_join(hass, light, zha_device_joined):
"""Test zha on off select.""" """Test zha on off select - new join."""
entity_registry = er.async_get(hass) entity_registry = er.async_get(hass)
on_off_cluster = light.endpoints[1].on_off on_off_cluster = light.endpoints[1].on_off
on_off_cluster.PLUGGED_ATTR_READS = { on_off_cluster.PLUGGED_ATTR_READS = {
"start_up_on_off": general.OnOff.StartUpOnOff.On "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__ select_name = general.OnOff.StartUpOnOff.__name__
entity_id = await find_entity_id( entity_id = await find_entity_id(
Platform.SELECT, 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 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) state = hass.states.get(entity_id)
assert state assert state
if zha_device_joined_restored.name == "zha_device_joined": assert state.state == general.OnOff.StartUpOnOff.On.name
assert state.state == general.OnOff.StartUpOnOff.On.name
else:
assert state.state == STATE_UNKNOWN
assert state.attributes["options"] == ["Off", "On", "Toggle", "PreviousValue"] 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 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): async def test_on_off_select_unsupported(hass, light, zha_device_joined_restored):
"""Test zha on off select unsupported.""" """Test zha on off select unsupported."""