Unified Printer API HOME ASSISTANT · PRINTDECK 集成

让你的打印机
成为智能家居的一部分。

Home Assistant 可以在本地网络中轮询 PrintDeck,将标准化打印机数据转换为实体,并在打印状态变化时作出响应。

自动 mDNS 发现 一次请求,多个传感器 受 Bearer 令牌保护 Klipper 和 Bambu Lab
基本思路

PrintDeck 负责转换。
Home Assistant 作出响应。

PrintDeck 集成会发现兼容设备,在 Home Assistant 界面中请求 Unified API 令牌,并自动创建可用的打印机实体。

01

打印完成

打开灯具、向手机发送通知,或播报零件已经完成。

02

进度里程碑

当进度越过 25%、50% 或 75% 时作出响应,以更改指示灯或更新仪表板。

03

任务暂停或停止

在返回工作间之前,对暂停、失败或取消的任务作出响应。

04

工作间概览

在一个本地仪表板中显示连接、温度、剩余时间和当前层。

从这里开始 · 无需 YAML

无需 configuration.yaml。
在界面中完成设置。

HACS 会安装持续维护的 PrintDeck 集成。之后,发现、令牌输入、设备、传感器和自动化都在 Home Assistant 的常规界面中完成。

同一本地网络Home Assistant 和 PrintDeck 必须能够互相访问。

最新的 PrintDeck 固件连接集成前请更新显示器。

已安装 HACS如果尚未安装 HACS,请先按照官方指南进行安装。

  1. 01

    在 PrintDeck 中启用 API

    打开 PrintDeck Web Config,选择“设置”>“Unified Printer API”,启用后复制生成的令牌。请妥善保管;在 Home Assistant 中粘贴原始令牌时不要添加 Bearer。

  2. 02

    将 PrintDeck 添加到 HACS

    使用下方按钮可直接在 HACS 中打开 PrintDeck 自定义仓库。如果按钮无法访问你的 Home Assistant,请使用下方的手动路径。

    在 HACS 中打开 PrintDeck
    手动添加仓库

    打开 HACS > 集成 > 三点菜单 > 自定义仓库。粘贴 https://github.com/PrintDeck/home-assistant,类型选择“集成”,然后点击“添加”。

    阅读 HACS 自定义仓库官方指南
  3. 03

    下载并重启

    在 HACS 中选择 PrintDeck,点击“下载”并安装最新版本。HACS 提示时请重启 Home Assistant;刷新浏览器不等于重启。

  4. 04

    添加集成

    打开“设置”>“设备与服务”>“添加集成”并搜索 PrintDeck。选择已发现的显示器,或输入 printdeck.local 或其本地 IP 地址。粘贴原始 Unified API 令牌并提交。

  5. 05

    命名并分配

    Home Assistant 会显示 PrintDeck 显示器和每台已配置的打印机。可按需重命名或分配区域,然后选择“完成”。只有拥有另一台实体 PrintDeck 显示器时才使用“添加集线器”。

  6. 06

    确认实体

    打开 PrintDeck 集成。你应看到一个集线器以及每台打印机对应的设备。每台打印机会在数据可用时提供进度、阶段、活动、温度、层数、时间、连接信息、网络地址和网络端口。

    打印机自动保持同步

    在 PrintDeck 中添加打印机后,Home Assistant 会在下一次轮询时创建设备和实体。删除打印机后,0.1.2 或更高版本的集成会在下一次完整刷新时从 Home Assistant 中删除对应设备和实体。临时连接问题绝不会触发清理。删除打印机会有意中断引用其实体的自动化;如果只是地址发生变化,请改为编辑已保存的打印机。

你的第一个自动化

打开一盏灯
当进度达到 75% 时。

此示例使用可视化自动化编辑器,适用于任意百分比,包括 82% 或 88%。

  1. 当

    选择“数值状态”,选择打印机的“打印进度”实体,并将“高于”设为 74.9。

  2. 并且如果

    选择“状态”,选择同一打印机的“打印阶段”实体,并将状态设为 Printing。

  3. 然后执行

    选择“灯光:打开”并选择一盏灯。使用“打开”而不是“切换”,结果会更可预测。

  4. 保存

    为自动化命名并保存。“运行动作”只会测试灯光;短时间打印可测试触发器和条件。

为什么是 74.9 而不是 75?

Home Assistant 的“高于”判断是严格比较。阈值设为 74.9 后,传感器首次报告 75 或更高值时会触发。Printing 条件可防止打印机空闲时由旧的进度值打开灯光。

现成蓝图

更喜欢引导式表单?

导入蓝图,然后在 Home Assistant 的下拉列表中选择打印机传感器和灯光。

快速故障排除

如果某项没有出现,
请先检查这些项目。

“添加集成”中没有 PrintDeck

确认 HACS 已下载该集成,重启 Home Assistant,然后刷新浏览器。

Home Assistant 要求更新固件

更新 PrintDeck 显示器后再次尝试连接。此消息表示显示器尚未声明支持原生集成。

无法连接到主机

请让 Home Assistant 和 PrintDeck 位于同一本地网络。如果 printdeck.local 无法解析,请输入 PrintDeck 显示的本地 IP 地址。

令牌被拒绝

从 PrintDeck Web Config 复制新令牌并原样粘贴。不要在原生集成表单中添加 Bearer。

进度不可用

在 PrintDeck 上选择该打印机,使其获得完整的实时连接。部分未激活的打印机仅提供摘要数据。

灯光没有打开

打开自动化并选择“跟踪”。跟踪会显示进度触发器是否触发,以及 Printing 条件是否通过。

HOME ASSISTANT 示例

在“添加集成”中找到 PrintDeck

Home Assistant 添加集成搜索中显示 PrintDeck
搜索 PrintDeck,然后选择带有圆形 PrintDeck 图标的结果。
HOME ASSISTANT 示例

为显示器和打印机命名

PrintDeck 显示器及其打印机的 Home Assistant 命名和分配页面
区域是可选的。如果暂时不想整理设备,请选择“跳过并完成”。
HOME ASSISTANT 示例

包含打印机设备的集线器

PrintDeck 集成页面显示一个集线器和四台打印机设备
集线器代表实体 PrintDeck 显示器。其下方各行是该显示器上配置的打印机。
HOME ASSISTANT 示例

完整的进度自动化

包含进度触发器、Printing 条件和打开灯光动作的 Home Assistant 自动化
此有效示例使用 82%。若需 75%,请将“高于”设为 74.9,并保留相同的 Printing 条件。
故障排除示例

需要更新固件

Home Assistant PrintDeck 连接表单显示固件更新警告
这是错误示例,不是预期的成功页面。请更新 PrintDeck,然后重新提交连接。
手动 REST 备选方案

更喜欢 YAML?
连接一个状态和一盏灯。

建议使用上方的原生集成。仅在无法使用 HACS,或你明确希望自行维护 REST 传感器时,才展开此高级备用方案。

显示手动 REST 说明
  1. 01

    启用 API

    在 PrintDeck 上打开 Web Config,选择 Unified Printer API,将其启用并复制生成的访问令牌。

  2. 02

    查找打印机 ID

    请求打印机列表,并记下要监控的打印机 ID。

    Terminal
    curl http://PRINTDECK-IP/v1/printers \
      -H 'Authorization: Bearer pd_your_token_here'
  3. 03

    将令牌保存在 secrets.yaml 中

    在密钥值中包含 Bearer 一词。

    secrets.yaml
    printdeck_api_bearer: "Bearer pd_your_token_here"
  4. 04

    添加阶段传感器

    这会每 10 秒发送一次请求。请更改 URL 中的 PRINTDECK-IP 和打印机 ID 1。

    configuration.yaml
    rest:
      - resource: "http://PRINTDECK-IP/v1/printers/1/status"
        method: GET
        headers:
          Authorization: !secret printdeck_api_bearer
        scan_interval: 10
        timeout: 5
        sensor:
          - name: "PrintDeck Phase"
            unique_id: printdeck_printer_1_phase
            value_template: "{{ value_json.status.job.phase }}"
  5. 05

    检查并重启 Home Assistant

    在开发者工具中验证 YAML,重启 Home Assistant,然后确认 PrintDeck Phase 实体具有值。

  6. 06

    添加自动化

    请将 light.living_room 替换为你的灯具实体 ID。

    automations.yaml
    - alias: "PrintDeck - light on when print completes"
      id: printdeck_light_on_when_print_completes
      triggers:
        - trigger: state
          entity_id: sensor.printdeck_phase
          to: "completed"
      conditions:
        - condition: template
          value_template: >-
            {{ trigger.from_state is not none and
               trigger.from_state.state in ['preparing', 'printing', 'paused'] }}
      actions:
        - action: light.turn_on
          target:
            entity_id: light.living_room
      mode: single
  7. 07

    运行一次简短的测试打印

    观察阶段实体变为 completed。如果灯具未开启,请打开自动化跟踪以查看触发器和条件结果。

所有标准化状态

使用概括阶段
或详细活动。

任务阶段最适合大多数自动化。打印机上报任务活动时,该字段会提供驱动 PrintDeck 反应的详细活动。

任务阶段

所有支持的任务阶段值:

unknownidlepreparingprintingpausedcompletedfailedcancelled

详细活动

所有支持的任务活动值:

unknownstandbypreparingnozzle_heatingbed_heatinghomingbed_levelingnozzle_cleaningcalibratingfilament_changingfilament_unloadingfilament_loadingfilament_purgingprintingpausedcompletedfailedcancelled

无需为每个值创建一个实体。下方的 PrintDeck Activity 传感器会在所有列出的活动之间切换,自动化可对你选择的值作出响应。

连接和状态值

connection.state
stopped waiting_for_network connecting online offline
connection.reachability
unknown online offline
connection.detail_level
summary full
job.kind
print calibration

详细活动是否可用取决于已连接打印机上报的数据。API 值 unknown 会使用 PrintDeck 的 unavailable 反应作为后备。当前选中的打印机提供完整实时数据;其他已保存的打印机可能会按照配置的打印机列表刷新间隔提供摘要数据。

完整状态传感器包

一个 API 请求。
每个详细状态字段。

原生集成会自动创建这些实体。此 YAML 包保留用于高级手动 REST 安装。

显示完整的手动传感器 YAML
configuration.yaml
rest:
  - resource: "http://PRINTDECK-IP/v1/printers/1/status"
    method: GET
    headers:
      Authorization: !secret printdeck_api_bearer
    scan_interval: 10
    timeout: 5
    sensor:
      - name: "PrintDeck Printer ID"
        unique_id: printdeck_printer_1_id
        value_template: "{{ value_json.status.printer_id }}"

      - name: "PrintDeck Connection"
        unique_id: printdeck_printer_1_connection
        value_template: "{{ value_json.status.connection.state }}"

      - name: "PrintDeck Reachability"
        unique_id: printdeck_printer_1_reachability
        value_template: "{{ value_json.status.connection.reachability }}"

      - name: "PrintDeck Detail Level"
        unique_id: printdeck_printer_1_detail_level
        value_template: "{{ value_json.status.connection.detail_level }}"

      - name: "PrintDeck Update Marker"
        unique_id: printdeck_printer_1_updated_at_ms
        value_template: "{{ value_json.status.connection.updated_at_ms }}"
        unit_of_measurement: "ms"

      - name: "PrintDeck Phase"
        unique_id: printdeck_printer_1_phase
        value_template: "{{ value_json.status.job.phase }}"

      - name: "PrintDeck Job Kind"
        unique_id: printdeck_printer_1_job_kind
        value_template: "{{ value_json.status.job.kind }}"

      - name: "PrintDeck Activity"
        unique_id: printdeck_printer_1_activity
        value_template: "{{ value_json.status.job.activity }}"

      - name: "PrintDeck Job Name"
        unique_id: printdeck_printer_1_job_name
        value_template: "{{ value_json.status.job.name | default('none', true) }}"

      - name: "PrintDeck Progress"
        unique_id: printdeck_printer_1_progress
        value_template: "{{ value_json.status.job.progress_percent }}"
        availability: >-
          {{ value_json.status.connection.detail_level == 'full' and
             not value_json.status.connection.stale }}
        unit_of_measurement: "%"

      - name: "PrintDeck Elapsed"
        unique_id: printdeck_printer_1_elapsed
        value_template: "{{ value_json.status.job.elapsed_seconds }}"
        availability: >-
          {{ value_json.status.connection.detail_level == 'full' and
             not value_json.status.connection.stale }}
        device_class: duration
        unit_of_measurement: "s"

      - name: "PrintDeck Remaining"
        unique_id: printdeck_printer_1_remaining
        value_template: "{{ value_json.status.job.remaining_seconds }}"
        availability: "{{ not value_json.status.connection.stale }}"
        device_class: duration
        unit_of_measurement: "s"

      - name: "PrintDeck Current Layer"
        unique_id: printdeck_printer_1_current_layer
        value_template: "{{ value_json.status.job.current_layer }}"
        availability: >-
          {{ value_json.status.connection.detail_level == 'full' and
             not value_json.status.connection.stale }}

      - name: "PrintDeck Total Layers"
        unique_id: printdeck_printer_1_total_layers
        value_template: "{{ value_json.status.job.total_layers }}"
        availability: >-
          {{ value_json.status.connection.detail_level == 'full' and
             not value_json.status.connection.stale }}

      - name: "PrintDeck Nozzle Temperature"
        unique_id: printdeck_printer_1_nozzle_temperature
        value_template: "{{ value_json.status.temperatures.nozzle_current_c }}"
        availability: >-
          {{ value_json.status.temperatures.nozzle_current_c is not none and
             not value_json.status.connection.stale }}
        device_class: temperature
        state_class: measurement
        unit_of_measurement: "°C"

      - name: "PrintDeck Nozzle Target"
        unique_id: printdeck_printer_1_nozzle_target
        value_template: "{{ value_json.status.temperatures.nozzle_target_c }}"
        availability: >-
          {{ value_json.status.temperatures.nozzle_target_c is not none and
             not value_json.status.connection.stale }}
        device_class: temperature
        unit_of_measurement: "°C"

      - name: "PrintDeck Bed Temperature"
        unique_id: printdeck_printer_1_bed_temperature
        value_template: "{{ value_json.status.temperatures.bed_current_c }}"
        availability: >-
          {{ value_json.status.temperatures.bed_current_c is not none and
             not value_json.status.connection.stale }}
        device_class: temperature
        state_class: measurement
        unit_of_measurement: "°C"

      - name: "PrintDeck Bed Target"
        unique_id: printdeck_printer_1_bed_target
        value_template: "{{ value_json.status.temperatures.bed_target_c }}"
        availability: >-
          {{ value_json.status.temperatures.bed_target_c is not none and
             not value_json.status.connection.stale }}
        device_class: temperature
        unit_of_measurement: "°C"

      - name: "PrintDeck Chamber Temperature"
        unique_id: printdeck_printer_1_chamber_temperature
        value_template: "{{ value_json.status.temperatures.chamber_current_c }}"
        availability: >-
          {{ value_json.status.temperatures.chamber_current_c is not none and
             not value_json.status.connection.stale }}
        device_class: temperature
        state_class: measurement
        unit_of_measurement: "°C"

    binary_sensor:
      - name: "PrintDeck Data Stale"
        unique_id: printdeck_printer_1_data_stale
        value_template: "{{ value_json.status.connection.stale }}"
        device_class: problem

      - name: "PrintDeck Online"
        unique_id: printdeck_printer_1_online
        value_template: "{{ value_json.status.connection.state == 'online' }}"
        device_class: connectivity
重新启动前

请将对应令牌保存在 secrets.yaml 中,并替换 PRINTDECK-IP 和打印机 ID 1。如果 configuration.yaml 已有顶层 rest 部分,请在其下添加此资源,不要创建第二个 rest 键。

值得了解

专为本地运行而设计。
专为只读访问而设计。

Home Assistant 会轮询 PrintDeck;PrintDeck 不发送 Webhook。请将两台设备置于受信任的本地网络中,不要将 API 端口暴露到互联网。集成会把令牌保存在 Home Assistant 配置条目中;手动 REST 设置应将其保存在 secrets.yaml 中。

当前在 PrintDeck 中选中的打印机可提供最完整的进度、温度和反应级详细活动。其他已保存打印机仍可提供连接信息和摘要任务状态。

返回 Unified Printer API

为本地工具提供 MQTT

PrintDeck 将统一格式的打印机数据发送到 Mosquitto 等本地代理。应用订阅更新,无需反复请求 REST API。HTTP 和 MQTT 可以独立运行,也可以同时使用。

01

状态更新

在仪表板或 Node-RED 流程中接收任务状态、进度、温度和可用性信息。

02

打印事件

对检测到的打印开始、进度里程碑和需关注事件作出响应。实时事件不会保留,也不会在重新连接后重放。

03

Home Assistant 自动发现

让 Home Assistant 通过内置 MQTT 集成自动创建设备和实体。也可以通过 HACS 使用 PrintDeck 的 MQTT 连接,此时请关闭标准自动发现。