system
#
Description#
Plugin to get system info.
- param thresholds:
A number, numeric pair or mapping of
str
to number/numeric pair representing the thresholds for the sensor.Examples:
# Any value below 25 from any sensor will trigger a # SensorDataBelowThresholdEvent, if the previous value was # equal or above, and any value above 25 will trigger a # SensorDataAboveThresholdEvent, if the previous value was # equal or below thresholds: 25.0 # Same as above, but the threshold is only applied to # ``temperature`` readings thresholds: temperature: 25.0 # Any value below 20 from any sensor will trigger a # SensorDataBelowThresholdEvent, if the previous value was # equal or above, and any value above 25 will trigger a # SensorDataAboveThresholdEvent, if the previous value was # equal or below (hysteresis configuration with double # threshold) thresholds: - 20.0 - 25.0 # Same as above, but the threshold is only applied to # ``temperature`` readings thresholds: temperature: - 20.0 - 25.0
- param tolerance:
If set, then the sensor change events will be triggered only if the difference between the new value and the previous value is higher than the specified tolerance. For example, if the sensor data is mapped to a dictionary:
{ "temperature": 0.01, # Tolerance on the 2nd decimal digit "humidity": 0.1 # Tolerance on the 1st decimal digit }
Or, if it’s a raw scalar number:
0.1 # Tolerance on the 1st decimal digit
Or, if it’s a list of values:
[ 0.01, # Tolerance on the 2nd decimal digit for the first value 0.1 # Tolerance on the 1st decimal digit for the second value ]
- param enabled_sensors:
If SystemPlugin.get_measurement returns a key-value mapping, and
enabled_sensors
is set, then only the reported sensor keys will be returned.
Configuration#
system:
# [Optional]
# How often the `RunnablePlugin.loop <https://docs.platypush.tech/platypush/plugins/.html#platypush.plugins.RunnablePlugin.loop>`_ function should be
# executed (default: 15 seconds). *NOTE*: For back-compatibility
# reasons, the `poll_seconds` argument is also supported, but it's
# deprecated.
# poll_interval: 60 # type=Optional[float]
# [Optional]
# A number, numeric pair or mapping of ``str`` to
# number/numeric pair representing the thresholds for the sensor.
#
# Examples:
#
# .. code-block:: yaml
#
# # Any value below 25 from any sensor will trigger a
# # SensorDataBelowThresholdEvent, if the previous value was
# # equal or above, and any value above 25 will trigger a
# # SensorDataAboveThresholdEvent, if the previous value was
# # equal or below
# thresholds: 25.0
#
# # Same as above, but the threshold is only applied to
# # ``temperature`` readings
# thresholds:
# temperature: 25.0
#
# # Any value below 20 from any sensor will trigger a
# # SensorDataBelowThresholdEvent, if the previous value was
# # equal or above, and any value above 25 will trigger a
# # SensorDataAboveThresholdEvent, if the previous value was
# # equal or below (hysteresis configuration with double
# # threshold)
# thresholds:
# - 20.0
# - 25.0
#
# # Same as above, but the threshold is only applied to
# # ``temperature`` readings
# thresholds:
# temperature:
# - 20.0
# - 25.0
# thresholds: # type=Union[float, int, Tuple[Union[float, int], Union[float, int]], Mapping[str, Union[float, int, Tuple[Union[float, int], Union[float, int]]]], NoneType]
# [Optional]
# If set, then the sensor change events will be
# triggered only if the difference between the new value and the
# previous value is higher than the specified tolerance. For example,
# if the sensor data is mapped to a dictionary::
#
# {
# "temperature": 0.01, # Tolerance on the 2nd decimal digit
# "humidity": 0.1 # Tolerance on the 1st decimal digit
# }
#
# Or, if it's a raw scalar number::
#
# 0.1 # Tolerance on the 1st decimal digit
#
# Or, if it's a list of values::
#
# [
# 0.01, # Tolerance on the 2nd decimal digit for the first value
# 0.1 # Tolerance on the 1st decimal digit for the second value
# ]
# tolerance: 0 # type=Union[float, int, Mapping[str, Union[float, int]], Iterable[Union[float, int]]]
# [Optional]
# If `SensorPlugin.get_measurement <https://docs.platypush.tech/platypush/plugins/sensor.html#platypush.plugins.sensor.SensorPlugin.get_measurement>`_ returns a key-value
# mapping, and ``enabled_sensors`` is set, then only the reported
# sensor keys will be returned.
# enabled_sensors: # type=Optional[Iterable[str]]
# [Optional]
# How long we should wait for any running
# threads/processes to stop before exiting (default: 5 seconds).
# stop_timeout: 5 # type=Optional[float]
# [Optional]
# If set to True then the plugin will not monitor
# for new events. This is useful if you want to run a plugin in
# stateless mode and only leverage its actions, without triggering any
# events. Defaults to False.
# disable_monitor: False # type=bool
Dependencies#
pip
pip install psutil py-cpuinfo
Alpine
apk add py3-psutil py3-py-cpuinfo
Debian
apt install python3-psutil python3-cpuinfo
Fedora
yum install python-cpuinfo python-psutil
Arch Linux
pacman -S python-py-cpuinfo python-psutil
Actions#
Module reference#
- class platypush.plugins.system.SystemPlugin(*_, **__)[source]#
Bases:
SensorPlugin
,EntityManager
Plugin to get system info.
- __init__(*args, poll_interval: float | None = 60, **kwargs)[source]#
- Parameters:
thresholds –
A number, numeric pair or mapping of
str
to number/numeric pair representing the thresholds for the sensor.Examples:
# Any value below 25 from any sensor will trigger a # SensorDataBelowThresholdEvent, if the previous value was # equal or above, and any value above 25 will trigger a # SensorDataAboveThresholdEvent, if the previous value was # equal or below thresholds: 25.0 # Same as above, but the threshold is only applied to # ``temperature`` readings thresholds: temperature: 25.0 # Any value below 20 from any sensor will trigger a # SensorDataBelowThresholdEvent, if the previous value was # equal or above, and any value above 25 will trigger a # SensorDataAboveThresholdEvent, if the previous value was # equal or below (hysteresis configuration with double # threshold) thresholds: - 20.0 - 25.0 # Same as above, but the threshold is only applied to # ``temperature`` readings thresholds: temperature: - 20.0 - 25.0
tolerance –
If set, then the sensor change events will be triggered only if the difference between the new value and the previous value is higher than the specified tolerance. For example, if the sensor data is mapped to a dictionary:
{ "temperature": 0.01, # Tolerance on the 2nd decimal digit "humidity": 0.1 # Tolerance on the 1st decimal digit }
Or, if it’s a raw scalar number:
0.1 # Tolerance on the 1st decimal digit
Or, if it’s a list of values:
[ 0.01, # Tolerance on the 2nd decimal digit for the first value 0.1 # Tolerance on the 1st decimal digit for the second value ]
enabled_sensors – If
get_measurement()
returns a key-value mapping, andenabled_sensors
is set, then only the reported sensor keys will be returned.
- connected_users() List[dict] [source]#
Get the list of connected users.
- Returns:
{ "pid": 1234, "started": "2021-01-01T00:00:00+00:00", "terminal": "tty1", "username": "johndoe" }
- cpu_frequency(per_cpu: bool = False) CpuFrequency | List[CpuFrequency] [source]#
Get the CPU frequency, in MHz.
- Parameters:
per_cpu – Get per-CPU stats (default: False).
- Returns:
If
per_cpu=False
:{ "current": 2800000000.0, "max": 2800000000.0, "min": 800000000.0 }
If
per_cpu=True
then a list will be returned, where each item identifies the CPU times of a core:[ { "current": 2800000000.0, "max": 2800000000.0, "min": 800000000.0 } ]
- cpu_percent(per_cpu: bool = False, interval: float | None = None) float | List[float] [source]#
Get the CPU load percentage.
- Parameters:
per_cpu – Get per-CPU stats (default: False).
interval – When interval is 0.0 or None compares system CPU times elapsed since last call or module import, returning immediately (non blocking). That means the first time this is called it will return a meaningless 0.0 value which you should ignore. In this case is recommended for accuracy that this function be called with at least 0.1 seconds between calls.
- Returns:
float if
per_cpu=False
,list[float]
otherwise.
- cpu_stats() CpuStats [source]#
Get CPU stats.
- Returns:
{ "ctx_switches": 1234, "interrupts": 1234, "soft_interrupts": 1234, "syscalls": 1234 }
- cpu_times(per_cpu=False, percent=True) list | dict [source]#
Get the CPU times per status, either as absolute time or a percentage.
- Parameters:
per_cpu – Get per-CPU stats (default: False).
percent – Get the stats in percentage (default: True).
- Returns:
If
per_cpu=False
:{ "guest": 17, "guest_nice": 84, "idle": 68, "iowait": 89, "irq": 16, "nice": 91, "softirq": 13, "steal": 93, "system": 42, "user": 20 }
If
per_cpu=True
then a list will be returned, where each item identifies the CPU times of a core:[ { "guest": 9, "guest_nice": 46, "idle": 93, "iowait": 74, "irq": 56, "nice": 55, "softirq": 39, "steal": 78, "system": 51, "user": 8 } ]
- disk_info()[source]#
Get information about the detected disks and partitions.
- Returns:
[ { "busy_time": 20.5, "device": "/dev/sda1", "free": 1072693248, "fstype": "ext4", "mountpoint": "/mnt/data", "opts": "rw,relatime", "percent": 85, "read_bytes": 1073741824, "read_count": 100, "read_time": 10.5, "total": 1073741824, "used": 1048576, "write_bytes": 1048576, "write_count": 50, "write_time": 5.5 } ]
- get_data(*args, **kwargs)#
(Deprecated) alias for
get_measurement()
- get_measurement(*_, **__)[source]#
- Returns:
{ "battery": { "power_plugged": "Whether the battery is currently plugged in", "seconds_left": 7200, "value": 87 }, "cpu": { "frequency": { "current": 2800000000.0, "max": 2800000000.0, "min": 800000000.0 }, "info": { "architecture": "x86_64", "bits": 64, "brand": "Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz", "cores": 4, "flags": [ "fpu", "vme", "de", "pse", "tsc", "msr", "pae" ], "frequency_actual": 2650000000.0, "frequency_advertised": 2800000000.0, "l1_data_cache_size": 65536, "l1_instruction_cache_size": 65536, "l2_cache_size": 524288, "l3_cache_size": 6291456, "vendor": "GenuineIntel" }, "load_avg": [ 0.0, 0.0, 0.0 ], "percent": 96, "stats": { "ctx_switches": 1234, "interrupts": 1234, "soft_interrupts": 1234, "syscalls": 1234 }, "times": { "guest": 70, "guest_nice": 80, "idle": 27, "iowait": 84, "irq": 66, "nice": 36, "softirq": 50, "steal": 91, "system": 19, "user": 79 } }, "disks": [ { "busy_time": 20.5, "device": "/dev/sda1", "free": 1072693248, "fstype": "ext4", "mountpoint": "/mnt/data", "opts": "rw,relatime", "percent": 56, "read_bytes": 1073741824, "read_count": 100, "read_time": 10.5, "total": 1073741824, "used": 1048576, "write_bytes": 1048576, "write_count": 50, "write_time": 5.5 } ], "fans": [ { "id": "acpi_1", "label": "CPU Fan", "value": 1200 } ], "memory": { "active": 4294967296, "available": 2147483648, "buffers": 2147483648, "cached": 2147483648, "free": 2147483648, "inactive": 2147483648, "percent": 84, "shared": 3221225472, "total": 8589934592, "used": 6442450944 }, "network": [ { "addresses": [ { "address": "192.168.1.4", "broadcast": "192.168.1.255", "family": "AF_INET", "netmask": "255.255.255.0" } ], "bytes_recv": 654321, "bytes_sent": 123456, "drop_in": 1, "drop_out": 2, "duplex": "FULL", "errors_in": 10, "errors_out": 5, "flags": [ "up", "broadcast", "running", "multicast" ], "interface": "eth0", "is_up": true, "mtu": 1500, "packets_recv": 321, "packets_sent": 123, "speed": 1000 } ], "swap": { "free": 2147483648, "percent": 84, "total": 8589934592, "used": 6442450944 }, "temperature": [ { "critical": 100.0, "high": 90.0, "id": "acpi_1", "label": "CPU Temperature", "value": 56.0 } ] }
- load_avg() Tuple[float, float, float] [source]#
Get the average load as a vector that represents the load within the last 1, 5 and 15 minutes.
- main()#
Implementation of the main loop of the plugin.
- mem_swap() dict [source]#
Get the current swap memory usage stats.
- Returns:
{ "free": 2147483648, "percent": 62, "total": 8589934592, "used": 6442450944 }
- mem_virtual() dict [source]#
Get the current virtual memory usage stats.
- Returns:
{ "active": 4294967296, "available": 2147483648, "buffers": 2147483648, "cached": 2147483648, "free": 2147483648, "inactive": 2147483648, "percent": 31, "shared": 3221225472, "total": 8589934592, "used": 6442450944 }
- network_connections(type: str = 'inet') List[dict] [source]#
Get the list of active network connections. On MacOS this function requires root privileges.
- Parameters:
type –
Connection type to filter (default:
inet
). Supported types:type
Description
inet
inet4
inet6
tcp
tcp4
tcp6
udp
udp4
udp6
unix
all
IPv4 and IPv6 IPv4 IPv6 TCP TCP over IPv4 TCP over IPv6 UDP UDP over IPv4 UDP over IPv6 UNIX socket (both UDP and TCP protocols) Any families and protocols
- Returns:
[ { "family": "AF_INET", "fd": 3, "local_address": "192.168.1.3", "local_port": 1234, "pid": 1234, "remote_address": "192.168.1.4", "remote_port": 5678, "status": "ESTABLISHED", "type": "SOCK_STREAM" } ]
- network_info(per_nic: bool = False)[source]#
Get the information and statistics for the network interfaces.
- Parameters:
per_nic – Return the stats grouped by interface (default: False).
- Returns:
If
per_nic=False
:{ "addresses": [ { "address": "192.168.1.4", "broadcast": "192.168.1.255", "family": "AF_INET", "netmask": "255.255.255.0" } ], "bytes_recv": 654321, "bytes_sent": 123456, "drop_in": 1, "drop_out": 2, "duplex": "FULL", "errors_in": 10, "errors_out": 5, "flags": [ "up", "broadcast", "running", "multicast" ], "interface": "eth0", "is_up": true, "mtu": 1500, "packets_recv": 321, "packets_sent": 123, "speed": 1000 }
If
per_nic=True
then a list will be returned, where each item identifies the statistics per network interface:[ { "addresses": [ { "address": "192.168.1.4", "broadcast": "192.168.1.255", "family": "AF_INET", "netmask": "255.255.255.0" } ], "bytes_recv": 654321, "bytes_sent": 123456, "drop_in": 1, "drop_out": 2, "duplex": "FULL", "errors_in": 10, "errors_out": 5, "flags": [ "up", "broadcast", "running", "multicast" ], "interface": "eth0", "is_up": true, "mtu": 1500, "packets_recv": 321, "packets_sent": 123, "speed": 1000 } ]
- pid_exists(pid: int) bool [source]#
- Parameters:
pid – Process PID.
- Returns:
True
if the process exists,False
otherwise.
- processes() List[dict] [source]#
Get the list of running processes.
- Returns:
{ "command_line": [ "python", "script.py" ], "cpu_percent": 85, "current_directory": "/home/user", "memory_percent": 96, "name": "python", "parent_pid": 1000, "pid": 1234, "started": "2021-01-01T00:00:00+00:00", "status": "running", "terminal": "tty1", "username": "root" }
- publish_entities(entities: float | int | Mapping[str, float | int] | Iterable[float | int], *args, **kwargs) Collection[Entity] #
Publishes a list of entities. The downstream consumers include:
The entity persistence manager
The web server
- Any consumer subscribed to
platypush.message.event.entities.EntityUpdateEvent
events (e.g. web clients)
It also accepts an optional callback that will be called when each of the entities in the set is flushed to the database.
You usually don’t need to override this class (but you may want to extend
transform_entities()
instead if your extension doesn’t natively handle Entity objects).
- sensors_battery() dict | None [source]#
Get stats from the battery sensor.
- Returns:
{ "power_plugged": "Whether the battery is currently plugged in", "seconds_left": 7200, "value": 48 }
- sensors_fan() List[dict] [source]#
Get stats from the fan sensors.
- Returns:
[ { "id": "acpi_1", "label": "CPU Fan", "value": 1200 } ]
- sensors_temperature() List[dict] [source]#
Get stats from the temperature sensors.
- Returns:
[ { "critical": 100.0, "high": 90.0, "id": "acpi_1", "label": "CPU Temperature", "value": 56.0 } ]
- start()#
Start the plugin.
- status(*_, **__) float | int | Mapping[str, float | int] | Iterable[float | int] | None #
Returns the latest read values and publishes the
platypush.message.event.entities.EntityUpdateEvent
events if required.
- stop()#
Stop the plugin.
- transform_entities(entities: dict) List[Entity] [source]#
This method takes a list of entities in any (plugin-specific) format and converts them into a standardized collection of Entity objects. Since this method is called by
publish_entities()
before entity updates are published, you may usually want to extend it to pre-process the entities managed by your extension into the standard format before they are stored and published to all the consumers.
- wait(pid: int, timeout: int | None = None)[source]#
Wait for a process to terminate.
- Parameters:
pid – Process PID.
timeout – Timeout in seconds (default:
None
).
- wait_stop(timeout=None)#
Wait until a stop event is received.