Skip to content

octoprint

tested on simulator

Tier Tier 1
Protocol OctoPrint REST API over HTTP
Covers 3D printers connected to OctoPrint (Marlin, Prusa, RepRapFirmware and Klipper with the OctoPrint connector)
Hazard default medium
Conformance control
Tested with OctoPrint REST simulator over an HTTP mock transport

Estimated reach. Every OctoPrint install, on the order of a hundred thousand active printers. OctoPrint's anonymous usage statistics report on the order of a hundred thousand active instances, each driving one printer, and OctoPrint supports most serial printer firmwares. Anything OctoPrint can control exposes the same REST endpoints, so the driver covers them all at the level of temperatures, fan, homing and job control.

The octoprint driver talks to printers that OctoPrint controls, through OctoPrint's REST API. The driver reads temperatures, the printer state and job progress, sets heater targets and the part fan, and runs homing and job control. Channel names match the moonraker driver where the API allows it.

Driver nameoctoprint
Libraryhttpx 0.28.1 (BSD-3-Clause)
Extrauv tool install --compile-bytecode "openhal-hub[octoprint] @ git+https://github.com/sohan-bhat/OpenHAL"
Hazard defaultmedium
Safe statenative. Every heater in the file, plus tool0 and the bed, gets target 0
Self-describeyes, from the current printer profile

What it supports

Channel nameKindEndpoint
stateread, enum (standby, printing, paused, cancelling, error, offline)GET /api/printer, from state.flags
state_textread, stringstate.text, for example Operational
extruder_temp, bed_temp, chamber_tempread, temperaturetemperature.tool0, bed, chamber
progress, filenamereadGET /api/job (progress.completion, unknown with no job)
extruder_target, bed_target, chamber_targetwrite, temperaturePOST /api/printer/tool, /bed, /chamber with command: target
fan_speedwrite, percentPOST /api/printer/command with M106 P0 S0..255
home (arg axes x, y, z, xy or all)actionPOST /api/printer/printhead with command: home
pause, resume, cancelactionPOST /api/job

Other names need a map, such as { heater: tool1 } (or tool0 to tool9, bed, chamber) with field: actual or field: target for reads, and { heater: tool1 } or { fan: 1 } for writes. Actions take { command: home } and so on under another name.

Temperatures are degC on the wire and converted to the channel unit both ways.

How the protocol is handled

  • The API key comes from the environment variable named in token_env (default OCTOPRINT_API_KEY) and is sent as X-Api-Key. A missing variable fails the connect before any request, and a 403 means the key was refused.
  • OctoPrint returns 409 when the printer isn't connected or the operation doesn't fit the current state. The driver turns that into an error that says the printer can't do this now, and state reads offline.
  • health() reads /api/printer, and a printer that isn't operational counts as disconnected.
  • OctoPrint has no fan read, so fan_speed reads back the last value this driver sent, and unknown before the first write or after a failed one.
  • Homing is queued by OctoPrint and the request returns at once, so the action returns queued.

Setup

  1. Install the extra with uv tool install --compile-bytecode "openhal-hub[octoprint] @ git+https://github.com/sohan-bhat/OpenHAL".
  2. In OctoPrint, open Settings, Application Keys, and create a key for OpenHAL. A user with the Control permission is enough.
  3. Export the key, for example export OCTOPRINT_API_KEY=..., in the environment the hub runs in.
  4. Start from openhal/drivers/octoprint/examples/prusa-mk3s-octopi.hal.yaml.
  5. Validate with openhal file validate, then confirm the limits by hand.

Parameters

KeyDefaultMeaning
hostrequiredOctoPrint host name or address
port80HTTP port
schemehttphttp or https
pathemptyPrefix when OctoPrint runs under a sub path, for example /octoprint
token_envOCTOPRINT_API_KEYEnvironment variable that holds the API key
timeout5 sDeadline for each request

Example device file

device: { name: Prusa MK3S, manufacturer: Prusa Research }
id: mk3s
connect: { octoprint: octopi.local, token_env: OCTOPRINT_API_KEY }
read:
  state: { type: enum, values: [standby, printing, paused, cancelling, error, offline], every: 2 s }
  extruder_temp: { unit: degC, every: 2 s }
  bed_temp: { unit: degC, every: 2 s }
write:
  extruder_target: { unit: degC, min: 0, max: 260, max_change_per_s: 50, confirm: confirm }
  bed_target: { unit: degC, min: 0, max: 100, max_change_per_s: 20 }
  fan_speed: { unit: percent, min: 0, max: 100 }
actions:
  home: { args: { axes: { type: enum, values: [x, y, z, xy, all] } }, require: ["state != printing"] }
safe_state:
  - { extruder_target: 0, bed_target: 0, fan_speed: 0 }
hazard: medium

Known limitations

  • File upload, selection and starting prints are not exposed.
  • The fan speed can't be read from the printer, and a fan change made on the printer's own display isn't seen.
  • Because printer profiles don't record heater maxima, proposals from describe() use placeholder heater maxima (250, 100 and 60 degC), so lower the maxima to your printer's real limits.
  • The driver can't check the printer's firmware thermal protection, which remains the last line of defense.

Hazard defaults

The default hazard is medium, because heaters and moving axes can burn or pinch, so keep confirm: confirm on the hotend target and on home.

Sources