forked from platypush/platypush
Refactoring the system
plugin to support entities.
This commit is contained in:
parent
3e3c48d779
commit
b43017ef01
1 changed files with 276 additions and 165 deletions
|
@ -2,18 +2,47 @@ import socket
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Union, List, Optional, Dict
|
from typing import Union, List, Optional, Dict
|
||||||
|
from typing_extensions import override
|
||||||
|
|
||||||
from platypush.message.response.system import CpuInfoResponse, CpuTimesResponse, CpuResponseList, CpuStatsResponse, \
|
from platypush.entities import Entity
|
||||||
CpuFrequencyResponse, VirtualMemoryUsageResponse, SwapMemoryUsageResponse, DiskResponseList, \
|
from platypush.entities.managers import EntityManager
|
||||||
DiskPartitionResponse, DiskUsageResponse, DiskIoCountersResponse, NetworkIoCountersResponse, NetworkResponseList, \
|
from platypush.entities.system import CpuInfo as CpuInfoModel
|
||||||
NetworkConnectionResponse, NetworkAddressResponse, NetworkInterfaceStatsResponse, SensorTemperatureResponse, \
|
from platypush.message.response.system import (
|
||||||
SensorResponseList, SensorFanResponse, SensorBatteryResponse, ConnectedUserResponseList, ConnectUserResponse, \
|
CpuTimesResponse,
|
||||||
ProcessResponseList, ProcessResponse
|
CpuResponseList,
|
||||||
|
CpuStatsResponse,
|
||||||
from platypush.plugins import Plugin, action
|
CpuFrequencyResponse,
|
||||||
|
VirtualMemoryUsageResponse,
|
||||||
|
SwapMemoryUsageResponse,
|
||||||
|
DiskResponseList,
|
||||||
|
DiskPartitionResponse,
|
||||||
|
DiskUsageResponse,
|
||||||
|
DiskIoCountersResponse,
|
||||||
|
NetworkIoCountersResponse,
|
||||||
|
NetworkResponseList,
|
||||||
|
NetworkConnectionResponse,
|
||||||
|
NetworkAddressResponse,
|
||||||
|
NetworkInterfaceStatsResponse,
|
||||||
|
SensorTemperatureResponse,
|
||||||
|
SensorResponseList,
|
||||||
|
SensorFanResponse,
|
||||||
|
SensorBatteryResponse,
|
||||||
|
ConnectedUserResponseList,
|
||||||
|
ConnectUserResponse,
|
||||||
|
ProcessResponseList,
|
||||||
|
ProcessResponse,
|
||||||
|
)
|
||||||
|
from platypush.plugins import action
|
||||||
|
from platypush.plugins.sensor import SensorPlugin
|
||||||
|
from platypush.schemas.system import (
|
||||||
|
CpuInfo,
|
||||||
|
CpuInfoSchema,
|
||||||
|
SystemInfoSchema,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SystemPlugin(Plugin):
|
# pylint: disable=too-many-ancestors
|
||||||
|
class SystemPlugin(SensorPlugin, EntityManager):
|
||||||
"""
|
"""
|
||||||
Plugin to get system info.
|
Plugin to get system info.
|
||||||
|
|
||||||
|
@ -24,35 +53,40 @@ class SystemPlugin(Plugin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.__cpu_info: Optional[CpuInfo] = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _entity_args(name: str) -> Dict[str, str]:
|
||||||
|
return {
|
||||||
|
'id': f'system:{name}',
|
||||||
|
'name': name,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _cpu_info(self) -> CpuInfo:
|
||||||
|
from cpuinfo import get_cpu_info
|
||||||
|
|
||||||
|
if not self.__cpu_info:
|
||||||
|
# The CPU information won't change while the process is running, so
|
||||||
|
# it makes sense to cache it only once.
|
||||||
|
self.__cpu_info = CpuInfoSchema().load(get_cpu_info()) # type: ignore
|
||||||
|
|
||||||
|
return self.__cpu_info # type: ignore
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def cpu_info(self) -> CpuInfoResponse:
|
def cpu_info(self):
|
||||||
"""
|
"""
|
||||||
Get CPU info.
|
Get CPU info.
|
||||||
:return: :class:`platypush.message.response.system.CpuInfoResponse`
|
:return: .. schema:: system.CpuInfoSchema
|
||||||
"""
|
"""
|
||||||
from cpuinfo import get_cpu_info
|
return CpuInfoSchema().dump(self._cpu_info)
|
||||||
info = get_cpu_info()
|
|
||||||
|
|
||||||
return CpuInfoResponse(
|
|
||||||
arch=info.get('raw_arch_string'),
|
|
||||||
bits=info.get('bits'),
|
|
||||||
count=info.get('count'),
|
|
||||||
vendor_id=info.get('vendor_id'),
|
|
||||||
brand=info.get('brand'),
|
|
||||||
hz_advertised=info.get('hz_advertised_raw')[0],
|
|
||||||
hz_actual=info.get('hz_actual_raw')[0],
|
|
||||||
stepping=info.get('stepping'),
|
|
||||||
model=info.get('model'),
|
|
||||||
family=info.get('family'),
|
|
||||||
flags=info.get('flags'),
|
|
||||||
l1_instruction_cache_size=info.get('l1_instruction_cache_size'),
|
|
||||||
l1_data_cache_size=info.get('l1_data_cache_size'),
|
|
||||||
l2_cache_size=info.get('l2_cache_size'),
|
|
||||||
l3_cache_size=info.get('l3_cache_size'),
|
|
||||||
)
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def cpu_times(self, per_cpu=False, percent=False) -> Union[CpuTimesResponse, CpuResponseList]:
|
def cpu_times(
|
||||||
|
self, per_cpu=False, percent=False
|
||||||
|
) -> Union[CpuTimesResponse, CpuResponseList]:
|
||||||
"""
|
"""
|
||||||
Get the CPU times stats.
|
Get the CPU times stats.
|
||||||
|
|
||||||
|
@ -62,25 +96,30 @@ class SystemPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
times = psutil.cpu_times_percent(percpu=per_cpu) if percent else \
|
times = (
|
||||||
psutil.cpu_times(percpu=per_cpu)
|
psutil.cpu_times_percent(percpu=per_cpu)
|
||||||
|
if percent
|
||||||
|
else psutil.cpu_times(percpu=per_cpu)
|
||||||
|
)
|
||||||
|
|
||||||
if per_cpu:
|
if per_cpu:
|
||||||
return CpuResponseList([
|
return CpuResponseList(
|
||||||
CpuTimesResponse(
|
[
|
||||||
user=t.user,
|
CpuTimesResponse(
|
||||||
nice=t.nice,
|
user=t.user,
|
||||||
system=t.system,
|
nice=t.nice,
|
||||||
idle=t.idle,
|
system=t.system,
|
||||||
iowait=t.iowait,
|
idle=t.idle,
|
||||||
irq=t.irq,
|
iowait=t.iowait,
|
||||||
softirq=t.softirq,
|
irq=t.irq,
|
||||||
steal=t.steal,
|
softirq=t.softirq,
|
||||||
guest=t.guest,
|
steal=t.steal,
|
||||||
guest_nice=t.guest_nice,
|
guest=t.guest,
|
||||||
)
|
guest_nice=t.guest_nice,
|
||||||
for t in times
|
)
|
||||||
])
|
for t in times
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return CpuTimesResponse(
|
return CpuTimesResponse(
|
||||||
user=times.user,
|
user=times.user,
|
||||||
|
@ -96,7 +135,9 @@ class SystemPlugin(Plugin):
|
||||||
)
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def cpu_percent(self, per_cpu: bool = False, interval: Optional[float] = None) -> Union[float, List[float]]:
|
def cpu_percent(
|
||||||
|
self, per_cpu: bool = False, interval: Optional[float] = None
|
||||||
|
) -> Union[float, List[float]]:
|
||||||
"""
|
"""
|
||||||
Get the CPU load percentage.
|
Get the CPU load percentage.
|
||||||
|
|
||||||
|
@ -108,10 +149,11 @@ class SystemPlugin(Plugin):
|
||||||
:return: float if ``per_cpu=False``, ``list[float]`` otherwise.
|
:return: float if ``per_cpu=False``, ``list[float]`` otherwise.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
percent = psutil.cpu_percent(percpu=per_cpu, interval=interval)
|
percent = psutil.cpu_percent(percpu=per_cpu, interval=interval)
|
||||||
|
|
||||||
if per_cpu:
|
if per_cpu:
|
||||||
return [p for p in percent]
|
return list(percent) # type: ignore
|
||||||
return percent
|
return percent
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -121,6 +163,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: :class:`platypush.message.response.system.CpuStatsResponse`
|
:return: :class:`platypush.message.response.system.CpuStatsResponse`
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
stats = psutil.cpu_stats()
|
stats = psutil.cpu_stats()
|
||||||
|
|
||||||
return CpuStatsResponse(
|
return CpuStatsResponse(
|
||||||
|
@ -131,7 +174,9 @@ class SystemPlugin(Plugin):
|
||||||
)
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def cpu_frequency(self, per_cpu: bool = False) -> Union[CpuFrequencyResponse, CpuResponseList]:
|
def cpu_frequency(
|
||||||
|
self, per_cpu: bool = False
|
||||||
|
) -> Union[CpuFrequencyResponse, CpuResponseList]:
|
||||||
"""
|
"""
|
||||||
Get CPU stats.
|
Get CPU stats.
|
||||||
|
|
||||||
|
@ -139,17 +184,20 @@ class SystemPlugin(Plugin):
|
||||||
:return: :class:`platypush.message.response.system.CpuFrequencyResponse`
|
:return: :class:`platypush.message.response.system.CpuFrequencyResponse`
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
freq = psutil.cpu_freq(percpu=per_cpu)
|
freq = psutil.cpu_freq(percpu=per_cpu)
|
||||||
|
|
||||||
if per_cpu:
|
if per_cpu:
|
||||||
return CpuResponseList([
|
return CpuResponseList(
|
||||||
CpuFrequencyResponse(
|
[
|
||||||
min=f.min,
|
CpuFrequencyResponse(
|
||||||
max=f.max,
|
min=f.min,
|
||||||
current=f.current,
|
max=f.max,
|
||||||
)
|
current=f.current,
|
||||||
for f in freq
|
)
|
||||||
])
|
for f in freq
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return CpuFrequencyResponse(
|
return CpuFrequencyResponse(
|
||||||
min=freq.min,
|
min=freq.min,
|
||||||
|
@ -163,6 +211,7 @@ class SystemPlugin(Plugin):
|
||||||
Get the average load as a vector that represents the load within the last 1, 5 and 15 minutes.
|
Get the average load as a vector that represents the load within the last 1, 5 and 15 minutes.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
return psutil.getloadavg()
|
return psutil.getloadavg()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -172,6 +221,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: list of :class:`platypush.message.response.system.VirtualMemoryUsageResponse`
|
:return: list of :class:`platypush.message.response.system.VirtualMemoryUsageResponse`
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
return VirtualMemoryUsageResponse(
|
return VirtualMemoryUsageResponse(
|
||||||
total=mem.total,
|
total=mem.total,
|
||||||
|
@ -193,6 +243,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: list of :class:`platypush.message.response.system.SwapMemoryUsageResponse`
|
:return: list of :class:`platypush.message.response.system.SwapMemoryUsageResponse`
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
mem = psutil.swap_memory()
|
mem = psutil.swap_memory()
|
||||||
return SwapMemoryUsageResponse(
|
return SwapMemoryUsageResponse(
|
||||||
total=mem.total,
|
total=mem.total,
|
||||||
|
@ -210,18 +261,24 @@ class SystemPlugin(Plugin):
|
||||||
:return: list of :class:`platypush.message.response.system.DiskPartitionResponse`
|
:return: list of :class:`platypush.message.response.system.DiskPartitionResponse`
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
parts = psutil.disk_partitions()
|
parts = psutil.disk_partitions()
|
||||||
return DiskResponseList([
|
return DiskResponseList(
|
||||||
DiskPartitionResponse(
|
[
|
||||||
device=p.device,
|
DiskPartitionResponse(
|
||||||
mount_point=p.mountpoint,
|
device=p.device,
|
||||||
fstype=p.fstype,
|
mount_point=p.mountpoint,
|
||||||
opts=p.opts,
|
fstype=p.fstype,
|
||||||
) for p in parts
|
opts=p.opts,
|
||||||
])
|
)
|
||||||
|
for p in parts
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def disk_usage(self, path: Optional[str] = None) -> Union[DiskUsageResponse, DiskResponseList]:
|
def disk_usage(
|
||||||
|
self, path: Optional[str] = None
|
||||||
|
) -> Union[DiskUsageResponse, DiskResponseList]:
|
||||||
"""
|
"""
|
||||||
Get the usage of a mounted disk.
|
Get the usage of a mounted disk.
|
||||||
|
|
||||||
|
@ -234,29 +291,35 @@ class SystemPlugin(Plugin):
|
||||||
if path:
|
if path:
|
||||||
usage = psutil.disk_usage(path)
|
usage = psutil.disk_usage(path)
|
||||||
return DiskUsageResponse(
|
return DiskUsageResponse(
|
||||||
path=path,
|
path=path,
|
||||||
total=usage.total,
|
total=usage.total,
|
||||||
used=usage.used,
|
used=usage.used,
|
||||||
free=usage.free,
|
free=usage.free,
|
||||||
percent=usage.percent,
|
percent=usage.percent,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
disks = {p.mountpoint: psutil.disk_usage(p.mountpoint)
|
disks = {
|
||||||
for p in psutil.disk_partitions()}
|
p.mountpoint: psutil.disk_usage(p.mountpoint)
|
||||||
|
for p in psutil.disk_partitions()
|
||||||
|
}
|
||||||
|
|
||||||
return DiskResponseList([
|
return DiskResponseList(
|
||||||
DiskUsageResponse(
|
[
|
||||||
path=path,
|
DiskUsageResponse(
|
||||||
total=disk.total,
|
path=path,
|
||||||
used=disk.used,
|
total=disk.total,
|
||||||
free=disk.free,
|
used=disk.used,
|
||||||
percent=disk.percent,
|
free=disk.free,
|
||||||
) for path, disk in disks.items()
|
percent=disk.percent,
|
||||||
])
|
)
|
||||||
|
for path, disk in disks.items()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def disk_io_counters(self, disk: Optional[str] = None, per_disk: bool = False) -> \
|
def disk_io_counters(
|
||||||
Union[DiskIoCountersResponse, DiskResponseList]:
|
self, disk: Optional[str] = None, per_disk: bool = False
|
||||||
|
) -> Union[DiskIoCountersResponse, DiskResponseList]:
|
||||||
"""
|
"""
|
||||||
Get the I/O counter stats for the mounted disks.
|
Get the I/O counter stats for the mounted disks.
|
||||||
|
|
||||||
|
@ -293,14 +356,14 @@ class SystemPlugin(Plugin):
|
||||||
if not per_disk:
|
if not per_disk:
|
||||||
return _expand_response(None, io)
|
return _expand_response(None, io)
|
||||||
|
|
||||||
return DiskResponseList([
|
return DiskResponseList(
|
||||||
_expand_response(disk, stats)
|
[_expand_response(disk, stats) for disk, stats in io.items()]
|
||||||
for disk, stats in io.items()
|
)
|
||||||
])
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def net_io_counters(self, nic: Optional[str] = None, per_nic: bool = False) -> \
|
def net_io_counters(
|
||||||
Union[NetworkIoCountersResponse, NetworkResponseList]:
|
self, nic: Optional[str] = None, per_nic: bool = False
|
||||||
|
) -> Union[NetworkIoCountersResponse, NetworkResponseList]:
|
||||||
"""
|
"""
|
||||||
Get the I/O counters stats for the network interfaces.
|
Get the I/O counters stats for the network interfaces.
|
||||||
|
|
||||||
|
@ -336,14 +399,14 @@ class SystemPlugin(Plugin):
|
||||||
if not per_nic:
|
if not per_nic:
|
||||||
return _expand_response(nic, io)
|
return _expand_response(nic, io)
|
||||||
|
|
||||||
return NetworkResponseList([
|
return NetworkResponseList(
|
||||||
_expand_response(nic, stats)
|
[_expand_response(nic, stats) for nic, stats in io.items()]
|
||||||
for nic, stats in io.items()
|
)
|
||||||
])
|
|
||||||
|
|
||||||
# noinspection PyShadowingBuiltins
|
|
||||||
@action
|
@action
|
||||||
def net_connections(self, type: Optional[str] = None) -> Union[NetworkConnectionResponse, NetworkResponseList]:
|
def net_connections(
|
||||||
|
self, type: Optional[str] = None
|
||||||
|
) -> Union[NetworkConnectionResponse, NetworkResponseList]:
|
||||||
"""
|
"""
|
||||||
Get the list of active network connections.
|
Get the list of active network connections.
|
||||||
On macOS this function requires root privileges.
|
On macOS this function requires root privileges.
|
||||||
|
@ -369,24 +432,30 @@ class SystemPlugin(Plugin):
|
||||||
:return: List of :class:`platypush.message.response.system.NetworkConnectionResponse`.
|
:return: List of :class:`platypush.message.response.system.NetworkConnectionResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
conns = psutil.net_connections(kind=type)
|
conns = psutil.net_connections(kind=type)
|
||||||
|
|
||||||
return NetworkResponseList([
|
return NetworkResponseList(
|
||||||
NetworkConnectionResponse(
|
[
|
||||||
fd=conn.fd,
|
NetworkConnectionResponse(
|
||||||
family=conn.family.name,
|
fd=conn.fd,
|
||||||
type=conn.type.name,
|
family=conn.family.name,
|
||||||
local_address=conn.laddr[0] if conn.laddr else None,
|
type=conn.type.name,
|
||||||
local_port=conn.laddr[1] if len(conn.laddr) > 1 else None,
|
local_address=conn.laddr[0] if conn.laddr else None,
|
||||||
remote_address=conn.raddr[0] if conn.raddr else None,
|
local_port=conn.laddr[1] if len(conn.laddr) > 1 else None,
|
||||||
remote_port=conn.raddr[1] if len(conn.raddr) > 1 else None,
|
remote_address=conn.raddr[0] if conn.raddr else None,
|
||||||
status=conn.status,
|
remote_port=conn.raddr[1] if len(conn.raddr) > 1 else None,
|
||||||
pid=conn.pid,
|
status=conn.status,
|
||||||
) for conn in conns
|
pid=conn.pid,
|
||||||
])
|
)
|
||||||
|
for conn in conns
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def net_addresses(self, nic: Optional[str] = None) -> Union[NetworkAddressResponse, NetworkResponseList]:
|
def net_addresses(
|
||||||
|
self, nic: Optional[str] = None
|
||||||
|
) -> Union[NetworkAddressResponse, NetworkResponseList]:
|
||||||
"""
|
"""
|
||||||
Get address info associated to the network interfaces.
|
Get address info associated to the network interfaces.
|
||||||
|
|
||||||
|
@ -395,6 +464,7 @@ class SystemPlugin(Plugin):
|
||||||
:class:`platypush.message.response.system.NetworkAddressResponse`.
|
:class:`platypush.message.response.system.NetworkAddressResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
addrs = psutil.net_if_addrs()
|
addrs = psutil.net_if_addrs()
|
||||||
|
|
||||||
def _expand_addresses(_nic, _addrs):
|
def _expand_addresses(_nic, _addrs):
|
||||||
|
@ -402,22 +472,28 @@ class SystemPlugin(Plugin):
|
||||||
|
|
||||||
for addr in _addrs:
|
for addr in _addrs:
|
||||||
if addr.family == socket.AddressFamily.AF_INET:
|
if addr.family == socket.AddressFamily.AF_INET:
|
||||||
args.update({
|
args.update(
|
||||||
'ipv4_address': addr.address,
|
{
|
||||||
'ipv4_netmask': addr.netmask,
|
'ipv4_address': addr.address,
|
||||||
'ipv4_broadcast': addr.broadcast,
|
'ipv4_netmask': addr.netmask,
|
||||||
})
|
'ipv4_broadcast': addr.broadcast,
|
||||||
|
}
|
||||||
|
)
|
||||||
elif addr.family == socket.AddressFamily.AF_INET6:
|
elif addr.family == socket.AddressFamily.AF_INET6:
|
||||||
args.update({
|
args.update(
|
||||||
'ipv6_address': addr.address,
|
{
|
||||||
'ipv6_netmask': addr.netmask,
|
'ipv6_address': addr.address,
|
||||||
'ipv6_broadcast': addr.broadcast,
|
'ipv6_netmask': addr.netmask,
|
||||||
})
|
'ipv6_broadcast': addr.broadcast,
|
||||||
|
}
|
||||||
|
)
|
||||||
elif addr.family == socket.AddressFamily.AF_PACKET:
|
elif addr.family == socket.AddressFamily.AF_PACKET:
|
||||||
args.update({
|
args.update(
|
||||||
'mac_address': addr.address,
|
{
|
||||||
'mac_broadcast': addr.broadcast,
|
'mac_address': addr.address,
|
||||||
})
|
'mac_broadcast': addr.broadcast,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if addr.ptp and not args.get('ptp'):
|
if addr.ptp and not args.get('ptp'):
|
||||||
args['ptp'] = addr.ptp
|
args['ptp'] = addr.ptp
|
||||||
|
@ -430,13 +506,14 @@ class SystemPlugin(Plugin):
|
||||||
addr = addrs[0]
|
addr = addrs[0]
|
||||||
return _expand_addresses(nic, addr)
|
return _expand_addresses(nic, addr)
|
||||||
|
|
||||||
return NetworkResponseList([
|
return NetworkResponseList(
|
||||||
_expand_addresses(nic, addr)
|
[_expand_addresses(nic, addr) for nic, addr in addrs.items()]
|
||||||
for nic, addr in addrs.items()
|
)
|
||||||
])
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def net_stats(self, nic: Optional[str] = None) -> Union[NetworkInterfaceStatsResponse, NetworkResponseList]:
|
def net_stats(
|
||||||
|
self, nic: Optional[str] = None
|
||||||
|
) -> Union[NetworkInterfaceStatsResponse, NetworkResponseList]:
|
||||||
"""
|
"""
|
||||||
Get stats about the network interfaces.
|
Get stats about the network interfaces.
|
||||||
|
|
||||||
|
@ -445,6 +522,7 @@ class SystemPlugin(Plugin):
|
||||||
:class:`platypush.message.response.system.NetworkInterfaceStatsResponse`.
|
:class:`platypush.message.response.system.NetworkInterfaceStatsResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
stats = psutil.net_if_stats()
|
stats = psutil.net_if_stats()
|
||||||
|
|
||||||
def _expand_stats(_nic, _stats):
|
def _expand_stats(_nic, _stats):
|
||||||
|
@ -461,16 +539,18 @@ class SystemPlugin(Plugin):
|
||||||
assert stats, 'No such network interface: {}'.format(nic)
|
assert stats, 'No such network interface: {}'.format(nic)
|
||||||
return _expand_stats(nic, stats[0])
|
return _expand_stats(nic, stats[0])
|
||||||
|
|
||||||
return NetworkResponseList([
|
return NetworkResponseList(
|
||||||
_expand_stats(nic, addr)
|
[_expand_stats(nic, addr) for nic, addr in stats.items()]
|
||||||
for nic, addr in stats.items()
|
)
|
||||||
])
|
|
||||||
|
|
||||||
# noinspection DuplicatedCode
|
|
||||||
@action
|
@action
|
||||||
def sensors_temperature(self, sensor: Optional[str] = None, fahrenheit: bool = False) \
|
def sensors_temperature(
|
||||||
-> Union[SensorTemperatureResponse, List[SensorTemperatureResponse],
|
self, sensor: Optional[str] = None, fahrenheit: bool = False
|
||||||
Dict[str, Union[SensorTemperatureResponse, List[SensorTemperatureResponse]]]]:
|
) -> Union[
|
||||||
|
SensorTemperatureResponse,
|
||||||
|
List[SensorTemperatureResponse],
|
||||||
|
Dict[str, Union[SensorTemperatureResponse, List[SensorTemperatureResponse]]],
|
||||||
|
]:
|
||||||
"""
|
"""
|
||||||
Get stats from the temperature sensors.
|
Get stats from the temperature sensors.
|
||||||
|
|
||||||
|
@ -478,6 +558,7 @@ class SystemPlugin(Plugin):
|
||||||
:param fahrenheit: Return the temperature in Fahrenheit (default: Celsius).
|
:param fahrenheit: Return the temperature in Fahrenheit (default: Celsius).
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
stats = psutil.sensors_temperatures(fahrenheit=fahrenheit)
|
stats = psutil.sensors_temperatures(fahrenheit=fahrenheit)
|
||||||
|
|
||||||
if sensor:
|
if sensor:
|
||||||
|
@ -524,7 +605,6 @@ class SystemPlugin(Plugin):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# noinspection DuplicatedCode
|
|
||||||
@action
|
@action
|
||||||
def sensors_fan(self, sensor: Optional[str] = None) -> SensorResponseList:
|
def sensors_fan(self, sensor: Optional[str] = None) -> SensorResponseList:
|
||||||
"""
|
"""
|
||||||
|
@ -534,27 +614,29 @@ class SystemPlugin(Plugin):
|
||||||
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
stats = psutil.sensors_fans()
|
stats = psutil.sensors_fans()
|
||||||
|
|
||||||
def _expand_stats(name, _stats):
|
def _expand_stats(name, _stats):
|
||||||
return SensorResponseList([
|
return SensorResponseList(
|
||||||
SensorFanResponse(
|
[
|
||||||
name=name,
|
SensorFanResponse(
|
||||||
current=s.current,
|
name=name,
|
||||||
label=s.label,
|
current=s.current,
|
||||||
)
|
label=s.label,
|
||||||
for s in _stats
|
)
|
||||||
])
|
for s in _stats
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
if sensor:
|
if sensor:
|
||||||
stats = [addr for name, addr in stats.items() if name == sensor]
|
stats = [addr for name, addr in stats.items() if name == sensor]
|
||||||
assert stats, 'No such sensor name: {}'.format(sensor)
|
assert stats, 'No such sensor name: {}'.format(sensor)
|
||||||
return _expand_stats(sensor, stats[0])
|
return _expand_stats(sensor, stats[0])
|
||||||
|
|
||||||
return SensorResponseList([
|
return SensorResponseList(
|
||||||
_expand_stats(name, stat)
|
[_expand_stats(name, stat) for name, stat in stats.items()]
|
||||||
for name, stat in stats.items()
|
)
|
||||||
])
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def sensors_battery(self) -> SensorBatteryResponse:
|
def sensors_battery(self) -> SensorBatteryResponse:
|
||||||
|
@ -563,6 +645,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
:return: List of :class:`platypush.message.response.system.SensorFanResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
stats = psutil.sensors_battery()
|
stats = psutil.sensors_battery()
|
||||||
|
|
||||||
return SensorBatteryResponse(
|
return SensorBatteryResponse(
|
||||||
|
@ -578,20 +661,22 @@ class SystemPlugin(Plugin):
|
||||||
:return: List of :class:`platypush.message.response.system.ConnectUserResponse`.
|
:return: List of :class:`platypush.message.response.system.ConnectUserResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
users = psutil.users()
|
users = psutil.users()
|
||||||
|
|
||||||
return ConnectedUserResponseList([
|
return ConnectedUserResponseList(
|
||||||
ConnectUserResponse(
|
[
|
||||||
name=u.name,
|
ConnectUserResponse(
|
||||||
terminal=u.terminal,
|
name=u.name,
|
||||||
host=u.host,
|
terminal=u.terminal,
|
||||||
started=datetime.fromtimestamp(u.started),
|
host=u.host,
|
||||||
pid=u.pid,
|
started=datetime.fromtimestamp(u.started),
|
||||||
)
|
pid=u.pid,
|
||||||
for u in users
|
)
|
||||||
])
|
for u in users
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# noinspection PyShadowingBuiltins
|
|
||||||
@action
|
@action
|
||||||
def processes(self, filter: Optional[str] = '') -> ProcessResponseList:
|
def processes(self, filter: Optional[str] = '') -> ProcessResponseList:
|
||||||
"""
|
"""
|
||||||
|
@ -601,6 +686,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: List of :class:`platypush.message.response.system.ProcessResponse`.
|
:return: List of :class:`platypush.message.response.system.ProcessResponse`.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
processes = [psutil.Process(pid) for pid in psutil.pids()]
|
processes = [psutil.Process(pid) for pid in psutil.pids()]
|
||||||
p_list = []
|
p_list = []
|
||||||
|
|
||||||
|
@ -652,6 +738,7 @@ class SystemPlugin(Plugin):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_process(pid: int):
|
def _get_process(pid: int):
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
return psutil.Process(pid)
|
return psutil.Process(pid)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -661,6 +748,7 @@ class SystemPlugin(Plugin):
|
||||||
:return: ``True`` if the process exists, ``False`` otherwise.
|
:return: ``True`` if the process exists, ``False`` otherwise.
|
||||||
"""
|
"""
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
return psutil.pid_exists(pid)
|
return psutil.pid_exists(pid)
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -696,7 +784,7 @@ class SystemPlugin(Plugin):
|
||||||
self._get_process(pid).kill()
|
self._get_process(pid).kill()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def wait(self, pid: int, timeout: int = None):
|
def wait(self, pid: int, timeout: Optional[int] = None):
|
||||||
"""
|
"""
|
||||||
Wait for a process to terminate.
|
Wait for a process to terminate.
|
||||||
|
|
||||||
|
@ -705,5 +793,28 @@ class SystemPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
self._get_process(pid).wait(timeout)
|
self._get_process(pid).wait(timeout)
|
||||||
|
|
||||||
|
@override
|
||||||
|
@action
|
||||||
|
def get_measurement(self, *_, **__):
|
||||||
|
"""
|
||||||
|
:return: .. schema:: system.SystemInfoSchema
|
||||||
|
"""
|
||||||
|
ret = SystemInfoSchema().dump(
|
||||||
|
{
|
||||||
|
'cpu_info': self._cpu_info,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@override
|
||||||
|
def transform_entities(self, entities: dict) -> List[Entity]:
|
||||||
|
return [
|
||||||
|
CpuInfoModel(
|
||||||
|
**self._entity_args('cpu_info'),
|
||||||
|
**entities['cpu_info'],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
Loading…
Reference in a new issue