Above Brum
I loved the idea of
Above London
(twitter)
and as I utterly failed to see any Perseid meteors this week, I
thought I’d shamelessly steal the idea for my locality, so I can at least
hopefully see something light up in the sky in the not-too-distant future. :)
The account will send a message c. 30 minutes before an Iridium flare or an ISS flyby, based on information from heavens-above. It always sends the message even if the weather is bad, but does include the latest weather report so you can decide for yourself whether it’s worth popping outside.
Source code
There are three scripts: scrape, weather, and twitter. scrape runs daily to fetch the flare/ISS times, weather runs hourly to fetch the latest weather from Yahoo!, and twitter runs every five minutes to see if something is coming up that needs to be sent to Twitter.
weather
#!/usr/local/bin/python # # Run hourly to fetch latest weather from Yahoo! import urllib, re, time # Get the code for a different place from the Yahoo! web site or similar code = 'UKXX0018' weather = urllib.urlopen('http://weather.yahooapis.com/forecastrss?p=%s&u=c' % code).read() # visibility might be useful for someone - I don't use it # m = re.search('<yweather:atmosphere humidity="(\d*)" visibility="([\d.]*)" pressure="([\d.]*)"', weather) # humidity, visibility, pressure = m.groups() m = re.search('<yweather:condition text="(.*?)" code="(\d+)" temp="(-?\d+)" date="(.*?)"', weather) text, code, temp, date = m.groups() epoch = time.mktime( time.strptime(date, '%a, %d %b %Y %I:%M %p %Z') ) # Twitter bot doesn't actually use this, but it possibly could. clear = 'NO' # Blustery, Windy, Cold, Partly cloudy, clear, Sunny, Fair if int(code) in [ 23, 24, 25, 29, 30, 44, 31, 32, 33, 34, 36 ]: clear = 'YES' print "%s\t%s\t%s\t%s" % (epoch, clear, text, code)
scrape
#!/usr/local/bin/python # # Scraper for ISS and Iridium flare pages # Runs once a day. # Change these co-ordinates for your location lat = 52.48 lon = -1.90 import urllib, re, time, sys from datetime import datetime dir = sys.path[0] + '/' iss = urllib.urlopen('http://www.heavens-above.com/PassSummary.aspx?satid=25544&lat=%f&lng=%f&alt=114&tz=GMT' % (lat, lon)).read() rows = re.findall('<tr class="(?:light|dark)row">\s*<td><a href="[^"]*">(.*?)</a></td>' + ('<td>\s*(.*?)\s*</td>' * 10), iss) fp = open(dir + 'iss.tsv', 'w') for row in rows: date, mag, start_time, start_alt, start_az, max_time, max_alt, max_az, end_time, end_alt, end_az = row # This will break around New Year time. timestamp = time.mktime(time.strptime('%s %s %s' % (datetime.now().year, date, start_time), '%Y %d %b %H:%M:%S')) out = (str(timestamp), mag, start_time, end_time, start_az, end_az, max_time, max_alt, max_az) fp.write("\t".join(out) + "\n") fp.close() iridium = urllib.urlopen('http://www.heavens-above.com/iridium.asp?Dur=7&lat=%f&lng=%f&alt=114&tz=GMT' % (lat, lon)).read() rows = re.findall('<tr>\s*<td>(.*?)</td>\s*<td><a href="flaredetails[^"]*">(.*?)</a></td>\s*<td align=center>(.*?)</td>\s*<td align=right>(\d+)°</td>\s*<td align=right>(\d+)° \((.*?)\s*\)</td>\s*<td align=right>.*?</td>\s*<td align=center>.*?</td>\s*<td align=left><a href="[^"]*">(.*?)</a></td>', iridium) fp = open(dir + 'iridium.tsv', 'w') for row in rows: date, flare_time, mag, altitude, azimuth, compass, name = row timestamp = time.mktime(time.strptime('%s %s %s' % (datetime.now().year, date, flare_time), '%Y %d %b %H:%M:%S')) out = (str(timestamp), mag, altitude, azimuth, compass, name) fp.write("\t".join(out) + "\n") fp.close()
#!/usr/local/bin/python # # twitter: # Twitter Iridium flares and ISS flybys above Birmingham # # Copyright (c) 2009 Matthew Somerville. http://www.dracos.co.uk/ import urllib, urllib2, sys from datetime import datetime, timedelta import tweepy from config import * dir = sys.path[0] + '/' def main(): soon = datetime.today() + timedelta(minutes=30) weather = open(dir + 'weather.tsv').read() weather_epoch, weather_clear, weather_desc, weather_code = weather.strip().split("\t") flares = open(dir + 'iridium.tsv') for row in flares: epoch, mag, altitude, azimuth, compass, name = row.strip().split("\t") epoch = datetime.fromtimestamp(float(epoch)) if soon >= epoch and soon < epoch + timedelta(minutes=5): s = u"Iridium flare: magnitude %s at %s, altitude %d\u00b0, in direction %d\u00b0 (%s), from %s. Weather: %s." % ( mag, epoch.strftime('%H:%M:%S'), float(altitude), float(azimuth), compass, name, weather_desc ) twitter(s) iss = open(dir + 'iss.tsv') for row in iss: epoch, mag, start_time, end_time, start_az, end_az, max_time, max_alt, max_az = row.strip().split("\t") epoch = datetime.fromtimestamp(float(epoch)) if soon >= epoch and soon < epoch + timedelta(minutes=5): s = u"ISS pass: magnitude %.1f, %s\u2013%s from %s to %s, maximum altitude %d\u00b0 at %s in %s. Weather: %s." % ( float(mag), start_time, end_time, start_az, end_az, float(max_alt), max_time, max_az, weather_desc ) twitter(s) def twitter(line): line = line.encode('utf-8') auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) return tweepy.API(auth).update_status(line) main()