Remove legacy fan template entities (#169613)

This commit is contained in:
Petro31
2026-05-07 09:51:08 -04:00
committed by GitHub
parent ee19c11565
commit 8d30abab9e
2 changed files with 51 additions and 167 deletions
+1 -52
View File
@@ -18,14 +18,7 @@ from homeassistant.components.fan import (
FanEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_ENTITY_ID,
CONF_FRIENDLY_NAME,
CONF_NAME,
CONF_STATE,
CONF_UNIQUE_ID,
CONF_VALUE_TEMPLATE,
)
from homeassistant.const import CONF_NAME, CONF_STATE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import (
@@ -44,7 +37,6 @@ from .helpers import (
async_setup_template_preview,
)
from .schemas import (
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY,
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA,
TEMPLATE_ENTITY_OPTIMISTIC_SCHEMA,
make_template_entity_common_modern_schema,
@@ -54,13 +46,8 @@ from .trigger_entity import TriggerEntity
_LOGGER = logging.getLogger(__name__)
CONF_FANS = "fans"
CONF_SPEED_COUNT = "speed_count"
CONF_PRESET_MODES = "preset_modes"
CONF_PERCENTAGE_TEMPLATE = "percentage_template"
CONF_PRESET_MODE_TEMPLATE = "preset_mode_template"
CONF_OSCILLATING_TEMPLATE = "oscillating_template"
CONF_DIRECTION_TEMPLATE = "direction_template"
CONF_ON_ACTION = "turn_on"
CONF_OFF_ACTION = "turn_off"
CONF_SET_PERCENTAGE_ACTION = "set_percentage"
@@ -75,14 +62,6 @@ CONF_OSCILLATING = "oscillating"
CONF_PERCENTAGE = "percentage"
CONF_PRESET_MODE = "preset_mode"
LEGACY_FIELDS = {
CONF_DIRECTION_TEMPLATE: CONF_DIRECTION,
CONF_OSCILLATING_TEMPLATE: CONF_OSCILLATING,
CONF_PERCENTAGE_TEMPLATE: CONF_PERCENTAGE,
CONF_PRESET_MODE_TEMPLATE: CONF_PRESET_MODE,
CONF_VALUE_TEMPLATE: CONF_STATE,
}
DEFAULT_NAME = "Template Fan"
SCRIPT_FIELDS = (
@@ -116,34 +95,6 @@ FAN_YAML_SCHEMA = FAN_COMMON_SCHEMA.extend(TEMPLATE_ENTITY_OPTIMISTIC_SCHEMA).ex
make_template_entity_common_modern_schema(FAN_DOMAIN, DEFAULT_NAME).schema
)
FAN_LEGACY_YAML_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
vol.Schema(
{
vol.Optional(CONF_DIRECTION_TEMPLATE): cv.template,
vol.Optional(CONF_ENTITY_ID): cv.entity_ids,
vol.Optional(CONF_FRIENDLY_NAME): cv.string,
vol.Required(CONF_OFF_ACTION): cv.SCRIPT_SCHEMA,
vol.Required(CONF_ON_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_OSCILLATING_TEMPLATE): cv.template,
vol.Optional(CONF_PERCENTAGE_TEMPLATE): cv.template,
vol.Optional(CONF_PRESET_MODE_TEMPLATE): cv.template,
vol.Optional(CONF_PRESET_MODES): cv.ensure_list,
vol.Optional(CONF_SET_DIRECTION_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_SET_OSCILLATING_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_SET_PERCENTAGE_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_SET_PRESET_MODE_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_SPEED_COUNT): vol.Coerce(int),
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
}
).extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA_LEGACY.schema),
)
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(
{vol.Required(CONF_FANS): cv.schema_with_slug_keys(FAN_LEGACY_YAML_SCHEMA)}
)
FAN_CONFIG_ENTRY_SCHEMA = FAN_COMMON_SCHEMA.extend(
TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA.schema
)
@@ -164,8 +115,6 @@ async def async_setup_platform(
TriggerFanEntity,
async_add_entities,
discovery_info,
LEGACY_FIELDS,
legacy_key=CONF_FANS,
script_options=SCRIPT_FIELDS,
)
+50 -115
View File
@@ -172,13 +172,33 @@ 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)],
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_missing_optional_config(hass: HomeAssistant) -> None:
@@ -190,7 +210,7 @@ async def test_missing_optional_config(hass: HomeAssistant) -> None:
@pytest.mark.parametrize("count", [0])
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
"extra_config",
@@ -208,7 +228,7 @@ async def test_wrong_template_config(hass: HomeAssistant) -> None:
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_state_template(hass: HomeAssistant) -> None:
@@ -245,7 +265,7 @@ async def test_state_template(hass: HomeAssistant) -> None:
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_state_template_states(hass: HomeAssistant, expected: str) -> None:
@@ -328,7 +348,6 @@ async def test_icon_template(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("style", "attribute"),
[
(ConfigurationStyle.LEGACY, "percentage_template"),
(ConfigurationStyle.MODERN, "percentage"),
(ConfigurationStyle.TRIGGER, "percentage"),
],
@@ -366,7 +385,6 @@ async def test_percentage_template(
@pytest.mark.parametrize(
("style", "attribute"),
[
(ConfigurationStyle.LEGACY, "preset_mode_template"),
(ConfigurationStyle.MODERN, "preset_mode"),
(ConfigurationStyle.TRIGGER, "preset_mode"),
],
@@ -403,7 +421,6 @@ async def test_preset_mode_template(
@pytest.mark.parametrize(
("style", "attribute"),
[
(ConfigurationStyle.LEGACY, "oscillating_template"),
(ConfigurationStyle.MODERN, "oscillating"),
(ConfigurationStyle.TRIGGER, "oscillating"),
],
@@ -438,7 +455,6 @@ async def test_oscillating_template(
@pytest.mark.parametrize(
("style", "attribute"),
[
(ConfigurationStyle.LEGACY, "direction_template"),
(ConfigurationStyle.MODERN, "direction"),
(ConfigurationStyle.TRIGGER, "direction"),
],
@@ -463,19 +479,6 @@ async def test_direction_template(
@pytest.mark.parametrize(
("style", "config"),
[
(
ConfigurationStyle.LEGACY,
{
"availability_template": (
"{{ is_state('binary_sensor.availability', 'on') }}"
),
"value_template": "{{ 'on' }}",
"oscillating_template": "{{ 1 == 1 }}",
"direction_template": "{{ 'forward' }}",
"turn_on": {"service": "script.fan_on"},
"turn_off": {"service": "script.fan_off"},
},
),
(
ConfigurationStyle.MODERN,
{
@@ -514,14 +517,6 @@ async def test_availability_template_with_entities(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("style", "config", "states"),
[
(
ConfigurationStyle.LEGACY,
{
"value_template": "{{ 'unavailable' }}",
**OPTIMISTIC_ON_OFF_ACTIONS,
},
[STATE_UNKNOWN, None, None, None],
),
(
ConfigurationStyle.MODERN,
{
@@ -538,19 +533,6 @@ async def test_availability_template_with_entities(hass: HomeAssistant) -> None:
},
[STATE_UNKNOWN, None, None, None],
),
(
ConfigurationStyle.LEGACY,
{
"value_template": "{{ 'on' }}",
"percentage_template": "{{ 0 }}",
**OPTIMISTIC_PERCENTAGE_CONFIG,
"oscillating_template": "{{ 'unavailable' }}",
**OSCILLATE_ACTION,
"direction_template": "{{ 'unavailable' }}",
**DIRECTION_ACTION,
},
[STATE_ON, 0, None, None],
),
(
ConfigurationStyle.MODERN,
{
@@ -577,19 +559,6 @@ async def test_availability_template_with_entities(hass: HomeAssistant) -> None:
},
[STATE_ON, 0, None, None],
),
(
ConfigurationStyle.LEGACY,
{
"value_template": "{{ 'on' }}",
"percentage_template": "{{ 66 }}",
**OPTIMISTIC_PERCENTAGE_CONFIG,
"oscillating_template": "{{ 1 == 1 }}",
**OSCILLATE_ACTION,
"direction_template": "{{ 'forward' }}",
**DIRECTION_ACTION,
},
[STATE_ON, 66, True, DIRECTION_FORWARD],
),
(
ConfigurationStyle.MODERN,
{
@@ -616,19 +585,6 @@ async def test_availability_template_with_entities(hass: HomeAssistant) -> None:
},
[STATE_ON, 66, True, DIRECTION_FORWARD],
),
(
ConfigurationStyle.LEGACY,
{
"value_template": "{{ 'abc' }}",
"percentage_template": "{{ 0 }}",
**OPTIMISTIC_PERCENTAGE_CONFIG,
"oscillating_template": "{{ 'xyz' }}",
**OSCILLATE_ACTION,
"direction_template": "{{ 'right' }}",
**DIRECTION_ACTION,
},
[STATE_UNKNOWN, 0, None, None],
),
(
ConfigurationStyle.MODERN,
{
@@ -664,24 +620,11 @@ async def test_template_with_unavailable_entities(hass: HomeAssistant, states) -
_verify(hass, states[0], states[1], states[2], states[3], None)
@pytest.mark.parametrize(("count", "extra_config"), [(1, {})])
@pytest.mark.parametrize(
("style", "config"),
("count", "config", "extra_config"),
[
(
ConfigurationStyle.LEGACY,
{
"value_template": "{{ 'on' }}",
"availability_template": "{{ x - 12 }}",
"preset_mode_template": ("{{ states('input_select.preset_mode') }}"),
"oscillating_template": "{{ states('input_select.osc') }}",
"direction_template": "{{ states('input_select.direction') }}",
"turn_on": {"service": "script.fan_on"},
"turn_off": {"service": "script.fan_off"},
},
),
(
ConfigurationStyle.MODERN,
1,
{
"state": "{{ 'on' }}",
"availability": "{{ x - 12 }}",
@@ -691,21 +634,13 @@ async def test_template_with_unavailable_entities(hass: HomeAssistant, states) -
"turn_on": {"service": "script.fan_on"},
"turn_off": {"service": "script.fan_off"},
},
),
(
ConfigurationStyle.TRIGGER,
{
"state": "{{ 'on' }}",
"availability": "{{ x - 12 }}",
"preset_mode": ("{{ states('input_select.preset_mode') }}"),
"oscillating": "{{ states('input_select.osc') }}",
"direction": "{{ states('input_select.direction') }}",
"turn_on": {"service": "script.fan_on"},
"turn_off": {"service": "script.fan_off"},
},
),
{},
)
],
)
@pytest.mark.parametrize(
"style", [ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER]
)
@pytest.mark.usefixtures("setup_fan")
async def test_invalid_availability_template_keeps_component_available(
hass: HomeAssistant, caplog_setup_text, caplog: pytest.LogCaptureFixture
@@ -726,7 +661,7 @@ async def test_invalid_availability_template_keeps_component_available(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_on_off(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -764,7 +699,7 @@ async def test_on_off(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_on_with_extra_attributes(
@@ -812,7 +747,7 @@ async def test_on_with_extra_attributes(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_invalid_direction_from_initial_stage(hass: HomeAssistant) -> None:
@@ -829,7 +764,7 @@ async def test_set_invalid_direction_from_initial_stage(hass: HomeAssistant) ->
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_osc(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -855,7 +790,7 @@ async def test_set_osc(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_direction(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -881,7 +816,7 @@ async def test_set_direction(hass: HomeAssistant, calls: list[ServiceCall]) -> N
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_invalid_direction(
@@ -910,7 +845,7 @@ async def test_set_invalid_direction(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_preset_modes(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -926,7 +861,7 @@ async def test_preset_modes(hass: HomeAssistant, calls: list[ServiceCall]) -> No
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_invalid_preset_modes(
@@ -944,7 +879,7 @@ async def test_invalid_preset_modes(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_percentage(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -977,7 +912,7 @@ async def test_set_percentage(hass: HomeAssistant, calls: list[ServiceCall]) ->
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_increase_decrease_speed(
@@ -1018,7 +953,7 @@ async def test_increase_decrease_speed(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_fan")
async def test_optimistic_state(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -1070,7 +1005,7 @@ async def test_optimistic_state(hass: HomeAssistant, calls: list[ServiceCall]) -
@pytest.mark.parametrize("count", [1])
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
("extra_config", "attribute", "action", "verify_attr", "coro", "value"),
@@ -1135,7 +1070,7 @@ async def test_optimistic_attributes(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_increase_decrease_speed_default_speed_count(
@@ -1161,7 +1096,7 @@ async def test_increase_decrease_speed_default_speed_count(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_invalid_osc_from_initial_state(
@@ -1181,7 +1116,7 @@ async def test_set_invalid_osc_from_initial_state(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_state_fan")
async def test_set_invalid_osc(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
@@ -1202,7 +1137,7 @@ async def test_set_invalid_osc(hass: HomeAssistant, calls: list[ServiceCall]) ->
@pytest.mark.parametrize("config", [OPTIMISTIC_ON_OFF_ACTIONS])
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
async def test_unique_id(
hass: HomeAssistant, style: ConfigurationStyle, config: ConfigType
@@ -1233,7 +1168,7 @@ async def test_nested_unique_id(
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
("config", "percentage_step"),
@@ -1256,7 +1191,7 @@ async def test_speed_percentage_step(hass: HomeAssistant, percentage_step) -> No
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.usefixtures("setup_fan")
async def test_preset_mode_supported_features(hass: HomeAssistant) -> None:
@@ -1274,7 +1209,7 @@ async def test_preset_mode_supported_features(hass: HomeAssistant) -> None:
)
@pytest.mark.parametrize(
"style",
[ConfigurationStyle.LEGACY, ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
[ConfigurationStyle.MODERN, ConfigurationStyle.TRIGGER],
)
@pytest.mark.parametrize(
("extra_config", "supported_features"),