Add horizontal swing to Sensibo (#132117)

* Add horizontal swing to Sensibo

* Fixes

* Only load select if already there

* Remove feature check

* Fixes

* Mods

* Last bits

* Mod

* Fixes

* Mods

* Fix test

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
G Johansson 2025-01-06 11:20:11 +01:00 committed by GitHub
parent eafbf1d1fd
commit 20cf21d88e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 346 additions and 90 deletions

View File

@ -81,12 +81,28 @@ AVAILABLE_SWING_MODES = {
"horizontal", "horizontal",
"both", "both",
} }
AVAILABLE_HORIZONTAL_SWING_MODES = {
"stopped",
"fixedleft",
"fixedcenterleft",
"fixedcenter",
"fixedcenterright",
"fixedright",
"fixedleftright",
"rangecenter",
"rangefull",
"rangeleft",
"rangeright",
"horizontal",
"both",
}
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
FIELD_TO_FLAG = { FIELD_TO_FLAG = {
"fanLevel": ClimateEntityFeature.FAN_MODE, "fanLevel": ClimateEntityFeature.FAN_MODE,
"swing": ClimateEntityFeature.SWING_MODE, "swing": ClimateEntityFeature.SWING_MODE,
"horizontalSwing": ClimateEntityFeature.SWING_HORIZONTAL_MODE,
"targetTemperature": ClimateEntityFeature.TARGET_TEMPERATURE, "targetTemperature": ClimateEntityFeature.TARGET_TEMPERATURE,
} }
@ -107,6 +123,7 @@ AC_STATE_TO_DATA = {
"on": "device_on", "on": "device_on",
"mode": "hvac_mode", "mode": "hvac_mode",
"swing": "swing_mode", "swing": "swing_mode",
"horizontalSwing": "horizontal_swing_mode",
} }
@ -292,6 +309,16 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
"""Return the list of available swing modes.""" """Return the list of available swing modes."""
return self.device_data.swing_modes return self.device_data.swing_modes
@property
def swing_horizontal_mode(self) -> str | None:
"""Return the horizontal swing setting."""
return self.device_data.horizontal_swing_mode
@property
def swing_horizontal_modes(self) -> list[str] | None:
"""Return the list of available horizontal swing modes."""
return self.device_data.horizontal_swing_modes
@property @property
def min_temp(self) -> float: def min_temp(self) -> float:
"""Return the minimum temperature.""" """Return the minimum temperature."""
@ -379,6 +406,26 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity):
transformation=transformation, transformation=transformation,
) )
async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None:
"""Set new target horizontal swing operation."""
if swing_horizontal_mode not in AVAILABLE_HORIZONTAL_SWING_MODES:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="horizontal_swing_not_supported",
translation_placeholders={
"horizontal_swing_mode": swing_horizontal_mode
},
)
transformation = self.device_data.horizontal_swing_modes_translated
await self.async_send_api_call(
key=AC_STATE_TO_DATA["horizontalSwing"],
value=swing_horizontal_mode,
name="horizontalSwing",
assumed_state=False,
transformation=transformation,
)
async def async_turn_on(self) -> None: async def async_turn_on(self) -> None:
"""Turn Sensibo unit on.""" """Turn Sensibo unit on."""
await self.async_send_api_call( await self.async_send_api_call(

View File

@ -8,10 +8,22 @@ from typing import TYPE_CHECKING, Any
from pysensibo.model import SensiboDevice from pysensibo.model import SensiboDevice
from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.components.automation import automations_with_entity
from homeassistant.components.script import scripts_with_entity
from homeassistant.components.select import (
DOMAIN as SELECT_DOMAIN,
SelectEntity,
SelectEntityDescription,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.issue_registry import (
IssueSeverity,
async_create_issue,
async_delete_issue,
)
from . import SensiboConfigEntry from . import SensiboConfigEntry
from .const import DOMAIN from .const import DOMAIN
@ -31,15 +43,17 @@ class SensiboSelectEntityDescription(SelectEntityDescription):
transformation: Callable[[SensiboDevice], dict | None] transformation: Callable[[SensiboDevice], dict | None]
HORIZONTAL_SWING_MODE_TYPE = SensiboSelectEntityDescription(
key="horizontalSwing",
data_key="horizontal_swing_mode",
value_fn=lambda data: data.horizontal_swing_mode,
options_fn=lambda data: data.horizontal_swing_modes,
translation_key="horizontalswing",
transformation=lambda data: data.horizontal_swing_modes_translated,
entity_registry_enabled_default=False,
)
DEVICE_SELECT_TYPES = ( DEVICE_SELECT_TYPES = (
SensiboSelectEntityDescription(
key="horizontalSwing",
data_key="horizontal_swing_mode",
value_fn=lambda data: data.horizontal_swing_mode,
options_fn=lambda data: data.horizontal_swing_modes,
translation_key="horizontalswing",
transformation=lambda data: data.horizontal_swing_modes_translated,
),
SensiboSelectEntityDescription( SensiboSelectEntityDescription(
key="light", key="light",
data_key="light_mode", data_key="light_mode",
@ -60,12 +74,51 @@ async def async_setup_entry(
coordinator = entry.runtime_data coordinator = entry.runtime_data
async_add_entities( entities: list[SensiboSelect] = []
SensiboSelect(coordinator, device_id, description)
for device_id, device_data in coordinator.data.parsed.items() entity_registry = er.async_get(hass)
for description in DEVICE_SELECT_TYPES for device_id, device_data in coordinator.data.parsed.items():
if description.key in device_data.full_features if entity_id := entity_registry.async_get_entity_id(
SELECT_DOMAIN, DOMAIN, f"{device_id}-horizontalSwing"
):
entity = entity_registry.async_get(entity_id)
if entity and entity.disabled:
entity_registry.async_remove(entity_id)
async_delete_issue(
hass,
DOMAIN,
"deprecated_entity_horizontalswing",
)
elif entity and HORIZONTAL_SWING_MODE_TYPE.key in device_data.full_features:
entities.append(
SensiboSelect(coordinator, device_id, HORIZONTAL_SWING_MODE_TYPE)
)
if automations_with_entity(hass, entity_id) or scripts_with_entity(
hass, entity_id
):
async_create_issue(
hass,
DOMAIN,
"deprecated_entity_horizontalswing",
breaks_in_ha_version="2025.8.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_entity_horizontalswing",
translation_placeholders={
"name": str(entity.name or entity.original_name),
"entity": entity_id,
},
)
entities.extend(
[
SensiboSelect(coordinator, device_id, description)
for device_id, device_data in coordinator.data.parsed.items()
for description in DEVICE_SELECT_TYPES
if description.key in device_data.full_features
]
) )
async_add_entities(entities)
class SensiboSelect(SensiboDeviceBaseEntity, SelectEntity): class SensiboSelect(SensiboDeviceBaseEntity, SelectEntity):

View File

@ -387,6 +387,21 @@
"horizontal": "[%key:component::sensibo::entity::sensor::climate_react_low::state_attributes::swing::state::horizontal%]", "horizontal": "[%key:component::sensibo::entity::sensor::climate_react_low::state_attributes::swing::state::horizontal%]",
"both": "[%key:component::climate::entity_component::_::state_attributes::swing_mode::state::both%]" "both": "[%key:component::climate::entity_component::_::state_attributes::swing_mode::state::both%]"
} }
},
"swing_horizontal_mode": {
"state": {
"stopped": "[%key:common::state::off%]",
"fixedleft": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedleft%]",
"fixedcenterleft": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedcenterleft%]",
"fixedcenter": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedcenter%]",
"fixedcenterright": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedcenterright%]",
"fixedright": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedright%]",
"fixedleftright": "[%key:component::sensibo::entity::select::horizontalswing::state::fixedleftright%]",
"rangecenter": "[%key:component::sensibo::entity::select::horizontalswing::state::rangecenter%]",
"rangefull": "[%key:component::sensibo::entity::select::horizontalswing::state::rangefull%]",
"rangeleft": "[%key:component::sensibo::entity::select::horizontalswing::state::rangeleft%]",
"rangeright": "[%key:component::sensibo::entity::select::horizontalswing::state::rangeright%]"
}
} }
} }
} }
@ -551,6 +566,9 @@
"swing_not_supported": { "swing_not_supported": {
"message": "Climate swing mode {swing_mode} is not supported by the integration, please open an issue" "message": "Climate swing mode {swing_mode} is not supported by the integration, please open an issue"
}, },
"horizontal_swing_not_supported": {
"message": "Climate horizontal swing mode {horizontal_swing_mode} is not supported by the integration, please open an issue"
},
"service_result_not_true": { "service_result_not_true": {
"message": "Could not perform action for {name}" "message": "Could not perform action for {name}"
}, },
@ -575,5 +593,11 @@
"mode_not_exist": { "mode_not_exist": {
"message": "The entity does not support the chosen mode" "message": "The entity does not support the chosen mode"
} }
},
"issues": {
"deprecated_entity_horizontalswing": {
"title": "The Sensibo {name} entity is deprecated",
"description": "The Sensibo entity `{entity}` is deprecated and will be removed in a future release.\nPlease update your automations and scripts to use the `horizontal_swing` attribute part of the `climate` entity instead.\n, Disable the `{entity}` and reload the config entry or restart Home Assistant to fix this issue."
}
} }
} }

View File

@ -81,6 +81,11 @@
]), ]),
'max_temp': 20, 'max_temp': 20,
'min_temp': 10, 'min_temp': 10,
'swing_horizontal_modes': list([
'stopped',
'fixedleft',
'fixedcenterleft',
]),
'swing_modes': list([ 'swing_modes': list([
'stopped', 'stopped',
'fixedtop', 'fixedtop',
@ -109,7 +114,7 @@
'original_name': None, 'original_name': None,
'platform': 'sensibo', 'platform': 'sensibo',
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': <ClimateEntityFeature: 425>, 'supported_features': <ClimateEntityFeature: 937>,
'translation_key': 'climate_device', 'translation_key': 'climate_device',
'unique_id': 'ABC999111', 'unique_id': 'ABC999111',
'unit_of_measurement': None, 'unit_of_measurement': None,
@ -137,7 +142,13 @@
]), ]),
'max_temp': 20, 'max_temp': 20,
'min_temp': 10, 'min_temp': 10,
'supported_features': <ClimateEntityFeature: 425>, 'supported_features': <ClimateEntityFeature: 937>,
'swing_horizontal_mode': 'stopped',
'swing_horizontal_modes': list([
'stopped',
'fixedleft',
'fixedcenterleft',
]),
'swing_mode': 'stopped', 'swing_mode': 'stopped',
'swing_modes': list([ 'swing_modes': list([
'stopped', 'stopped',

View File

@ -1,61 +1,4 @@
# serializer version: 1 # serializer version: 1
# name: test_select[load_platforms0][select.hallway_horizontal_swing-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'stopped',
'fixedleft',
'fixedcenterleft',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'select',
'entity_category': None,
'entity_id': 'select.hallway_horizontal_swing',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Horizontal swing',
'platform': 'sensibo',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'horizontalswing',
'unique_id': 'ABC999111-horizontalSwing',
'unit_of_measurement': None,
})
# ---
# name: test_select[load_platforms0][select.hallway_horizontal_swing-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Hallway Horizontal swing',
'options': list([
'stopped',
'fixedleft',
'fixedcenterleft',
]),
}),
'context': <ANY>,
'entity_id': 'select.hallway_horizontal_swing',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'stopped',
})
# ---
# name: test_select[load_platforms0][select.hallway_light-entry] # name: test_select[load_platforms0][select.hallway_light-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({

View File

@ -13,12 +13,14 @@ from voluptuous import MultipleInvalid
from homeassistant.components.climate import ( from homeassistant.components.climate import (
ATTR_FAN_MODE, ATTR_FAN_MODE,
ATTR_HVAC_MODE, ATTR_HVAC_MODE,
ATTR_SWING_HORIZONTAL_MODE,
ATTR_SWING_MODE, ATTR_SWING_MODE,
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_LOW,
DOMAIN as CLIMATE_DOMAIN, DOMAIN as CLIMATE_DOMAIN,
SERVICE_SET_FAN_MODE, SERVICE_SET_FAN_MODE,
SERVICE_SET_HVAC_MODE, SERVICE_SET_HVAC_MODE,
SERVICE_SET_SWING_HORIZONTAL_MODE,
SERVICE_SET_SWING_MODE, SERVICE_SET_SWING_MODE,
SERVICE_SET_TEMPERATURE, SERVICE_SET_TEMPERATURE,
HVACMode, HVACMode,
@ -265,6 +267,95 @@ async def test_climate_swing(
assert "swing_mode" not in state.attributes assert "swing_mode" not in state.attributes
async def test_climate_horizontal_swing(
hass: HomeAssistant,
load_int: ConfigEntry,
mock_client: MagicMock,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the Sensibo climate horizontal swing service."""
state = hass.states.get("climate.hallway")
assert state.attributes["swing_horizontal_mode"] == "stopped"
mock_client.async_get_devices_data.return_value.parsed[
"ABC999111"
].horizontal_swing_modes = [
"stopped",
"fixedleft",
"fixedcenter",
"fixedright",
"not_in_ha",
]
mock_client.async_get_devices_data.return_value.parsed[
"ABC999111"
].swing_modes_translated = {
"stopped": "stopped",
"fixedleft": "fixedLeft",
"fixedcenter": "fixedCenter",
"fixedright": "fixedRight",
"not_in_ha": "not_in_ha",
}
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
with pytest.raises(
HomeAssistantError,
match="Climate horizontal swing mode not_in_ha is not supported by the integration",
):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_SWING_HORIZONTAL_MODE,
{ATTR_ENTITY_ID: state.entity_id, ATTR_SWING_HORIZONTAL_MODE: "not_in_ha"},
blocking=True,
)
mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "Success"}
}
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_SWING_HORIZONTAL_MODE,
{ATTR_ENTITY_ID: state.entity_id, ATTR_SWING_HORIZONTAL_MODE: "fixedleft"},
blocking=True,
)
state = hass.states.get("climate.hallway")
assert state.attributes["swing_horizontal_mode"] == "fixedleft"
mock_client.async_get_devices_data.return_value.parsed[
"ABC999111"
].active_features = [
"timestamp",
"on",
"mode",
"targetTemperature",
"swing",
"light",
]
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done()
with pytest.raises(HomeAssistantError, match="service_not_supported"):
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_SWING_HORIZONTAL_MODE,
{
ATTR_ENTITY_ID: state.entity_id,
ATTR_SWING_HORIZONTAL_MODE: "fixedcenter",
},
blocking=True,
)
state = hass.states.get("climate.hallway")
assert "swing_horizontal_mode" not in state.attributes
async def test_climate_temperatures( async def test_climate_temperatures(
hass: HomeAssistant, hass: HomeAssistant,
load_int: ConfigEntry, load_int: ConfigEntry,

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from unittest.mock import MagicMock from unittest.mock import MagicMock, patch
from freezegun.api import FrozenDateTimeFactory from freezegun.api import FrozenDateTimeFactory
import pytest import pytest
@ -14,13 +14,16 @@ from homeassistant.components.select import (
DOMAIN as SELECT_DOMAIN, DOMAIN as SELECT_DOMAIN,
SERVICE_SELECT_OPTION, SERVICE_SELECT_OPTION,
) )
from homeassistant.components.sensibo.const import DOMAIN
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er, issue_registry as ir
from tests.common import async_fire_time_changed, snapshot_platform from . import ENTRY_CONFIG
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -40,15 +43,15 @@ async def test_select(
await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id) await snapshot_platform(hass, entity_registry, snapshot, load_int.entry_id)
mock_client.async_get_devices_data.return_value.parsed[ mock_client.async_get_devices_data.return_value.parsed[
"ABC999111" "AAZZAAZZ"
].horizontal_swing_mode = "fixedleft" ].light_mode = "dim"
freezer.tick(timedelta(minutes=5)) freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass) async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("select.hallway_horizontal_swing") state = hass.states.get("select.kitchen_light")
assert state.state == "fixedleft" assert state.state == "dim"
async def test_select_set_option( async def test_select_set_option(
@ -73,8 +76,8 @@ async def test_select_set_option(
async_fire_time_changed(hass) async_fire_time_changed(hass)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("select.hallway_horizontal_swing") state = hass.states.get("select.kitchen_light")
assert state.state == "stopped" assert state.state == "on"
mock_client.async_set_ac_state_property.return_value = { mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "failed"} "result": {"status": "failed"}
@ -86,12 +89,12 @@ async def test_select_set_option(
await hass.services.async_call( await hass.services.async_call(
SELECT_DOMAIN, SELECT_DOMAIN,
SERVICE_SELECT_OPTION, SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"}, {ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "dim"},
blocking=True, blocking=True,
) )
state = hass.states.get("select.hallway_horizontal_swing") state = hass.states.get("select.kitchen_light")
assert state.state == "stopped" assert state.state == "on"
mock_client.async_get_devices_data.return_value.parsed[ mock_client.async_get_devices_data.return_value.parsed[
"ABC999111" "ABC999111"
@ -118,12 +121,12 @@ async def test_select_set_option(
await hass.services.async_call( await hass.services.async_call(
SELECT_DOMAIN, SELECT_DOMAIN,
SERVICE_SELECT_OPTION, SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"}, {ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "dim"},
blocking=True, blocking=True,
) )
state = hass.states.get("select.hallway_horizontal_swing") state = hass.states.get("select.kitchen_light")
assert state.state == "stopped" assert state.state == "on"
mock_client.async_set_ac_state_property.return_value = { mock_client.async_set_ac_state_property.return_value = {
"result": {"status": "Success"} "result": {"status": "Success"}
@ -132,9 +135,93 @@ async def test_select_set_option(
await hass.services.async_call( await hass.services.async_call(
SELECT_DOMAIN, SELECT_DOMAIN,
SERVICE_SELECT_OPTION, SERVICE_SELECT_OPTION,
{ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "fixedleft"}, {ATTR_ENTITY_ID: state.entity_id, ATTR_OPTION: "dim"},
blocking=True, blocking=True,
) )
state = hass.states.get("select.kitchen_light")
assert state.state == "dim"
@pytest.mark.parametrize(
"load_platforms",
[[Platform.SELECT]],
)
async def test_deprecated_horizontal_swing_select(
hass: HomeAssistant,
load_platforms: list[Platform],
mock_client: MagicMock,
entity_registry: er.EntityRegistry,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test the deprecated horizontal swing select entity."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data=ENTRY_CONFIG,
entry_id="1",
unique_id="firstnamelastname",
version=2,
)
config_entry.add_to_hass(hass)
entity_registry.async_get_or_create(
SELECT_DOMAIN,
DOMAIN,
"ABC999111-horizontalSwing",
config_entry=config_entry,
disabled_by=None,
has_entity_name=True,
suggested_object_id="hallway_horizontal_swing",
)
with patch("homeassistant.components.sensibo.PLATFORMS", load_platforms):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get("select.hallway_horizontal_swing") state = hass.states.get("select.hallway_horizontal_swing")
assert state.state == "fixedleft" assert state.state == "stopped"
# No issue created without automation or script
assert issue_registry.issues == {}
with (
patch("homeassistant.components.sensibo.PLATFORMS", load_platforms),
patch(
# Patch check for automation, that one exist
"homeassistant.components.sensibo.select.automations_with_entity",
return_value=["automation.test"],
),
):
await hass.config_entries.async_reload(config_entry.entry_id)
await hass.async_block_till_done(True)
# Issue is created when entity is enabled and automation/script exist
issue = issue_registry.async_get_issue(DOMAIN, "deprecated_entity_horizontalswing")
assert issue
assert issue.translation_key == "deprecated_entity_horizontalswing"
assert hass.states.get("select.hallway_horizontal_swing")
assert entity_registry.async_is_registered("select.hallway_horizontal_swing")
# Disabling the entity should remove the entity and remove the issue
# once the integration is reloaded
entity_registry.async_update_entity(
state.entity_id, disabled_by=er.RegistryEntryDisabler.USER
)
with (
patch("homeassistant.components.sensibo.PLATFORMS", load_platforms),
patch(
"homeassistant.components.sensibo.select.automations_with_entity",
return_value=["automation.test"],
),
):
await hass.config_entries.async_reload(config_entry.entry_id)
await hass.async_block_till_done(True)
# Disabling the entity and reloading has removed the entity and issue
assert not hass.states.get("select.hallway_horizontal_swing")
assert not entity_registry.async_is_registered("select.hallway_horizontal_swing")
issue = issue_registry.async_get_issue(DOMAIN, "deprecated_entity_horizontalswing")
assert not issue