diff --git a/routes/satellite.py b/routes/satellite.py
index 60340a5..88ca2f0 100644
--- a/routes/satellite.py
+++ b/routes/satellite.py
@@ -509,33 +509,33 @@ def get_satellite_position():
for sat in sat_input:
sat_name, norad_id, tle_data = _resolve_satellite_request(sat, tracked_by_norad, tracked_by_name)
- # Special handling for ISS - use real-time API for accurate position
+ # Special handling for ISS - prefer real-time API, but fall back to TLE if offline.
if norad_id == 25544 or sat_name == 'ISS':
iss_data = _fetch_iss_realtime(lat, lon)
if iss_data:
# Add orbit track if requested (using TLE for track prediction)
if include_track and 'ISS' in _tle_cache:
try:
- tle_data = _tle_cache['ISS']
- satellite = EarthSatellite(tle_data[1], tle_data[2], tle_data[0], ts)
- orbit_track = []
- for minutes_offset in range(-45, 46, 1):
- t_point = ts.utc(now_dt + timedelta(minutes=minutes_offset))
- try:
- geo = satellite.at(t_point)
- sp = wgs84.subpoint(geo)
- orbit_track.append({
- 'lat': float(sp.latitude.degrees),
- 'lon': float(sp.longitude.degrees),
- 'past': minutes_offset < 0
- })
- except Exception:
- continue
- iss_data['track'] = orbit_track
- except Exception:
- pass
+ tle_data = _tle_cache['ISS']
+ satellite = EarthSatellite(tle_data[1], tle_data[2], tle_data[0], ts)
+ orbit_track = []
+ for minutes_offset in range(-45, 46, 1):
+ t_point = ts.utc(now_dt + timedelta(minutes=minutes_offset))
+ try:
+ geo = satellite.at(t_point)
+ sp = wgs84.subpoint(geo)
+ orbit_track.append({
+ 'lat': float(sp.latitude.degrees),
+ 'lon': float(sp.longitude.degrees),
+ 'past': minutes_offset < 0
+ })
+ except Exception:
+ continue
+ iss_data['track'] = orbit_track
+ except Exception:
+ pass
positions.append(iss_data)
- continue
+ continue
# Other satellites - use TLE data
if not tle_data:
diff --git a/templates/index.html b/templates/index.html
index bebc94c..0ebb852 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1416,7 +1416,7 @@
-
diff --git a/templates/satellite_dashboard.html b/templates/satellite_dashboard.html
index 952754e..019be32 100644
--- a/templates/satellite_dashboard.html
+++ b/templates/satellite_dashboard.html
@@ -602,6 +602,18 @@
let _txRequestId = 0;
let _telemetryPollTimer = null;
let _passRequestId = 0;
+ const BUILTIN_TX_FALLBACK = {
+ 25544: [
+ { description: 'APRS digipeater', downlink_low: 145.825, downlink_high: 145.825, uplink_low: null, uplink_high: null, mode: 'FM AX.25', baud: 1200, status: 'active', type: 'beacon', service: 'Packet' },
+ { description: 'SSTV events', downlink_low: 145.800, downlink_high: 145.800, uplink_low: null, uplink_high: null, mode: 'FM', baud: null, status: 'active', type: 'image', service: 'SSTV' }
+ ],
+ 57166: [
+ { description: 'Meteor LRPT weather downlink', downlink_low: 137.900, downlink_high: 137.900, uplink_low: null, uplink_high: null, mode: 'LRPT', baud: 72000, status: 'active', type: 'image', service: 'Weather' }
+ ],
+ 59051: [
+ { description: 'Meteor LRPT weather downlink', downlink_low: 137.900, downlink_high: 137.900, uplink_low: null, uplink_high: null, mode: 'LRPT', baud: 72000, status: 'active', type: 'image', service: 'Weather' }
+ ]
+ };
let satellites = {
25544: { name: 'ISS (ZARYA)', color: '#00ffff' },
@@ -1637,9 +1649,17 @@
const data = await r.json();
if (requestId !== _txRequestId) return;
if (data.status !== 'success') throw new Error('Unexpected response');
- renderTransmitters(data.transmitters || []);
+ const txList = (data.transmitters && data.transmitters.length)
+ ? data.transmitters
+ : (BUILTIN_TX_FALLBACK[noradId] || []);
+ renderTransmitters(txList);
} catch (e) {
if (requestId !== _txRequestId) return;
+ const fallback = BUILTIN_TX_FALLBACK[noradId] || [];
+ if (fallback.length) {
+ renderTransmitters(fallback);
+ return;
+ }
const timedOut = e && (e.name === 'AbortError' || String(e).includes('AbortError'));
container.innerHTML = `
${timedOut ? 'Timed out loading transmitter data' : 'Failed to load transmitter data'}
`;
if (countEl) countEl.textContent = '';