#305 - extract calypso-sim into a standalone MQTT simulator crate#326
Draft
bracyw wants to merge 10 commits into
Draft
#305 - extract calypso-sim into a standalone MQTT simulator crate#326bracyw wants to merge 10 commits into
bracyw wants to merge 10 commits into
Conversation
…ous modes Replace `simulate` with a single `calypso-sim` binary organized as a folder of focused modules under `src/bin/calypso-sim/`. Modes (can run together): - Autonomous heartbeat (`--auto`, default when no other mode is chosen) - Interactive keymap (`--key-map`) - Scripted keymap replay (`--script` with `--key-map`) - JSON-RPC 2.0 over stdio (`--stream`, for an agent) Per-topic ownership (`auto` / `stream` / `silenced`) lets stream and keymap modes claim/release/silence topics; the autonomous loop checks ownership before each publish. Stream protocol: NDJSON over stdin/stdout, methods `publish`, `claim`, `release`, `silence`, `status`, `list_topics`, `ping`. Tracing on stderr so stdout stays clean for JSON-RPC. Other: - Startup warning lists CAN topics with no `sim_freq` - README documents all four modes, keymap formats, and the stream protocol - Keymap supports Random / Pinned / Increment / Sequence per key, with optional `desc` per entry
Adds calypso-sim/scripts/: vcu_mimic.py (drives the sim's stream mode to emulate the VCU), the generated serverdata_pb2.py, and a README.
# Conflicts: # Cargo.toml # Odyssey-Definitions # src/bin/simulate.rs
Add `"unit": ""` to the 9 Wheel/Buttons/button_id entries so they publish without relying on a `sim` block in Odyssey-Definitions. We dropped the local-only OD sim-block commit and point the submodule at Develop's pointer, where button_id is not auto-simulatable; explicit units keep these keymap entries working. button_id is the only non-simulatable topic in this keymap (home_mode/nero_index/not_in_reverse remain simulatable via Develop's OD).
- autonomous: validate --enable/--disable-topic regexes up front so a bad pattern exits non-zero instead of silently disabling the heartbeat - script: fail-fast on malformed sleep / multi-char / unknown-key lines (deterministic replay shouldn't silently skip) - stream: async stdout so a stalled consumer can't block a runtime worker - build.rs: rerun-if-changed=Odyssey-Definitions so spec edits rebuild sim data - simulatable_message: guard SimValue::initialize against empty range/options to avoid a startup panic on a degenerate spec - drop set_topic_alias_max(600) to match the decoder and prior simulator - fix S5 README description (REVERSE is gateless) and vcu_mimic cleanup branch - remove Embedded-Base gitlink (not on Develop, no .gitmodules entry, unreferenced)
…st degenerate spec - Remove `crossterm` from the root Cargo.toml (zero refs in src/ or libs/; only the separate calypso-sim crate uses it, via its own manifest) and drop its now-orphaned transitive crates from Cargo.lock — pure removal, no other version changes. - Guard `SimValue::initialize` in the main crate against degenerate spec entries (empty min==max range, empty discrete options) so a malformed CAN spec can't panic at startup, bringing it to parity with the already-hardened calypso-sim copy. - Remove the now-stale "Divergence from upstream" note from the vendored calypso-sim copy, since upstream now carries the same guards.
…compile placeholder regex once
Centralize the per-topic publish/ownership policy that was re-derived inline at
four call sites across three mode files: add TopicRegistry::auto_may_publish
(the heartbeat publishes only while a topic is still Auto-owned) and
driver_may_publish (stream/keymap drivers publish unless a topic is Silenced),
co-located with the Owner enum, and route autonomous/keymap/stream through them.
Behavior-preserving.
In the vendored simulatable_message.rs, hoist the `{}` placeholder Regex in
topic_values_inject into a compile-once LazyLock and drop the per-call
intermediate Vec - a documented sim-local divergence from the upstream copy,
which still recompiles per call.
These per-repo Claude Code command/skill files were force-added in fdab310 despite `.claude` already being in .gitignore (since 7ac8de7). Untrack them with `git rm --cached` so the ignore rule takes effect — the files stay on disk locally and remain in history at fdab310; this only drops them from the branch tip going forward.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Pulls the MQTT simulator out of the main
calypsobinary into its own standalonecalypso-simcrate, and deletes the old in-treesrc/bin/simulate.rs. The new crate has four input modes — autonomous heartbeat, interactive keymap, scripted replay, and a JSON-RPC stream driver — arbitrated by a per-topic ownership model so the heartbeat doesn't fight a live driver. Also drops the now-unusedcrosstermdep from the main crate and guardsSimValue::initializeagainst degenerate spec entries (emptymin==maxrange / empty discrete options) so a malformed spec can't panic at startup.Notes
calypso-simis its own workspace (detachedCargo.lock+ target dir), so it does not build from a top-levelcargo build --all—cd calypso-simfirst. Seecalypso-sim/README.mdfor all flags, the keymap format, and the stream protocol.calypso-sim/src/{simulatable_message,data}.rsare intentional vendored copies of the main crate's files (the sim crate can't depend oncalypso). One small documented sim-local divergence:topic_values_injectcompiles its{}placeholder regex once instead of per call.calypsocrate doesn't compile on macOS (it usessocketcanin non-cfg-gated lib code — pre-existing, identical onDevelop), so root-workspaceclippy/testonly pass on Linux/CI. The changed code here is thecalypso-simcrate, which passesfmt/clippy -D warnings/testlocally.keymap.rsdoc-vs-code nit onunitprecedence for known topics, and (upstream, then re-vendor) the remainingsimulatable_message.rsmicro-perf items (rand::rng()reuse).Test Cases
All assume a broker running (
mosquitto) and a viewer (mqttui). Fromcalypso-sim/:cargo run -- --list-topics— prints every simulatable topic + unit and exits 0.cargo run— autonomous heartbeat;mqttuishows live-looking values updating for every topic that has asim_freqin the spec. Topics without one are listed once at startup asWarning topics (not simulated): ....cargo run -- --enable-topic '^BMS/'— heartbeat publishes onlyBMS/...topics;--disable-topic '^BMS/'does the inverse (the two are mutually exclusive).cargo run -- --key-map manual_sim_keymap.example.json— interactive raw mode; a mapped keypress publishes its topic (random / pinned / increment / sequence per the entry), logging[k] Topic = [..] unit.Ctrl+Cexits cleanly.cargo run -- --key-map keys.json --script play.txt— replays the script lines (single chars fire keys,sleep Nwaits), then exits.cargo run -- --key-map keys.json --auto— interactive plus background heartbeat; claimed keymap topics override the heartbeat and release back to it afterward.cargo run -- --streamthen on stdin:{"jsonrpc":"2.0","id":1,"method":"publish","params":{"topic":"Wheel/Buttons/button_id","value":5}}→ one-line response{"...","result":{"ts_us":...}}and the message lands on the broker.claim/release/silence/status/list_topics/pingbehave per the README table.Checklist
Closes #305