Add helper to set name of helper config entries (#67950)
This commit is contained in:
parent
4e7d4db7ae
commit
ee38dbd698
5 changed files with 75 additions and 107 deletions
|
@ -6,12 +6,7 @@ from typing import Any
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.core import split_entity_id
|
from homeassistant.helpers import helper_config_entry_flow, selector
|
||||||
from homeassistant.helpers import (
|
|
||||||
entity_registry as er,
|
|
||||||
helper_config_entry_flow,
|
|
||||||
selector,
|
|
||||||
)
|
|
||||||
|
|
||||||
from . import DOMAIN
|
from . import DOMAIN
|
||||||
|
|
||||||
|
@ -40,12 +35,6 @@ class SwitchAsXConfigFlowHandler(
|
||||||
|
|
||||||
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
|
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
|
||||||
"""Return config entry title."""
|
"""Return config entry title."""
|
||||||
registry = er.async_get(self.hass)
|
return helper_config_entry_flow.wrapped_entity_config_entry_title(
|
||||||
object_id = split_entity_id(options["entity_id"])[1]
|
self.hass, options["entity_id"]
|
||||||
entry = registry.async_get(options["entity_id"])
|
)
|
||||||
if entry:
|
|
||||||
return entry.name or entry.original_name or object_id
|
|
||||||
state = self.hass.states.get(options["entity_id"])
|
|
||||||
if state:
|
|
||||||
return state.name or object_id
|
|
||||||
return object_id
|
|
||||||
|
|
|
@ -10,9 +10,11 @@ from typing import Any
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import HomeAssistant, callback, split_entity_id
|
||||||
from homeassistant.data_entry_flow import FlowResult, UnknownHandler
|
from homeassistant.data_entry_flow import FlowResult, UnknownHandler
|
||||||
|
|
||||||
|
from . import entity_registry as er
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class HelperFlowStep:
|
class HelperFlowStep:
|
||||||
|
@ -181,3 +183,25 @@ class HelperOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Finish config flow and create a config entry."""
|
"""Finish config flow and create a config entry."""
|
||||||
return super().async_create_entry(title="", **kwargs)
|
return super().async_create_entry(title="", **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def wrapped_entity_config_entry_title(
|
||||||
|
hass: HomeAssistant, entity_id_or_uuid: str
|
||||||
|
) -> str:
|
||||||
|
"""Generate title for a config entry wrapping a single entity.
|
||||||
|
|
||||||
|
If the entity is registered, use the registry entry's name.
|
||||||
|
If the entity is in the state machine, use the name from the state.
|
||||||
|
Otherwise, fall back to the object ID.
|
||||||
|
"""
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
entity_id = er.async_validate_entity_id(registry, entity_id_or_uuid)
|
||||||
|
object_id = split_entity_id(entity_id)[1]
|
||||||
|
entry = registry.async_get(entity_id)
|
||||||
|
if entry:
|
||||||
|
return entry.name or entry.original_name or object_id
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
if state:
|
||||||
|
return state.name or object_id
|
||||||
|
return object_id
|
||||||
|
|
|
@ -48,72 +48,17 @@ async def test_config_flow(hass: HomeAssistant, target_domain) -> None:
|
||||||
"target_domain": target_domain,
|
"target_domain": target_domain,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert hass.states.get(f"{target_domain}.ceiling")
|
# Check the wrapped switch has a state and is added to the registry
|
||||||
|
state = hass.states.get(f"{target_domain}.ceiling")
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
|
||||||
|
# Name copied from config entry title
|
||||||
|
assert state.name == "ceiling"
|
||||||
|
|
||||||
@pytest.mark.parametrize("target_domain", ("light",))
|
# Check the light is added to the entity registry
|
||||||
async def test_name(hass: HomeAssistant, target_domain) -> None:
|
|
||||||
"""Test the config flow name is copied from registry entry, with fallback to state."""
|
|
||||||
registry = er.async_get(hass)
|
registry = er.async_get(hass)
|
||||||
|
entity_entry = registry.async_get(f"{target_domain}.ceiling")
|
||||||
# No entry or state, use Object ID
|
assert entity_entry.unique_id == config_entry.entry_id
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{"entity_id": "switch.ceiling", "target_domain": target_domain},
|
|
||||||
)
|
|
||||||
assert result["title"] == "ceiling"
|
|
||||||
|
|
||||||
# State set, use name from state
|
|
||||||
hass.states.async_set("switch.ceiling", "on", {"friendly_name": "State Name"})
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{"entity_id": "switch.ceiling", "target_domain": target_domain},
|
|
||||||
)
|
|
||||||
assert result["title"] == "State Name"
|
|
||||||
|
|
||||||
# Entity registered, use original name from registry entry
|
|
||||||
hass.states.async_remove("switch.ceiling")
|
|
||||||
entry = registry.async_get_or_create(
|
|
||||||
"switch",
|
|
||||||
"test",
|
|
||||||
"unique",
|
|
||||||
suggested_object_id="ceiling",
|
|
||||||
original_name="Original Name",
|
|
||||||
)
|
|
||||||
assert entry.entity_id == "switch.ceiling"
|
|
||||||
hass.states.async_set("switch.ceiling", "on", {"friendly_name": "State Name"})
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{"entity_id": "switch.ceiling", "target_domain": target_domain},
|
|
||||||
)
|
|
||||||
assert result["title"] == "Original Name"
|
|
||||||
|
|
||||||
# Entity has customized name
|
|
||||||
registry.async_update_entity("switch.ceiling", name="Custom Name")
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{"entity_id": "switch.ceiling", "target_domain": target_domain},
|
|
||||||
)
|
|
||||||
assert result["title"] == "Custom Name"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("target_domain", ("light",))
|
@pytest.mark.parametrize("target_domain", ("light",))
|
||||||
|
|
|
@ -106,34 +106,6 @@ async def test_switch_service_calls(hass):
|
||||||
assert hass.states.get("light.decorative_lights").state == "on"
|
assert hass.states.get("light.decorative_lights").state == "on"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("target_domain", ("light",))
|
|
||||||
async def test_config_entry(hass: HomeAssistant, target_domain):
|
|
||||||
"""Test light switch setup from config entry."""
|
|
||||||
config_entry = MockConfigEntry(
|
|
||||||
data={},
|
|
||||||
domain=DOMAIN,
|
|
||||||
options={"entity_id": "switch.abc", "target_domain": target_domain},
|
|
||||||
title="ABC",
|
|
||||||
)
|
|
||||||
|
|
||||||
config_entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert DOMAIN in hass.config.components
|
|
||||||
|
|
||||||
state = hass.states.get(f"{target_domain}.abc")
|
|
||||||
assert state.state == "unavailable"
|
|
||||||
# Name copied from config entry title
|
|
||||||
assert state.name == "ABC"
|
|
||||||
|
|
||||||
# Check the light is added to the entity registry
|
|
||||||
registry = er.async_get(hass)
|
|
||||||
entity_entry = registry.async_get(f"{target_domain}.abc")
|
|
||||||
assert entity_entry.unique_id == config_entry.entry_id
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("target_domain", ("light",))
|
@pytest.mark.parametrize("target_domain", ("light",))
|
||||||
async def test_config_entry_uuid(hass: HomeAssistant, target_domain):
|
async def test_config_entry_uuid(hass: HomeAssistant, target_domain):
|
||||||
"""Test light switch setup from config entry with entity registry id."""
|
"""Test light switch setup from config entry with entity registry id."""
|
||||||
|
|
38
tests/helpers/test_helper_config_entry_flow.py
Normal file
38
tests/helpers/test_helper_config_entry_flow.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
"""Test helper_config_entry_flow."""
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.helpers.helper_config_entry_flow import (
|
||||||
|
wrapped_entity_config_entry_title,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_name(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the config flow name is copied from registry entry, with fallback to state."""
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
entity_id = "switch.ceiling"
|
||||||
|
|
||||||
|
# No entry or state, use Object ID
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entity_id) == "ceiling"
|
||||||
|
|
||||||
|
# State set, use name from state
|
||||||
|
hass.states.async_set(entity_id, "on", {"friendly_name": "State Name"})
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entity_id) == "State Name"
|
||||||
|
|
||||||
|
# Entity registered, use original name from registry entry
|
||||||
|
hass.states.async_remove(entity_id)
|
||||||
|
entry = registry.async_get_or_create(
|
||||||
|
"switch",
|
||||||
|
"test",
|
||||||
|
"unique",
|
||||||
|
suggested_object_id="ceiling",
|
||||||
|
original_name="Original Name",
|
||||||
|
)
|
||||||
|
hass.states.async_set(entity_id, "on", {"friendly_name": "State Name"})
|
||||||
|
assert entry.entity_id == entity_id
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entity_id) == "Original Name"
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entry.id) == "Original Name"
|
||||||
|
|
||||||
|
# Entity has customized name
|
||||||
|
registry.async_update_entity("switch.ceiling", name="Custom Name")
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entity_id) == "Custom Name"
|
||||||
|
assert wrapped_entity_config_entry_title(hass, entry.id) == "Custom Name"
|
Loading…
Add table
Reference in a new issue