API
Serial API
USB-C serial JSON command set for the Posture-Tracking Monitor Arm: read status, set positions, switch modes, store presets and tune tracking.
Serial API
Preliminary documentation. This product is in pre-launch preview; specifications and commands may change before shipping.
The arm appears as a USB serial device (115200 baud, 8N1). Each command is one line of JSON; each reply is one line of JSON.
Read status
{"cmd": "status"}
{"ok": true, "mode": "follow", "pos": {"height": 142, "depth": 80, "tilt": 6, "pan": -3},
"user": {"present": true, "distance_mm": 612}, "fw": "1.2.0"}
Positions are millimetres (height, depth) and degrees (tilt, pan).
Move
{"cmd": "move", "height": 180, "tilt": 5, "speed": 15}
Omitted axes stay where they are. speed is mm/s (max 20). Moving manually
switches the arm to manual mode.
Modes
{"cmd": "mode", "value": "follow"}
| Value | Behaviour |
|---|---|
follow |
Continuous tracking |
nudge |
Hold position, tilt up after 20 min of slouching |
manual |
No automatic movement |
Presets
{"cmd": "preset.save", "slot": "stand"}
{"cmd": "preset.go", "slot": "sit"}
Slots: sit, stand.
Tracking tuning
{"cmd": "tracking", "deadband_mm": 40, "delay_s": 3, "distance_mm": 600}
| Field | Default | Range | Meaning |
|---|---|---|---|
deadband_mm |
40 | 10–120 | Ignore head movement smaller than this |
delay_s |
3 | 1–30 | Movement must persist this long before the arm follows |
distance_mm |
600 | 450–800 | Target viewing distance |
Python example: stand at 2 pm
import json, serial, time
arm = serial.Serial("/dev/ttyACM0", 115200, timeout=1)
def send(**cmd):
arm.write((json.dumps(cmd) + "\n").encode())
return json.loads(arm.readline())
while True:
if time.strftime("%H:%M") == "14:00":
send(cmd="preset.go", slot="stand")
time.sleep(30)
Errors
Errors reply with {"ok": false, "error": "<code>"}. Codes: bad_json,
unknown_cmd, out_of_range, obstructed, overload.
Last updated 21 Sep 2026