diff --git a/z21.md b/z21.md new file mode 100644 index 0000000..5360ca9 --- /dev/null +++ b/z21.md @@ -0,0 +1,73 @@ +# Z21 Items and Actions (WebSocket/TCP) + +Date: 23 février 2026 + +This document lists practical Z21 control items and their expected actions when exposed through a WebSocket/TCP API. + +## Command Table + +| Item | WebSocket Action | Typical Parameters | Expected Effect | Notes | +|---|---|---|---|---| +| Connection / Handshake | `z21.connect` | `clientName`, `protocolVersion` | Opens session, validates client, initializes subscriptions | Required before control commands | +| Track Power ON | `z21.track.power_on` | none | Energizes track output | Keep idempotent: calling twice stays ON | +| Track Power OFF | `z21.track.power_off` | none | Cuts track output immediately | Keep idempotent: calling twice stays OFF | +| Emergency Stop | `z21.track.emergency_stop` | optional `scope` (`all`/`loco`) | Immediate stop for all locomotives or selected scope | Higher priority than normal speed commands | +| Read Power State | `z21.track.power_state` | none | Returns current state (`on`/`off`/`estop`) | Useful on reconnect | +| Loco Acquire | `z21.loco.acquire` | `address` | Reserves/selects locomotive for control | Enforce ownership rules if multi-client | +| Loco Speed/Direction | `z21.loco.drive` | `address`, `speedStep`, `direction` | Updates speed and direction | Validate speed-step mode compatibility | +| Loco Function Set | `z21.loco.function` | `address`, `fn`, `value` | Sets F0..Fn on/off (or tri-state if supported) | Coalesce bursts for UI sliders/buttons | +| Accessory Switch | `z21.accessory.set` | `address`, `state` (`thrown`/`closed`) | Toggles turnout/accessory output | Add optional pulse duration if needed | +| Read Loco State | `z21.loco.state` | `address` | Returns cached/current speed, direction, functions | Source can be polled or event-fed | +| Subscribe Events | `z21.subscribe` | list of topics | Enables push updates (power, loco, accessory, feedback) | Recommended for reactive UI | +| Unsubscribe Events | `z21.unsubscribe` | list of topics | Stops selected event streams | Keep lightweight for mobile clients | + +## Special Actions + +| Special Item | WebSocket Action | Values | Expected Action | Compatibility Note | +|---|---|---|---|---| +| Switching Mode | `z21.track.switch_mode` | `analog`, `marklin`, `dcc` | Requests output/protocol mode switch | Not always a native Z21 LAN command; may require backend-specific mapping or be unsupported on some hardware/firmware | +| Ensure Track Power ON/OFF Exists | `z21.track.power_on` / `z21.track.power_off` | none | Guarantees explicit power control in API | Keep these actions present even if other protocols already define similar commands | + +## Suggested Request/Response Shapes + +### Request + +```json +{ + "type": "z21.track.power_on", + "seq": 102, + "payload": {} +} +``` + +### Success Response + +```json +{ + "type": "ack", + "seq": 102, + "ok": true, + "result": { + "trackPower": "on" + } +} +``` + +### Event Push Example + +```json +{ + "type": "event.track.power", + "timestamp": "2026-02-23T12:00:00Z", + "payload": { + "state": "off" + } +} +``` + +## Implementation Notes + +- Treat `power_on`, `power_off`, and `emergency_stop` as safety-critical and process first. +- Make power and mode commands idempotent and return current state after execution. +- For `switch_mode`, return explicit capability errors when unsupported, for example: `ERR_UNSUPPORTED_MODE_SWITCH`. +- Keep internal model protocol-neutral (`ThrottleCommand`, `FunctionCommand`, `PowerStateEvent`) to simplify interoperability with XpressNet/LocoNet backends.