Stack map — rusty-bacnet, this app, bacpypes3, and friends
Beginners often ask: “Is everything rusty-bacnet?” No. This page is the map. Read it before Architecture.
LAB / HUMAN TOOLS (not in the appliance image)
┌─────────────────────────────────────────────────────────────────┐
│ bacpypes3 shell / scripts Workbench (optional) tcpdump │
│ (Python BACnet/IP client) (Windows FX UI) Wireshark │
└───────────────────────────────┬─────────────────────────────────┘
│ UDP 47808 (BACnet/IP)
▼
┌─────────────────────────────────────────────────────────────────┐
│ THIS REPO — DIY BACnet Router appliance │
│ │
│ React UI ──► routerd (Axum HTTP/WS) ──► router-core │
│ │ │
│ ▼ │
│ rusty-bacnet-adapter (thin wrap only) │
│ │ │
│ ▼ │
│ rusty-bacnet crates (PINNED upstream git SHA) │
│ bacnet-transport / bacnet-network / encoding / types │
│ │ │
│ B/IP socket ◄──────► MS/TP USB RS-485 │
└─────────────────────────────────────────────────────────────────┘
│ RS-485 trunk
▼
┌─────────────────────────────────────────────────────────────────┐
│ LAB FIXTURES / FIELD DEVICES │
│ mstp-mini-device (Vibe13) · real FEC / other MS/TP devices │
└─────────────────────────────────────────────────────────────────┘
1. rusty-bacnet (upstream ecosystem)
| Item | Detail |
|---|---|
| What | Open Rust BACnet stack — transports, NPDU routing, MS/TP master logic, codecs |
| Where | jscott3201/rusty-bacnet |
| How we use it | Pinned full git SHA in Cargo.toml + config/upstream-lock.toml (never a floating dev branch in commits) |
| Crates we consume | bacnet-types, bacnet-encoding, bacnet-transport, bacnet-network |
| What it is not | Not our web UI, not our Buildroot OS, not bacpypes3 |
We prefer upstream public APIs. We do not copy stack internals into this
repo to paper over an API mismatch. Pin bumps follow the Repin gate in
AGENTS.md.
2. This repository (Rust + React + Buildroot) — outside “just the stack”
Everything below is ours (or our packaging). It sits around rusty-bacnet.
| Piece | Language | Job |
|---|---|---|
rusty-bacnet-adapter |
Rust | Only crate allowed to call rusty-bacnet; maps ports/sessions into appliance types |
router-core |
Rust | Config, capabilities, metrics contracts — no Axum, serial, or BACnet deps |
routerd |
Rust | Process entry: open ports when opted in, HTTP/WebSocket/Prometheus, embed React |
frontend/web |
React / TypeScript | LAN operator dashboard (status, metrics). Management only — never blocks MS/TP |
| Buildroot external | Make / configs | Custom Linux OS image (kernel, eudev, USB-serial, service unit) |
| Ansible lab playbooks | YAML | Deploy dual mini fixtures / baud changes on Mint lab Pis |
| Evidence + Learn docs | Markdown | Honest gates; beginner tutorials on GitHub Pages |
The web app is not rusty-bacnet. It is React assets served by routerd
(Axum). Closing a browser tab must never stop token passing on the RS-485 trunk.
Default boot is fail-closed: management may run; BACnet forwarding stays off
until a controlled lab flag such as --route-enable.
3. bacpypes3 — lab / field troubleshooting client (not in the product)
| Item | Detail |
|---|---|
| What | Python BACnet/IP stack + interactive shell |
| Where | bacpypes3; cheat sheet gist |
| How we use it | Oracle on the Ethernet side: whois, wirtn, read 2001:7@router … through our DIY router |
| Shipped in appliance image? | No |
Same process as routerd? |
No — separate venv / host; must use a different BIP IP than the router bind |
Typical lab flow:
- Start DIY router on bensbench (BIP
.11, MS/TP MAC1). - Run bacpypes3 on another address (e.g. Pi Ethernet
.59or.12alias). read 2001:2@192.168.204.11 device,123102 object-name— proves routing, not the Python stack inside the appliance.
Scripts such as scripts/lab_routed_rp_oracle.py wrap the same idea for
non-interactive evidence packs.
4. Other things outside rusty-bacnet (lab / optional)
| Piece | Role |
|---|---|
Vibe13 mstp-mini-device |
Fake MS/TP device (MAC/instance) for trunk tests — lives in py-bacnet-stacks-playground; not imported as the router data plane |
| Real controllers (e.g. JCI FEC) | Field devices on the trunk; read-only in our lab; baud often fixed (ours: 38400) |
| FX Workbench | Optional Windows BACnet/IP UI evidence — not required for CI |
| tcpdump / Wireshark | Packet proof on UDP 47808 |
| ace-bbmd-manager (mentioned in the gist) | Optional BBMD topology walks — product BBMD stays off until named gates pass |
| GitHub Actions | ci, bip-qualify, build-os — software / netns / Buildroot images (no local heavy Buildroot on the lab PC) |
One-sentence summary
rusty-bacnet moves BACnet bits; this repo wraps it in an appliance OS + management UI; bacpypes3 is how humans/agents test the Ethernet side from outside; minis/FEC are what live on the RS-485 cable.