作为一个 3D 打印爱好者,随着折腾的时间越来越长,手里的耗材种类和数量肯定也会越来越多。特别是像我使用拓竹 H2S 这样的机器,各种颜色、各种材质的料盘堆满架子。每次打印前都要靠肉眼估算还剩多少料,常常提心吊胆怕中途断料。
为了彻底解决这个痛点,我花了一些时间,将我的 3D 打印机接入了家里的 Home Assistant (HA) 小主机,并在服务器上部署了专业的耗材管理软件 Spoolman。现在,只需在 HA 的控制面板上点选当前使用的耗材,打印完成后,系统就会自动从 Spoolman 中扣减消耗的重量,甚至还能自动生成待补货清单!
今天就把这套“自动化耗材库存系统”的搭建过程分享给大家。
一、 前提条件与准备工作(必看!)
在开始折腾之前,请确保你已经具备以下基础环境,并在 Home Assistant 中提前安装好需要的插件。
1. 基础环境准备:
Docker 环境: 你的服务器、NAS 或软路由上需要已经安装好 Docker 和 Docker Compose,用于后续部署 Spoolman 容器。
已安装 HACS 商店: 你的 Home Assistant 必须已经安装了 HACS (Home Assistant Community Store)。本教程中的很多高级功能都依赖它。
2. HACS 插件“采购清单”(请提前下载安装): 打开 HA 的 HACS 页面,提前搜索并下载以下插件:
🧩 核心集成 (Integrations) 篇:
Spoolman:搜索并下载,用于将 Spoolman 耗材系统的数据接入 HA。(注意:下载后需重启 HA 并在“配置-设备与服务”中添加)。
Bambu Lab:必须安装此集成。只有把它接入 HA,我们才能获取到打印机的实时状态(print_status)和耗材消耗重量(print_weight),这是实现自动化扣减的基石。(Klipper 用户请通过 Moonraker 接入)。
🎨 前端面板 (Frontend) 篇:
auto-entities:用于在控制面板上自动遍历和筛选 Spoolman 里的所有耗材,省去一个个手动添加实体的麻烦。
card-mod:用于自定义前端卡片的 CSS 样式。非常重要!你看到的耗材图标能根据实际线材颜色变色,全靠这个插件生效。
(前端插件下载完成后,请记得刷新浏览器页面或清理缓存让其生效)。
准备好这些后,我们就可以正式开始搭建了!
二、 最终效果展示
先来看看成果。我在 Home Assistant 中配置了一个专属的 3D 打印控制面板:

不仅可以监控打印机的实时状态(温度、进度、摄像头画面),下方还有所有耗材的详细档案。更棒的是,它能根据设定的阈值(例如 <150g),自动筛选出需要补货的耗材清单。

三、 第一步:部署 Spoolman 耗材管理系统
Spoolman 是一个非常优秀的开源 3D 打印耗材管理工具。我们首先需要在服务器上部署它。
项目开源地址: https://github.com/Donkie/Spoolman
1. 使用 Docker Compose 部署
新建一个目录,创建 docker-compose.yml 文件,填入以下内容:
version: '3.8'
services:
spoolman:
image: ghcr.io/donkie/spoolman:latest
container_name: spoolman
restart: unless-stopped
volumes:
# 将左侧的路径替换为你本地存放 Spoolman 数据的实际路径
- /path/to/your/spoolman/data:/home/app/.local/share/spoolman
ports:
- "7912:8000" # 左侧端口可自定义,右侧 8000 为容器内端口
environment:
- TZ=Asia/Shanghai # 设置时区
保存后,在终端运行 docker-compose up -d 即可启动服务。启动后,通过浏览器访问 http://服务器IP:7912 就可以进入 Spoolman 的界面了。
2. Spoolman 基础数据录入(按顺序)
第一次进入 Spoolman,你需要按照一定的逻辑层级来录入你的耗材信息。顺序非常重要:
添加制造商 (Vendors): 首先在系统中添加你常用的耗材品牌(例如:拓竹 Bambu Lab、eSUN 易生等)。
添加耗材 (Filaments): 接着,基于刚才添加的制造商,创建具体的耗材类型。填写材质(PLA、PETG 等)、颜色、密度以及整盘标准重量(通常是 1000g)。
添加料盘 (Spools): 最后,把你手上真正在用的每一卷料盘录入系统。选择刚才建好的“耗材”,系统会自动带入属性。你还可以记录料盘的存放位置(Location)。每个料盘生成后,都会有一个唯一的 ID,这是后续自动化的关键。

四、 第二步:将 Spoolman 接入 Home Assistant
Spoolman 部署好后,我们需要让 Home Assistant 能够读取它的数据并发送扣减指令。
1. 启用 HACS 集成:
打开 Home Assistant,进入左侧边栏的 HACS -> 集成 (Integrations)。
确认你已经下载了 "Spoolman"。
⚠️ 非常重要: 下载完成后,请务必重启一次 Home Assistant。
2. 配置并对接 Spoolman 服务器地址:
HA 重启完毕后,点击左侧边栏的 “配置” -> “设备与服务”。
点击右下角的 “添加集成” 按钮。
搜索 “Spoolman” 并点击弹出的选项。
在弹出的配置对话框中填入你第一步中部署的 Spoolman 完整访问地址(例如:http://192.168.1.100:7912)。
点击“提交”。对接成功后,HA 会自动拉取所有耗材数据并生成对应的实体(如 sensor.spoolman_filament_xxx)。
五、 第三步:配置 RESTful Command (连接 HA 与 Spoolman)
为了让 HA 能够在打印完成后告诉 Spoolman 扣减多少耗材,我们需要在 HA 的配置文件中定义一个接口调用指令。
打开 Home Assistant 配置目录下的 configuration.yaml 文件,添加以下内容:
# Spoolman 耗材扣减指令
rest_command:
spoolman_consume:
# 你的 spoolman 地址,注意替换括号部分
url: "http://(替换为你的spoolman地址)/api/v1/spool/{{ spool_id }}/use"
# ⚠️ 必须是 PUT,不能是 POST
method: PUT
# ⚠️ 加上 | float 确保发送纯数字格式
payload: '{"use_weight": {{ weight | float }}}'
content_type: 'application/json'
提示:添加完成后,记得在 HA 的“开发者工具”中点击“检查配置”并重启 Home Assistant 让配置生效。
六、 第四步:打造 HA 可视化控制台 (Lovelace UI)
数据接入后,我们需要用到提前安装好的 auto-entities 和 card-mod 插件来美化面板。
下面是我截图里用到的几个核心卡片的配置代码:
1. 耗材库存 (点击选择)
这个卡片会自动列出所有未归档的料盘。最重要的是,点击对应的耗材,就会把它的 ID 赋值给一个辅助元素 (input_text.current_spool),告诉系统“我正在用这卷料”。
(注意:使用此卡片前,请先在 HA 的“配置”->“设备与服务”->“辅助元素”中,新建一个名为 current_spool 的文本输入框)
type: custom:auto-entities
card:
type: grid
columns: 3
square: false
title: 🧵 耗材库存 (点击选择)
card_param: cards
filter:
template: |
{% set ns = namespace(cards=[]) %}
{# 1\. 筛选条件:名字含spool_,且未归档 #}
{% for s in states.sensor
| selectattr('entity_id', 'search', 'spoolman_spool_')
| selectattr('attributes.archived', 'defined')
| selectattr('attributes.archived', 'eq', false)
| sort(attribute='attributes.id') %}
{# 2\. 获取颜色 #}
{% set color = s.attributes.get('filament_color_hex', '999999') %}
{# 3\. 组合显示名称:#ID 名称 (去掉了厂商) #}
{% set display_name = '#' ~ s.attributes.id ~ ' ' ~ s.attributes.get('filament_name', '未知') %}
{# 4\. 副标题:材质 | 位置 #}
{% set sub_info = s.attributes.get('filament_material', '') ~ '\n📍' ~ s.attributes.get('location', '未知位置') %}
{# 5\. 定义卡片 #}
{% set this_card = {
"type": "button",
"entity": s.entity_id,
"name": display_name ~ '\n' ~ sub_info,
"icon": "mdi:printer-3d-nozzle",
"show_state": true,
"tap_action": {
"action": "call-service",
"service": "input_text.set_value",
"target": {"entity_id": "input_text.current_spool"},
"data": {"value": s.attributes.id}
},
"card_mod": {
"style": "ha-state-icon { color: #" ~ color ~ " !important; filter: drop-shadow(1px 1px 2px rgba(0,0,0,0.5)); } span { font-size: 12px !important; line-height: 1.2 !important; }"
}
} %}
{% set ns.cards = ns.cards + [this_card] %}
{% endfor %}
{{ ns.cards }}
2. 耗材档案与待补货清单
耗材档案卡片可以列出所有耗材的基本信息:
type: custom:auto-entities
card:
type: entities
title: 📋 耗材档案 (自动扫描)
state_color: true
filter:
include:
- options:
secondary_info: last-updated
entity_id: sensor.spoolman_filament_*
exclude:
- options: {}
state: unavailable
- options: {}
state: unknown
sort:
method: attribute
attribute: id
numeric: true
待补货清单使用 Markdown 卡片,利用 Jinja2 模板自动找出剩余重量小于 150g 的料盘:
YAML
type: markdown
title: 📉 待补货清单 (<150g)
content: >
| ID | 名称 | 剩余 |
| :--- | :--- | :--- |
{% for s in states.sensor | selectattr('entity_id', 'search', 'spoolman_filament_') %}
{% if s.state | float(0) < 150 and s.state | float(0) > 0 %}
| {{ s.attributes.id }} | {{ s.attributes.name }} | **{{ s.state }}g** 🔴 |
{% endif %}
{% endfor %}
七、 第五步:核心自动化——打印完成自动扣库存
最后一步,创建一个自动化:当打印机状态变为 "finish" 时,读取本次消耗重量,并调用 rest_command 从面板上选中的耗材中扣除。
💡 如何查找你的打印机实体 ID? 进入 HA 的『配置』 -> 『设备与服务』 -> 『实体』,搜索你的打印机名称。找到表示“打印状态”和“打印重量”的实体,点击即可看到实体 ID(例如:sensor.h2s_xxxxxx_print_status)。将下面代码中的 [打印机实际ID] 替换为你自己的。
✅ 自动化创建步骤:
在 HA 左侧边栏点击 “配置” -> “自动化与场景”。
点击右下角 “创建自动化” -> “创建全新的自动化”。
点击右上角的 三个点 (⋮) 菜单图标,选择 “在 YAML 中编辑”。
将默认代码删除,完整粘贴以下代码并保存:
alias: 3D打印完成-自动扣库存
description: 检测到打印机状态变为 finish 时,自动将消耗重量同步到 Spoolman
mode: single
triggers:
- entity_id:
- sensor.h2s_[打印机实际ID]_print_status
to: finish
trigger: state
conditions:
# 确保打印机状态不是未知或不可用
- condition: template
value_template: "{{ trigger.from_state.state not in ['unavailable', 'unknown'] }}"
# 确保我们已经选择了要扣减的耗材 ID
- condition: not
conditions:
- condition: state
entity_id: input_text.current_spool
state: ""
- condition: state
entity_id: input_text.current_spool
state: unknown
actions:
# 调用我们刚才在 configuration.yaml 里配置的服务扣减库存
- data:
spool_id: "{{ states('input_text.current_spool') }}"
weight: "{{ states('sensor.h2s_[打印机实际ID]_print_weight') }}"
action: rest_command.spoolman_consume
# 发送成功通知到 HA 面板
- data:
title: Spoolman 库存更新成功
message: |-
打印完成!
已扣减耗材 ID: {{ states('input_text.current_spool') }}
消耗重量: {{ states('sensor.h2s_[打印机实际ID]_print_weight') }} g
action: notify.persistent_notification
总结
经过上面的折腾,现在每次打印前,只需要在 HA 面板点一下正在用的料盘。打印结束后,系统会默默帮我把库存算好,快用完的还会自动列在补货清单里。这套工作流极大地缓解了我的“耗材焦虑”。
如果你也是一个喜欢折腾的 3D 打印玩家,强烈建议尝试一下这套方案!**