Fix blocking I/O in the event loop when starting ONVIF (#92518)

This commit is contained in:
J. Nick Koston 2023-05-04 12:05:29 -05:00 committed by GitHub
parent e0903b8bc4
commit 7987b00d89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 23 additions and 23 deletions

View File

@ -34,7 +34,7 @@ class RebootButton(ONVIFBaseEntity, ButtonEntity):
async def async_press(self) -> None: async def async_press(self) -> None:
"""Send out a SystemReboot command.""" """Send out a SystemReboot command."""
device_mgmt = self.device.device.create_devicemgmt_service() device_mgmt = await self.device.device.create_devicemgmt_service()
await device_mgmt.SystemReboot() await device_mgmt.SystemReboot()

View File

@ -275,7 +275,7 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
try: try:
await device.update_xaddrs() await device.update_xaddrs()
device_mgmt = device.create_devicemgmt_service() device_mgmt = await device.create_devicemgmt_service()
# Get the MAC address to use as the unique ID for the config flow # Get the MAC address to use as the unique ID for the config flow
if not self.device_id: if not self.device_id:
try: try:
@ -314,7 +314,7 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
} }
) )
# Verify there is an H264 profile # Verify there is an H264 profile
media_service = device.create_media_service() media_service = await device.create_media_service()
profiles = await media_service.GetProfiles() profiles = await media_service.GetProfiles()
except AttributeError: # Likely an empty document or 404 from the wrong port except AttributeError: # Likely an empty document or 404 from the wrong port
LOGGER.debug( LOGGER.debug(

View File

@ -136,7 +136,7 @@ class ONVIFDevice:
if self.capabilities.ptz: if self.capabilities.ptz:
LOGGER.debug("%s: creating PTZ service", self.name) LOGGER.debug("%s: creating PTZ service", self.name)
self.device.create_ptz_service() await self.device.create_ptz_service()
# Determine max resolution from profiles # Determine max resolution from profiles
self.max_resolution = max( self.max_resolution = max(
@ -159,7 +159,7 @@ class ONVIFDevice:
async def async_manually_set_date_and_time(self) -> None: async def async_manually_set_date_and_time(self) -> None:
"""Set Date and Time Manually using SetSystemDateAndTime command.""" """Set Date and Time Manually using SetSystemDateAndTime command."""
device_mgmt = self.device.create_devicemgmt_service() device_mgmt = await self.device.create_devicemgmt_service()
# Retrieve DateTime object from camera to use as template for Set operation # Retrieve DateTime object from camera to use as template for Set operation
device_time = await device_mgmt.GetSystemDateAndTime() device_time = await device_mgmt.GetSystemDateAndTime()
@ -202,7 +202,7 @@ class ONVIFDevice:
async def async_check_date_and_time(self) -> None: async def async_check_date_and_time(self) -> None:
"""Warns if device and system date not synced.""" """Warns if device and system date not synced."""
LOGGER.debug("%s: Setting up the ONVIF device management service", self.name) LOGGER.debug("%s: Setting up the ONVIF device management service", self.name)
device_mgmt = self.device.create_devicemgmt_service() device_mgmt = await self.device.create_devicemgmt_service()
system_date = dt_util.utcnow() system_date = dt_util.utcnow()
LOGGER.debug("%s: Retrieving current device date/time", self.name) LOGGER.debug("%s: Retrieving current device date/time", self.name)
@ -285,7 +285,7 @@ class ONVIFDevice:
async def async_get_device_info(self) -> DeviceInfo: async def async_get_device_info(self) -> DeviceInfo:
"""Obtain information about this device.""" """Obtain information about this device."""
device_mgmt = self.device.create_devicemgmt_service() device_mgmt = await self.device.create_devicemgmt_service()
manufacturer = None manufacturer = None
model = None model = None
firmware_version = None firmware_version = None
@ -331,7 +331,7 @@ class ONVIFDevice:
"""Obtain information about the available services on the device.""" """Obtain information about the available services on the device."""
snapshot = False snapshot = False
with suppress(*GET_CAPABILITIES_EXCEPTIONS): with suppress(*GET_CAPABILITIES_EXCEPTIONS):
media_service = self.device.create_media_service() media_service = await self.device.create_media_service()
media_capabilities = await media_service.GetServiceCapabilities() media_capabilities = await media_service.GetServiceCapabilities()
snapshot = media_capabilities and media_capabilities.SnapshotUri snapshot = media_capabilities and media_capabilities.SnapshotUri
@ -342,7 +342,7 @@ class ONVIFDevice:
imaging = False imaging = False
with suppress(*GET_CAPABILITIES_EXCEPTIONS): with suppress(*GET_CAPABILITIES_EXCEPTIONS):
self.device.create_imaging_service() await self.device.create_imaging_service()
imaging = True imaging = True
return Capabilities(snapshot=snapshot, ptz=ptz, imaging=imaging) return Capabilities(snapshot=snapshot, ptz=ptz, imaging=imaging)
@ -361,7 +361,7 @@ class ONVIFDevice:
async def async_get_profiles(self) -> list[Profile]: async def async_get_profiles(self) -> list[Profile]:
"""Obtain media profiles for this device.""" """Obtain media profiles for this device."""
media_service = self.device.create_media_service() media_service = await self.device.create_media_service()
LOGGER.debug("%s: xaddr for media_service: %s", self.name, media_service.xaddr) LOGGER.debug("%s: xaddr for media_service: %s", self.name, media_service.xaddr)
try: try:
result = await media_service.GetProfiles() result = await media_service.GetProfiles()
@ -408,7 +408,7 @@ class ONVIFDevice:
) )
try: try:
ptz_service = self.device.create_ptz_service() ptz_service = await self.device.create_ptz_service()
presets = await ptz_service.GetPresets(profile.token) presets = await ptz_service.GetPresets(profile.token)
profile.ptz.presets = [preset.token for preset in presets if preset] profile.ptz.presets = [preset.token for preset in presets if preset]
except GET_CAPABILITIES_EXCEPTIONS: except GET_CAPABILITIES_EXCEPTIONS:
@ -427,7 +427,7 @@ class ONVIFDevice:
async def async_get_stream_uri(self, profile: Profile) -> str: async def async_get_stream_uri(self, profile: Profile) -> str:
"""Get the stream URI for a specified profile.""" """Get the stream URI for a specified profile."""
media_service = self.device.create_media_service() media_service = await self.device.create_media_service()
req = media_service.create_type("GetStreamUri") req = media_service.create_type("GetStreamUri")
req.ProfileToken = profile.token req.ProfileToken = profile.token
req.StreamSetup = { req.StreamSetup = {
@ -454,7 +454,7 @@ class ONVIFDevice:
LOGGER.warning("PTZ actions are not supported on device '%s'", self.name) LOGGER.warning("PTZ actions are not supported on device '%s'", self.name)
return return
ptz_service = self.device.create_ptz_service() ptz_service = await self.device.create_ptz_service()
pan_val = distance * PAN_FACTOR.get(pan, 0) pan_val = distance * PAN_FACTOR.get(pan, 0)
tilt_val = distance * TILT_FACTOR.get(tilt, 0) tilt_val = distance * TILT_FACTOR.get(tilt, 0)
@ -576,7 +576,7 @@ class ONVIFDevice:
LOGGER.warning("PTZ actions are not supported on device '%s'", self.name) LOGGER.warning("PTZ actions are not supported on device '%s'", self.name)
return return
ptz_service = self.device.create_ptz_service() ptz_service = await self.device.create_ptz_service()
LOGGER.debug( LOGGER.debug(
"Running Aux Command | Cmd = %s", "Running Aux Command | Cmd = %s",
@ -607,7 +607,7 @@ class ONVIFDevice:
) )
return return
imaging_service = self.device.create_imaging_service() imaging_service = await self.device.create_imaging_service()
LOGGER.debug("Setting Imaging Setting | Settings = %s", settings) LOGGER.debug("Setting Imaging Setting | Settings = %s", settings)
try: try:

View File

@ -392,12 +392,12 @@ class PullPointManager:
return False return False
# Create subscription manager # Create subscription manager
self._pullpoint_subscription = self._device.create_subscription_service( self._pullpoint_subscription = await self._device.create_subscription_service(
"PullPointSubscription" "PullPointSubscription"
) )
# Create the service that will be used to pull messages from the device. # Create the service that will be used to pull messages from the device.
self._pullpoint_service = self._device.create_pullpoint_service() self._pullpoint_service = await self._device.create_pullpoint_service()
# Initialize events # Initialize events
with suppress(*SET_SYNCHRONIZATION_POINT_ERRORS): with suppress(*SET_SYNCHRONIZATION_POINT_ERRORS):

View File

@ -8,5 +8,5 @@
"documentation": "https://www.home-assistant.io/integrations/onvif", "documentation": "https://www.home-assistant.io/integrations/onvif",
"iot_class": "local_push", "iot_class": "local_push",
"loggers": ["onvif", "wsdiscovery", "zeep"], "loggers": ["onvif", "wsdiscovery", "zeep"],
"requirements": ["onvif-zeep-async==1.3.1", "WSDiscovery==2.0.0"] "requirements": ["onvif-zeep-async==2.0.0", "WSDiscovery==2.0.0"]
} }

View File

@ -1258,7 +1258,7 @@ ondilo==0.2.0
onkyo-eiscp==1.2.7 onkyo-eiscp==1.2.7
# homeassistant.components.onvif # homeassistant.components.onvif
onvif-zeep-async==1.3.1 onvif-zeep-async==2.0.0
# homeassistant.components.opengarage # homeassistant.components.opengarage
open-garage==0.2.0 open-garage==0.2.0

View File

@ -945,7 +945,7 @@ omnilogic==0.4.5
ondilo==0.2.0 ondilo==0.2.0
# homeassistant.components.onvif # homeassistant.components.onvif
onvif-zeep-async==1.3.1 onvif-zeep-async==2.0.0
# homeassistant.components.opengarage # homeassistant.components.opengarage
open-garage==0.2.0 open-garage==0.2.0

View File

@ -98,8 +98,8 @@ def setup_mock_onvif_camera(
) )
else: else:
mock_onvif_camera.update_xaddrs = AsyncMock(return_value=True) mock_onvif_camera.update_xaddrs = AsyncMock(return_value=True)
mock_onvif_camera.create_devicemgmt_service = MagicMock(return_value=devicemgmt) mock_onvif_camera.create_devicemgmt_service = AsyncMock(return_value=devicemgmt)
mock_onvif_camera.create_media_service = MagicMock(return_value=media_service) mock_onvif_camera.create_media_service = AsyncMock(return_value=media_service)
mock_onvif_camera.close = AsyncMock(return_value=None) mock_onvif_camera.close = AsyncMock(return_value=None)
def mock_constructor( def mock_constructor(

View File

@ -27,7 +27,7 @@ async def test_reboot_button(hass: HomeAssistant) -> None:
async def test_reboot_button_press(hass: HomeAssistant) -> None: async def test_reboot_button_press(hass: HomeAssistant) -> None:
"""Test Reboot button press.""" """Test Reboot button press."""
_, camera, _ = await setup_onvif_integration(hass) _, camera, _ = await setup_onvif_integration(hass)
devicemgmt = camera.create_devicemgmt_service() devicemgmt = await camera.create_devicemgmt_service()
devicemgmt.SystemReboot = AsyncMock(return_value=True) devicemgmt.SystemReboot = AsyncMock(return_value=True)
await hass.services.async_call( await hass.services.async_call(