thieggs/battery-widget

GitHub: thieggs/battery-widget

一款 KDE Plasma 6 桌面电池监控小组件,通过可插拔数据源汇聚系统原生无法识别的各类设备的电量信息。

Stars: 0 | Forks: 0

# 电池 Widget **一个 KDE Plasma 6 小组件,适用于你拥有的每一块电池。** 手机、无线外设、无头 Android 盒子、那些不向任何东西汇报电量的 蓝牙音箱——全部作为圆环显示在你的桌面上。 ![Battery Widget 桌面展示](https://static.pigsec.cn/wp-content/uploads/repos/cas/2b/2b812e092d27c6af80bdd50970fa22ccc798016bd0c5c07c3e6698abe149b31b.png) *一台通过 KDE Connect 连接的手机,一台通过 adb 连接的无头 Android 服务器,一把无线 键盘,一个游戏手柄,以及一个在 Linux 上不向任何程序报告电量的 蓝牙音箱——全部集中在一处。* ## 为什么会有这个项目 Linux 已经能显示它所识别的设备的电量。问题在于 其他所有设备: - **充当服务器的手机**。`upower` 根本不知道它的 存在。 - **与你的手机配对而非与电脑配对的蓝牙外设**。 - **不向任何对象报告电量的音箱**——不是 upower,不是 蓝牙电量配置文件,甚至不是它自己的 USB 通道。厂商应用 知道。其他都没人知道。 Battery Widget 就是为填补这一空白而生的。数据源是可插拔的,其中之一是 “任何能写入 JSON 文件的程序”,因此对于具有专有 协议的设备,只需一个小脚本就能将其变成桌面上的一个圆环。 **如果你只需要标准设备, [BatteryWatch](https://github.com/itayavra/batterywatch) 是一个极好的选择,可能更适合 你**——它在一个整洁的系统托盘图标中涵盖了 upower、KDE Connect、OpenRazer 和 OpenLinkHub。Battery Widget 适用于那些拒绝合作的硬件。 ## 数据源 | 数据源 | 覆盖范围 | 设置 | |---|---|---| | **upower** | 鼠标、键盘、耳机、游戏手柄——任何内核暴露的设备 | 无,自动发现 | | **KDE Connect** | 已配对的手机、平板电脑、笔记本电脑 | 无,如果你已经在使用 | | **OpenRazer** | Razer 外设 | 无,前提是已安装 daemon | | **OpenLinkHub** | Corsair 外设 | 无,前提是它正在运行 | | **adb** | 通过无线调试连接的 Android 设备,**以及与其配对的蓝牙外设** | 在设置中添加设备 | | **external** | 任何设备——你只需将数值写入 JSON 文件 | 编写一个脚本 | 每一个数据源都可以安全地保持启用。当其 daemon 未安装时, 查询会瞬间失败,该数据源只会保持为空——即使它们全都不 存在,整个集合的运行时间也能远远控制在一秒以内。 ### 关于 adb 数据源 这是一个 **pull 模型**。手机上不运行任何东西;小组件在需要时 主动询问。有两个值得理解的要点: - **离开家不会产生任何开销。** mDNS 找不到设备,收集器会在大约 一秒后放弃,永远不会去联系手机。 - **必须开启无线调试。** 一些银行应用会在此状态下拒绝运行, 因此这可能不适合你的日常手机。但它非常适合那些放在 架子上作为服务器的设备。 每次重启无线调试时,Android 都会分配一个**新端口**,因此 硬编码的地址会不断失效。使用 `auto`,它每次都会通过 mDNS 重新被发现。 ## 安装 无需 root 权限,完全可逆。 ``` git clone https://github.com/thieggs/battery-widget cd battery-widget ./install.sh ``` 然后:**右键点击桌面 → 添加小组件… → “Battery Widget”**。 如果它没有出现在列表中,请重新加载 shell——Plasma 会缓存小组件的 QML: ``` systemctl --user restart plasma-plasmashell.service ``` 要移除所有内容: ``` ./uninstall.sh # keeps the cache ./uninstall.sh --purge # deletes it too ``` ### 依赖项 只有 **python3** 是真正必需的。其他每个工具都会启用一个数据源, 如果缺少该工具,只会导致该数据源为空: | 工具 | 启用 | |---|---| | `upower` | 本地外设 | | `kdeconnect-cli`, `gdbus` | KDE Connect 设备,以及即时刷新 | | `adb`, `avahi-browse` | Android 设备 | | `gatttool`, `bluetoothctl` | JBL 示例数据源 | `install.sh` 会告诉你缺少哪些工具,并继续执行。 ## 配置 右键点击小组件 → **配置 Battery Widget**。 **常规** —— 刷新间隔,隐藏离线设备,显示/隐藏标题和 设备名称。 **外观** —— 圆环直径和厚度,图标大小(0 表示隐藏), 警告和严重阈值,以及所有三种颜色。 **数据源** —— 切换每个数据源,并管理 **adb 设备网格**: | 字段 | 含义 | |---|---| | **目标** | 使用 `auto` 通过 mDNS 发现,使用 `auto:HINT` 在多个设备中选择(例如 `auto:SM-M356B`),或者直接填入 `192.168.1.10:5555` | | **名称** | 圆环的标签 | | **蓝牙** | 同时读取与该设备配对的蓝牙外设 | | **跳过自身** | 忽略设备自身的电池——当 KDE Connect 已经显示该手机,而你只想要它的外设时非常有用 | 你可以随意添加任意数量的设备。 ## 工作原理 三个部分,刻意保持独立: ``` battery-hub-watch ──touches──▶ ~/.cache/battery-hub/dirty (D-Bus listener) │ stat, every 2 s ▼ ┌───────────────┐ │ widget │ └───────┬───────┘ │ runs, with your settings as flags ▼ ┌───────────────┐ ┌──────────────┐ │ battery-hub │◀─────│ external.json│ │ (collector) │ └──────────────┘ └───────┬───────┘ ▲ │ │ upower · KDE Connect · adb your script ``` **收集器** (`battery-hub`) 是一个普通的程序:它查询数据源 并输出 JSON。你可以在终端中运行它,将其通过管道传递给 `jq`,或者在与 Plasma 毫无关系的 状态栏中使用它。 **小组件** 从不与设备直接通信。它根据其 设置构建命令行,运行收集器,并绘制结果。支持新硬件 只需修改收集器,完全不需要碰 QML。 **监听器** (`battery-hub-watch`) 监听 D-Bus —— UPower、BlueZ 和 KDE Connect —— 并在有设备连接时触碰一个标记文件。小组件每两 秒钟检查一次该文件的统计信息,这几乎不消耗任何资源,并且只有在 时间戳发生变化时才运行真正的收集器。实测从插入设备到 圆环出现的延迟:**大约一秒钟**。 它故意*不*自己运行收集器,因为只有小组件才 知道你的设置。它只负责敲响警钟。 如果监听器没有运行,所有功能仍会根据轮询定时器正常运行。这是 功能降级,而不是中断。 ## 编写你自己的数据源 将一个 JSON 数组写入 `~/.cache/battery-hub/external.json`: ``` [ { "id": "my-thing", "name": "My Thing", "kind": "headset", "pct": 80, "charging": false, "ts": 1750000000 } ] ``` - `id` —— 保持稳定,这样你就可以在不影响其他条目的情况下更新自己的条目 - `kind` —— 选择图标:`phone`, `tablet`, `laptop`, `mouse`, `keyboard`, `headset`, `gamepad`, `watch`, `generic` - `ts` —— Unix 时间戳,可选。如果早于 TTL(默认为 15 分钟), 该设备将显示为 **离线**,而不是显示一个过时的错误数值。 有两点值得从 `contrib/jbl-battery` 中借鉴: - **合并,不要覆盖。** 读取文件,只删除你自己的 `id`,然后写 回——否则你会删除别人的数据源。 - **原子写入** (`os.replace`),否则收集器最终会读取到一个 写了一半的文件。 ## 案例研究:一个对谁都保密的音箱 插上 USB 后,音箱枚举出了一个 HID 接口,带有一个 **厂商定义的通道,进出各 63 字节**。看起来很有希望——却是一个 彻底的死胡同。在狂按每个按钮的同时监听它,结果只产生了媒体键 报告。它从不主动报告电量,而且用于询问电量的厂商命令 在任何地方都没有文档记录。 **传输方式错了。** JBL 通过 **BLE GATT** 进行通信,该协议已由 [ConnectPlus](https://github.com/pembem22/connect-plus/discussions/56) 记录,这是对官方应用的 一次开源重新实现: ``` packet AA | type | length | payload payload 00 | token | value... write AA 11 00 "tell me about yourself" read AA 12 .. 00 44 token 0x44 = BATTERY_STATUS ``` 写入该内容,读取通知,搞定。完整的详细指南——包括 应该使用哪些 handle 以及如何在其他型号上找到它们——位于 [`docs/JBL-PROTOCOL.md`](docs/JBL-PROTOCOL.md)。 这个经验具有普适性:**在对协议进行逆向工程之前,先检查一下 你是否选对了传输方式。** ## 故障排除 **小组件永远显示“正在读取设备…”。** 手动运行收集器:`~/.local/bin/battery-hub`。它会输出 JSON 或者 一个错误。 **我修改了 QML,但没有任何反应。** Plasma 缓存了小组件的 QML。重新加载 shell: `systemctl --user restart plasma-plasmashell.service`。 **设置无法保存,点击“确定”没有任何反应。** 原因同上。一个小程序会在**加载时读取一次**其配置 schema —— 如果 schema 到达时小组件已经在运行,它就不会读取。请重新加载 shell。(症状:你在 `~/.config/plasma-org.kde.plasma.desktop-appletsrc` 中的小程序组里有一个 `[ConfigDialog]` 部分,但没有 `[General]`。) **adb 设备从未出现。** 检查 `adb devices`,并确保无线调试已开启且 PC 已配对。如果 你固定了 `host:port`,请记住 Android 每次重启时都会更改端口—— 将目标切换为 `auto`。 **蓝牙设备不显示电量。** 有些设备根本不报告。尝试启用 BlueZ 实验性功能,这 适用于许多音频设备:在 `/etc/bluetooth/main.conf` 中设置 `Experimental = true` 并重启 `bluetooth.service`。 ## 许可证 MIT —— 详见 [LICENSE](LICENSE)。 # 🇧🇷 Português **Um widget do KDE Plasma 6 para todas as suas baterias.** Celulares, periféricos sem fio, Android headless e caixas de som que não contam sua bateria pra ninguém — tudo em anéis na sua área de trabalho. ![Battery Widget na área de trabalho](https://static.pigsec.cn/wp-content/uploads/repos/cas/2b/2b812e092d27c6af80bdd50970fa22ccc798016bd0c5c07c3e6698abe149b31b.png) ## 为什么存在 O Linux já mostra a bateria dos aparelhos que ele entende. O problema é o resto: um **celular servindo de servidor** na rede, os **periféricos Bluetooth pareados no celular** (e não no PC), e a **caixa de som que não reporta bateria pra ninguém** — nem upower, nem perfil Bluetooth, nem o próprio canal USB dela. O Battery Widget foi feito pra essa lacuna. As fontes são plugáveis, e uma delas é "qualquer programa que saiba escrever um JSON" — então um aparelho de protocolo proprietário está a um script de virar um anel na sua tela. **Se você só precisa de aparelhos comuns, o [BatteryWatch](https://github.com/itayavra/batterywatch) é excelente e provavelmente serve melhor.** Este aqui é pra quando o hardware não colabora. ## 安装 ``` git clone https://github.com/thieggs/battery-widget cd battery-widget ./install.sh ``` Depois: **botão direito na área de trabalho → Adicionar widgets… → "Battery Widget"**. Se não aparecer na lista, recarregue o shell (o Plasma guarda o QML em cache): ``` systemctl --user restart plasma-plasmashell.service ``` Pra remover: `./uninstall.sh` (ou `--purge` pra apagar o cache junto). Só o **python3** é realmente obrigatório. Cada outra ferramenta habilita uma fonte, e a falta dela só deixa aquela fonte vazia. ## adb 来源 É um **modelo pull**: nada roda no celular, o widget é que pergunta quando quer saber. Duas consequências: - **Estar fora de casa não custa nada.** O mDNS não acha, o coletor desiste em ~1s, e o celular nunca é contatado. - **Precisa da depuração sem fio ligada.** Alguns apps de banco se recusam a funcionar assim — então pode não servir pro seu celular do dia a dia, mas serve muito bem pra um aparelho que vive numa prateleira sendo servidor. O Android **sorteia uma porta nova toda vez** que a depuração sem fio reinicia. Por isso use `auto` no campo de alvo: ele redescobre por mDNS sozinho. ## 配置 Botão direito no widget → **Configurar**. Você controla intervalo, aparência (tamanho e espessura do anel, ícones, limiares e cores) e as fontes — incluindo uma **grade onde dá pra adicionar quantos aparelhos adb quiser**, cada um com alvo, nome, e as opções de ler os periféricos Bluetooth dele e de ignorar a bateria dele mesmo. ## 工作原理 Três peças separadas de propósito: o **coletor** (`battery-hub`) consulta as fontes e imprime JSON — dá pra rodar no terminal, jogar no `jq`, usar em outra barra de status. O **widget** nunca fala com aparelho nenhum: monta a de comando a partir das configurações, roda o coletor e desenha o resultado. E o **vigia** (`battery-hub-watch`) escuta o D-Bus e avisa quando algo conecta — latência medida de **cerca de 1 segundo** entre plugar e o anel aparecer. Suportar hardware novo significa mexer no coletor, nunca no QML. ## 许可证 MIT.
标签:KDE Plasma, 桌面组件, 电量监控, 系统工具, 蓝牙设备