diff --git a/protocols.md b/protocols.md new file mode 100644 index 0000000..2c10403 --- /dev/null +++ b/protocols.md @@ -0,0 +1,119 @@ +# XpressNet vs LocoNet vs Roco Z21 over WebSocket/TCP + +Date: 23 février 2026 + +This note compares **XpressNet**, **LocoNet**, and **Roco Z21** for use in this project where protocol messages are exchanged through a **TCP connection via WebSocket**. + +## Scope + +- Compare all options on: + - Functionality + - Simplicity of implementation +- Assume transport is not native bus wiring, but encapsulated over WebSocket/TCP. + +## Quick Summary + +- **XpressNet** is generally simpler to implement as a request/response protocol with clearer master/slave behavior. +- **LocoNet** is generally richer and more event-driven, but that usually means more parser/state complexity. +- **Roco Z21** is typically the easiest for IP-native integration because it is already network-oriented. +- For a minimal and reliable WebSocket bridge: + - easiest IP-native path: **Roco Z21** + - easiest classic bus-style path: **XpressNet** + +## Functional Comparison + +| Area | XpressNet | LocoNet | Roco Z21 | +|---|---|---|---| +| Architecture style | Master/slave polling/request-response | Multi-master event bus with asynchronous traffic | IP/LAN command protocol | +| Locomotive control | Strong support (speed, direction, functions) | Strong support (speed, direction, functions) | Strong support (speed steps, direction, functions) | +| Accessory control | Supported | Supported | Supported | +| Feedback/sensors | Supported, often through explicit queries | Strong asynchronous event reporting | Supported (depends on connected modules and setup) | +| Bus arbitration concerns | Lower in logical model | Higher (collision/arbitration model in native bus semantics) | Low at application layer (network transport handles link-level arbitration) | +| Typical message flow | More deterministic sequences | More spontaneous/event-driven traffic | Command/response plus asynchronous status updates | +| Ecosystem breadth | Strong in Lenz/XpressNet-oriented environments | Very broad in Digitrax/LocoNet ecosystems | Strong in Roco/Fleischmann Z21 ecosystems | + +## Simplicity Comparison (for WebSocket/TCP) + +### XpressNet + +Pros: + +- Easier command/response mapping to WebSocket request IDs. +- More deterministic transactions reduce server-side state machine complexity. +- Simpler for first implementation of throttle + function control. + +Cons: + +- Can require periodic polling for some status data. +- Less naturally event-driven than LocoNet. + +### LocoNet + +Pros: + +- Naturally event-oriented; good for pushing updates to all connected WebSocket clients. +- Very capable for layouts with rich feedback traffic. + +Cons: + +- More complex parser/state handling due to asynchronous mixed traffic. +- Harder to keep deterministic behavior for beginners. +- Requires careful handling of event ordering and duplication in TCP/WebSocket bridge logic. + +### Roco Z21 + +Pros: + +- IP-native model maps naturally to TCP/WebSocket gateway designs. +- Good fit when your command station already exposes Z21 LAN interfaces. +- Usually less protocol-bridging effort for app/web control. + +Cons: + +- More tied to Z21 ecosystem assumptions and command set. +- Feature depth can vary with hardware/firmware capabilities. +- Integration with non-Z21-specific buses may still need mapping layers. + +## WebSocket/TCP Considerations (all options) + +- Add an application frame format (JSON or binary) with: + - `type` (protocol/command) + - `seq` or transaction ID + - `timestamp` + - payload bytes or structured fields +- Handle reconnect cleanly: + - session restore (selected loco, speed, function states) + - idempotent command handling where possible +- Separate command channel and telemetry/events logically (even if same WebSocket). +- Add rate limiting/coalescing for high-frequency updates (speed sliders, feedback bursts). +- Define timeout + retry policy at bridge layer, not only protocol layer. + +## Practical Recommendation + +If the priority is **simplicity and quick delivery** for a WebSocket-based controller: + +1. If a Z21 command station is available, start with **Roco Z21** for MVP. +2. Otherwise start with **XpressNet**. +3. Use **LocoNet** when rich asynchronous bus events are a primary requirement. +4. Implement core features first: + - loco select + - speed/direction + - function groups (F0+) + - accessory switch basic commands +5. Add event streaming abstractions in your WebSocket API so a future backend swap (**XpressNet/LocoNet/Z21**) can fit without breaking clients. + +If the priority is **richer asynchronous layout events** from day one and complexity is acceptable: + +- Choose **LocoNet** and invest early in robust event/state synchronization. + +## Suggested API-neutral internal model + +To support all three options long-term, keep an internal domain model independent of bus specifics: + +- `ThrottleCommand` +- `FunctionCommand` +- `AccessoryCommand` +- `FeedbackEvent` +- `PowerStateEvent` + +Then map protocol-specific frames to/from this model.