diff --git a/modules/core/sensors2.py b/modules/core/sensors2.py new file mode 100644 index 0000000..3bd245a --- /dev/null +++ b/modules/core/sensors2.py @@ -0,0 +1,156 @@ +# -*- coding: UTF-8 -*- + +"""Displays sensor temperature and CPU frequency + +Parameters: + + * sensors2.chip: "sensors -u" compatible filter for chip to display (default to empty - show all chips) + * sensors2.showcpu: Enable or disable CPU frequency display (default: true) + * sensors2.showtemp: Enable or disable temperature display (default: true) + * sensors2.showfan: Enable or disable fan display (default: true) + * sensors2.showother: Enable or display "other" sensor readings (default: false) + * sensors2.showname: Enable or disable show of sensor name (default: false) +""" + +import re + +import bumblebee.util +import bumblebee.output +import bumblebee.engine + +class Module(bumblebee.engine.Module): + def __init__(self, engine, config): + super(Module, self).__init__(engine, config, None) + self._chip = self.parameter("chip", "") + self._data = {} + self._update() + + self.widgets(self._create_widgets()) + + def update(self, widgets): + self._update() + for widget in widgets: + self._update_widget(widget) + + def state(self, widget): + widget_type = widget.get("type", "") + try: + data = self._data[widget.get("adapter")][widget.get("package")][widget.get("field")] + if "crit" in data and float(data["input"]) > float(data["crit"]): + return ["critical", widget_type] + if "max" in data and float(data["input"]) > float(data["max"]): + return ["warning", widget_type] + except: + pass + return [widget_type] + + def _create_widgets(self): + widgets = [] + show_temp = bumblebee.util.asbool(self.parameter("showtemp", "true")) + show_fan = bumblebee.util.asbool(self.parameter("showfan", "true")) + show_other = bumblebee.util.asbool(self.parameter("showother", "false")) + + if bumblebee.util.asbool(self.parameter("showcpu", "true")): + widget = bumblebee.output.Widget(full_text=self._cpu) + widget.set("type", "cpu") + widgets.append(widget) + + for adapter in self._data: + for package in self._data[adapter]: + if bumblebee.util.asbool(self.parameter("showname", "false")): + widget = bumblebee.output.Widget(full_text=package) + widget.set("data", self._data[adapter][package]) + widget.set("package", package) + widget.set("field", "") + widget.set("adapter", adapter) + widgets.append(widget) + for field in self._data[adapter][package]: + widget = bumblebee.output.Widget() + widget.set("package", package) + widget.set("field", field) + widget.set("adapter", adapter) + if "temp" in field and show_temp: + # seems to be a temperature + widget.set("type", "temp") + widgets.append(widget) + if "fan" in field and show_fan: + # seems to be a fan + widget.set("type", "fan") + widgets.append(widget) + elif show_other: + # everything else + widget.set("type", "other") + widgets.append(widget) + return widgets + + def _update_widget(self, widget): + if widget.get("field", "") == "": + return # nothing to do + data = self._data[widget.get("adapter")][widget.get("package")][widget.get("field")] + if "temp" in widget.get("field"): + widget.full_text(u"{:0.01f}°C".format(data["input"])) + elif "fan" in widget.get("field"): + widget.full_text(u"{:0.0f}RPM".format(data["input"])) + else: + widget.full_text(u"{:0.0f}".format(data["input"])) + + def _update(self): + output = bumblebee.util.execute("sensors -u {}".format(self._chip)) + self._data = self._parse(output) + + def _parse(self, data): + output = {} + package = "" + adapter = None + chip = None + for line in data.split("\n"): + if "Adapter" in line: + # new adapter + line = line.replace("Adapter: ", "") + output[chip + " " + line] = {} + adapter = chip + " " + line + chip = line #default - line before adapter is always the chip + if not adapter: continue + key, value = (line.split(":") + ["", ""])[:2] + if not line.startswith(" "): + # assume this starts a new package + if package in output[adapter] and output[adapter][package] == {}: + del output[adapter][package] + output[adapter][key] = {} + package = key + else: + # feature for this chip + try: + name, variant = (key.strip().split("_", 1) + ["",""])[:2] + if not name in output[adapter][package]: + output[adapter][package][name] = { } + if variant: + output[adapter][package][name][variant] = {} + output[adapter][package][name][variant] = float(value) + except Exception as e: + pass + return output + + def _cpu(self, _): + mhz = None + try: + output = open("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq").read() + mhz = int(float(output)/1000.0) + except: + output = open("/proc/cpuinfo").read() + m = re.search(r"cpu MHz\s+:\s+(\d+)", output) + if m: + mhz = int(m.group(1)) + else: + m = re.search(r"BogoMIPS\s+:\s+(\d+)", output) + if m: + return "{} BogoMIPS".format(int(m.group(1))) + if not mhz: + return "n/a" + + if mhz < 1000: + return "{} MHz".format(mhz) + else: + return "{:0.01f} GHz".format(float(mhz)/1000.0) + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4