Fix ADS-B and VDL2 stop button handling

This commit is contained in:
Smittix
2026-02-25 10:05:16 +00:00
parent c4bde6c707
commit 2c76039f2c
3 changed files with 120 additions and 54 deletions

View File

@@ -685,7 +685,7 @@ def start_adsb():
'session': session 'session': session
}), 409 }), 409
data = request.json or {} data = request.get_json(silent=True) or {}
start_source = data.get('source') start_source = data.get('source')
started_by = request.remote_addr started_by = request.remote_addr
@@ -899,7 +899,7 @@ def start_adsb():
def stop_adsb(): def stop_adsb():
"""Stop ADS-B tracking.""" """Stop ADS-B tracking."""
global adsb_using_service, adsb_active_device global adsb_using_service, adsb_active_device
data = request.json or {} data = request.get_json(silent=True) or {}
stop_source = data.get('source') stop_source = data.get('source')
stopped_by = request.remote_addr stopped_by = request.remote_addr

View File

@@ -2214,21 +2214,44 @@ sudo make install</code>
} }
} else { } else {
try { try {
// Route stop through agent proxy if using remote agent // Route stop through the source that actually started tracking.
const url = useAgent const stopSource = adsbTrackingSource || (useAgent ? adsbCurrentAgent : 'local');
? `/controller/agents/${adsbCurrentAgent}/adsb/stop` const stopViaAgent = stopSource !== null && stopSource !== undefined && stopSource !== 'local';
const url = stopViaAgent
? `/controller/agents/${stopSource}/adsb/stop`
: '/adsb/stop'; : '/adsb/stop';
await fetch(url, { const response = await fetch(url, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}) body: JSON.stringify({ source: 'adsb_dashboard' })
}); });
const text = await response.text();
let data = {};
if (text) {
try {
data = JSON.parse(text);
} catch (e) {
throw new Error(`Invalid response: ${text}`);
}
}
const result = stopViaAgent && data.result ? data.result : data;
const stopped = response.ok && (
result.status === 'stopped' ||
result.status === 'success' ||
data.status === 'success'
);
if (!stopped) {
throw new Error(result.message || data.message || `HTTP ${response.status}`);
}
// Update agent running modes tracking // Update agent running modes tracking
if (useAgent && typeof agentRunningModes !== 'undefined') { if (stopViaAgent && typeof agentRunningModes !== 'undefined') {
agentRunningModes = agentRunningModes.filter(m => m !== 'adsb'); agentRunningModes = agentRunningModes.filter(m => m !== 'adsb');
} }
} catch (err) {} } catch (err) {
alert('Failed to stop ADS-B: ' + err.message);
return;
}
stopEventStream(); stopEventStream();
isTracking = false; isTracking = false;
@@ -2381,16 +2404,17 @@ sudo make install</code>
function startEventStream() { function startEventStream() {
if (eventSource) eventSource.close(); if (eventSource) eventSource.close();
const useAgent = typeof adsbCurrentAgent !== 'undefined' && adsbCurrentAgent !== 'local'; const activeSource = (isTracking && adsbTrackingSource) ? adsbTrackingSource : adsbCurrentAgent;
const useAgent = typeof activeSource !== 'undefined' && activeSource !== null && activeSource !== 'local';
const streamUrl = useAgent ? '/controller/stream/all' : '/adsb/stream'; const streamUrl = useAgent ? '/controller/stream/all' : '/adsb/stream';
console.log(`[ADS-B] startEventStream called - adsbCurrentAgent=${adsbCurrentAgent}, useAgent=${useAgent}, streamUrl=${streamUrl}`); console.log(`[ADS-B] startEventStream called - activeSource=${activeSource}, useAgent=${useAgent}, streamUrl=${streamUrl}`);
eventSource = new EventSource(streamUrl); eventSource = new EventSource(streamUrl);
// Get agent name for filtering multi-agent stream // Get agent name for filtering multi-agent stream
let targetAgentName = null; let targetAgentName = null;
if (useAgent && typeof agents !== 'undefined') { if (useAgent && typeof agents !== 'undefined') {
const agent = agents.find(a => a.id == adsbCurrentAgent); const agent = agents.find(a => a.id == activeSource);
targetAgentName = agent ? agent.name : null; targetAgentName = agent ? agent.name : null;
} }
@@ -4023,30 +4047,56 @@ sudo make install</code>
.catch(err => alert('VDL2 Error: ' + err)); .catch(err => alert('VDL2 Error: ' + err));
} }
function stopVdl2() { async function stopVdl2() {
const isAgentMode = vdl2CurrentAgent !== null; const sourceAgentId = vdl2CurrentAgent;
const isAgentMode = sourceAgentId !== null && sourceAgentId !== undefined;
const endpoint = isAgentMode const endpoint = isAgentMode
? `/controller/agents/${vdl2CurrentAgent}/vdl2/stop` ? `/controller/agents/${sourceAgentId}/vdl2/stop`
: '/vdl2/stop'; : '/vdl2/stop';
fetch(endpoint, { method: 'POST' }) try {
.then(r => r.json()) const response = await fetch(endpoint, {
.then(() => { method: 'POST',
isVdl2Running = false; headers: { 'Content-Type': 'application/json' },
vdl2CurrentAgent = null; body: JSON.stringify({ source: 'adsb_dashboard' })
document.getElementById('vdl2ToggleBtn').innerHTML = '&#9654; START VDL2';
document.getElementById('vdl2ToggleBtn').classList.remove('active');
document.getElementById('vdl2PanelIndicator').classList.remove('active');
if (vdl2EventSource) {
vdl2EventSource.close();
vdl2EventSource = null;
}
// Clear polling timer
if (vdl2PollTimer) {
clearInterval(vdl2PollTimer);
vdl2PollTimer = null;
}
}); });
const text = await response.text();
let data = {};
if (text) {
try {
data = JSON.parse(text);
} catch (e) {
throw new Error(`Invalid response: ${text}`);
}
}
const result = isAgentMode && data.result ? data.result : data;
const stopped = response.ok && (
result.status === 'stopped' ||
result.status === 'success' ||
data.status === 'success'
);
if (!stopped) {
throw new Error(result.message || data.message || `HTTP ${response.status}`);
}
isVdl2Running = false;
vdl2CurrentAgent = null;
document.getElementById('vdl2ToggleBtn').innerHTML = '&#9654; START VDL2';
document.getElementById('vdl2ToggleBtn').classList.remove('active');
document.getElementById('vdl2PanelIndicator').classList.remove('active');
if (vdl2EventSource) {
vdl2EventSource.close();
vdl2EventSource = null;
}
// Clear polling timer
if (vdl2PollTimer) {
clearInterval(vdl2PollTimer);
vdl2PollTimer = null;
}
} catch (err) {
alert('Failed to stop VDL2: ' + err.message);
}
} }
// Sync VDL2 UI state (called by syncModeUI in agents.js) // Sync VDL2 UI state (called by syncModeUI in agents.js)
@@ -4064,6 +4114,7 @@ sudo make install</code>
startVdl2Stream(agentId !== null); startVdl2Stream(agentId !== null);
} }
} else { } else {
vdl2CurrentAgent = null;
btn.innerHTML = '&#9654; START VDL2'; btn.innerHTML = '&#9654; START VDL2';
btn.classList.remove('active'); btn.classList.remove('active');
if (indicator) indicator.classList.remove('active'); if (indicator) indicator.classList.remove('active');
@@ -5216,24 +5267,27 @@ sudo make install</code>
if (running) { if (running) {
isTracking = true; isTracking = true;
const normalizedSource = source === null || source === undefined
? (adsbTrackingSource || 'local')
: source;
// If source is an agent ID (not 'local' and not null), update adsbCurrentAgent // If source is an agent ID (not 'local' and not null), update adsbCurrentAgent
// This ensures startEventStream uses the correct routing // This ensures startEventStream uses the correct routing
if (source && source !== 'local') { if (normalizedSource !== 'local') {
adsbCurrentAgent = source; adsbCurrentAgent = normalizedSource;
// Also update the dropdown to match // Also update the dropdown to match
const agentSelect = document.getElementById('agentSelect'); const agentSelect = document.getElementById('agentSelect');
if (agentSelect) { if (agentSelect) {
agentSelect.value = source; agentSelect.value = normalizedSource;
} }
// Update global agent state too // Update global agent state too
if (typeof currentAgent !== 'undefined') { if (typeof currentAgent !== 'undefined') {
currentAgent = source; currentAgent = normalizedSource;
} }
console.log(`[ADS-B] Updated adsbCurrentAgent to ${source}`); console.log(`[ADS-B] Updated adsbCurrentAgent to ${normalizedSource}`);
} }
adsbTrackingSource = source || adsbCurrentAgent; // Track which source is active adsbTrackingSource = normalizedSource; // Track which source is active
// Update button // Update button
if (btn) { if (btn) {
@@ -5253,9 +5307,9 @@ sudo make install</code>
if (agentSelect) agentSelect.disabled = true; if (agentSelect) agentSelect.disabled = true;
// Start data stream for the active source // Start data stream for the active source
const isAgentSource = adsbCurrentAgent !== 'local'; const isAgentSource = normalizedSource !== 'local';
if (isAgentSource) { if (isAgentSource) {
console.log(`[ADS-B] Starting data stream from agent ${adsbCurrentAgent}`); console.log(`[ADS-B] Starting data stream from agent ${normalizedSource}`);
startEventStream(); startEventStream();
drawRangeRings(); drawRangeRings();
startSessionTimer(); startSessionTimer();

View File

@@ -170,8 +170,19 @@
} }
function stopVdl2Mode() { function stopVdl2Mode() {
fetch('/vdl2/stop', { method: 'POST' }) fetch('/vdl2/stop', {
.then(r => r.json()) method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ source: 'vdl2_mode' })
})
.then(async (r) => {
const text = await r.text();
const data = text ? JSON.parse(text) : {};
if (!r.ok || (data.status !== 'stopped' && data.status !== 'success')) {
throw new Error(data.message || `HTTP ${r.status}`);
}
return data;
})
.then(() => { .then(() => {
document.getElementById('startVdl2Btn').style.display = 'block'; document.getElementById('startVdl2Btn').style.display = 'block';
document.getElementById('stopVdl2Btn').style.display = 'none'; document.getElementById('stopVdl2Btn').style.display = 'none';
@@ -181,7 +192,8 @@
vdl2MainEventSource.close(); vdl2MainEventSource.close();
vdl2MainEventSource = null; vdl2MainEventSource = null;
} }
}); })
.catch(err => alert('Failed to stop VDL2: ' + err.message));
} }
function startVdl2MainSSE() { function startVdl2MainSSE() {