Tuesday, October 6, 2009

Where is my satellite - in Python

Mark (K6HX) had suggested that using PyEphem would be easy.... and, well it is! I worked off his example here to create my own utility that would poll for updates as time ticks on and on. It's nothing fancy by any means but it got me digging into the code a bit. Here are the results:

# Script to sit and poll for upcoming satellite passes.
# Joseph Armbruster

# TODO(joe) : clean up these imports
import datetime
import ephem
import math
import os
import sys
import time
import urllib2

# TODO(joe) : add getopt configuration options for this to main.
_latlong = ('28.5340','-81.2594') # user lat/long
_notify = 30 # let us know this many minutes in advance to a pass
_usevoice = True # use voice?
_statussleep = 1 # how many minutes to sleep between status updates

def GetTLEs():
'''GetTLEs(): returns a list of tuples of keps for each satellite.
This function currently relies on a url from amsat.org.'''
# grab the latest keps
tles = urllib2.urlopen('http://www.amsat.org/amsat/ftp/keps/current/nasabare.txt').readlines()

# strip off the header tokens and newlines
tles = [item.strip() for item in tles]

# clean up the lines
tles = [(tles[i],tles[i+1],tles[i+2]) for i in xrange(0,len(tles)-2,3)]

return tles

if __name__ == '__main__':

observer = ephem.Observer()
observer.lat = _latlong[0]
observer.long = _latlong[1]

tles = GetTLEs()

while 1:
now = datetime.datetime.now()

# iterate through all the two line element sets
for tle in tles:

sat = ephem.readtle(tle[0],tle[1],tle[2])

rt, ra, tt, ta, st, sa = observer.next_pass(sat)
observer.date = rt
localrisetime = ephem.localtime(rt)

timeuntilrise = localrisetime-now

minutesaway = timeuntilrise.seconds/60.0
if minutesaway <= _notify:

if _usevoice and sys.platform=='darwin':
say = 'say "%s WILL BE MAKING A PASS IN %d MINUTES."' % (tle[0],minutesaway)

print tle[0]
print ' Rise Azimuth: ', ra
print ' Transit Time: ', tt
print ' Transit Altitude: ', ta
print ' Set Time: ', st
print ' Set Azimuth: ', sa


I learned a very valuable lesson about setting the observers lat/long values to a double. That's a REALLY bad idea and a rather difficult bug to find!