Avoid creating onvif switches on unsupported devices (#91907)

* Avoid creating onvif switches on unsupported devices

fixes #89064

* cover
This commit is contained in:
J. Nick Koston 2023-04-23 19:56:43 -05:00 committed by GitHub
parent 0b0c94ee52
commit 14d2645de2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 6 deletions

View File

@ -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):

View File

@ -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()

View File

@ -55,7 +55,7 @@ async def test_diagnostics(
"capabilities": {
"snapshot": False,
"events": False,
"ptz": False,
"ptz": True,
"imaging": True,
},
"profiles": [

View File

@ -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)