#!/usr/bin/env python3 import re import time import logging import argparse from datetime import datetime from spacetrack import SpaceTrackClient # ========================= CONFIG ========================= USERNAME = 'YourSpacetrackUserName' PASSWORD = 'YourSpacetrackPassword' INPUT_FILE = '/home/pi/satellites.txt' OUTPUT_FILE = '/home/pi/Spacetrack_downloaded_satellites.txt' # ======================================================= # Setup logging logging.basicConfig( filename='/home/pi/space-track.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) def is_high_load_window(): m = datetime.utcnow().minute return (m <= 5 or m >= 55) or (14 <= m <= 16) or (25 <= m <= 35) or (44 <= m <= 46) def wait_for_good_window(): while is_high_load_window(): now = datetime.utcnow().strftime('%H:%M UTC') print(f"High-load window active ({now}). Waiting 60s...") logging.info("Waiting in high-load window") time.sleep(60) def download_tles(): try: with open(INPUT_FILE, 'r') as f: lines = [line.strip() for line in f if line.strip() and not line.startswith('#')] except FileNotFoundError: logging.error(f"Input file {INPUT_FILE} not found") print(f"Error: {INPUT_FILE} not found") return False cat_ids = [] name_map = {} for line in lines: match = re.match(r'^(\d+).*?#\s*(.*)', line) if match: cat_id = match.group(1).strip() name = match.group(2).strip() or f"NORAD_{cat_id}" cat_ids.append(cat_id) name_map[cat_id] = name if not cat_ids: logging.warning("No valid satellite IDs found") print("No satellites found in input file") return False wait_for_good_window() logging.info(f"Requesting {len(cat_ids)} satellites using Space-Track native client...") try: with SpaceTrackClient(identity=USERNAME, password=PASSWORD) as st: # Query the 'gp' class using official native keyword arguments # Removed the decay filter to ensure the database returns all targeted numbers response_text = st.gp( norad_cat_id=cat_ids, format='tle' ) data = response_text.strip().split('\n') with open(OUTPUT_FILE, 'w') as f: count = 0 buffer = [] for line in data: line = line.strip() if not line: continue buffer.append(line) if len(buffer) == 2: line1, line2 = buffer # Parse the NORAD ID to accurately match it back to your station's naming map norad = line1[2:7].strip().lstrip('0') sat_name = name_map.get(norad, f"NORAD_{norad}") f.write(f"{sat_name}\n{line1}\n{line2}\n") count += 1 buffer = [] logging.info(f"Successfully downloaded {count} optimized TLE updates") print(f"✅ Successfully downloaded {count} TLE updates → {OUTPUT_FILE}") return True except Exception as e: logging.error(f"Download error: {e}") print(f"Download failed: {e}") return False if __name__ == "__main__": parser = argparse.ArgumentParser(description="Space-Track Bulk TLE Downloader") parser.add_argument('--upload', action='store_true', help="Enable SFTP upload functionality") args = parser.parse_args() download_tles() if args.upload: print("SFTP upload functionality is currently commented out.")