forked from platypush/platypush
Added support for fan sensors on the system
plugin.
This commit is contained in:
parent
45d5f439be
commit
b3440ab96b
11 changed files with 127 additions and 50 deletions
|
@ -0,0 +1 @@
|
|||
NumericSensor.vue
|
|
@ -87,6 +87,14 @@
|
|||
}
|
||||
},
|
||||
|
||||
"system_fan": {
|
||||
"name": "System",
|
||||
"name_plural": "System",
|
||||
"icon": {
|
||||
"class": "fas fa-fan"
|
||||
}
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
"name": "System",
|
||||
"name_plural": "System",
|
||||
|
|
|
@ -4,6 +4,7 @@ from platypush.common.db import Base
|
|||
|
||||
from . import Entity
|
||||
from .devices import Device
|
||||
from .sensors import NumericSensor
|
||||
from .temperature import TemperatureSensor
|
||||
|
||||
|
||||
|
@ -232,3 +233,23 @@ if 'system_temperature' not in Base.metadata:
|
|||
__mapper_args__ = {
|
||||
'polymorphic_identity': __tablename__,
|
||||
}
|
||||
|
||||
|
||||
if 'system_fan' not in Base.metadata:
|
||||
|
||||
class SystemFan(NumericSensor):
|
||||
"""
|
||||
``SystemFan`` ORM model.
|
||||
"""
|
||||
|
||||
__tablename__ = 'system_fan'
|
||||
|
||||
id = Column(
|
||||
Integer,
|
||||
ForeignKey(NumericSensor.id, ondelete='CASCADE'),
|
||||
primary_key=True,
|
||||
)
|
||||
|
||||
__mapper_args__ = {
|
||||
'polymorphic_identity': __tablename__,
|
||||
}
|
||||
|
|
|
@ -12,21 +12,6 @@ class SensorResponse(SystemResponse):
|
|||
pass
|
||||
|
||||
|
||||
class SensorFanResponse(SensorResponse):
|
||||
def __init__(
|
||||
self, name: str, current: int, label: Optional[str] = None, *args, **kwargs
|
||||
):
|
||||
super().__init__(
|
||||
*args,
|
||||
output={
|
||||
'name': name,
|
||||
'current': current,
|
||||
'label': label,
|
||||
},
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
class SensorBatteryResponse(SensorResponse):
|
||||
def __init__(
|
||||
self, percent: float, secs_left: int, power_plugged: bool, *args, **kwargs
|
||||
|
@ -127,11 +112,6 @@ class SystemResponseList(SystemResponse):
|
|||
super().__init__(output=[r.output for r in responses], *args, **kwargs)
|
||||
|
||||
|
||||
class SensorResponseList(SensorResponse, SystemResponseList):
|
||||
def __init__(self, responses: List[SensorResponse], *args, **kwargs):
|
||||
super().__init__(responses=responses, *args, **kwargs)
|
||||
|
||||
|
||||
class ConnectedUserResponseList(SystemResponseList):
|
||||
def __init__(self, responses: List[ConnectUserResponse], *args, **kwargs):
|
||||
super().__init__(responses=responses, *args, **kwargs)
|
||||
|
|
|
@ -19,11 +19,10 @@ from platypush.entities.system import (
|
|||
MemoryStats as MemoryStatsModel,
|
||||
NetworkInterface as NetworkInterfaceModel,
|
||||
SwapStats as SwapStatsModel,
|
||||
SystemFan,
|
||||
SystemTemperature,
|
||||
)
|
||||
from platypush.message.response.system import (
|
||||
SensorResponseList,
|
||||
SensorFanResponse,
|
||||
SensorBatteryResponse,
|
||||
ConnectedUserResponseList,
|
||||
ConnectUserResponse,
|
||||
|
@ -44,6 +43,8 @@ from platypush.schemas.system import (
|
|||
CpuTimesSchema,
|
||||
Disk,
|
||||
DiskSchema,
|
||||
Fan,
|
||||
FanSchema,
|
||||
MemoryStats,
|
||||
MemoryStatsSchema,
|
||||
NetworkInterface,
|
||||
|
@ -363,36 +364,28 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
"""
|
||||
return TemperatureSchema().dump(self._sensors_temperature(), many=True)
|
||||
|
||||
def _sensors_fan(self) -> List[Fan]:
|
||||
return FanSchema().load( # type: ignore
|
||||
[
|
||||
{
|
||||
**sensor._asdict(),
|
||||
'id': f'{kind}_{i + 1}',
|
||||
'label': (f'{kind} #{i + 1}' if not sensor.label else sensor.label),
|
||||
}
|
||||
for kind, sensors in psutil.sensors_fans().items()
|
||||
for i, sensor in enumerate(sensors)
|
||||
],
|
||||
many=True,
|
||||
)
|
||||
|
||||
@action
|
||||
def sensors_fan(self, sensor: Optional[str] = None) -> SensorResponseList:
|
||||
def sensors_fan(self) -> List[dict]:
|
||||
"""
|
||||
Get stats from the fan sensors.
|
||||
|
||||
:param sensor: Select the sensor name.
|
||||
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
||||
:return: .. schema:: system.FanSchema(many=True)
|
||||
"""
|
||||
stats = psutil.sensors_fans()
|
||||
|
||||
def _expand_stats(name, _stats):
|
||||
return SensorResponseList(
|
||||
[
|
||||
SensorFanResponse(
|
||||
name=name,
|
||||
current=s.current,
|
||||
label=s.label,
|
||||
)
|
||||
for s in _stats
|
||||
]
|
||||
)
|
||||
|
||||
if sensor:
|
||||
stats = [addr for name, addr in stats.items() if name == sensor]
|
||||
assert stats, 'No such sensor name: {}'.format(sensor)
|
||||
return _expand_stats(sensor, stats[0])
|
||||
|
||||
return SensorResponseList(
|
||||
[_expand_stats(name, stat) for name, stat in stats.items()]
|
||||
)
|
||||
return FanSchema().dump(self._sensors_fan(), many=True)
|
||||
|
||||
@action
|
||||
def sensors_battery(self) -> SensorBatteryResponse:
|
||||
|
@ -545,7 +538,7 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
"""
|
||||
:return: .. schema:: system.SystemInfoSchema
|
||||
"""
|
||||
ret = SystemInfoSchema().dump(
|
||||
return SystemInfoSchema().dump(
|
||||
{
|
||||
'cpu': {
|
||||
'frequency': self._cpu_frequency_avg(),
|
||||
|
@ -560,11 +553,10 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
'disks': self._disk_info(),
|
||||
'network': self._network_info(),
|
||||
'temperature': self._sensors_temperature(),
|
||||
'fans': self._sensors_fan(),
|
||||
}
|
||||
)
|
||||
|
||||
return ret
|
||||
|
||||
@override
|
||||
def transform_entities(self, entities: dict) -> List[Entity]:
|
||||
cpu = entities['cpu'].copy()
|
||||
|
@ -662,6 +654,15 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
)
|
||||
for temp in entities.get('temperature', [])
|
||||
],
|
||||
*[
|
||||
SystemFan(
|
||||
id=f'system:fan:{fan.pop("id")}',
|
||||
name=fan.pop('label'),
|
||||
unit='rpm',
|
||||
**fan,
|
||||
)
|
||||
for fan in entities.get('fans', [])
|
||||
],
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from ._cpu import (
|
|||
CpuTimesSchema,
|
||||
)
|
||||
from ._disk import Disk, DiskSchema
|
||||
from ._fan import Fan, FanSchema
|
||||
from ._memory import MemoryStats, MemoryStatsSchema, SwapStats, SwapStatsSchema
|
||||
from ._model import SystemInfo
|
||||
from ._network import NetworkInterface, NetworkInterfaceSchema
|
||||
|
@ -32,6 +33,8 @@ __all__ = [
|
|||
"CpuTimesSchema",
|
||||
"Disk",
|
||||
"DiskSchema",
|
||||
"Fan",
|
||||
"FanSchema",
|
||||
"MemoryStats",
|
||||
"MemoryStatsSchema",
|
||||
"SwapStats",
|
||||
|
|
4
platypush/schemas/system/_fan/__init__.py
Normal file
4
platypush/schemas/system/_fan/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
from ._model import Fan
|
||||
from ._schemas import FanSchema
|
||||
|
||||
__all__ = ["Fan", "FanSchema"]
|
15
platypush/schemas/system/_fan/_base.py
Normal file
15
platypush/schemas/system/_fan/_base.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from marshmallow import pre_load
|
||||
|
||||
from .._base import SystemBaseSchema
|
||||
|
||||
|
||||
class FanBaseSchema(SystemBaseSchema):
|
||||
"""
|
||||
Base schema for system fan sensors.
|
||||
"""
|
||||
|
||||
@pre_load
|
||||
def pre_load(self, data: dict, **_) -> dict:
|
||||
data = super().pre_load(data)
|
||||
data['value'] = data.pop('current', data.pop('value', None))
|
||||
return data
|
35
platypush/schemas/system/_fan/_model.py
Normal file
35
platypush/schemas/system/_fan/_model.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
|
||||
@dataclass
|
||||
class Fan:
|
||||
"""
|
||||
System fan sensor data class.
|
||||
"""
|
||||
|
||||
id: str = field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'Unique ID for the sensor',
|
||||
'example': 'acpi_1',
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
label: str = field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'Name of the sensor',
|
||||
'example': 'CPU',
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
value: float = field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'Current fan speed, in RPM',
|
||||
'example': 3000,
|
||||
}
|
||||
}
|
||||
)
|
7
platypush/schemas/system/_fan/_schemas.py
Normal file
7
platypush/schemas/system/_fan/_schemas.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from marshmallow_dataclass import class_schema
|
||||
|
||||
from ._base import FanBaseSchema
|
||||
from ._model import Fan
|
||||
|
||||
|
||||
FanSchema = class_schema(Fan, base_schema=FanBaseSchema)
|
|
@ -3,6 +3,7 @@ from typing import List
|
|||
|
||||
from ._cpu import Cpu
|
||||
from ._disk import Disk
|
||||
from ._fan import Fan
|
||||
from ._memory import MemoryStats, SwapStats
|
||||
from ._network import NetworkInterface
|
||||
from ._temperature import Temperature
|
||||
|
@ -20,3 +21,4 @@ class SystemInfo:
|
|||
disks: List[Disk]
|
||||
network: List[NetworkInterface]
|
||||
temperature: List[Temperature]
|
||||
fans: List[Fan]
|
||||
|
|
Loading…
Reference in a new issue