summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraristocratos <gnmjpl@gmail.com>2021-02-21 13:35:54 +0100
committeraristocratos <gnmjpl@gmail.com>2021-02-21 13:35:54 +0100
commit2318f506d4127c45d3eea4e24543e4b41b885938 (patch)
tree6a3b701849008a893de06e19d687415476589e69
parent57778eee034f41b97af09148271db7ebbb77d6d3 (diff)
Added: Options for choosing temperature scale and readded support for negative celsius temps
-rwxr-xr-xbpytop.py73
1 files changed, 61 insertions, 12 deletions
diff --git a/bpytop.py b/bpytop.py
index d935601..51ecbd4 100755
--- a/bpytop.py
+++ b/bpytop.py
@@ -161,6 +161,9 @@ cpu_sensor=$cpu_sensor
#* Show temperatures for cpu cores also if check_temp is True and sensors has been found
show_coretemp=$show_coretemp
+#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine"
+temp_scale="$temp_scale"
+
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable.
draw_clock="$draw_clock"
@@ -405,7 +408,7 @@ class Config:
"swap_disk", "show_disks", "use_fstab", "net_download", "net_upload", "net_auto", "net_color_fixed", "show_init", "theme_background",
"net_sync", "show_battery", "tree_depth", "cpu_sensor", "show_coretemp", "proc_update_mult", "shown_boxes", "net_iface", "only_physical",
"truecolor", "io_mode", "io_graph_combined", "io_graph_speeds", "show_io_stat", "cpu_graph_upper", "cpu_graph_lower", "cpu_invert_lower",
- "cpu_single_graph", "show_uptime"]
+ "cpu_single_graph", "show_uptime", "temp_scale"]
conf_dict: Dict[str, Union[str, int, bool]] = {}
color_theme: str = "Default"
theme_background: bool = True
@@ -429,6 +432,7 @@ class Config:
check_temp: bool = True
cpu_sensor: str = "Auto"
show_coretemp: bool = True
+ temp_scale: str = "celsius"
draw_clock: str = "%X"
background_update: bool = True
custom_cpu_name: str = ""
@@ -461,6 +465,7 @@ class Config:
log_levels: List[str] = ["ERROR", "WARNING", "INFO", "DEBUG"]
cpu_percent_fields: List = ["total"]
cpu_percent_fields.extend(getattr(psutil.cpu_times_percent(), "_fields", []))
+ temp_scales: List[str] = ["celsius", "fahrenheit", "kelvin", "rankine"]
cpu_sensors: List[str] = [ "Auto" ]
@@ -567,6 +572,9 @@ class Config:
if cpu_graph in new_config and not new_config[cpu_graph] in self.cpu_percent_fields:
new_config[cpu_graph] = "_error_"
self.warnings.append(f'Config key "{cpu_graph}" does not contain an available cpu stat attribute!')
+ if "temp_scale" in new_config and not new_config["temp_scale"] in self.temp_scales:
+ new_config["temp_scale"] = "_error_"
+ self.warnings.append(f'Config key "temp_scale" does not contain a recognized temperature scale!')
return new_config
def save_config(self):
@@ -1449,7 +1457,7 @@ class Graph:
if max_value:
self.lowest = 1 if self.round_up_low else 0
self.max_value = max_value
- data = [ min_max((v + offset) * 100 // (max_value + offset), self.lowest, 100) for v in data ] #* Convert values to percentage values of max_value with max_value as ceiling
+ data = [ min_max((v + offset) * 100 // (max_value + offset), min_max(v + offset, 0, self.lowest), 100) for v in data ] #* Convert values to percentage values of max_value with max_value as ceiling
else:
self.max_value = 0
if color_max_value:
@@ -1533,7 +1541,7 @@ class Graph:
else:
for n in range(self.height):
self.graphs[self.current][n] = self.graphs[self.current][n][1:]
- if self.max_value: value = min_max((value + self.offset) * 100 // (self.max_value + self.offset), self.lowest, 100)
+ if self.max_value: value = min_max((value + self.offset) * 100 // (self.max_value + self.offset), min_max(value + self.offset, 0, self.lowest), 100)
self._create([value])
return self.out
@@ -1865,6 +1873,8 @@ class CpuBox(Box, SubBox):
hh: int = ceil(h / 2)
hh2: int = h - hh
mid_line: bool = False
+ temp: int = 0
+ unit: str = ""
if not CONFIG.cpu_single_graph and CONFIG.cpu_graph_upper != CONFIG.cpu_graph_lower:
mid_line = True
if h % 2: hh = floor(h / 2)
@@ -1937,8 +1947,9 @@ class CpuBox(Box, SubBox):
f'{THEME.gradient["cpu"][cpu.cpu_usage[0][-1]]}{cpu.cpu_usage[0][-1]:>4}{THEME.main_fg}%')
if cpu.got_sensors:
try:
+ temp, unit = temperature(cpu.cpu_temp[0][-1], CONFIG.temp_scale)
out += (f'{THEME.inactive_fg} ⡀⡀⡀⡀⡀{Mv.l(5)}{THEME.gradient["temp"][min_max(cpu.cpu_temp[0][-1], 0, cpu.cpu_temp_crit) * 100 // cpu.cpu_temp_crit]}{Graphs.temps[0](None if cls.resized else cpu.cpu_temp[0][-1])}'
- f'{cpu.cpu_temp[0][-1]:>4}{THEME.main_fg}°C')
+ f'{temp:>4}{THEME.main_fg}{unit}')
except:
cpu.got_sensors = False
@@ -1952,11 +1963,12 @@ class CpuBox(Box, SubBox):
out += f'{cpu.cpu_usage[n][-1]:>{3 if cls.column_size < 2 else 4}}{THEME.main_fg}%'
if cpu.got_sensors and cpu.cpu_temp[n] and not hide_cores:
try:
+ temp, unit = temperature(cpu.cpu_temp[n][-1], CONFIG.temp_scale)
if cls.column_size > 1:
- out += f'{THEME.inactive_fg} ⡀⡀⡀⡀⡀{Mv.l(5)}{THEME.gradient["temp"][100 if cpu.cpu_temp[n][-1] >= cpu.cpu_temp_crit else (cpu.cpu_temp[n][-1] * 100 // cpu.cpu_temp_crit)]}{Graphs.temps[n](None if cls.resized else cpu.cpu_temp[n][-1])}'
+ out += f'{THEME.inactive_fg} ⡀⡀⡀⡀⡀{Mv.l(5)}{THEME.gradient["temp"][min_max(cpu.cpu_temp[n][-1], 0, cpu.cpu_temp_crit) * 100 // cpu.cpu_temp_crit]}{Graphs.temps[n](None if cls.resized else cpu.cpu_temp[n][-1])}'
else:
- out += f'{THEME.gradient["temp"][100 if cpu.cpu_temp[n][-1] >= cpu.cpu_temp_crit else (cpu.cpu_temp[n][-1] * 100 // cpu.cpu_temp_crit)]}'
- out += f'{cpu.cpu_temp[n][-1]:>4}{THEME.main_fg}°C'
+ out += f'{THEME.gradient["temp"][min_max(temp, 0, cpu.cpu_temp_crit) * 100 // cpu.cpu_temp_crit]}'
+ out += f'{temp:>4}{THEME.main_fg}{unit}'
except:
cpu.got_sensors = False
elif cpu.got_sensors and not hide_cores:
@@ -3062,7 +3074,7 @@ class CpuCollector(Collector):
s_name, s_label = CONFIG.cpu_sensor.split(":", 1)
for name, entries in psutil.sensors_temperatures().items():
for num, entry in enumerate(entries, 1):
- if name == s_name and (entry.label == s_label or str(num) == s_label) and round(entry.current) > 0:
+ if name == s_name and (entry.label == s_label or str(num) == s_label):
if entry.label.startswith("Package"):
cpu_type = "intel"
elif entry.label.startswith("Tdie"):
@@ -3074,7 +3086,7 @@ class CpuCollector(Collector):
if getattr(entry, "critical", None) != None and entry.critical > 1: cls.cpu_temp_crit = round(entry.critical)
else: cls.cpu_temp_crit = 95
temp = round(entry.current)
- elif entry.label.startswith(("Package", "Tdie")) and cpu_type in ["", "other"] and s_name == "_-_" and hasattr(entry, "current") and round(entry.current) > 0:
+ elif entry.label.startswith(("Package", "Tdie")) and cpu_type in ["", "other"] and s_name == "_-_" and hasattr(entry, "current"):
if not cls.cpu_temp_high or cls.sensor_swap or cpu_type == "other":
cls.sensor_swap = False
if getattr(entry, "high", None) != None and entry.high > 1: cls.cpu_temp_high = round(entry.high)
@@ -3083,7 +3095,7 @@ class CpuCollector(Collector):
else: cls.cpu_temp_crit = 95
cpu_type = "intel" if entry.label.startswith("Package") else "ryzen"
temp = round(entry.current)
- elif (entry.label.startswith(("Core", "Tccd", "CPU")) or (name.lower().startswith("cpu") and not entry.label)) and hasattr(entry, "current") and round(entry.current) > 0:
+ elif (entry.label.startswith(("Core", "Tccd", "CPU")) or (name.lower().startswith("cpu") and not entry.label)) and hasattr(entry, "current"):
if entry.label.startswith(("Core", "Tccd")):
entry_int = int(entry.label.replace("Core", "").replace("Tccd", ""))
if entry_int in core_dict and cpu_type != "ryzen":
@@ -4368,7 +4380,18 @@ class Menu:
'',
'Only works if check_temp is True and',
'the system is reporting core temps.'],
-
+ "temp_scale" : [
+ 'Which temperature scale to use.',
+ '',
+ 'Celsius, default scale.',
+ '',
+ 'Fahrenheit, the american one.',
+ '',
+ 'Kelvin, 0 = absolute zero, 1 degree change',
+ 'equals 1 degree change in Celsius.',
+ '',
+ 'Rankine, 0 = abosulte zero, 1 degree change',
+ 'equals 1 degree change in Fahrenheit.'],
"custom_cpu_name" : [
'Custom cpu model name in cpu percentage box.',
'',
@@ -4572,6 +4595,7 @@ class Menu:
cpu_sensor_i: int = CONFIG.cpu_sensors.index(CONFIG.cpu_sensor)
cpu_graph_i: Dict[str, int] = { "cpu_graph_upper" : CONFIG.cpu_percent_fields.index(CONFIG.cpu_graph_upper),
"cpu_graph_lower" : CONFIG.cpu_percent_fields.index(CONFIG.cpu_graph_lower)}
+ temp_scale_i: int = CONFIG.temp_scales.index(CONFIG.temp_scale)
color_i: int
max_opt_len: int = max([len(categories[x]) for x in categories]) * 2
cat_list = list(categories)
@@ -4635,11 +4659,13 @@ class Menu:
counter = f' {cpu_sensor_i + 1}/{len(CONFIG.cpu_sensors)}'
elif opt in ["cpu_graph_upper", "cpu_graph_lower"]:
counter = f' {cpu_graph_i[opt] + 1}/{len(CONFIG.cpu_percent_fields)}'
+ elif opt == "temp_scale":
+ counter = f' {temp_scale_i + 1}/{len(CONFIG.temp_scales)}'
else:
counter = ""
out += f'{Mv.to(y+1+cy, x+1)}{t_color}{Fx.b}{opt.replace("_", " ").capitalize() + counter:^24.24}{Fx.ub}{Mv.to(y+2+cy, x+1)}{v_color}'
if opt == selected:
- if isinstance(value, bool) or opt in ["color_theme", "proc_sorting", "log_level", "cpu_sensor", "cpu_graph_upper", "cpu_graph_lower"]:
+ if isinstance(value, bool) or opt in ["color_theme", "proc_sorting", "log_level", "cpu_sensor", "cpu_graph_upper", "cpu_graph_lower", "temp_scale"]:
out += f'{t_color} {Symbol.left}{v_color}{d_quote + str(value) + d_quote:^20.20}{t_color}{Symbol.right} '
elif inputting:
out += f'{str(input_val)[-17:] + Fx.bl + "█" + Fx.ubl + "" + Symbol.enter:^33.33}'
@@ -4849,6 +4875,16 @@ class Menu:
setattr(CpuCollector, selected.replace("_graph", ""), [])
Term.refresh(force=True)
cls.resized = False
+ elif key in ["left", "right"] and selected == "temp_scale":
+ if key == "left":
+ temp_scale_i -= 1
+ if temp_scale_i < 0: temp_scale_i = len(CONFIG.temp_scales) - 1
+ if key == "right":
+ temp_scale_i += 1
+ if temp_scale_i > len(CONFIG.temp_scales) - 1: temp_scale_i = 0
+ CONFIG.temp_scale = CONFIG.temp_scales[temp_scale_i]
+ Term.refresh(force=True)
+ cls.resized = False
elif key in ["left", "right"] and selected == "cpu_sensor" and len(CONFIG.cpu_sensors) > 1:
if key == "left":
cpu_sensor_i -= 1
@@ -5277,6 +5313,19 @@ def readfile(file: str, default: str = "") -> str:
pass
return default if out is None else out
+def temperature(value: int, scale: str = "celsius") -> Tuple[int, str]:
+ """Returns a tuple with integer value and string unit converted from an integer in celsius to: celsius, fahrenheit, kelvin or rankine."""
+ if scale == "celsius":
+ return (value, "°C")
+ elif scale == "fahrenheit":
+ return (round(value * 1.8 + 32), "°F")
+ elif scale == "kelvin":
+ return (round(value + 273.15), "°K")
+ elif scale == "rankine":
+ return (round(value * 1.8 + 491.67), "°R")
+ else:
+ return (0, "")
+
def process_keys():
mouse_pos: Tuple[int, int] = (0, 0)
filtered: bool = False