Homepage 集成 PeaNUT UPS Widget:NUT 不间断电源监控的配置、字段映射与源码解析
【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage
导读
本文介绍如何在 Homepage 仪表盘中通过 PeaNUT Widget 实时监控 Network UPS Tools (NUT) 管理的不间断电源(UPS),涵盖前置依赖、YAML 配置参数、多 UPS 实例拆分、字段映射与状态语义,并结合仓库源码说明 Widget 背后的 API 请求链路与数据校验逻辑。读完本文,你将能独立完成 UPS 监控 Widget 的配置、排错与界面理解。
前置条件:先有 NUT,再有 PeaNUT,然后才是 Homepage Widget
Homepage 的peanut类型 Widget 本身并不直接与 NUT 服务通信,而是通过第三方工具PeaNUT(一个面向 Network UPS Tools 的 Web 前端/API 网关)读取 UPS 数据,这一点在 官方 Widget 文档 中有明确说明。因此完整的数据链路为:
NUT(upsd / upsc 守护进程) → PeaNUT(REST API) → Homepage Widget(浏览器端渲染)此外,官方文档也提示:如果不想引入 PeaNUT,存在其他通过customapiWidget 实现类似效果的项目(例如 NUTCase)。因此本节建议先确认 PeaNUT 服务已部署且可访问,再继续后续配置。
最小可用配置:一段 YAML 接入 UPS
在 Homepage 的services.yaml(仓库内置示例见 src/skeleton/services.yaml)中,为一个服务组添加如下 Widget 配置:
widget: type: peanut url: http://peanut.host.or.ip:port key: nameofyourups username: username # only needed if set password: password # only needed if set保存配置并刷新页面后,服务卡片上会显示三块信息:Battery Charge(电池电量)、UPS Load(负载)与UPS Status(状态)。
核心参数逐个拆解
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
type | 是 | — | 固定为peanut |
url | 是 | — | PeaNUT 服务的地址,格式为http://主机或IP:端口 |
key | 是 | ups | 要监控的 UPS 名称,对应 NUT 中的 upsname |
username | 否 | — | 仅当 PeaNUT 启用了认证时需要 |
password | 否 | — | 仅当 PeaNUT 启用了认证时需要 |
关于key的默认值,官方文档明确指出:默认 UPS 名称是ups(NUT 默认配置下的标准 upsname)。如果你的 NUT 配置了其他名称,则必须通过key显式指定。
底层原理:Widget 如何拿到 UPS 数据
API 模板与占位符替换
Homepage 的每个 Widget 都由一个定义文件描述其 API 形态,PeaNUT 的定义位于 src/widgets/peanut/widget.js:
const widget = { api: "{url}/api/v1/{endpoint}/{key}", proxyHandler: genericProxyHandler, mappings: { devices: { endpoint: "devices" }, }, };其中{url}、{endpoint}、{key}三个占位符会在请求时被替换。替换逻辑在 src/utils/proxy/api-helpers.js 的formatApiCall中实现,其正则/\{.*?\}/g会匹配花括号内的键名并到 Widget 配置中取值;同时对url做了去尾斜杠处理(value.replace(/\/+$/, "")),避免http://host:port/与模板拼接后出现双斜杠。
结合mappings.devices.endpoint = "devices",实际请求 URL 即:
http://peanut.host.or.ip:port/api/v1/devices/{key}代理处理器与 Basic Auth
Widget 的请求统一经由genericProxyHandler(src/utils/proxy/handlers/generic.js)在服务端转发,而非浏览器直接跨域调用。其中与 PeaNUT 配置直接相关的两点:
- Basic 认证注入:当配置中同时提供了
username与password时,处理器会拼接Authorization: Basic base64(username:password)请求头(见 generic.js 中Buffer.from(...).toString("base64")的实现)。这正是官方配置注释 "only needed if set" 的源码依据——两者必须同时存在才会启用认证。 - 数据校验:返回数据会经过
validateWidgetData检查,若结构不符合预期(HTTP 200 但字段非法),前端会收到 "Invalid data" 错误而非渲染脏数据。
前端数据流与字段映射
组件实现位于 src/widgets/peanut/component.jsx,它通过useWidgetAPI(widget, "devices")(对应 src/utils/proxy/use-widget-api.js,基于 SWR 的封装)拉取数据,然后:
- 兼容 PeaNUT v1 的旧字段名:若返回数据中存在
"battery.charge"、"ups.load"、"ups.status"这类点分命名(PeaNUT v1 格式),会自动映射为battery_charge、ups_load、ups_status,保证新旧版本 API 都能正常渲染。这一逻辑由 src/widgets/peanut/component.test.jsx 中的 "renders legacy field mapping and status translation" 用例覆盖。 - 状态码翻译:NUT 的
ups.status是短码枚举,组件将其转换为可读文案:
| 原始值 | 含义 | 对应翻译键 |
|---|---|---|
OL | Online(市电在线) | peanut.online |
OB | On Battery(电池供电) | peanut.on_battery |
LB | Low Battery(电池电量低) | peanut.low_battery |
| 其他 | 原样展示 | — |
翻译文案定义在 public/locales/en/common.json 的peanut命名空间下(battery_charge、ups_load、ups_status、online、on_battery、low_battery),其他语言可通过对应 locale 文件本地化。
- 百分比渲染:
battery_charge与ups_load会通过common.percent翻译键渲染为带%的数值,并以数值本身作为高亮阈值(highlightValue)。
多 UPS 监控:一个 UPS 一个 Widget
官方文档明确:要监控多个 UPS,必须为每个 UPS 创建独立的 peanut 服务。原因是 Widget 的key字段是单值配置,一次只能指向一个 UPS。典型做法是在同一服务组下并列多个条目,例如:
- UPS 主机: widget: type: peanut url: http://peanut.host.or.ip:port key: ups - UPS 机房: widget: type: peanut url: http://peanut.host.or.ip:port key: rackups加载、错误与空白占位行为
从组件实现看,三个展示块在数据尚未返回时即以占位形式渲染(<Block label="peanut.battery_charge" />等,不传value),因此首屏会先出现三块灰色占位,数据到达后填充真实数值。若useWidgetAPI返回错误,整个 Container 会进入错误态,配合 Homepage 的全局错误处理展示具体原因;URL 中的敏感信息(如认证字段)会在错误日志中被sanitizeErrorURL脱敏为仅保留 hostname。
验证与排错建议
- 在浏览器直接访问
http://peanut.host.or.ip:port/api/v1/devices/ups,确认返回 JSON 中包含battery.charge/ups.load/ups.status(v1 风格)或battery_charge/ups_load/ups_status(新版风格)字段; - 若配置了认证,先在浏览器用 Basic Auth 方式验证账号密码是否可用;
- 在 Homepage 中确认
url未写错端口、key与 NUT 中实际的 UPS 名称一致; - 若仍失败,查看 Homepage 服务端日志中的 "HTTP Error %d calling..." 调试信息(由 genericProxyHandler 输出),其中会保留协议与主机名用于定位。
小结
PeaNUT Widget 是 Homepage 为数不多面向硬件电源场景的开箱即用集成:只需一段 YAML 即可把 NUT 生态的 UPS 数据搬上仪表盘,并且仓库源码同时兼容 PeaNUT v1 与新版字段命名,状态短码也会被自动翻译为直观文案。结合服务端代理、Basic Auth 注入与数据校验机制,整个链路在安全性与健壮性上都有保障。对于多 UPS 机房场景,按"一个 UPS 一个 Widget 实例"的方式横向扩展即可。
【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考