forked from platypush/platypush
Added battery entity support to system
plugin.
This commit is contained in:
parent
b3440ab96b
commit
a72c32cb00
11 changed files with 141 additions and 40 deletions
|
@ -0,0 +1 @@
|
|||
Battery.vue
|
|
@ -79,14 +79,6 @@
|
|||
}
|
||||
},
|
||||
|
||||
"current_sensor": {
|
||||
"name": "Sensor",
|
||||
"name_plural": "Sensors",
|
||||
"icon": {
|
||||
"class": "fas fa-bolt"
|
||||
}
|
||||
},
|
||||
|
||||
"system_fan": {
|
||||
"name": "System",
|
||||
"name_plural": "System",
|
||||
|
@ -95,6 +87,22 @@
|
|||
}
|
||||
},
|
||||
|
||||
"system_battery": {
|
||||
"name": "System",
|
||||
"name_plural": "System",
|
||||
"icon": {
|
||||
"class": "fas fa-battery-full"
|
||||
}
|
||||
},
|
||||
|
||||
"current_sensor": {
|
||||
"name": "Sensor",
|
||||
"name_plural": "Sensors",
|
||||
"icon": {
|
||||
"class": "fas fa-bolt"
|
||||
}
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
"name": "System",
|
||||
"name_plural": "System",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from sqlalchemy import Column, Float, ForeignKey, Integer, JSON, String
|
||||
from sqlalchemy import Boolean, Column, Float, ForeignKey, Integer, JSON, String
|
||||
|
||||
from platypush.common.db import Base
|
||||
|
||||
from . import Entity
|
||||
from .devices import Device
|
||||
from .sensors import NumericSensor
|
||||
from .sensors import NumericSensor, PercentSensor
|
||||
from .temperature import TemperatureSensor
|
||||
|
||||
|
||||
|
@ -253,3 +253,26 @@ if 'system_fan' not in Base.metadata:
|
|||
__mapper_args__ = {
|
||||
'polymorphic_identity': __tablename__,
|
||||
}
|
||||
|
||||
|
||||
if 'system_battery' not in Base.metadata:
|
||||
|
||||
class SystemBattery(PercentSensor):
|
||||
"""
|
||||
``SystemBattery`` ORM model.
|
||||
"""
|
||||
|
||||
__tablename__ = 'system_battery'
|
||||
|
||||
id = Column(
|
||||
Integer,
|
||||
ForeignKey(PercentSensor.id, ondelete='CASCADE'),
|
||||
primary_key=True,
|
||||
)
|
||||
|
||||
seconds_left = Column(Float)
|
||||
power_plugged = Column(Boolean)
|
||||
|
||||
__mapper_args__ = {
|
||||
'polymorphic_identity': __tablename__,
|
||||
}
|
||||
|
|
|
@ -8,25 +8,6 @@ class SystemResponse(Response):
|
|||
pass
|
||||
|
||||
|
||||
class SensorResponse(SystemResponse):
|
||||
pass
|
||||
|
||||
|
||||
class SensorBatteryResponse(SensorResponse):
|
||||
def __init__(
|
||||
self, percent: float, secs_left: int, power_plugged: bool, *args, **kwargs
|
||||
):
|
||||
super().__init__(
|
||||
*args,
|
||||
output={
|
||||
'percent': percent,
|
||||
'secs_left': secs_left,
|
||||
'power_plugged': power_plugged,
|
||||
},
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
class ConnectUserResponse(SystemResponse):
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
@ -19,11 +19,11 @@ from platypush.entities.system import (
|
|||
MemoryStats as MemoryStatsModel,
|
||||
NetworkInterface as NetworkInterfaceModel,
|
||||
SwapStats as SwapStatsModel,
|
||||
SystemBattery,
|
||||
SystemFan,
|
||||
SystemTemperature,
|
||||
)
|
||||
from platypush.message.response.system import (
|
||||
SensorBatteryResponse,
|
||||
ConnectedUserResponseList,
|
||||
ConnectUserResponse,
|
||||
ProcessResponseList,
|
||||
|
@ -32,6 +32,8 @@ from platypush.message.response.system import (
|
|||
from platypush.plugins import action
|
||||
from platypush.plugins.sensor import SensorPlugin
|
||||
from platypush.schemas.system import (
|
||||
Battery,
|
||||
BatterySchema,
|
||||
ConnectionSchema,
|
||||
CpuFrequency,
|
||||
CpuFrequencySchema,
|
||||
|
@ -387,19 +389,19 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
"""
|
||||
return FanSchema().dump(self._sensors_fan(), many=True)
|
||||
|
||||
def _sensors_battery(self) -> Optional[Battery]:
|
||||
battery = psutil.sensors_battery()
|
||||
return BatterySchema().load(battery) if battery else None # type: ignore
|
||||
|
||||
@action
|
||||
def sensors_battery(self) -> SensorBatteryResponse:
|
||||
def sensors_battery(self) -> Optional[dict]:
|
||||
"""
|
||||
Get stats from the battery sensor.
|
||||
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
||||
"""
|
||||
stats = psutil.sensors_battery()
|
||||
|
||||
return SensorBatteryResponse(
|
||||
percent=stats.percent,
|
||||
secs_left=stats.secsleft,
|
||||
power_plugged=stats.power_plugged,
|
||||
)
|
||||
:return: .. schema:: system.BatterySchema
|
||||
"""
|
||||
battery = self._sensors_battery()
|
||||
return BatterySchema().dump(battery) if battery else None # type: ignore
|
||||
|
||||
@action
|
||||
def connected_users(self) -> ConnectedUserResponseList:
|
||||
|
@ -554,12 +556,14 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
'network': self._network_info(),
|
||||
'temperature': self._sensors_temperature(),
|
||||
'fans': self._sensors_fan(),
|
||||
'battery': self._sensors_battery(),
|
||||
}
|
||||
)
|
||||
|
||||
@override
|
||||
def transform_entities(self, entities: dict) -> List[Entity]:
|
||||
cpu = entities['cpu'].copy()
|
||||
battery = entities['battery']
|
||||
|
||||
return [
|
||||
Cpu(
|
||||
|
@ -663,6 +667,15 @@ class SystemPlugin(SensorPlugin, EntityManager):
|
|||
)
|
||||
for fan in entities.get('fans', [])
|
||||
],
|
||||
*[
|
||||
SystemBattery(
|
||||
id='system:battery',
|
||||
name='Battery',
|
||||
**battery,
|
||||
)
|
||||
if battery
|
||||
else ()
|
||||
],
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from ._battery import Battery, BatterySchema
|
||||
from ._connection import Connection, ConnectionSchema
|
||||
from ._cpu import (
|
||||
Cpu,
|
||||
|
@ -20,6 +21,8 @@ from ._temperature import Temperature, TemperatureSchema
|
|||
|
||||
|
||||
__all__ = [
|
||||
"Battery",
|
||||
"BatterySchema",
|
||||
"Connection",
|
||||
"ConnectionSchema",
|
||||
"Cpu",
|
||||
|
|
4
platypush/schemas/system/_battery/__init__.py
Normal file
4
platypush/schemas/system/_battery/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
from ._model import Battery
|
||||
from ._schemas import BatterySchema
|
||||
|
||||
__all__ = ['Battery', 'BatterySchema']
|
20
platypush/schemas/system/_battery/_base.py
Normal file
20
platypush/schemas/system/_battery/_base.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from enum import Enum
|
||||
|
||||
from marshmallow import pre_load
|
||||
|
||||
from .._base import SystemBaseSchema
|
||||
|
||||
|
||||
class BatteryBaseSchema(SystemBaseSchema):
|
||||
"""
|
||||
Base schema for system battery sensors.
|
||||
"""
|
||||
|
||||
@pre_load
|
||||
def pre_load(self, data: dict, **_) -> dict:
|
||||
data = super().pre_load(data)
|
||||
percent = data.pop('percent', data.pop('value', None))
|
||||
seconds_left = data.pop('secsleft', data.pop('seconds_left', None))
|
||||
data['value'] = percent / 100 if percent is not None else None
|
||||
data['seconds_left'] = None if isinstance(seconds_left, Enum) else seconds_left
|
||||
return data
|
39
platypush/schemas/system/_battery/_model.py
Normal file
39
platypush/schemas/system/_battery/_model.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from dataclasses import dataclass, field
|
||||
from typing import Optional
|
||||
|
||||
from platypush.schemas.dataclasses import percent_field
|
||||
|
||||
|
||||
@dataclass
|
||||
class Battery:
|
||||
"""
|
||||
System battery sensor wrapper.
|
||||
"""
|
||||
|
||||
seconds_left: Optional[float] = field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'High threshold for the temperature sensor, in Celsius',
|
||||
'example': 75,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
power_plugged: Optional[bool] = field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'Whether the battery is plugged in or not',
|
||||
'example': False,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
value: Optional[float] = percent_field(
|
||||
metadata={
|
||||
'metadata': {
|
||||
'description': 'Current charge left, as a percentage value '
|
||||
'between 0 and 1',
|
||||
'example': 0.5,
|
||||
}
|
||||
}
|
||||
)
|
7
platypush/schemas/system/_battery/_schemas.py
Normal file
7
platypush/schemas/system/_battery/_schemas.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from marshmallow_dataclass import class_schema
|
||||
|
||||
from ._base import BatteryBaseSchema
|
||||
from ._model import Battery
|
||||
|
||||
|
||||
BatterySchema = class_schema(Battery, base_schema=BatteryBaseSchema)
|
|
@ -1,6 +1,7 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from ._battery import Battery
|
||||
from ._cpu import Cpu
|
||||
from ._disk import Disk
|
||||
from ._fan import Fan
|
||||
|
@ -22,3 +23,4 @@ class SystemInfo:
|
|||
network: List[NetworkInterface]
|
||||
temperature: List[Temperature]
|
||||
fans: List[Fan]
|
||||
battery: Optional[Battery]
|
||||
|
|
Loading…
Reference in a new issue