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 155 156 157 158
|
"""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:
* cpu3.layout: Space-separated list of widgets to add.
Possible widgets are:
* cpu3.maxfreq
* cpu3.cpuload
* cpu3.coresload
* cpu3.temp
* cpu3.fanspeed
* cpu3.colored: 1 for colored per core load graph, 0 for mono (default)
* cpu3.temp_json: json path to look for in the output of 'sensors -j';
required if cpu3.temp widget is used
* cpu3.fan_json: json path to look for in the output of 'sensors -j';
required if cpu3.fanspeed widget is used
Note: if you are getting 'n/a' for CPU temperature / fan speed, then you're
lacking the aforementioned json path settings or they have wrong values.
Example json paths:
* `cpu3.temp_json="coretemp-isa-0000.Package id 0.temp1_input"`
* `cpu3.fan_json="thinkpad-isa-0000.fan1.fan1_input"`
contributed by `SuperQ <https://github.com/SuperQ>`
based on cpu2 by `<somospocos <https://github.com/somospocos>`
"""
import json
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", "cpu3.maxfreq cpu3.cpuload cpu3.coresload cpu3.temp cpu3.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 == "cpu3.maxfreq":
widget = self.add_widget(name=widget_name, full_text=self.maxfreq)
widget.set("type", "freq")
elif widget_name == "cpu3.cpuload":
widget = self.add_widget(name=widget_name, full_text=self.cpuload)
widget.set("type", "load")
elif widget_name == "cpu3.coresload":
widget = self.add_widget(name=widget_name, full_text=self.coresload)
widget.set("type", "loads")
elif widget_name == "cpu3.temp":
widget = self.add_widget(name=widget_name, full_text=self.temp)
widget.set("type", "temp")
elif widget_name == "cpu3.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_json = self.parameter("temp_json")
if self.__temp_json is None:
self.__temp = "n/a"
self.__fan_json = self.parameter("fan_json")
if self.__fan_json is None:
self.__fan = "n/a"
# maxfreq is loaded only once at startup
if "cpu3.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 -j")
json_data = json.loads(output)
temp = "n/a"
fan = "n/a"
temp_json = json_data
fan_json = json_data
for path in self.__temp_json.split('.'):
temp_json = temp_json[path]
for path in self.__fan_json.split('.'):
fan_json = fan_json[path]
if temp_json is not None:
temp = float(temp_json)
if fan_json is not None:
fan = int(fan_json)
return temp, fan
def update(self):
if "cpu3.maxfreq" in self.__widget_names:
self.__maxfreq = psutil.cpu_freq().max / 1000
if "cpu3.cpuload" in self.__widget_names:
self.__cpuload = round(psutil.cpu_percent(percpu=False))
if "cpu3.coresload" in self.__widget_names:
self.__coresload = psutil.cpu_percent(percpu=True)
if "cpu3.temp" in self.__widget_names or "cpu3.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
|