Compare commits

...

2 Commits

Author SHA1 Message Date
Jan Bouwhuis 344a6abd83 Update tests/components/mqtt/test_mixins.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-22 19:33:34 +02:00
jbouwh 28ffa02f8c Allow MQTT entities to be hidden by default 2026-04-22 17:09:28 +00:00
5 changed files with 94 additions and 1 deletions
@@ -271,6 +271,7 @@ ABBREVIATIONS = {
"l_ver_t": "latest_version_topic",
"l_ver_tpl": "latest_version_template",
"pl_inst": "payload_install",
"vis": "visible_by_default",
}
DEVICE_ABBREVIATIONS = {
+1
View File
@@ -244,6 +244,7 @@ CONF_TILT_STATE_OPTIMISTIC = "tilt_optimistic"
CONF_TRANSITION = "transition"
CONF_URL_TEMPLATE = "url_template"
CONF_URL_TOPIC = "url_topic"
CONF_VISIBLE_BY_DEFAULT = "visible_by_default"
CONF_XY_COMMAND_TEMPLATE = "xy_command_template"
CONF_XY_COMMAND_TOPIC = "xy_command_topic"
CONF_XY_STATE_TOPIC = "xy_state_topic"
+12 -1
View File
@@ -95,6 +95,7 @@ from .const import (
CONF_SW_VERSION,
CONF_TOPIC,
CONF_VIA_DEVICE,
CONF_VISIBLE_BY_DEFAULT,
DEFAULT_ENCODING,
DOMAIN,
MQTT_CONNECTION_STATE,
@@ -1438,6 +1439,9 @@ class MqttEntity(
entity_registry.async_update_entity(
recreated_entry.entity_id,
disabled_by=None,
hidden_by=None
if self._config[CONF_VISIBLE_BY_DEFAULT]
else er.RegistryEntryHider.INTEGRATION,
)
if discovery_data is None:
@@ -1468,7 +1472,11 @@ class MqttEntity(
if self._update_registry_entity_id is not None:
entity_registry = er.async_get(self.hass)
entity_registry.async_update_entity(
self.entity_id, new_entity_id=self._update_registry_entity_id
self.entity_id,
new_entity_id=self._update_registry_entity_id,
hidden_by=None
if self._config[CONF_VISIBLE_BY_DEFAULT]
else er.RegistryEntryHider.INTEGRATION,
)
self._update_registry_entity_id = None
@@ -1594,6 +1602,9 @@ class MqttEntity(
self._attr_entity_registry_enabled_default = bool(
config.get(CONF_ENABLED_BY_DEFAULT, True)
)
self._attr_entity_registry_visible_default = bool(
config.get(CONF_VISIBLE_BY_DEFAULT, True)
)
self._attr_icon = config.get(CONF_ICON)
self._attr_entity_picture = config.get(CONF_ENTITY_PICTURE)
# Set the entity name if needed
+2
View File
@@ -53,6 +53,7 @@ from .const import (
CONF_SW_VERSION,
CONF_TOPIC,
CONF_VIA_DEVICE,
CONF_VISIBLE_BY_DEFAULT,
DEFAULT_PAYLOAD_AVAILABLE,
DEFAULT_PAYLOAD_NOT_AVAILABLE,
ENTITY_PLATFORMS,
@@ -173,6 +174,7 @@ MQTT_ENTITY_COMMON_SCHEMA = _MQTT_AVAILABILITY_SCHEMA.extend(
vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template,
vol.Optional(CONF_DEFAULT_ENTITY_ID): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_VISIBLE_BY_DEFAULT, default=True): cv.boolean,
}
)
+78
View File
@@ -541,6 +541,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
"name": None,
"state_topic": "state-topic",
"enabled_by_default": False,
"visible_by_default": True,
"unique_id": "very_unique",
"default_entity_id": "sensor.test",
"device": {"identifiers": "very_unique_device", "name": "test"},
@@ -551,6 +552,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
"name": None,
"state_topic": "state-topic",
"enabled_by_default": True,
"visible_by_default": False,
"unique_id": "very_unique",
"default_entity_id": "sensor.test",
"device": {"identifiers": "very_unique_device", "name": "test"},
@@ -561,6 +563,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
"name": None,
"state_topic": "state-topic",
"enabled_by_default": True,
"visible_by_default": True,
"unique_id": "very_unique",
"default_entity_id": "sensor.test_new",
"device": {"identifiers": "very_unique_device", "name": "test"},
@@ -574,6 +577,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
entry = entity_registry.async_get("sensor.test")
assert entry is not None
assert entry.disabled
assert entry.hidden is False
assert (device_id := entry.device_id)
assert device_registry.async_get(device_id) is not None
@@ -587,6 +591,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
assert device_registry.async_get(device_id) is None
# Rediscover the previous deleted entity and allow it to be enabled
# but not visible by default
async_fire_mqtt_message(hass, discovery_topic, config_enabled)
await hass.async_block_till_done()
state = hass.states.get("sensor.test")
@@ -594,10 +599,12 @@ async def test_registry_enable_not_enabled_by_default_entity(
entry = entity_registry.async_get("sensor.test")
assert entry is not None
assert not entry.disabled
assert entry.hidden is True
assert device_registry.async_get(device_id) is not None
# Update entity to not be enabled by default
# The entity should stay available as it was enabled before
# Also it should remain hidden
async_fire_mqtt_message(hass, discovery_topic, config_disabled)
await hass.async_block_till_done()
state = hass.states.get("sensor.test")
@@ -605,6 +612,7 @@ async def test_registry_enable_not_enabled_by_default_entity(
entry = entity_registry.async_get("sensor.test")
assert entry is not None
assert not entry.disabled
assert entry.hidden is True
assert device_registry.async_get(device_id) is not None
# Delete the entity again
@@ -616,16 +624,86 @@ async def test_registry_enable_not_enabled_by_default_entity(
assert device_registry.async_get(device_id) is None
# Repeat the re-discovery, with a new entity name
# The entity should be visible by default now
async_fire_mqtt_message(hass, discovery_topic, config_enabled_new_entity_name)
await hass.async_block_till_done()
state = hass.states.get("sensor.test_new")
assert state is not None
entry = entity_registry.async_get("sensor.test_new")
assert entry is not None
assert entry.hidden is False
assert not entry.disabled
assert device_registry.async_get(device_id) is not None
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
sensor.DOMAIN: {
"name": "test",
"state_topic": "state-topic",
"unique_id": "very_unique",
}
}
},
{
mqtt.DOMAIN: {
sensor.DOMAIN: {
"name": "test",
"state_topic": "state-topic",
"visible_by_default": True,
"unique_id": "very_unique",
}
}
},
],
)
async def test_registry_visible_by_default(
hass: HomeAssistant,
mqtt_mock_entry: MqttMockHAClientGenerator,
entity_registry: er.EntityRegistry,
) -> None:
"""Test an entity that is visible by default or not."""
await mqtt_mock_entry()
state = hass.states.get("sensor.test")
assert state is not None
entry = entity_registry.async_get("sensor.test")
assert not entry.disabled
assert entry.hidden is False
assert entry.hidden_by is None
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
sensor.DOMAIN: {
"name": "test",
"state_topic": "state-topic",
"visible_by_default": False,
"unique_id": "very_unique",
}
}
},
],
)
async def test_registry_not_visible_by_default(
hass: HomeAssistant,
mqtt_mock_entry: MqttMockHAClientGenerator,
entity_registry: er.EntityRegistry,
) -> None:
"""Test an entity that is not visible by default."""
await mqtt_mock_entry()
state = hass.states.get("sensor.test")
assert state is not None
entry = entity_registry.async_get("sensor.test")
assert entry.hidden is True
assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION
@pytest.mark.parametrize(
"mqtt_config_subentries_data",
[