Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions homeassistant/components/mqtt/abbreviations.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"dev_cla": "device_class",
"dock_t": "docked_topic",
"dock_tpl": "docked_template",
"en": "enabled_by_default",
"err_t": "error_topic",
"err_tpl": "error_template",
"fanspd_t": "fan_speed_topic",
Expand Down
9 changes: 8 additions & 1 deletion homeassistant/components/mqtt/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
CONF_AVAILABILITY = "availability"
CONF_AVAILABILITY_MODE = "availability_mode"
CONF_AVAILABILITY_TOPIC = "availability_topic"
CONF_ENABLED_BY_DEFAULT = "enabled_by_default"
CONF_PAYLOAD_AVAILABLE = "payload_available"
CONF_PAYLOAD_NOT_AVAILABLE = "payload_not_available"
CONF_JSON_ATTRS_TOPIC = "json_attributes_topic"
Expand Down Expand Up @@ -140,6 +141,7 @@ def validate_device_has_at_least_one_identifier(value: ConfigType) -> ConfigType
MQTT_ENTITY_COMMON_SCHEMA = MQTT_AVAILABILITY_SCHEMA.extend(
{
vol.Optional(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA,
vol.Optional(CONF_ENABLED_BY_DEFAULT, default=True): cv.boolean,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_JSON_ATTRS_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template,
Expand Down Expand Up @@ -353,7 +355,7 @@ async def cleanup_device_registry(hass, device_id):
if (
device_id
and not hass.helpers.entity_registry.async_entries_for_device(
entity_registry, device_id, include_disabled_entities=True
entity_registry, device_id, include_disabled_entities=False
)
and not await device_trigger.async_get_triggers(hass, device_id)
and not tag.async_has_tags(hass, device_id)
Expand Down Expand Up @@ -586,6 +588,11 @@ def _setup_from_config(self, config):
async def _subscribe_topics(self):
"""(Re)Subscribe to topics."""

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._config.get(CONF_ENABLED_BY_DEFAULT)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the key is always there, use square brackets. If you want to have teh default live here and not in the config schema, remove default=True from MQTT_ENTITY_COMMON_SCHEMA


@property
def icon(self):
"""Return icon of the entity if any."""
Expand Down
36 changes: 36 additions & 0 deletions tests/components/mqtt/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,3 +1146,39 @@ async def help_test_entity_debug_info_update_entity_id(hass, mqtt_mock, domain,
assert (
f"{domain}.test" not in hass.data[debug_info.DATA_MQTT_DEBUG_INFO]["entities"]
)


async def help_test_entity_disabled_by_default(hass, mqtt_mock, domain, config):
"""Test device registry remove."""
# Add device settings to config
config = copy.deepcopy(config[domain])
config["device"] = copy.deepcopy(DEFAULT_CONFIG_DEVICE_INFO_ID)
config["enabled_by_default"] = False
config["unique_id"] = "veryunique1"

dev_registry = dr.async_get(hass)
ent_registry = er.async_get(hass)

# Discover a disabled entity
data = json.dumps(config)
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla1/config", data)
await hass.async_block_till_done()
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique1")
assert not hass.states.get(entity_id)
assert dev_registry.async_get_device({("mqtt", "helloworld")})

# Discover an enabled entity, tied to the same device
config["enabled_by_default"] = True
config["unique_id"] = "veryunique2"
data = json.dumps(config)
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla2/config", data)
await hass.async_block_till_done()
entity_id = ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique2")
assert hass.states.get(entity_id)

# Remove the enabled entity, both entities and the device should be removed
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla2/config", "")
await hass.async_block_till_done()
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique1")
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, "veryunique2")
assert not dev_registry.async_get_device({("mqtt", "helloworld")})
8 changes: 8 additions & 0 deletions tests/components/mqtt/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
help_test_entity_device_info_update,
help_test_entity_device_info_with_connection,
help_test_entity_device_info_with_identifier,
help_test_entity_disabled_by_default,
help_test_entity_id_update_discovery_update,
help_test_entity_id_update_subscriptions,
help_test_setting_attribute_via_mqtt_json_message,
Expand Down Expand Up @@ -632,3 +633,10 @@ async def test_entity_debug_info_update_entity_id(hass, mqtt_mock):
await help_test_entity_debug_info_update_entity_id(
hass, mqtt_mock, sensor.DOMAIN, DEFAULT_CONFIG
)


async def test_entity_disabled_by_default(hass, mqtt_mock):
"""Test entity disabled by default."""
await help_test_entity_disabled_by_default(
hass, mqtt_mock, sensor.DOMAIN, DEFAULT_CONFIG
)