Add option to disable webhooks in ONVIF (#93186)
parent
0c51de25a2
commit
2eef2ed911
|
@ -20,7 +20,13 @@ from homeassistant.const import (
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
|
||||
from .const import CONF_SNAPSHOT_AUTH, DEFAULT_ARGUMENTS, DOMAIN
|
||||
from .const import (
|
||||
CONF_ENABLE_WEBHOOKS,
|
||||
CONF_SNAPSHOT_AUTH,
|
||||
DEFAULT_ARGUMENTS,
|
||||
DEFAULT_ENABLE_WEBHOOKS,
|
||||
DOMAIN,
|
||||
)
|
||||
from .device import ONVIFDevice
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
@ -143,6 +149,7 @@ async def async_populate_options(hass, entry):
|
|||
options = {
|
||||
CONF_EXTRA_ARGUMENTS: DEFAULT_ARGUMENTS,
|
||||
CONF_RTSP_TRANSPORT: next(iter(RTSP_TRANSPORTS)),
|
||||
CONF_ENABLE_WEBHOOKS: DEFAULT_ENABLE_WEBHOOKS,
|
||||
}
|
||||
|
||||
hass.config_entries.async_update_entry(entry, options=options)
|
||||
|
|
|
@ -34,7 +34,9 @@ from homeassistant.helpers import device_registry as dr
|
|||
|
||||
from .const import (
|
||||
CONF_DEVICE_ID,
|
||||
CONF_ENABLE_WEBHOOKS,
|
||||
DEFAULT_ARGUMENTS,
|
||||
DEFAULT_ENABLE_WEBHOOKS,
|
||||
DEFAULT_PORT,
|
||||
DOMAIN,
|
||||
GET_CAPABILITIES_EXCEPTIONS,
|
||||
|
@ -387,6 +389,12 @@ class OnvifOptionsFlowHandler(config_entries.OptionsFlow):
|
|||
CONF_USE_WALLCLOCK_AS_TIMESTAMPS,
|
||||
self.config_entry.options.get(CONF_USE_WALLCLOCK_AS_TIMESTAMPS, False),
|
||||
)
|
||||
self.options[CONF_ENABLE_WEBHOOKS] = user_input.get(
|
||||
CONF_ENABLE_WEBHOOKS,
|
||||
self.config_entry.options.get(
|
||||
CONF_ENABLE_WEBHOOKS, DEFAULT_ENABLE_WEBHOOKS
|
||||
),
|
||||
)
|
||||
return self.async_create_entry(title="", data=self.options)
|
||||
|
||||
advanced_options = {}
|
||||
|
@ -415,6 +423,12 @@ class OnvifOptionsFlowHandler(config_entries.OptionsFlow):
|
|||
CONF_RTSP_TRANSPORT, next(iter(RTSP_TRANSPORTS))
|
||||
),
|
||||
): vol.In(RTSP_TRANSPORTS),
|
||||
vol.Optional(
|
||||
CONF_ENABLE_WEBHOOKS,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_ENABLE_WEBHOOKS, DEFAULT_ENABLE_WEBHOOKS
|
||||
),
|
||||
): bool,
|
||||
**advanced_options,
|
||||
}
|
||||
),
|
||||
|
|
|
@ -14,6 +14,8 @@ DEFAULT_ARGUMENTS = "-pred 1"
|
|||
|
||||
CONF_DEVICE_ID = "deviceid"
|
||||
CONF_SNAPSHOT_AUTH = "snapshot_auth"
|
||||
CONF_ENABLE_WEBHOOKS = "enable_webhooks"
|
||||
DEFAULT_ENABLE_WEBHOOKS = True
|
||||
|
||||
ATTR_PAN = "pan"
|
||||
ATTR_TILT = "tilt"
|
||||
|
|
|
@ -28,7 +28,9 @@ import homeassistant.util.dt as dt_util
|
|||
|
||||
from .const import (
|
||||
ABSOLUTE_MOVE,
|
||||
CONF_ENABLE_WEBHOOKS,
|
||||
CONTINUOUS_MOVE,
|
||||
DEFAULT_ENABLE_WEBHOOKS,
|
||||
GET_CAPABILITIES_EXCEPTIONS,
|
||||
GOTOPRESET_MOVE,
|
||||
LOGGER,
|
||||
|
@ -52,6 +54,7 @@ class ONVIFDevice:
|
|||
"""Initialize the device."""
|
||||
self.hass: HomeAssistant = hass
|
||||
self.config_entry: ConfigEntry = config_entry
|
||||
self._original_options = dict(config_entry.options)
|
||||
self.available: bool = True
|
||||
|
||||
self.info: DeviceInfo = DeviceInfo()
|
||||
|
@ -63,6 +66,13 @@ class ONVIFDevice:
|
|||
|
||||
self._dt_diff_seconds: float = 0
|
||||
|
||||
async def _async_update_listener(
|
||||
self, hass: HomeAssistant, entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Handle options update."""
|
||||
if self._original_options != entry.options:
|
||||
hass.async_create_task(hass.config_entries.async_reload(entry.entry_id))
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return the name of this device."""
|
||||
|
@ -151,6 +161,14 @@ class ONVIFDevice:
|
|||
self.capabilities.events = await self.async_start_events()
|
||||
LOGGER.debug("Camera %s capabilities = %s", self.name, self.capabilities)
|
||||
|
||||
# Bind the listener to the ONVIFDevice instance since
|
||||
# async_update_listener only creates a weak reference to the listener
|
||||
# and we need to make sure it doesn't get garbage collected since only
|
||||
# the ONVIFDevice instance is stored in hass.data
|
||||
self.config_entry.async_on_unload(
|
||||
self.config_entry.add_update_listener(self._async_update_listener)
|
||||
)
|
||||
|
||||
async def async_stop(self, event=None):
|
||||
"""Shut it all down."""
|
||||
if self.events:
|
||||
|
@ -357,7 +375,12 @@ class ONVIFDevice:
|
|||
"WSPullPointSupport"
|
||||
)
|
||||
LOGGER.debug("%s: WSPullPointSupport: %s", self.name, pull_point_support)
|
||||
return await self.events.async_start(pull_point_support is not False, True)
|
||||
return await self.events.async_start(
|
||||
pull_point_support is not False,
|
||||
self.config_entry.options.get(
|
||||
CONF_ENABLE_WEBHOOKS, DEFAULT_ENABLE_WEBHOOKS
|
||||
),
|
||||
)
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
"data": {
|
||||
"extra_arguments": "Extra FFMPEG arguments",
|
||||
"rtsp_transport": "RTSP transport mechanism",
|
||||
"use_wallclock_as_timestamps": "Use wall clock as timestamps"
|
||||
"use_wallclock_as_timestamps": "Use wall clock as timestamps",
|
||||
"enable_webhooks": "Enable Webhooks"
|
||||
},
|
||||
"title": "ONVIF Device Options"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""Test ONVIF config flow."""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components import dhcp
|
||||
from homeassistant.components.onvif import DOMAIN, config_flow
|
||||
|
@ -597,7 +599,8 @@ async def test_flow_manual_entry_wrong_password(hass: HomeAssistant) -> None:
|
|||
}
|
||||
|
||||
|
||||
async def test_option_flow(hass: HomeAssistant) -> None:
|
||||
@pytest.mark.parametrize("option_value", [True, False])
|
||||
async def test_option_flow(hass: HomeAssistant, option_value: bool) -> None:
|
||||
"""Test config flow options."""
|
||||
entry, _, _ = await setup_onvif_integration(hass)
|
||||
|
||||
|
@ -613,7 +616,8 @@ async def test_option_flow(hass: HomeAssistant) -> None:
|
|||
user_input={
|
||||
config_flow.CONF_EXTRA_ARGUMENTS: "",
|
||||
config_flow.CONF_RTSP_TRANSPORT: list(config_flow.RTSP_TRANSPORTS)[1],
|
||||
config_flow.CONF_USE_WALLCLOCK_AS_TIMESTAMPS: True,
|
||||
config_flow.CONF_USE_WALLCLOCK_AS_TIMESTAMPS: option_value,
|
||||
config_flow.CONF_ENABLE_WEBHOOKS: option_value,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -621,7 +625,8 @@ async def test_option_flow(hass: HomeAssistant) -> None:
|
|||
assert result["data"] == {
|
||||
config_flow.CONF_EXTRA_ARGUMENTS: "",
|
||||
config_flow.CONF_RTSP_TRANSPORT: list(config_flow.RTSP_TRANSPORTS)[1],
|
||||
config_flow.CONF_USE_WALLCLOCK_AS_TIMESTAMPS: True,
|
||||
config_flow.CONF_USE_WALLCLOCK_AS_TIMESTAMPS: option_value,
|
||||
config_flow.CONF_ENABLE_WEBHOOKS: option_value,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,11 @@ async def test_diagnostics(
|
|||
"password": "**REDACTED**",
|
||||
"snapshot_auth": "digest",
|
||||
},
|
||||
"options": {"extra_arguments": "-pred 1", "rtsp_transport": "tcp"},
|
||||
"options": {
|
||||
"extra_arguments": "-pred 1",
|
||||
"rtsp_transport": "tcp",
|
||||
"enable_webhooks": True,
|
||||
},
|
||||
"pref_disable_new_entities": False,
|
||||
"pref_disable_polling": False,
|
||||
"source": "user",
|
||||
|
|
Loading…
Reference in New Issue