mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Check webhook url is reachable in Reolink (#89585)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
24d0d15f38
commit
e9925f6062
@ -54,7 +54,9 @@ class ReolinkHost:
|
||||
)
|
||||
|
||||
self.webhook_id: str | None = None
|
||||
self._webhook_url: str | None = None
|
||||
self._base_url: str = ""
|
||||
self._webhook_url: str = ""
|
||||
self._webhook_reachable: asyncio.Event = asyncio.Event()
|
||||
self._lost_subscription: bool = False
|
||||
|
||||
@property
|
||||
@ -138,6 +140,32 @@ class ReolinkHost:
|
||||
|
||||
await self.subscribe()
|
||||
|
||||
_LOGGER.debug(
|
||||
"Waiting for initial ONVIF state on webhook '%s'", self._webhook_url
|
||||
)
|
||||
try:
|
||||
await asyncio.wait_for(self._webhook_reachable.wait(), timeout=15)
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.debug(
|
||||
"Did not receive initial ONVIF state on webhook '%s' after 15 seconds",
|
||||
self._webhook_url,
|
||||
)
|
||||
ir.async_create_issue(
|
||||
self._hass,
|
||||
DOMAIN,
|
||||
"webhook_url",
|
||||
is_fixable=False,
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="webhook_url",
|
||||
translation_placeholders={
|
||||
"name": self._api.nvr_name,
|
||||
"base_url": self._base_url,
|
||||
"network_link": "https://my.home-assistant.io/redirect/network/",
|
||||
},
|
||||
)
|
||||
else:
|
||||
ir.async_delete_issue(self._hass, DOMAIN, "webhook_url")
|
||||
|
||||
if self._api.sw_version_update_required:
|
||||
ir.async_create_issue(
|
||||
self._hass,
|
||||
@ -287,10 +315,10 @@ class ReolinkHost:
|
||||
)
|
||||
|
||||
try:
|
||||
base_url = get_url(self._hass, prefer_external=False)
|
||||
self._base_url = get_url(self._hass, prefer_external=False)
|
||||
except NoURLAvailableError:
|
||||
try:
|
||||
base_url = get_url(self._hass, prefer_external=True)
|
||||
self._base_url = get_url(self._hass, prefer_external=True)
|
||||
except NoURLAvailableError as err:
|
||||
self.unregister_webhook()
|
||||
raise ReolinkWebhookException(
|
||||
@ -299,9 +327,9 @@ class ReolinkHost:
|
||||
) from err
|
||||
|
||||
webhook_path = webhook.async_generate_path(event_id)
|
||||
self._webhook_url = f"{base_url}{webhook_path}"
|
||||
self._webhook_url = f"{self._base_url}{webhook_path}"
|
||||
|
||||
if base_url.startswith("https"):
|
||||
if self._base_url.startswith("https"):
|
||||
ir.async_create_issue(
|
||||
self._hass,
|
||||
DOMAIN,
|
||||
@ -310,7 +338,7 @@ class ReolinkHost:
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="https_webhook",
|
||||
translation_placeholders={
|
||||
"base_url": base_url,
|
||||
"base_url": self._base_url,
|
||||
"network_link": "https://my.home-assistant.io/redirect/network/",
|
||||
},
|
||||
)
|
||||
@ -337,6 +365,8 @@ class ReolinkHost:
|
||||
"""Handle incoming webhook from Reolink for inbound messages and calls."""
|
||||
|
||||
_LOGGER.debug("Webhook '%s' called", webhook_id)
|
||||
if not self._webhook_reachable.is_set():
|
||||
self._webhook_reachable.set()
|
||||
|
||||
if not request.body_exists:
|
||||
_LOGGER.debug("Webhook '%s' triggered without payload", webhook_id)
|
||||
|
@ -41,7 +41,11 @@
|
||||
"issues": {
|
||||
"https_webhook": {
|
||||
"title": "Reolink webhook URL uses HTTPS (SSL)",
|
||||
"description": "Reolink products can not push motion events to an HTTPS address (SSL), please configure a (local) HTTP address under \"Home Assistant URL\" in the [network settings]({network_link}). The current (local) address is: `{base_url}`"
|
||||
"description": "Reolink products can not push motion events to an HTTPS address (SSL), please configure a (local) HTTP address under \"Home Assistant URL\" in the [network settings]({network_link}). The current (local) address is: `{base_url}`, a valid address could, for example, be `http://192.168.1.10:8123` where `192.168.1.10` is the IP of the Home Assistant device"
|
||||
},
|
||||
"webhook_url": {
|
||||
"title": "Reolink webhook URL unreachable",
|
||||
"description": "Did not receive initial ONVIF state from {name}. Most likely, the Reolink camera can not reach the current (local) Home Assistant URL `{base_url}`, please configure a (local) HTTP address under \"Home Assistant URL\" in the [network settings]({network_link}) that points to Home Assistant. For example `http://192.168.1.10:8123` where `192.168.1.10` is the IP of the Home Assistant device. Also, make sure the Reolink camera can reach that URL."
|
||||
},
|
||||
"enable_port": {
|
||||
"title": "Reolink port not enabled",
|
||||
|
@ -39,6 +39,8 @@ def reolink_connect(mock_get_source_ip: None) -> Generator[MagicMock, None, None
|
||||
with patch(
|
||||
"homeassistant.components.reolink.host.webhook.async_register",
|
||||
return_value=True,
|
||||
), patch(
|
||||
"homeassistant.components.reolink.host.asyncio.Event.wait", AsyncMock()
|
||||
), patch(
|
||||
"homeassistant.components.reolink.host.Host", autospec=True
|
||||
) as host_mock_class:
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Test the Reolink init."""
|
||||
import asyncio
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from reolink_aio.exceptions import ReolinkError
|
||||
@ -99,6 +100,7 @@ async def test_no_repair_issue(
|
||||
|
||||
issue_registry = ir.async_get(hass)
|
||||
assert (const.DOMAIN, "https_webhook") not in issue_registry.issues
|
||||
assert (const.DOMAIN, "webhook_url") not in issue_registry.issues
|
||||
assert (const.DOMAIN, "enable_port") not in issue_registry.issues
|
||||
assert (const.DOMAIN, "firmware_update") not in issue_registry.issues
|
||||
|
||||
@ -138,6 +140,21 @@ async def test_port_repair_issue(
|
||||
assert (const.DOMAIN, "enable_port") in issue_registry.issues
|
||||
|
||||
|
||||
async def test_webhook_repair_issue(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Test repairs issue is raised when the webhook url is unreachable."""
|
||||
with patch(
|
||||
"homeassistant.components.reolink.host.asyncio.Event.wait",
|
||||
AsyncMock(side_effect=asyncio.TimeoutError()),
|
||||
):
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
issue_registry = ir.async_get(hass)
|
||||
assert (const.DOMAIN, "webhook_url") in issue_registry.issues
|
||||
|
||||
|
||||
async def test_firmware_repair_issue(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry, reolink_connect: MagicMock
|
||||
) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user