Fix switch_as_x name (#91232)

This commit is contained in:
Erik Montnemery 2023-04-11 19:54:30 +02:00 committed by GitHub
parent aa68d1d617
commit eb63bc7967
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 176 additions and 8 deletions

View file

@ -3,7 +3,11 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.cover import CoverEntity, CoverEntityFeature
from homeassistant.components.cover import (
DOMAIN as COVER_DOMAIN,
CoverEntity,
CoverEntityFeature,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
@ -36,6 +40,7 @@ async def async_setup_entry(
CoverSwitch(
hass,
config_entry.title,
COVER_DOMAIN,
entity_id,
config_entry.entry_id,
)

View file

@ -23,13 +23,15 @@ class BaseEntity(Entity):
"""Represents a Switch as an X."""
_attr_should_poll = False
_is_new_entity: bool
def __init__(
self,
hass: HomeAssistant,
config_entry_title: str,
domain: str,
switch_entity_id: str,
unique_id: str | None,
unique_id: str,
) -> None:
"""Initialize Switch as an X."""
registry = er.async_get(hass)
@ -41,7 +43,7 @@ class BaseEntity(Entity):
name: str | None = config_entry_title
if wrapped_switch:
name = wrapped_switch.name or wrapped_switch.original_name
name = wrapped_switch.original_name
self._device_id = device_id
if device_id and (device := device_registry.async_get(device_id)):
@ -55,6 +57,10 @@ class BaseEntity(Entity):
self._attr_unique_id = unique_id
self._switch_entity_id = switch_entity_id
self._is_new_entity = (
registry.async_get_entity_id(domain, SWITCH_AS_X_DOMAIN, unique_id) is None
)
@callback
def async_state_changed_listener(self, event: Event | None = None) -> None:
"""Handle child updates."""
@ -67,7 +73,7 @@ class BaseEntity(Entity):
self._attr_available = True
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
"""Register callbacks and copy the wrapped entity's custom name if set."""
@callback
def _async_state_changed_listener(event: Event | None = None) -> None:
@ -93,6 +99,15 @@ class BaseEntity(Entity):
{"entity_id": self._switch_entity_id},
)
if not self._is_new_entity:
return
wrapped_switch = registry.async_get(self._switch_entity_id)
if not wrapped_switch or wrapped_switch.name is None:
return
registry.async_update_entity(self.entity_id, name=wrapped_switch.name)
class BaseToggleEntity(BaseEntity, ToggleEntity):
"""Represents a Switch as a ToggleEntity."""

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.fan import FanEntity
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN, FanEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ENTITY_ID
from homeassistant.core import HomeAssistant
@ -29,6 +29,7 @@ async def async_setup_entry(
FanSwitch(
hass,
config_entry.title,
FAN_DOMAIN,
entity_id,
config_entry.entry_id,
)

View file

@ -1,7 +1,11 @@
"""Light support for switch entities."""
from __future__ import annotations
from homeassistant.components.light import ColorMode, LightEntity
from homeassistant.components.light import (
DOMAIN as LIGHT_DOMAIN,
ColorMode,
LightEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ENTITY_ID
from homeassistant.core import HomeAssistant
@ -27,6 +31,7 @@ async def async_setup_entry(
LightSwitch(
hass,
config_entry.title,
LIGHT_DOMAIN,
entity_id,
config_entry.entry_id,
)

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.lock import LockEntity
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN, LockEntity
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
@ -36,6 +36,7 @@ async def async_setup_entry(
LockSwitch(
hass,
config_entry.title,
LOCK_DOMAIN,
entity_id,
config_entry.entry_id,
)

View file

@ -1,7 +1,11 @@
"""Siren support for switch entities."""
from __future__ import annotations
from homeassistant.components.siren import SirenEntity, SirenEntityFeature
from homeassistant.components.siren import (
DOMAIN as SIREN_DOMAIN,
SirenEntity,
SirenEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ENTITY_ID
from homeassistant.core import HomeAssistant
@ -27,6 +31,7 @@ async def async_setup_entry(
SirenSwitch(
hass,
config_entry.title,
SIREN_DOMAIN,
entity_id,
config_entry.entry_id,
)

View file

@ -534,7 +534,143 @@ async def test_entity_name(
assert entity_entry
assert entity_entry.device_id == switch_entity_entry.device_id
assert entity_entry.has_entity_name is True
assert entity_entry.name is None
assert entity_entry.original_name is None
assert entity_entry.options == {
DOMAIN: {"entity_id": switch_entity_entry.entity_id}
}
@pytest.mark.parametrize("target_domain", PLATFORMS_TO_TEST)
async def test_custom_name_1(
hass: HomeAssistant,
target_domain: Platform,
) -> None:
"""Test the source entity has a custom name."""
registry = er.async_get(hass)
device_registry = dr.async_get(hass)
switch_config_entry = MockConfigEntry()
device_entry = device_registry.async_get_or_create(
config_entry_id=switch_config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
name="Device name",
)
switch_entity_entry = registry.async_get_or_create(
"switch",
"test",
"unique",
device_id=device_entry.id,
has_entity_name=True,
original_name="Original entity name",
)
switch_entity_entry = registry.async_update_entity(
switch_entity_entry.entity_id,
config_entry_id=switch_config_entry.entry_id,
name="Custom entity name",
)
# Add the config entry
switch_as_x_config_entry = MockConfigEntry(
data={},
domain=DOMAIN,
options={
CONF_ENTITY_ID: switch_entity_entry.id,
CONF_TARGET_DOMAIN: target_domain,
},
title="ABC",
)
switch_as_x_config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id)
await hass.async_block_till_done()
entity_entry = registry.async_get(
f"{target_domain}.device_name_original_entity_name"
)
assert entity_entry
assert entity_entry.device_id == switch_entity_entry.device_id
assert entity_entry.has_entity_name is True
assert entity_entry.name == "Custom entity name"
assert entity_entry.original_name == "Original entity name"
assert entity_entry.options == {
DOMAIN: {"entity_id": switch_entity_entry.entity_id}
}
@pytest.mark.parametrize("target_domain", PLATFORMS_TO_TEST)
async def test_custom_name_2(
hass: HomeAssistant,
target_domain: Platform,
) -> None:
"""Test the source entity has a custom name.
This tests the custom name is only copied from the source device when the config
switch_as_x config entry is setup the first time.
"""
registry = er.async_get(hass)
device_registry = dr.async_get(hass)
switch_config_entry = MockConfigEntry()
device_entry = device_registry.async_get_or_create(
config_entry_id=switch_config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
name="Device name",
)
switch_entity_entry = registry.async_get_or_create(
"switch",
"test",
"unique",
device_id=device_entry.id,
has_entity_name=True,
original_name="Original entity name",
)
switch_entity_entry = registry.async_update_entity(
switch_entity_entry.entity_id,
config_entry_id=switch_config_entry.entry_id,
name="New custom entity name",
)
# Add the config entry
switch_as_x_config_entry = MockConfigEntry(
data={},
domain=DOMAIN,
options={
CONF_ENTITY_ID: switch_entity_entry.id,
CONF_TARGET_DOMAIN: target_domain,
},
title="ABC",
)
switch_as_x_config_entry.add_to_hass(hass)
switch_as_x_entity_entry = registry.async_get_or_create(
target_domain,
"switch_as_x",
switch_as_x_config_entry.entry_id,
suggested_object_id="device_name_original_entity_name",
)
switch_as_x_entity_entry = registry.async_update_entity(
switch_as_x_entity_entry.entity_id,
config_entry_id=switch_config_entry.entry_id,
name="Old custom entity name",
)
assert await hass.config_entries.async_setup(switch_as_x_config_entry.entry_id)
await hass.async_block_till_done()
entity_entry = registry.async_get(
f"{target_domain}.device_name_original_entity_name"
)
assert entity_entry
assert entity_entry.entity_id == switch_as_x_entity_entry.entity_id
assert entity_entry.device_id == switch_entity_entry.device_id
assert entity_entry.has_entity_name is True
assert entity_entry.name == "Old custom entity name"
assert entity_entry.original_name == "Original entity name"
assert entity_entry.options == {
DOMAIN: {"entity_id": switch_entity_entry.entity_id}
}