mirror of
https://github.com/smittix/intercept.git
synced 2026-07-10 18:48:12 -07:00
feat: Auto-update TLE data on app startup
- Add refresh_tle_data() function for reusable TLE updates - Automatically fetch fresh TLE from CelesTrak when app starts - Runs in background thread to avoid slowing down startup - Includes NOAA-20 and NOAA-21 in name mappings - Gracefully handles failures (uses cached data if offline) - Existing /update-tle endpoint now uses shared function This ensures satellite tracking data is always fresh, fixing inaccurate positions caused by stale TLE data. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -714,6 +714,22 @@ def main() -> None:
|
|||||||
from routes import register_blueprints
|
from routes import register_blueprints
|
||||||
register_blueprints(app)
|
register_blueprints(app)
|
||||||
|
|
||||||
|
# Update TLE data in background thread (non-blocking)
|
||||||
|
def update_tle_background():
|
||||||
|
try:
|
||||||
|
from routes.satellite import refresh_tle_data
|
||||||
|
print("Updating satellite TLE data from CelesTrak...")
|
||||||
|
updated = refresh_tle_data()
|
||||||
|
if updated:
|
||||||
|
print(f"TLE data updated for: {', '.join(updated)}")
|
||||||
|
else:
|
||||||
|
print("TLE update: No satellites updated (may be offline)")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"TLE update failed (will use cached data): {e}")
|
||||||
|
|
||||||
|
tle_thread = threading.Thread(target=update_tle_background, daemon=True)
|
||||||
|
tle_thread.start()
|
||||||
|
|
||||||
# Initialize WebSocket for audio streaming
|
# Initialize WebSocket for audio streaming
|
||||||
try:
|
try:
|
||||||
from routes.audio_websocket import init_audio_websocket
|
from routes.audio_websocket import init_audio_websocket
|
||||||
|
|||||||
+48
-35
@@ -412,56 +412,69 @@ def get_satellite_position():
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@satellite_bp.route('/update-tle', methods=['POST'])
|
def refresh_tle_data() -> list:
|
||||||
def update_tle():
|
"""
|
||||||
"""Update TLE data from CelesTrak."""
|
Refresh TLE data from CelesTrak.
|
||||||
|
|
||||||
|
This can be called at startup or periodically to keep TLE data fresh.
|
||||||
|
Returns list of satellite names that were updated.
|
||||||
|
"""
|
||||||
global _tle_cache
|
global _tle_cache
|
||||||
|
|
||||||
try:
|
name_mappings = {
|
||||||
name_mappings = {
|
'ISS (ZARYA)': 'ISS',
|
||||||
'ISS (ZARYA)': 'ISS',
|
'NOAA 15': 'NOAA-15',
|
||||||
'NOAA 15': 'NOAA-15',
|
'NOAA 18': 'NOAA-18',
|
||||||
'NOAA 18': 'NOAA-18',
|
'NOAA 19': 'NOAA-19',
|
||||||
'NOAA 19': 'NOAA-19',
|
'NOAA 20 (JPSS-1)': 'NOAA-20',
|
||||||
'METEOR-M 2': 'METEOR-M2',
|
'NOAA 21 (JPSS-2)': 'NOAA-21',
|
||||||
'METEOR-M2 3': 'METEOR-M2-3'
|
'METEOR-M 2': 'METEOR-M2',
|
||||||
}
|
'METEOR-M2 3': 'METEOR-M2-3'
|
||||||
|
}
|
||||||
|
|
||||||
updated = []
|
updated = []
|
||||||
|
|
||||||
for group in ['stations', 'weather']:
|
for group in ['stations', 'weather', 'noaa']:
|
||||||
url = f'https://celestrak.org/NORAD/elements/gp.php?GROUP={group}&FORMAT=tle'
|
url = f'https://celestrak.org/NORAD/elements/gp.php?GROUP={group}&FORMAT=tle'
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(url, timeout=10) as response:
|
with urllib.request.urlopen(url, timeout=15) as response:
|
||||||
content = response.read().decode('utf-8')
|
content = response.read().decode('utf-8')
|
||||||
lines = content.strip().split('\n')
|
lines = content.strip().split('\n')
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while i + 2 < len(lines):
|
while i + 2 < len(lines):
|
||||||
name = lines[i].strip()
|
name = lines[i].strip()
|
||||||
line1 = lines[i + 1].strip()
|
line1 = lines[i + 1].strip()
|
||||||
line2 = lines[i + 2].strip()
|
line2 = lines[i + 2].strip()
|
||||||
|
|
||||||
if not (line1.startswith('1 ') and line2.startswith('2 ')):
|
if not (line1.startswith('1 ') and line2.startswith('2 ')):
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
internal_name = name_mappings.get(name, name)
|
internal_name = name_mappings.get(name, name)
|
||||||
|
|
||||||
if internal_name in _tle_cache:
|
if internal_name in _tle_cache:
|
||||||
_tle_cache[internal_name] = (name, line1, line2)
|
_tle_cache[internal_name] = (name, line1, line2)
|
||||||
|
if internal_name not in updated:
|
||||||
updated.append(internal_name)
|
updated.append(internal_name)
|
||||||
|
|
||||||
i += 3
|
i += 3
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching {group}: {e}")
|
logger.warning(f"Error fetching TLE group {group}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
return updated
|
||||||
|
|
||||||
|
|
||||||
|
@satellite_bp.route('/update-tle', methods=['POST'])
|
||||||
|
def update_tle():
|
||||||
|
"""Update TLE data from CelesTrak (API endpoint)."""
|
||||||
|
try:
|
||||||
|
updated = refresh_tle_data()
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'status': 'success',
|
'status': 'success',
|
||||||
'updated': updated
|
'updated': updated
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'status': 'error', 'message': str(e)})
|
return jsonify({'status': 'error', 'message': str(e)})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user