#!/bin/bash # jmri-gui — launch JMRI GUI on VNC virtual display # Managed by Ansible — do not edit manually. # # Usage (connect as jmri user): # ssh jmri@main-street-station jmri-gui panelpro # ssh jmri@main-street-station jmri-gui decoderpro # ssh jmri@main-street-station jmri-gui status # # Then connect a VNC client to main-street-station.local.mk-labs.cloud:5901 # VNC password is in the Ansible vault (vault_jmri_vnc_password) set -euo pipefail JMRI_DIR="{{ jmri_install_dir }}" JMRI_SERVICE="jmri.service" MONITOR_SERVICE="jmri-monitor.service" VNC_SERVICE="jmri-vnc.service" DISPLAY=":{{ jmri_vnc_display }}" export DISPLAY usage() { echo "Usage: jmri-gui " exit 1 } status() { echo "=== JMRI daemon ===" systemctl status "$JMRI_SERVICE" --no-pager -l 2>&1 | head -8 echo "" echo "=== VNC server ===" systemctl status "$VNC_SERVICE" --no-pager -l 2>&1 | head -5 echo "" echo "=== Layout monitor ===" systemctl status "$MONITOR_SERVICE" --no-pager -l 2>&1 | head -5 echo "" echo "Connect VNC client to: $(hostname -f):{{ jmri_vnc_port }}" } launch() { local app="$1" local binary case "$app" in panelpro) binary="PanelPro" ;; decoderpro) binary="DecoderPro" ;; *) usage ;; esac # Ensure VNC server is running if ! systemctl is-active --quiet "$VNC_SERVICE" 2>/dev/null; then echo "Starting VNC server..." sudo systemctl start "$VNC_SERVICE" sleep 2 fi # Stop the JMRI daemon if running if systemctl is-active --quiet "$JMRI_SERVICE" 2>/dev/null; then echo "Stopping JMRI daemon..." sudo systemctl stop "$JMRI_SERVICE" fi echo "Launching $binary on VNC display $DISPLAY..." echo "Connect your VNC client to: $(hostname -f):{{ jmri_vnc_port }}" echo "VNC password: see Ansible vault (vault_jmri_vnc_password)" echo "" # Force AWT out of headless mode export JMRI_OPTIONS="-Djava.awt.headless=false" # Launch on the VNC display — no --profile so JMRI uses last-session preference "$JMRI_DIR/$binary" & echo "$binary launched in background on VNC display." echo "Close it from the VNC client, then run 'jmri-gui status' to check state." echo "" # Restart daemon if layout switch is still on if systemctl is-active --quiet "$MONITOR_SERVICE" 2>/dev/null; then if sudo /opt/jmri-monitor/bin/python3 - <<'EOF' from decora_wifi import DecoraWiFiSession from decora_wifi.models.residential_account import ResidentialAccount import sys session = DecoraWiFiSession() person = session.login("{{ jmri_leviton_email }}", "{{ jmri_leviton_password }}") perms = person.get_residential_permissions() for perm in perms: acct_id = perm.data.get('residentialAccountId') if not acct_id: continue acct = ResidentialAccount(session, acct_id) acct.refresh() for r in acct.get_residences(): for s in r.get_iot_switches(): if s.data.get('name') == '{{ jmri_leviton_switch_name }}': sys.exit(0 if s.data.get('power') == 'ON' else 1) sys.exit(1) EOF then echo "Layout is ON — JMRI daemon will restart when GUI is closed." else echo "Layout is OFF — JMRI daemon will not restart." fi fi } case "${1:-}" in panelpro|decoderpro) launch "$1" ;; status) status ;; *) usage ;; esac