File: cpu2.py

package info (click to toggle)
bumblebee-status 2.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,844 kB
  • sloc: python: 13,430; sh: 68; makefile: 29
file content (154 lines) | stat: -rw-r--r-- 5,735 bytes parent folder | download | duplicates (2)
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