diff --git a/intercept_agent.py b/intercept_agent.py index dc7564d..beabeaf 100644 --- a/intercept_agent.py +++ b/intercept_agent.py @@ -970,6 +970,43 @@ class ModeManager: # Clear DSC data if hasattr(self, 'dsc_messages'): self.dsc_messages = [] + elif mode == 'pager': + # Pager uses two processes: multimon-ng (pager) and rtl_fm (pager_rtl) + # Kill the rtl_fm process as well + if 'pager_rtl' in self.processes: + rtl_proc = self.processes['pager_rtl'] + if rtl_proc and rtl_proc.poll() is None: + rtl_proc.terminate() + try: + rtl_proc.wait(timeout=3) + except subprocess.TimeoutExpired: + rtl_proc.kill() + del self.processes['pager_rtl'] + # Clear pager data + if hasattr(self, 'pager_messages'): + self.pager_messages = [] + elif mode == 'aprs': + # APRS uses two processes: decoder (aprs) and rtl_fm (aprs_rtl) + if 'aprs_rtl' in self.processes: + rtl_proc = self.processes['aprs_rtl'] + if rtl_proc and rtl_proc.poll() is None: + rtl_proc.terminate() + try: + rtl_proc.wait(timeout=3) + except subprocess.TimeoutExpired: + rtl_proc.kill() + del self.processes['aprs_rtl'] + elif mode == 'rtlamr': + # RTLAMR uses two processes: rtlamr and rtl_tcp (rtlamr_tcp) + if 'rtlamr_tcp' in self.processes: + tcp_proc = self.processes['rtlamr_tcp'] + if tcp_proc and tcp_proc.poll() is None: + tcp_proc.terminate() + try: + tcp_proc.wait(timeout=3) + except subprocess.TimeoutExpired: + tcp_proc.kill() + del self.processes['rtlamr_tcp'] return {'status': 'stopped', 'mode': mode} diff --git a/static/js/core/agents.js b/static/js/core/agents.js index 37789e7..5c073aa 100644 --- a/static/js/core/agents.js +++ b/static/js/core/agents.js @@ -329,6 +329,8 @@ function selectAgent(agentId) { if (typeof refreshTscmDevices === 'function') { refreshTscmDevices(); } + // Sync mode UI to local status (reset modes that aren't running locally) + syncLocalModeStates(); // Notify WiFi mode of agent change if (typeof WiFiMode !== 'undefined' && WiFiMode.handleAgentChange) { WiFiMode.handleAgentChange(); @@ -413,6 +415,45 @@ async function syncAgentModeStates(agentId) { } } +/** + * Sync UI state with local mode statuses. + * Called when switching back to local to ensure UI reflects local state. + */ +async function syncLocalModeStates() { + console.log('[AgentManager] Syncing local mode states...'); + + // Check each mode's local status endpoint + const modeChecks = [ + { mode: 'pager', endpoint: '/status', runningKey: 'running' }, + { mode: 'sensor', endpoint: '/sensor/status', runningKey: 'running' }, + { mode: 'adsb', endpoint: '/adsb/status', runningKey: 'running' }, + { mode: 'tscm', endpoint: '/tscm/status', runningKey: 'running' }, + ]; + + for (const check of modeChecks) { + try { + const response = await fetch(check.endpoint); + if (response.ok) { + const data = await response.json(); + const isRunning = data[check.runningKey] || false; + syncModeUI(check.mode, isRunning, null); + } else { + // Endpoint not available or error - assume not running + syncModeUI(check.mode, false, null); + } + } catch (error) { + // Network error or endpoint doesn't exist - assume not running + syncModeUI(check.mode, false, null); + } + } + + // Clear agent mode warnings when switching to local + const warning = document.getElementById('agentModeWarning'); + if (warning) { + warning.style.display = 'none'; + } +} + /** * Show warnings about running modes that may cause conflicts. * @param {string[]} runningModes - List of running mode names diff --git a/templates/index.html b/templates/index.html index 3fe1508..3ad86e0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -2092,16 +2092,28 @@ // Mode switching function switchMode(mode) { - // Stop any running scans when switching modes - if (isRunning) stopDecoding(); - if (isSensorRunning) stopSensorDecoding(); - if (isWifiRunning) stopWifiScan(); - if (isBtRunning) stopBtScan(); - if (isAprsRunning) stopAprs(); - if (isTscmRunning) stopTscmSweep(); + // Only stop local scans if in local mode (not agent mode) + const isAgentMode = typeof currentAgent !== 'undefined' && currentAgent !== 'local'; + if (!isAgentMode) { + if (isRunning) stopDecoding(); + if (isSensorRunning) stopSensorDecoding(); + if (isWifiRunning) stopWifiScan(); + if (isBtRunning) stopBtScan(); + if (isAprsRunning) stopAprs(); + if (isTscmRunning) stopTscmSweep(); + } currentMode = mode; + // Sync mode state with current agent/local after switching + if (isAgentMode && typeof syncAgentModeStates === 'function') { + // Re-sync with agent to update this mode's UI state + syncAgentModeStates(currentAgent); + } else if (!isAgentMode && typeof syncLocalModeStates === 'function') { + // Sync with local status + syncLocalModeStates(); + } + // Close dropdowns and update active state closeAllDropdowns(); updateDropdownActiveState();