feat(jmri): headless JMRI server with Leviton layout power monitor and X11 GUI mode

- Stable udev device symlinks (/dev/jmri/nce, /dev/jmri/loconet, /dev/jmri/lcc)
- jmri-monitor: polls Leviton Decora Smart switch to start/stop JMRI automatically
  - Quiet hours 1-10 AM (no polling)
  - 30s off-delay before shutdown
- LCRR config cloned from Gitea (ssh://gitea.mk-labs.cloud:2221/rblundon/LCRR.git)
- ~/.jmri symlinked to LCRR repo for GitOps config management
- jmri-gui: X11 remote GUI access (PanelPro/DecoderPro) via ssh -X as jmri user
  - Stops daemon, launches GUI, restarts daemon on exit if layout still on
- jmri user gets login shell + SSH key for GUI sessions
- Full JRE installed (openjdk-21-jre) for AWT/X11 support
This commit is contained in:
Hermes Agent service account
2026-07-29 00:43:23 -05:00
parent a5433dcb5b
commit d974c75d7c
26 changed files with 2460 additions and 459 deletions

View File

@@ -9,17 +9,45 @@ jmri_user: jmri
jmri_group: jmri
jmri_home: /home/jmri
# Profile — override per-host in inventory
# Find on the old box: ls ~/.jmri/profiles/
# Profile — set per-host in host_vars
jmri_profile_id: ""
# Config restore source (path to the backed-up .jmri directory)
# LCRR git repo (set per-host in host_vars; leave blank to skip clone)
jmri_lcrr_repo: ""
# SSH key for jmri user (for jmri-gui X11 access — set per-host in host_vars)
jmri_ssh_authorized_key: ""
# SSH key for jmri user → Gitea
jmri_gitea_key: /home/jmri/.ssh/id_ed25519_gitea
# Config restore source (legacy tar-based restore — leave blank to skip)
jmri_config_src: ""
# Ports (for documentation / firewall rules)
jmri_json_port: 12080
jmri_withrottle_port: 12090
# USB serial device for NCE (set per-host in inventory)
# e.g. /dev/ttyUSB0 or /dev/ttyACM0
jmri_serial_device: /dev/ttyUSB0
# ---------------------------------------------------------------------------
# Phase 2 — Layout power monitor (Leviton Decora Smart Wi-Fi)
# ---------------------------------------------------------------------------
jmri_leviton_email: "" # set via group_vars (vault-backed)
jmri_leviton_password: "" # set via group_vars (vault-backed)
jmri_leviton_switch_name: "Layout"
jmri_monitor_poll_interval: 30 # seconds between polls (active hours)
jmri_monitor_quiet_start: 1 # hour (24h) to stop polling
jmri_monitor_quiet_end: 10 # hour (24h) to resume polling
jmri_monitor_stop_delay: 30 # seconds of OFF state before stopping JMRI
# ---------------------------------------------------------------------------
# USB device identification (ENV{ID_SERIAL} from udev — the segment of the
# by-id symlink name before the -ifNN suffix)
# ---------------------------------------------------------------------------
# LocoBuffer-NG (LocoNet bridge) → /dev/jmri/loconet
jmri_dev_loconet_serial: "RR-CirKits_LocoBuffer-NG_CDC_ACM_SERIAL_DEVICE_AA5700218A"
# NCE command station → /dev/jmri/nce ← triggers service start/stop
jmri_dev_nce_serial: "Microchip_Technology_Inc._Simple_CDC_Device_Demo"
# FTDI LCC interface → /dev/jmri/lcc
jmri_dev_lcc_serial: "ftdi_usb_serial_converter_ftDYQHZX"