System Bridge 3.x.x (#71218)
* Change to new package and tcp * Rework integration pt1 * Show by default * Handle auth error * Use const * New version avaliable (to be replaced in future by update entity) * Remove visible * Version latest * Filesystem space use * Dev package * Fix sensor * Add services * Update package * Add temperature and voltage * GPU * Bump package version * Update config flow * Add displays * Fix displays connected * Round to whole number * GPU fan speed in RPM * Handle disconnections * Update package * Fix * Update tests * Handle more errors * Check submodule and return missing uuid in test * Handle auth error on config flow * Fix test * Bump package version * Handle key errors * Update package to release version * Client session in config flow * Log * Increase timeout and use similar logic in config flow to init * 30 secs * Add test for timeout error * Cleanup logs Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update tests/components/system_bridge/test_config_flow.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * uuid raise specific error * Type * Lambda to functions for complex logic * Unknown error test * Bump package to 3.0.5 * Bump package to 3.0.6 * Use typings from package and pydantic * Use dict() * Use data listener function and map to models * Use passed module handler * Use lists from models * Update to 3.1.0 * Update coordinator to use passed module * Improve coordinator * Add debug * Bump package and avaliable -> available * Add version check Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
05296fb86e
commit
2ba45a9f99
12 changed files with 892 additions and 731 deletions
|
@ -6,8 +6,6 @@ from dataclasses import dataclass
|
|||
from datetime import datetime, timedelta
|
||||
from typing import Final, cast
|
||||
|
||||
from systembridge import Bridge
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
|
@ -16,6 +14,7 @@ from homeassistant.components.sensor import (
|
|||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_PORT,
|
||||
DATA_GIGABYTES,
|
||||
ELECTRIC_POTENTIAL_VOLT,
|
||||
FREQUENCY_GIGAHERTZ,
|
||||
|
@ -28,10 +27,11 @@ from homeassistant.const import (
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from . import SystemBridgeDeviceEntity
|
||||
from .const import DOMAIN
|
||||
from .coordinator import SystemBridgeDataUpdateCoordinator
|
||||
from .coordinator import SystemBridgeCoordinatorData, SystemBridgeDataUpdateCoordinator
|
||||
|
||||
ATTR_AVAILABLE: Final = "available"
|
||||
ATTR_FILESYSTEM: Final = "filesystem"
|
||||
|
@ -41,6 +41,7 @@ ATTR_TYPE: Final = "type"
|
|||
ATTR_USED: Final = "used"
|
||||
|
||||
PIXELS: Final = "px"
|
||||
RPM: Final = "RPM"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -50,21 +51,87 @@ class SystemBridgeSensorEntityDescription(SensorEntityDescription):
|
|||
value: Callable = round
|
||||
|
||||
|
||||
def battery_time_remaining(data: SystemBridgeCoordinatorData) -> datetime | None:
|
||||
"""Return the battery time remaining."""
|
||||
if data.battery.sensors_secsleft is not None:
|
||||
return utcnow() + timedelta(seconds=data.battery.sensors_secsleft)
|
||||
return None
|
||||
|
||||
|
||||
def cpu_speed(data: SystemBridgeCoordinatorData) -> float | None:
|
||||
"""Return the CPU speed."""
|
||||
if data.cpu.frequency_current is not None:
|
||||
return round(data.cpu.frequency_current / 1000, 2)
|
||||
return None
|
||||
|
||||
|
||||
def gpu_core_clock_speed(data: SystemBridgeCoordinatorData, key: str) -> float | None:
|
||||
"""Return the GPU core clock speed."""
|
||||
if getattr(data.gpu, f"{key}_core_clock") is not None:
|
||||
return round(getattr(data.gpu, f"{key}_core_clock"))
|
||||
return None
|
||||
|
||||
|
||||
def gpu_memory_clock_speed(data: SystemBridgeCoordinatorData, key: str) -> float | None:
|
||||
"""Return the GPU memory clock speed."""
|
||||
if getattr(data.gpu, f"{key}_memory_clock") is not None:
|
||||
return round(getattr(data.gpu, f"{key}_memory_clock"))
|
||||
return None
|
||||
|
||||
|
||||
def gpu_memory_free(data: SystemBridgeCoordinatorData, key: str) -> float | None:
|
||||
"""Return the free GPU memory."""
|
||||
if getattr(data.gpu, f"{key}_memory_free") is not None:
|
||||
return round(getattr(data.gpu, f"{key}_memory_free") / 10**3, 2)
|
||||
return None
|
||||
|
||||
|
||||
def gpu_memory_used(data: SystemBridgeCoordinatorData, key: str) -> float | None:
|
||||
"""Return the used GPU memory."""
|
||||
if getattr(data.gpu, f"{key}_memory_used") is not None:
|
||||
return round(getattr(data.gpu, f"{key}_memory_used") / 10**3, 2)
|
||||
return None
|
||||
|
||||
|
||||
def gpu_memory_used_percentage(
|
||||
data: SystemBridgeCoordinatorData, key: str
|
||||
) -> float | None:
|
||||
"""Return the used GPU memory percentage."""
|
||||
if (
|
||||
getattr(data.gpu, f"{key}_memory_used") is not None
|
||||
and getattr(data.gpu, f"{key}_memory_total") is not None
|
||||
):
|
||||
return round(
|
||||
getattr(data.gpu, f"{key}_memory_used")
|
||||
/ getattr(data.gpu, f"{key}_memory_total")
|
||||
* 100,
|
||||
2,
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def memory_free(data: SystemBridgeCoordinatorData) -> float | None:
|
||||
"""Return the free memory."""
|
||||
if data.memory.virtual_free is not None:
|
||||
return round(data.memory.virtual_free / 1000**3, 2)
|
||||
return None
|
||||
|
||||
|
||||
def memory_used(data: SystemBridgeCoordinatorData) -> float | None:
|
||||
"""Return the used memory."""
|
||||
if data.memory.virtual_used is not None:
|
||||
return round(data.memory.virtual_used / 1000**3, 2)
|
||||
return None
|
||||
|
||||
|
||||
BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="bios_version",
|
||||
name="BIOS Version",
|
||||
entity_registry_enabled_default=False,
|
||||
icon="mdi:chip",
|
||||
value=lambda bridge: bridge.system.bios.version,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="cpu_speed",
|
||||
name="CPU Speed",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_GIGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda bridge: bridge.cpu.currentSpeed.avg,
|
||||
value=cpu_speed,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="cpu_temperature",
|
||||
|
@ -73,7 +140,7 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
value=lambda bridge: bridge.cpu.temperature.main,
|
||||
value=lambda data: data.cpu.temperature,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="cpu_voltage",
|
||||
|
@ -82,21 +149,14 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
device_class=SensorDeviceClass.VOLTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
|
||||
value=lambda bridge: bridge.cpu.cpu.voltage,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="displays_connected",
|
||||
name="Displays Connected",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
icon="mdi:monitor",
|
||||
value=lambda bridge: len(bridge.display.displays),
|
||||
value=lambda data: data.cpu.voltage,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="kernel",
|
||||
name="Kernel",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
icon="mdi:devices",
|
||||
value=lambda bridge: bridge.os.kernel,
|
||||
value=lambda data: data.system.platform,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_free",
|
||||
|
@ -104,7 +164,7 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round(bridge.memory.free / 1000**3, 2),
|
||||
value=memory_free,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_used_percentage",
|
||||
|
@ -112,7 +172,7 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round((bridge.memory.used / bridge.memory.total) * 100, 2),
|
||||
value=lambda data: data.memory.virtual_percent,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_used",
|
||||
|
@ -121,14 +181,14 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round(bridge.memory.used / 1000**3, 2),
|
||||
value=memory_used,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="os",
|
||||
name="Operating System",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
icon="mdi:devices",
|
||||
value=lambda bridge: f"{bridge.os.distro} {bridge.os.release}",
|
||||
value=lambda data: f"{data.system.platform} {data.system.platform_version}",
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="processes_load",
|
||||
|
@ -136,46 +196,19 @@ BASE_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(bridge.processes.load.currentLoad, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="processes_load_idle",
|
||||
name="Idle Load",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(bridge.processes.load.currentLoadIdle, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="processes_load_system",
|
||||
name="System Load",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(bridge.processes.load.currentLoadSystem, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="processes_load_user",
|
||||
name="User Load",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(bridge.processes.load.currentLoadUser, 2),
|
||||
value=lambda data: data.cpu.usage,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="version",
|
||||
name="Version",
|
||||
icon="mdi:counter",
|
||||
value=lambda bridge: bridge.information.version,
|
||||
value=lambda data: data.system.version,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="version_latest",
|
||||
name="Latest Version",
|
||||
icon="mdi:counter",
|
||||
value=lambda bridge: bridge.information.updates.version.new,
|
||||
value=lambda data: data.system.version_latest,
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -186,238 +219,270 @@ BATTERY_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
|||
device_class=SensorDeviceClass.BATTERY,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value=lambda bridge: bridge.battery.percent,
|
||||
value=lambda data: data.battery.percentage,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="battery_time_remaining",
|
||||
name="Battery Time Remaining",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
value=lambda bridge: str(
|
||||
datetime.now() + timedelta(minutes=bridge.battery.timeRemaining)
|
||||
),
|
||||
value=battery_time_remaining,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up System Bridge sensor based on a config entry."""
|
||||
coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for description in BASE_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeSensor(coordinator, description))
|
||||
entities.append(
|
||||
SystemBridgeSensor(coordinator, description, entry.data[CONF_PORT])
|
||||
)
|
||||
|
||||
for key, _ in coordinator.data.filesystem.fsSize.items():
|
||||
uid = key.replace(":", "")
|
||||
for partition in coordinator.data.disk.partitions:
|
||||
entities.append(
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"filesystem_{uid}",
|
||||
name=f"{key} Space Used",
|
||||
key=f"filesystem_{partition.replace(':', '')}",
|
||||
name=f"{partition} Space Used",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:harddisk",
|
||||
value=lambda bridge, i=key: round(
|
||||
bridge.filesystem.fsSize[i]["use"], 2
|
||||
value=lambda data, p=partition: getattr(
|
||||
data.disk, f"usage_{p}_percent"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
)
|
||||
)
|
||||
|
||||
if coordinator.data.battery.hasBattery:
|
||||
if (
|
||||
coordinator.data.battery
|
||||
and coordinator.data.battery.percentage
|
||||
and coordinator.data.battery.percentage > -1
|
||||
):
|
||||
for description in BATTERY_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeSensor(coordinator, description))
|
||||
entities.append(
|
||||
SystemBridgeSensor(coordinator, description, entry.data[CONF_PORT])
|
||||
)
|
||||
|
||||
for index, _ in enumerate(coordinator.data.display.displays):
|
||||
name = index + 1
|
||||
displays = []
|
||||
for display in coordinator.data.display.displays:
|
||||
displays.append(
|
||||
{
|
||||
"key": display,
|
||||
"name": getattr(coordinator.data.display, f"{display}_name").replace(
|
||||
"Display ", ""
|
||||
),
|
||||
},
|
||||
)
|
||||
display_count = len(displays)
|
||||
|
||||
entities.append(
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="displays_connected",
|
||||
name="Displays Connected",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
icon="mdi:monitor",
|
||||
value=lambda _, count=display_count: count,
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
)
|
||||
)
|
||||
|
||||
for _, display in enumerate(displays):
|
||||
entities = [
|
||||
*entities,
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"display_{name}_resolution_x",
|
||||
name=f"Display {name} Resolution X",
|
||||
key=f"display_{display['name']}_resolution_x",
|
||||
name=f"Display {display['name']} Resolution X",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PIXELS,
|
||||
icon="mdi:monitor",
|
||||
value=lambda bridge, i=index: bridge.display.displays[
|
||||
i
|
||||
].resolutionX,
|
||||
value=lambda data, k=display["key"]: getattr(
|
||||
data.display, f"{k}_resolution_horizontal"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"display_{name}_resolution_y",
|
||||
name=f"Display {name} Resolution Y",
|
||||
key=f"display_{display['name']}_resolution_y",
|
||||
name=f"Display {display['name']} Resolution Y",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PIXELS,
|
||||
icon="mdi:monitor",
|
||||
value=lambda bridge, i=index: bridge.display.displays[
|
||||
i
|
||||
].resolutionY,
|
||||
value=lambda data, k=display["key"]: getattr(
|
||||
data.display, f"{k}_resolution_vertical"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"display_{name}_refresh_rate",
|
||||
name=f"Display {name} Refresh Rate",
|
||||
key=f"display_{display['name']}_refresh_rate",
|
||||
name=f"Display {display['name']} Refresh Rate",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_HERTZ,
|
||||
icon="mdi:monitor",
|
||||
value=lambda bridge, i=index: bridge.display.displays[
|
||||
i
|
||||
].currentRefreshRate,
|
||||
value=lambda data, k=display["key"]: getattr(
|
||||
data.display, f"{k}_refresh_rate"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
]
|
||||
|
||||
for index, _ in enumerate(coordinator.data.graphics.controllers):
|
||||
if coordinator.data.graphics.controllers[index].name is not None:
|
||||
# Remove vendor from name
|
||||
name = (
|
||||
coordinator.data.graphics.controllers[index]
|
||||
.name.replace(coordinator.data.graphics.controllers[index].vendor, "")
|
||||
.strip()
|
||||
)
|
||||
entities = [
|
||||
*entities,
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_core_clock_speed",
|
||||
name=f"{name} Clock Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_MEGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].clockCore,
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_clock_speed",
|
||||
name=f"{name} Memory Clock Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_MEGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].clockMemory,
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_free",
|
||||
name=f"{name} Memory Free",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge, i=index: round(
|
||||
bridge.graphics.controllers[i].memoryFree / 10**3, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_used_percentage",
|
||||
name=f"{name} Memory Used %",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge, i=index: round(
|
||||
(
|
||||
bridge.graphics.controllers[i].memoryUsed
|
||||
/ bridge.graphics.controllers[i].memoryTotal
|
||||
)
|
||||
* 100,
|
||||
2,
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_used",
|
||||
name=f"{name} Memory Used",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge, i=index: round(
|
||||
bridge.graphics.controllers[i].memoryUsed / 10**3, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_fan_speed",
|
||||
name=f"{name} Fan Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:fan",
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].fanSpeed,
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_power_usage",
|
||||
name=f"{name} Power Usage",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=POWER_WATT,
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].powerDraw,
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_temperature",
|
||||
name=f"{name} Temperature",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].temperatureGpu,
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_usage_percentage",
|
||||
name=f"{name} Usage %",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].utilizationGpu,
|
||||
),
|
||||
),
|
||||
]
|
||||
gpus = []
|
||||
for gpu in coordinator.data.gpu.gpus:
|
||||
gpus.append(
|
||||
{
|
||||
"key": gpu,
|
||||
"name": getattr(coordinator.data.gpu, f"{gpu}_name"),
|
||||
},
|
||||
)
|
||||
|
||||
for index, _ in enumerate(coordinator.data.processes.load.cpus):
|
||||
for index, gpu in enumerate(gpus):
|
||||
entities = [
|
||||
*entities,
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_core_clock_speed",
|
||||
name=f"{gpu['name']} Clock Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_MEGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda data, k=gpu["key"]: gpu_core_clock_speed(data, k),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_clock_speed",
|
||||
name=f"{gpu['name']} Memory Clock Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_MEGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda data, k=gpu["key"]: gpu_memory_clock_speed(data, k),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_free",
|
||||
name=f"{gpu['name']} Memory Free",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda data, k=gpu["key"]: gpu_memory_free(data, k),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_used_percentage",
|
||||
name=f"{gpu['name']} Memory Used %",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:memory",
|
||||
value=lambda data, k=gpu["key"]: gpu_memory_used_percentage(
|
||||
data, k
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_memory_used",
|
||||
name=f"{gpu['name']} Memory Used",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda data, k=gpu["key"]: gpu_memory_used(data, k),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_fan_speed",
|
||||
name=f"{gpu['name']} Fan Speed",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=RPM,
|
||||
icon="mdi:fan",
|
||||
value=lambda data, k=gpu["key"]: getattr(
|
||||
data.gpu, f"{k}_fan_speed"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_power_usage",
|
||||
name=f"{gpu['name']} Power Usage",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=POWER_WATT,
|
||||
value=lambda data, k=gpu["key"]: getattr(data.gpu, f"{k}_power"),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_temperature",
|
||||
name=f"{gpu['name']} Temperature",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
value=lambda data, k=gpu["key"]: getattr(
|
||||
data.gpu, f"{k}_temperature"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"gpu_{index}_usage_percentage",
|
||||
name=f"{gpu['name']} Usage %",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda data, k=gpu["key"]: getattr(
|
||||
data.gpu, f"{k}_core_load"
|
||||
),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
]
|
||||
|
||||
for index in range(coordinator.data.cpu.count):
|
||||
entities = [
|
||||
*entities,
|
||||
SystemBridgeSensor(
|
||||
|
@ -429,52 +494,9 @@ async def async_setup_entry(
|
|||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, index=index: round(
|
||||
bridge.processes.load.cpus[index].load, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"processes_load_cpu_{index}_idle",
|
||||
name=f"Idle Load CPU {index}",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, index=index: round(
|
||||
bridge.processes.load.cpus[index].loadIdle, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"processes_load_cpu_{index}_system",
|
||||
name=f"System Load CPU {index}",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, index=index: round(
|
||||
bridge.processes.load.cpus[index].loadSystem, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"processes_load_cpu_{index}_user",
|
||||
name=f"User Load CPU {index}",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, index=index: round(
|
||||
bridge.processes.load.cpus[index].loadUser, 2
|
||||
),
|
||||
value=lambda data, k=index: getattr(data.cpu, f"usage_{k}"),
|
||||
),
|
||||
entry.data[CONF_PORT],
|
||||
),
|
||||
]
|
||||
|
||||
|
@ -490,10 +512,12 @@ class SystemBridgeSensor(SystemBridgeDeviceEntity, SensorEntity):
|
|||
self,
|
||||
coordinator: SystemBridgeDataUpdateCoordinator,
|
||||
description: SystemBridgeSensorEntityDescription,
|
||||
api_port: int,
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
api_port,
|
||||
description.key,
|
||||
description.name,
|
||||
)
|
||||
|
@ -502,8 +526,7 @@ class SystemBridgeSensor(SystemBridgeDeviceEntity, SensorEntity):
|
|||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
try:
|
||||
return cast(StateType, self.entity_description.value(bridge))
|
||||
return cast(StateType, self.entity_description.value(self.coordinator.data))
|
||||
except TypeError:
|
||||
return None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue