Link manually added MQTT entities the the MQTT config entry (#78547)
Co-authored-by: Erik <erik@montnemery.com>pull/78704/head
parent
49ead219a5
commit
354411feed
|
@ -30,6 +30,7 @@ from homeassistant.helpers import (
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.device_registry import DeviceEntry
|
from homeassistant.helpers.device_registry import DeviceEntry
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
from homeassistant.helpers.entity_platform import async_get_platforms
|
||||||
from homeassistant.helpers.reload import (
|
from homeassistant.helpers.reload import (
|
||||||
async_integration_yaml_config,
|
async_integration_yaml_config,
|
||||||
async_reload_integration_platforms,
|
async_reload_integration_platforms,
|
||||||
|
@ -75,7 +76,7 @@ from .const import ( # noqa: F401
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
RELOADABLE_PLATFORMS,
|
RELOADABLE_PLATFORMS,
|
||||||
)
|
)
|
||||||
from .mixins import MqttData, async_discover_yaml_entities
|
from .mixins import MqttData
|
||||||
from .models import ( # noqa: F401
|
from .models import ( # noqa: F401
|
||||||
MqttCommandTemplate,
|
MqttCommandTemplate,
|
||||||
MqttValueTemplate,
|
MqttValueTemplate,
|
||||||
|
@ -422,13 +423,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
await async_reload_integration_platforms(hass, DOMAIN, RELOADABLE_PLATFORMS)
|
await async_reload_integration_platforms(hass, DOMAIN, RELOADABLE_PLATFORMS)
|
||||||
|
|
||||||
# Reload the modern yaml platforms
|
# Reload the modern yaml platforms
|
||||||
|
mqtt_platforms = async_get_platforms(hass, DOMAIN)
|
||||||
|
tasks = [
|
||||||
|
entity.async_remove()
|
||||||
|
for mqtt_platform in mqtt_platforms
|
||||||
|
for entity in mqtt_platform.entities.values()
|
||||||
|
if not entity._discovery_data # type: ignore[attr-defined] # pylint: disable=protected-access
|
||||||
|
if mqtt_platform.config_entry
|
||||||
|
and mqtt_platform.domain in RELOADABLE_PLATFORMS
|
||||||
|
]
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
config_yaml = await async_integration_yaml_config(hass, DOMAIN) or {}
|
config_yaml = await async_integration_yaml_config(hass, DOMAIN) or {}
|
||||||
mqtt_data.updated_config = config_yaml.get(DOMAIN, {})
|
mqtt_data.updated_config = config_yaml.get(DOMAIN, {})
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
*(
|
*(
|
||||||
[
|
[
|
||||||
async_discover_yaml_entities(hass, component)
|
mqtt_data.reload_handlers[component]()
|
||||||
for component in RELOADABLE_PLATFORMS
|
for component in RELOADABLE_PLATFORMS
|
||||||
|
if component in mqtt_data.reload_handlers
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,7 +44,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -146,9 +145,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT alarm control panel through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT alarm control panel through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, alarm.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,7 +42,6 @@ from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttAvailability,
|
MqttAvailability,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -102,9 +101,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT binary sensor through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT binary sensor through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, binary_sensor.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,7 +25,6 @@ from .const import (
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -81,9 +80,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT button through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT button through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, button.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -105,9 +104,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT camera through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT camera through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, camera.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,7 +50,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -350,9 +349,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT climate device through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT climate device through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, climate.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -46,7 +46,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -242,9 +241,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT cover through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT cover through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, cover.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,7 +50,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -241,9 +240,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT fan through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT fan through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, fan.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -46,7 +46,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -187,9 +186,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT humidifier through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT humidifier through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, humidifier.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from ..mixins import (
|
from ..mixins import (
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -111,9 +110,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT lights configured under the light platform key (deprecated)."""
|
"""Set up MQTT lights configured under the light platform key (deprecated)."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, light.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,7 +28,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -102,9 +101,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT lock through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT lock through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, lock.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -39,7 +39,6 @@ from homeassistant.core import (
|
||||||
from homeassistant.helpers import (
|
from homeassistant.helpers import (
|
||||||
config_validation as cv,
|
config_validation as cv,
|
||||||
device_registry as dr,
|
device_registry as dr,
|
||||||
discovery,
|
|
||||||
entity_registry as er,
|
entity_registry as er,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.device_registry import EVENT_DEVICE_REGISTRY_UPDATED
|
from homeassistant.helpers.device_registry import EVENT_DEVICE_REGISTRY_UPDATED
|
||||||
|
@ -286,6 +285,9 @@ class MqttData:
|
||||||
last_discovery: float = 0.0
|
last_discovery: float = 0.0
|
||||||
reload_dispatchers: list[CALLBACK_TYPE] = field(default_factory=list)
|
reload_dispatchers: list[CALLBACK_TYPE] = field(default_factory=list)
|
||||||
reload_entry: bool = False
|
reload_entry: bool = False
|
||||||
|
reload_handlers: dict[str, Callable[[], Coroutine[Any, Any, None]]] = field(
|
||||||
|
default_factory=dict
|
||||||
|
)
|
||||||
reload_needed: bool = False
|
reload_needed: bool = False
|
||||||
subscriptions_to_restore: list[Subscription] = field(default_factory=list)
|
subscriptions_to_restore: list[Subscription] = field(default_factory=list)
|
||||||
updated_config: ConfigType = field(default_factory=dict)
|
updated_config: ConfigType = field(default_factory=dict)
|
||||||
|
@ -305,30 +307,6 @@ class SetupEntity(Protocol):
|
||||||
"""Define setup_entities type."""
|
"""Define setup_entities type."""
|
||||||
|
|
||||||
|
|
||||||
async def async_discover_yaml_entities(
|
|
||||||
hass: HomeAssistant, platform_domain: str
|
|
||||||
) -> None:
|
|
||||||
"""Discover entities for a platform."""
|
|
||||||
mqtt_data: MqttData = hass.data[DATA_MQTT]
|
|
||||||
if mqtt_data.updated_config:
|
|
||||||
# The platform has been reloaded
|
|
||||||
config_yaml = mqtt_data.updated_config
|
|
||||||
else:
|
|
||||||
config_yaml = mqtt_data.config or {}
|
|
||||||
if not config_yaml:
|
|
||||||
return
|
|
||||||
if platform_domain not in config_yaml:
|
|
||||||
return
|
|
||||||
await asyncio.gather(
|
|
||||||
*(
|
|
||||||
discovery.async_load_platform(hass, platform_domain, DOMAIN, config, {})
|
|
||||||
for config in await async_get_platform_config_from_yaml(
|
|
||||||
hass, platform_domain, config_yaml
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_get_platform_config_from_yaml(
|
async def async_get_platform_config_from_yaml(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
platform_domain: str,
|
platform_domain: str,
|
||||||
|
@ -350,7 +328,7 @@ async def async_setup_entry_helper(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
domain: str,
|
domain: str,
|
||||||
async_setup: partial[Coroutine[HomeAssistant, str, None]],
|
async_setup: partial[Coroutine[HomeAssistant, str, None]],
|
||||||
schema: vol.Schema,
|
discovery_schema: vol.Schema,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up entity, automation or tag creation dynamically through MQTT discovery."""
|
"""Set up entity, automation or tag creation dynamically through MQTT discovery."""
|
||||||
mqtt_data: MqttData = hass.data[DATA_MQTT]
|
mqtt_data: MqttData = hass.data[DATA_MQTT]
|
||||||
|
@ -367,7 +345,7 @@ async def async_setup_entry_helper(
|
||||||
return
|
return
|
||||||
discovery_data = discovery_payload.discovery_data
|
discovery_data = discovery_payload.discovery_data
|
||||||
try:
|
try:
|
||||||
config = schema(discovery_payload)
|
config = discovery_schema(discovery_payload)
|
||||||
await async_setup(config, discovery_data=discovery_data)
|
await async_setup(config, discovery_data=discovery_data)
|
||||||
except Exception:
|
except Exception:
|
||||||
discovery_hash = discovery_data[ATTR_DISCOVERY_HASH]
|
discovery_hash = discovery_data[ATTR_DISCOVERY_HASH]
|
||||||
|
@ -383,6 +361,31 @@ async def async_setup_entry_helper(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def _async_setup_entities() -> None:
|
||||||
|
"""Set up MQTT items from configuration.yaml."""
|
||||||
|
mqtt_data: MqttData = hass.data[DATA_MQTT]
|
||||||
|
if mqtt_data.updated_config:
|
||||||
|
# The platform has been reloaded
|
||||||
|
config_yaml = mqtt_data.updated_config
|
||||||
|
else:
|
||||||
|
config_yaml = mqtt_data.config or {}
|
||||||
|
if not config_yaml:
|
||||||
|
return
|
||||||
|
if domain not in config_yaml:
|
||||||
|
return
|
||||||
|
await asyncio.gather(
|
||||||
|
*[
|
||||||
|
async_setup(config)
|
||||||
|
for config in await async_get_platform_config_from_yaml(
|
||||||
|
hass, domain, config_yaml
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# discover manual configured MQTT items
|
||||||
|
mqtt_data.reload_handlers[domain] = _async_setup_entities
|
||||||
|
await _async_setup_entities()
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform_helper(
|
async def async_setup_platform_helper(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
|
|
@ -44,7 +44,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -138,9 +137,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT number through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT number through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, number.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,6 @@ from .mixins import (
|
||||||
CONF_OBJECT_ID,
|
CONF_OBJECT_ID,
|
||||||
MQTT_AVAILABILITY_SCHEMA,
|
MQTT_AVAILABILITY_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -79,9 +78,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT scene through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT scene through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, scene.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,7 +30,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -93,9 +92,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT select through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT select through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, select.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""Support for MQTT sensors."""
|
"""Support for MQTT sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import subscription
|
from . import subscription
|
||||||
|
@ -41,7 +41,6 @@ from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttAvailability,
|
MqttAvailability,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -146,9 +145,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT sensor through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT sensor through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, sensor.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
@ -347,12 +343,12 @@ class MqttSensor(MqttEntity, RestoreSensor):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_unit_of_measurement(self):
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
"""Return the unit this state is expressed in."""
|
"""Return the unit this state is expressed in."""
|
||||||
return self._config.get(CONF_UNIT_OF_MEASUREMENT)
|
return self._config.get(CONF_UNIT_OF_MEASUREMENT)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self) -> StateType | datetime:
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -140,9 +139,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT siren through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT siren through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, siren.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,7 +42,6 @@ from .debug_info import log_messages
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
MQTT_ENTITY_COMMON_SCHEMA,
|
MQTT_ENTITY_COMMON_SCHEMA,
|
||||||
MqttEntity,
|
MqttEntity,
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
async_setup_entry_helper,
|
||||||
async_setup_platform_helper,
|
async_setup_platform_helper,
|
||||||
warn_for_legacy_schema,
|
warn_for_legacy_schema,
|
||||||
|
@ -101,9 +100,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT switch through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT switch through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, switch.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,11 +11,7 @@ from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from ..mixins import (
|
from ..mixins import async_setup_entry_helper, async_setup_platform_helper
|
||||||
async_discover_yaml_entities,
|
|
||||||
async_setup_entry_helper,
|
|
||||||
async_setup_platform_helper,
|
|
||||||
)
|
|
||||||
from .schema import CONF_SCHEMA, LEGACY, MQTT_VACUUM_SCHEMA, STATE
|
from .schema import CONF_SCHEMA, LEGACY, MQTT_VACUUM_SCHEMA, STATE
|
||||||
from .schema_legacy import (
|
from .schema_legacy import (
|
||||||
DISCOVERY_SCHEMA_LEGACY,
|
DISCOVERY_SCHEMA_LEGACY,
|
||||||
|
@ -90,9 +86,6 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MQTT vacuum through configuration.yaml and dynamically through MQTT discovery."""
|
"""Set up MQTT vacuum through configuration.yaml and dynamically through MQTT discovery."""
|
||||||
# load and initialize platform config from configuration.yaml
|
|
||||||
await async_discover_yaml_entities(hass, vacuum.DOMAIN)
|
|
||||||
# setup for discovery
|
|
||||||
setup = functools.partial(
|
setup = functools.partial(
|
||||||
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
_async_setup_entity, hass, async_add_entities, config_entry=config_entry
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,11 +29,13 @@ from homeassistant.core import CoreState, HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import device_registry as dr, template
|
from homeassistant.helpers import device_registry as dr, template
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.helpers.entity_platform import async_get_platforms
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
|
|
||||||
from .test_common import (
|
from .test_common import (
|
||||||
help_test_entry_reload_with_new_config,
|
help_test_entry_reload_with_new_config,
|
||||||
|
help_test_reload_with_config,
|
||||||
help_test_setup_manual_entity_from_yaml,
|
help_test_setup_manual_entity_from_yaml,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2986,3 +2988,68 @@ async def test_remove_unknown_conf_entry_options(hass, mqtt_client_mock, caplog)
|
||||||
"MQTT config entry: {'protocol'}. Add them to configuration.yaml if they "
|
"MQTT config entry: {'protocol'}. Add them to configuration.yaml if they "
|
||||||
"are needed"
|
"are needed"
|
||||||
) in caplog.text
|
) in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.LIGHT])
|
||||||
|
async def test_link_config_entry(hass, tmp_path, caplog):
|
||||||
|
"""Test manual and dynamically setup entities are linked to the config entry."""
|
||||||
|
config_manual = {
|
||||||
|
"mqtt": {
|
||||||
|
"light": [
|
||||||
|
{
|
||||||
|
"name": "test_manual",
|
||||||
|
"unique_id": "test_manual_unique_id123",
|
||||||
|
"command_topic": "test-topic_manual",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_discovery = {
|
||||||
|
"name": "test_discovery",
|
||||||
|
"unique_id": "test_discovery_unique456",
|
||||||
|
"command_topic": "test-topic_discovery",
|
||||||
|
}
|
||||||
|
|
||||||
|
# set up manual item
|
||||||
|
await help_test_setup_manual_entity_from_yaml(hass, config_manual)
|
||||||
|
|
||||||
|
# set up item through discovery
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "homeassistant/light/bla/config", json.dumps(config_discovery)
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("light.test_manual") is not None
|
||||||
|
assert hass.states.get("light.test_discovery") is not None
|
||||||
|
entity_names = ["test_manual", "test_discovery"]
|
||||||
|
|
||||||
|
# Check if both entities were linked to the MQTT config entry
|
||||||
|
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
|
||||||
|
mqtt_platforms = async_get_platforms(hass, mqtt.DOMAIN)
|
||||||
|
|
||||||
|
def _check_entities():
|
||||||
|
entities = []
|
||||||
|
for mqtt_platform in mqtt_platforms:
|
||||||
|
assert mqtt_platform.config_entry is mqtt_config_entry
|
||||||
|
entities += (entity for entity in mqtt_platform.entities.values())
|
||||||
|
|
||||||
|
for entity in entities:
|
||||||
|
assert entity.name in entity_names
|
||||||
|
return len(entities)
|
||||||
|
|
||||||
|
assert _check_entities() == 2
|
||||||
|
|
||||||
|
# reload entry and assert again
|
||||||
|
await help_test_entry_reload_with_new_config(hass, tmp_path, config_manual)
|
||||||
|
# manual set up item should remain
|
||||||
|
assert _check_entities() == 1
|
||||||
|
# set up item through discovery
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "homeassistant/light/bla/config", json.dumps(config_discovery)
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert _check_entities() == 2
|
||||||
|
|
||||||
|
# reload manual configured items and assert again
|
||||||
|
await help_test_reload_with_config(hass, caplog, tmp_path, config_manual)
|
||||||
|
assert _check_entities() == 2
|
||||||
|
|
Loading…
Reference in New Issue