Add sensor for CPU and memory utilization for unifi device (#114986)
Add system stats to unifi device sensors
This commit is contained in:
parent
f9a7e6bb9f
commit
f23e48f373
2 changed files with 86 additions and 3 deletions
|
@ -10,6 +10,7 @@ from collections.abc import Callable
|
|||
from dataclasses import dataclass
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from functools import partial
|
||||
|
||||
from aiounifi.interfaces.api_handlers import ItemEvent
|
||||
from aiounifi.interfaces.clients import Clients
|
||||
|
@ -32,7 +33,7 @@ from homeassistant.components.sensor import (
|
|||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory, UnitOfDataRate, UnitOfPower
|
||||
from homeassistant.const import PERCENTAGE, 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
|
||||
|
@ -140,6 +141,16 @@ def async_device_outlet_supported_fn(hub: UnifiHub, obj_id: str) -> bool:
|
|||
return hub.api.devices[obj_id].outlet_ac_power_budget is not None
|
||||
|
||||
|
||||
def device_system_stats_supported_fn(
|
||||
stat_index: int, hub: UnifiHub, obj_id: str
|
||||
) -> bool:
|
||||
"""Determine if a device supports reading item at index in system stats."""
|
||||
return (
|
||||
"system-stats" in hub.api.devices[obj_id].raw
|
||||
and hub.api.devices[obj_id].system_stats[stat_index] != ""
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_client_is_connected_fn(hub: UnifiHub, obj_id: str) -> bool:
|
||||
"""Check if client was last seen recently."""
|
||||
|
@ -352,6 +363,34 @@ ENTITY_DESCRIPTIONS: tuple[UnifiSensorEntityDescription, ...] = (
|
|||
unique_id_fn=lambda hub, obj_id: f"password-{obj_id}",
|
||||
value_fn=lambda hub, obj: obj.x_passphrase,
|
||||
),
|
||||
UnifiSensorEntityDescription[Devices, Device](
|
||||
key="Device CPU utilization",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
api_handler_fn=lambda api: api.devices,
|
||||
available_fn=async_device_available_fn,
|
||||
device_info_fn=async_device_device_info_fn,
|
||||
name_fn=lambda device: "CPU utilization",
|
||||
object_fn=lambda api, obj_id: api.devices[obj_id],
|
||||
supported_fn=partial(device_system_stats_supported_fn, 0),
|
||||
unique_id_fn=lambda hub, obj_id: f"cpu_utilization-{obj_id}",
|
||||
value_fn=lambda hub, device: device.system_stats[0],
|
||||
),
|
||||
UnifiSensorEntityDescription[Devices, Device](
|
||||
key="Device memory utilization",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
api_handler_fn=lambda api: api.devices,
|
||||
available_fn=async_device_available_fn,
|
||||
device_info_fn=async_device_device_info_fn,
|
||||
name_fn=lambda device: "Memory utilization",
|
||||
object_fn=lambda api, obj_id: api.devices[obj_id],
|
||||
supported_fn=partial(device_system_stats_supported_fn, 1),
|
||||
unique_id_fn=lambda hub, obj_id: f"memory_utilization-{obj_id}",
|
||||
value_fn=lambda hub, device: device.system_stats[1],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -835,8 +835,8 @@ async def test_outlet_power_readings(
|
|||
"""Test the outlet power reporting on PDU devices."""
|
||||
await setup_unifi_integration(hass, aioclient_mock, devices_response=[PDU_DEVICE_1])
|
||||
|
||||
assert len(hass.states.async_all()) == 11
|
||||
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 5
|
||||
assert len(hass.states.async_all()) == 13
|
||||
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 7
|
||||
|
||||
ent_reg_entry = entity_registry.async_get(f"sensor.{entity_id}")
|
||||
assert ent_reg_entry.unique_id == expected_unique_id
|
||||
|
@ -1069,3 +1069,47 @@ async def test_wlan_password(
|
|||
mock_unifi_websocket(message=MessageKey.WLAN_CONF_UPDATED, data=wlan_1)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(sensor_password).state == password
|
||||
|
||||
|
||||
async def test_device_system_stats(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
aioclient_mock: AiohttpClientMocker,
|
||||
mock_unifi_websocket,
|
||||
) -> None:
|
||||
"""Verify that device stats sensors are working as expected."""
|
||||
|
||||
device = {
|
||||
"device_id": "mock-id",
|
||||
"mac": "00:00:00:00:01:01",
|
||||
"model": "US16P150",
|
||||
"name": "Device",
|
||||
"state": 1,
|
||||
"version": "4.0.42.10433",
|
||||
"system-stats": {"cpu": 5.8, "mem": 31.1, "uptime": 7316},
|
||||
}
|
||||
|
||||
await setup_unifi_integration(hass, aioclient_mock, devices_response=[device])
|
||||
|
||||
assert len(hass.states.async_all()) == 8
|
||||
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
|
||||
|
||||
assert hass.states.get("sensor.device_cpu_utilization").state == "5.8"
|
||||
assert hass.states.get("sensor.device_memory_utilization").state == "31.1"
|
||||
|
||||
assert (
|
||||
entity_registry.async_get("sensor.device_cpu_utilization").entity_category
|
||||
is EntityCategory.DIAGNOSTIC
|
||||
)
|
||||
|
||||
assert (
|
||||
entity_registry.async_get("sensor.device_memory_utilization").entity_category
|
||||
is EntityCategory.DIAGNOSTIC
|
||||
)
|
||||
|
||||
# Verify new event change system-stats
|
||||
device["system-stats"] = {"cpu": 7.7, "mem": 33.3, "uptime": 7316}
|
||||
mock_unifi_websocket(message=MessageKey.DEVICE, data=device)
|
||||
|
||||
assert hass.states.get("sensor.device_cpu_utilization").state == "7.7"
|
||||
assert hass.states.get("sensor.device_memory_utilization").state == "33.3"
|
||||
|
|
Loading…
Add table
Reference in a new issue