mirror of
https://github.com/smittix/intercept.git
synced 2026-07-16 21:38:11 -07:00
Fix ADS-B aircraft map plotting and improve dependency detection
- Fix calls to non-existent drawAircraftRadar(), now calls updateAircraftMarkers() - Fix null check for lat/lon coordinates (use == null instead of === undefined) - Add polling of dump1090 JSON endpoint for decoded aircraft positions - Add debug logging for Python module import failures - Add startup diagnostics for troubleshooting skyfield detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+93
-24
@@ -13,6 +13,18 @@ A comprehensive signal intelligence tool featuring:
|
|||||||
Requires RTL-SDR hardware for RF modes.
|
Requires RTL-SDR hardware for RF modes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
print(f"[Debug] Python executable: {sys.executable}")
|
||||||
|
print(f"[Debug] Python version: {sys.version}")
|
||||||
|
print(f"[Debug] User site-packages: {'/home/radio/.local/lib/python3.10/site-packages' in sys.path}")
|
||||||
|
|
||||||
|
# Quick skyfield check at startup
|
||||||
|
try:
|
||||||
|
import skyfield
|
||||||
|
print(f"[Debug] Skyfield loaded: {skyfield.__file__}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[Debug] Skyfield import failed: {e}")
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
import re
|
import re
|
||||||
@@ -7942,7 +7954,7 @@ HTML_TEMPLATE = '''
|
|||||||
|
|
||||||
// Update or create markers for each aircraft
|
// Update or create markers for each aircraft
|
||||||
Object.entries(adsbAircraft).forEach(([icao, aircraft]) => {
|
Object.entries(adsbAircraft).forEach(([icao, aircraft]) => {
|
||||||
if (aircraft.lat === undefined || aircraft.lon === undefined) return;
|
if (aircraft.lat == null || aircraft.lon == null) return;
|
||||||
|
|
||||||
currentIds.add(icao);
|
currentIds.add(icao);
|
||||||
|
|
||||||
@@ -8157,7 +8169,7 @@ HTML_TEMPLATE = '''
|
|||||||
};
|
};
|
||||||
adsbMsgCount++;
|
adsbMsgCount++;
|
||||||
updateAdsbStats();
|
updateAdsbStats();
|
||||||
drawAircraftRadar();
|
updateAircraftMarkers();
|
||||||
addAircraftToOutput(data);
|
addAircraftToOutput(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -8170,7 +8182,7 @@ HTML_TEMPLATE = '''
|
|||||||
delete adsbAircraft[icao];
|
delete adsbAircraft[icao];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
drawAircraftRadar();
|
updateAircraftMarkers();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9725,7 +9737,8 @@ def check_all_dependencies():
|
|||||||
try:
|
try:
|
||||||
__import__(tool)
|
__import__(tool)
|
||||||
installed = True
|
installed = True
|
||||||
except ImportError:
|
except Exception as e:
|
||||||
|
print(f"[Dependency] Failed to import {tool}: {type(e).__name__}: {e}")
|
||||||
installed = False
|
installed = False
|
||||||
else:
|
else:
|
||||||
# Check for alternatives
|
# Check for alternatives
|
||||||
@@ -12046,43 +12059,99 @@ def stream_adsb():
|
|||||||
|
|
||||||
|
|
||||||
def parse_adsb_output(process):
|
def parse_adsb_output(process):
|
||||||
"""Parse ADS-B output and add to queue."""
|
"""Parse ADS-B output and poll dump1090 JSON for decoded data."""
|
||||||
global adsb_aircraft
|
global adsb_aircraft
|
||||||
import re
|
import re
|
||||||
|
import urllib.request
|
||||||
|
import json as json_lib
|
||||||
|
|
||||||
icao_pattern = re.compile(r'\*([0-9A-Fa-f]{6,14});')
|
icao_pattern = re.compile(r'\*([0-9A-Fa-f]{6,14});')
|
||||||
|
|
||||||
|
# Start a thread to poll dump1090's JSON endpoint for decoded positions
|
||||||
|
def poll_dump1090_json():
|
||||||
|
"""Poll dump1090's aircraft.json for decoded lat/lon data."""
|
||||||
|
json_urls = [
|
||||||
|
'http://localhost:8080/data/aircraft.json',
|
||||||
|
'http://localhost:30003/data/aircraft.json',
|
||||||
|
'http://localhost:8080/dump1090/data/aircraft.json'
|
||||||
|
]
|
||||||
|
working_url = None
|
||||||
|
|
||||||
|
while adsb_process and adsb_process.poll() is None:
|
||||||
|
try:
|
||||||
|
# Find working URL on first success
|
||||||
|
urls_to_try = [working_url] if working_url else json_urls
|
||||||
|
for url in urls_to_try:
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(url, timeout=2) as response:
|
||||||
|
data = json_lib.loads(response.read().decode())
|
||||||
|
working_url = url
|
||||||
|
|
||||||
|
for ac in data.get('aircraft', []):
|
||||||
|
icao = ac.get('hex', '').upper()
|
||||||
|
if not icao:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Update aircraft with decoded position data
|
||||||
|
aircraft = adsb_aircraft.get(icao, {'icao': icao})
|
||||||
|
aircraft.update({
|
||||||
|
'icao': icao,
|
||||||
|
'callsign': ac.get('flight', '').strip() or aircraft.get('callsign'),
|
||||||
|
'altitude': ac.get('altitude') or ac.get('alt_baro') or aircraft.get('altitude'),
|
||||||
|
'speed': ac.get('speed') or ac.get('gs') or aircraft.get('speed'),
|
||||||
|
'heading': ac.get('track') or aircraft.get('heading'),
|
||||||
|
'lat': ac.get('lat') or aircraft.get('lat'),
|
||||||
|
'lon': ac.get('lon') or aircraft.get('lon'),
|
||||||
|
'squawk': ac.get('squawk') or aircraft.get('squawk'),
|
||||||
|
'rssi': ac.get('rssi') or aircraft.get('rssi')
|
||||||
|
})
|
||||||
|
|
||||||
|
adsb_aircraft[icao] = aircraft
|
||||||
|
adsb_queue.put({
|
||||||
|
'type': 'aircraft',
|
||||||
|
**aircraft
|
||||||
|
})
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Start JSON polling thread
|
||||||
|
json_thread = threading.Thread(target=poll_dump1090_json, daemon=True)
|
||||||
|
json_thread.start()
|
||||||
|
|
||||||
|
# Also parse raw output for immediate ICAO detection
|
||||||
try:
|
try:
|
||||||
for line in process.stdout:
|
for line in process.stdout:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Parse raw Mode S messages (simplified)
|
# Parse raw Mode S messages for quick ICAO detection
|
||||||
match = icao_pattern.search(line)
|
match = icao_pattern.search(line)
|
||||||
if match:
|
if match:
|
||||||
raw = match.group(1)
|
raw = match.group(1)
|
||||||
if len(raw) >= 6:
|
if len(raw) >= 6:
|
||||||
icao = raw[:6].upper()
|
icao = raw[:6].upper()
|
||||||
|
|
||||||
# Basic aircraft data (would need proper Mode S decoding for full data)
|
# Create placeholder if not seen via JSON yet
|
||||||
aircraft = adsb_aircraft.get(icao, {
|
if icao not in adsb_aircraft:
|
||||||
'icao': icao,
|
aircraft = {
|
||||||
'callsign': None,
|
'icao': icao,
|
||||||
'altitude': None,
|
'callsign': None,
|
||||||
'speed': None,
|
'altitude': None,
|
||||||
'heading': None,
|
'speed': None,
|
||||||
'lat': None,
|
'heading': None,
|
||||||
'lon': None,
|
'lat': None,
|
||||||
'distance': 50, # Placeholder
|
'lon': None
|
||||||
'bearing': hash(icao) % 360 # Placeholder for demo
|
}
|
||||||
})
|
adsb_aircraft[icao] = aircraft
|
||||||
|
adsb_queue.put({
|
||||||
adsb_aircraft[icao] = aircraft
|
'type': 'aircraft',
|
||||||
adsb_queue.put({
|
**aircraft
|
||||||
'type': 'aircraft',
|
})
|
||||||
**aircraft
|
|
||||||
})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[ADS-B] Parse error: {e}")
|
print(f"[ADS-B] Parse error: {e}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user