Conserve Reolink battery by not waking the camera on each update (#118773)

* update to new cmd_list type

* Wake battery cams each 1 hour

* fix styling

* fix epoch

* fix timezone

* force full update when using generic update service

* improve comment

* Use time.time() instead of datetime

* fix import order
This commit is contained in:
starkillerOG 2024-06-05 03:54:31 +02:00 committed by GitHub
parent 8723441227
commit 678c06beb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 1 deletions

View File

@ -101,6 +101,11 @@ class ReolinkHostCoordinatorEntity(ReolinkBaseCoordinatorEntity[None]):
await super().async_will_remove_from_hass() await super().async_will_remove_from_hass()
async def async_update(self) -> None:
"""Force full update from the generic entity update service."""
self._host.last_wake = 0
await super().async_update()
class ReolinkChannelCoordinatorEntity(ReolinkHostCoordinatorEntity): class ReolinkChannelCoordinatorEntity(ReolinkHostCoordinatorEntity):
"""Parent class for Reolink hardware camera entities connected to a channel of the NVR.""" """Parent class for Reolink hardware camera entities connected to a channel of the NVR."""

View File

@ -6,6 +6,7 @@ import asyncio
from collections import defaultdict from collections import defaultdict
from collections.abc import Mapping from collections.abc import Mapping
import logging import logging
from time import time
from typing import Any, Literal from typing import Any, Literal
import aiohttp import aiohttp
@ -40,6 +41,10 @@ POLL_INTERVAL_NO_PUSH = 5
LONG_POLL_COOLDOWN = 0.75 LONG_POLL_COOLDOWN = 0.75
LONG_POLL_ERROR_COOLDOWN = 30 LONG_POLL_ERROR_COOLDOWN = 30
# Conserve battery by not waking the battery cameras each minute during normal update
# Most props are cached in the Home Hub and updated, but some are skipped
BATTERY_WAKE_UPDATE_INTERVAL = 3600 # seconds
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -68,6 +73,7 @@ class ReolinkHost:
timeout=DEFAULT_TIMEOUT, timeout=DEFAULT_TIMEOUT,
) )
self.last_wake: float = 0
self._update_cmd: defaultdict[str, defaultdict[int | None, int]] = defaultdict( self._update_cmd: defaultdict[str, defaultdict[int | None, int]] = defaultdict(
lambda: defaultdict(int) lambda: defaultdict(int)
) )
@ -337,7 +343,13 @@ class ReolinkHost:
async def update_states(self) -> None: async def update_states(self) -> None:
"""Call the API of the camera device to update the internal states.""" """Call the API of the camera device to update the internal states."""
await self._api.get_states(cmd_list=self._update_cmd) wake = False
if time() - self.last_wake > BATTERY_WAKE_UPDATE_INTERVAL:
# wake the battery cameras for a complete update
wake = True
self.last_wake = time()
await self._api.get_states(cmd_list=self._update_cmd, wake=wake)
async def disconnect(self) -> None: async def disconnect(self) -> None:
"""Disconnect from the API, so the connection will be released.""" """Disconnect from the API, so the connection will be released."""