Operator hub - Introduce Escape Gallery branding and Glitch: the Dark Machine room views - Add cabinet illustrations, Pac-Man marquee/gameplay artwork, and waiting states - Add device feedback panels with RFID readings, input/output states, and stale status - Add logged operator hardware interventions with request deduplication Room and cabinet authoring - Add a visual custom-PCB connection editor with per-cabinet device inventory - Support device IDs, bindings, wiring notes, input polarity, and validation - Add physical-room label/dimension toggles and editable doorway annotations - Preserve doorway changes through undo, save, and revert - Expand cabinet profiles, room layout, and Glitch scenario resources Scenarios and gameplay - Add per-assignment game configuration and runtime feature validation - Add timed test wins and Frogger individual-home objectives - Add the three-cabinet timed/score/Frogger test scenario - Add Cabinet 1 Pac-Man RFID credits, credit sound, and CREDIT 0/1 display - Require physical Start after an accepted scan and prevent duplicate credits Pi hardware and deployment - Add GPIO feedback sampling and a separate multiplexed RFID helper - Validate reader pin ownership and input/output conflicts - Add SSH cabinet startup and Pi desktop-session service support - Add master packaging, site setup, SSH enrollment, and staged cabinet releases - Verify deployment manifests and support explicit activation/status/log commands Documentation and verification - Consolidate the root README around the current architecture and setup workflow - Add the complete master/Pi/RFID export and deployment walkthrough - Document network isolation, credentials, card identification, and rollback - Add PCB, room-editor, feedback, credit, deployment, and controller tests - Isolate protocol tests from designer-edited cabinet configurations Known limitations - RFID helper compilation and physical Pi commissioning remain unverified - Fleet provisioning does not yet configure RFID-only installations completely - Broader Pac-Man tests retain a ghost-capture assertion failure - Staged exports must be rebuilt and checked before deploying runtime 2.3
119 lines
7.2 KiB
Markdown
119 lines
7.2 KiB
Markdown
# Start the Pi cabinets from the controller PC
|
|
|
|
After one-time setup, your usual command starts the Windows controller, opens the browser, and asks each configured Pi to start its cabinet service:
|
|
|
|
```powershell
|
|
.\Start-Arcade.ps1 -Mode controller -Browser
|
|
```
|
|
|
|
The Pi service runs the existing cabinet launcher, which starts its GPIO bridge when enabled and then the managed game. SSH disconnects after the start request; the service stays running on the Pi. Already-running services are not restarted. Starting the apps does not automatically prepare or start a scenario; continue doing that in the operator.
|
|
|
|
The Pis must be powered on, reachable, and logged into their graphical desktop. This is remote application startup, not remote power-on. Desktop autologin is useful for cabinets; configure it on each Pi if desired.
|
|
|
|
## 1. Install the cabinet service on each Pi
|
|
|
|
Copy the updated `tools/launch/` scripts to the Pi's deployment folder. Stop the manually running cabinet launcher with Ctrl+C first so it releases the GPIO bridge port.
|
|
|
|
From a terminal **on the Pi desktop**, as the normal account that runs the game (without sudo):
|
|
|
|
```sh
|
|
python3 tools/launch/pi_service.py install --config tools/launch/launcher.ini
|
|
```
|
|
|
|
Use your actual INI filename, such as `launcher-pi.ini`, if different. It must contain that Pi's executable path, cabinet ID, controller URL/token (or blank URL/token to use its existing Godot CFG), and GPIO settings. The installer records the absolute config path; rerun it if the deployment/config moves.
|
|
|
|
This creates:
|
|
|
|
- `~/.config/systemd/user/arcade-cabinet.service`: runs your existing managed launcher as the desktop user.
|
|
- `~/.config/autostart/arcade-cabinet-display.desktop`: refreshes display settings at each desktop login, without launching the game.
|
|
- A temporary display environment file under the user's runtime directory, refreshed immediately during installation.
|
|
|
|
The installer does not start the game, enable boot startup, configure SSH, or change OS autologin. It captures only display-related variables, not application tokens. The service clears inherited `ARCADE_*` credential/URL overrides, so keep its intended settings in the configured INI or Godot CFG rather than relying on a terminal's environment.
|
|
|
|
Test locally:
|
|
|
|
```sh
|
|
systemctl --user start arcade-cabinet.service
|
|
systemctl --user status arcade-cabinet.service
|
|
```
|
|
|
|
Confirm the game appears on the cabinet monitor and becomes ONLINE. To stop it:
|
|
|
|
```sh
|
|
systemctl --user stop arcade-cabinet.service
|
|
```
|
|
|
|
If display settings change, run `python3 tools/launch/pi_service.py refresh-session` from the current Pi desktop terminal before starting it again.
|
|
|
|
## 2. Set up SSH access from Windows
|
|
|
|
SSH must be enabled on each Pi. Use the same SSH username as the desktop account where you installed the service.
|
|
|
|
These are **SSH keys**, separate from the 16-character application tokens in the cabinet setup guide. The tokens cannot authenticate SSH.
|
|
|
|
Generate a dedicated key on the PC (do not overwrite an existing one):
|
|
|
|
```powershell
|
|
ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\arcade_cabinets" -C "arcade-controller"
|
|
```
|
|
|
|
If you use a passphrase, load the key into your SSH agent before launching the room. Automated startup uses batch mode and cannot ask for passwords or passphrases.
|
|
|
|
For each Pi, first connect interactively and verify its host fingerprint before trusting it:
|
|
|
|
```powershell
|
|
ssh PI_USER@PI_HOST
|
|
```
|
|
|
|
Log out with `exit`. To authorize the public key on that Pi, run from PowerShell (substitute its real user and host):
|
|
|
|
```powershell
|
|
Get-Content "$env:USERPROFILE\.ssh\arcade_cabinets.pub" | ssh PI_USER@PI_HOST 'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'
|
|
```
|
|
|
|
Only copy the `.pub` key; the private key stays on the PC. Test unattended access:
|
|
|
|
```powershell
|
|
ssh -i "$env:USERPROFILE\.ssh\arcade_cabinets" -o BatchMode=yes -o StrictHostKeyChecking=yes PI_USER@PI_HOST "systemctl --user status arcade-cabinet.service"
|
|
```
|
|
|
|
An inactive service may return a nonzero status; confirm SSH succeeded and systemd found the installed unit. The launcher keeps host-key checking enabled and never automatically accepts a new or changed host key.
|
|
|
|
## 3. Add the Pi list to the PC launcher INI
|
|
|
|
Merge this into the controller INI you actually launch with. Replace each host and username:
|
|
|
|
```ini
|
|
[remote]
|
|
enabled = true
|
|
cabinets = [{"id":"cabinet_01","host":"PI_1_HOST","user":"PI_USER","identity_file":"~/.ssh/arcade_cabinets"},{"id":"cabinet_02","host":"PI_2_HOST","user":"PI_USER","identity_file":"~/.ssh/arcade_cabinets"},{"id":"cabinet_03","host":"PI_3_HOST","user":"PI_USER","identity_file":"~/.ssh/arcade_cabinets"}]
|
|
```
|
|
|
|
`identity_file` is optional if your default SSH identity or agent is already configured. `port` is optional and defaults to 22. Each ID must exist in the controller catalog and its cabinet-token map. The Pi's own launcher must use the same cabinet ID; this list does not remotely rewrite its identity or credentials.
|
|
|
|
Validate, then launch:
|
|
|
|
```powershell
|
|
.\Start-Arcade.ps1 -Mode controller -Check
|
|
.\Start-Arcade.ps1 -Mode controller -Browser
|
|
```
|
|
|
|
Use `-Config tools/launch/launcher-pc.ini` if that is your actual config filename. `-Check` validates local settings only; it does not contact or start a Pi.
|
|
|
|
The controller starts first. The launcher sends the SSH requests concurrently, then checks controller heartbeats. It prints separate **SSH OK/FAILED** and **ONLINE/OFFLINE** results, so a successful service command is not mistaken for a working game connection. A failed/offline Pi leaves the controller running for troubleshooting.
|
|
|
|
## Operating behavior
|
|
|
|
- Starting the controller again leaves active Pi services running; it does not interrupt their games with `restart`.
|
|
- Closing the browser or stopping the PC controller leaves the Pi services running. They reconnect when the controller returns.
|
|
- Closing the Pi game with Escape stops that Pi's launcher/bridge. It will not restart automatically; the next controller launch can start it again.
|
|
- A crash is not automatically restarted, avoiding unexpected game resets during a room session.
|
|
- Use `ssh PI_USER@PI_HOST "systemctl --user stop arcade-cabinet.service"` for an intentional remote stop.
|
|
- Application logs remain in the Pi launcher's configured log folder. Service startup errors are available through `journalctl --user -u arcade-cabinet.service -n 60 --no-pager`.
|
|
- If the PC launches before the Pi desktop is ready, startup can fail. Wait for desktop login and launch the controller again, or issue the same `systemctl --user start` command over SSH. There is no automatic power-on or infinite retry loop.
|
|
- After a desktop restart/logout, confirm the display helper has run before starting games. If your desktop does not honor XDG autostart entries, run `pi_service.py refresh-session` locally and check the desktop's startup configuration.
|
|
|
|
The service can be removed by stopping it, removing the two managed files listed above, and running `systemctl --user daemon-reload`. Game resources, saved control mappings, tokens, and GPIO ledger are unaffected.
|
|
|
|
Implementation references: [OpenSSH client configuration](https://man.openbsd.org/ssh_config), [systemd execution environment](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html), and [systemd desktop integration](https://github.com/systemd/systemd/blob/main/docs/DESKTOP_ENVIRONMENTS.md).
|