Install
openclaw skills install @rockets-cn/k10-compile-serverUse when compiling UNIHIKER K10 PlatformIO projects via the K10 Compile Server (HTTPS port 8900), opening the browser Web Serial flash page for a compiled build, downloading firmware, flashing a K10 connected to the compile server, or optionally uploading compiled firmware with local esptool. Prefer this skill over local pio run when the user wants LAN server compilation and client-side flashing without installing PlatformIO or esptool.
openclaw skills install @rockets-cn/k10-compile-serverThe K10 Compile Server is a FastAPI service running on port 8900 (HTTPS) that compiles UNIHIKER K10 PlatformIO projects remotely. Instead of installing PlatformIO + toolchains locally, submit the project with the helper script, get a build_id, and flash from the browser with Web Serial.
Use an existing LAN server, or self-host one from the public server repo:
https://github.com/rockets-cn/unihiker-k10-compile-server
Self-hosting details live in references/server-setup.md. The Docker setup persists PlatformIO packages/toolchains in the named volume pio-data, so docker compose down && docker compose up -d keeps the K10 toolchain cache.
If platformio.ini references partitions.csv, the server expects that file to be present. It returns an error instead of silently generating a partition table.
服务器地址: 必须来自用户提供的服务器 URL、COMPILE_SERVER 环境变量,或项目/对话中已经明确确认过的地址。不要猜测、不要写死公共域名;如果不知道服务器地址,先问用户:“你的 K10 编译服务器地址是什么(例如 https://k10.example.com:8900)?”
# 方式 A:环境变量(推荐,一次设置一直用)
export COMPILE_SERVER=https://your-k10-compile-server.example.com:8900
# 方式 B:每次命令指定
bash k10-compile-server/scripts/compile-project.sh \
--server https://your-k10-compile-server.example.com:8900 \
--dir /path/to/k10-project \
--web-serial
自建服务器时,把上面的地址替换为 https://<server-ip>:8900 或你的域名。
# 方式 A:环境变量(推荐,设一次就不用每次都写 --server)
export COMPILE_SERVER=https://your-k10-compile-server.example.com:8900
# Recommended: compile remotely, then open the preloaded Web Serial flash page.
bash k10-compile-server/scripts/compile-project.sh \
--server $COMPILE_SERVER \
--dir /path/to/k10-project \
--web-serial
On Windows clients, prefer the PowerShell helper so the workflow does not depend on WSL networking or Unix zip:
.\k10-compile-server\scripts\compile-project.ps1 `
-Server https://your-k10-compile-server.example.com:8900 `
-Dir C:\path\to\k10-project `
-WebSerial
The helper compiles the project, waits for completion, then opens:
https://<server-ip>:8900/?build_id=<build_id>
Use Chrome/Edge, click "浏览器烧录", choose the K10 serial port, and let the page flash and reset the board.
Do not tell users to manually upload files in the web page or type a build ID for the normal workflow. The normal workflow is helper script → completed build_id → auto-open ?build_id=<build_id> → click browser flash. Manual web upload is only a fallback when the helper script cannot be used.
Choose the upload mode explicitly:
| Goal | Use |
|---|---|
| Compile remotely and flash from browser without local upload tools | --web-serial or -WebSerial |
| Compile only and download firmware | --output ./firmware.bin or -Output .\firmware.bin |
| Flash a K10 plugged into the compile server | --flash or -Flash |
| Upload from this client with local esptool instead of browser | --upload-local --port <port> or -UploadLocal -Port COM3 |
Check if the server is running:
sudo systemctl status k10-compile-server 2>/dev/null || echo "not running as service"
Health check API:
curl -k https://localhost:8900/api/health
Expected response:
{
"status": "ok",
"k10_toolchain_ready": true,
"active_compiles": 0,
"waiting_in_queue": 0
}
Restart server:
cd /path/to/unihiker-k10-compile-server/server
bash restart.sh
Use this section only when the helper scripts cannot be used. For normal use, prefer --web-serial / -WebSerial.
The server accepts projects via POST /api/compile (zip) or POST /api/compile/files (multi-file). The zip method is simplest for scripted use:
# Zip the project (must contain platformio.ini + src/*.cpp)
cd /path/to/k10-project
zip -r /tmp/k10-project.zip . \
-x ".pio/*" ".git/*" "build/*"
SERVER="${COMPILE_SERVER:?Set COMPILE_SERVER to your K10 compile server URL first}"
# Upload zip → get build_id
RESP=$(curl -sk -X POST "$SERVER/api/compile" \
-F "file=@/tmp/k10-project.zip")
BUILD_ID=$(echo "$RESP" | python3 -c "import sys,json;print(json.load(sys.stdin)['build_id'])")
echo "Build ID: $BUILD_ID"
while true; do
STATUS=$(curl -sk "$SERVER/api/build/$BUILD_ID/status")
STATE=$(echo "$STATUS" | python3 -c "import sys,json;print(json.load(sys.stdin)['status'])")
echo "Status: $STATE"
if [ "$STATE" = "done" ]; then
echo "Compile complete!"
SIZE=$(echo "$STATUS" | python3 -c "import sys,json;print(json.load(sys.stdin)['bin_size'])")
echo "Firmware size: $((SIZE/1024)) KB"
break
elif [ "$STATE" = "error" ]; then
echo "Compile failed!"
echo "$STATUS" | python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get('error',''),d.get('log','')[-500:])"
exit 1
fi
sleep 3
done
# Download combined firmware.bin
curl -sk -o firmware.bin "$SERVER/api/build/$BUILD_ID/download"
ls -lh firmware.bin
Or get individual flash files with their offsets:
# Get flash manifest (files + offsets)
curl -sk "$SERVER/api/build/$BUILD_ID/flash-files" | python3 -m json.tool
# Download each file
for FILE in bootloader partitions firmware; do
curl -sk -o "${FILE}.bin" "$SERVER/api/build/$BUILD_ID/file/${FILE}.bin"
done
The standard ESP32-S3 flash layout is:
| File | Flash Offset | Purpose |
|---|---|---|
bootloader.bin | 0x0 | ESP32-S3 bootloader |
partitions.bin | 0x8000 | Partition table |
firmware.bin | 0x10000 | Application code |
The compile server's web page at <server-url>/?build_id=<id> supports direct browser-based flashing of API/CLI-created builds:
--web-serial / -WebSerial, or otherwise obtain a completed build_id.<server-url>/?build_id=<build_id> URL in Chrome/Edge.Requirements: Chrome/Edge, HTTPS, USB-C connection to the K10 board.
This mode requires no local PlatformIO, no local K10 toolchain, and no local esptool; the browser uses Web Serial and the server-hosted esptool-js bundle. Browser security still requires a user gesture: the user must click the flash button and choose the serial port.
The server frontend must support ?build_id=<id> and initialize its flash manifest from /api/build/<id>/flash-files.
The page first tries automatic reset (default_reset) and only shows a BOOT/RST fallback if automatic entry fails. Do not instruct users to hold BOOT and tap RST as the default path. On current server builds, flashing completion uses a DTR/RTS reset-to-firmware sequence and releases the Web Serial connection.
If the K10 is connected via USB to the compile server machine, use the server-side flash:
curl -sk -X POST "$SERVER/api/flash/$BUILD_ID"
Or via the helper script:
bash k10-compile-server/scripts/compile-project.sh \
--server https://your-k10-compile-server.example.com:8900 \
--dir /path/to/k10-project \
--flash
Prefer browser Web Serial for normal classroom/client workflows. Use this local esptool path only when the user explicitly wants command-line upload and has local Python/esptool available.
If the K10 is connected via USB to the client machine running Codex, compile remotely, download the flash files, then upload locally with esptool:
bash k10-compile-server/scripts/compile-project.sh \
--server https://your-k10-compile-server.example.com:8900 \
--dir /path/to/k10-project \
--upload-local \
--port /dev/cu.usbmodemXXXX
Windows PowerShell:
.\k10-compile-server\scripts\compile-project.ps1 `
-Server https://your-k10-compile-server.example.com:8900 `
-Dir C:\path\to\k10-project `
-UploadLocal `
-Port COM3
If the port is omitted, the helper auto-detects only when there is exactly one likely USB serial port. Pass the port explicitly when multiple boards or serial devices are connected.
Client-side upload requires local esptool only; it does not require the full PlatformIO K10 toolchain:
python3 -m pip install esptool
python -m pip install esptool
The local upload writes the standard ESP32-S3 flash layout returned by the server:
0x0 bootloader.bin
0x8000 partitions.bin
0x10000 firmware.bin
If automatic reset does not enter the bootloader, hold BOOT, tap RST, then release BOOT while the upload is connecting.
# Complete pipeline: zip → submit → poll → open browser flash page
bash k10-compile-server/scripts/compile-project.sh \
--server https://your-k10-compile-server.example.com:8900 \
--dir /path/to/k10-project \
--web-serial
Remote compile and firmware download only:
bash k10-compile-server/scripts/compile-project.sh \
--server https://your-k10-compile-server.example.com:8900 \
--dir /path/to/k10-project \
--output ./firmware.bin
| Symptom | Likely Cause | Fix |
|---|---|---|
"k10_toolchain_ready": false | Server hasn't built a K10 project yet | Run a dummy build on the server first, or install the PlatformIO K10 platform |
error: "未找到 platformio.ini" | Project missing platformio.ini or zip structure wrong | Make sure platformio.ini is at the zip root |
error: "缺少 partitions.csv" | platformio.ini references a partition table that was not uploaded | Add the matching partitions.csv next to platformio.ini |
error: "编译超时" | Project takes > 5 min to compile | Simplify project, or use local pio run for this project |
| Connection refused | Server not running | Start the Docker/systemd service from references/server-setup.md |
| SSL cert error on curl | Self-signed cert | Use -k flag (insecure) for curl |
| Browser flash page says build_id is expired | Server restarted or build cache expired | Recompile and open the new ?build_id=<id> URL |
| Web Serial unsupported | Browser is not Chromium-based or page is not HTTPS | Use Chrome/Edge over HTTPS |
| Web Serial cannot see the board | Wrong port, cable, or browser permission | Replug K10, use a data-capable USB-C cable, and select the K10 serial port |
| Browser upload cannot enter download mode | Automatic reset failed | Follow the page's BOOT/RST fallback prompt |
| Server-side flash fails | K10 not connected to server | Check ls /dev/ttyUSB* or ls /dev/ttyACM* on server |
| Client-side upload fails with missing esptool | Local client lacks upload tool | Run python -m pip install esptool |
| Client-side upload cannot find port | Multiple serial devices or no K10 connected | Pass --port <port> / -Port COM3 explicitly |
| Client-side upload cannot connect | K10 did not enter bootloader mode | Hold BOOT, tap RST, then release BOOT while upload is connecting |
unihiker-k10-platformio — local PlatformIO development (no server needed)unihiker-k10-ota — OTA firmware update workflowunihiker-k10-arduino — Arduino CLI development