mirror of https://github.com/aristocratos/bpytop
Added battery meter and stats
parent
d811c04b3c
commit
f093d793d1
47
bpytop.py
47
bpytop.py
|
@ -181,6 +181,9 @@ net_sync=$net_sync
|
||||||
#* If the network graphs color gradient should scale to bandwith usage or auto scale, bandwith usage is based on "net_download" and "net_upload" values
|
#* If the network graphs color gradient should scale to bandwith usage or auto scale, bandwith usage is based on "net_download" and "net_upload" values
|
||||||
net_color_fixed=$net_color_fixed
|
net_color_fixed=$net_color_fixed
|
||||||
|
|
||||||
|
#* Show battery stats in top right if battery is present
|
||||||
|
show_battery=$show_battery
|
||||||
|
|
||||||
#* Show init screen at startup, the init screen is purely cosmetical
|
#* Show init screen at startup, the init screen is purely cosmetical
|
||||||
show_init=$show_init
|
show_init=$show_init
|
||||||
|
|
||||||
|
@ -361,7 +364,8 @@ class Config:
|
||||||
'''Holds all config variables and functions for loading from and saving to disk'''
|
'''Holds all config variables and functions for loading from and saving to disk'''
|
||||||
keys: List[str] = ["color_theme", "update_ms", "proc_sorting", "proc_reversed", "proc_tree", "check_temp", "draw_clock", "background_update", "custom_cpu_name",
|
keys: List[str] = ["color_theme", "update_ms", "proc_sorting", "proc_reversed", "proc_tree", "check_temp", "draw_clock", "background_update", "custom_cpu_name",
|
||||||
"proc_colors", "proc_gradient", "proc_per_core", "proc_mem_bytes", "disks_filter", "update_check", "log_level", "mem_graphs", "show_swap",
|
"proc_colors", "proc_gradient", "proc_per_core", "proc_mem_bytes", "disks_filter", "update_check", "log_level", "mem_graphs", "show_swap",
|
||||||
"swap_disk", "show_disks", "net_download", "net_upload", "net_auto", "net_color_fixed", "show_init", "view_mode", "theme_background", "net_sync"]
|
"swap_disk", "show_disks", "net_download", "net_upload", "net_auto", "net_color_fixed", "show_init", "view_mode", "theme_background",
|
||||||
|
"net_sync", "show_battery"]
|
||||||
conf_dict: Dict[str, Union[str, int, bool]] = {}
|
conf_dict: Dict[str, Union[str, int, bool]] = {}
|
||||||
color_theme: str = "Default"
|
color_theme: str = "Default"
|
||||||
theme_background: bool = True
|
theme_background: bool = True
|
||||||
|
@ -388,6 +392,7 @@ class Config:
|
||||||
net_color_fixed: bool = False
|
net_color_fixed: bool = False
|
||||||
net_auto: bool = True
|
net_auto: bool = True
|
||||||
net_sync: bool = False
|
net_sync: bool = False
|
||||||
|
show_battery: bool = True
|
||||||
show_init: bool = True
|
show_init: bool = True
|
||||||
view_mode: str = "full"
|
view_mode: str = "full"
|
||||||
log_level: str = "WARNING"
|
log_level: str = "WARNING"
|
||||||
|
@ -1419,14 +1424,16 @@ class Meter:
|
||||||
color_inactive: Color
|
color_inactive: Color
|
||||||
gradient_name: str
|
gradient_name: str
|
||||||
width: int
|
width: int
|
||||||
|
invert: bool
|
||||||
saved: Dict[int, str]
|
saved: Dict[int, str]
|
||||||
|
|
||||||
def __init__(self, value: int, width: int, gradient_name: str):
|
def __init__(self, value: int, width: int, gradient_name: str, invert: bool = False):
|
||||||
self.gradient_name = gradient_name
|
self.gradient_name = gradient_name
|
||||||
self.color_gradient = THEME.gradient[gradient_name]
|
self.color_gradient = THEME.gradient[gradient_name]
|
||||||
self.color_inactive = THEME.meter_bg
|
self.color_inactive = THEME.meter_bg
|
||||||
self.width = width
|
self.width = width
|
||||||
self.saved = {}
|
self.saved = {}
|
||||||
|
self.invert = invert
|
||||||
self.out = self._create(value)
|
self.out = self._create(value)
|
||||||
|
|
||||||
def __call__(self, value: Union[int, None]) -> str:
|
def __call__(self, value: Union[int, None]) -> str:
|
||||||
|
@ -1451,7 +1458,7 @@ class Meter:
|
||||||
out: str = ""
|
out: str = ""
|
||||||
for i in range(1, self.width + 1):
|
for i in range(1, self.width + 1):
|
||||||
if value >= round(i * 100 / self.width):
|
if value >= round(i * 100 / self.width):
|
||||||
out += f'{self.color_gradient[round(i * 100 / self.width)]}{Symbol.meter}'
|
out += f'{self.color_gradient[round(i * 100 / self.width) if not self.invert else round(100 - (i * 100 / self.width))]}{Symbol.meter}'
|
||||||
else:
|
else:
|
||||||
out += self.color_inactive(Symbol.meter * (self.width + 1 - i))
|
out += self.color_inactive(Symbol.meter * (self.width + 1 - i))
|
||||||
break
|
break
|
||||||
|
@ -1463,6 +1470,7 @@ class Meter:
|
||||||
|
|
||||||
class Meters:
|
class Meters:
|
||||||
cpu: Meter
|
cpu: Meter
|
||||||
|
battery: Meter
|
||||||
mem: Dict[str, Union[Meter, Graph]] = {}
|
mem: Dict[str, Union[Meter, Graph]] = {}
|
||||||
swap: Dict[str, Union[Meter, Graph]] = {}
|
swap: Dict[str, Union[Meter, Graph]] = {}
|
||||||
disks_used: Dict[str, Meter] = {}
|
disks_used: Dict[str, Meter] = {}
|
||||||
|
@ -1506,7 +1514,12 @@ class Box:
|
||||||
Draw.buffer("update_ms!" if now and not Menu.active else "update_ms",
|
Draw.buffer("update_ms!" if now and not Menu.active else "update_ms",
|
||||||
f'{Mv.to(CpuBox.y, xpos)}{THEME.cpu_box(Symbol.h_line * 7, Symbol.title_left)}{Fx.b}{THEME.hi_fg("+")} ',
|
f'{Mv.to(CpuBox.y, xpos)}{THEME.cpu_box(Symbol.h_line * 7, Symbol.title_left)}{Fx.b}{THEME.hi_fg("+")} ',
|
||||||
f'{THEME.title(update_string)} {THEME.hi_fg("-")}{Fx.ub}{THEME.cpu_box(Symbol.title_right)}', only_save=Menu.active, once=True)
|
f'{THEME.title(update_string)} {THEME.hi_fg("-")}{Fx.ub}{THEME.cpu_box(Symbol.title_right)}', only_save=Menu.active, once=True)
|
||||||
if now and not Menu.active: Draw.clear("update_ms")
|
if now and not Menu.active:
|
||||||
|
Draw.clear("update_ms")
|
||||||
|
if CONFIG.show_battery and CpuBox.battery_present:
|
||||||
|
CpuBox.redraw = True
|
||||||
|
CpuBox._draw_fg()
|
||||||
|
Draw.out("cpu")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def draw_clock(cls, force: bool = False):
|
def draw_clock(cls, force: bool = False):
|
||||||
|
@ -1543,6 +1556,9 @@ class CpuBox(Box, SubBox):
|
||||||
resized: bool = True
|
resized: bool = True
|
||||||
redraw: bool = False
|
redraw: bool = False
|
||||||
buffer: str = "cpu"
|
buffer: str = "cpu"
|
||||||
|
battery_percent: int = 1000
|
||||||
|
old_battery_pos = 0
|
||||||
|
battery_present: bool = True if hasattr(psutil, "sensors_battery") and psutil.sensors_battery() else False
|
||||||
clock_block: bool = True
|
clock_block: bool = True
|
||||||
Box.buffers.append(buffer)
|
Box.buffers.append(buffer)
|
||||||
|
|
||||||
|
@ -1613,6 +1629,24 @@ class CpuBox(Box, SubBox):
|
||||||
Graphs.temps[n] = Graph(5, 1, None, cpu.cpu_temp[n], max_value=cpu.cpu_temp_crit, offset=-23)
|
Graphs.temps[n] = Graph(5, 1, None, cpu.cpu_temp[n], max_value=cpu.cpu_temp_crit, offset=-23)
|
||||||
Draw.buffer("cpu_misc", out_misc, only_save=True)
|
Draw.buffer("cpu_misc", out_misc, only_save=True)
|
||||||
|
|
||||||
|
if CONFIG.show_battery and cls.battery_present and psutil.sensors_battery().percent != cls.battery_percent:
|
||||||
|
if isinstance(psutil.sensors_battery().secsleft, int):
|
||||||
|
battery_secs: int = psutil.sensors_battery().secsleft
|
||||||
|
else:
|
||||||
|
battery_secs = 0
|
||||||
|
cls.battery_percent = psutil.sensors_battery().percent
|
||||||
|
if not hasattr(Meters, "battery") or cls.resized:
|
||||||
|
Meters.battery = Meter(cls.battery_percent, 10, "cpu", invert=True)
|
||||||
|
battery_symbol: str = "▼" if not psutil.sensors_battery().power_plugged else "▲"
|
||||||
|
battery_pos = cls.width - len(f'{CONFIG.update_ms}') - 17 - (11 if cls.width >= 100 else 0) - (6 if battery_secs else 0) - len(f'{cls.battery_percent}')
|
||||||
|
if battery_pos != cls.old_battery_pos and cls.old_battery_pos > 0 and not cls.resized:
|
||||||
|
out += f'{Mv.to(y-1, cls.old_battery_pos)}{THEME.cpu_box(Symbol.h_line*(15 if cls.width >= 100 else 5))}'
|
||||||
|
cls.old_battery_pos = battery_pos
|
||||||
|
out += (f'{Mv.to(y-1, battery_pos)}{THEME.cpu_box(Symbol.title_left)}{Fx.b}{THEME.title}BAT{battery_symbol} {cls.battery_percent}%'+
|
||||||
|
("" if cls.width < 100 else f' {Fx.ub}{Meters.battery(cls.battery_percent)}{Fx.b}') +
|
||||||
|
("" if not battery_secs else f' {THEME.title}{battery_secs // 3600:02}:{(battery_secs % 3600) // 60:02}') +
|
||||||
|
f'{Fx.ub}{THEME.cpu_box(Symbol.title_right)}')
|
||||||
|
|
||||||
cx = cy = cc = 0
|
cx = cy = cc = 0
|
||||||
ccw = (bw + 1) // cls.box_columns
|
ccw = (bw + 1) // cls.box_columns
|
||||||
if cpu.cpu_freq:
|
if cpu.cpu_freq:
|
||||||
|
@ -3752,6 +3786,11 @@ class Menu:
|
||||||
'The bandwidth usage is based on the',
|
'The bandwidth usage is based on the',
|
||||||
'"net_download" and "net_upload" values set',
|
'"net_download" and "net_upload" values set',
|
||||||
'above.'],
|
'above.'],
|
||||||
|
"show_battery" : [
|
||||||
|
'Show battery stats.',
|
||||||
|
'',
|
||||||
|
'Show battery stats in the top right corner',
|
||||||
|
'if a battery is present.'],
|
||||||
"show_init" : [
|
"show_init" : [
|
||||||
'Show init screen at startup.',
|
'Show init screen at startup.',
|
||||||
'',
|
'',
|
||||||
|
|
Loading…
Reference in New Issue