Use this skill whenever you need to control the workbench's WiFi radio for testing — starting a SoftAP for DUTs to connect to, joining a DUT's captive portal as a station, scanning for networks, relaying HTTP requests to devices on the WiFi network, or provisioning DUT WiFi credentials. Essential for any test that involves WiFi connectivity, captive portal flows, or HTTP communication with devices on the isolated test network (192.168.4.x). Triggers on "wifi", "AP", "station", "scan", "provision", "captive portal", "enter-portal", "HTTP relay", "wifi test", "SoftAP".
Base URL: http://workbench.local:8080
Before using any workbench API, ensure workbench.local resolves:
curl -s http://workbench.local:8080/api/info
If that fails, run the discovery script from the workbench repo:
sudo python3 .claude/skills/esp-idf-handling/discover-workbench.py --hosts
The workbench has two WiFi operating modes:
| Mode | wlan0 usage | WiFi endpoints |
|---|---|---|
| wifi-testing (default) | Test instrument (AP/STA/scan) | Active |
| serial-interface |
| Joins WiFi for additional LAN |
| Disabled |
# Check current mode
curl http://workbench.local:8080/api/wifi/mode
# Switch to wifi-testing mode
curl -X POST http://workbench.local:8080/api/wifi/mode \
-H 'Content-Type: application/json' \
-d '{"mode": "wifi-testing"}'
# Switch to serial-interface mode (joins a WiFi network)
curl -X POST http://workbench.local:8080/api/wifi/mode \
-H 'Content-Type: application/json' \
-d '{"mode": "serial-interface", "ssid": "MyNetwork", "pass": "password"}'
| Method | Path | Purpose |
|---|---|---|
| POST | /api/wifi/ap_start | Start WiFi AP (for DUT to connect to) |
| POST | /api/wifi/ap_stop | Stop WiFi AP |
| GET | /api/wifi/ap_status | Current AP state and connected clients |
| POST | /api/wifi/sta_join | Join an existing WiFi network as station |
| POST | /api/wifi/sta_leave | Disconnect from WiFi network |
| GET | /api/wifi/scan | Scan for nearby WiFi networks |
| POST | /api/wifi/http | HTTP relay — make HTTP requests via workbench's network |
| GET | /api/wifi/events | Long-poll for STA_CONNECT / STA_DISCONNECT events |
| POST | /api/enter-portal | Ensure device is on workbench AP — provision via captive portal if needed |
| GET | /api/wifi/ping | Quick connectivity check |
| POST | /api/wifi/mode | Set mode: wifi-testing or serial-interface |
| GET | /api/wifi/mode | Get current mode |
# Start AP
curl -X POST http://workbench.local:8080/api/wifi/ap_start \
-H 'Content-Type: application/json' \
-d '{"ssid": "TestAP", "pass": "testpass123", "channel": 6}'
# Check AP status and connected clients
curl http://workbench.local:8080/api/wifi/ap_status
# Stop AP
curl -X POST http://workbench.local:8080/api/wifi/ap_stop
AP and STA are mutually exclusive — starting one stops the other.
# Join a network
curl -X POST http://workbench.local:8080/api/wifi/sta_join \
-H 'Content-Type: application/json' \
-d '{"ssid": "MyNetwork", "pass": "password", "timeout": 15}'
# Disconnect
curl -X POST http://workbench.local:8080/api/wifi/sta_leave
curl http://workbench.local:8080/api/wifi/scan
To test a device's behavior when WiFi connectivity is lost and restored:
# 1. Ensure device is connected to workbench AP
curl -X POST http://workbench.local:8080/api/wifi/ap_start \
-H 'Content-Type: application/json' \
-d '{"ssid": "TestAP", "pass": "testpass123"}'
# 2. Stop AP — device loses WiFi
curl -X POST http://workbench.local:8080/api/wifi/ap_stop
# 3. Monitor device behavior (serial or UDP logs)
# ... wait for desired duration ...
# 4. Restart AP — device should reconnect
curl -X POST http://workbench.local:8080/api/wifi/ap_start \
-H 'Content-Type: application/json' \
-d '{"ssid": "TestAP", "pass": "testpass123"}'
# 5. Wait for device to reconnect
curl "http://workbench.local:8080/api/wifi/events?timeout=30"
IMPORTANT: Devices on the workbench AP (192.168.4.x) are NOT directly reachable from the development machine. Always use this relay to make HTTP requests to device endpoints (e.g. /status, /ota). The response body is base64-encoded — decode it to get the actual JSON.
# GET request to device
curl -X POST http://workbench.local:8080/api/wifi/http \
-H 'Content-Type: application/json' \
-d '{"method": "GET", "url": "http://192.168.4.2/status", "timeout": 10}'
# POST with base64-encoded body
BODY=$(echo -n '{"key":"value"}' | base64)
curl -X POST http://workbench.local:8080/api/wifi/http \
-H 'Content-Type: application/json' \
-d "{\"method\": \"POST\", \"url\": \"http://192.168.4.2/config\", \"headers\": {\"Content-Type\": \"application/json\"}, \"body\": \"$BODY\", \"timeout\": 10}"
# Decode the base64 response body
curl -s -X POST http://workbench.local:8080/api/wifi/http \
-H 'Content-Type: application/json' \
-d '{"method": "GET", "url": "http://192.168.4.x:8080/endpoint", "timeout": 10}' \
| python3 -c "import json,sys,base64; r=json.load(sys.stdin); print(base64.b64decode(r['body']).decode())"
Long-poll for STA_CONNECT / STA_DISCONNECT events:
curl "http://workbench.local:8080/api/wifi/events?timeout=30"
Ensures a device is connected to the workbench AP. If the device has no WiFi credentials, the workbench provisions it via the device's captive portal.
curl -X POST http://workbench.local:8080/api/enter-portal \
-H 'Content-Type: application/json' \
-d '{"portal_ssid": "iOS-Keyboard-Setup", "ssid": "TestAP", "password": "testpass123"}'
| Field | Description |
|---|---|
portal_ssid | Device's captive portal SoftAP name |
ssid | Workbench's AP SSID (filled into the device's portal form) |
password | Workbench's AP password (filled into the device's portal form) |
Procedure:
ssid/password) if not already runningportal_ssid)All three values must come from the project FSD — never guess them.
Monitor progress via GET /api/log.
Ensure device is connected to workbench AP:
POST /api/enter-portal with all three valuesGET /api/wifi/ap_status — verify device appears as connected clientTest device WiFi connectivity:
POST /api/enter-portal — ensure device is on workbench APPOST /api/wifi/http — relay HTTP to device's IP to verify it respondsTest WiFi disconnect/reconnect behavior:
POST /api/wifi/ap_stop — device loses WiFiPOST /api/wifi/ap_start — device should reconnectGET /api/wifi/events — confirm reconnection| Problem | Fix |
|---|---|
| AP won't start | Check that mode is wifi-testing via GET /api/wifi/mode |
| STA join timeout | Verify SSID/password; increase timeout |
| HTTP relay fails | Ensure workbench is on same network as target (AP or STA) |
| enter-portal "already running" | Previous run still active; wait for it to finish |
| No events from long-poll | DUT may not have connected yet; increase timeout |
| WiFi endpoints return "disabled" | System is in serial-interface mode; switch to wifi-testing |