Source code for libqtile.widget.nvidia_sensors

import csv
import re

from libqtile.widget import base

sensors_mapping = {
    "fan_speed": "fan.speed",
    "perf": "pstate",
    "temp": "temperature.gpu",
}


def _all_sensors_names_correct(sensors):
    return all(map(lambda x: x in sensors_mapping, sensors))


[docs]class NvidiaSensors(base.ThreadPoolText): """Displays temperature, fan speed and performance level Nvidia GPU.""" defaults = [ ( "format", "{temp}°C", "Display string format. Three options available: " "``{temp}`` - temperature, ``{fan_speed}`` and ``{perf}`` - " "performance level", ), ("foreground_alert", "ff0000", "Foreground colour alert"), ( "gpu_bus_id", "", "GPU's Bus ID, ex: ``01:00.0``. If leave empty will display all " "available GPU's", ), ("update_interval", 2, "Update interval in seconds."), ( "threshold", 70, "If the current temperature value is above, " "then change to foreground_alert colour", ), ] def __init__(self, **config): base.ThreadPoolText.__init__(self, "", **config) self.add_defaults(NvidiaSensors.defaults) self.foreground_normal = self.foreground def _get_sensors_data(self, command): return csv.reader( self.call_process(command, shell=True).strip().replace(" ", "").split("\n") ) def _parse_format_string(self): return {sensor for sensor in re.findall("{(.+?)}", self.format)} def poll(self): sensors = self._parse_format_string() if not _all_sensors_names_correct(sensors): return "Wrong sensor name" bus_id = f"-i {self.gpu_bus_id}" if self.gpu_bus_id else "" command = "nvidia-smi {} --query-gpu={} --format=csv,noheader".format( bus_id, ",".join(sensors_mapping[sensor] for sensor in sensors) ) try: sensors_data = [dict(zip(sensors, gpu)) for gpu in self._get_sensors_data(command)] for gpu in sensors_data: if gpu.get("temp"): if int(gpu["temp"]) > self.threshold: self.foreground = self.foreground_alert else: self.foreground = self.foreground_normal return " - ".join([self.format.format(**gpu) for gpu in sensors_data]) except Exception: return None