mirror of
https://github.com/home-assistant/core.git
synced 2026-08-14 17:23:33 +01:00
240 lines
6.9 KiB
Python
240 lines
6.9 KiB
Python
"""KNX base entity tests."""
|
|
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components.knx.const import DOMAIN, KNX_ADDRESS
|
|
from homeassistant.const import STATE_UNKNOWN, EntityCategory, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
|
|
|
from .conftest import KNXTestKit
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("config", "expected_entity_id", "expected_friendly_name"),
|
|
[
|
|
(
|
|
{
|
|
"name": "test",
|
|
KNX_ADDRESS: "1/2/3",
|
|
},
|
|
"switch.test",
|
|
"test",
|
|
),
|
|
(
|
|
{
|
|
KNX_ADDRESS: "1/2/3",
|
|
},
|
|
"switch.knx_1_2_3", # generated from unique_id
|
|
None,
|
|
),
|
|
(
|
|
{
|
|
"name": "",
|
|
KNX_ADDRESS: "1/2/3",
|
|
},
|
|
"switch.knx_1_2_3", # generated from unique_id
|
|
None,
|
|
),
|
|
(
|
|
{
|
|
"default_entity_id": "switch.test_default_entity_id",
|
|
KNX_ADDRESS: "1/2/3",
|
|
},
|
|
"switch.test_default_entity_id",
|
|
None,
|
|
),
|
|
(
|
|
{
|
|
"name": "my_test_name",
|
|
"default_entity_id": "switch.test_default_entity_id",
|
|
KNX_ADDRESS: "1/2/3",
|
|
},
|
|
"switch.test_default_entity_id",
|
|
"my_test_name",
|
|
),
|
|
],
|
|
)
|
|
async def test_yaml_entity_naming(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
config: dict[str, Any],
|
|
expected_entity_id: str,
|
|
expected_friendly_name: str | None,
|
|
) -> None:
|
|
"""Test KNX entity id and name setting from YAML configuration."""
|
|
await knx.setup_integration({Platform.SWITCH: config})
|
|
knx.assert_state(
|
|
expected_entity_id,
|
|
STATE_UNKNOWN,
|
|
friendly_name=expected_friendly_name,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("config", "expected_entity_category"),
|
|
[
|
|
(
|
|
{},
|
|
None,
|
|
),
|
|
(
|
|
{
|
|
"entity_category": "diagnostic",
|
|
},
|
|
EntityCategory.DIAGNOSTIC,
|
|
),
|
|
(
|
|
{
|
|
"entity_category": "config",
|
|
},
|
|
EntityCategory.CONFIG,
|
|
),
|
|
],
|
|
)
|
|
async def test_yaml_entity_category(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
entity_registry: er.EntityRegistry,
|
|
config: dict[str, Any],
|
|
expected_entity_category: EntityCategory | None,
|
|
) -> None:
|
|
"""Test KNX entity category setting from YAML configuration."""
|
|
await knx.setup_integration(
|
|
{
|
|
Platform.SWITCH: [
|
|
{
|
|
"default_entity_id": "switch.test",
|
|
KNX_ADDRESS: "1/1/1",
|
|
**config,
|
|
},
|
|
]
|
|
}
|
|
)
|
|
|
|
entity = entity_registry.async_get("switch.test")
|
|
assert entity.entity_category is expected_entity_category
|
|
|
|
|
|
async def test_yaml_entity_device_grouping(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
entity_registry: er.EntityRegistry,
|
|
device_registry: dr.DeviceRegistry,
|
|
) -> None:
|
|
"""Entities sharing a `device` name are grouped into a single device."""
|
|
await knx.setup_integration(
|
|
{
|
|
Platform.SWITCH: [
|
|
{
|
|
"default_entity_id": "switch.a",
|
|
KNX_ADDRESS: "1/1/1",
|
|
"device": {"id": "living_room", "name": "Living room"},
|
|
},
|
|
{
|
|
"default_entity_id": "switch.b",
|
|
KNX_ADDRESS: "1/1/2",
|
|
"device": {"id": "living_room", "name": "Living room"},
|
|
},
|
|
{
|
|
"default_entity_id": "switch.c",
|
|
KNX_ADDRESS: "1/1/3",
|
|
"device": {"id": "bedroom"}, # name is optional
|
|
},
|
|
{"default_entity_id": "switch.d", KNX_ADDRESS: "1/1/4"},
|
|
]
|
|
}
|
|
)
|
|
|
|
entity_a = entity_registry.async_get("switch.a")
|
|
entity_b = entity_registry.async_get("switch.b")
|
|
entity_c = entity_registry.async_get("switch.c")
|
|
entity_d = entity_registry.async_get("switch.d")
|
|
|
|
assert entity_a.device_id is not None
|
|
assert entity_a.device_id == entity_b.device_id
|
|
assert entity_c.device_id not in (None, entity_a.device_id)
|
|
assert entity_d.device_id is None
|
|
|
|
device = device_registry.async_get(entity_a.device_id)
|
|
assert device.name == "Living room"
|
|
assert device.manufacturer == "KNX"
|
|
assert (DOMAIN, "living_room") in device.identifiers
|
|
|
|
# `name` is optional; the device is still created keyed by its `id`.
|
|
bedroom = device_registry.async_get(entity_c.device_id)
|
|
assert (DOMAIN, "bedroom") in bedroom.identifiers
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("config", "expected_friendly_name"),
|
|
[
|
|
(
|
|
{
|
|
"name": "Ceiling light",
|
|
KNX_ADDRESS: "1/1/1",
|
|
"device": {"id": "kitchen", "name": "Kitchen"},
|
|
},
|
|
"Kitchen Ceiling light",
|
|
),
|
|
(
|
|
{
|
|
KNX_ADDRESS: "1/1/1",
|
|
"device": {"id": "kitchen", "name": "Kitchen"},
|
|
},
|
|
"Kitchen", # no entity name: entity is the device's main feature
|
|
),
|
|
(
|
|
{"name": "Ceiling light", KNX_ADDRESS: "1/1/1"},
|
|
"Ceiling light", # no device: name is shown verbatim, as before
|
|
),
|
|
],
|
|
)
|
|
async def test_yaml_entity_device_naming(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
config: dict[str, Any],
|
|
expected_friendly_name: str,
|
|
) -> None:
|
|
"""An entity on a device uses has_entity_name naming, like a UI entity."""
|
|
await knx.setup_integration({Platform.SWITCH: config})
|
|
states = hass.states.async_all("switch")
|
|
assert len(states) == 1
|
|
assert states[0].attributes["friendly_name"] == expected_friendly_name
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("device_id", "expected_identifier"),
|
|
[
|
|
("Living Room", "living_room"),
|
|
("living room", "living_room"),
|
|
(" living_room ", "living_room"),
|
|
# A UI device identifier is preserved verbatim, not lower-cased.
|
|
("knx_vdev_ABC123", "knx_vdev_ABC123"),
|
|
# Surrounding whitespace is stripped before the UI-prefix check.
|
|
(" knx_vdev_ABC123 ", "knx_vdev_ABC123"),
|
|
],
|
|
)
|
|
async def test_yaml_device_id_normalization(
|
|
hass: HomeAssistant,
|
|
knx: KNXTestKit,
|
|
device_registry: dr.DeviceRegistry,
|
|
device_id: str,
|
|
expected_identifier: str,
|
|
) -> None:
|
|
"""A YAML device `id` is slugified unless it is a UI device identifier."""
|
|
await knx.setup_integration(
|
|
{
|
|
Platform.SWITCH: {
|
|
"name": "test",
|
|
KNX_ADDRESS: "1/1/1",
|
|
"device": {"id": device_id},
|
|
}
|
|
}
|
|
)
|
|
assert device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, expected_identifier), knx.mock_config_entry.entry_id
|
|
)
|