HTTP API (ESP32)
The ESP32 positioner firmware exposes a REST API for position control.
Base URL
Default: http://positioner.local
Override with MCPOSITIONER_HOST environment variable.
Endpoints
GET /status
Returns current positioner state.
Response:
{ "theta_deg": 45.0, "phi_deg": 90.0, "moving": false, "homed": true}| Field | Type | Description |
|---|---|---|
theta_deg | float | Current polar angle (0-180°) |
phi_deg | float | Current azimuth angle (0-360°) |
moving | bool | True if motors are moving |
homed | bool | True if homing completed |
POST /move
Move to absolute position.
Request:
{ "theta_deg": 90, "phi_deg": 45}Response:
{ "status": "moving", "target_theta": 90, "target_phi": 45}POST /move/relative
Move relative to current position.
Request:
{ "d_theta": 5, "d_phi": -10}Response:
{ "status": "moving", "target_theta": 95, "target_phi": 80}POST /home
Run sensorless homing.
Request:
{ "axis": "both"}Valid values for axis: "theta", "phi", "both"
Response:
{ "status": "homing", "axis": "both"}POST /stop
Emergency stop all motors.
Request: (empty body)
Response:
{ "status": "stopped"}GET /config
Get current motion parameters.
Response:
{ "speed": 2000, "accel": 1000, "microstepping": 16, "theta_steps_per_deg": 17.78, "phi_steps_per_deg": 17.78}POST /config
Update motion parameters.
Request:
{ "speed": 1500, "accel": 800}Only include fields you want to change.
Response:
{ "status": "ok", "speed": 1500, "accel": 800, "microstepping": 16}Error Handling
Errors return HTTP 4xx/5xx with JSON body:
{ "error": "description of the error"}Common errors:
| Code | Meaning |
|---|---|
| 400 | Invalid request (bad JSON, out of range) |
| 503 | Busy (already moving/homing) |
Example: curl
# Get statuscurl http://positioner.local/status
# Move to positioncurl -X POST http://positioner.local/move \ -H "Content-Type: application/json" \ -d '{"theta_deg": 90, "phi_deg": 0}'
# Home both axescurl -X POST http://positioner.local/home \ -H "Content-Type: application/json" \ -d '{"axis": "both"}'
# Emergency stopcurl -X POST http://positioner.local/stopExample: Python
import httpx
async def move_positioner(theta: float, phi: float): async with httpx.AsyncClient() as client: response = await client.post( "http://positioner.local/move", json={"theta_deg": theta, "phi_deg": phi} ) return response.json()