Reject unifi uptime sensor updates if time delta is small (#108464)
* Reject unifi uptime sensor updates if time delta is small * Revise uptime change threshold tuning * Use StateType helper * Treat missing or zero uptime as None (unknown)
This commit is contained in:
parent
80bfd4cef7
commit
a9fe63ed90
1 changed files with 29 additions and 7 deletions
|
@ -7,7 +7,8 @@ from __future__ import annotations
|
|||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from typing import Generic
|
||||
|
||||
from aiounifi.interfaces.api_handlers import ItemEvent
|
||||
|
@ -35,6 +36,7 @@ from homeassistant.const import EntityCategory, UnitOfDataRate, UnitOfPower
|
|||
from homeassistant.core import Event as core_Event, HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .const import DEVICE_STATES
|
||||
|
@ -110,11 +112,22 @@ def async_wlan_client_value_fn(controller: UniFiController, wlan: Wlan) -> int:
|
|||
@callback
|
||||
def async_device_uptime_value_fn(
|
||||
controller: UniFiController, device: Device
|
||||
) -> datetime:
|
||||
"""Calculate the uptime of the device."""
|
||||
return (dt_util.now() - timedelta(seconds=device.uptime)).replace(
|
||||
second=0, microsecond=0
|
||||
)
|
||||
) -> datetime | None:
|
||||
"""Calculate the approximate time the device started (based on uptime returned from API, in seconds)."""
|
||||
if device.uptime <= 0:
|
||||
# Library defaults to 0 if uptime is not provided, e.g. when offline
|
||||
return None
|
||||
return (dt_util.now() - timedelta(seconds=device.uptime)).replace(microsecond=0)
|
||||
|
||||
|
||||
@callback
|
||||
def async_device_uptime_value_changed_fn(
|
||||
old: StateType | date | datetime | Decimal, new: datetime | float | str | None
|
||||
) -> bool:
|
||||
"""Reject the new uptime value if it's too similar to the old one. Avoids unwanted fluctuation."""
|
||||
if isinstance(old, datetime) and isinstance(new, datetime):
|
||||
return new != old and abs((new - old).total_seconds()) > 120
|
||||
return old is None or (new != old)
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -169,6 +182,11 @@ class UnifiSensorEntityDescription(
|
|||
"""Class describing UniFi sensor entity."""
|
||||
|
||||
is_connected_fn: Callable[[UniFiController, str], bool] | None = None
|
||||
# Custom function to determine whether a state change should be recorded
|
||||
value_changed_fn: Callable[
|
||||
[StateType | date | datetime | Decimal, datetime | float | str | None],
|
||||
bool,
|
||||
] = lambda old, new: old != new
|
||||
|
||||
|
||||
ENTITY_DESCRIPTIONS: tuple[UnifiSensorEntityDescription, ...] = (
|
||||
|
@ -349,6 +367,7 @@ ENTITY_DESCRIPTIONS: tuple[UnifiSensorEntityDescription, ...] = (
|
|||
supported_fn=lambda controller, obj_id: True,
|
||||
unique_id_fn=lambda controller, obj_id: f"device_uptime-{obj_id}",
|
||||
value_fn=async_device_uptime_value_fn,
|
||||
value_changed_fn=async_device_uptime_value_changed_fn,
|
||||
),
|
||||
UnifiSensorEntityDescription[Devices, Device](
|
||||
key="Device temperature",
|
||||
|
@ -425,7 +444,10 @@ class UnifiSensorEntity(UnifiEntity[HandlerT, ApiItemT], SensorEntity):
|
|||
"""
|
||||
description = self.entity_description
|
||||
obj = description.object_fn(self.controller.api, self._obj_id)
|
||||
if (value := description.value_fn(self.controller, obj)) != self.native_value:
|
||||
# Update the value only if value is considered to have changed relative to its previous state
|
||||
if description.value_changed_fn(
|
||||
self.native_value, (value := description.value_fn(self.controller, obj))
|
||||
):
|
||||
self._attr_native_value = value
|
||||
|
||||
if description.is_connected_fn is not None:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue