mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add Shelly support for Plus WallDimmer US (#83385)
This commit is contained in:
parent
874315c3fc
commit
e1923bc13b
@ -109,10 +109,15 @@ def async_setup_rpc_entry(
|
||||
unique_id = f"{coordinator.mac}-switch:{id_}"
|
||||
async_remove_shelly_entity(hass, "switch", unique_id)
|
||||
|
||||
if not switch_ids:
|
||||
if switch_ids:
|
||||
async_add_entities(
|
||||
RpcShellySwitchAsLight(coordinator, id_) for id_ in switch_ids
|
||||
)
|
||||
return
|
||||
|
||||
async_add_entities(RpcShellyLight(coordinator, id_) for id_ in switch_ids)
|
||||
light_key_ids = get_rpc_key_ids(coordinator.device.status, "light")
|
||||
if light_key_ids:
|
||||
async_add_entities(RpcShellyLight(coordinator, id_) for id_ in light_key_ids)
|
||||
|
||||
|
||||
class BlockShellyLight(ShellyBlockEntity, LightEntity):
|
||||
@ -367,8 +372,8 @@ class BlockShellyLight(ShellyBlockEntity, LightEntity):
|
||||
super()._update_callback()
|
||||
|
||||
|
||||
class RpcShellyLight(ShellyRpcEntity, LightEntity):
|
||||
"""Entity that controls a light on RPC based Shelly devices."""
|
||||
class RpcShellySwitchAsLight(ShellyRpcEntity, LightEntity):
|
||||
"""Entity that controls a relay as light on RPC based Shelly devices."""
|
||||
|
||||
_attr_color_mode = ColorMode.ONOFF
|
||||
_attr_supported_color_modes = {ColorMode.ONOFF}
|
||||
@ -390,3 +395,39 @@ class RpcShellyLight(ShellyRpcEntity, LightEntity):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off light."""
|
||||
await self.call_rpc("Switch.Set", {"id": self._id, "on": False})
|
||||
|
||||
|
||||
class RpcShellyLight(ShellyRpcEntity, LightEntity):
|
||||
"""Entity that controls a light on RPC based Shelly devices."""
|
||||
|
||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||
|
||||
def __init__(self, coordinator: ShellyRpcCoordinator, id_: int) -> None:
|
||||
"""Initialize light."""
|
||||
super().__init__(coordinator, f"light:{id_}")
|
||||
self._id = id_
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""If light is on."""
|
||||
return bool(self.coordinator.device.status[self.key]["output"])
|
||||
|
||||
@property
|
||||
def brightness(self) -> int:
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
brightness_pct = self.coordinator.device.status[self.key]["brightness"]
|
||||
return round(255 * brightness_pct / 100)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on light."""
|
||||
params: dict[str, Any] = {"id": self._id, "on": True}
|
||||
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
params["brightness"] = int(100 * (kwargs[ATTR_BRIGHTNESS] + 1) / 255)
|
||||
|
||||
await self.call_rpc("Light.Set", params)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off light."""
|
||||
await self.call_rpc("Light.Set", {"id": self._id, "on": False})
|
||||
|
@ -298,7 +298,7 @@ def get_rpc_channel_name(device: RpcDevice, key: str) -> str:
|
||||
entity_name = device.config[key].get("name", device_name)
|
||||
|
||||
if entity_name is None:
|
||||
if key.startswith(("input:", "switch:")):
|
||||
if key.startswith(("input:", "light:", "switch:")):
|
||||
return f"{device_name} {key.replace(':', '_')}"
|
||||
return device_name
|
||||
|
||||
|
@ -124,6 +124,7 @@ MOCK_BLOCKS = [
|
||||
|
||||
MOCK_CONFIG = {
|
||||
"input:0": {"id": 0, "type": "button"},
|
||||
"light:0": {"name": "test light_0"},
|
||||
"switch:0": {"name": "test switch_0"},
|
||||
"cover:0": {"name": "test cover_0"},
|
||||
"sys": {
|
||||
@ -169,6 +170,7 @@ MOCK_STATUS_COAP = {
|
||||
|
||||
MOCK_STATUS_RPC = {
|
||||
"switch:0": {"output": True},
|
||||
"light:0": {"output": True, "brightness": 53.0},
|
||||
"cloud": {"connected": False},
|
||||
"cover:0": {
|
||||
"state": "stopped",
|
||||
|
@ -383,3 +383,60 @@ async def test_rpc_device_switch_type_lights_mode(hass, mock_rpc_device, monkeyp
|
||||
)
|
||||
mock_rpc_device.mock_update()
|
||||
assert hass.states.get("light.test_switch_0").state == STATE_OFF
|
||||
|
||||
|
||||
async def test_rpc_light(hass, mock_rpc_device, monkeypatch):
|
||||
"""Test RPC light."""
|
||||
entity_id = f"{LIGHT_DOMAIN}.test_light_0"
|
||||
monkeypatch.delitem(mock_rpc_device.status, "switch:0")
|
||||
await init_integration(hass, 2)
|
||||
|
||||
# Turn on
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_rpc_device.call_rpc.assert_called_once_with("Light.Set", {"id": 0, "on": True})
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[ATTR_BRIGHTNESS] == 135
|
||||
|
||||
# Turn off
|
||||
mock_rpc_device.call_rpc.reset_mock()
|
||||
mutate_rpc_device_status(monkeypatch, mock_rpc_device, "light:0", "output", False)
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_rpc_device.mock_update()
|
||||
mock_rpc_device.call_rpc.assert_called_once_with(
|
||||
"Light.Set", {"id": 0, "on": False}
|
||||
)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
# Turn on, brightness = 33
|
||||
mock_rpc_device.call_rpc.reset_mock()
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 33},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mutate_rpc_device_status(monkeypatch, mock_rpc_device, "light:0", "output", True)
|
||||
mutate_rpc_device_status(monkeypatch, mock_rpc_device, "light:0", "brightness", 13)
|
||||
mock_rpc_device.mock_update()
|
||||
|
||||
mock_rpc_device.call_rpc.assert_called_once_with(
|
||||
"Light.Set", {"id": 0, "on": True, "brightness": 13}
|
||||
)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[ATTR_BRIGHTNESS] == 33
|
||||
|
Loading…
x
Reference in New Issue
Block a user