Hands-onW103DFT-7102026-10-11

A ¥125 Box
as My FT-710's Remote Server

The radio is chained to the desk because its front panel is a computer. This is the whole road: what I actually wanted, what such a server really needs, how it compares with a Raspberry Pi or a mini PC, why a second-hand carrier cloud terminal won, the six defects the first real box exposed, and what the ¥125 bought.

1. The idea: a radio should not be tied to the desk

An FT-710 needs nothing added: CAT, a USB sound card and a real spectrum interface are all inside the case, reachable through one USB cable. What it lacks is any way to use it from somewhere else — from the sofa for twenty minutes on 40 m, from the balcony while adjusting an antenna, or from a hotel room to check whether the band is occupied.

The first reflex is remote desktop or VNC. I tried it honestly and dropped it, for three concrete reasons:

The shape I actually wanted is the other way round: the server sits next to the radio, the browser is only a panel. Phone, tablet, laptop — whichever is at hand opens a URL and becomes a radio that can listen, show a waterfall and press PTT. That server has to hold the radio's USB (serial, sound card, spectrum), encode audio, push state to the browser, and run for years without heat or noise.

2. Research: what such a server really needs

Quantify the requirement before shopping. The server is Python (there is a GIL): the hot path lives on one core, so core count does not help — single-thread performance decides everything. Item by item:

What actually decides it Why
Single-thread performance Python server, audio encoding and spectrum parsing share one event loop; extra cores only help other processes
At least two USB ports One for the radio cable, one spare for a tuner, a stick or a keyboard. This is the most common way to get it wrong
A wired NIC Each client needs roughly 60 KB/s — 100 Mb is plenty. But Wi-Fi jitter turns straight into chopped audio
24/7 power and heat It stays powered on beside the radio; fan noise and the power bill are part of the cost
Price and availability Once the four above are satisfied, this is the one that actually decides

Then look up measured single-thread scores for the candidates (PassMark, one source, fetched the same day — with sample counts, because anything below a hundred samples is a hint, not a fact):

Processor Single-thread TDP Samples Server hot path ≈
Intel N100 1879 6 W 4111 ~8%
AMD R1505G (HP t640) 1822 15 W 138 ~8%
Broadcom BCM2712 (Pi 5) 1813 — ⚠️ 4 ~8%
Intel Celeron J1900 653 10 W 881 ~22%
Intel Atom D525 293 13 W 336 ~49%

The conclusion is counter-intuitive and useful: compute is almost never the selection criterion. From a 2008 Core 2 Duo to today's N100, anything scoring above ~700 single-thread spends 15–45% of one core, and 2 GB of RAM with a few hundred MB of storage is plenty. What actually blocks the project is USB port count, the NIC, power draw — and whether the thing is easy to buy and easy to install.

3. The comparison: four roads and their real price

Option What is good What it costs you
N100 mini PC (new) Highest single-thread, 6 W, four cores, warranty — the one tier where you never have to compute headroom The most expensive (typically ¥500+ for a complete new machine, plus storage and PSU)
Second-hand thin client (HP t640, Dell Wyse …) Single-thread on par with the N100 (1822 vs 1879), 15 W, dumped in volume by enterprises, cheap You must pick a model: USB port count, storage form factor, whether Linux installs at all; stock and condition are luck
Raspberry Pi 4 / 5 Official images, the thickest ecosystem, the most tutorials — almost zero porting Prices and stock; you add PSU, cooling and storage; with accessories usually ¥400 and up
A carrier box (ZTE W103D) ¥125 second-hand, <5 W, 32 GB eMMC, two USB ports and a wired NIC included You replace the OS yourself: vendor kernel, cannot be upgraded; 100 Mb NIC; Wi-Fi needs a community driver

Note the difference in the last row: the first three are "buy it and install something"; this one is "buy it and replace the operating system". It works here because we already build a server image for MRRC Modern — and that is also the part of this project that took the longest.

4. Why this ¥125 box

Let me be clear: it was never meant for radio amateurs. It is a carrier-issued "cloud terminal" — China Mobile / ZTE W103D, Android out of the box, made to drive a monitor against a cloud desktop. I paid ¥125 second-hand, for a plain reason: it satisfies all four requirements from section 2.

The retail box of the ZTE W103D cloud terminal
The box says "ZTE cloud computer W103D / cloud desktop terminal BAZ01 linux" — a terminal for cloud desktops, not radio equipment.
The W103D label: model W103D, input 5V 2A
Identifying the model is step one, and the only step you cannot skip. You need the ZTE W103D (Amlogic S905L3A). The same shells ship with GK6323 or RK3566 chips and look nearly identical — the image supports exactly one of them, so buying the wrong one is buying a brick.
The W103D label in close-up: model, CMIIT ID, production date and serial number
Worth photographing before you buy: the label carries the model, the CMIIT ID and the production date (2024.09) next to the serial number — the fastest way to confirm what you are actually holding.
The W103D next to an AA battery for scale
Size: palm-sized, with an AA battery for scale (that one is a rechargeable eneloop). Rated 5 V/2 A; measured draw is under 5 W — a year of always-on costs less than ¥30 of electricity.
ZTE W103D Raspberry Pi 4 Raspberry Pi 5
SoC S905L3A · 4×A53 (in-order) BCM2711 · 4×A72 (out-of-order) BCM2712 · 4×A76 (out-of-order)
RAM / storage 2 GB / 32 GB eMMC 1–8 GB / microSD 4–8 GB / microSD·NVMe
NIC 100 Mb Gigabit Gigabit
Power < 5 W ~3–7 W ~5–12 W
Software maturity Vendor kernel, cannot upgrade Official images, biggest ecosystem Same
The costs, stated plainly: its Wi-Fi (MT7663S) needs a community driver and vendor kernel patches, so upgrading the kernel can silently lose Wi-Fi (no error, it just never associates). The NIC is 100 Mb, not gigabit. And you flash Armbian yourself (ophub's s905l3a-w103d variant, kernel 6.18). In other words: the money you save, you pay back in your own time. If you are willing to spend that time, this is the cheapest option on the table.

5. Hands-on: from unboxing to a waterfall on the phone

Five steps, needing only a network cable, a USB stick and a computer you can SSH from:

Unboxing: the W103D and its accessories
Unboxing: the unit, a USB-C power supply and a cable. HDMI, the NIC and both USB ports are all there.

① Write the USB stick

Flash the image to a USB stick (check the device name twice) and plug it into the box:

The W103D with a USB stick plugged in
Stick in, cable in — ready to boot from USB.

② Boot from USB (Android stays untouched)

Power the box and run reboot update once from Android. It then boots from the stick. This writes the u-boot boot order once and touches no Android partition or data — unplug the stick, power-cycle, and it is the same Android box again. My favourite property of this whole approach: failure is free, because nothing was changed.

Armbian first-boot banner on HDMI with an SSH session
First boot: the Armbian banner on HDMI (S905L3a / kernel 6.18.54-ophub / 50 °C / LAN address) while SSH is already usable. First boot needs no network: password, self-signed certificate and serial probing all happen locally, and the banner prints the web password.

③ Connect the radio

The FT-710 plugs into the box through its upper "Enhanced" port; one cable delivers three things at once: the CAT serial port (/dev/ttyUSB0), the USB sound card, and the FT4222 interface used for the real spectrum. Switch models with the bundled command:

ssh root@<box-ip>
mrrc-radio use ft710        # probes the serial port → writes config → restarts
Connection settings in the browser: FT-710, serial port, RX/TX audio devices
The connection page in the browser: model, serial port, RX/TX audio devices — changes take effect immediately.

④ A radio on the phone

MRRC in a phone browser: spectrum, waterfall, power/SWR meters, PTT
This is what the ¥125 bought: a real spectrum and waterfall (not the synthetic S-meter fallback), power/SWR meters, mode and filter controls, and that red PTT — in a phone browser. Transmitting from a phone requires HTTPS (browsers only grant microphone access in a secure context), so the image signs a self-signed certificate on first boot.

⑤ Move it onto the box itself (and retire the stick)

Everything above still ran off the USB stick. The last step makes the box standalone: run ophub's installer on the box and it clones the running system into the internal 28.9 GB eMMC, bootloader handling included.

armbian-ddbr            # first: back the whole eMMC up to /ddbr/ (factory bootloader included)
armbian-install         # device ID 307 (ZTE-W103D), rootfs 1 (ext4) — never add -m yes
poweroff                # unplug the stick, power on: it boots from eMMC from now on

Two things worth knowing. The installer keeps the factory bootloader byte for byte — only the 68-byte partition table changes, and you can prove it with cmp. And it regenerates the machine-id, so the box's IPv6 interface identifier changes once: anything that follows it by name (a DDNS updater, the Cloud Hub tunnel) catches up by itself within minutes.

What is left is the final form: the box, a power lead, and one USB lead for the radio — no stick, no monitor, 28.9 GB of its own storage, and the stick becomes the rescue copy (the full eMMC backup lives on it).

The finished W103D: power in, the radio's USB lead in, no stick
The final form: power in, the radio's lead in the USB port, the network arriving over Wi-Fi — and the system booting from the box's own eMMC.

6. Booting is not working: six defects the real box found

The image had been built and verified in a container — "green all the way". The first evening it ran on real hardware with a real radio attached, it produced six defects. Every one of them only shows up on this hardware, which is why I refuse to treat "the build succeeded" as evidence. All six were then fixed, given regression guards, and the image was rebuilt (52 acceptance checks green); the table in section 8 is what was measured item by item afterwards.

Symptom Cause
The web UI never opens; the service restarts every 3 seconds First boot generated the TLS certificate as root, so the key was 0600 root:root, while the service runs as mrrc — uvicorn cannot read it
The real spectrum never starts (CAT and audio are fine) The FT4222 has no /dev node of its own; the library opens the USB device directly and it was root:root — a missing udev rule. A half-failure is the hardest kind to diagnose
The first-boot banner (with the password) never appears on HDMI The unit asked for StandardOutput=console — not valid systemd syntax, which systemd silently ignores
The box's config carried the build host's serial port The installer's config file was written on the build machine and copied into the image verbatim (mine had /dev/cu.SLAB_USBtoUART)
Every fresh box shows one failed unit Debian's dnsmasq.service fights systemd-resolved for port 53 (the hotspot uses NetworkManager's own instance)
The acceptance script calls a running unit "not installed" systemctl list-unit-files | grep -q under pipefail exits 141 from SIGPIPE: grep leaves as soon as it matches, systemctl gets SIGPIPE, and "found it" is reported as "not found"

The audio fight (worth its own section)

With the radio connected, audio in the browser stuttered badly — chopped first, then gone. My first guesses were the network, the browser, or transmit interference. All wrong. Using the server's own audio code outside the server gave three clean control runs:

How it read Audio actually received
As shipped (one 20 ms period) 4%, and a permanent stall after ~60 seconds
The same code, reading aggressively 100%
The same code, with a 400 ms buffer 99.7%
Fixed (100 ms buffer) 100%, 50 frames/s, 20 ms spacing, stable

The root cause is that this box's host audio buffer holds only one or two 20 ms periods: read a little late and it overflows — and here is the deceptive part — the capture interface then stops silently. The system reports it stopped, while the audio library still reports an open stream, raises nothing and logs nothing. macOS and Windows hand the same code far more slack, so this class of bug is invisible on a desktop.

Two fixes: set the capture buffer per platform to 100 ms (MRRC_RX_BUFFER_MS), and add a stall watchdog — if someone is listening and no audio arrives for three seconds, log it and reopen the capture stream. The first stops the problem from happening; the second makes it visible and self-healing when it happens anyway.

7. What it is worth

What you get Notes
Every device is a front panel Phone, tablet, laptop (and the native Android client) open a URL and can listen, watch a real waterfall and press PTT; the server sits by the radio instead of on the desk
Cost ¥125 for the box, plus a USB stick I already had. A Raspberry Pi build is usually ¥400+ with PSU, cooling and storage; an N100 mini PC is ¥500+
The price of always-on Under 5 W — less than ¥30 a year — passively cooled, so no fan noise
It does other things too The same box records QSOs (verified — section 8) and drives an ATR-1000 tuner if one is connected (none here); it can also hand a friend a listen-only password
One step further out Add Cloud Hub (outbound tunnel + per-instance certificates) and it stops being "a radio on the LAN" and becomes reachable from the internet: see The Cloud's First Mile

The most concrete win: the radio is back where it belongs. The spot on the desk now only supplies an antenna and power; who uses it and from where is the browser's business. Anyone at home can be given a listen-only password for an evening of shortwave, and from out of town that familiar FT-710 is one URL away.

The W103D sitting quietly on the radio desk
Where it ends up: beside the radio, not in front of a monitor, not in the middle of the desk, and nobody ever has to switch it off — once power and the cable are in, it is just a small box that is always there.

8. The verified list: what it does now

Everything below was actually done on the day it went live. This is not "it should work"; these are the numbers from the logs:

Capability Evidence from the real box
CAT control Frequency, mode, filter, ATT and PRE read back live; polling steady on 40 m (7.050–7.053 MHz, LSB, 2.4 kHz)
Receive audio 50.0 frames/s, 20 ms spacing, Opus at ~52 kbps — listened continuously in a phone browser
Transmit Phone microphone → server → the radio's USB sound card: one session with 62 frames, peak=100%, 57 frames written to the radio, decode_fail=0, write_err=0, queue_drops=0; the radio keyed and its TX meters (PWR/SWR/ALC) came back
QSO recording Two MP3s in recordings/: 07050kHz_20261011_102001.mp3 (134.7 s, 64 kbps) plus a short clip (199 KB)
Real spectrum first frame received — spectrum active — the FT4222's real spectrum, not the synthetic S-meter fallback
The web UI HTTPS with a self-signed certificate; opened from a phone, a tablet and a laptop; guests can be handed a listen-only password
24/7 Moved house, power cut, powered back up: systemd brings it back by itself; under 5 W, passively cooled
Its own storage armbian-install moved the running system onto the internal 28.9 GB eMMC; it boots with no stick attached, and the factory bootloader was verified byte for byte (cmp over [0,444) and [512,4 MiB) — only the 68-byte partition table differs)
Public access Live on Cloud Hub: https://<callsign>.mrrc.vlsc.net/ serves HTTPS with a hub-issued certificate; a DDNS name keeps following the box's IPv6 address

And it is reachable from the internet now. Cloud Hub hands the box a callsign entry (https://<callsign>.mrrc.vlsc.net/, example: https://bg1sb.mrrc.vlsc.net/) with its own certificate, so the phone UI follows you out of the house; guests can be handed a listen-only password. On the LAN nothing changed — it is still doing all of the work.

MRRC opened from a phone through the Cloud Hub entry
The public entry, opened on a phone: the same UI and the same waterfall as on the LAN.

Written 2026-10-11, the day this box went live — and the day receive, transmit, spectrum, recording and phone control were each verified on the real hardware (the numbers are in section 8). Every figure here comes from that day's logs, commits and artifact checks, including the one-line test for each of the six defects. Updated 2026-10-12: step ⑤ (install onto the box itself) and public access were added the next day. The image is on the download page; step-by-step operation is in the W103D guide.
中文版:125 元的盒子