Don't set entity_id in ZHA entities (#28362)

* Don't set entity_id on ZHA entities.
* Update tests.
* Use comma as separator for multiple channel names.
* Address PR comments.
This commit is contained in:
Alexei Chetroi 2019-10-31 12:31:06 -04:00 committed by GitHub
parent d133501735
commit 89213a4ce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 66 deletions

View File

@ -9,7 +9,6 @@ from homeassistant.helpers import entity
from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.util import slugify
from .core.const import (
ATTR_MANUFACTURER,
@ -38,17 +37,10 @@ class ZhaEntity(RestoreEntity, LogMixin, entity.Entity):
self._force_update = False
self._should_poll = False
self._unique_id = unique_id
if not skip_entity_id:
ieee = zha_device.ieee
ieeetail = "".join([f"{o:02x}" for o in ieee[:4]])
self.entity_id = "{}.{}_{}_{}_{}{}".format(
self._domain,
slugify(zha_device.manufacturer),
slugify(zha_device.model),
ieeetail,
channels[0].cluster.endpoint.endpoint_id,
kwargs.get(ENTITY_SUFFIX, ""),
)
ieeetail = "".join([f"{o:02x}" for o in zha_device.ieee[:4]])
ch_names = [ch.cluster.ep_attribute for ch in channels]
ch_names = ", ".join(sorted(ch_names))
self._name = f"{zha_device.name} {ieeetail} {ch_names}"
self._state = None
self._device_state_attributes = {}
self._zha_device = zha_device
@ -63,7 +55,7 @@ class ZhaEntity(RestoreEntity, LogMixin, entity.Entity):
@property
def name(self):
"""Return Entity's default name."""
return self.zha_device.name
return self._name
@property
def unique_id(self) -> str:

View File

@ -161,23 +161,22 @@ async def async_setup_entry(hass, config_entry):
return True
def make_entity_id(domain, device, cluster, use_suffix=True):
"""Make the entity id for the entity under testing.
async def find_entity_id(domain, zha_device, hass):
"""Find the entity id under the testing.
This is used to get the entity id in order to get the state from the state
machine so that we can test state changes.
"""
ieee = device.ieee
ieeetail = "".join([f"{o:02x}" for o in ieee[:4]])
entity_id = "{}.{}_{}_{}_{}{}".format(
domain,
slugify(device.manufacturer),
slugify(device.model),
ieeetail,
cluster.endpoint.endpoint_id,
("", "_{}".format(cluster.cluster_id))[use_suffix],
)
return entity_id
ieeetail = "".join([f"{o:02x}" for o in zha_device.ieee[:4]])
head = f"{domain}." + slugify(f"{zha_device.name} {ieeetail}")
enitiy_ids = hass.states.async_entity_ids(domain)
await hass.async_block_till_done()
for entity_id in enitiy_ids:
if entity_id.startswith(head):
return entity_id
return None
async def async_enable_traffic(hass, zha_gateway, zha_devices):
@ -188,7 +187,7 @@ async def async_enable_traffic(hass, zha_gateway, zha_devices):
async def async_test_device_join(
hass, zha_gateway, cluster_id, domain, device_type=None
hass, zha_gateway, cluster_id, entity_id, device_type=None
):
"""Test a newly joining device.
@ -205,21 +204,15 @@ async def async_test_device_join(
"zigpy.zcl.Cluster.bind",
return_value=mock_coro([zcl_f.Status.SUCCESS, zcl_f.Status.SUCCESS]),
):
zigpy_device = await async_init_zigpy_device(
await async_init_zigpy_device(
hass,
[cluster_id, zigpy.zcl.clusters.general.Basic.cluster_id],
[],
device_type,
zha_gateway,
ieee="00:0d:6f:00:0a:90:69:f7",
manufacturer="FakeMan{}".format(cluster_id),
model="FakeMod{}".format(cluster_id),
is_new_join=True,
)
cluster = zigpy_device.endpoints.get(1).in_clusters[cluster_id]
entity_id = make_entity_id(
domain, zigpy_device, cluster, use_suffix=device_type is None
)
assert hass.states.get(entity_id) is not None

View File

@ -11,8 +11,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -27,6 +27,7 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
[],
None,
zha_gateway,
ieee="00:0d:6f:11:9a:90:69:e6",
)
zigpy_device_occupancy = await async_init_zigpy_device(
@ -46,15 +47,15 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
# on off binary_sensor
zone_cluster = zigpy_device_zone.endpoints.get(1).ias_zone
zone_entity_id = make_entity_id(DOMAIN, zigpy_device_zone, zone_cluster)
zone_zha_device = zha_gateway.get_device(zigpy_device_zone.ieee)
zone_entity_id = await find_entity_id(DOMAIN, zone_zha_device, hass)
assert zone_entity_id is not None
# occupancy binary_sensor
occupancy_cluster = zigpy_device_occupancy.endpoints.get(1).occupancy
occupancy_entity_id = make_entity_id(
DOMAIN, zigpy_device_occupancy, occupancy_cluster
)
occupancy_zha_device = zha_gateway.get_device(zigpy_device_occupancy.ieee)
occupancy_entity_id = await find_entity_id(DOMAIN, occupancy_zha_device, hass)
assert occupancy_entity_id is not None
# test that the sensors exist and are in the unavailable state
assert hass.states.get(zone_entity_id).state == STATE_UNAVAILABLE
@ -76,7 +77,7 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
# test new sensor join
await async_test_device_join(
hass, zha_gateway, measurement.OccupancySensing.cluster_id, DOMAIN
hass, zha_gateway, measurement.OccupancySensing.cluster_id, occupancy_entity_id
)

View File

@ -16,8 +16,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -47,8 +47,9 @@ async def test_device_tracker(hass, config_entry, zha_gateway):
await hass.async_block_till_done()
cluster = zigpy_device.endpoints.get(1).power
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster, use_suffix=False)
zha_device = zha_gateway.get_device(zigpy_device.ieee)
entity_id = await find_entity_id(DOMAIN, zha_device, hass)
assert entity_id is not None
# test that the device tracker was created and that it is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
@ -90,6 +91,6 @@ async def test_device_tracker(hass, config_entry, zha_gateway):
hass,
zha_gateway,
general.PowerConfiguration.cluster_id,
DOMAIN,
entity_id,
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE,
)

View File

@ -20,8 +20,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -41,8 +41,9 @@ async def test_fan(hass, config_entry, zha_gateway):
await hass.async_block_till_done()
cluster = zigpy_device.endpoints.get(1).fan
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
zha_device = zha_gateway.get_device(zigpy_device.ieee)
entity_id = await find_entity_id(DOMAIN, zha_device, hass)
assert entity_id is not None
# test that the fan was created and that it is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
@ -97,7 +98,7 @@ async def test_fan(hass, config_entry, zha_gateway):
assert cluster.write_attributes.call_args == call({"fan_mode": 3})
# test adding new fan to the network and HA
await async_test_device_join(hass, zha_gateway, hvac.Fan.cluster_id, DOMAIN)
await async_test_device_join(hass, zha_gateway, hvac.Fan.cluster_id, entity_id)
async def async_turn_on(hass, entity_id, speed=None):

View File

@ -14,8 +14,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -35,6 +35,7 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
[],
zigpy.profiles.zha.DeviceType.ON_OFF_LIGHT,
zha_gateway,
ieee="00:0d:6f:11:0a:90:69:e6",
)
zigpy_device_level = await async_init_zigpy_device(
@ -58,10 +59,9 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
# on off light
on_off_device_on_off_cluster = zigpy_device_on_off.endpoints.get(1).on_off
on_off_entity_id = make_entity_id(
DOMAIN, zigpy_device_on_off, on_off_device_on_off_cluster, use_suffix=False
)
on_off_zha_device = zha_gateway.get_device(zigpy_device_on_off.ieee)
on_off_entity_id = await find_entity_id(DOMAIN, on_off_zha_device, hass)
assert on_off_entity_id is not None
# dimmable light
level_device_on_off_cluster = zigpy_device_level.endpoints.get(1).on_off
@ -78,10 +78,9 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
)
monkeypatch.setattr(level_device_on_off_cluster, "request", on_off_mock)
monkeypatch.setattr(level_device_level_cluster, "request", level_mock)
level_entity_id = make_entity_id(
DOMAIN, zigpy_device_level, level_device_on_off_cluster, use_suffix=False
)
level_zha_device = zha_gateway.get_device(zigpy_device_level.ieee)
level_entity_id = await find_entity_id(DOMAIN, level_zha_device, hass)
assert level_entity_id is not None
# test that the lights were created and that they are unavailable
assert hass.states.get(on_off_entity_id).state == STATE_UNAVAILABLE
@ -125,7 +124,7 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
hass,
zha_gateway,
general.OnOff.cluster_id,
DOMAIN,
on_off_entity_id,
device_type=zigpy.profiles.zha.DeviceType.ON_OFF_LIGHT,
)

View File

@ -11,8 +11,8 @@ from homeassistant.const import STATE_LOCKED, STATE_UNAVAILABLE, STATE_UNLOCKED
from .common import (
async_enable_traffic,
async_init_zigpy_device,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -39,8 +39,9 @@ async def test_lock(hass, config_entry, zha_gateway):
await hass.async_block_till_done()
cluster = zigpy_device.endpoints.get(1).door_lock
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
zha_device = zha_gateway.get_device(zigpy_device.ieee)
entity_id = await find_entity_id(DOMAIN, zha_device, hass)
assert entity_id is not None
# test that the lock was created and that it is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE

View File

@ -12,8 +12,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -85,7 +85,7 @@ async def test_sensor(hass, config_entry, zha_gateway):
# test joining a new temperature sensor to the network
await async_test_device_join(
hass, zha_gateway, measurement.TemperatureMeasurement.cluster_id, DOMAIN
hass, zha_gateway, measurement.TemperatureMeasurement.cluster_id, entity_id
)
@ -110,7 +110,7 @@ async def async_build_devices(hass, zha_gateway, config_entry, cluster_ids):
[],
None,
zha_gateway,
ieee="{}0:15:8d:00:02:32:4f:32".format(counter),
ieee="00:15:8d:00:02:32:4f:0{}".format(counter),
manufacturer="Fake{}".format(cluster_id),
model="FakeModel{}".format(cluster_id),
)
@ -126,10 +126,10 @@ async def async_build_devices(hass, zha_gateway, config_entry, cluster_ids):
device_info = device_infos[cluster_id]
zigpy_device = device_info["zigpy_device"]
device_info["cluster"] = zigpy_device.endpoints.get(1).in_clusters[cluster_id]
device_info["entity_id"] = make_entity_id(
DOMAIN, zigpy_device, device_info["cluster"]
)
device_info["zha_device"] = zha_gateway.get_device(zigpy_device.ieee)
zha_device = zha_gateway.get_device(zigpy_device.ieee)
device_info["zha_device"] = zha_device
device_info["entity_id"] = await find_entity_id(DOMAIN, zha_device, hass)
await hass.async_block_till_done()
return device_infos

View File

@ -11,8 +11,8 @@ from .common import (
async_enable_traffic,
async_init_zigpy_device,
async_test_device_join,
find_entity_id,
make_attribute,
make_entity_id,
make_zcl_header,
)
@ -39,8 +39,9 @@ async def test_switch(hass, config_entry, zha_gateway):
await hass.async_block_till_done()
cluster = zigpy_device.endpoints.get(1).on_off
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
zha_device = zha_gateway.get_device(zigpy_device.ieee)
entity_id = await find_entity_id(DOMAIN, zha_device, hass)
assert entity_id is not None
# test that the switch was created and that its state is unavailable
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
@ -93,4 +94,4 @@ async def test_switch(hass, config_entry, zha_gateway):
)
# test joining a new switch to the network and HA
await async_test_device_join(hass, zha_gateway, general.OnOff.cluster_id, DOMAIN)
await async_test_device_join(hass, zha_gateway, general.OnOff.cluster_id, entity_id)