1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
"""Multiwidget CPU module
Can display any combination of:
* max CPU frequency
* total CPU load in percents (integer value)
* per-core CPU load as graph - either mono or colored
* CPU temperature (in Celsius degrees)
* CPU fan speed
Requirements:
* the psutil Python module for the first three items from the list above
* sensors executable for the rest
Parameters:
* cpu2.layout: Space-separated list of widgets to add.
Possible widgets are:
* cpu2.maxfreq
* cpu2.cpuload
* cpu2.coresload
* cpu2.temp
* cpu2.fanspeed
* cpu2.colored: 1 for colored per core load graph, 0 for mono (default)
* cpu2.temp_pattern: pattern to look for in the output of 'sensors -u';
required if cpu2.temp widget is used
* cpu2.fan_pattern: pattern to look for in the output of 'sensors -u';
required if cpu2.fanspeed widget is used
Note: if you are getting 'n/a' for CPU temperature / fan speed, then you're
lacking the aforementioned pattern settings or they have wrong values.
contributed by `somospocos <https://github.com/somospocos>`_ - many thanks!
"""
import psutil
import core.module
import util.cli
import util.graph
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, [])
self.__layout = self.parameter(
"layout", "cpu2.maxfreq cpu2.cpuload cpu2.coresload cpu2.temp cpu2.fanspeed"
)
self.__widget_names = self.__layout.split()
self.__colored = util.format.asbool(self.parameter("colored", False))
for widget_name in self.__widget_names:
if widget_name == "cpu2.maxfreq":
widget = self.add_widget(name=widget_name, full_text=self.maxfreq)
widget.set("type", "freq")
elif widget_name == "cpu2.cpuload":
widget = self.add_widget(name=widget_name, full_text=self.cpuload)
widget.set("type", "load")
elif widget_name == "cpu2.coresload":
widget = self.add_widget(name=widget_name, full_text=self.coresload)
widget.set("type", "loads")
elif widget_name == "cpu2.temp":
widget = self.add_widget(name=widget_name, full_text=self.temp)
widget.set("type", "temp")
elif widget_name == "cpu2.fanspeed":
widget = self.add_widget(name=widget_name, full_text=self.fanspeed)
widget.set("type", "fan")
if self.__colored:
widget.set("pango", True)
self.__temp_pattern = self.parameter("temp_pattern")
if self.__temp_pattern is None:
self.__temp = "n/a"
self.__fan_pattern = self.parameter("fan_pattern")
if self.__fan_pattern is None:
self.__fan = "n/a"
# maxfreq is loaded only once at startup
if "cpu2.maxfreq" in self.__widget_names:
self.__maxfreq = psutil.cpu_freq().max / 1000
def maxfreq(self, _):
return "{:.2f}GHz".format(self.__maxfreq)
def cpuload(self, _):
return "{:>3}%".format(self.__cpuload)
def add_color(self, bar):
"""add color as pango markup to a bar"""
if bar in ["▁", "▂"]:
color = self.theme.color("green", "green")
elif bar in ["▃", "▄"]:
color = self.theme.color("yellow", "yellow")
elif bar in ["▅", "▆"]:
color = self.theme.color("orange", "orange")
elif bar in ["▇", "█"]:
color = self.theme.color("red", "red")
colored_bar = '<span foreground="{}">{}</span>'.format(color, bar)
return colored_bar
def coresload(self, _):
mono_bars = [util.graph.hbar(x) for x in self.__coresload]
if not self.__colored:
return "".join(mono_bars)
colored_bars = [self.add_color(x) for x in mono_bars]
return "".join(colored_bars)
def temp(self, _):
if self.__temp == "n/a" or self.__temp == 0:
return "n/a"
return "{}°C".format(self.__temp)
def fanspeed(self, _):
if self.__fanspeed == "n/a":
return "n/a"
return "{}RPM".format(self.__fanspeed)
def _parse_sensors_output(self):
output = util.cli.execute("sensors -u")
lines = output.split("\n")
temp = "n/a"
fan = "n/a"
temp_line = None
fan_line = None
for line in lines:
if self.__temp_pattern is not None and self.__temp_pattern in line:
temp_line = line
if self.__fan_pattern is not None and self.__fan_pattern in line:
fan_line = line
if temp_line is not None and fan_line is not None:
break
if temp_line is not None:
temp = round(float(temp_line.split(":")[1].strip()))
if fan_line is not None:
fan = int(fan_line.split(":")[1].strip()[:-4])
return temp, fan
def update(self):
if "cpu2.maxfreq" in self.__widget_names:
self.__maxfreq = psutil.cpu_freq().max / 1000
if "cpu2.cpuload" in self.__widget_names:
self.__cpuload = round(psutil.cpu_percent(percpu=False))
if "cpu2.coresload" in self.__widget_names:
self.__coresload = psutil.cpu_percent(percpu=True)
if "cpu2.temp" in self.__widget_names or "cpu2.fanspeed" in self.__widget_names:
self.__temp, self.__fanspeed = self._parse_sensors_output()
def state(self, widget):
"""for having per-widget icons"""
return [widget.get("type", "")]
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|