ZeroTrace HID
TraceNetwork — Usage Guide
Set up a fleet, run synchronized payloads, scan WiFi together, and orchestrate light shows
This is the full operator's guide to TraceNetwork — the multi-device coordination feature. For the high-level "what is this" overview see the feature page.
How it works
┌────────────┐
│ Controller │ the device whose webui you have open
│ (any ZT) │
└─────┬──────┘
ESP-NOW │ AES-128-GCM, channel 1
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Agent │ │ Agent │ │ Agent │ each runs the same firmware,
│ ghost │ │ glitch │ │ phantom │ shares the passphrase
└──────────┘ └──────────┘ └──────────┘
There's no central server — every device runs the same firmware and the same TraceNetwork stack. Whichever one you happen to be looking at via webui acts as the controller; the others act as agents. Heartbeats fly out every 10 seconds (1 second while a script runs) so the fleet stays current.
1. Setup
Prereq: Every device in the fleet needs a TraceNetwork-capable firmware build (any current ZeroTrace release).
On every device's webui:
- Open Settings
- Scroll to the TraceNetwork card
- Toggle Enable TraceNetwork on
- Set a passphrase — minimum 8 characters. Use the same passphrase on every device.
- Pick an Identify color (default red)
- Reboot the device
The passphrase is the encryption key. Devices with a mismatched passphrase produce traffic that other devices silently drop — they're invisible to each other. Pick something strong, and remember: rotating it later means re-keying every device.
After all devices have rebooted, open the webui on any one of them. Within ~10 seconds, every other device shows up in the Network tab. Your own device is the first row, marked THIS.
2. The target picker
The header (top right) has a target picker with the current selection. Click it (or press Ctrl+K).
It's a multi-select — you can check any combination of:
- Local — the device whose webui you're viewing
- All agents — selects every online agent at once
- Per-agent checkboxes — check exactly the units you want
Whatever's selected becomes the implicit target for run/stop, light show, and WiFi scan actions. The selection persists across tabs — pick targets in the header, then go to the Executor or WiFi tab and your choice is already in effect.
The header also has a polling-status dot next to the target picker:
- Green — heartbeats arriving fine
- Yellow — at least one source is stale (no recent success)
- Red — at least one source is erroring
Click the dot for a per-source breakdown with last-success age and any error message. Useful when an agent disappears and you're not sure if it's the radio or the webui.
3. Identify a device
The simplest fleet operation. In the Network tab, click Identify on any row — that device's LED blinks 5 times in its configured Identify color.
Use it to physically locate planted hardware in a room of identical units. From the Agent details drawer (click any row) you can also Identify.
4. Run a script across the fleet
This is the headline use case.
Workflow
- In the header, pick targets — Local + agents, all agents, or any subset.
- Open the Executor tab.
- Paste a script (or load one from the file picker).
- When the target includes more than one device, a Fire simultaneously (500ms offset) checkbox appears above the Run button. Keep it checked.
- Hit Run (or
Ctrl+Enter).
Every selected device starts typing within ~10–20 ms of each other. The 500 ms offset gives the controller time to dispatch all the ESP-NOW packets so every agent has scheduled the run before any of them starts firing.
What's actually happening
- Controller sends
RUN(withstart_at_offset_ms = 500) to each agent over ESP-NOW. - Each agent, upon receiving the packet, schedules
executeTranspilation()fornow() + 500mson a FreeRTOS task. - At the deadline, every agent fires.
- ESP-NOW unicast latency over short range is single-digit ms, so the deadlines align tightly.
If a script touches the LED (ledColor, ledOff, ledBlink), the firmware records that and won't auto-reset the LED to green at script end. So ledOff actually stays off after the script ends.
Recipe — synchronized AltGr injection
Three planted devices need to type the same payload at the same instant on three different hosts:
- Settings on each device → enable TraceNetwork with the same passphrase. Reboot.
- Connect to one of them via webui (it doesn't matter which — they're peers).
- Header → target picker → check All agents. Uncheck Local (you don't want this device firing).
- Executor → paste payload, check Fire simultaneously, Run.
All three devices type within the same instant.
Recipe — local payload + remote witnesses
You're physically holding one device that types into a target host. Two planted devices nearby need to record what happened (e.g. set a status LED) at the same moment.
- Set up the two planted devices as TraceNetwork agents.
- On your device, write a script ending with
traceBroadcast "fired". - Header → target picker → check Local only.
- Run the script. The Local device executes the payload. When it hits
traceBroadcast, every other agent receives the broadcast event.
(Per-agent reaction-to-broadcast is on the v2 roadmap; current traceBroadcast is one-way.)
5. Fleet WiFi scan
Each device has its own WiFi radio. Devices placed in different physical locations see different networks. Fleet WiFi scan aggregates them.
Workflow
- In the header, pick the agents you want to scan from. (Local scan isn't supported — would disrupt the device's own AP and disconnect your webui.)
- Open the WiFi tab.
- Hit Scan (or
R).
After ~5–12 seconds (per-agent scan time, all run in parallel), the table populates with the deduped union of every WiFi network any selected agent could hear.
What each column means
- SSID — the network name.
(hidden)if it doesn't broadcast. - BSSID — the AP's MAC address. Unique even when SSIDs collide.
- Encryption — color-coded badge. Red = Open, yellow = WPA, green = WPA2/WPA3, etc.
- Best RSSI — strongest signal across all agents.
- Channel — 2.4 GHz channel number.
- Seen by — small badges showing each agent that detected this network and its individual RSSI for that network.
Sort and filter
- Search box — filters by SSID or BSSID substring.
- Encryption toggle — show All / Secure-only / Open-only.
- Sort toggle — by RSSI, SSID, Channel, or number of devices that saw it (Seen).
Recipe — survey a 3-room office
- Place one device in each room. Make sure all three are on the same TraceNetwork passphrase.
- Connect to your laptop's webui (or to one of the devices' APs).
- Header → All agents → WiFi tab → Scan.
- The aggregated view shows every AP any device can hear. The "Seen by" column tells you the geographic spread — an AP visible to all three is probably big and central; one visible to only one device is local to that room.
Use the per-agent breakdown badges + signal strength to triangulate APs roughly.
6. Light show
The Network tab has a Light show card.
Patterns
| Pattern | What it looks like | Best with |
|---|---|---|
| Off / Stop | Turns the LED off | n/a |
| Solid | Every device shows the same color | 1+ devices |
| Pulse | Triangle-wave fade in/out | 1+ devices |
| Strobe | On/off flash | 1+ devices |
| Rainbow | HSV cycle, hue offset by index — wave moves down the chain | 2+ devices |
| Chase | One device lit at a time, rotating through the chain | 2+ devices |
| Cylon | Chase that bounces back and forth (Knight Rider) | 3+ devices |
Workflow
- In the header, pick targets — Local + agents, just agents, or just one.
- Open the Network tab → scroll to the Light show card.
- Pick a pattern from the dropdown.
- Pick a primary color. The picker supports HEX/RGB/HSL inputs and includes an EyeDropper button (Chromium-only) for picking colors from anything on screen.
- Set Speed (ms per step) — 50 ms = rapid strobe, 200 ms = snappy chase, 1000 ms = slow pulse.
- Set Duration (s) — 0 means run forever until you hit Stop.
- Hit Start.
All selected devices fire ~500 ms later (intentional — gives every agent time to schedule, so they animate in lockstep). When Local + agents are both included, Local actually waits ~600 ms to compensate for the agents' ESP-NOW transit time, so the anchors line up.
The Sync button
Even with everything timed, ESP-NOW packet jitter at start time can offset devices by 5–20 ms. Over a long-running pattern they stay aligned (the firmware anchors steps to wall-clock time per device, so drift doesn't accumulate). But if the initial start lands them visibly out of phase, hit Sync — it re-broadcasts the current pattern with a fresh 500 ms offset. Every device drops its current animation and re-anchors in lockstep.
Recipe — best Cylon demo
3+ devices in a row on a desk:
- Put them ~10 cm apart, USB-powered.
- All on the same TraceNetwork passphrase, all online in your Network tab.
- Header → All agents (or include Local if your laptop's device is in the row).
- Network → Light show → Pattern: Cylon, Color: red, Speed: 150 ms, Duration: 0.
- Hit Start. The red dot bounces left-right across the row.
- If devices look offset, Sync.
Recipe — synchronized strobe
Practical "fleet status" effect:
- Pick Pattern: Strobe, Color: white, Speed: 80 ms, Duration: 5 (seconds).
- Hit Start.
All selected devices flash white for 5 seconds in unison.
7. The traceBroadcast script command
Inside any HID or BLE script:
traceBroadcast "label"
Sends a broadcast packet to every other device on the fleet. Currently used for emit-only signaling — receiving devices don't react to broadcasts in the v1 firmware, but the receive path is in place for future use.
Useful right now as a marker in serial logs when debugging multi-device scenarios.
8. Settings reference
| Setting | Default | Notes |
|---|---|---|
tracenet_enabled | false | Master enable. When false, ESP-NOW never initializes and TraceNetwork is invisible. |
tracenet_passphrase | empty | Shared key. Minimum 8 characters. Empty = effectively disabled. |
tracenet_identify_color | red | Color the LED blinks when another device pings this one. Options: red, green, blue, yellow, purple, orange, white, cyan. |
All managed from the Settings tab → TraceNetwork card. Changes take effect after reboot for the master enable; passphrase + identify color apply immediately.
9. Constraints & gotchas
Range
~200 m line of sight, single-hop. Indoors with walls, much less. There is no mesh forwarding in v1 — agents must be in direct ESP-NOW range of the controller. Plan device placement accordingly.
WiFi channel
ESP-NOW pins to channel 1 (the same channel the device's SoftAP uses by default). If your wifi_sta setting connects to an upstream AP on a different channel, the device's radio will be tuned to that other channel, and ESP-NOW packets will drop. Either keep STA off, or accept that TraceNetwork won't work while STA is on a non-1 channel.
File transfers
Chunked over ESP-NOW at ~30–60 KB/s in practice. Fine for scripts (KB-sized). Painful for multi-MB logs — minutes, not seconds.
No agent-to-agent direct
All commands flow through the controller. Two agents can't directly talk to each other; they can only broadcast (one-way) via traceBroadcast.
Heartbeat cadence
Idle devices broadcast every 10 seconds. While a script runs, the cadence drops to 1 second so the controller can show live progress. Means: agent rows in the Network table only update every 10 s when idle (RSSI, uptime, free heap). The THIS row updates every 2 s because it's queried live, not heartbeat-driven.
Settings UI mentions BLE host
On variants compiled without BLE (Ghost, Mini, T-Dongle, Waveshare), the BLE host indicator is always false. That's correct, not a bug.
10. Troubleshooting
Devices don't see each other
- Confirm passphrases are byte-for-byte identical (≥ 8 chars, no leading/trailing whitespace).
- Confirm
tracenet_enabled = trueon both. - Confirm both devices were rebooted after the passphrase change.
- Within range? Try moving them closer.
Identify works but the device shows "stale" or "offline"
Identify uses unicast; heartbeats use broadcast. They share the same encryption but go through slightly different ESP-NOW paths. If broadcasts aren't arriving:
- Check
wifi_sta— connecting to an upstream AP on a non-1 channel breaks broadcasts. - Check the polling badge in the header for source-specific errors.
Light show devices are out of sync
- Hit the Sync button to re-anchor every device with a fresh start time.
- ESP-NOW packet arrival jitter contributes ~10–20 ms variance at start. The firmware bounds drift over time (steps anchored to wall-clock per device), so resyncing once at start is usually enough.
Local LED leads the agents
- Local has a built-in 100 ms compensation when agents are selected. If your fleet is unusually large (>5 agents) and transit exceeds that, Local might still lead. Open an issue with your fleet size.
WiFi scan returns "timeout" for an agent
- A scan takes 5–12 s on the agent. The controller's proxy waits 15 s. Timeouts mean the agent is out of range, offline, or busy with a script (scans are blocked while a script runs — the scan would disrupt HID injection).
Webui hammers /api/tracenet/fleet and /api/tracenet/local extremely fast
Fixed in current firmware — was a render loop in the polling-status hook. If you're on an older build, update.
Browser disconnects briefly
Could be a WiFi scan running on the device serving your webui (its AP drops momentarily during a scan). The browser will reconnect. Run scans against agents, not the local device.
11. Related
- Feature overview — short pitch and constraints
- HID scripting commands — script reference
- Web UI — general webui guide