1
mirror of https://github.com/home-assistant/core synced 2024-08-28 03:36:46 +02:00

Remove naming warnings and work-a-rounds for incorrectly configured MQTT entities (#107188)

* Remove naming warnings for MQTT entities

* Remove unused const
This commit is contained in:
Jan Bouwhuis 2024-01-05 09:32:22 +01:00 committed by GitHub
parent 8c4a29c200
commit f0ec1235b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 102 deletions

View File

@ -35,7 +35,6 @@ from homeassistant.core import (
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass
from homeassistant.util import dt as dt_util
@ -94,10 +93,6 @@ SUBSCRIBE_COOLDOWN = 0.1
UNSUBSCRIBE_COOLDOWN = 0.1
TIMEOUT_ACK = 10
MQTT_ENTRIES_NAMING_BLOG_URL = (
"https://developers.home-assistant.io/blog/2023-057-21-change-naming-mqtt-entities/"
)
SubscribePayloadType = str | bytes # Only bytes if encoding is None
@ -425,7 +420,6 @@ class MQTT:
@callback
def ha_started(_: Event) -> None:
self.register_naming_issues()
self._ha_started.set()
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, ha_started)
@ -438,25 +432,6 @@ class MQTT:
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop_mqtt)
)
def register_naming_issues(self) -> None:
"""Register issues with MQTT entity naming."""
mqtt_data = get_mqtt_data(self.hass)
for issue_key, items in mqtt_data.issues.items():
config_list = "\n".join([f"- {item}" for item in items])
async_create_issue(
self.hass,
DOMAIN,
issue_key,
breaks_in_ha_version="2024.2.0",
is_fixable=False,
translation_key=issue_key,
translation_placeholders={
"config": config_list,
},
learn_more_url=MQTT_ENTRIES_NAMING_BLOG_URL,
severity=IssueSeverity.WARNING,
)
def start(
self,
mqtt_data: MqttData,

View File

@ -1158,7 +1158,6 @@ class MqttEntity(
_attr_should_poll = False
_default_name: str | None
_entity_id_format: str
_issue_key: str | None
def __init__(
self,
@ -1196,7 +1195,6 @@ class MqttEntity(
@final
async def async_added_to_hass(self) -> None:
"""Subscribe to MQTT events."""
self.collect_issues()
await super().async_added_to_hass()
self._prepare_subscribe_topics()
await self._subscribe_topics()
@ -1269,7 +1267,6 @@ class MqttEntity(
def _set_entity_name(self, config: ConfigType) -> None:
"""Help setting the entity name if needed."""
self._issue_key = None
entity_name: str | None | UndefinedType = config.get(CONF_NAME, UNDEFINED)
# Only set _attr_name if it is needed
if entity_name is not UNDEFINED:
@ -1282,50 +1279,13 @@ class MqttEntity(
# don't set the name attribute and derive
# the name from the device_class
delattr(self, "_attr_name")
if CONF_DEVICE in config:
device_name: str
if CONF_NAME not in config[CONF_DEVICE]:
_LOGGER.info(
"MQTT device information always needs to include a name, got %s, "
"if device information is shared between multiple entities, the device "
"name must be included in each entity's device configuration",
config,
)
elif (device_name := config[CONF_DEVICE][CONF_NAME]) == entity_name:
self._attr_name = None
if not self._discovery:
self._issue_key = "entity_name_is_device_name_yaml"
_LOGGER.warning(
"MQTT device name is equal to entity name in your config %s, "
"this is not expected. Please correct your configuration. "
"The entity name will be set to `null`",
config,
)
elif isinstance(entity_name, str) and entity_name.startswith(device_name):
self._attr_name = (
new_entity_name := entity_name[len(device_name) :].lstrip()
)
if device_name[:1].isupper():
# Ensure a capital if the device name first char is a capital
new_entity_name = new_entity_name[:1].upper() + new_entity_name[1:]
if not self._discovery:
self._issue_key = "entity_name_startswith_device_name_yaml"
_LOGGER.warning(
"MQTT entity name starts with the device name in your config %s, "
"this is not expected. Please correct your configuration. "
"The device name prefix will be stripped off the entity name "
"and becomes '%s'",
config,
new_entity_name,
)
def collect_issues(self) -> None:
"""Process issues for MQTT entities."""
if self._issue_key is None:
return
mqtt_data = get_mqtt_data(self.hass)
issues = mqtt_data.issues.setdefault(self._issue_key, set())
issues.add(self.entity_id)
if CONF_DEVICE in config and CONF_NAME not in config[CONF_DEVICE]:
_LOGGER.info(
"MQTT device information always needs to include a name, got %s, "
"if device information is shared between multiple entities, the device "
"name must be included in each entity's device configuration",
config,
)
def _setup_common_attributes_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the common attributes for the entity."""

View File

@ -339,7 +339,6 @@ class MqttData:
)
discovery_unsubscribe: list[CALLBACK_TYPE] = field(default_factory=list)
integration_unsubscribe: dict[str, CALLBACK_TYPE] = field(default_factory=dict)
issues: dict[str, set[str]] = field(default_factory=dict)
last_discovery: float = 0.0
reload_dispatchers: list[CALLBACK_TYPE] = field(default_factory=list)
reload_handlers: dict[str, CALLBACK_TYPE] = field(default_factory=dict)

View File

@ -8,14 +8,6 @@
"title": "MQTT vacuum entities with legacy schema added through MQTT discovery",
"description": "MQTT vacuum entities that use the legacy schema are deprecated, please adjust your devices to use the correct schema and restart Home Assistant to fix this issue."
},
"entity_name_is_device_name_yaml": {
"title": "Manual configured MQTT entities with a name that is equal to the device name",
"description": "Some MQTT entities have an entity name equal to the device name. This is not expected. The entity name is set to `null` as a work-a-round to avoid a duplicate name. Please update your configuration and restart Home Assistant to fix this issue.\n\nList of affected entities:\n\n{config}"
},
"entity_name_startswith_device_name_yaml": {
"title": "Manual configured MQTT entities with a name that starts with the device name",
"description": "Some MQTT entities have an entity name that starts with the device name. This is not expected. To avoid a duplicate name the device name prefix is stripped off the entity name as a work-a-round. Please update your configuration and restart Home Assistant to fix this issue. \n\nList of affected entities:\n\n{config}"
},
"deprecated_climate_aux_property": {
"title": "MQTT entities with auxiliary heat support found",
"description": "Entity `{entity_id}` has auxiliary heat support enabled, which has been deprecated for MQTT climate devices. Please adjust your configuration and remove deprecated config options from your configuration and restart Home Assistant to fix this issue."

View File

@ -89,7 +89,6 @@ async def test_availability_with_shared_state_topic(
"friendly_name",
"device_name",
"assert_log",
"issue_events",
),
[
( # default_entity_name_without_device_name
@ -106,7 +105,6 @@ async def test_availability_with_shared_state_topic(
DEFAULT_SENSOR_NAME,
None,
True,
0,
),
( # default_entity_name_with_device_name
{
@ -122,7 +120,6 @@ async def test_availability_with_shared_state_topic(
"Test MQTT Sensor",
"Test",
False,
0,
),
( # name_follows_device_class
{
@ -139,7 +136,6 @@ async def test_availability_with_shared_state_topic(
"Test Humidity",
"Test",
False,
0,
),
( # name_follows_device_class_without_device_name
{
@ -156,7 +152,6 @@ async def test_availability_with_shared_state_topic(
"Humidity",
None,
True,
0,
),
( # name_overrides_device_class
{
@ -174,7 +169,6 @@ async def test_availability_with_shared_state_topic(
"Test MySensor",
"Test",
False,
0,
),
( # name_set_no_device_name_set
{
@ -192,7 +186,6 @@ async def test_availability_with_shared_state_topic(
"MySensor",
None,
True,
0,
),
( # none_entity_name_with_device_name
{
@ -210,7 +203,6 @@ async def test_availability_with_shared_state_topic(
"Test",
"Test",
False,
0,
),
( # none_entity_name_without_device_name
{
@ -228,7 +220,6 @@ async def test_availability_with_shared_state_topic(
"mqtt veryunique",
None,
True,
0,
),
( # entity_name_and_device_name_the_same
{
@ -245,11 +236,10 @@ async def test_availability_with_shared_state_topic(
}
}
},
"sensor.hello_world",
"Hello world",
"sensor.hello_world_hello_world",
"Hello world Hello world",
"Hello world",
False,
1,
),
( # entity_name_startswith_device_name1
{
@ -266,11 +256,10 @@ async def test_availability_with_shared_state_topic(
}
}
},
"sensor.world_automation",
"World automation",
"sensor.world_world_automation",
"World World automation",
"World",
False,
1,
),
( # entity_name_startswith_device_name2
{
@ -287,11 +276,10 @@ async def test_availability_with_shared_state_topic(
}
}
},
"sensor.world_automation",
"world automation",
"sensor.world_world_automation",
"world world automation",
"world",
False,
1,
),
],
ids=[
@ -320,7 +308,6 @@ async def test_default_entity_and_device_name(
friendly_name: str,
device_name: str | None,
assert_log: bool,
issue_events: int,
) -> None:
"""Test device name setup with and without a device_class set.
@ -349,8 +336,8 @@ async def test_default_entity_and_device_name(
"MQTT device information always needs to include a name" in caplog.text
) is assert_log
# Assert that an issues ware registered
assert len(events) == issue_events
# Assert that no issues ware registered
assert len(events) == 0
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])