Unified Printer API HOME ASSISTANT · PRINTDECK INTEGRATION

Your printer becomes
part of your smart home.

Home Assistant can poll PrintDeck on your local network, turn its normalized printer data into entities, and react whenever a print changes state.

Automatic mDNS discovery One request, many sensors Protected by a bearer token Klipper and Bambu Lab
THE IDEA

PrintDeck translates.
Home Assistant reacts.

The PrintDeck integration discovers compatible devices, asks for the Unified API token in the Home Assistant interface and creates the available printer entities automatically.

01

Finished print

Turn on a lamp, send a phone notification or announce that the part is ready.

02

Progress milestones

React when progress crosses 25%, 50% or 75% to change an indicator light or update a dashboard.

03

Job paused or stopped

React to paused, failed or cancelled jobs before returning to the workshop.

04

Workshop overview

Show connection, temperatures, remaining time and the current layer on one local dashboard.

START HERE · NO YAML REQUIRED

No configuration.yaml.
Set it up in the interface.

HACS installs the maintained PrintDeck integration. After that, everything happens in the normal Home Assistant interface: discovery, token entry, devices, sensors and automations.

Same local networkHome Assistant and PrintDeck must be able to reach each other.

Current PrintDeck firmwareUpdate the monitor before connecting the integration.

HACS installedIf you do not have HACS yet, install it first using the official guide.

  1. 01

    Enable the API in PrintDeck

    Open PrintDeck Web Config, choose Settings > Unified Printer API, enable it and copy the generated token. Keep it private; you will paste the raw token into Home Assistant without adding the word Bearer.

  2. 02

    Add PrintDeck to HACS

    Use the button below. It opens the PrintDeck custom repository directly in HACS. If the button cannot reach your Home Assistant, use the manual path shown underneath.

    Open PrintDeck in HACS
    Add the repository manually

    Open HACS > Integrations > three-dot menu > Custom repositories. Paste https://github.com/PrintDeck/home-assistant, choose Integration as the type, then select Add.

    Read the official HACS custom repository guide
  3. 03

    Download and restart

    In HACS, select PrintDeck, choose Download and install the newest version. Restart Home Assistant when HACS asks. Refreshing the browser is not a restart.

  4. 04

    Add the integration

    Open Settings > Devices & services > Add integration and search for PrintDeck. Choose a discovered monitor, or enter printdeck.local or its local IP address. Paste the raw Unified API token and submit.

  5. 05

    Name and assign

    Home Assistant shows the PrintDeck monitor and every configured printer. Rename them or assign areas if useful, then choose Finish. Use Add hub only when you have another physical PrintDeck monitor.

  6. 06

    Confirm the entities

    Open the PrintDeck integration. You should see one hub and a device for every printer. Each printer exposes progress, phase, activity, temperatures, layers, time, connection data, network address and network port when available.

    Printers stay synchronized automatically

    Add a printer in PrintDeck and Home Assistant creates its device and entities after the next polling cycle. Remove a printer and integration version 0.1.2 or newer removes its Home Assistant device and entities after the next complete refresh. A temporary connection problem never triggers cleanup. Deleting a printer intentionally breaks automations that reference its entities; edit the saved printer instead if only its address changed.

YOUR FIRST AUTOMATION

Turn on one light
when progress reaches 75%.

This example uses the visual automation editor. It works with any percentage, including 82% or 88%.

  1. WHEN

    Choose Numeric state, select the printer's Print progress entity and set Above to 74.9.

  2. AND IF

    Choose State, select the same printer's Print phase entity and set the state to Printing.

  3. THEN DO

    Choose Light: Turn on and select one light. Use Turn on rather than Toggle so the result is predictable.

  4. SAVE

    Give the automation a name and save it. Run actions tests only the light; a short print tests the trigger and condition.

Why 74.9 instead of 75?

Home Assistant's Above test is strict. A threshold of 74.9 triggers when the sensor first reports 75 or any higher value. The Printing condition prevents an old stored progress value from turning on the light while the printer is idle.

READY-MADE BLUEPRINTS

Prefer a guided form?

Import a blueprint, then choose the printer sensor and light from dropdowns in Home Assistant.

QUICK TROUBLESHOOTING

If something does not appear,
check these first.

PrintDeck is missing from Add integration

Confirm that HACS downloaded it, restart Home Assistant and refresh the browser after the restart.

Home Assistant asks for a firmware update

Update the PrintDeck monitor, then try the connection again. This message means the monitor does not yet advertise native integration support.

Cannot connect to the host

Keep Home Assistant and PrintDeck on the same local network. If printdeck.local does not resolve, enter the local IP shown by PrintDeck.

The token is rejected

Copy a fresh token from PrintDeck Web Config and paste it exactly. Do not add Bearer in the native integration form.

Progress is unavailable

Select that printer on PrintDeck so it has a full live connection. Some inactive printers expose only summary data.

The light did not turn on

Open the automation and choose Traces. The trace shows whether the progress trigger fired and whether the Printing condition passed.

HOME ASSISTANT EXAMPLE

Find PrintDeck in Add integration

Home Assistant Add integration search showing PrintDeck
Search for PrintDeck and select the result with the round PrintDeck icon.
HOME ASSISTANT EXAMPLE

Name the monitor and printers

Home Assistant Name and assign screen for a PrintDeck monitor and its printers
Areas are optional. Choose Skip and finish if you do not want to organize the devices yet.
HOME ASSISTANT EXAMPLE

A hub with its printer devices

PrintDeck integration page showing one hub and four printer devices
The hub represents the physical PrintDeck monitor. The rows below it are the printers configured on that monitor.
HOME ASSISTANT EXAMPLE

A complete progress automation

Home Assistant automation with progress trigger, Printing condition and Turn on light action
This working example uses 82%. For 75%, enter Above 74.9 and keep the same Printing condition.
TROUBLESHOOTING EXAMPLE

Firmware update required

Home Assistant PrintDeck connection form showing a firmware update warning
This is an error example, not the expected success screen. Update PrintDeck and submit the connection again.
MANUAL REST FALLBACK

Prefer YAML?
Connect one state and one light.

The native integration above is recommended. Open this advanced fallback only when HACS cannot be used or you deliberately want to maintain the REST sensors yourself.

Show the manual REST instructions
  1. 01

    Enable the API

    Open Web Config on PrintDeck, choose Unified Printer API, enable it and copy the generated access token.

  2. 02

    Find the printer ID

    Request the printer list and note the ID of the printer you want to watch.

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

    Keep the token in secrets.yaml

    Include the word Bearer in the secret value.

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

    Add the phase sensor

    This makes one request every 10 seconds. Change PRINTDECK-IP and printer ID 1 in the URL.

    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

    Check and restart Home Assistant

    Validate the YAML in Developer Tools, restart Home Assistant, then confirm that the PrintDeck Phase entity has a value.

  6. 06

    Add the automation

    Replace light.living_room with the entity ID of your lamp.

    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

    Run a short test print

    Watch the phase entity move to completed. If the lamp does not switch on, open the automation trace to see the trigger and condition results.

ALL NORMALIZED STATES

Use broad phases
or detailed activities.

Job phase is best for most automations. Job activity exposes the detailed activities that drive PrintDeck reactions when the printer reports them.

Job phases

Every supported job phase value:

unknownidlepreparingprintingpausedcompletedfailedcancelled

Detailed activities

Every supported job activity value:

unknownstandbypreparingnozzle_heatingbed_heatinghomingbed_levelingnozzle_cleaningcalibratingfilament_changingfilament_unloadingfilament_loadingfilament_purgingprintingpausedcompletedfailedcancelled

You do not need one entity per value. The PrintDeck Activity sensor below moves between every listed activity, and an automation can react to the value you choose.

Connection and status values

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

Detailed activity availability depends on what the connected printer reports. The API value unknown uses PrintDeck's unavailable reaction as its fallback. A selected printer provides full live data; other saved printers may provide summary data at the configured Printer List Refresh interval.

COMPLETE STATUS SENSOR PACK

One API request.
Every detailed-status field.

The native integration creates these entities automatically. This YAML pack is kept for advanced manual REST installations.

Show the complete manual sensor 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
Before you restart

Keep the matching token in secrets.yaml, replace PRINTDECK-IP and printer ID 1. If configuration.yaml already has a top-level rest section, add this resource below it instead of creating a second rest key.

GOOD TO KNOW

Local by design.
Read-only by design.

Home Assistant polls PrintDeck; PrintDeck does not send webhooks. Keep both devices on a trusted local network and do not expose the API port to the internet. The integration stores its token in the Home Assistant config entry; manual REST setups should keep it in secrets.yaml.

Progress, temperatures and reaction-level activities are fullest for the printer currently selected on PrintDeck. Connection and summary job state remain useful for other saved printers.

Return to the Unified Printer API

MQTT for your local tools

PrintDeck sends normalized printer data to a local broker such as Mosquitto. Your apps subscribe to updates instead of repeatedly requesting them through the REST API. HTTP and MQTT can run independently or together.

01

Status updates

Receive job state, progress, temperatures and availability in your dashboards or Node-RED flows.

02

Print events

React to observed print starts, progress milestones and attention events. Live events are not retained or replayed after reconnecting.

03

Home Assistant Discovery

Let Home Assistant create devices and entities automatically through its built-in MQTT integration. Or choose PrintDeck through HACS with MQTT and keep standard Discovery off.