diff options
| author | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-27 01:55:13 +0530 |
|---|---|---|
| committer | Arpit Chakladar <arpitchakladar+git@gmail.com> | 2026-08-29 03:50:30 +0530 |
| commit | 9a6f21b65da927fb064773bd83e92151c50b6823 (patch) | |
| tree | 897de5d11ba347529e0f16fe554eac0d5d908fd1 /modules/desktop/eww/system-stats.py | |
| parent | f3407d3d21c29eb4a59732d02f8f309b113fa480 (diff) | |
| download | home-manager-config-9a6f21b65da927fb064773bd83e92151c50b6823.tar.gz home-manager-config-9a6f21b65da927fb064773bd83e92151c50b6823.zip | |
desktop: added some of basic system information in the system section
- added date, time, memory used (percent), cpu usage (percent), network
status (icons for up or down)
Diffstat (limited to 'modules/desktop/eww/system-stats.py')
| -rw-r--r-- | modules/desktop/eww/system-stats.py | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/modules/desktop/eww/system-stats.py b/modules/desktop/eww/system-stats.py new file mode 100644 index 0000000..380dc25 --- /dev/null +++ b/modules/desktop/eww/system-stats.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +"""system-stats: emit {cpu, ram, net} as JSON. CPU/RAM sample on an interval +inside one long-lived process (no per-tick spawn)""" +import json +import subprocess +import threading +import time + +STATE_LOCK = threading.Lock() +STATE = {"cpu": 0, "ram": 0, "net": "down"} + + +def read_cpu_times(): + with open("/proc/stat") as f: + parts = f.readline().split()[1:] + vals = list(map(int, parts)) + idle = vals[3] + vals[4] # idle + iowait + total = sum(vals) + return idle, total + + +def cpu_ram_loop(interval=2.0): + prev_idle, prev_total = read_cpu_times() + while True: + time.sleep(interval) + idle, total = read_cpu_times() + d_idle = idle - prev_idle + d_total = total - prev_total + prev_idle, prev_total = idle, total + cpu_pct = round((1 - d_idle / d_total) * 100) if d_total else 0 + + with open("/proc/meminfo") as f: + meminfo = {} + for line in f: + k, v, *_ = line.split() + meminfo[k.rstrip(":")] = int(v) + total_kb = meminfo["MemTotal"] + avail_kb = meminfo["MemAvailable"] + ram_pct = round((1 - avail_kb / total_kb) * 100) if total_kb else 0 + + with STATE_LOCK: + STATE["cpu"] = cpu_pct + STATE["ram"] = ram_pct + emit() + + +def check_net_status() -> str: + try: + with open("/run/systemd/netif/state") as f: + state = dict( + line.strip().split("=", 1) for line in f if "=" in line + ) + except FileNotFoundError: + return "down" + + oper = state.get("OPER_STATE", "off") + if oper == "routable": + return "up" + if oper in ("degraded", "carrier", "degraded-carrier"): + return "limited" + return "down" + + +def net_loop(): + with STATE_LOCK: + STATE["net"] = check_net_status() + emit() + + proc = subprocess.Popen( + ["inotifywait", "-m", "-e", "modify", "/run/systemd/netif/state"], + stdout=subprocess.PIPE, text=True, bufsize=1, + ) + for _ in proc.stdout: + with STATE_LOCK: + STATE["net"] = check_net_status() + emit() + + +def emit(): + with STATE_LOCK: + print(json.dumps(STATE), flush=True) + + +def main(): + threading.Thread(target=cpu_ram_loop, daemon=True).start() + threading.Thread(target=net_loop, daemon=True).start() + threading.Event().wait() # keep main thread alive + + +if __name__ == "__main__": + main() |
