fix(satellite): populate currentPos with full telemetry in pass predictions

Previously currentPos only had lat/lon, so the updateTelemetry fallback
(used before first live position arrives) always showed '---' for
altitude/elevation/azimuth/distance. currentPos now includes all fields
computed from the request observer location. updateTelemetry simplified
to delegate to applyTelemetryPosition.
This commit is contained in:
James Smith
2026-03-19 21:48:33 +00:00
parent d84237dbb4
commit d240ae06e3
3 changed files with 34 additions and 15 deletions

View File

@@ -513,7 +513,19 @@ def predict_passes():
current_pos = {
'lat': float(sp.latitude.degrees),
'lon': float(sp.longitude.degrees),
'altitude': float(sp.elevation.km),
}
# Add observer-relative data using the request's observer location
try:
diff = satellite - observer
topo = diff.at(t0)
alt_deg, az_deg, dist_km = topo.altaz()
current_pos['elevation'] = round(float(alt_deg.degrees), 1)
current_pos['azimuth'] = round(float(az_deg.degrees), 1)
current_pos['distance'] = round(float(dist_km.km), 1)
current_pos['visible'] = bool(alt_deg.degrees > 0)
except Exception:
pass
except Exception:
pass

View File

@@ -2404,21 +2404,9 @@
clearTelemetry();
return;
}
const pos = pass.currentPos;
const telLat = document.getElementById('telLat');
const telLon = document.getElementById('telLon');
const telAlt = document.getElementById('telAlt');
const telEl = document.getElementById('telEl');
const telAz = document.getElementById('telAz');
const telDist = document.getElementById('telDist');
if (telLat) telLat.textContent = Number.isFinite(pos.lat) ? pos.lat.toFixed(4) + '°' : '---.----';
if (telLon) telLon.textContent = Number.isFinite(pos.lon) ? pos.lon.toFixed(4) + '°' : '---.----';
if (telAlt && Number.isFinite(pos.alt)) telAlt.textContent = pos.alt.toFixed(0) + ' km';
if (telEl && Number.isFinite(pos.el)) telEl.textContent = pos.el.toFixed(1) + '°';
if (telAz && Number.isFinite(pos.az)) telAz.textContent = pos.az.toFixed(1) + '°';
if (telDist && Number.isFinite(pos.dist)) telDist.textContent = pos.dist.toFixed(0) + ' km';
// currentPos now contains full position data (lat, lon, altitude,
// elevation, azimuth, distance, visible) from the predict endpoint.
applyTelemetryPosition(pass.currentPos);
}
function updateCountdown() {

View File

@@ -121,6 +121,25 @@ def test_tracker_position_has_no_observer_fields():
assert required in pos, f"SSE tracker must emit '{required}'"
def test_predict_passes_currentpos_has_full_fields(client):
"""currentPos in pass results must include altitude, elevation, azimuth, distance."""
payload = {
'latitude': 51.5074,
'longitude': -0.1278,
'hours': 48,
'minEl': 5,
'satellites': ['ISS'],
}
response = client.post('/satellite/predict', json=payload)
assert response.status_code == 200
data = response.json
assert data['status'] == 'success'
if data['passes']:
cp = data['passes'][0].get('currentPos', {})
for field in ('lat', 'lon', 'altitude', 'elevation', 'azimuth', 'distance'):
assert field in cp, f"currentPos missing field: {field}"
@patch('routes.satellite.refresh_tle_data', return_value=['ISS'])
@patch('routes.satellite._load_db_satellites_into_cache')
def test_tle_auto_refresh_schedules_daily_repeat(mock_load_db, mock_refresh):