feat: airgradient

This commit is contained in:
2026-04-28 15:38:47 +02:00
parent b6359d4468
commit fa70c98160
7 changed files with 293 additions and 139 deletions
-2
View File
@@ -60,8 +60,6 @@
udev.packages = with pkgs; [ udev.packages = with pkgs; [
usb-sniffer usb-sniffer
]; ];
hardware.openrgb.enable = true;
}; };
hardware = { hardware = {
+1 -1
View File
@@ -1,6 +1,7 @@
window#waybar { window#waybar {
background: none; background: none;
border-bottom: none; border-bottom: none;
font-size: 20px;
} }
window#waybar > box.horizontal { window#waybar > box.horizontal {
@@ -15,7 +16,6 @@ window#waybar > box.horizontal {
#clock { #clock {
font-weight: bold; font-weight: bold;
font-size: 16px;
} }
#privacy-item { #privacy-item {
+17
View File
@@ -0,0 +1,17 @@
{ python3Packages }:
with python3Packages;
buildPythonPackage rec {
pname = "waybar-ha";
version = "0.0.1";
format = "pyproject";
src = ./.;
buildInputs = [
setuptools
];
propagatedBuildInputs = [
requests
keyring
];
meta.mainProgram = pname;
}
@@ -0,0 +1,10 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "waybar-ha"
version = "0.0.1"
[project.scripts]
waybar-ha = "waybar_ha.main:main"
@@ -0,0 +1,111 @@
import json
from requests import get
import keyring
import colorsys
import math
group = "waybar-ha"
HA_URL = keyring.get_password(group, "HA_URL")
HA_TOKEN = keyring.get_password(group, "HA_TOKEN")
if not HA_URL:
keyring.set_password(group, "HA_URL", "YOUR_URL")
if not HA_TOKEN:
keyring.set_password(group, "HA_TOKEN", "YOUR_TOKEN")
hsv_s = 0.42
hsv_v = 0.96
numbers_filled = ["󰰖", "󰲠", "󰲢", "󰲤", "󰲦", "󰲨", "󰲪", "󰲬", "󰲮", "󰲰", "󰄯", "󰰙", "󰰐"]
numbers_outline = ["󰰗", "󰲡", "󰲣", "󰲥", "󰲧", "󰲩", "󰲫", "󰲭", "󰲯", "󰲱", "󰄰", "󰰚", "󰰑"]
dots = 8
SENSORS = [
(
"sensor.i_9psl_carbon_dioxide",
[
(0, 1, 117),
(600, 2, 100),
(800, 3, 65),
(1000, 4, 41),
(1250, 5, 27),
(1500, 6, 12),
(1750, 7, 0),
(1751, 7, 360),
(2000, 8, 329),
(3000, 8, 290),
],
),
]
def lerp(a: float, b: float, t: float) -> float:
return (1 - t) * a + t * b
def main() -> None:
states = get(
f"{HA_URL}/api/states",
headers={
"Authorization": f"Bearer {HA_TOKEN}",
"Content-Type": "application/json",
},
).json()
text = ""
states_idx = {s["entity_id"]: s for s in states}
for sensor, thresholds in SENSORS:
if sensor not in states_idx:
continue
state = states_idx[sensor]
state_icon = 1
state_color = ""
sensor_value = int(state["state"])
if thresholds is not None:
try:
for i, (threshold, icon, hue) in reversed(list(enumerate(thresholds))):
if sensor_value >= threshold:
if sensor_value != threshold and i < len(thresholds) - 1:
next_threshold, _, next_hue = SENSORS[0][1][i + 1]
hue = lerp(
hue,
next_hue,
(sensor_value - threshold)
/ (next_threshold - threshold),
)
state_icon = icon
state_color = "#{:02x}{:02x}{:02x}".format(
*(
int(c * 255)
for c in colorsys.hsv_to_rgb(hue / 360, hsv_s, hsv_v)
)
)
break
except ValueError:
pass
suffix = [] # [11, 11, 12]
digits: list[int] = list(map(lambda x: int(x), list(f"{sensor_value}")))
s = "".join(
map(
lambda t: (
numbers_outline[t[1]]
if dots - t[0] > state_icon
else numbers_filled[t[1]]
),
enumerate(
[
*map(lambda _: 10, range(dots - len(digits) - len(suffix))),
*digits,
*suffix,
]
),
)
)
text += f'<span color="{state_color}">{s}</span>'
print(json.dumps({"text": text}))
+22 -4
View File
@@ -16,17 +16,26 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home-manager.users.${username}.programs.waybar = { home-manager.users.${username} = {
home.packages = [ (pkgs.callPackage ./waybar-ha { }) ];
programs.waybar = {
enable = true; enable = true;
settings = { settings =
let
waybar-ha = pkgs.callPackage ./waybar-ha { };
in
{
mainBar = { mainBar = {
layer = "top"; layer = "top";
height = 24; height = 36;
reload_style_on_change = true; reload_style_on_change = true;
exclusive = true; exclusive = true;
modules-left = ( modules-left = [
"custom/ha"
]
++ (
if cfg.mobile then if cfg.mobile then
[ [
"battery" "battery"
@@ -41,6 +50,7 @@ in
"privacy" "privacy"
"gamemode" "gamemode"
"tray" "tray"
"pulseaudio" "pulseaudio"
] ]
++ ( ++ (
@@ -130,6 +140,13 @@ in
"tooltip-format" = "{capacity}%"; "tooltip-format" = "{capacity}%";
}; };
"custom/ha" = {
exec = pkgs.lib.getExe waybar-ha;
return-type = "json";
interval = 30;
format = "{}";
};
"custom/theme" = { "custom/theme" = {
return-type = "json"; return-type = "json";
exec-on-event = true; exec-on-event = true;
@@ -156,4 +173,5 @@ in
}; };
}; };
}; };
};
} }