diff --git a/homeassistant/components/onvif/switch.py b/homeassistant/components/onvif/switch.py index c72a826a79c..4f7de67386b 100644 --- a/homeassistant/components/onvif/switch.py +++ b/homeassistant/components/onvif/switch.py @@ -28,6 +28,7 @@ class ONVIFSwitchEntityDescriptionMixin: ] turn_on_data: Any turn_off_data: Any + supported_fn: Callable[[ONVIFDevice], bool] @dataclass @@ -46,6 +47,7 @@ SWITCHES: tuple[ONVIFSwitchEntityDescription, ...] = ( turn_off_data={"Focus": {"AutoFocusMode": "MANUAL"}}, turn_on_fn=lambda device: device.async_set_imaging_settings, turn_off_fn=lambda device: device.async_set_imaging_settings, + supported_fn=lambda device: device.capabilities.imaging, ), ONVIFSwitchEntityDescription( key="ir_lamp", @@ -55,6 +57,7 @@ SWITCHES: tuple[ONVIFSwitchEntityDescription, ...] = ( turn_off_data={"IrCutFilter": "ON"}, turn_on_fn=lambda device: device.async_set_imaging_settings, turn_off_fn=lambda device: device.async_set_imaging_settings, + supported_fn=lambda device: device.capabilities.imaging, ), ONVIFSwitchEntityDescription( key="wiper", @@ -64,6 +67,7 @@ SWITCHES: tuple[ONVIFSwitchEntityDescription, ...] = ( turn_off_data="tt:Wiper|Off", turn_on_fn=lambda device: device.async_run_aux_command, turn_off_fn=lambda device: device.async_run_aux_command, + supported_fn=lambda device: device.capabilities.ptz, ), ) @@ -76,7 +80,11 @@ async def async_setup_entry( """Set up a ONVIF switch platform.""" device = hass.data[DOMAIN][config_entry.unique_id] - async_add_entities(ONVIFSwitch(device, description) for description in SWITCHES) + async_add_entities( + ONVIFSwitch(device, description) + for description in SWITCHES + if description.supported_fn(device) + ) class ONVIFSwitch(ONVIFBaseEntity, SwitchEntity): diff --git a/tests/components/onvif/__init__.py b/tests/components/onvif/__init__.py index 17ba41588ff..fc29b99303a 100644 --- a/tests/components/onvif/__init__.py +++ b/tests/components/onvif/__init__.py @@ -91,7 +91,7 @@ def setup_mock_onvif_camera( mock_onvif_camera.side_effect = mock_constructor -def setup_mock_device(mock_device): +def setup_mock_device(mock_device, capabilities=None): """Prepare mock ONVIFDevice.""" mock_device.async_setup = AsyncMock(return_value=True) mock_device.available = True @@ -103,7 +103,7 @@ def setup_mock_device(mock_device): SERIAL_NUMBER, MAC, ) - mock_device.capabilities = Capabilities(imaging=True) + mock_device.capabilities = capabilities or Capabilities(imaging=True, ptz=True) profile1 = Profile( index=0, token="dummy", @@ -132,6 +132,7 @@ async def setup_onvif_integration( unique_id=MAC, entry_id="1", source=config_entries.SOURCE_USER, + capabilities=None, ) -> tuple[MockConfigEntry, MagicMock, MagicMock]: """Create an ONVIF config entry.""" if not config: @@ -164,7 +165,7 @@ async def setup_onvif_integration( setup_mock_onvif_camera(mock_onvif_camera, two_profiles=True) # no discovery mock_discovery.return_value = [] - setup_mock_device(mock_device) + setup_mock_device(mock_device, capabilities=capabilities) mock_device.device = mock_onvif_camera await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() diff --git a/tests/components/onvif/test_diagnostics.py b/tests/components/onvif/test_diagnostics.py index 0ef474e7790..70dafe960b4 100644 --- a/tests/components/onvif/test_diagnostics.py +++ b/tests/components/onvif/test_diagnostics.py @@ -55,7 +55,7 @@ async def test_diagnostics( "capabilities": { "snapshot": False, "events": False, - "ptz": False, + "ptz": True, "imaging": True, }, "profiles": [ diff --git a/tests/components/onvif/test_switch.py b/tests/components/onvif/test_switch.py index ef20586e0bf..1228f72ba22 100644 --- a/tests/components/onvif/test_switch.py +++ b/tests/components/onvif/test_switch.py @@ -6,7 +6,7 @@ from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNKNO from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from . import MAC, setup_onvif_integration +from . import MAC, Capabilities, setup_onvif_integration async def test_wiper_switch(hass: HomeAssistant) -> None: @@ -24,6 +24,16 @@ async def test_wiper_switch(hass: HomeAssistant) -> None: assert entry.unique_id == f"{MAC}_wiper" +async def test_wiper_switch_no_ptz(hass: HomeAssistant) -> None: + """Test the wiper switch does not get created if the camera does not support ptz.""" + _config, _camera, device = await setup_onvif_integration( + hass, capabilities=Capabilities(imaging=True, ptz=False) + ) + device.profiles = device.async_get_profiles() + + assert hass.states.get("switch.testcamera_wiper") is None + + async def test_turn_wiper_switch_on(hass: HomeAssistant) -> None: """Test Wiper switch turn on.""" _, _camera, device = await setup_onvif_integration(hass) @@ -75,6 +85,16 @@ async def test_autofocus_switch(hass: HomeAssistant) -> None: assert entry.unique_id == f"{MAC}_autofocus" +async def test_auto_focus_switch_no_imaging(hass: HomeAssistant) -> None: + """Test the autofocus switch does not get created if the camera does not support imaging.""" + _config, _camera, device = await setup_onvif_integration( + hass, capabilities=Capabilities(imaging=False, ptz=True) + ) + device.profiles = device.async_get_profiles() + + assert hass.states.get("switch.testcamera_autofocus") is None + + async def test_turn_autofocus_switch_on(hass: HomeAssistant) -> None: """Test autofocus switch turn on.""" _, _camera, device = await setup_onvif_integration(hass) @@ -126,6 +146,16 @@ async def test_infrared_switch(hass: HomeAssistant) -> None: assert entry.unique_id == f"{MAC}_ir_lamp" +async def test_infrared_switch_no_imaging(hass: HomeAssistant) -> None: + """Test the infrared switch does not get created if the camera does not support imaging.""" + _config, _camera, device = await setup_onvif_integration( + hass, capabilities=Capabilities(imaging=False, ptz=False) + ) + device.profiles = device.async_get_profiles() + + assert hass.states.get("switch.testcamera_ir_lamp") is None + + async def test_turn_infrared_switch_on(hass: HomeAssistant) -> None: """Test infrared switch turn on.""" _, _camera, device = await setup_onvif_integration(hass)