"""Tests for Shelly light platform.""" from unittest.mock import AsyncMock, Mock from aioshelly.const import ( MODEL_BULB, MODEL_BULB_RGBW, MODEL_DIMMER, MODEL_DIMMER_2, MODEL_DUO, MODEL_RGBW2, MODEL_VINTAGE_V2, ) import pytest from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_MODE, ATTR_COLOR_TEMP_KELVIN, ATTR_EFFECT, ATTR_EFFECT_LIST, ATTR_RGB_COLOR, ATTR_RGBW_COLOR, ATTR_SUPPORTED_COLOR_MODES, ATTR_TRANSITION, DOMAIN as LIGHT_DOMAIN, SERVICE_TURN_OFF, SERVICE_TURN_ON, ColorMode, LightEntityFeature, ) from homeassistant.components.shelly.const import SHELLY_PLUS_RGBW_CHANNELS from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, STATE_OFF, STATE_ON, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_registry import EntityRegistry from . import get_entity, init_integration, mutate_rpc_device_status, register_entity from .conftest import mock_white_light_set_state RELAY_BLOCK_ID = 0 LIGHT_BLOCK_ID = 2 async def test_block_device_rgbw_bulb( hass: HomeAssistant, mock_block_device: Mock, entity_registry: EntityRegistry ) -> None: """Test block device RGBW bulb.""" entity_id = "light.test_name_channel_1" await init_integration(hass, 1, model=MODEL_BULB) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_RGBW_COLOR] == (45, 55, 65, 70) assert attributes[ATTR_BRIGHTNESS] == 48 assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ ColorMode.COLOR_TEMP, ColorMode.RGBW, ] assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.EFFECT assert len(attributes[ATTR_EFFECT_LIST]) == 7 assert attributes[ATTR_EFFECT] == "Off" # Turn off mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="off" ) state = hass.states.get(entity_id) assert state.state == STATE_OFF # Turn on, RGBW = [70, 80, 90, 20], brightness = 33, effect = Flash mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: entity_id, ATTR_RGBW_COLOR: [70, 80, 90, 30], ATTR_BRIGHTNESS: 33, ATTR_EFFECT: "Flash", }, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", gain=13, brightness=13, red=70, green=80, blue=90, white=30, effect=3 ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.RGBW assert attributes[ATTR_RGBW_COLOR] == (70, 80, 90, 30) assert attributes[ATTR_BRIGHTNESS] == 33 assert attributes[ATTR_EFFECT] == "Flash" # Turn on, COLOR_TEMP_KELVIN = 3500 mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP_KELVIN: 3500}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", temp=3500, mode="white" ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP assert attributes[ATTR_COLOR_TEMP_KELVIN] == 3500 entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-light_0" async def test_block_device_rgb_bulb( hass: HomeAssistant, mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch, entity_registry: EntityRegistry, caplog: pytest.LogCaptureFixture, ) -> None: """Test block device RGB bulb.""" entity_id = "light.test_name_channel_1" monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "mode") monkeypatch.setattr( mock_block_device.blocks[LIGHT_BLOCK_ID], "description", "light_1" ) await init_integration(hass, 1, model=MODEL_BULB_RGBW) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_RGB_COLOR] == (45, 55, 65) assert attributes[ATTR_BRIGHTNESS] == 48 assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ ColorMode.COLOR_TEMP, ColorMode.RGB, ] assert ( attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.EFFECT | LightEntityFeature.TRANSITION ) assert len(attributes[ATTR_EFFECT_LIST]) == 4 assert attributes[ATTR_EFFECT] == "Off" # Turn off mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="off" ) state = hass.states.get(entity_id) assert state.state == STATE_OFF # Turn on, RGB = [70, 80, 90], brightness = 33, effect = Flash mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, { ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: [70, 80, 90], ATTR_BRIGHTNESS: 33, ATTR_EFFECT: "Flash", }, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", gain=13, brightness=13, red=70, green=80, blue=90, effect=3 ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.RGB assert attributes[ATTR_RGB_COLOR] == (70, 80, 90) assert attributes[ATTR_BRIGHTNESS] == 33 assert attributes[ATTR_EFFECT] == "Flash" # Turn on, COLOR_TEMP_KELVIN = 3500 mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_COLOR_TEMP_KELVIN: 3500}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", temp=3500, mode="white" ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP assert attributes[ATTR_COLOR_TEMP_KELVIN] == 3500 # Turn on with unsupported effect mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "Breath"}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", mode="color" ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_EFFECT] == "Off" assert "Effect 'Breath' not supported" in caplog.text entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-light_1" async def test_block_device_white_bulb( hass: HomeAssistant, mock_block_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test block device white bulb.""" entity_id = "light.test_name_channel_1" monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "red") monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "green") monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "blue") monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "mode") monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "colorTemp") monkeypatch.delattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "effect") monkeypatch.setattr( mock_block_device.blocks[LIGHT_BLOCK_ID], "description", "light_1" ) monkeypatch.setattr( mock_block_device.blocks[LIGHT_BLOCK_ID], "set_state", AsyncMock(side_effect=mock_white_light_set_state), ) await init_integration(hass, 1, model=MODEL_VINTAGE_V2) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_BRIGHTNESS] == 128 assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.BRIGHTNESS] assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION # Turn off mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="off" ) state = hass.states.get(entity_id) assert state.state == STATE_OFF # Turn on, brightness = 33 mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 33}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", gain=13, brightness=13 ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_BRIGHTNESS] == 33 entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-light_1" @pytest.mark.parametrize( "model", [ MODEL_DUO, MODEL_BULB_RGBW, MODEL_DIMMER, MODEL_DIMMER_2, MODEL_RGBW2, MODEL_VINTAGE_V2, ], ) async def test_block_device_support_transition( hass: HomeAssistant, mock_block_device: Mock, entity_registry: EntityRegistry, model: str, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test block device supports transition.""" entity_id = "light.test_name_channel_1" monkeypatch.setitem( mock_block_device.settings, "fw", "20220809-122808/v1.12-g99f7e0b" ) monkeypatch.setattr( mock_block_device.blocks[LIGHT_BLOCK_ID], "description", "light_1" ) await init_integration(hass, 1, model=model) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert attributes[ATTR_SUPPORTED_FEATURES] & LightEntityFeature.TRANSITION # Turn on, TRANSITION = 4 mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_TRANSITION: 4}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="on", transition=4000 ) state = hass.states.get(entity_id) assert state.state == STATE_ON # Turn off, TRANSITION = 6, limit to 5000ms mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id, ATTR_TRANSITION: 6}, blocking=True, ) mock_block_device.blocks[LIGHT_BLOCK_ID].set_state.assert_called_once_with( turn="off", transition=5000 ) state = hass.states.get(entity_id) assert state.state == STATE_OFF entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-light_1" async def test_block_device_relay_app_type_light( hass: HomeAssistant, mock_block_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test block device relay in app type set to light mode.""" entity_id = "light.test_name_channel_1" monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "red") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "green") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "blue") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "mode") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "gain") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "brightness") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "effect") monkeypatch.delattr(mock_block_device.blocks[RELAY_BLOCK_ID], "colorTemp") monkeypatch.setitem( mock_block_device.settings["relays"][RELAY_BLOCK_ID], "appliance_type", "light" ) monkeypatch.setattr( mock_block_device.blocks[RELAY_BLOCK_ID], "description", "relay_1" ) await init_integration(hass, 1) assert hass.states.get("switch.test_name_channel_1") is None # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.ONOFF] assert attributes[ATTR_SUPPORTED_FEATURES] == 0 # Turn off mock_block_device.blocks[RELAY_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) mock_block_device.blocks[RELAY_BLOCK_ID].set_state.assert_called_once_with( turn="off" ) state = hass.states.get(entity_id) assert state.state == STATE_OFF # Turn on mock_block_device.blocks[RELAY_BLOCK_ID].set_state.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) mock_block_device.blocks[RELAY_BLOCK_ID].set_state.assert_called_once_with( turn="on" ) state = hass.states.get(entity_id) assert state.state == STATE_ON entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-relay_1" async def test_block_device_no_light_blocks( hass: HomeAssistant, mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch ) -> None: """Test block device without light blocks.""" monkeypatch.setattr(mock_block_device.blocks[LIGHT_BLOCK_ID], "type", "roller") await init_integration(hass, 1) assert hass.states.get("light.test_name_channel_1") is None async def test_rpc_device_switch_type_lights_mode( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test RPC device with switch in consumption type lights mode.""" entity_id = "light.test_switch_0" monkeypatch.setitem( mock_rpc_device.config["sys"]["ui_data"], "consumption_types", ["lights"] ) await init_integration(hass, 2) await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) assert hass.states.get(entity_id).state == STATE_ON mutate_rpc_device_status(monkeypatch, mock_rpc_device, "switch: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() assert hass.states.get(entity_id).state == STATE_OFF entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-switch:0" async def test_rpc_light( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """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 # Turn on, transition = 10.1 mock_rpc_device.call_rpc.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_TRANSITION: 10.1}, blocking=True, ) mock_rpc_device.mock_update() mock_rpc_device.call_rpc.assert_called_once_with( "Light.Set", {"id": 0, "on": True, "transition_duration": 10.1} ) state = hass.states.get(entity_id) assert state.state == STATE_ON # Turn off, transition = 0.4, should be limited to 0.5 mock_rpc_device.call_rpc.reset_mock() await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id, ATTR_TRANSITION: 0.4}, blocking=True, ) mutate_rpc_device_status(monkeypatch, mock_rpc_device, "light:0", "output", False) mock_rpc_device.mock_update() mock_rpc_device.call_rpc.assert_called_once_with( "Light.Set", {"id": 0, "on": False, "transition_duration": 0.5} ) state = hass.states.get(entity_id) assert state.state == STATE_OFF entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-light:0" async def test_rpc_device_rgb_profile( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test RPC device in RGB profile.""" for i in range(SHELLY_PLUS_RGBW_CHANNELS): monkeypatch.delitem(mock_rpc_device.status, f"light:{i}") monkeypatch.delitem(mock_rpc_device.status, "rgbw:0") entity_id = "light.test_rgb_0" await init_integration(hass, 2) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_RGB_COLOR] == (45, 55, 65) assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.RGB] assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION # Turn on, RGB = [70, 80, 90] await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: [70, 80, 90]}, blocking=True, ) mutate_rpc_device_status(monkeypatch, mock_rpc_device, "rgb:0", "rgb", [70, 80, 90]) mock_rpc_device.mock_update() mock_rpc_device.call_rpc.assert_called_once_with( "RGB.Set", {"id": 0, "on": True, "rgb": [70, 80, 90]} ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.RGB assert attributes[ATTR_RGB_COLOR] == (70, 80, 90) entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-rgb:0" async def test_rpc_device_rgbw_profile( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test RPC device in RGBW profile.""" for i in range(SHELLY_PLUS_RGBW_CHANNELS): monkeypatch.delitem(mock_rpc_device.status, f"light:{i}") monkeypatch.delitem(mock_rpc_device.status, "rgb:0") entity_id = "light.test_rgbw_0" await init_integration(hass, 2) # Test initial state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_RGBW_COLOR] == (21, 22, 23, 120) assert attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.RGBW] assert attributes[ATTR_SUPPORTED_FEATURES] == LightEntityFeature.TRANSITION # Turn on, RGBW = [72, 82, 92, 128] await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id, ATTR_RGBW_COLOR: [72, 82, 92, 128]}, blocking=True, ) mutate_rpc_device_status( monkeypatch, mock_rpc_device, "rgbw:0", "rgb", [72, 82, 92] ) mutate_rpc_device_status(monkeypatch, mock_rpc_device, "rgbw:0", "white", 128) mock_rpc_device.mock_update() mock_rpc_device.call_rpc.assert_called_once_with( "RGBW.Set", {"id": 0, "on": True, "rgb": [72, 82, 92], "white": 128} ) state = hass.states.get(entity_id) attributes = state.attributes assert state.state == STATE_ON assert attributes[ATTR_COLOR_MODE] == ColorMode.RGBW assert attributes[ATTR_RGBW_COLOR] == (72, 82, 92, 128) entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == "123456789ABC-rgbw:0" async def test_rpc_rgbw_device_light_mode_remove_others( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, ) -> None: """Test Shelly RPC RGBW device in light mode removes RGB/RGBW entities.""" # register lights monkeypatch.delitem(mock_rpc_device.status, "rgb:0") monkeypatch.delitem(mock_rpc_device.status, "rgbw:0") register_entity(hass, LIGHT_DOMAIN, "test_rgb_0", "rgb:0") register_entity(hass, LIGHT_DOMAIN, "test_rgbw_0", "rgbw:0") # verify RGB & RGBW entities created assert get_entity(hass, LIGHT_DOMAIN, "rgb:0") is not None assert get_entity(hass, LIGHT_DOMAIN, "rgbw:0") is not None # init to remove RGB & RGBW await init_integration(hass, 2) # verify we have 4 lights for i in range(SHELLY_PLUS_RGBW_CHANNELS): entity_id = f"light.test_light_{i}" assert hass.states.get(entity_id).state == STATE_ON entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == f"123456789ABC-light:{i}" # verify RGB & RGBW entities removed assert get_entity(hass, LIGHT_DOMAIN, "rgb:0") is None assert get_entity(hass, LIGHT_DOMAIN, "rgbw:0") is None @pytest.mark.parametrize( ("active_mode", "removed_mode"), [ ("rgb", "rgbw"), ("rgbw", "rgb"), ], ) async def test_rpc_rgbw_device_rgb_w_modes_remove_others( hass: HomeAssistant, mock_rpc_device: Mock, entity_registry: EntityRegistry, monkeypatch: pytest.MonkeyPatch, active_mode: str, removed_mode: str, ) -> None: """Test Shelly RPC RGBW device in RGB/W modes other lights.""" removed_key = f"{removed_mode}:0" # register lights for i in range(SHELLY_PLUS_RGBW_CHANNELS): monkeypatch.delitem(mock_rpc_device.status, f"light:{i}") entity_id = f"light.test_light_{i}" register_entity(hass, LIGHT_DOMAIN, entity_id, f"light:{i}") monkeypatch.delitem(mock_rpc_device.status, f"{removed_mode}:0") register_entity(hass, LIGHT_DOMAIN, f"test_{removed_key}", removed_key) # verify lights entities created for i in range(SHELLY_PLUS_RGBW_CHANNELS): assert get_entity(hass, LIGHT_DOMAIN, f"light:{i}") is not None assert get_entity(hass, LIGHT_DOMAIN, removed_key) is not None await init_integration(hass, 2) # verify we have RGB/w light entity_id = f"light.test_{active_mode}_0" assert hass.states.get(entity_id).state == STATE_ON entry = entity_registry.async_get(entity_id) assert entry assert entry.unique_id == f"123456789ABC-{active_mode}:0" # verify light & RGB/W entities removed for i in range(SHELLY_PLUS_RGBW_CHANNELS): assert get_entity(hass, LIGHT_DOMAIN, f"light:{i}") is None assert get_entity(hass, LIGHT_DOMAIN, removed_key) is None