mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Add entity_platform helper function to create issues when platform setup is not supported by integration (#171105)
Co-authored-by: Erik Montnemery <erik@montnemery.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Erik Montnemery
Copilot Autofix powered by AI
parent
f823ef639a
commit
3fee05db71
@@ -7,12 +7,6 @@
|
||||
"message": "Timeout trying to execute command: {command}"
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"platform_yaml_not_supported": {
|
||||
"description": "Platform YAML setup is not supported.\nChange from configuring it using the `{platform}:` key to using the `command_line:` key directly in configuration.yaml and restart Home Assistant to resolve the issue.\nTo see the detailed documentation, select Learn more.",
|
||||
"title": "Platform YAML is not supported in Command Line"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"reload": {
|
||||
"description": "Reloads command line configuration from the YAML-configuration.",
|
||||
|
||||
@@ -4,7 +4,9 @@ import asyncio
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.template import Template
|
||||
|
||||
from .const import DOMAIN, LOGGER
|
||||
@@ -98,13 +100,11 @@ def create_platform_yaml_not_supported_issue(
|
||||
hass: HomeAssistant, platform_domain: str
|
||||
) -> None:
|
||||
"""Create an issue when platform yaml is used."""
|
||||
async_create_issue(
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
f"{platform_domain}_platform_yaml_not_supported",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.ERROR,
|
||||
translation_key="platform_yaml_not_supported",
|
||||
translation_placeholders={"platform": platform_domain},
|
||||
platform_domain,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/command_line/",
|
||||
logger=LOGGER,
|
||||
)
|
||||
|
||||
@@ -91,6 +91,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the Compensation sensor."""
|
||||
hass.data[DATA_COMPENSATION] = {}
|
||||
|
||||
# Exit early if no compensations are configured using the compensation: key in configuration.yaml.
|
||||
# This allows us to create an issue if platform: compensation is present in the sensor: section.
|
||||
if DOMAIN not in config:
|
||||
return True
|
||||
|
||||
for compensation, conf in config[DOMAIN].items():
|
||||
_LOGGER.debug("Setup %s.%s", DOMAIN, compensation)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import numpy as np
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
CONF_STATE_CLASS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorEntity,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
@@ -31,7 +32,10 @@ from homeassistant.core import (
|
||||
State,
|
||||
callback,
|
||||
)
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.event import async_track_state_change_event
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
@@ -41,6 +45,7 @@ from .const import (
|
||||
CONF_PRECISION,
|
||||
DATA_COMPENSATION,
|
||||
DEFAULT_NAME,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -58,6 +63,14 @@ async def async_setup_platform(
|
||||
) -> None:
|
||||
"""Set up the Compensation sensor."""
|
||||
if discovery_info is None:
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
SENSOR_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/compensation/",
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
compensation: str = discovery_info[CONF_COMPENSATION]
|
||||
|
||||
@@ -167,10 +167,6 @@
|
||||
"description": "Please do the following steps:\n- Adopt your configuration to support template rendering to native python types.\n- Remove the `legacy_templates` key from the `homeassistant` configuration in your configuration.yaml file.\n- Restart Home Assistant to fix this issue.",
|
||||
"title": "The support for legacy templates is being removed"
|
||||
},
|
||||
"no_platform_setup": {
|
||||
"description": "It's not possible to configure {platform} {domain} by adding `{platform_key}` to the {domain} configuration. Please check the documentation for more information on how to set up this integration.\n\nTo resolve this:\n1. Remove `{platform_key}` occurrences from the `{domain}:` configuration in your YAML configuration file.\n2. Restart Home Assistant.\n\nExample that should be removed:\n{yaml_example}",
|
||||
"title": "Unused YAML configuration for the {platform} integration"
|
||||
},
|
||||
"orphaned_ignored_config_entry": {
|
||||
"fix_flow": {
|
||||
"abort": {
|
||||
@@ -189,10 +185,18 @@
|
||||
},
|
||||
"title": "Orphaned ignored config entry for {domain}"
|
||||
},
|
||||
"platform_config_not_supported": {
|
||||
"description": "Configuring the {integration_domain} integration by adding `{platform_key}` under the `{platform_domain}:` key is not supported. The {integration_domain} integration must be configured under its own `{integration_domain}:` key instead.\n\nTo resolve this:\n\n1. Remove the following from your YAML configuration file:\n\n{yaml_example}\n\n2. Move the configuration under the `{integration_domain}:` key instead.\n\n3. Restart Home Assistant.\n\nTo see the detailed documentation, select Learn more.",
|
||||
"title": "Unsupported YAML configuration for the {integration_domain} integration"
|
||||
},
|
||||
"platform_only": {
|
||||
"description": "The {domain} integration does not support configuration under its own key, it must be configured under its supported platforms.\n\nTo resolve this:\n\n1. Remove `{domain}:` from your YAML configuration file.\n\n2. Restart Home Assistant.",
|
||||
"title": "The {domain} integration does not support YAML configuration under its own key"
|
||||
},
|
||||
"platform_setup_not_supported": {
|
||||
"description": "It's not possible to configure {integration_domain} {platform_domain} by adding `{platform_key}` to the {platform_domain} configuration. Please check the documentation for more information on how to set up this integration.\n\nTo resolve this:\n\n1. Remove `{platform_key}` occurrences from the `{platform_domain}:` configuration in your YAML configuration file.\n\n2. Restart Home Assistant.",
|
||||
"title": "Unused YAML configuration for the {integration_domain} integration"
|
||||
},
|
||||
"storage_corruption": {
|
||||
"fix_flow": {
|
||||
"step": {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"""Support for getting data from websites with scraping."""
|
||||
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import CONF_STATE_CLASS
|
||||
from homeassistant.components.sensor import CONF_STATE_CLASS, DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import (
|
||||
CONF_ATTRIBUTE,
|
||||
CONF_DEVICE_CLASS,
|
||||
@@ -21,6 +21,7 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.template import _SENTINEL, Template
|
||||
from homeassistant.helpers.trigger_template_entity import (
|
||||
@@ -59,7 +60,17 @@ async def async_setup_platform(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up the Web scrape sensor."""
|
||||
discovery_info = cast(DiscoveryInfoType, discovery_info)
|
||||
if discovery_info is None:
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
SENSOR_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/scrape/",
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
coordinator: ScrapeCoordinator = discovery_info["coordinator"]
|
||||
sensors_config: list[ConfigType] = discovery_info["configs"]
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import scoped_session
|
||||
|
||||
from homeassistant.components.recorder import CONF_DB_URL, get_instance
|
||||
from homeassistant.components.sensor import CONF_STATE_CLASS
|
||||
from homeassistant.components.sensor import CONF_STATE_CLASS, DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE_CLASS,
|
||||
@@ -25,8 +25,8 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.template import Template
|
||||
from homeassistant.helpers.trigger_template_entity import (
|
||||
CONF_AVAILABILITY,
|
||||
@@ -69,14 +69,13 @@ async def async_setup_platform(
|
||||
) -> None:
|
||||
"""Set up the SQL sensor from yaml."""
|
||||
if (conf := discovery_info) is None:
|
||||
async_create_issue(
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
"sensor_platform_yaml_not_supported",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="platform_yaml_not_supported",
|
||||
SENSOR_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/sql/",
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -66,10 +66,6 @@
|
||||
"entity_id_query_does_full_table_scan": {
|
||||
"description": "The query `{query}` contains the keyword `entity_id` but does not reference the `states_meta` table. This will cause a full table scan and database instability. Please check the documentation and use `states_meta.entity_id` instead.",
|
||||
"title": "SQL query does full table scan"
|
||||
},
|
||||
"platform_yaml_not_supported": {
|
||||
"description": "Platform YAML setup is not supported.\nChange from configuring it in the `sensor:` key to using the `sql:` key directly in configuration.yaml.\nTo see the detailed documentation, select Learn more.",
|
||||
"title": "Platform YAML is not supported in SQL"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
||||
@@ -19,6 +19,8 @@ CONF_TURN_ON = "turn_on"
|
||||
|
||||
DOMAIN = "template"
|
||||
|
||||
DOCUMENTATION_URL = "https://www.home-assistant.io/integrations/template/"
|
||||
|
||||
PLATFORM_STORAGE_KEY = "template_platforms"
|
||||
|
||||
PLATFORMS = [
|
||||
|
||||
@@ -32,6 +32,7 @@ from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
async_get_platforms,
|
||||
)
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity
|
||||
@@ -50,6 +51,7 @@ from .const import (
|
||||
CONF_AVAILABILITY_TEMPLATE,
|
||||
CONF_DEFAULT_ENTITY_ID,
|
||||
CONF_PICTURE,
|
||||
DOCUMENTATION_URL,
|
||||
DOMAIN,
|
||||
PLATFORMS,
|
||||
)
|
||||
@@ -372,8 +374,13 @@ async def async_setup_template_platform(
|
||||
None,
|
||||
)
|
||||
else:
|
||||
_LOGGER.warning(
|
||||
"Template %s entities can only be configured under template:", domain
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
domain,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url=DOCUMENTATION_URL,
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.restore_state import ExtraStoredData, RestoreEntity
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
@@ -51,7 +52,8 @@ from homeassistant.util.unit_conversion import (
|
||||
TemperatureConverter,
|
||||
)
|
||||
|
||||
from . import TriggerUpdateCoordinator, validators as template_validators
|
||||
from . import DOMAIN, TriggerUpdateCoordinator, validators as template_validators
|
||||
from .const import DOCUMENTATION_URL
|
||||
from .entity import AbstractTemplateEntity
|
||||
from .helpers import (
|
||||
async_setup_template_entry,
|
||||
@@ -242,8 +244,13 @@ async def async_setup_platform(
|
||||
|
||||
# Rewrite the configuration options to modern keys.
|
||||
if discovery_info is None:
|
||||
_LOGGER.warning(
|
||||
"Template weather entities can only be configured under template:"
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
WEATHER_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url=DOCUMENTATION_URL,
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from homeassistant.components.select import SelectEntity
|
||||
from homeassistant.components.select import DOMAIN as SELECT_DOMAIN, SelectEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_NAME, CONF_UNIQUE_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -11,11 +11,12 @@ from homeassistant.helpers.device_registry import DeviceEntry
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from .const import CONF_METER, CONF_SOURCE_SENSOR, CONF_TARIFFS, DATA_UTILITY
|
||||
from .const import CONF_METER, CONF_SOURCE_SENSOR, CONF_TARIFFS, DATA_UTILITY, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -53,9 +54,13 @@ async def async_setup_platform(
|
||||
) -> None:
|
||||
"""Set up the utility meter select."""
|
||||
if discovery_info is None:
|
||||
_LOGGER.error(
|
||||
"This platform is not available to configure "
|
||||
"from 'select:' in configuration.yaml"
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
SELECT_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/utility_meter/",
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ from homeassistant.components.sensor import (
|
||||
ATTR_LAST_RESET,
|
||||
DEVICE_CLASS_STATE_CLASSES,
|
||||
DEVICE_CLASS_UNITS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
RestoreSensor,
|
||||
SensorDeviceClass,
|
||||
SensorExtraStoredData,
|
||||
@@ -46,6 +47,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
async_create_platform_config_not_supported_issue,
|
||||
)
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_point_in_time,
|
||||
@@ -75,6 +77,7 @@ from .const import (
|
||||
DAILY,
|
||||
DATA_TARIFF_SENSORS,
|
||||
DATA_UTILITY,
|
||||
DOMAIN,
|
||||
HOURLY,
|
||||
MONTHLY,
|
||||
QUARTER_HOURLY,
|
||||
@@ -212,9 +215,13 @@ async def async_setup_platform(
|
||||
) -> None:
|
||||
"""Set up the utility meter sensor."""
|
||||
if discovery_info is None:
|
||||
_LOGGER.error(
|
||||
"This platform is not available to configure "
|
||||
"from 'sensor:' in configuration.yaml"
|
||||
async_create_platform_config_not_supported_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
SENSOR_DOMAIN,
|
||||
yaml_config_under_integration_supported=True,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/utility_meter/",
|
||||
logger=_LOGGER,
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@@ -66,6 +66,61 @@ PLATFORM_NOT_READY_BASE_WAIT_TIME = 30 # seconds
|
||||
_LOGGER = getLogger(__name__)
|
||||
|
||||
|
||||
@callback
|
||||
def async_create_platform_config_not_supported_issue(
|
||||
hass: HomeAssistant,
|
||||
integration_domain: str,
|
||||
platform_domain: str,
|
||||
*,
|
||||
yaml_config_under_integration_supported: bool = False,
|
||||
learn_more_url: str | None = None,
|
||||
logger: Logger = _LOGGER,
|
||||
) -> None:
|
||||
"""Create a repair issue for an unsupported YAML platform configuration.
|
||||
|
||||
Raised when an integration is configured via the legacy
|
||||
<platform_domain>: - platform: <integration_domain> schema.
|
||||
Set yaml_config_under_integration_supported=False if the integration does
|
||||
not support YAML configuration for this platform and the config should be
|
||||
removed. Set it to True if the integration supports YAML configuration
|
||||
under its own <integration_domain>: key and the config should be moved
|
||||
there.
|
||||
"""
|
||||
if yaml_config_under_integration_supported:
|
||||
logger.error(
|
||||
"Configuring the %s integration under the %s platform key is not"
|
||||
" supported, it must be configured under its own %s key instead",
|
||||
integration_domain,
|
||||
platform_domain,
|
||||
integration_domain,
|
||||
)
|
||||
else:
|
||||
logger.error(
|
||||
"The %s platform for the %s integration does not support platform"
|
||||
" setup, please remove it from your config",
|
||||
integration_domain,
|
||||
platform_domain,
|
||||
)
|
||||
platform_key = f"platform: {integration_domain}"
|
||||
yaml_example = f"```yaml\n{platform_domain}:\n - {platform_key}\n```"
|
||||
async_create_issue(
|
||||
hass,
|
||||
HOMEASSISTANT_DOMAIN,
|
||||
f"platform_integration_no_support_{platform_domain}_{integration_domain}",
|
||||
is_fixable=False,
|
||||
issue_domain=integration_domain,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=IssueSeverity.ERROR,
|
||||
translation_key=f"platform_{'config' if yaml_config_under_integration_supported else 'setup'}_not_supported",
|
||||
translation_placeholders={
|
||||
"platform_domain": platform_domain,
|
||||
"integration_domain": integration_domain,
|
||||
"platform_key": platform_key,
|
||||
"yaml_example": yaml_example,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class AddEntitiesCallback(Protocol):
|
||||
"""Protocol type for EntityPlatform.add_entities callback."""
|
||||
|
||||
@@ -315,14 +370,6 @@ class EntityPlatform:
|
||||
if not hasattr(platform, "async_setup_platform") and not hasattr(
|
||||
platform, "setup_platform"
|
||||
):
|
||||
self.logger.error(
|
||||
(
|
||||
"The %s platform for the %s integration does not support platform"
|
||||
" setup. Please remove it from your config."
|
||||
),
|
||||
self.platform_name,
|
||||
self.domain,
|
||||
)
|
||||
learn_more_url = None
|
||||
if self.platform:
|
||||
if "custom_components" in self.platform.__file__: # type: ignore[attr-defined]
|
||||
@@ -337,25 +384,14 @@ class EntityPlatform:
|
||||
)
|
||||
else:
|
||||
learn_more_url = f"https://www.home-assistant.io/integrations/{self.platform_name}/"
|
||||
platform_key = f"platform: {self.platform_name}"
|
||||
yaml_example = f"```yaml\n{self.domain}:\n - {platform_key}\n```"
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
HOMEASSISTANT_DOMAIN,
|
||||
f"platform_integration_no_support_{self.domain}_{self.platform_name}",
|
||||
is_fixable=False,
|
||||
issue_domain=self.platform_name,
|
||||
learn_more_url=learn_more_url,
|
||||
severity=IssueSeverity.ERROR,
|
||||
translation_key="no_platform_setup",
|
||||
translation_placeholders={
|
||||
"domain": self.domain,
|
||||
"platform": self.platform_name,
|
||||
"platform_key": platform_key,
|
||||
"yaml_example": yaml_example,
|
||||
},
|
||||
)
|
||||
|
||||
async_create_platform_config_not_supported_issue(
|
||||
self.hass,
|
||||
self.platform_name,
|
||||
self.domain,
|
||||
learn_more_url=learn_more_url,
|
||||
logger=self.logger,
|
||||
)
|
||||
return
|
||||
|
||||
@callback
|
||||
|
||||
@@ -100,6 +100,7 @@ from homeassistant.helpers.entity_platform import (
|
||||
)
|
||||
from homeassistant.helpers.json import JSONEncoder, _orjson_default_encoder, json_dumps
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util, ulid as ulid_util, uuid as uuid_util
|
||||
from homeassistant.util.async_ import (
|
||||
_SHUTDOWN_RUN_CALLBACK_THREADSAFE,
|
||||
@@ -2026,3 +2027,47 @@ def get_sensor_display_state(
|
||||
numerical_value = float(value)
|
||||
value = f"{numerical_value:z.{precision}f}"
|
||||
return value
|
||||
|
||||
|
||||
async def assert_platform_setup_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
platform_domain: str,
|
||||
integration_domain: str,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Assert that setting up a platform creates an issue."""
|
||||
caplog.clear()
|
||||
with assert_setup_component(1, platform_domain):
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
platform_domain,
|
||||
{platform_domain: {"platform": integration_domain}},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(hass.states.async_all(platform_domain)) == 0
|
||||
assert (
|
||||
f"Configuring the {integration_domain} integration under the {platform_domain} platform key is not"
|
||||
f" supported, it must be configured under its own {integration_domain} key instead"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
issue = issue_registry.async_get_issue(
|
||||
"homeassistant",
|
||||
f"platform_integration_no_support_{platform_domain}_{integration_domain}",
|
||||
)
|
||||
|
||||
assert issue
|
||||
assert issue.issue_domain == integration_domain
|
||||
assert issue.learn_more_url is not None
|
||||
assert issue.translation_key == "platform_config_not_supported"
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {
|
||||
"platform_domain": platform_domain,
|
||||
"integration_domain": integration_domain,
|
||||
"platform_key": f"platform: {integration_domain}",
|
||||
"yaml_example": f"```yaml\n{platform_domain}:\n - platform: {integration_domain}\n```",
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
|
||||
from homeassistant import setup
|
||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||
from homeassistant.components.command_line.binary_sensor import CommandBinarySensor
|
||||
from homeassistant.components.command_line.const import DOMAIN
|
||||
from homeassistant.components.homeassistant import (
|
||||
@@ -18,7 +17,7 @@ from homeassistant.components.homeassistant import (
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import mock_asyncio_subprocess_run
|
||||
@@ -55,33 +54,6 @@ async def test_setup_integration_yaml(
|
||||
assert entity_state.name == "Test"
|
||||
|
||||
|
||||
async def test_setup_platform_yaml(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test setting up the platform with platform yaml."""
|
||||
await setup.async_setup_component(
|
||||
hass,
|
||||
"binary_sensor",
|
||||
{
|
||||
"binary_sensor": {
|
||||
"platform": "command_line",
|
||||
"command": "echo 1",
|
||||
"payload_on": "1",
|
||||
"payload_off": "0",
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 0
|
||||
|
||||
issue = issue_registry.async_get_issue(
|
||||
DOMAIN, "binary_sensor_platform_yaml_not_supported"
|
||||
)
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {"platform": BINARY_SENSOR_DOMAIN}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"get_config",
|
||||
[
|
||||
|
||||
@@ -29,7 +29,7 @@ from homeassistant.const import (
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import mock_asyncio_subprocess_run
|
||||
@@ -37,30 +37,6 @@ from . import mock_asyncio_subprocess_run
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_setup_platform_yaml(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test setting up the platform with platform yaml."""
|
||||
await setup.async_setup_component(
|
||||
hass,
|
||||
"cover",
|
||||
{
|
||||
"cover": {
|
||||
"platform": "command_line",
|
||||
"command": "echo 1",
|
||||
"payload_on": "1",
|
||||
"payload_off": "0",
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 0
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "cover_platform_yaml_not_supported")
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {"platform": COVER_DOMAIN}
|
||||
|
||||
|
||||
async def test_no_poll_when_cover_has_no_command_state(hass: HomeAssistant) -> None:
|
||||
"""Test that the cover does not polls when there's no state command."""
|
||||
|
||||
|
||||
@@ -9,9 +9,40 @@ from homeassistant import config as hass_config
|
||||
from homeassistant.components.command_line.const import DOMAIN
|
||||
from homeassistant.const import SERVICE_RELOAD, STATE_ON, STATE_OPEN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed, get_fixture_path
|
||||
from tests.common import (
|
||||
assert_platform_setup_creates_issue,
|
||||
async_fire_time_changed,
|
||||
get_fixture_path,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"platform_domain",
|
||||
[
|
||||
"binary_sensor",
|
||||
"cover",
|
||||
"notify",
|
||||
"sensor",
|
||||
"switch",
|
||||
],
|
||||
)
|
||||
async def test_platform_config_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
platform_domain: str,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test invalid platform config creates issue and logs a warning."""
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
platform_domain,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_config(hass: HomeAssistant, load_yaml_integration: None) -> None:
|
||||
|
||||
@@ -13,31 +13,6 @@ from homeassistant.components.command_line import DOMAIN
|
||||
from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
|
||||
|
||||
async def test_setup_platform_yaml(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test setting up the platform with platform yaml."""
|
||||
await setup.async_setup_component(
|
||||
hass,
|
||||
"notify",
|
||||
{
|
||||
"notify": {
|
||||
"platform": "command_line",
|
||||
"command": "echo 1",
|
||||
"payload_on": "1",
|
||||
"payload_off": "0",
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 0
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "notify_platform_yaml_not_supported")
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {"platform": NOTIFY_DOMAIN}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -15,10 +15,9 @@ from homeassistant.components.homeassistant import (
|
||||
DOMAIN as HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
)
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import mock_asyncio_subprocess_run
|
||||
@@ -26,30 +25,6 @@ from . import mock_asyncio_subprocess_run
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_setup_platform_yaml(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test setting up the platform with platform yaml."""
|
||||
await setup.async_setup_component(
|
||||
hass,
|
||||
"sensor",
|
||||
{
|
||||
"sensor": {
|
||||
"platform": "command_line",
|
||||
"command": "echo 1",
|
||||
"payload_on": "1",
|
||||
"payload_off": "0",
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 0
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "sensor_platform_yaml_not_supported")
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {"platform": SENSOR_DOMAIN}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"get_config",
|
||||
[
|
||||
|
||||
@@ -27,7 +27,7 @@ from homeassistant.const import (
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import mock_asyncio_subprocess_run
|
||||
@@ -35,30 +35,6 @@ from . import mock_asyncio_subprocess_run
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_setup_platform_yaml(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test setting up the platform with platform yaml."""
|
||||
await setup.async_setup_component(
|
||||
hass,
|
||||
"switch",
|
||||
{
|
||||
"switch": {
|
||||
"platform": "command_line",
|
||||
"command": "echo 1",
|
||||
"payload_on": "1",
|
||||
"payload_off": "0",
|
||||
}
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 0
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "switch_platform_yaml_not_supported")
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.ERROR
|
||||
assert issue.translation_placeholders == {"platform": SWITCH_DOMAIN}
|
||||
|
||||
|
||||
async def test_state_integration_yaml(hass: HomeAssistant) -> None:
|
||||
"""Test with none state."""
|
||||
with tempfile.TemporaryDirectory() as tempdirname:
|
||||
|
||||
@@ -10,6 +10,7 @@ from homeassistant.components.compensation.const import CONF_PRECISION, DOMAIN
|
||||
from homeassistant.components.compensation.sensor import ATTR_COEFFICIENTS
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
@@ -24,9 +25,14 @@ from homeassistant.const import (
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import assert_setup_component, get_fixture_path
|
||||
from tests.common import (
|
||||
assert_platform_setup_creates_issue,
|
||||
assert_setup_component,
|
||||
get_fixture_path,
|
||||
)
|
||||
|
||||
TEST_OBJECT_ID = "test_compensation"
|
||||
TEST_ENTITY_ID = "sensor.test_compensation"
|
||||
@@ -47,6 +53,21 @@ TEST_CONFIG = {
|
||||
}
|
||||
|
||||
|
||||
async def test_platform_config_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test invalid platform config creates issue and logs a warning."""
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_compensation(hass: HomeAssistant, config: dict[str, Any]) -> None:
|
||||
"""Do setup of a compensation integration sensor."""
|
||||
with assert_setup_component(1, DOMAIN):
|
||||
|
||||
@@ -16,6 +16,7 @@ from homeassistant.components.scrape.const import (
|
||||
)
|
||||
from homeassistant.components.sensor import (
|
||||
CONF_STATE_CLASS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
@@ -35,7 +36,7 @@ from homeassistant.const import (
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.helpers.trigger_template_entity import (
|
||||
CONF_AVAILABILITY,
|
||||
CONF_PICTURE,
|
||||
@@ -45,11 +46,30 @@ from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import MockRestData, return_integration_config
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_platform_setup_creates_issue,
|
||||
async_fire_time_changed,
|
||||
)
|
||||
|
||||
DOMAIN = "scrape"
|
||||
|
||||
|
||||
async def test_platform_config_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test invalid platform config creates issue and logs a warning."""
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
async def test_scrape_sensor(hass: HomeAssistant) -> None:
|
||||
"""Test Scrape sensor minimal."""
|
||||
config = {
|
||||
|
||||
@@ -13,6 +13,7 @@ from sqlalchemy.exc import SQLAlchemyError
|
||||
from homeassistant.components.recorder import CONF_DB_URL, Recorder
|
||||
from homeassistant.components.sensor import (
|
||||
CONF_STATE_CLASS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
@@ -50,7 +51,11 @@ from . import (
|
||||
init_integration,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_platform_setup_creates_issue,
|
||||
async_fire_time_changed,
|
||||
)
|
||||
|
||||
|
||||
async def test_query_basic(recorder_mock: Recorder, hass: HomeAssistant) -> None:
|
||||
@@ -432,30 +437,19 @@ async def test_templates_with_yaml(
|
||||
|
||||
|
||||
async def test_config_from_old_yaml(
|
||||
recorder_mock: Recorder, hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
recorder_mock: Recorder,
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the SQL sensor from old yaml config does not create any entity."""
|
||||
config = {
|
||||
"sensor": {
|
||||
"platform": "sql",
|
||||
CONF_DB_URL: "sqlite://",
|
||||
"queries": [
|
||||
{
|
||||
CONF_NAME: "count_tables",
|
||||
CONF_QUERY: "SELECT 5 as value",
|
||||
CONF_COLUMN_NAME: "value",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
assert await async_setup_component(hass, "sensor", config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.count_tables")
|
||||
assert not state
|
||||
issue = issue_registry.async_get_issue(DOMAIN, "sensor_platform_yaml_not_supported")
|
||||
assert issue is not None
|
||||
assert issue.severity == ir.IssueSeverity.WARNING
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -350,19 +350,6 @@ async def test_template_syntax_error(
|
||||
assert (msg) in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY)],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_panel")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("alarm_control_panel")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "attribute", "attribute_template"),
|
||||
[(1, "disarmed", "name", '{{ "Template Alarm Panel" }}')],
|
||||
|
||||
@@ -234,19 +234,6 @@ async def test_setup_invalid_sensors(hass: HomeAssistant, count: int) -> None:
|
||||
assert len(hass.states.async_entity_ids("binary_sensor")) == count
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style", "extra_config"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY, {})],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_binary_sensor")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("binary_sensor")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("state_template", "expected_result"),
|
||||
[
|
||||
|
||||
@@ -6,6 +6,7 @@ import voluptuous as vol
|
||||
from homeassistant.components.template import DOMAIN
|
||||
from homeassistant.components.template.config import (
|
||||
CONFIG_SECTION_SCHEMA,
|
||||
PLATFORMS,
|
||||
async_validate_config_section,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -14,6 +15,28 @@ from homeassistant.helpers.script_variables import ScriptVariables
|
||||
from homeassistant.helpers.template import Template
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import assert_platform_setup_creates_issue
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"platform_domain",
|
||||
PLATFORMS,
|
||||
)
|
||||
async def test_platform_config_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
platform_domain: str,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test invalid platform config creates issue and logs a warning."""
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
platform_domain,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config",
|
||||
|
||||
@@ -161,26 +161,6 @@ async def setup_empty_action(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style", "config"),
|
||||
[
|
||||
(
|
||||
1,
|
||||
"{{ states('sensor.test_state') }}",
|
||||
ConfigurationStyle.LEGACY,
|
||||
COVER_ACTIONS,
|
||||
)
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_cover")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("cover")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "config"),
|
||||
[(1, "{{ states.sensor.test_state.state }}", COVER_ACTIONS)],
|
||||
|
||||
@@ -113,21 +113,6 @@ async def setup_single_attribute_state_event(
|
||||
)
|
||||
|
||||
|
||||
async def test_legacy_platform_config(hass: HomeAssistant) -> None:
|
||||
"""Test a legacy platform does not create event entities."""
|
||||
with assert_setup_component(1, event.DOMAIN):
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
event.DOMAIN,
|
||||
{"event": {"platform": "template", "events": {TEST_EVENT.object_id: {}}}},
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.async_all("event") == []
|
||||
|
||||
|
||||
@pytest.mark.freeze_time(TEST_FROZEN_INPUT)
|
||||
async def test_setup_config_entry(
|
||||
hass: HomeAssistant,
|
||||
|
||||
@@ -172,26 +172,6 @@ async def setup_single_attribute_state_fan(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style", "extra_config"),
|
||||
[
|
||||
(
|
||||
1,
|
||||
"{{ states('sensor.test_state') }}",
|
||||
ConfigurationStyle.LEGACY,
|
||||
OPTIMISTIC_ON_OFF_ACTIONS,
|
||||
)
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_fan")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("fan")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "extra_config"),
|
||||
[(1, "{{ 'on' }}", OPTIMISTIC_ON_OFF_ACTIONS)],
|
||||
|
||||
@@ -343,19 +343,6 @@ async def setup_light_with_transition_template(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style", "extra_config"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY, {})],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_light")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("light")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "extra_config"),
|
||||
[(1, "{{states.test['big.fat...']}}", {})],
|
||||
|
||||
@@ -132,19 +132,6 @@ async def setup_state_lock_with_attribute(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY)],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_lock")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("lock")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template"), [(1, "{{ states.sensor.test_state.state }}")]
|
||||
)
|
||||
|
||||
@@ -125,19 +125,6 @@ async def setup_attributes_state_sensor(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style", "config"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY, {})],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_sensor")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("sensor")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config_entry_extra_options",
|
||||
[
|
||||
|
||||
@@ -149,19 +149,6 @@ async def setup_single_attribute_optimistic_switch(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY)],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_switch")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("switch")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("count", "state_template"), [(1, "{{ True }}")])
|
||||
@pytest.mark.parametrize(
|
||||
"style",
|
||||
|
||||
@@ -125,21 +125,6 @@ async def setup_single_attribute_update(
|
||||
)
|
||||
|
||||
|
||||
async def test_legacy_platform_config(hass: HomeAssistant) -> None:
|
||||
"""Test a legacy platform does not create update entities."""
|
||||
with assert_setup_component(1, update.DOMAIN):
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
update.DOMAIN,
|
||||
{"update": {"platform": "template", "updates": {"anything": {}}}},
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.async_all("update") == []
|
||||
|
||||
|
||||
async def test_setup_config_entry(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
|
||||
@@ -191,19 +191,6 @@ async def setup_attributes_state_vacuum(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("count", "state_template", "style"),
|
||||
[(1, "{{ states('sensor.test_state') }}", ConfigurationStyle.LEGACY)],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_state_vacuum")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("vacuum")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("count", [1])
|
||||
@pytest.mark.parametrize(
|
||||
("style", "state_template", "extra_config", "parm1", "parm2"),
|
||||
|
||||
@@ -106,19 +106,6 @@ async def setup_weather(
|
||||
await setup_entity(hass, TEST_WEATHER, style, 1, config)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("style", "config"),
|
||||
[(ConfigurationStyle.LEGACY, TEST_LEGACY_REQUIRED)],
|
||||
)
|
||||
@pytest.mark.usefixtures("setup_weather")
|
||||
async def test_legacy_template_creates_warning(
|
||||
hass: HomeAssistant, caplog_setup_text
|
||||
) -> None:
|
||||
"""Test legacy YAML configuration logs a warning."""
|
||||
assert len(hass.states.async_all("weather")) == 0
|
||||
assert "entities can only be configured under template:" in caplog_setup_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"style", [ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER]
|
||||
)
|
||||
|
||||
@@ -28,12 +28,20 @@ from homeassistant.const import (
|
||||
UnitOfEnergy,
|
||||
)
|
||||
from homeassistant.core import Event, HomeAssistant, State, callback
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers import (
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
issue_registry as ir,
|
||||
)
|
||||
from homeassistant.helpers.event import async_track_entity_registry_updated_event
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import MockConfigEntry, mock_restore_cache
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_platform_setup_creates_issue,
|
||||
mock_restore_cache,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -116,6 +124,26 @@ def track_entity_registry_actions(hass: HomeAssistant, entity_id: str) -> list[s
|
||||
return events
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"platform_domain",
|
||||
["select", "sensor"],
|
||||
)
|
||||
async def test_platform_config_creates_issue(
|
||||
hass: HomeAssistant,
|
||||
platform_domain: str,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test invalid platform config creates issue and logs a warning."""
|
||||
await assert_platform_setup_creates_issue(
|
||||
hass,
|
||||
platform_domain,
|
||||
DOMAIN,
|
||||
issue_registry,
|
||||
caplog,
|
||||
)
|
||||
|
||||
|
||||
async def test_restore_state(hass: HomeAssistant) -> None:
|
||||
"""Test utility sensor restore state."""
|
||||
config = {
|
||||
|
||||
@@ -1612,7 +1612,8 @@ async def test_platform_with_no_setup(
|
||||
|
||||
assert (
|
||||
"The mock-platform platform for the mock-integration"
|
||||
" integration does not support platform setup." in caplog.text
|
||||
" integration does not support platform setup, please remove it from your config"
|
||||
in caplog.text
|
||||
)
|
||||
issue = issue_registry.async_get_issue(
|
||||
domain="homeassistant",
|
||||
@@ -1621,10 +1622,10 @@ async def test_platform_with_no_setup(
|
||||
assert issue
|
||||
assert issue.issue_domain == "mock-platform"
|
||||
assert issue.learn_more_url is None
|
||||
assert issue.translation_key == "no_platform_setup"
|
||||
assert issue.translation_key == "platform_setup_not_supported"
|
||||
assert issue.translation_placeholders == {
|
||||
"domain": "mock-integration",
|
||||
"platform": "mock-platform",
|
||||
"platform_domain": "mock-integration",
|
||||
"integration_domain": "mock-platform",
|
||||
"platform_key": "platform: mock-platform",
|
||||
"yaml_example": "```yaml\nmock-integration:\n - platform: mock-platform\n```",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user