Files
escape_gallery_obsidian_vault/Projects/Software/Escape Gallery Control Software.md
2026-07-11 16:48:59 -07:00

342 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
active: true
tags:
- project
- eg
---
## Goal
Create escape room control software. Each Raspberry Pi (RPi) controls some number of wired props in the room. The room and props are referred to as the game. The game is made up of a number of game elements which can be puzzles, lights, sound, etc.. Each element can utilize one or more props, wired and/or non-wired.
## System Diagram
![[EG-Controllers.png]]
## Tasks
- [x] Add horse nicker as a sound effect 2026-05-11 ✅ 2026-05-11
- [x] Set horse to only trigger in auto pilot if ship and axe puzzle are solved, otherwise nicker and reset after 10 seconds 2026-05-10 ✅ 2026-05-12
- [x] Set helmets to only trigger in auto pilot if knocker is solved, otherwise grunt and reset after 10 seconds 2026-05-10 ✅ 2026-05-12
- [x] Display the version number in the DMG title (use `version.json5`) 2026-04-21 ✅ 2026-05-14
- [x] Collect and display the prop controller version numbers and display in the user interface 2026-05-11 ✅ 2026-05-14
- [x] Change the drum sequence and the number of lights that illuminate 2026-05-15 ✅ 2026-05-20
- [x] Add the lock combinations to the user interface 2026-04-23 ✅ 2026-05-20
- [x] Put all locks on one tab 2026-05-22 ✅ 2026-05-30
- [ ] Add drum puzzle sequence to the UI 2026-05-22
- [ ] Add axe puzzle order to the UI 2026-05-22
- [ ] Add the table puzzle order to the UI 2026-05-22
- [ ] Move all lock combinations onto one tab 2026-05-21
- [ ] Add Postgres user for the control software 2026-05-22
- [ ] Add tables for the Memir phrases 2026-05-22
- [ ] Collect and display the game controller version number in the user interface 2026-05-14
- [ ] Change the knocker sequence to match the tapping 2026-05-15
## Archived Tasks
- [x] Change each prop controller to send the time to the next ping in seconds along with it's name 2026-04-21 ✅ 2026-05-09
- [x] Ensure prop controllers send a ping when they start 2026-04-22 ✅ 2026-05-09
- [x] Add `.pkg` generation to the `odin_ui/Justfile` with version number in file name 2026-03-20 ✅ 2026-05-09
- [x] Rename `sys_ping_interval_secs` in the server to be `initial_sys_poll_time_secs` 2026-04-21 ✅ 2026-05-09
- [x] Keep track of all next contact Instant 2026-04-21 ✅ 2026-05-10
- [x] Switch iOS build of Odin to Escape Gallery profile 2026-04-16 ✅ 2026-05-10
- [x] Add support for pre-defined messages for Memir in the user interface 2026-03-05 ✅ 2026-05-06
- [x] Create a separate stopwatch task with it's own commands; start, stop, reset 2026-02-06 ✅ 2026-02-11
- [x] Incorporate new stopwatch into auto pilot and UI 2026-02-09 ✅ 2026-03-17
- [x] Fix timer to be visible everywhere 2026-02-07 ✅ 2026-03-17
- [x] Add faster feedback when press speak button 2026-02-07 ✅ 2026-03-17
- [x] Move Memir up in the UI 2026-02-07 ✅ 2026-04-16
- [x] Update the [[Escape Gallery Control Software]] with Geno structures 2026-03-23 ✅ 2026-04-16
- [x] Swap in Geno for all messages and use MessagePack in Dart 2026-03-03 ✅ 2026-04-16
- [x] Test out using MessagePack in Dart with Geno and Rust 2026-03-03 ✅ 2026-04-16
- [x] Add `release` to the `Justfile` to build macOS package and iOS app 2026-04-16 ✅ 2026-04-21
- [x] Fix running the app in release mode on MacOS 2026-03-08 ✅ 2026-04-21
- [x] Create a tool to generate the `update` methods that copy from game command to game state where the name matches 2026-04-22 ✅ 2026-04-23
- [x] Sync up all the game command message field with corresponding state message fields 2026-04-22 ✅ 2026-04-23
- [x] Finish the `odin_game_test` service that just responds to commands by changing state 2026-04-21 ✅ 2026-04-23
- [x] Add a script to start the NATS service and the test game controller 2026-04-23 ✅ 2026-04-23
- [x] Move all `getFullState` calls into the services after connection 2026-04-23 ✅ 2026-04-26
- [x] All UI latch toggles are broken 2026-04-23 ✅ 2026-04-26
- [x] Change UI to toggle buttons to solve/unsolve puzzles 2026-04-23 ✅ 2026-04-26
- [x] Fix the bug with leaving the bellows in the fishes mouth 2026-03-05 ✅ 2026-04-26
- [x] Add the two iOS devices to the provisioning profile for Escape Gallery 2026-04-16 ✅ 2026-04-27
- [x] Create a tool to generate the `update` from prop state to prop state 2026-04-22 ✅ 2026-05-01
- [x] Fix iOS app to reconnect to the NATS service after resume 2026-04-22 ✅ 2026-05-04
- [x] Add `ClueServer` to `odin-ctrl` 2026-02-04 ✅ 2026-02-04
- [x] Move Piper TTS code over to `odin-av2` and cut volume 2026-02-04 ✅ 2026-02-04
- [x] Add Memir text to speech UI 2026-01-16 ✅ 2026-02-04
- [x] Debug Memir end-to-end 2026-02-04 ✅ 2026-02-06
- [x] Ensure time with seconds shows when in finished state 2026-01-28 ✅ 2026-02-06
- [x] Increase power supply timer for `odin-drum` and screw down the lid 2026-01-26 ✅ 2026-02-06
- [x] Remove and drill out the holes for the knocker 2026-02-04 ✅ 2026-02-06
- [x] Ensure `odin-ctrl` restarts always (fix `.conf` file) 2026-01-28 ✅ 2026-02-06
- [x] Write test program for `odin-av2` to test TTS 2026-01-14 ✅ 2026-02-04
- [x] Fix `odin-av2` build problem 2026-01-18 ✅ 2026-01-25
- [x] Design and print caps for the knocker switches 2026-01-18 ✅ 2026-01-25
- [x] Fix the electronics in the horses head 2026-01-11 ✅ 2026-01-25
- [x] Add continuous re-start logic to all servers 2026-01-22 ✅ 2026-01-25
- [x] Fix the knocker detection algorithm 2026-01-14 ✅ 2026-01-26
- [x] Merge new knocker code into `odin-drum` 2026-01-26 ✅ 2026-01-27
- [x] Add the code to gradually turn off the sconces 2026-01-19 ✅ 2026-01-28
- [x] Wolf snarl starts to quickly after last animal head solved 2026-01-19 ✅ 2026-01-19
- [x] End sequence starts to quickly after hammer or dragon is solved 2026-01-19 ✅ 2026-01-19
- [x] Tree of life lights turn off when the helm lights are turned on or off 2026-01-19 ✅ 2026-01-19
- [x] Turn on the other light when going through the fireplace 2026-01-19 ✅ 2026-01-19
- [x] Fireplace latch extra toggles need to be faster 2026-01-19 ✅ 2026-01-19
- [x] Reduce sound effect volume 2026-01-19 ✅ 2026-01-19
- [x] Switch eyes on the berserker heads in the prop controller 2026-01-18 ✅ 2026-01-19
- [x] Change all prop controller `main.rs` and `config_file.rs` to require a config file 2026-01-18 ✅ 2026-01-19
- [x] Reduce number of times required to turn crank and make configurable 2026-01-19 ✅ 2026-01-19
- [x] Put `degrees_to_duty_cycle` in `odin_prop_util` 2026-01-19 ✅ 2026-01-19
- [x] Dragons triggered with only one half of the spear 2026-01-19 ✅ 2026-01-19
- [x] Turn off barrel puzzle after 5 minutes 2026-01-19 ✅ 2026-01-19
- [x] Make Memir's eye pulse when on 2026-01-19 ✅ 2026-01-19
- [x] Make sconces flicker 2025-08-13 ✅ 2026-01-19
- [x] Make chandelier flicker 2025-12-23 ✅ 2026-01-19
- [x] Make fireplace flicker 2025-12-23 ✅ 2026-01-19
- [x] `Off` condition must turn off cupboards lights, dragon eyes, helm eyes, hammer box light 2026-01-19 ✅ 2026-01-19
- [x] Check the `Running` room condition sets all the game states 2026-01-19 ✅ 2026-01-19
- [x] Implement the `Ready` room condition 2026-01-17 ✅ 2026-01-19
- [x] Implement the `Resetting` room condition 2026-01-17 ✅ 2026-01-19
- [x] Implement the `Finished` room condition 2026-01-17 ✅ 2026-01-19
- [x] Turn on warriors eyes when helm puzzle solved 2026-01-19 ✅ 2026-01-19
- [x] Check tree lights turn on when the fireplace opens 2026-01-19 ✅ 2026-01-19
- [x] Add sound effects into the auto-pilot; eagle, horse, bear, fish, hammer, dragons, 2026-01-18 ✅ 2026-01-19
- [x] Grand finale lightning sequence with flashing lights 2026-01-18 ✅ 2026-01-19
- [x] Add a timer to the auto-pilot tab 2026-01-19 ✅ 2026-01-19
- [x] Hook up auto-pilot logic to update the time and sconces based on the time elapsed 2026-01-19 ✅ 2026-01-19
- [x] Have fire place latch cycle 3 times in the prop controller 2026-01-19 ✅ 2026-01-19
- [x] Replace the barrel audio 2026-01-13 ✅ 2026-01-14
- [x] Test out the microphones and make sure we can hear everything 2026-01-13 ✅ 2026-01-14
- [x] Refactor to remove the timer in the controller in prep for moving timing to the auto-pilot 2026-01-14 ✅ 2026-01-14
- [x] Add margin to the LabelIconButtons 2026-01-16 ✅ 2026-01-16
- [x] Make a LabelButton widget with a fix width 2026-01-14 ✅ 2026-01-16
- [x] Switch to using `publish_json` and `publish_rmp` in `odin_ctrl` 2026-01-15 ✅ 2026-01-16
- [x] Get [piper-rs](https://github.com/thewh1teagle/piper-rs) building in container 2026-01-14 ✅ 2026-01-16
- [x] Go through all `cmd_loop`'s and move `Some(cmd) =>` logic inside the `match` 2026-01-04 ✅ 2026-01-16
- [x] Rename dragon to mantle puzzle 2026-01-11 \7 u ✅ 2026-01-16
- [x] Create new helm electronics for testing with simulator 2026-01-10 ✅ 2026-01-17
- [x] Repair electronics for the helms in `odin-tree` 2026-01-11 ✅ 2026-01-17
- [x] Implement end game and room off commands for auto-pilot 2026-01-16 ✅ 2026-01-17
- [x] Remove "Auto Pilot" toggle and add buttons for "Room Ready", "Start Game", "End Game", and "Room Off" 2026-01-14 ✅ 2026-01-17
- [x] Process, add to `assets` and upload all sound effects to `odin-av1` 2026-01-15 ✅ 2026-01-17
- [x] Write test program to set background audio volume 2026-01-15 ✅ 2026-01-18
- [x] Play sound effects and duck background audio 2026-01-11 ✅ 2026-01-18
- [x] Change color of buttons when value like radio button (add a flag to `LabelIconButton`) 2026-01-11 ✅ 2026-01-18
- [x] Hook up Ui for sound effects 2026-01-15 ✅ 2026-01-18
- [x] Implement the `Off` room condition 2026-01-17 ✅ 2026-01-18
- [x] Install new software on iPad 2026-01-18 ✅ 2026-01-19
- [x] Commit all `odin_test` to Gitea 2026-01-11 ✅ 2026-01-11
- [x] Create test program for the drum sequence 2026-01-11 ✅ 2026-01-11
- [x] Finish the coding for the drum sequence 2026-01-04 ✅ 2026-01-11
- [x] Fix sequence and write the tree on/off prop code 2025-12-29 ✅ 2026-01-11
- [x] Install new piezo drum vibration sensors 2025-08-17 ✅ 2026-01-11
- [x] Write code for `odin-drum` to detect drumming pattern 2025-12-23 ✅ 2026-01-11
- [x] Hook up knocker to auto-pilot 2025-12-26 ✅ 2026-01-11
- [x] Hook up drums to auto-pilot 2025-12-26 ✅ 2026-01-11
- [x] Hook up hammer hand to auto-pilot 2026-01-11 ✅ 2026-01-11
- [x] Hook up dragons to auto-pilot 2026-01-11 ✅ 2026-01-11
- [x] Add the timer to the auto-pilot 2025-12-23 ✅ 2026-01-13
- [x] Add UI to start background music 2025-12-23 ✅ 2026-01-11
- [x] Add UI for drums 2025-12-23 ✅ 2026-01-11
- [x] Design the case for the combined power and buck board 2025-12-23 ✅ 2026-01-11
- [x] Print cases and assemble and program the first one taking notes 2025-12-23 ✅ 2026-01-11
- [x] Add code to read the Berserker heads in `odin_tree` 2025-11-06 ✅ 2026-01-11
- [x] Add UI for Berserker heads 2025-11-12 ✅ 2026-01-11
- [x] Make the barrel puzzle audio play forever 2026-01-04 ✅ 2026-01-10
- [x] Add a switch in UI to turn on tree lights 2025-11-12 ✅ 2026-01-10
- [x] Write the helms prop code 2025-12-29 ✅ 2026-01-10
- [x] Finish the dragon prop code (reset is not working) 2026-01-03 ✅ 2026-01-10
- [x] Finish the coding for the detection of the knocker sequence 2026-01-04 ✅ 2026-01-10
- [x] Add `av1` and `av2` into System tab 2025-12-13 ✅ 2025-12-13
- [x] Create prop control software for `odin-av1` 2025-12-13 ✅ 2025-12-13
- [x] Create prop control software for `odin-av2` 2025-12-13 ✅ 2025-12-13
- [x] RFID reader for spear do not register RFID tag reliably. Wall is likely too thick, there are metal nails or screws in the wood, RFID tags buried too deep 2025-11-08 ✅ 2025-11-13
- [x] Dagger no longer registers reliably. RFID in wrong position or too deep. Also, knife can be reversed so not sure which side RFID tag is on 2025-11-08 ✅ 2025-11-13
- [x] Horses right eye no longer registers light/dark - need to dismantle and debug 2025-11-08 ✅ 2025-11-13
- [x] Divide up the controllers equally between the power supplies and see if that fixes the power on problem 2025-11-08 ✅ 2025-11-13
- [x] Add horse head eye sensor code code in `odin_middle` 2025-11-04 ✅ 2025-11-06
- [x] Add short door latch opener code to `odin_left` 2025-11-05 ✅ 2025-11-06
- [x] Add long door latch opener code to `odin_left` 2025-11-05 ✅ 2025-11-06
- [x] Create `deploy-all` script 2025-11-05 ✅ 2025-11-06
- [x] Add reset UI 2025-11-08 ✅ 2025-11-08
- [x] Get fish RFID reader working with reset on `odin_left` 2025-11-04 ✅ 2025-11-08
- [x] Get bear RFID reader working with reset `odin_left` 2025-11-04 ✅ 2025-11-08
- [x] Get bird RFID reader working `odin_middle` 2025-11-04 ✅ 2025-11-08
- [x] Get horse eye light sensors working `odin_middle` 2025-11-04 ✅ 2025-11-08
- [x] Change `PROP_SYSTEM_STATE_SUBJECT` to `prop.system.state` and re-deploy all prop controllers 2025-11-04 ✅ 2025-11-08
- [x] Fix the broken sensors on the barrel puzzle 2025-11-04 ✅ 2025-11-08
- [x] Add UI for the knocker puzzle; knocker, long door 2025-11-08 ✅ 2025-11-08
- [x] Get knocker door opener working 2025-11-08 ✅ 2025-11-08
- [x] Add UI for drum puzzle; tree, sensors, short door 2025-11-08 ✅ 2025-11-08
- [x] Get the drum door opener working 2025-11-08 ✅ 2025-11-08
- [x] Add UI for the helm puzzle; helmets, hammer chest 2025-11-08 ✅ 2025-11-08
- [x] Get helm puzzle chest opening 2025-11-08 ✅ 2025-11-08
- [x] Add UI for `berserker_puzzle.` 2025-11-06 ✅ 2025-11-09
- [x] Rename `odin_prop` to `odin_prop_msg` 2025-11-08 ✅ 2025-11-09
- [x] Create a new `odin_prop_util` for `helpers.rs` contents and remove all helpers.rs files 2025-11-08 ✅ 2025-11-09
- [x] Tidy up dragon puzzle UI 2025-11-11 ✅ 2025-11-11
- [x] Get spear hooked up to UI 2025-11-11 ✅ 2025-11-11
- [x] Create a generic to `fn` for receiving `Cmd` messages and do a `debug!` in prop controllers like in `odin_ctrl` 2025-11-08 ✅ 2025-11-12
- [x] Generate a Dart file for `SvgPicture` in a service and register 2025-11-05 ✅ 2025-11-12
- [x] Get hammer UI working; hand 2025-11-08 ✅ 2025-11-12
- [x] Get table puzzle UI coded 2025-10-18 ✅ 2025-10-31
- [x] Get ship puzzle UI coded 2025-10-26 ✅ 2025-10-31
- [x] Change timer UI to be a slider 2025-10-25 ✅ 2025-10-31
- [x] Add a [Slider](https://api.flutter.dev/flutter/material/Slider-class.html) with discrete values and allow setting 2025-10-26 ✅ 2025-10-31
- [x] Get fireplace puzzle UI coded 2025-10-26 ✅ 2025-10-31
- [x] Get barrel puzzle UI coded 2025-10-31 ✅ 2025-10-31
- [x] Configure laptop so I can build and install control software on iPad 2025-10-31 ✅ 2025-11-01
- [x] Figure out how to set macOS menu and window to **Odin** 2025-10-31 ✅ 2025-11-01
- [x] Hook lighting up end-to-end 2025-10-31 ✅ 2025-11-01
- [x] Create a `label_switch` widget with a ✅ 2025-11-01
- [x] Use `label_switch` everywhere for consistent sizing of label plus switch 2025-11-01 ✅ 2025-11-01
- [x] Debug the axe puzzle 2025-11-01 ✅ 2025-11-01
- [x] Create a `PositionedAxe` widget with a `bool?` for the state 2025-11-01 ✅ 2025-11-01
- [x] Refactor `odin-ctrl` to pass discrete `bool?` back to UI for axes from controller 2025-11-01 ✅ 2025-11-02
- [x] Split lighting into throne and feast rooms 2025-10-31 ✅ 2025-11-02
- [x] Refactor controller to use `include!` to avoid extra module 2025-11-02 ✅ 2025-11-02
- [x] Hook table puzzle up end-to-end 2025-11-01 ✅ 2025-11-02
- [x] Hook ship puzzle up end-to-end 2025-10-31 ✅ 2025-11-02
- [x] Make `NavigationRail` scrollable 2025-11-04 ✅ 2025-11-04
- [x] Hook up the barrel puzzle end-to-end 2025-11-02 ✅ 2025-11-04
- [x] Put the `Stack` elements in a container that is sized from the biggest SVG 2025-11-04 ✅ 2025-11-04
- [x] Remove the numbers from the `axeFrame` 2025-11-04 ✅ 2025-11-04
- [x] Fix the system status code in the controller. 2025-11-04 ✅ 2025-11-04
- [x] Add fireplace latch pin code 2025-11-04 ✅ 2025-11-04
- [x] Get bird RFID reader working 2025-11-04 ✅ 2025-11-05
- [x] Add chest latch opener code 2025-11-05 ✅ 2025-11-05
- [x] Break the messages to/from the prop controllers into a separate library 2025-09-28 ✅ 2025-09-28
- [x] Switch to using `MessagePacker` cr for message transmission 2025-09-28 ✅ 2025-09-28
- [x] Just add the message format header 2025-09-28 ✅ 2025-09-28
- [x] Test the new `odin_axe` code 2025-09-28 ✅ 2025-09-28
- [x] Merge changes back into `rust_prop_quickstart` 2025-09-28 ✅ 2025-09-28
- [x] Add `odin_prop` to `odin_ctrl` 2025-09-28 ✅ 2025-10-03
- [x] Create `AxePuzzle` object and hold onto the handle in the `Server` object 2025-09-28 ✅ 2025-10-03
- [x] Create a new new Flutter app for control 2025-04-21 ✅ 2025-10-03
- [x] Add `dummy` state into `odin_prop` to support `rust_prop_quickstart` 2025-09-28 ✅ 2025-10-03
- [x] Add command to force full state to be sent to controller 2025-10-03 ✅ 2025-10-03
- [x] Send full state command when controller starts 2025-10-03 ✅ 2025-10-03
- [x] Request full state when the UI starts up or when the puzzle button is clicked on left 2025-10-03 ✅ 2025-10-04
- [x] Whiteboard the control software design 2024-11-26 ✅ 2025-04-25
- [x] Finish Sketch from a plan view of the room 2025-02-16 ✅ 2025-08-13
- [x] Configure static IP for `eg-1` on `rm-1.escapegallery.net` ✅ 2025-09-08
- [x] Configure DHCP & DNS via `dnsmasq` on `eg-1` 2025-08-06 ✅ 2025-09-08
- [x] Configure wired connection for `odin-axe` 2025-08-13 ✅ 2025-09-08
- [x] Configure `/etc/hosts` on `eg-1` to add `eg-1.rm-1.escapegallery.net` 2025-09-08 ✅ 2025-09-09
- [x] Ensure that we can `ssh` over the `10.10.0.0/24` network 2025-09-08 ✅ 2025-09-09
- [x] Configure `nftables` for the `rm-1` network to NAT packets 2025-09-08 ✅ 2025-09-09
- [x] Temporarily take down `odin-axe` WiFi and check that updates work 2025-09-09 ✅ 2025-09-09
- [x] Set timeouts for DHCP on `odin-axe` and reboot 2025-09-09 ✅ 2025-09-09
- [x] Disable the WiFi permanently on RPi for `odin-axe` and test reboot 2025-09-08 ✅ 2025-09-09
- [x] Add `env_logger` to `odin_axe` and remove existing logger 2025-09-11 ✅ 2025-09-11
- [x] Add a command line to indicated the name of the NATS server 2025-09-11 ✅ 2025-09-11
- [x] Add Ctrl+C handling 2025-09-11 ✅ 2025-09-12
- [x] Add a `select` loop that listens on a `flume` channel for messages from the monitor thread 2025-09-11 ✅ 2025-09-12
- [x] Add the thread to monitor the state of the readers 2025-09-11 ✅ 2025-09-12
- [x] Add `flume` and send a message when axe state changes to main loop 2025-09-11 ✅ 2025-09-12
- [x] Remove the checks for correctness just record the UID from the RFID chips 2025-09-11 ✅ 2025-09-12
- [x] Add `serde` and `serde_json` to the project 2025-09-11 ✅ 2025-09-12
- [x] Kill the GPIO thread when Ctrl+C is hit 2025-09-12 ✅ 2025-09-12
- [x] Add a `HashMap<String, Value>` to track prop state 2025-09-11 ✅ 2025-09-12
- [x] If the value has change, update the `HashMap` 2025-09-12 ✅ 2025-09-12
- [x] Publish nats message when state changes 2025-09-12 ✅ 2025-09-12
- [x] Run setup scripts on `odin-throne` and `odin-feast` 2025-09-13 ✅ 2025-09-13
- [x] Reverse `odin-throne` and `odin-feast` host names 2025-09-13 ✅ 2025-09-13
- [x] Add `odin` account to `/etc/nats-server.conf` on `eg-1` 2025-09-13 ✅ 2025-09-13
- [x] Install and configure [`lld` linker and test](https://users.rust-lang.org/t/linking-taking-an-inordinately-long-time/39253/4) 2025-09-13 ✅ 2025-09-14
- [x] Fix `odin-drum` ethernet connection 2025-09-15 ✅ 2025-09-19
- [x] Set up quick-start to cross compile on mac and then copy to specific machine using `Justfile` 2025-09-13 ✅ 2025-09-19
- [x] Put new SD card in `odin-ship` 2025-09-15 ✅ 2025-09-25
- [x] Configure SD card in `odin-ship` 2025-09-25 ✅ 2025-09-25
- [x] Take `odin-ship` off of WiFi 2025-09-25 ✅ 2025-09-26
- [x] Create a service file template for prop controllers 2025-09-13 ✅ 2025-09-26
- [x] Make `cmd` messages set the `prop` state and publish 2025-09-13 ✅ 2025-09-26
- [x] Update the `HashMap` when the state of the axes changes 2025-09-11 ✅ 2025-09-26
- [x] Create script to turrn off WiFi for a prop controller 2025-09-08 ✅ 2025-09-26
- [x] Refactor code to put stuff into `self` methods 2025-09-26 ✅ 2025-09-26
- [x] Ensure prop servers output version number when starting 2025-09-25 ✅ 2025-09-26
- [x] Increment patch number when doing deployments 2025-09-25 ✅ 2025-09-26
- [x] Write out name of controller from the `clap` information as first log message 2025-09-13 ✅ 2025-09-26
- [x] Add code to reset the latch after configurable amount of time (1 sec default) 2025-09-26 ✅ 2025-09-26
- [x] Debug why the `single_instance` code is not working! 2025-09-25 ✅ 2025-09-26
- [x] Merge common changes into `rust_prop_quickstart` 2025-09-26 ✅ 2025-09-26
- [x] Create the `odin-ctrl` project 2025-09-14 ✅ 2025-09-27
- [x] Install `odin-ctrl` on `eg-1` and setup to build it there 2025-09-14 ✅ 2025-09-27
- [x] `odin-axe` ✅ 2025-10-05
- [x] Fix `dnsmasq` issue on `eg-1` 2025-10-05 ✅ 2025-10-05
- [x] Install [Caddy]() on `eg-1` 2025-10-05 ✅ 2025-10-05
- [x] Create feast room lighting page 2025-10-05 ✅ 2025-10-23
- [x] Take `odin-av` off of WiFi 2025-09-15 ✅ 2025-10-23
- [x] Test that `rust-analyzer` in VS Code works with just the `settings.json` value set 2025-10-23 ✅ 2025-10-23
- [x] Remove all `config.toml` files 2025-10-23 ✅ 2025-10-23
- [x] Set `RUSTFLAGS` environment variable for builds in the Justfile and test 2025-10-23 ✅ 2025-10-23
- [x] Fix prop control install scripts 2025-10-23 ✅ 2025-10-23
- [x] Move `odin-ctrl` install and deploy scripts to `Justfile` 2025-10-23 ✅ 2025-10-23
- [x] Ensure all prop controllers send actual state after initialization 2025-10-19 ✅ 2025-10-23
- [x] Add icons for macOS and web 2025-10-19 ✅ 2025-10-24
- [x] Make sure each dashboard tab requests state when it loads 2025-10-23 ✅ 2025-10-24
- [x] Get `odin-axe` controller ping working end-to-end 2025-10-18 ✅ 2025-10-25
- [x] Send the system state on a timer from `odin-ctrl` instead of as it comes in 2025-10-25 ✅ 2025-10-25
- [x] Make prop controller status update time a config setting 2025-10-25 ✅ 2025-10-25
- [x] Add prop controller status for all other prop controllers 2025-10-24 ✅ 2025-10-26
- [x] Ensure `odin-ctrl` requests full state from all prop controllers 3 seconds after it starts 2025-10-18 ✅ 2025-10-26
- [x] Label the unused switch that now lights the table 2025-10-26 ✅ 2025-10-26
- [x] Put a `GridView` in the lighting tab 2025-10-26 ✅ 2025-10-29
- [x] Remove the arrays from the Lighting controller messages and use named fields 2025-10-29 ✅ 2025-10-30
- [x] Remove the chandelier solenoid out of the lighting tab 2025-10-20 ✅ 2025-10-30
- [x] Add unique nav bar icons for all the puzzles 2025-11-02 ✅ 2025-11-13
- [x] Create `AsyncAwaiter` widget centered [`flutter_spinkit`](https://pub.dev/packages/flutter_spinkit) spinner and message 2025-10-30 ✅ 2025-11-13
- [x] Position the drums 2025-11-13 ✅ 2025-11-13
- [x] Add code to drive tree lights in `odin_tree` 2025-11-06 ✅ 2025-11-13
- [x] Move code into the `odin_prop_util` from `odin_prop_msg` 2025-12-09 ✅ 2025-12-09
- [x] Fix the `Justfile` to label builds correctly 2025-12-09 ✅ 2025-12-09
- [x] Configure scripting on `odin-ctrl` 2025-12-09 ✅ 2025-12-09
- [x] Add code to receive commands from script and forward 2025-12-09 ✅ 2025-12-13
- [x] Update prop and game controllers 2025-12-13 ✅ 2025-12-13
- [x] Copy auto pilot code over from the simulator 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot UI in the app 2025-12-13 ✅ 2025-12-23
- [x] Get auto pilot triggering the axe puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the table puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the ship puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the bird puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the horse puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the bear puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the fish puzzle 2025-12-14 ✅ 2025-12-23
- [x] Get auto pilot triggering the fireplace 2025-12-14 ✅ 2025-12-23
- [x] Test EG room cameras 2025-07-06 ✅ 2025-12-23
- [x] Test EG speakers with `audio-forwarder` 2025-09-15 ✅ 2025-12-23
- [x] Test Memir speakers with `audio-forwarder` 2025-10-23 ✅ 2025-12-23
- [x] Test EG microphone with `audio-forwarder` 2025-09-15 ✅ 2025-12-23
- [x] Get crank count code working on `odin_right` 2025-11-05 ✅ 2025-12-23
- [x] Add the crank count to the fireplace UI 2025-10-31 ✅ 2025-12-23
- [x] Add `room_on` state to the `game.controller.state` message and set when all prop controllers are alive 2025-10-20 ✅ 2025-12-23
- [x] Update UI based on `room_on` state 2025-10-20 ✅ 2025-12-23
- [x] Re-install the knocker in the wall 2025-12-26 ✅ 2025-12-26
## Notes
Debug msgpack encoded messages on NATS using:
```sh
nats sub --translate 'mpk --to-json' prop.<prop-host>.state
```
You can also create a debug build of the the prop controller that uses [`to_vec_named`](https://docs.rs/rmp-serde/1.3.0/rmp_serde/encode/fn.to_vec_named.html) to add field names to the structure.
## References
![[odin_left_middle_right.png.jpeg]]
- [NATS](https://github.com/nats-io/nats.ws)
- [[Prop and Game Controller Raspberry Pi Configuration]]
- [Use Rhai for Scripting in Rust](https://crates.io/crates/rhai)
- [`msgpack-cli`](https://crates.io/crates/msgpack-cli)
- [Flutter Drawer](https://docs.flutter.dev/cookbook/design/drawer)
- [flutter_svg](https://pub.dev/packages/flutter_svg)
## System Ping
- The room is expected to be started in the following order - game controller then prop controllers and user interface.
- When a prop controller starts it will connect to the NATS server, and once successful will immediately send a system state message, updating the game controllers alive/dead state for that prop controller.
- The prop controller system state ping interval defaults to 60 seconds.
- The system service on the game controller will send a request for full state to all prop controllers when it starts. This is to handle situations where the room is running and the game controller needs to be restarted.
- The system service keeps a list of the last contact time for each of prop controllers. This time is updated each time a prop controller sends a system state message.
- Every 60 seconds (by default) the system service goes through the contact times and checks to see if the last contact time from any prop controller is greater than twice that, i.e. 120 seconds. If so it marks the prop controller as dead.
- The system server will only send out changes to the alive/dead status of systems if anything changes to avoid unnecessary network traffic.