mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
System Bridge 2.5.0 - Additional Sensors (#53892)
* Update package to 2.1.0 * Add version sensor * Add graphics memory sensors * Change graphics memory data from MB * Add GPU usage sensor * Add gpu clock speed sensors * GPU sensors * GPU power usage * enumerate instead of range len * Updates from rebase * Add graphics * Add Per CPU load sensor * Cleanup * Use super class attributes * Suggested changes and fix * User, System, Idle sensors * Average, User, System and idle sensors instead of attrs * Remove unused attrs * Remove null/none sensor * Sensor entity descriptions * Fix index out of range error * Set state class * Use entity_registry_enabled_default * Use built in entity_registry_enabled_default * Use built in icon * Fix * Use binary sensor entity description * Fix pylint * Fix uom * Add to coveragerc * is_on * Move entity descriptions to platforms * Clearout default values * Fix docstring Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Cleanup and catch Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
071fcee9a9
commit
25273c694a
@ -85,6 +85,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
coordinator.bridge.battery is None
|
||||
or coordinator.bridge.cpu is None
|
||||
or coordinator.bridge.filesystem is None
|
||||
or coordinator.bridge.graphics is None
|
||||
or coordinator.bridge.information is None
|
||||
or coordinator.bridge.memory is None
|
||||
or coordinator.bridge.network is None
|
||||
@ -230,17 +231,13 @@ class SystemBridgeEntity(CoordinatorEntity):
|
||||
self,
|
||||
coordinator: SystemBridgeDataUpdateCoordinator,
|
||||
key: str,
|
||||
name: str,
|
||||
icon: str | None,
|
||||
enabled_by_default: bool,
|
||||
name: str | None,
|
||||
) -> None:
|
||||
"""Initialize the System Bridge entity."""
|
||||
super().__init__(coordinator)
|
||||
bridge: Bridge = coordinator.data
|
||||
self._key = f"{bridge.information.host}_{key}"
|
||||
self._name = f"{bridge.information.host} {name}"
|
||||
self._icon = icon
|
||||
self._enabled_default = enabled_by_default
|
||||
self._hostname = bridge.information.host
|
||||
self._mac = bridge.information.mac
|
||||
self._manufacturer = bridge.system.system.manufacturer
|
||||
@ -257,16 +254,6 @@ class SystemBridgeEntity(CoordinatorEntity):
|
||||
"""Return the name of the entity."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
"""Return the mdi icon of the entity."""
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self) -> bool:
|
||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||
return self._enabled_default
|
||||
|
||||
|
||||
class SystemBridgeDeviceEntity(SystemBridgeEntity):
|
||||
"""Defines a System Bridge device entity."""
|
||||
|
@ -1,11 +1,15 @@
|
||||
"""Support for System Bridge binary sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
from systembridge import Bridge
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASS_BATTERY_CHARGING,
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -15,6 +19,32 @@ from .const import DOMAIN
|
||||
from .coordinator import SystemBridgeDataUpdateCoordinator
|
||||
|
||||
|
||||
@dataclass
|
||||
class SystemBridgeBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Class describing System Bridge binary sensor entities."""
|
||||
|
||||
value: Callable = round
|
||||
|
||||
|
||||
BASE_BINARY_SENSOR_TYPES: tuple[SystemBridgeBinarySensorEntityDescription, ...] = (
|
||||
SystemBridgeBinarySensorEntityDescription(
|
||||
key="version_available",
|
||||
name="New Version Available",
|
||||
icon="mdi:counter",
|
||||
value=lambda bridge: bridge.information.updates.available,
|
||||
),
|
||||
)
|
||||
|
||||
BATTERY_BINARY_SENSOR_TYPES: tuple[SystemBridgeBinarySensorEntityDescription, ...] = (
|
||||
SystemBridgeBinarySensorEntityDescription(
|
||||
key="battery_is_charging",
|
||||
name="Battery Is Charging",
|
||||
device_class=DEVICE_CLASS_BATTERY_CHARGING,
|
||||
value=lambda bridge: bridge.information.updates.available,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
|
||||
) -> None:
|
||||
@ -22,49 +52,38 @@ async def async_setup_entry(
|
||||
coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
bridge: Bridge = coordinator.data
|
||||
|
||||
entities = []
|
||||
for description in BASE_BINARY_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeBinarySensor(coordinator, description))
|
||||
|
||||
if bridge.battery and bridge.battery.hasBattery:
|
||||
async_add_entities([SystemBridgeBatteryIsChargingBinarySensor(coordinator)])
|
||||
for description in BATTERY_BINARY_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeBinarySensor(coordinator, description))
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SystemBridgeBinarySensor(SystemBridgeDeviceEntity, BinarySensorEntity):
|
||||
"""Defines a System Bridge binary sensor."""
|
||||
"""Define a System Bridge binary sensor."""
|
||||
|
||||
coordinator: SystemBridgeDataUpdateCoordinator
|
||||
entity_description: SystemBridgeBinarySensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: SystemBridgeDataUpdateCoordinator,
|
||||
key: str,
|
||||
name: str,
|
||||
icon: str | None,
|
||||
device_class: str | None,
|
||||
enabled_by_default: bool,
|
||||
description: SystemBridgeBinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize System Bridge binary sensor."""
|
||||
self._device_class = device_class
|
||||
|
||||
super().__init__(coordinator, key, name, icon, enabled_by_default)
|
||||
|
||||
@property
|
||||
def device_class(self) -> str | None:
|
||||
"""Return the class of this binary sensor."""
|
||||
return self._device_class
|
||||
|
||||
|
||||
class SystemBridgeBatteryIsChargingBinarySensor(SystemBridgeBinarySensor):
|
||||
"""Defines a Battery is charging binary sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge binary sensor."""
|
||||
"""Initialize."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"battery_is_charging",
|
||||
"Battery Is Charging",
|
||||
None,
|
||||
DEVICE_CLASS_BATTERY_CHARGING,
|
||||
True,
|
||||
description.key,
|
||||
description.name,
|
||||
)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return if the state is on."""
|
||||
"""Return the boolean state of the binary sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.battery.isCharging
|
||||
return self.entity_description.value(bridge)
|
||||
|
@ -66,6 +66,7 @@ class SystemBridgeDataUpdateCoordinator(DataUpdateCoordinator[Bridge]):
|
||||
"battery",
|
||||
"cpu",
|
||||
"filesystem",
|
||||
"graphics",
|
||||
"memory",
|
||||
"network",
|
||||
"os",
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "System Bridge",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/system_bridge",
|
||||
"requirements": ["systembridge==2.0.6"],
|
||||
"requirements": ["systembridge==2.1.0"],
|
||||
"codeowners": ["@timmo001"],
|
||||
"zeroconf": ["_system-bridge._udp.local."],
|
||||
"after_dependencies": ["zeroconf"],
|
||||
|
@ -1,40 +1,195 @@
|
||||
"""Support for System Bridge sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
from typing import Callable, Final, cast
|
||||
|
||||
from systembridge import Bridge
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.components.sensor import (
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
DATA_GIGABYTES,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ELECTRIC_POTENTIAL_VOLT,
|
||||
FREQUENCY_GIGAHERTZ,
|
||||
FREQUENCY_MEGAHERTZ,
|
||||
PERCENTAGE,
|
||||
POWER_WATT,
|
||||
TEMP_CELSIUS,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import StateType
|
||||
|
||||
from . import SystemBridgeDeviceEntity
|
||||
from .const import DOMAIN
|
||||
from .coordinator import SystemBridgeDataUpdateCoordinator
|
||||
|
||||
ATTR_AVAILABLE = "available"
|
||||
ATTR_FILESYSTEM = "filesystem"
|
||||
ATTR_LOAD_AVERAGE = "load_average"
|
||||
ATTR_LOAD_IDLE = "load_idle"
|
||||
ATTR_LOAD_SYSTEM = "load_system"
|
||||
ATTR_LOAD_USER = "load_user"
|
||||
ATTR_MOUNT = "mount"
|
||||
ATTR_SIZE = "size"
|
||||
ATTR_TYPE = "type"
|
||||
ATTR_USED = "used"
|
||||
ATTR_AVAILABLE: Final = "available"
|
||||
ATTR_FILESYSTEM: Final = "filesystem"
|
||||
ATTR_MOUNT: Final = "mount"
|
||||
ATTR_SIZE: Final = "size"
|
||||
ATTR_TYPE: Final = "type"
|
||||
ATTR_USED: Final = "used"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SystemBridgeSensorEntityDescription(SensorEntityDescription):
|
||||
"""Class describing System Bridge sensor entities."""
|
||||
|
||||
value: Callable = round
|
||||
|
||||
|
||||
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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=FREQUENCY_GIGAHERTZ,
|
||||
icon="mdi:speedometer",
|
||||
value=lambda bridge: bridge.cpu.currentSpeed.avg,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="cpu_temperature",
|
||||
name="CPU Temperature",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
value=lambda bridge: bridge.cpu.temperature.main,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="cpu_voltage",
|
||||
name="CPU Voltage",
|
||||
entity_registry_enabled_default=False,
|
||||
device_class=DEVICE_CLASS_VOLTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
|
||||
value=lambda bridge: bridge.cpu.cpu.voltage,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="kernel",
|
||||
name="Kernel",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
icon="mdi:devices",
|
||||
value=lambda bridge: bridge.os.kernel,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_free",
|
||||
name="Memory Free",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round(bridge.memory.free / 1000 ** 3, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_used_percentage",
|
||||
name="Memory Used %",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round((bridge.memory.used / bridge.memory.total) * 100, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="memory_used",
|
||||
name="Memory Used",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
icon="mdi:memory",
|
||||
value=lambda bridge: round(bridge.memory.used / 1000 ** 3, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="os",
|
||||
name="Operating System",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
icon="mdi:devices",
|
||||
value=lambda bridge: f"{bridge.os.distro} {bridge.os.release}",
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="processes_load",
|
||||
name="Load",
|
||||
state_class=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(bridge.processes.load.currentLoadUser, 2),
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="version",
|
||||
name="Version",
|
||||
icon="mdi:counter",
|
||||
value=lambda bridge: bridge.information.version,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="version_latest",
|
||||
name="Latest Version",
|
||||
icon="mdi:counter",
|
||||
value=lambda bridge: bridge.information.updates.version.new,
|
||||
),
|
||||
)
|
||||
|
||||
BATTERY_SENSOR_TYPES: tuple[SystemBridgeSensorEntityDescription, ...] = (
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="battery",
|
||||
name="Battery",
|
||||
device_class=DEVICE_CLASS_BATTERY,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
value=lambda bridge: bridge.battery.percent,
|
||||
),
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key="battery_time_remaining",
|
||||
name="Battery Time Remaining",
|
||||
device_class=DEVICE_CLASS_TIMESTAMP,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
value=lambda bridge: str(
|
||||
datetime.now() + timedelta(minutes=bridge.battery.timeRemaining)
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -43,395 +198,260 @@ async def async_setup_entry(
|
||||
"""Set up System Bridge sensor based on a config entry."""
|
||||
coordinator: SystemBridgeDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
entities = [
|
||||
SystemBridgeCpuSpeedSensor(coordinator),
|
||||
SystemBridgeCpuTemperatureSensor(coordinator),
|
||||
SystemBridgeCpuVoltageSensor(coordinator),
|
||||
*(
|
||||
SystemBridgeFilesystemSensor(coordinator, key)
|
||||
for key, _ in coordinator.data.filesystem.fsSize.items()
|
||||
),
|
||||
SystemBridgeMemoryFreeSensor(coordinator),
|
||||
SystemBridgeMemoryUsedSensor(coordinator),
|
||||
SystemBridgeMemoryUsedPercentageSensor(coordinator),
|
||||
SystemBridgeKernelSensor(coordinator),
|
||||
SystemBridgeOsSensor(coordinator),
|
||||
SystemBridgeProcessesLoadSensor(coordinator),
|
||||
SystemBridgeBiosVersionSensor(coordinator),
|
||||
]
|
||||
entities = []
|
||||
for description in BASE_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeSensor(coordinator, description))
|
||||
|
||||
for key, _ in coordinator.data.filesystem.fsSize.items():
|
||||
uid = key.replace(":", "")
|
||||
entities.append(
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"filesystem_{uid}",
|
||||
name=f"{key} Space Used",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:harddisk",
|
||||
value=lambda bridge, i=key: round(
|
||||
bridge.filesystem.fsSize[i]["use"], 2
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if coordinator.data.battery.hasBattery:
|
||||
entities.append(SystemBridgeBatterySensor(coordinator))
|
||||
entities.append(SystemBridgeBatteryTimeRemainingSensor(coordinator))
|
||||
for description in BATTERY_SENSOR_TYPES:
|
||||
entities.append(SystemBridgeSensor(coordinator, description))
|
||||
|
||||
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=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_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=STATE_CLASS_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=DEVICE_CLASS_POWER,
|
||||
state_class=STATE_CLASS_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=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge, i=index: bridge.graphics.controllers[
|
||||
i
|
||||
].utilizationGpu,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
for index, _ in enumerate(coordinator.data.processes.load.cpus):
|
||||
entities = [
|
||||
*entities,
|
||||
SystemBridgeSensor(
|
||||
coordinator,
|
||||
SystemBridgeSensorEntityDescription(
|
||||
key=f"processes_load_cpu_{index}",
|
||||
name=f"Load CPU {index}",
|
||||
entity_registry_enabled_default=False,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: 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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: 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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: 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=STATE_CLASS_MEASUREMENT,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:percent",
|
||||
value=lambda bridge: round(
|
||||
bridge.processes.load.cpus[index].loadUser, 2
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SystemBridgeSensor(SystemBridgeDeviceEntity, SensorEntity):
|
||||
"""Defines a System Bridge sensor."""
|
||||
"""Define a System Bridge sensor."""
|
||||
|
||||
coordinator: SystemBridgeDataUpdateCoordinator
|
||||
entity_description: SystemBridgeSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: SystemBridgeDataUpdateCoordinator,
|
||||
key: str,
|
||||
name: str,
|
||||
icon: str | None,
|
||||
device_class: str | None,
|
||||
unit_of_measurement: str | None,
|
||||
enabled_by_default: bool,
|
||||
description: SystemBridgeSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
self._device_class = device_class
|
||||
self._unit_of_measurement = unit_of_measurement
|
||||
|
||||
super().__init__(coordinator, key, name, icon, enabled_by_default)
|
||||
|
||||
@property
|
||||
def device_class(self) -> str | None:
|
||||
"""Return the class of this sensor."""
|
||||
return self._device_class
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit this state is expressed in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
||||
class SystemBridgeBatterySensor(SystemBridgeSensor):
|
||||
"""Defines a Battery sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
"""Initialize."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"battery",
|
||||
"Battery",
|
||||
None,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
PERCENTAGE,
|
||||
True,
|
||||
description.key,
|
||||
description.name,
|
||||
)
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.battery.percent
|
||||
|
||||
|
||||
class SystemBridgeBatteryTimeRemainingSensor(SystemBridgeSensor):
|
||||
"""Defines the Battery Time Remaining sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"battery_time_remaining",
|
||||
"Battery Time Remaining",
|
||||
None,
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
None,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
if bridge.battery.timeRemaining is None:
|
||||
try:
|
||||
return cast(StateType, self.entity_description.value(bridge))
|
||||
except TypeError:
|
||||
return None
|
||||
return str(datetime.now() + timedelta(minutes=bridge.battery.timeRemaining))
|
||||
|
||||
|
||||
class SystemBridgeCpuSpeedSensor(SystemBridgeSensor):
|
||||
"""Defines a CPU speed sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"cpu_speed",
|
||||
"CPU Speed",
|
||||
"mdi:speedometer",
|
||||
None,
|
||||
FREQUENCY_GIGAHERTZ,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.cpu.currentSpeed.avg
|
||||
|
||||
|
||||
class SystemBridgeCpuTemperatureSensor(SystemBridgeSensor):
|
||||
"""Defines a CPU temperature sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"cpu_temperature",
|
||||
"CPU Temperature",
|
||||
None,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
TEMP_CELSIUS,
|
||||
False,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.cpu.temperature.main
|
||||
|
||||
|
||||
class SystemBridgeCpuVoltageSensor(SystemBridgeSensor):
|
||||
"""Defines a CPU voltage sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"cpu_voltage",
|
||||
"CPU Voltage",
|
||||
None,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ELECTRIC_POTENTIAL_VOLT,
|
||||
False,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.cpu.cpu.voltage
|
||||
|
||||
|
||||
class SystemBridgeFilesystemSensor(SystemBridgeSensor):
|
||||
"""Defines a filesystem sensor."""
|
||||
|
||||
def __init__(
|
||||
self, coordinator: SystemBridgeDataUpdateCoordinator, key: str
|
||||
) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
uid_key = key.replace(":", "")
|
||||
super().__init__(
|
||||
coordinator,
|
||||
f"filesystem_{uid_key}",
|
||||
f"{key} Space Used",
|
||||
"mdi:harddisk",
|
||||
None,
|
||||
PERCENTAGE,
|
||||
True,
|
||||
)
|
||||
self._fs_key = key
|
||||
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return (
|
||||
round(bridge.filesystem.fsSize[self._fs_key]["use"], 2)
|
||||
if bridge.filesystem.fsSize[self._fs_key]["use"] is not None
|
||||
else None
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes of the entity."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return {
|
||||
ATTR_AVAILABLE: bridge.filesystem.fsSize[self._fs_key]["available"],
|
||||
ATTR_FILESYSTEM: bridge.filesystem.fsSize[self._fs_key]["fs"],
|
||||
ATTR_MOUNT: bridge.filesystem.fsSize[self._fs_key]["mount"],
|
||||
ATTR_SIZE: bridge.filesystem.fsSize[self._fs_key]["size"],
|
||||
ATTR_TYPE: bridge.filesystem.fsSize[self._fs_key]["type"],
|
||||
ATTR_USED: bridge.filesystem.fsSize[self._fs_key]["used"],
|
||||
}
|
||||
|
||||
|
||||
class SystemBridgeMemoryFreeSensor(SystemBridgeSensor):
|
||||
"""Defines a memory free sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"memory_free",
|
||||
"Memory Free",
|
||||
"mdi:memory",
|
||||
None,
|
||||
DATA_GIGABYTES,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return (
|
||||
round(bridge.memory.free / 1000 ** 3, 2)
|
||||
if bridge.memory.free is not None
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
class SystemBridgeMemoryUsedSensor(SystemBridgeSensor):
|
||||
"""Defines a memory used sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"memory_used",
|
||||
"Memory Used",
|
||||
"mdi:memory",
|
||||
None,
|
||||
DATA_GIGABYTES,
|
||||
False,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return (
|
||||
round(bridge.memory.used / 1000 ** 3, 2)
|
||||
if bridge.memory.used is not None
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
class SystemBridgeMemoryUsedPercentageSensor(SystemBridgeSensor):
|
||||
"""Defines a memory used percentage sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"memory_used_percentage",
|
||||
"Memory Used %",
|
||||
"mdi:memory",
|
||||
None,
|
||||
PERCENTAGE,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return (
|
||||
round((bridge.memory.used / bridge.memory.total) * 100, 2)
|
||||
if bridge.memory.used is not None and bridge.memory.total is not None
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
class SystemBridgeKernelSensor(SystemBridgeSensor):
|
||||
"""Defines a kernel sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"kernel",
|
||||
"Kernel",
|
||||
"mdi:devices",
|
||||
None,
|
||||
None,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.os.kernel
|
||||
|
||||
|
||||
class SystemBridgeOsSensor(SystemBridgeSensor):
|
||||
"""Defines an OS sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"os",
|
||||
"Operating System",
|
||||
"mdi:devices",
|
||||
None,
|
||||
None,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return f"{bridge.os.distro} {bridge.os.release}"
|
||||
|
||||
|
||||
class SystemBridgeProcessesLoadSensor(SystemBridgeSensor):
|
||||
"""Defines a Processes Load sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"processes_load",
|
||||
"Load",
|
||||
"mdi:percent",
|
||||
None,
|
||||
PERCENTAGE,
|
||||
True,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return (
|
||||
round(bridge.processes.load.currentLoad, 2)
|
||||
if bridge.processes.load.currentLoad is not None
|
||||
else None
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes of the entity."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
attrs = {}
|
||||
if bridge.processes.load.avgLoad is not None:
|
||||
attrs[ATTR_LOAD_AVERAGE] = round(bridge.processes.load.avgLoad, 2)
|
||||
if bridge.processes.load.currentLoadUser is not None:
|
||||
attrs[ATTR_LOAD_USER] = round(bridge.processes.load.currentLoadUser, 2)
|
||||
if bridge.processes.load.currentLoadSystem is not None:
|
||||
attrs[ATTR_LOAD_SYSTEM] = round(bridge.processes.load.currentLoadSystem, 2)
|
||||
if bridge.processes.load.currentLoadIdle is not None:
|
||||
attrs[ATTR_LOAD_IDLE] = round(bridge.processes.load.currentLoadIdle, 2)
|
||||
return attrs
|
||||
|
||||
|
||||
class SystemBridgeBiosVersionSensor(SystemBridgeSensor):
|
||||
"""Defines a bios version sensor."""
|
||||
|
||||
def __init__(self, coordinator: SystemBridgeDataUpdateCoordinator) -> None:
|
||||
"""Initialize System Bridge sensor."""
|
||||
super().__init__(
|
||||
coordinator,
|
||||
"bios_version",
|
||||
"BIOS Version",
|
||||
"mdi:chip",
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> str:
|
||||
"""Return the state of the sensor."""
|
||||
bridge: Bridge = self.coordinator.data
|
||||
return bridge.system.bios.version
|
||||
|
@ -2251,7 +2251,7 @@ swisshydrodata==0.1.0
|
||||
synology-srm==0.2.0
|
||||
|
||||
# homeassistant.components.system_bridge
|
||||
systembridge==2.0.6
|
||||
systembridge==2.1.0
|
||||
|
||||
# homeassistant.components.tahoma
|
||||
tahoma-api==0.0.16
|
||||
|
@ -1264,7 +1264,7 @@ sunwatcher==0.2.1
|
||||
surepy==0.7.0
|
||||
|
||||
# homeassistant.components.system_bridge
|
||||
systembridge==2.0.6
|
||||
systembridge==2.1.0
|
||||
|
||||
# homeassistant.components.tellduslive
|
||||
tellduslive==0.10.11
|
||||
|
Loading…
x
Reference in New Issue
Block a user