Libraries for talking to model-railroad command stations over LocoNet, Z21 LAN, and WiThrottle. Use them when you build throttles, automation, or firmware that must drive locos, toggle functions, program CVs, or switch track power — without re-implementing wire formats.
Go provides connected clients and test servers — documented on pkg.go.dev. Rust provides no_std protocol crates for embedded targets (LongFred); the host owns sockets. Both languages share the same golden test vectors.
- Unified drive API (Go) —
Open(uri)thenSetSpeed,GetSpeed,SendFn,ListFunctions,EmergencyStop, CV read/write, optional track power and LocoNet slot management - Three transports — Z21 (UDP), LocoNet (serial / TCP), WiThrottle (TCP)
- LAN autodetection (Go) — scan a /24 for Z21, WiThrottle, and LocoNet-over-TCP
- Protocol libraries — frame encode/decode, checksums, WiThrottle line grammar; Rust crates are
no_std, noalloc - Loopback servers (Go) — Z21 UDP and WiThrottle TCP for tests and interop
- LocoNet gateway (Go) — fan-out upstream bus to binary/ASCII TCP listeners
- Shared vectors —
go run ./cmd/gen-vectorswritestestdata/; Go and Rust tests must match - CI interop — Rust protocol crate ↔ Go
Listenon every push - OpenTelemetry hooks (Go) — optional driver metrics without OTel on the hot path
| Area | Go | Rust | Notes |
|---|---|---|---|
| Z21 protocol | ✅ | ✅ | LAN frames, drive, functions, track power, CV/POM |
Z21 Station client |
✅ | — | Open("z21://…") / NewZ21Roco |
Z21 server (Listen) |
✅ | 🧪 | Rust crate is experimental |
| WiThrottle protocol | ✅ | ✅ | Handshake, acquire, drive, fn, e-stop, track power |
WiThrottle Station client |
✅ | — | Open("withrottle://…") / JMRI, DCC-EX, LNWI, RB1110 |
| WiThrottle server | ✅ | 🧪 | Rust crate is experimental |
| LocoNet framing + gateway | ✅ | 🧪 | Rust gateway is a stub |
LocoNet Station client |
✅ | — | Open("serial://…" / "loconet-tcp://…" / "lbserver://…") |
| LocoNet slot lifecycle | ✅ | — | Acquire, release, dispatch, steal |
| CV programming | ✅ | ✅ | Go: Station ReadCV/WriteCV (Z21+LocoNet); Rust: Z21 encode/decode + address helpers |
| Golden test vectors | ✅ | ✅ | Generated from Go |
| Usage guides | ✅ | ✅ | See docs/ below |
✅ production-oriented in this repo · 🧪 experimental / stub · — not implemented
Go packages (pkg.go.dev)
| Package | pkg.go.dev |
|---|---|
| Module | github.com/dcc-bigfred/proto/go |
commandstation |
pkgs/commandstation |
z21 |
pkgs/z21 |
withrottle |
pkgs/withrottle |
loconet |
pkgs/loconet |
drive |
pkgs/drive |
telemetry |
pkgs/telemetry |
| Document | Audience |
|---|---|
| Go module on pkg.go.dev | API reference for all Go packages |
| Go client guide | Connect, drive, functions, e-stop, track power |
| Rust protocol guide | no_std Z21 / WiThrottle from firmware or std::net |
| Z21 LAN spec | Wire format reference |
| LocoNet spec | Opcodes and framing |
| WiThrottle spec | Line protocol reference |
| Architecture | Repo layout, layers, equivalence |
This library exists for the rest of the dcc-bigfred stack:
- BigFred — layout hub (Go). Connected
Stationclients over Z21, LocoNet, and WiThrottle (commandstation). - BigFred Wizard — event-tablet helper (Rust). Talks Z21 LAN when programming handsets on the layout.
- LongFred — wireless throttle firmware (Rust
no_std). Encodes and decodes Z21 / WiThrottle on the device; the firmware owns sockets.
Go — full client to a command station:
make -C go test
# or from the repo root: make test-gogo get github.com/dcc-bigfred/proto/go@v0.1.0Reference: pkg.go.dev/github.com/dcc-bigfred/proto/go
Rust — protocol crate only (no sockets):
make -C rust test
# or from the repo root: make test-rustdcc-bigfred-proto-z21 = "0.1"
dcc-bigfred-proto-withrottle = "0.1"Path dependency: dcc-bigfred-proto-z21, dcc-bigfred-proto-withrottle under rust/.
Rust (crates.io) and Go (pkg.go.dev) use different git tags. Versions can match (0.1.0) but the tag names do not.
| Target | Git tag | How it is published |
|---|---|---|
| pkg.go.dev/github.com/dcc-bigfred/proto/go | go/vX.Y.Z |
Push the tag; go-release.yml tests and pings proxy.golang.org. Then go get github.com/dcc-bigfred/proto/go@vX.Y.Z. |
| crates.io | vX.Y.Z |
Bump [workspace.package] version in rust/Cargo.toml, commit, tag and push. release.yml publishes every crate without publish = false and creates a GitHub Release. Set repository secret CARGO_REGISTRY_TOKEN. |
Example: first public cut.
git tag go/v0.1.0
git push origin go/v0.1.0
# crates.io (after bumping rust/Cargo.toml):
git tag v0.1.0
git push origin v0.1.0The Go module lives in subdirectory go/, so the git tag must be prefixed (go/v0.1.0) while go get still uses @v0.1.0. Until the first go/v* tag is fetched by the proxy, pkg.go.dev returns 404. Versions v0.x show a “not yet at v1” notice.
Apache-2.0
