Poll Reolink motion when ONVIF not available (#92837)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
8711735ec0
commit
051d631504
2 changed files with 47 additions and 2 deletions
|
@ -14,10 +14,11 @@ from reolink_aio.exceptions import ReolinkError, SubscriptionError
|
|||
|
||||
from homeassistant.components import webhook
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import CALLBACK_TYPE, HassJob, HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
from homeassistant.helpers.network import NoURLAvailableError, get_url
|
||||
|
||||
from .const import CONF_PROTOCOL, CONF_USE_HTTPS, DOMAIN
|
||||
|
@ -26,6 +27,7 @@ from .exceptions import ReolinkSetupException, ReolinkWebhookException, UserNotA
|
|||
DEFAULT_TIMEOUT = 60
|
||||
FIRST_ONVIF_TIMEOUT = 15
|
||||
SUBSCRIPTION_RENEW_THRESHOLD = 300
|
||||
POLL_INTERVAL_NO_PUSH = 5
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -59,6 +61,8 @@ class ReolinkHost:
|
|||
self._base_url: str = ""
|
||||
self._webhook_url: str = ""
|
||||
self._webhook_reachable: asyncio.Event = asyncio.Event()
|
||||
self._cancel_poll: CALLBACK_TYPE | None = None
|
||||
self._poll_job = HassJob(self._async_poll_all_motion, cancel_on_shutdown=True)
|
||||
self._lost_subscription: bool = False
|
||||
|
||||
@property
|
||||
|
@ -169,6 +173,7 @@ class ReolinkHost:
|
|||
"network_link": "https://my.home-assistant.io/redirect/network/",
|
||||
},
|
||||
)
|
||||
await self._async_poll_all_motion()
|
||||
else:
|
||||
ir.async_delete_issue(self._hass, DOMAIN, "webhook_url")
|
||||
|
||||
|
@ -228,6 +233,9 @@ class ReolinkHost:
|
|||
|
||||
async def stop(self, event=None):
|
||||
"""Disconnect the API."""
|
||||
if self._cancel_poll is not None:
|
||||
self._cancel_poll()
|
||||
self._cancel_poll = None
|
||||
self.unregister_webhook()
|
||||
await self.disconnect()
|
||||
|
||||
|
@ -359,6 +367,43 @@ class ReolinkHost:
|
|||
webhook.async_unregister(self._hass, self.webhook_id)
|
||||
self.webhook_id = None
|
||||
|
||||
async def _async_poll_all_motion(self, *_) -> None:
|
||||
"""Poll motion and AI states until the first ONVIF push is received."""
|
||||
if self._webhook_reachable.is_set():
|
||||
# ONVIF push is working, stop polling
|
||||
self._cancel_poll = None
|
||||
return
|
||||
|
||||
try:
|
||||
await self._api.get_motion_state_all_ch()
|
||||
except (
|
||||
aiohttp.ClientConnectorError,
|
||||
ReolinkError,
|
||||
) as err:
|
||||
_LOGGER.error(
|
||||
"Reolink error while polling motion state for host %s:%s: %s",
|
||||
self._api.host,
|
||||
self._api.port,
|
||||
str(err),
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
_LOGGER.error(
|
||||
"Reolink timeout error while polling motion state for host %s:%s",
|
||||
self._api.host,
|
||||
self._api.port,
|
||||
)
|
||||
finally:
|
||||
# schedule next poll
|
||||
if not self._hass.is_stopping:
|
||||
self._cancel_poll = async_call_later(
|
||||
self._hass, POLL_INTERVAL_NO_PUSH, self._poll_job
|
||||
)
|
||||
|
||||
# After receiving the new motion states in the upstream lib,
|
||||
# update the binary sensors with async_write_ha_state
|
||||
# The same dispatch as for the webhook can be used
|
||||
async_dispatcher_send(self._hass, f"{self.webhook_id}_all", {})
|
||||
|
||||
async def handle_webhook(
|
||||
self, hass: HomeAssistant, webhook_id: str, request: Request
|
||||
) -> None:
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
},
|
||||
"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."
|
||||
"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. Using fast motion/AI state polling until the first ONVIF push is received."
|
||||
},
|
||||
"enable_port": {
|
||||
"title": "Reolink port not enabled",
|
||||
|
|
Loading…
Add table
Reference in a new issue