- Go 45.8%
- TypeScript 38.5%
- HTML 9.5%
- CSS 5.2%
- Makefile 1%
| cmd/server | ||
| internal | ||
| web | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
| UserInterface.md | ||
tinySA Web
A self-hosted web UI for the tinySA spectrum analyzer. It's a Go backend (using a forked version of go-tinysa to talk to the device) serving a small REST + SSE API, and a plain HTML/CSS/Canvas + TypeScript frontend with no build framework or bundler. It aims to cover the same ground as the various PC control apps listed on the tinySA wiki (sweep control, multi-trace with hold/average calc functions, multi-marker with delta/tracking, waterfall, presets, screenshot capture, battery status, LNA/spur toggles, raw command access) in one live, continuously-updating page.
See UserInterface.md for how to use the running app, the go-tinysa fork, and known device gotchas.
Prerequisites
- Go 1.25+
- Node.js + npm (for compiling the TypeScript frontend with
tsc) - go-tinysa from kkettinger
- A tinySA, reachable either:
- directly, as a local serial port (e.g. if running this on the same machine the tinySA is plugged into, perhaps /dev/cu.something), or
- over TCP, via a serial-to-TCP bridge such as
socat(see Connecting to the device below, requires the forked go-tinysa).
Building
make build
This runs make web (installs frontend deps and compiles web/src/*.ts to
web/dist/*.js via tsc) and then builds the Go binary to bin/tinysa-server.
To build just the frontend or just the backend:
make web # web/dist/*.js
go build -o bin/tinysa-server ./cmd/server
Running
Two Makefile targets cover the two ways to reach the device (edit SERIAL, HOST,
and PROXYPORT at the top of the Makefile to match your setup):
make run # direct serial connection
make run-tcp # TCP bridge (e.g. socat) - see "Connecting to the device" below
equivalent to:
go run ./cmd/server -serial-port=/dev/cu.usbmodem4001
go run ./cmd/server -bridge-addr=host.docker.internal:9001
If neither -serial-port nor -bridge-addr is given, the server lists the
/dev/cu.* devices it finds (most recently created first) and exits, as a hint for
-serial-port.
Or run the built binary directly:
./bin/tinysa-server [flags]
Then open the printed listen address in a browser (default http://localhost:9040).
If you're running inside a container/devcontainer whose ports aren't published to the
host, you can access it through a port-forwarding proxy such as the one provided by
VSCode's web interface. For example if you have this running on https://localhost:8190/,
you can access the TinySA at https://localhost:8190/proxy/9040/
Just make sure whatever URL you use ends up serving the page from a path that lets relative asset/API requests resolve correctly (a trailing slash after any proxy path prefix as shown in this example).
Flags
| Flag | Default | Description |
|---|---|---|
-addr |
:9040 |
HTTP listen address for the web UI and API. |
-bridge-addr |
(empty) | host:port of a socat (or similar) TCP bridge to the tinySA's serial port. Mutually exclusive with -serial-port; if neither is set, the server lists available /dev/cu.* serial devices and exits. |
-serial-port |
(empty) | Connect directly to this serial port instead of the TCP bridge, e.g. /dev/ttyACM0 or /dev/cu.usbmodem4001. Use this when running the server on the same machine the tinySA is physically attached to. Mutually exclusive with -bridge-addr. |
-web-dir |
web |
Directory to serve the frontend from (expects index.html, style.css, dist/*.js inside it). |
-poll-interval |
0 (→ 1.5s) |
How often to poll the device for live state. Don't set this much lower - the tinySA is bridged over a 115200 baud serial link (~9-11 KB/s effective), and a single 450-point trace response is already ~10-11 KB; polling faster than the link can drain a response backs up the device's command parser until it stops responding entirely. |
-debug |
false |
Enable debug-level logging (logs every HTTP request and every device command). |
Connecting to the device
The included Makefile has two helper targets for the TCP-bridge setup, meant to be run
on whichever machine the tinySA is physically plugged into:
make tcp # socat <serial device>,raw,... TCP-LISTEN:<port>,reuseaddr,fork
make connectivity # telnet <host> <port>, for manually sanity-checking the bridge
Edit SERIAL, HOST, and PROXYPORT at the top of the Makefile to match your setup
(defaults: /dev/cu.usbmodem4001, host.docker.internal, 9001). Once make tcp is
running, point tinysa-server at it with make run-tcp (or -bridge-addr=<host>:<port>
directly - host.docker.internal if the server runs in a container on the same machine,
the bridge machine's LAN address/hostname otherwise).
If the server runs directly on the machine with the tinySA attached, skip the bridge
entirely and use make run (or -serial-port directly) instead.
Development
make webrebuilds the frontend; the Go server servesweb/dist/*.jsstraight off disk, so no server restart is needed after a frontend-only change.cd web && npm run watchrecompiles TypeScript on save.go vet ./...andgofmt -l .before committing Go changes.