fix: release SDR device when switching modes across pages

When navigating from another mode (e.g. pager) to the ADS-B dashboard,
the old process could still hold the USB device. Two fixes:

1. routes/adsb.py: If dump1090 starts but SBS port never comes up,
   kill the process and return a DEVICE_BUSY error instead of silently
   claiming success with no data.

2. templates/adsb_dashboard.html: Pre-flight conflict check in
   toggleTracking() queries /devices/status and auto-stops any
   conflicting mode before starting ADS-B, with a 1.5s USB release
   delay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-03-02 22:21:30 +00:00
parent eea44f9a6b
commit 4b64862eb4
2 changed files with 82 additions and 0 deletions

View File

@@ -2172,6 +2172,58 @@ sudo make install</code>
const [adsbSdrType, adsbDeviceIdx] = adsbSelectVal.includes(':') ? adsbSelectVal.split(':') : ['rtlsdr', adsbSelectVal];
const adsbDevice = parseInt(adsbDeviceIdx) || 0;
// Pre-flight: check if another mode is using this device and auto-stop it
if (!useAgent) {
try {
const devResp = await fetch('/devices/status');
if (devResp.ok) {
const devices = await devResp.json();
const target = devices.find(d => d.sdr_type === adsbSdrType && d.index === adsbDevice);
if (target && target.in_use && target.used_by && target.used_by !== 'adsb') {
const stopEndpoints = {
pager: '/stop',
sensor: '/stop_sensor',
morse: '/morse/stop',
adsb: '/adsb/stop',
acars: '/acars/stop',
vdl2: '/vdl2/stop',
ais: '/ais/stop',
dsc: '/dsc/stop',
weathersat: '/weather-sat/stop',
sstv: '/sstv/stop',
radiosonde: '/radiosonde/stop',
rtlamr: '/rtlamr/stop_rtlamr',
aprs: '/aprs/stop',
tscm: '/tscm/sweep/stop',
wefax: '/wefax/stop',
sstv_general: '/sstv-general/stop',
};
const mode = target.used_by;
const stopUrl = stopEndpoints[mode];
if (stopUrl) {
console.log(`Device ${adsbSdrType}:${adsbDevice} in use by ${mode}, stopping...`);
btn.textContent = `Stopping ${mode}...`;
btn.disabled = true;
try {
await fetch(stopUrl, { method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ source: 'adsb_conflict' })
});
} catch (e) {
console.warn(`Failed to stop ${mode}:`, e);
}
// Wait for USB device to be released
await new Promise(resolve => setTimeout(resolve, 1500));
btn.textContent = 'Starting...';
btn.disabled = false;
}
}
}
} catch (e) {
console.warn('Device conflict check failed:', e);
}
}
const requestBody = {
device: adsbDevice,
sdr_type: adsbSdrType,