news 2026/9/10 16:44:48

Homepage 接入 QNAP NAS:QNAP 监控 Widget 配置详解与实现原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Homepage 接入 QNAP NAS:QNAP 监控 Widget 配置详解与实现原理

Homepage 接入 QNAP NAS:QNAP 监控 Widget 配置详解与实现原理

【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage

导读

本文以 QNAP Widget 文档 为主体,讲解如何在 Homepage 首页仪表盘中接入 QNAP NAS,实时展示 CPU 使用率、内存使用率、系统温度和存储池/卷空间占用。文章不仅覆盖完整配置示例与参数说明,还结合仓库中src/widgets/qnap/目录下的代理层、前端组件与测试用例,剖析登录鉴权、会话令牌缓存、多卷聚合等底层实现,帮助你不仅会配,更知道它为什么这样工作。

QNAP Widget 能展示什么

QNAP Widget 属于 Homepage 的服务类 Widget,以widget.type: qnap声明后,会在服务卡片内渲染 4 个指标块,对应文档中声明的允许字段:

字段含义前端标签(public/locales/en/common.json#L252-L259
cpuUsageCPU 使用率(百分比)CPU Usage
memUsage内存使用率(百分比)MEM Usage
systemTempC系统温度(摄氏度)System Temp
poolUsage存储池使用率(所有卷合计)Pool Usage
volumeUsage指定单个卷的使用率Volume Usage

注意poolUsagevolumeUsage二选一的关系:不配置volume字段时显示poolUsage(全部卷聚合),配置了volume字段后则改为volumeUsage(单卷跟踪)。这些标签在 public/locales/en/common.json 中统一定义,并通过 i18n 的common命名空间渲染,因此其他语言包同样包含对应翻译。

最小配置:直接可用

在服务的widget段写入以下内容即可接入 QNAP NAS(原文档示例):

widget: type: qnap url: http://qnap.host.or.ip:port username: user password: pass

参数说明:

  • type:固定为qnap,用于匹配src/widgets/qnap/widget.js导出的 Widget 定义;
  • url:QNAP 设备的管理地址,需包含端口(默认 Web 管理端口 8080,可按实际填写);
  • username/password:QNAP 登录凭据,用于调用 NAS 的 CGI 管理接口(见下文鉴权流程)。

单卷跟踪配置

文档明确指出:如果 QNAP 设备有多个卷,默认的poolUsage会是所有卷的合计值。若只想跟踪某一个卷,在 Widget 配置中追加volume字段即可:

volume: Volume Name From QNAP

volume的值必须是 QNAP 中实际的卷标签(Volume Label),例如DataVol1。该字段的解析在 src/utils/config/service-helpers.js#L562-L564 中与diskstation共用一段逻辑:当类型为["diskstation", "qnap"]时,若存在volume配置项则写入widget.volume,随后由前端组件消费。

工作原理:会话令牌 + 两个数据接口

Widget 前端通过useWidgetAPI(widget, "status")(见 src/widgets/qnap/component.jsx)向代理层请求/status端点,该端点由 src/widgets/qnap/widget.js 中的allowedEndpoints: /status/声明为唯一允许的接口。真正的数据获取全部发生在服务端代理qnapProxyHandler中(src/widgets/qnap/proxy.js),QNAP 密码不会暴露给浏览器。

1. 登录与令牌缓存

QNAP 的 CGI 接口使用基于会话 ID(sid)的鉴权方式。代理层首先向{url}/cgi-bin/authLogin.cgi发送POST请求(proxy.js 的 login 函数):

  • 请求头为Content-Type: application/x-www-form-urlencoded
  • 表单携带user(明文)与pwdBase64 编码后的密码)两个字段;
  • 响应是 XML 格式,通过xml-jsxml2json转换为 JSON 后取出QDocRoot.authSid作为会话令牌。

获取到的令牌以qnapProxyHandler__sessionToken.<service>为键存入memory-cachesessionTokenCacheKey常量),按服务维度隔离缓存。后续所有数据请求都会携带&sid=<token>参数。令牌无需在每次请求时重复登录,这也是代理层减少对 NAS 负担的关键设计。

2. 两个数据接口

登录成功后,代理层并行发起两个请求(见 proxy.js 的 qnapProxyHandler):

数据接口路径用途
系统信息{url}/cgi-bin/management/manaRequest.cgi?subfunc=sysinfo&hd=no&multicpu=1CPU、内存、温度
卷用量{url}/cgi-bin/management/chartReq.cgi?chart_func=disk_usage&disk_select=all&include=all各卷总大小与剩余空间

响应同样为 XML,转 JSON 后提取QDocRoot.func.ownContent.root作为systemQDocRoot作为volume返回给前端。

3. 令牌失效自动重登

QNAP 会话令牌会过期。代理层对两种失效场景做了兜底:

  • 请求返回HTTP 404
  • 响应中QDocRoot.authPassed._cdata === "0"(鉴权未通过)。

出现以上情况时,代理层会重新执行login()获取新令牌,并用新令牌重试一次该请求;若重试仍非 200,则记录错误日志并返回data: null。整个重登重试逻辑在 proxy.js 的 apiCall 函数 中实现,前端收到错误后会在容器内展示错误状态(component.jsx中的statusError分支)。

前端指标计算逻辑

src/widgets/qnap/component.jsx 将代理返回的原始 XML-JSON 数据转换为 4 个展示块:

  • CPU 使用率:读取system.cpu_usage._cdata,并剥离尾部的" %"字符串后以百分比渲染;
  • 内存使用率:由total_memoryfree_memory计算(total - free) / total × 100,结果取整(toFixed(0));
  • 系统温度:读取system.sys_tempc._text,按celsius单位格式化,保留 1 位小数;
  • 卷/池使用率:优先按volumeUseList.volumeUse是否为数组区分单卷与多卷场景:
    • 单卷(非数组):直接使用total_sizefree_size
    • 多卷 + 未配置volume:遍历volumeUse数组,累加所有卷的total_sizefree_size(对应文档“poolUsage 是所有卷之和”的说明),再计算使用率;
    • 多卷 + 已配置volume:在volumeList.volume中按volumeLabel._cdata精确匹配配置的卷名,命中后取该卷的total_size/free_size计算volumeUsage;若未命中(例如卷名拼写错误),validVolume置为false,该块显示翻译键qnap.invalid(即 “Invalid”),避免渲染出误导性的 0%。

这些计算逻辑均有测试用例覆盖,例如 src/widgets/qnap/component.test.jsx 中构造total_memory = 100free_memory = 25的载荷,断言内存使用率渲染为75;构造total_size = 100free_size = 50的单卷数组,断言池使用率为50。加载期间(data未返回)组件渲染 4 个占位 Block,标签同样区分qnap.poolUsageqnap.volumeUsage

服务端代理验证

src/widgets/qnap/proxy.test.js 验证了端到端的代理流程:通过 mock 依次返回“登录 → 系统信息 → 卷用量”三段 XML 响应,断言:

  1. 代理返回 HTTP 200;
  2. res.body.system为系统信息解析结果;
  3. res.body.volume包含authPassed字段(即完整QDocRoot对象)。

此外,代理入口会校验req.query中的groupservice参数,缺失时返回 400Invalid proxy service typegetServiceWidget找不到对应 Widget 时同样返回 400。这与 Homepage 通用的服务代理模式一致(可参考 docs/widgets/services/index.md 与 docs/configs/services.md 了解服务定义规范)。

使用前提与注意事项

  • 需要能访问管理接口:代理层通过 QNAP 的/cgi-bin/管理 CGI 接口取数,Widget 所在环境(Homepage 容器)必须能通过网络访问该地址,且需在 QNAP 上开启相应管理访问权限;
  • 凭据安全:密码只在服务端代理层使用,前端与浏览器不会接触到密码;但由于登录接口按文档要求使用 Base64 编码传输,建议仅在可信的内网环境使用;
  • 卷名精确匹配volume字段必须与 QNAP 卷标签完全一致(区分大小写),否则对应指标块显示Invalid
  • 令牌生命周期:会话令牌按 service 维度缓存在内存中并支持失效自动重登,一般无需人工干预;长时间不访问后首次请求可能因重登多一次往返,属正常现象。

小结

QNAP Widget 是 Homepage 服务类 Widget 中典型的“登录鉴权 + 多接口聚合 + 前端计算展示”型组件:widget.js定义接口与白名单,proxy.js负责令牌管理与数据拉取,component.jsx负责指标计算与多卷逻辑,配套测试覆盖了核心路径。按本文配置type: qnap并视需要指定volume字段,即可把 NAS 的关键运行指标直接钉在个人首页上。

【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 16:43:38

MIMO-MRI时间序列预测模型构建与MATLAB实现

1. 项目概述&#xff1a;MIMO-MRI时间序列预测的临床价值在医学影像分析领域&#xff0c;多输入多输出磁共振成像&#xff08;MIMO-MRI&#xff09;时间序列预测正成为研究热点。这个项目使用MATLAB构建两输入三输出的预测模型&#xff0c;核心目标是解决动态MRI扫描中的关键问…

作者头像 李华
网站建设 2026/9/10 16:43:09

视觉伺服云台控制实战:OpenCV坐标映射与PID追踪系统搭建

简介&#xff1a;一套面向2023年全国大学生电子设计竞赛E题的完整工程代码包&#xff0c;主控采用STM32F407VET6&#xff0c;搭配OpenMV作为视觉从机&#xff0c;适用于电子竞赛备赛、毕业设计、课程设计或工程实训等场景。代码涵盖STM32端PID控制、多级菜单调参逻辑、OpenMV图…

作者头像 李华
网站建设 2026/9/10 16:39:08

现在性价比高的AI论文写作软件有哪些品牌?学生党亲测反馈

每到期末、毕业答辩、课题申报阶段&#xff0c;很多学生都会陷入论文写作的困境&#xff1a;选题毫无头绪、大纲搭建逻辑混乱、正文撰写耗时长、参考文献格式出错、查重重复率偏高、AIGC检测告警、本校论文排版标准复杂。纯人工从零开始撰写、反复修改格式和降重&#xff0c;往…

作者头像 李华