Switch cleanup for Shelly (part 1) (#138791)

This commit is contained in:
Simone Chemelli 2025-02-19 22:39:17 +01:00 committed by GitHub
parent 406f894dc1
commit eb6993f0a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, cast from typing import Any, cast
@ -29,7 +30,7 @@ from .entity import (
ShellyRpcEntity, ShellyRpcEntity,
ShellySleepingBlockAttributeEntity, ShellySleepingBlockAttributeEntity,
async_setup_entry_attribute_entities, async_setup_entry_attribute_entities,
async_setup_rpc_attribute_entities, async_setup_entry_rpc,
) )
from .utils import ( from .utils import (
async_remove_orphaned_entities, async_remove_orphaned_entities,
@ -60,18 +61,32 @@ MOTION_SWITCH = BlockSwitchDescription(
class RpcSwitchDescription(RpcEntityDescription, SwitchEntityDescription): class RpcSwitchDescription(RpcEntityDescription, SwitchEntityDescription):
"""Class to describe a RPC virtual switch.""" """Class to describe a RPC virtual switch."""
is_on: Callable[[dict[str, Any]], bool]
method_on: str
method_off: str
method_params_fn: Callable[[int | None, bool], dict]
RPC_VIRTUAL_SWITCH = RpcSwitchDescription(
RPC_SWITCHES = {
"boolean": RpcSwitchDescription(
key="boolean", key="boolean",
sub_key="value", sub_key="value",
) is_on=lambda status: bool(status["value"]),
method_on="Boolean.Set",
RPC_SCRIPT_SWITCH = RpcSwitchDescription( method_off="Boolean.Set",
method_params_fn=lambda id, value: {"id": id, "value": value},
),
"script": RpcSwitchDescription(
key="script", key="script",
sub_key="running", sub_key="running",
is_on=lambda status: bool(status["running"]),
method_on="Script.Start",
method_off="Script.Stop",
method_params_fn=lambda id, _: {"id": id},
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
) ),
}
async def async_setup_entry( async def async_setup_entry(
@ -174,20 +189,8 @@ def async_setup_rpc_entry(
unique_id = f"{coordinator.mac}-switch:{id_}" unique_id = f"{coordinator.mac}-switch:{id_}"
async_remove_shelly_entity(hass, "light", unique_id) async_remove_shelly_entity(hass, "light", unique_id)
async_setup_rpc_attribute_entities( async_setup_entry_rpc(
hass, hass, config_entry, async_add_entities, RPC_SWITCHES, RpcSwitch
config_entry,
async_add_entities,
{"boolean": RPC_VIRTUAL_SWITCH},
RpcVirtualSwitch,
)
async_setup_rpc_attribute_entities(
hass,
config_entry,
async_add_entities,
{"script": RPC_SCRIPT_SWITCH},
RpcScriptSwitch,
) )
# the user can remove virtual components from the device configuration, so we need # the user can remove virtual components from the device configuration, so we need
@ -324,8 +327,8 @@ class RpcRelaySwitch(ShellyRpcEntity, SwitchEntity):
await self.call_rpc("Switch.Set", {"id": self._id, "on": False}) await self.call_rpc("Switch.Set", {"id": self._id, "on": False})
class RpcVirtualSwitch(ShellyRpcAttributeEntity, SwitchEntity): class RpcSwitch(ShellyRpcAttributeEntity, SwitchEntity):
"""Entity that controls a virtual boolean component on RPC based Shelly devices.""" """Entity that controls a switch on RPC based Shelly devices."""
entity_description: RpcSwitchDescription entity_description: RpcSwitchDescription
_attr_has_entity_name = True _attr_has_entity_name = True
@ -333,32 +336,18 @@ class RpcVirtualSwitch(ShellyRpcAttributeEntity, SwitchEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""If switch is on.""" """If switch is on."""
return bool(self.attribute_value) return self.entity_description.is_on(self.status)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on relay.""" """Turn on relay."""
await self.call_rpc("Boolean.Set", {"id": self._id, "value": True}) await self.call_rpc(
self.entity_description.method_on,
self.entity_description.method_params_fn(self._id, True),
)
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off relay.""" """Turn off relay."""
await self.call_rpc("Boolean.Set", {"id": self._id, "value": False}) await self.call_rpc(
self.entity_description.method_off,
self.entity_description.method_params_fn(self._id, False),
class RpcScriptSwitch(ShellyRpcAttributeEntity, SwitchEntity): )
"""Entity that controls a script component on RPC based Shelly devices."""
entity_description: RpcSwitchDescription
_attr_has_entity_name = True
@property
def is_on(self) -> bool:
"""If switch is on."""
return bool(self.status["running"])
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on relay."""
await self.call_rpc("Script.Start", {"id": self._id})
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off relay."""
await self.call_rpc("Script.Stop", {"id": self._id})