Skip to content

Commit 75597ac

Browse files
authored
Add Shelly removal condition for virtual components (home-assistant#152312)
1 parent b503f79 commit 75597ac

File tree

14 files changed

+59
-0
lines changed

14 files changed

+59
-0
lines changed

homeassistant/components/shelly/binary_sensor.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
get_virtual_component_ids,
4141
is_block_momentary_input,
4242
is_rpc_momentary_input,
43+
is_view_for_platform,
4344
)
4445

4546
PARALLEL_UPDATES = 0
@@ -273,6 +274,9 @@ def __init__(
273274
"boolean": RpcBinarySensorDescription(
274275
key="boolean",
275276
sub_key="value",
277+
removal_condition=lambda config, _status, key: not is_view_for_platform(
278+
config, key, BINARY_SENSOR_PLATFORM
279+
),
276280
),
277281
"calibration": RpcBinarySensorDescription(
278282
key="blutrv",

homeassistant/components/shelly/number.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
get_device_entry_gen,
4242
get_virtual_component_ids,
4343
get_virtual_component_unit,
44+
is_view_for_platform,
4445
)
4546

4647
PARALLEL_UPDATES = 0
@@ -185,6 +186,9 @@ async def async_set_native_value(self, value: float) -> None:
185186
"number": RpcNumberDescription(
186187
key="number",
187188
sub_key="value",
189+
removal_condition=lambda config, _status, key: not is_view_for_platform(
190+
config, key, NUMBER_PLATFORM
191+
),
188192
max_fn=lambda config: config["max"],
189193
min_fn=lambda config: config["min"],
190194
mode_fn=lambda config: VIRTUAL_NUMBER_MODE_MAP.get(

homeassistant/components/shelly/select.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
async_remove_orphaned_entities,
2727
get_device_entry_gen,
2828
get_virtual_component_ids,
29+
is_view_for_platform,
2930
)
3031

3132
PARALLEL_UPDATES = 0
@@ -40,6 +41,9 @@ class RpcSelectDescription(RpcEntityDescription, SelectEntityDescription):
4041
"enum": RpcSelectDescription(
4142
key="enum",
4243
sub_key="value",
44+
removal_condition=lambda config, _status, key: not is_view_for_platform(
45+
config, key, SELECT_PLATFORM
46+
),
4347
),
4448
}
4549

homeassistant/components/shelly/sensor.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
get_virtual_component_ids,
6464
get_virtual_component_unit,
6565
is_rpc_wifi_stations_disabled,
66+
is_view_for_platform,
6667
)
6768

6869
PARALLEL_UPDATES = 0
@@ -1385,10 +1386,16 @@ def __init__(
13851386
"text": RpcSensorDescription(
13861387
key="text",
13871388
sub_key="value",
1389+
removal_condition=lambda config, _status, key: not is_view_for_platform(
1390+
config, key, SENSOR_PLATFORM
1391+
),
13881392
),
13891393
"number": RpcSensorDescription(
13901394
key="number",
13911395
sub_key="value",
1396+
removal_condition=lambda config, _status, key: not is_view_for_platform(
1397+
config, key, SENSOR_PLATFORM
1398+
),
13921399
unit=get_virtual_component_unit,
13931400
device_class_fn=lambda config: ROLE_TO_DEVICE_CLASS_MAP.get(config["role"])
13941401
if "role" in config
@@ -1397,6 +1404,9 @@ def __init__(
13971404
"enum": RpcSensorDescription(
13981405
key="enum",
13991406
sub_key="value",
1407+
removal_condition=lambda config, _status, key: not is_view_for_platform(
1408+
config, key, SENSOR_PLATFORM
1409+
),
14001410
options_fn=lambda config: config["options"],
14011411
device_class=SensorDeviceClass.ENUM,
14021412
),

homeassistant/components/shelly/switch.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
get_virtual_component_ids,
3838
is_block_exclude_from_relay,
3939
is_rpc_exclude_from_relay,
40+
is_view_for_platform,
4041
)
4142

4243
PARALLEL_UPDATES = 0
@@ -89,6 +90,9 @@ class RpcSwitchDescription(RpcEntityDescription, SwitchEntityDescription):
8990
"boolean": RpcSwitchDescription(
9091
key="boolean",
9192
sub_key="value",
93+
removal_condition=lambda config, _status, key: not is_view_for_platform(
94+
config, key, SWITCH_PLATFORM
95+
),
9296
is_on=lambda status: bool(status["value"]),
9397
method_on="Boolean.Set",
9498
method_off="Boolean.Set",

homeassistant/components/shelly/text.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
async_remove_orphaned_entities,
2727
get_device_entry_gen,
2828
get_virtual_component_ids,
29+
is_view_for_platform,
2930
)
3031

3132
PARALLEL_UPDATES = 0
@@ -40,6 +41,9 @@ class RpcTextDescription(RpcEntityDescription, TextEntityDescription):
4041
"text": RpcTextDescription(
4142
key="text",
4243
sub_key="value",
44+
removal_condition=lambda config, _status, key: not is_view_for_platform(
45+
config, key, TEXT_PLATFORM
46+
),
4347
),
4448
}
4549

homeassistant/components/shelly/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,13 @@ def get_virtual_component_ids(config: dict[str, Any], platform: str) -> list[str
654654
return ids
655655

656656

657+
def is_view_for_platform(config: dict[str, Any], key: str, platform: str) -> bool:
658+
"""Return true if the virtual component view match the platform."""
659+
component = VIRTUAL_COMPONENTS_MAP[platform]
660+
view = config[key]["meta"]["ui"]["view"]
661+
return view in component["modes"]
662+
663+
657664
def get_virtual_component_unit(config: dict[str, Any]) -> str | None:
658665
"""Return the unit of a virtual component.
659666

tests/components/shelly/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,3 +762,16 @@ def mock_setup() -> Generator[AsyncMock]:
762762
"homeassistant.components.shelly.async_setup", return_value=True
763763
) as mock_setup:
764764
yield mock_setup
765+
766+
767+
@pytest.fixture
768+
def disable_async_remove_shelly_rpc_entities() -> Generator[None]:
769+
"""Patch out async_remove_shelly_rpc_entities.
770+
771+
This is used by virtual components tests that should not create entities,
772+
without it async_remove_shelly_rpc_entities will clean up the entities.
773+
"""
774+
with patch(
775+
"homeassistant.components.shelly.utils.async_remove_shelly_rpc_entities"
776+
):
777+
yield

tests/components/shelly/test_binary_sensor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ async def test_rpc_device_virtual_binary_sensor(
435435
assert state.state == STATE_OFF
436436

437437

438+
@pytest.mark.usefixtures("disable_async_remove_shelly_rpc_entities")
438439
async def test_rpc_remove_virtual_binary_sensor_when_mode_toggle(
439440
hass: HomeAssistant,
440441
entity_registry: EntityRegistry,

tests/components/shelly/test_number.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ async def test_rpc_device_virtual_number(
340340
assert state.state == "56.7"
341341

342342

343+
@pytest.mark.usefixtures("disable_async_remove_shelly_rpc_entities")
343344
async def test_rpc_remove_virtual_number_when_mode_label(
344345
hass: HomeAssistant,
345346
entity_registry: EntityRegistry,

0 commit comments

Comments
 (0)