Flake for my NixOS devices
1#!/usr/bin/env nu
2
3const BUS_NAME = "org.kde.kdeconnect";
4const PATH_PREFIX = "/modules/kdeconnect";
5const DEVICE_INTERFACE = "org.kde.kdeconnect.device";
6const DAEMON_INTERFACE = "org.kde.kdeconnect.daemon";
7
8def dev_path [name: string] {
9 $"($PATH_PREFIX)/devices/($name)"
10}
11
12def get_device_list [] {
13 # org.kde.kdeconnect.daemon.devices (bool onlyReachable, bool onlyPaired)
14 dbus call --session --dest=$BUS_NAME --no-introspect $PATH_PREFIX $DAEMON_INTERFACE devices false true --signature=bb
15}
16
17def device_info [id: string] {
18 dbus get-all --session --dest=$BUS_NAME (dev_path $id) $DEVICE_INTERFACE
19}
20
21def get_devices [] {
22 get_device_list | each {|it| device_info $it | insert "id" $it}
23}
24
25def is_reachable [device: record] {
26 $device.isReachable? | default false
27}
28
29def supports_battery [device: record] {
30 let reachable = is_reachable $device;
31 let supported = "kdeconnect_battery" in ($device.supportedPlugins? | default []);
32 let exists = dbus introspect --session --dest=$BUS_NAME (dev_path $device.id) | get -o children | default [] | any {|it| $it.name == "battery"}
33
34 $reachable and $supported and $exists
35}
36
37def get_battery_info [device: record] {
38 if not (supports_battery $device) {
39 return null
40 }
41
42 dbus get-all --session --dest=$BUS_NAME $"(dev_path $device.id)/battery" $"($DEVICE_INTERFACE).battery"
43}
44
45# Everything except phone is a guess here, I don't know
46# what the other types are and I can't find any documentation
47# on it, we'll just assume laptop for now
48const icon_ref = {
49 phone: [
50 "",
51 "",
52 "",
53 ],
54 desktop: [
55 "",
56 "",
57 "",
58 ],
59 laptop: [
60 "",
61 "",
62 "",
63 ],
64};
65
66def main [] {
67 let devices = get_devices;
68
69 let status = $devices | each {|it|
70
71 let name = $it.name? | default "Unknown Device";
72
73 let reachable = is_reachable $it;
74
75 let icons = $icon_ref | get -o ($it.type? | default "") | default $icon_ref.phone;
76
77 let battery_info = get_battery_info $it | default { isCharging: false };
78
79 let icon = $icons | get (if (not $reachable) {
80 2
81 } else {
82 if ($battery_info.isCharging? | default false) {
83 1
84 } else {
85 0
86 }
87 });
88
89 let percent = if $battery_info.charge? != null and $battery_info.charge != -1 {
90 $" ($battery_info.charge)%"
91 } else { "" };
92
93 {
94 chip: $"($icon)($percent)"
95 tooltip: $"($icon) ($name) -($percent)"
96 }
97 };
98
99 let output = {
100 text: ($status | get chip | str join " "),
101 tooltip: ($status | get tooltip | str join "\n"),
102 class: "kdeconnect",
103 };
104
105 print ($output | to json -r);
106}
107