
homepage 集成 Spoolman Widget3D 打印耗材余量监控配置与源码级解析【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage导读Spoolman 是一个用于 3D 打印的耗材spool库存管理服务可以记录每卷耗材的剩余重量、初始重量与所属线材型号。homepage 通过内置的spoolman类型 Widget把 Spoolman 实例中的耗材余量以百分比进度条的形式直接渲染到你的起始页仪表盘上让你在准备打印任务时无需打开 Spoolman 后台即可一眼掌握耗材余量。本文将以 Spoolman Widget 官方文档 为主体结合仓库源码与测试用例完整讲解其配置方式、展示逻辑、API 代理链路与常见排障思路。Spoolman Widget 能做什么SpoolmanSpoolman 项目仓库 README 未在本仓库内此处仅作功能背景说明提供 REST API 管理耗材库存。homepage 的spoolmanWidget 通过其/api/v1/spool接口拉取所有耗材记录并为每个 spool 展示两块信息线材名称filament.name例如 PLA 白色、PETG 黑色剩余比例remaining_weight / initial_weight * 100以百分比形式显示当前耗材剩余量。这样首页上每个耗材对应一个信息块Block形成一排放置、一眼可读的耗材余量面板非常适合放在 3D 打印相关的服务分组中。快速开始最小配置在services.yaml中为你的 Spoolman 实例添加一个服务条目并在其widget段声明type: spoolman和url即可services: my-print-stack: displayName: 3D Print icon: sh-print widget: type: spoolman url: http://spoolman.host.or.ip配置完成后首页会从http://spoolman.host.or.ip/api/v1/spool拉取耗材数据并默认展示前 4 个 spool的余量。配置参数详解核心参数参数必填类型默认值说明type是string—固定为spoolman声明 Widget 类型url是string—Spoolman 实例的根地址如http://spoolman.host.or.ipWidget 会在此基础上拼接/api/v1/spoolspoolIds否number[]未设置时展示前 4 个指定要展示的耗材 ID 列表用于过滤显示官方文档给出的带过滤示例widget: type: spoolman url: http://spoolman.host.or.ip spoolIds: [1, 2, 3, 4] # optional通用 Widget 参数可选spoolman使用认证代理处理器credentialedProxyHandler因此还可以叠加 homepage 服务 Widget 的通用配置项widget: type: spoolman url: http://spoolman.host.or.ip spoolIds: [1, 2, 3, 4] username: admin # 可选Basic Auth 用户名 password: secret # 可选Basic Auth 密码 refreshInterval: 60 # 可选覆盖全局刷新间隔秒username/password当 Spoolman 开启了 Basic Auth 时使用代理层会生成Authorization: Basic ...请求头refreshInterval自定义该 Widget 的数据刷新间隔未设置时遵循全局设置。数据链路Widget 如何拿到耗材数据整个请求链路由三部分组成均可在仓库中直接找到对应实现。1. Widget 定义API 模板与端点映射Widget 的元信息定义在 src/widgets/spoolman/widget.jsimport credentialedProxyHandler from utils/proxy/handlers/credentialed; const widget { api: {url}/api/v1/{endpoint}, proxyHandler: credentialedProxyHandler, mappings: { spools: { endpoint: spool, }, }, }; export default widget;关键点api模板为{url}/api/v1/{endpoint}其中{url}来自配置中的url{endpoint}由映射决定mappings.spools.endpoint spool即前端请求名为spools的数据时实际请求的是GET {url}/api/v1/spool该 Widget 注册在 src/widgets/widgets.js 与 src/widgets/components.js 中供配置校验与组件渲染统一引用。2. 代理层服务端转发避免浏览器直连Widget 数据并非由浏览器直接请求 Spoolman而是经过 homepage 的服务端代理。spoolman使用的 src/utils/proxy/handlers/credentialed.js 会根据请求中的group/service/index定位到对应 Widget 配置getServiceWidget用formatApiCall按api模板拼出真实地址http://spoolman.host.or.ip/api/v1/spool合并请求头若配置了username/password自动附加Basic base64(username:password)认证头见basicAuthHeader源码 src/utils/proxy/handlers/credentialed.js将请求转发到 Spoolman再把响应回传给前端组件。这种浏览器 → homepage 服务端 → Spoolman的链路天然规避了跨域CORS问题也避免了在浏览器中暴露认证凭据。3. 组件渲染过滤、排序与展示前端组件实现位于 src/widgets/spoolman/component.jsx其完整渲染逻辑如下let { data: spoolData, error: spoolError } useWidgetAPI(widget, spools); if (spoolError) return Container service{service} error{spoolError} /; if (!spoolData) { const nBlocksGuess widget.spoolIds?.length ?? 4; return ( Container service{service} {[...Array(nBlocksGuess)].map((_, i) ( Block key{i} labelspoolman.loading / ))} /Container ); } if (spoolData.length 0) { return Container service{service}Block labelspoolman.noSpools //Container; } if (widget.spoolIds?.length) { spoolData spoolData.filter((spool) widget.spoolIds.includes(spool.id)); } if (spoolData.length 4) { spoolData spoolData.slice(0, 4); }具体行为可归纳为 4 条规则加载占位数据尚未返回时渲染 N 个 Loading 占位块N 取spoolIds的长度未配置spoolIds时默认渲染 4 个占位空状态Spoolman 返回空列表时显示一条 No spoolsspoolman.noSpools提示过滤配置了spoolIds时只保留 ID 命中列表的 spool数量上限无论是否过滤最终最多渲染4 个spoolslice(0, 4)。每个 spool 块的展示内容为Block key{spool.id} label{spool.filament.name} value{t(common.percent, { value: (spool.remaining_weight / spool.initial_weight) * 100, })} /即标签label显示线材名称数值value显示剩余重量占初始重量的百分比并套用common.percent的本地化格式输出。从源码看展示规则的细节spoolIds 的解析与透传在 src/utils/config/service-helpers.js 中spoolIds作为该 Widget 的特有字段被解构出来并在type spoolman时写入最终 Widget 配置src/utils/config/service-helpers.jsif (type spoolman) { if (spoolIds ! undefined) widget.spoolIds spoolIds; }这意味着spoolIds可以直接以 YAML 数组形式书写如[1, 2, 3, 4]服务端代理会根据该字段在数据返回后过滤展示。数量上限的双保险即便你不配置spoolIds组件也会在过滤之后执行slice(0, 4)确保展示数量不超过 4。因此默认只显示前 4 个 spool若你的 Spoolman 实例中耗材超过 4 卷有两种方式控制展示用spoolIds精确指定要看的耗材推荐顺序可控不指定时展示 API 返回顺序中的前 4 个。测试用例印证仓库的组件测试 src/widgets/spoolman/component.test.jsx 覆盖了上述全部核心行为加载时按spoolIds: [1, 2]渲染 2 个占位块renders guessed loading blocks while loadingAPI 返回空数组时展示spoolman.noSpoolsrenders no-spools message when API returns an empty list传入 5 个 spool 数据与spoolIds: [2, 3, 4, 5, 1]时先按 ID 过滤、再截断为 4 个块并验证第一个块为 A / 50%第二个为 B / 25%filters to selected spoolIds and caps at 4 entries。而 src/widgets/spoolman/widget.test.js 则验证了 Widget 定义api模板、代理处理器、端点映射符合 homepage 的统一配置形状保证该 Widget 能被配置校验与代理调度正常识别。实际使用建议按打印任务挑选耗材若你同时持有 10 卷耗材建议用spoolIds只列出常用的 34 卷避免首页信息过载结合服务组布局把spoolman服务与你的打印管理服务如 OctoPrint、Mainsail 等参见 docs/widgets/services 中对应文档放在同一分组形成完整的 3D 打印监控面板认证场景Spoolman 若启用了 Basic Auth务必在 Widget 中配置username/password否则代理请求会返回 401组件将进入错误态并显示错误信息hideErrors全局设置可控制是否展示错误详情错误排查Widget 出现异常时首先用浏览器直接访问http://spoolman地址/api/v1/spool确认服务本身可用再检查 homepage 配置中的url是否可达、认证是否匹配代理层会将非 2xx 响应回传为error组件会通过错误容器提示。小结spoolmanWidget 是 homepage 服务 Widget 体系中API 映射 服务端代理 受控渲染模式的典型范例只需在 docs/widgets/services/spoolman.md 描述的type/url/spoolIds三个核心配置项上做少量声明即可把 Spoolman 的耗材库存变成首页上一个实时、美观、信息密度适中的余量面板。配合 src/widgets/spoolman/widget.js 定义的端点映射、src/widgets/spoolman/component.jsx 的渲染规则以及 src/widgets/spoolman/component.test.jsx 的测试佐证你可以清楚地理解它的数据链路与行为边界并据此按需定制自己的打印监控面板。【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考