Skip to content

Quickstart

This guide runs the demo, an agent keeping an eye on a simulated 3D print, then a Hub you control with the simulated Arduino plant waterer. Nothing in this guide touches real hardware.

You need Python 3.12 or newer and uv.

Run the demo

$ git clone https://github.com/sohan-bhat/OpenHAL
$ cd OpenHAL
$ uv run openhal demo

The demo starts a hub with a simulated Klipper printer and its camera, and connects an agent to watch a print. The agent reads camera frames and warms the bed, the hub refuses the agent's request for a nozzle temperature above the limit, and the agent pauses the print and requests a cancel. Because a cancel can't be undone, the cancel waits for a person, and the owner approves the cancel over the same protocol. The demo prints this trace.

  1. Comment the agent checks the first layer
  2. Request
    hal/read { "device": "printer-cam", "channel": "frame" }
  3. Response
    result { "value": { "mimeType": "image/jpeg", "bytes": 19409, "width": 640, "height": 480, "data": "…" } }
  4. Comment a corner of the first layer is lifting
  5. Request
    hal/write { "device": "printer", "channel": "bed_target", "value": 70, "unit": "degC" }
  6. Response
    result { "status": "done" }
  7. Comment a hotter nozzle might help the corner stick
  8. Request
    hal/write { "device": "printer", "channel": "extruder_target", "value": 300, "unit": "degC" }
  9. Response
    error -32010 LIMIT_EXCEEDED extruder_target 300 degC exceeds the limit of 260 degC (printer.hal.yaml, confirmed by owner 2026-10-24)
  10. Comment later the agent checks the print again
  11. Request
    hal/read { "device": "printer-cam", "channel": "frame" }
  12. Response
    result { "value": { "mimeType": "image/jpeg", "bytes": 23567, "width": 640, "height": 480, "data": "…" } }
  13. Comment the print has come loose
  14. Request
    hal/action { "device": "printer", "action": "pause" }
  15. Response
    result { "status": "done" }
  16. Comment cancelling can't be undone
  17. Request
    hal/action { "device": "printer", "action": "cancel" }
  18. Response
    result { "status": "pending", "requestId": "REQUEST_ID", "expiresInS": 300 }
  19. Comment the owner approves the cancel
  20. Request
    hal/confirmations/approve { "requestId": "REQUEST_ID" }
  21. Response
    result { "status": "done" }

Run the whole system

$ uv run openhal demo --full
  soil_moisture rises from 31 % to 46 %
<- error -32010 LIMIT_EXCEEDED

--full runs the whole system with the Arduino plant waterer, starting from a hub with no devices that discovers the simulated board. The driver writer drafts the board's Device File from the board and the sketch, and a script answers the limits interview as a person would. An agent then connects through openhal mcp and drafts a routine, which a person enables. The routine waters the plant. Because 120 s is above the duration limit, the agent's request to water for 120 s never reaches the board. Every step is recorded in e2e.yaml.

Run the hub yourself

init creates ~/.openhal with a human token and a Device File for the simulated plant waterer. The file is read-only until a person confirms its limits.

$ uv run openhal init
sample device  ~/.openhal/devices/plant-waterer.hal.yaml created, read-only until you confirm it
$ uv run openhal file confirm ~/.openhal/devices/plant-waterer.hal.yaml
action  water
$ uv run openhald &
$ uv run openhal status
devices 1 of 1 connected

The hub listens on 127.0.0.1:7420 only.

Send two commands

$ uv run openhal action plant-waterer.water duration=120s
blocked above_max  Blocked. The duration limit is 30 s (max). Asked for 120 s.
$ uv run openhal action plant-waterer.water duration=20s
done  Done. water ran.

Because the duration in the first command is above the limit, the Safety Kernel refused the command before anything reached the board. Over the protocol, the hub returns the same refusal as error -32010 LIMIT_EXCEEDED.

Stop

Any client may stop every device, but lifting the stop takes the human token and the typed phrase unlock.

$ uv run openhal stop
plant-waterer  safe
$ uv run openhal unlock

Next