Appearance
Remote Development Environment
The board always hangs off the company VM
10.8.0.6; every other machine uses its serial ports, ADB and flashing over WireGuard. Zero changes to the board — the workflow is identical from whichever machine you sit at.
Overview
Star topology: every node peers only with the cloud, and cross-node traffic is relayed through the cloud's ip_forward. Onboarding a new device touches just two places: itself and the cloud.
Machine Inventory
The single source of truth is machines.tsv (versioned; the authoritative copy lives on the cloud at /srv/mesh/). Whenever you switch machines, check your identity first:
bash
mesh-whoami # 按本机 WireGuard IP 自动匹配身份| id | IP | Role |
|---|---|---|
| cloud | 10.8.0.1 | WG relay · authoritative inventory host · nginx hosting · archive |
| home-vm | 10.8.0.4 | home build VM · always-on Agent |
| company-vm | 10.8.0.6 | board host: ser2net / adb-server / board lock |
| mac | 10.8.0.10 | interactive · AI Agent · on-the-go build & flash |
| phone | 10.8.0.100 | Termius SSH · remote viewing |
| home-host | 10.8.0.2 | home-vm hypervisor (usually offline) |
Same-name trap
vms and vmt share the hostname olicca-vm — go by IP, not hostname.
WireGuard: Onboarding a New Device
The full chain, using an iPhone as the example (measured 2026-09):
Config discipline: client configs live in ~/.wireguard-mesh/<设备>.conf (0600, the private key never goes into git); render the QR code as a PNG with the qrcode library — don't use terminal ASCII (it gets cut off).
Daily Workflow Cheat Sheet
| Need | Channel | Key command |
|---|---|---|
| shell / push-pull files | adb client → remote adb server | adb -H 10.8.0.6 shell |
| MCU log / console | ser2net raw TCP | socket://10.8.0.6:400x |
| Flashing | push artifacts to the remote, run the flash command there | rsync + ssh |
| On-board web UI | run the forward locally on vmt | http://10.8.0.6:18080 |
| Anything else | passwordless SSH (ed25519) | ssh olicca@10.8.0.6 |
Remote ADB
bash
adb -H 10.8.0.6 devices # 显式走远端
export ADB_SERVER_SOCKET=tcp:10.8.0.6:5037 # 脚本里免 -HThe remote's local adb shell and a remote adb -H share one server and can run concurrently; the adb versions on both ends should be close (28.0.2 on both right now).
Remote Serial (ser2net)
| Port | Board | Function | Baud rate |
|---|---|---|---|
| 4000 | S100P | MCU-COM | 921600 |
| 4001 | S100P | Main-COM | 921600 |
| 4002 | RV1126B | AP (Linux) | 1500000 |
| 4003 | RV1126B | MCU (RT-Thread) | 1500000 |
python
import serial
s = serial.serial_for_url("socket://10.8.0.6:4002", timeout=2) # raw TCP,波特率在 ser2net 端固定Don't use rfc2217://
ser2net 4.3.4's telnet stack freezes after an abnormal disconnect (it accepts TCP but never sends the negotiation bytes). The raw TCP mode stayed stable across 15 fast connect/disconnect cycles. The only cost is that you can't change the baud rate remotely — and ours is fixed anyway.
30-Second Health Check
Remote Flashing
On a high-latency link (RTT 130ms), don't map the flashing USB back to your local machine. Do this instead:
Board Mutex Lock
The dev board is a singleton resource — always take the lock before flashing or running an exclusive monitor:
Locks live in /tmp/boards/*.lock/ (owner / task / timestamp), and /tmp is wiped on reboot, so deadlocks heal themselves.
Async Task Dispatch (Level 2)
You drop a task file into a shared directory and the unattended Agent on the home VM picks it up and runs it:
Direct Local Mode (Board Plugged into the Mac)
Without WireGuard, adb connects directly; the four CH340/341 serial ports (/dev/cu.wchusbserial*) change names on re-enumeration, so identify them by baud rate + prompt:
| Board | Function | Baud rate | Prompt |
|---|---|---|---|
| RV1126B | AP | 1500000 | root@ATK-DLRV1126B-MCU720:/# |
| RV1126B | MCU | 1500000 | msh /> |
| S100P | AP | 921600 | ubuntu login: (root, empty password) |
| S100P | MCU | 921600 | no shell, boot log only |
Getting the S100P into fastboot: send \x03 one byte at a time at ~100ms intervals on the AP serial port to break the zero-delay autoboot (sending every 10ms floods the U-Boot input buffer) → Hobot$ → fastboot 0.
Data and Collaboration Ecosystem
The cloud isn't just a relay — it hosts the whole collaboration stack:
| Facility | Port / entry | Notes |
|---|---|---|
| omp-web | http://10.8.0.1:8080 (WG intranet only, no auth) | browse sessions from any device + web chat + task UI |
| Task Center | http://10.8.0.1:8090 | REST + work-task CLI + deadline reminders over Feishu |
| Session daily report | systemd timer at 09:30 | scans all sessions → kimi-k3 writes it → Feishu DM |
| nginx | 80 (public) | static homepage + prebuilts toolchain downloads |
omp session sync uses one syncthing folder per project: the folder_id is the same on all three ends while each end maps its own path, and on the cloud ignoreDelete makes it an append-only archive. Single source of truth for the mapping: projects.tsv.
Pitfall Archive
| Symptom | Root cause | Fix |
|---|---|---|
CH340 plugged in but no /dev/ttyUSB0 | Ubuntu brltty grabs CH340/CP210x | apt purge brltty + replug |
| ser2net accepts TCP but sends no data | the 4.3.4 RFC2217 stack freezes after an abnormal disconnect | switch to raw TCP (socket://) |
| ser2net process alive but the port isn't listening | boot race: the USB serial port isn't enumerated yet when it starts, so it silently disables itself | udev rule that restarts it automatically |
| adb-server systemd stuck in activating | an old adb -a nodaemon still holds port 5037 | pkill -f "adb -a nodaemon" |
| Remote adb suddenly dies completely | adb version drift between the two ends | align the versions (28.0.2 right now) |
adb -H ... forward on the Mac reports more than one | adb 1.0.41's -s doesn't work with forward | run the forward locally on vmt |
| All syncthing folders on vms suspend | disk at 100% trips minHomeFreePct | journal vacuum + free up disk |
Reproduction and Sources
- All remote configuration is captured as idempotent scripts under
setup/; runsetup-resource-host.shonce on a new resource host to reproduce it - For operating details and command-by-command notes, see the
remote-devskill and its four reference documents (initialization pitfalls / design choices / topology evolution / multi-project design)