feat: kitty status bar — CPU temp + battery (hidden when sensor absent)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-10-01 23:26:54 -04:00
parent 98f6a38373
commit bc4cb47a4c
+48 -2
View File
@@ -2,9 +2,11 @@
Flat tab style (no powerline separators) + right-aligned status area. Flat tab style (no powerline separators) + right-aligned status area.
Shows user@ prefix for non-seth users. Shows user@ prefix for non-seth users.
Status: git branch, CPU%, memory, uptime, hostname, clock. Status: git branch, CPU% + temp, memory, uptime, hostname, battery, clock.
Temp and battery hide themselves when the sensor is missing (steel141 has no battery).
""" """
import glob
import os import os
import subprocess import subprocess
from datetime import datetime from datetime import datetime
@@ -29,11 +31,15 @@ _ICON_MEM = "\uf035b"
_ICON_UP = "\uf0aa" _ICON_UP = "\uf0aa"
_ICON_HOST = "\uf108" _ICON_HOST = "\uf108"
_ICON_CLOCK = "\uf017" _ICON_CLOCK = "\uf017"
_ICON_TEMP = "\uf2c9"
_ICON_BAT = "\uf240"
_ICON_CHG = "\uf0e7"
# Colors # Colors
_ORANGE = as_rgb(0xD35400) _ORANGE = as_rgb(0xD35400)
_BLACK = as_rgb(0x000000) _BLACK = as_rgb(0x000000)
_DIM = as_rgb(0x666666) _DIM = as_rgb(0x666666)
_RED = as_rgb(0xFF3030)
_TAB_BG = as_rgb(0x1A1A1A) _TAB_BG = as_rgb(0x1A1A1A)
_BAR_BG = as_rgb(0x0D0D0D) _BAR_BG = as_rgb(0x0D0D0D)
@@ -80,6 +86,39 @@ def _get_cpu_percent() -> str:
return "?" return "?"
# Intel = coretemp, AMD = k10temp; temp1 is the package/Tctl sensor on both.
# hwmon numbers move between boots, so resolve once at kitty start.
_CPU_TEMP = next(
(os.path.join(os.path.dirname(n), "temp1_input")
for n in glob.glob("/sys/class/hwmon/hwmon*/name")
if open(n).read().strip() in ("coretemp", "k10temp")),
None,
)
# BAT* only: mice/keyboards also show up in power_supply as hid*/hidpp_battery*.
_BAT = next(iter(sorted(glob.glob("/sys/class/power_supply/BAT*"))), None)
def _get_cpu_temp() -> str:
try:
with open(_CPU_TEMP) as f:
return f"{int(f.read()) // 1000}\u00b0"
except Exception:
return ""
def _get_battery() -> tuple[str, str, bool]:
"""(icon, '60%', low) or ('', '', False) when there's no battery."""
try:
with open(f"{_BAT}/capacity") as f:
cap = int(f.read())
with open(f"{_BAT}/status") as f:
status = f.read().strip()
except Exception:
return "", "", False
on_ac = status in ("Charging", "Full", "Not charging")
return (_ICON_CHG if on_ac else _ICON_BAT), f"{cap}%", (not on_ac and cap <= 20)
def _get_memory() -> str: def _get_memory() -> str:
try: try:
info = {} info = {}
@@ -160,10 +199,17 @@ def draw_tab(
if branch: if branch:
cells += [(_ICON_BRANCH + " ", _ORANGE), (branch, _DIM), (sep, _DIM)] cells += [(_ICON_BRANCH + " ", _ORANGE), (branch, _DIM), (sep, _DIM)]
cells += [(_ICON_CPU + " ", _ORANGE), (_get_cpu_percent(), _DIM), (sep, _DIM)] cells += [(_ICON_CPU + " ", _ORANGE), (_get_cpu_percent(), _DIM)]
temp = _get_cpu_temp()
if temp:
cells += [(" " + _ICON_TEMP + " ", _ORANGE), (temp, _DIM)]
cells += [(sep, _DIM)]
cells += [(_ICON_MEM + " ", _ORANGE), (_get_memory(), _DIM), (sep, _DIM)] cells += [(_ICON_MEM + " ", _ORANGE), (_get_memory(), _DIM), (sep, _DIM)]
cells += [(_ICON_UP + " ", _ORANGE), (_get_uptime(), _DIM), (sep, _DIM)] cells += [(_ICON_UP + " ", _ORANGE), (_get_uptime(), _DIM), (sep, _DIM)]
cells += [(_ICON_HOST + " ", _ORANGE), (_hostname, _DIM), (sep, _DIM)] cells += [(_ICON_HOST + " ", _ORANGE), (_hostname, _DIM), (sep, _DIM)]
bat_icon, bat, low = _get_battery()
if bat:
cells += [(bat_icon + " ", _RED if low else _ORANGE), (bat, _RED if low else _DIM), (sep, _DIM)]
cells += [(_ICON_CLOCK + " ", _ORANGE), (datetime.now().strftime("%H:%M"), _DIM), (" ", _DIM)] cells += [(_ICON_CLOCK + " ", _ORANGE), (datetime.now().strftime("%H:%M"), _DIM), (" ", _DIM)]
total_len = sum(len(t) for t, _ in cells) total_len = sum(len(t) for t, _ in cells)