Skip to content

Commit

Permalink
Remove naming warnings and work-a-rounds for incorrectly configured M…
Browse files Browse the repository at this point in the history
…QTT entities (home-assistant#107188)

* Remove naming warnings for MQTT entities

* Remove unused const
  • Loading branch information
jbouwh authored Jan 5, 2024
1 parent 8c4a29c commit f0ec123
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 102 deletions.
25 changes: 0 additions & 25 deletions homeassistant/components/mqtt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
)
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
Expand Down Expand Up @@ -94,10 +93,6 @@
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


Expand Down Expand Up @@ -425,7 +420,6 @@ def __init__(

@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)
Expand All @@ -438,25 +432,6 @@ async def async_stop_mqtt(_event: Event) -> None:
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,
Expand Down
54 changes: 7 additions & 47 deletions homeassistant/components/mqtt/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1196,7 +1195,6 @@ def _init_entity_id(self) -> None:
@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()
Expand Down Expand Up @@ -1269,7 +1267,6 @@ def config_schema() -> vol.Schema:

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:
Expand All @@ -1282,50 +1279,13 @@ def _set_entity_name(self, config: ConfigType) -> None:
# 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."""
Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/mqtt/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 0 additions & 8 deletions homeassistant/components/mqtt/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
29 changes: 8 additions & 21 deletions tests/components/mqtt/test_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def test_callback(event) -> None:
"friendly_name",
"device_name",
"assert_log",
"issue_events",
),
[
( # default_entity_name_without_device_name
Expand All @@ -106,7 +105,6 @@ def test_callback(event) -> None:
DEFAULT_SENSOR_NAME,
None,
True,
0,
),
( # default_entity_name_with_device_name
{
Expand All @@ -122,7 +120,6 @@ def test_callback(event) -> None:
"Test MQTT Sensor",
"Test",
False,
0,
),
( # name_follows_device_class
{
Expand All @@ -139,7 +136,6 @@ def test_callback(event) -> None:
"Test Humidity",
"Test",
False,
0,
),
( # name_follows_device_class_without_device_name
{
Expand All @@ -156,7 +152,6 @@ def test_callback(event) -> None:
"Humidity",
None,
True,
0,
),
( # name_overrides_device_class
{
Expand All @@ -174,7 +169,6 @@ def test_callback(event) -> None:
"Test MySensor",
"Test",
False,
0,
),
( # name_set_no_device_name_set
{
Expand All @@ -192,7 +186,6 @@ def test_callback(event) -> None:
"MySensor",
None,
True,
0,
),
( # none_entity_name_with_device_name
{
Expand All @@ -210,7 +203,6 @@ def test_callback(event) -> None:
"Test",
"Test",
False,
0,
),
( # none_entity_name_without_device_name
{
Expand All @@ -228,7 +220,6 @@ def test_callback(event) -> None:
"mqtt veryunique",
None,
True,
0,
),
( # entity_name_and_device_name_the_same
{
Expand All @@ -245,11 +236,10 @@ def test_callback(event) -> None:
}
}
},
"sensor.hello_world",
"Hello world",
"sensor.hello_world_hello_world",
"Hello world Hello world",
"Hello world",
False,
1,
),
( # entity_name_startswith_device_name1
{
Expand All @@ -266,11 +256,10 @@ def test_callback(event) -> None:
}
}
},
"sensor.world_automation",
"World automation",
"sensor.world_world_automation",
"World World automation",
"World",
False,
1,
),
( # entity_name_startswith_device_name2
{
Expand All @@ -287,11 +276,10 @@ def test_callback(event) -> None:
}
}
},
"sensor.world_automation",
"world automation",
"sensor.world_world_automation",
"world world automation",
"world",
False,
1,
),
],
ids=[
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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])
Expand Down

0 comments on commit f0ec123

Please sign in to comment.