## HAAC Plotter API

This document describes two layers:

- **Firmware commands (Pico)**: line-based text protocol
- **REST API (Backend)**: triggers firmware commands from web/apps

### 1) Firmware command protocol (Pico)

Commands are line-based and end with a newline.

#### Basic commands

- `PENUP`
- `PENDOWN`
- `STOP`
- `WAIT`
- `STATUS`

#### Motion

- `X<steps>` (e.g. `X200`, `X-200`)
- `Y<steps>`
- `MOVE X<steps> Y<steps>`

#### Speed

- `SPEED <interval_us>`
  - Example: `SPEED 1200`
  - Minimum: 200µs

#### Servo (optional)

- `SERVO_MODE ANGLE|CR`
- `SERVO <value>`
  - In `CR` mode: microsecond pulse width
  - In `ANGLE` mode: degrees (0..180)
- `SERVO_STOP_US <us>`
- `PENUP_US <us>`
- `PENDOWN_US <us>`
- `PENUP_MS <ms>`
- `PENDOWN_MS <ms>`
- `PENUP_ANGLE <deg>`
- `PENDOWN_ANGLE <deg>`

Firmware file: `pico/main.py`

### 2) REST API (Backend)

Base URL:

- `http://localhost:3001/api`

Notes:

- Endpoints require **JWT auth** (Authorization: Bearer …).
- Allowed roles: `manager`, `instructor`, `ta`, `fab_student`
- Local demo auth bypass: `PLOTTER_AUTH_DISABLED=1`

#### GET `/plotter/health`

Returns plotter service status.

Example response:

- `status: "ok"`
- `plotter.portPath`, `plotter.baudRate`, `plotter.isOpen`

#### POST `/plotter/command`

Sends a single line command to the firmware and attempts to capture the `OK/ERR` response.

Body:

- `command`: string (e.g. `"PENUP"` or `"MOVE X200 Y-200"`)
- `timeoutMs`: number (optional, 200..20000)

Example response:

- `ok`: boolean
- `terminalLine`: string | undefined
- `lines`: string[]

#### POST `/plotter/job`

Runs a multi-command “job” sequentially.

Body (choose one):

- `script`: string (multi-line; blank lines and lines starting with `#` are ignored)
- `commands`: string[] (pre-split commands)

Options:

- `timeoutMs`: number (per-command, 200..20000; default 4000)
- `stopOnError`: boolean (default true)

Response:

- `ok`: boolean
- `results`: array of `{ command, ok, terminalLine, lines }`

### Configuration (Backend env)

- `PLOTTER_SERIAL_PORT` (default `/dev/ttyACM0`)
- `PLOTTER_BAUD_RATE` (default `115200`)
- `PLOTTER_ONLY=1` (start server without DB init; plotter-only demo)
- `PLOTTER_AUTH_DISABLED=1` (disable auth on plotter routes; local demo only)

