diff --git a/users/price/dots/.config/waybar/config b/users/price/dots/.config/waybar/config
index 6d7ad417..b669feb0 100644
--- a/users/price/dots/.config/waybar/config
+++ b/users/price/dots/.config/waybar/config
@@ -20,7 +20,7 @@
],
"modules-right": [
"privacy",
- "systemd-failed-units",
+ "custom/systemd-failed-units",
"tray",
"backlight",
"network",
@@ -225,10 +225,10 @@
"icon-spacing": 2,
"icon-size": 14,
},
- "systemd-failed-units": {
- "format": "✗ Degraded Units: {nr_failed}",
- "system": true,
- "user": true
+ "custom/systemd-failed-units": {
+ "exec": "~/.config/waybar/scripts/systemd-status.py",
+ "return-type": "json",
+ "interval": 3
},
"tray": {
"icon-size": 14
diff --git a/users/price/dots/.config/waybar/scripts/systemd-status.py b/users/price/dots/.config/waybar/scripts/systemd-status.py
new file mode 100755
index 00000000..4b456150
--- /dev/null
+++ b/users/price/dots/.config/waybar/scripts/systemd-status.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env -S nix shell nixpkgs#python3 nixpkgs#nix-prefetch-git --command python3
+
+from enum import Enum
+import subprocess
+import json
+from typing import NotRequired, TypedDict
+
+
+class SystemUnitStatus(str, Enum):
+ Ok = "ok"
+ Degraded = "degraded"
+
+
+WaybarJsonRet = TypedDict(
+ "WaybarJsonRet",
+ {
+ "text": str,
+ "class": SystemUnitStatus,
+ "alt": NotRequired[str],
+ "tooltip": NotRequired[str],
+ "percentage": NotRequired[str],
+ },
+)
+
+
+class FailedUnit(TypedDict):
+ unit: str
+ load: str
+ active: str
+ sub: str
+ description: str
+
+
+def get_failed_units(extra_args: list[str] | None = None) -> list[FailedUnit]:
+ extra_args = extra_args or []
+ args = ["systemctl", "--state=failed", "--output=json"]
+ args.extend(extra_args)
+
+ units_proc = subprocess.run(args, capture_output=True)
+ units_proc.check_returncode()
+ failed_units: list[FailedUnit] = json.loads(units_proc.stdout)
+
+ return failed_units
+
+
+system_failed_units = get_failed_units()
+user_failed_units = get_failed_units(["--user"])
+total_units_failed = len(system_failed_units) + len(user_failed_units)
+
+status: SystemUnitStatus = SystemUnitStatus.Ok
+text = ""
+failed_units_tooltip: list[str] = []
+
+if total_units_failed > 0:
+ text = f" Degraded Units: {total_units_failed}"
+ status = SystemUnitStatus.Degraded
+ failed_units_tooltip.extend(
+ map(
+ lambda unit: f"System > {unit["unit"]}",
+ system_failed_units,
+ )
+ )
+ failed_units_tooltip.extend(
+ map(
+ lambda unit: f"User > {unit["unit"]}",
+ user_failed_units,
+ )
+ )
+
+
+out: WaybarJsonRet = {
+ "text": text,
+ "class": status,
+ "tooltip": "\r\n".join(failed_units_tooltip),
+}
+
+print(json.dumps(out))
diff --git a/users/price/dots/.config/waybar/style.css b/users/price/dots/.config/waybar/style.css
index 70ce7442..e2f52c7f 100644
--- a/users/price/dots/.config/waybar/style.css
+++ b/users/price/dots/.config/waybar/style.css
@@ -72,7 +72,7 @@ tooltip label,
#tray,
#backlight,
#privacy,
-#systemd-failed-units,
+#custom-systemd-failed-units,
#tray menu,
#custom-lock {
background-color: #16161d;
@@ -285,11 +285,11 @@ tooltip {
color: #A3D4D5;
}
-#systemd-failed-units.ok {
+#custom-systemd-failed-units.ok {
color: #98BB6C;
}
-#systemd-failed-units.degraded {
+#custom-systemd-failed-units.degraded {
color: #FF5D62;
font-weight: bolder;
}