def predict(self, days=2.0): utc_now_seconds = float(datetime.now(tz=timezone('UTC')).timestamp()) self.logger.info( f"Time now in UTC is {datetime.now(tz=timezone('UTC')).isoformat()}" ) self.logger.info( f"Checking for {self.config.Lat}N {self.config.Lon}E {self.config.Lat}m " ) for sat in self.config.Sats: self.logger.debug(f"Checking for {sat}") sat, line1, line2 = self.tle_reader.find_sat(sat) if sat: self.logger.debug(f"We have TLE for {sat}") tle = f"{sat}\n{line1}\n{line2}\n" predict.observe(tle, self.config.Qth) try: p = predict.transits(tle, self.config.Qth, ending_after=utc_now_seconds - 900.0, ending_before=utc_now_seconds + days * 24.0 * 3600.0) passes = list(p) except Exception: passes = [] for orbit in passes: if orbit.peak()['elevation'] > self.config.MinAlt: when = datetime.fromtimestamp(orbit.start) #local_time = when.astimezone(timezone(self.config.TimeZone)) when_utc_str = when.strftime("%Y-%m-%d %H:%M:%S %Z%z") delay_str = self.secs_to_hms(orbit.start - utc_now_seconds) self.logger.info( f"{sat} Delay: {delay_str} Start: {when_utc_str} Duration: {int(orbit.duration()):4} Max Ele: {int(orbit.peak()['elevation']):3} " ) self.logger.debug(f"We have {len(passes)} Passes for {sat}")
def next_pass(self, obs_time=None): if not obs_time: obs_time = time.time() p = predict.transits(self.tle, self.qth, ending_after=obs_time) transit = p.next() return transit.start, transit.duration(), transit.peak()['elevation']
def satellite_obstruction(az, el, loc, fov, obs_time, obs_len): ''' params: az: center azimuth of observation el: center elevation of observation loc: ecef telescope location (x, y, z) obs_time: GPS(?) #FIXME: figure this out fov: radius of the field of view in degrees obs_len: length of exposure (seconds) returns: bool: whether a satellite will be in the view TODO: Other info? ''' all_visible_passes = [] az_rng = (az - fov, az + fov) el_rng = (el - fov, el + fov) tles = get_celestrack_data() sat_passes = [ predict.transits( tle, loc, ending_after=obs_time, ending_before=(obs_time + obs_len) #FIXME: think about this more ) for tle in tles ] for passes in sat_passes: try: ps = list(passes) #unpack generator except predict.PredictException: print("ISSUE!") continue visible_passes = [ p.prune( lambda ts: ( p.at(ts)['visibility'] == 'V' and az_rng[0] <= p.at(ts)['azimuth'] <= az_rng[1] and el_rng[0] <= p.at(ts)['elevation'] <= el_rng[1] ) ) for p in ps ] passes_in_observation = [p for p in visible_passes if p.duration() > 0] all_visible_passes += passes_in_observation return all_visible_passes
def run(self): self._logger.info('Running %s', self) while not self.stopped(): passes = predict.transits(self.tle, self.qth) next_pass = passes.next() start = next_pass.start end = next_pass.start + next_pass.duration() now = time.time() if now >= start and now <= end: self.send_beacon() time.sleep(self.interval)
def nextsat(): transits = [] i=0 for tle, freq in SATELLITES: p = predict.transits(tle, GROUNDSTATION) for n in range(0,EVALPASSES): try: transit = p.next() except predict.PredictException, e: logging.warning("Satellite not scheduled. Reason: %s" % (e)) break if(transit.peak()['elevation'] > MINELEVATION): # skip low transit transit = transit.above(MINELEVATION) if transit.start > time.time(): # skip old transit transits.append([i, transit]) i+=1
def test_transits_are_truncated_if_the_overlap_the_start_or_end_times(self): #predict.massage_tle(EXAMPLE_QTH) tle = predict.massage_tle(TLE) qth = predict.massage_qth(QTH) at = T1_IN_TRANSIT obs = predict.observe(tle, qth, at=at) self.assertTrue(obs['elevation'] > 0) at = T2_NOT_IN_TRANSIT obs = predict.observe(tle, qth, at=at) self.assertTrue(obs['elevation'] < 0) # should not raise a StopIteration next_transit = next(predict.transits(tle, qth, ending_after=at))
def predictOneStation(tle, qth): predictions = [] p = predict.transits(tle, qth) while len(predictions) < count: transit = p.next() start = transit.start stop = transit.end maxElev = round(transit.peak()['elevation'], 2) aosAzimuth = transit.at(transit.start)['azimuth'] prediction = Predicton(start, stop, maxElev, aosAzimuth) if start > end_datetime: predictions.append(prediction) return predictions
def monitor(tle): while True: raw_data = predict.observe(tle, qth) data=json.dumps(raw_data) p = predict.transits(tle, qth) transit = p.next() #print("%f\t%f\t%f" % (transit.start, transit.duration(), transit.peak()['elevation'])) print "-------------------------------------------------------\n" print "Current sattelite: " + str(json.loads(data)['name']) + "\n" print "Latitude: " + str(json.loads(data)['latitude']) + " \n" print "Longitude: " + str(json.loads(data)['longitude']) + " \n" print "Next Transit: "+ str(datetime.datetime.fromtimestamp(int(transit.start)).strftime('%Y-%m-%d %H:%M:%S'))+"\n" print "Transit duration: " + str(transit.duration()) + "\n" print "Transit Peak: " + str(transit.peak()['elevation']) + "\n" print "-------------------------------------------------------\n" time.sleep(0.5) os.system("clear")
def azel_points(tlefile, qthfile, t): qth, locname = load_qth(qthfile) tle, satname = load_tle(tlefile) data = predict.observe(tle, qth, t) #find current state return data['azimuth'], data['elevation'], locname, satname ################################################################ if __name__ == "__main__": qthfile = 'ARGUS.qth' tlefile = 'iridium139.tle' # Find passes qth, locname = load_qth(qthfile) #load qth tle, satname = load_tle(tlefile) # load tle p = predict.transits(tle, qth) # predict future passes starttime, endtime, startaz, endaz, maxel = ([] for i in range(5) ) #initialize # Create Figure fig = plt.figure() ax = plt.subplot(111, projection='polar') # For each pass plot .... for i in range(3): # Predict 3 passes transit = next(p) #Find next pass starttime.append(time.ctime(transit.start)) endtime.append(time.ctime(transit.end)) startaz.append(predict.observe(tle, qth, transit.start)['azimuth']) endaz.append(predict.observe(tle, qth, transit.end)['azimuth']) maxel.append(transit.peak()['elevation'])
font2 = {'color': '#00796B', 'size': 12, } time_start = time.time() - 1000 time_end = time.time() + 86400 printEl = 0 minEl = 20 for h in birds: print h[0] if h[0] in ('NOAA 15', 'NOAA 18', 'NOAA 19'): minEl = elNOAA elif h[0] == 'METEOR-M 2': minEl = elMETEOR p = predict.transits(h, qth, time_start) for i in range(1, 20): transit = p.next() minuty = time.strftime("%M:%S", time.gmtime(transit.duration())) if int(transit.peak()['elevation']) >= minEl: f = predict.quick_predict(h, transit.start, qth) XP = [] YP = [] TIME = [] TABLE = [] name = f[0]['name'] for md in f: YP.append(90 - md['elevation']) XP.append(md['azimuth']) TIME.append(int(md['epoch'])) for ed, ag in enumerate(XP):
def run(hours): #get lat and lon from private file with open("/home/pi/website/weather/scripts/secrets.json") as f: data = json.load(f) lat = data["lat"] lon = data["lon"] #get the tle file form celestrak url = "https://www.celestrak.com/NORAD/elements/weather.txt" r = requests.get(url) tle = r.content.decode("utf-8").replace("\r\n", "newline").split("newline") #write tle to file for use with wxmap with open("/home/pi/website/weather/scripts/weather.tle", "w+") as f: f.write(r.text.replace("\r", "")) #find the satellites in the tle index = tle.index("NOAA 15 ") NOAA15 = "\n".join(tle[index:index + 3]) index = tle.index("NOAA 18 ") NOAA18 = "\n".join(tle[index:index + 3]) index = tle.index("NOAA 19 ") NOAA19 = "\n".join(tle[index:index + 3]) index = tle.index("METEOR-M 2 ") METEOR = "\n".join(tle[index:index + 3]) #set the ground station location loc = (lat, lon * -1, 20) #get the next passes of NOAA 15 within the next 24 hours print("getting NOAA 15 passes") NOAA15_passes = predict.transits(NOAA15, loc, time.time() + 900, time.time() + (3600 * hours)) #get the next passes of NOAA 18 within the next 24 hours print("getting NOAA 18 passes") NOAA18_passes = predict.transits(NOAA18, loc, time.time() + 900, time.time() + (3600 * hours)) #get the next passes of NOAA 19 within the next 24 hours print("getting NOAA 19 passes") NOAA19_passes = predict.transits(NOAA19, loc, time.time() + 900, time.time() + (3600 * hours)) #get the next passes of METEOR within the next 24 hours print("getting METEOR passes") METEOR_passes = predict.transits(METEOR, loc, time.time() + 900, time.time() + (3600 * hours)) #create one big list of all the passes passes = [] for p in NOAA15_passes: if p.peak()['elevation'] >= 20: passes.append(["NOAA 15", "NOAA", p]) for p in NOAA18_passes: if p.peak()['elevation'] >= 20: passes.append(["NOAA 18", "NOAA", p]) for p in NOAA19_passes: if p.peak()['elevation'] >= 20: passes.append(["NOAA 19", "NOAA", p]) for p in METEOR_passes: if p.peak()['elevation'] >= 20: passes.append(["METEOR-M 2", "METEOR", p]) #sort them by their date passes.sort(key=lambda x: x[2].start) freqs = { 'NOAA 15': 137620000, 'NOAA 18': 137912500, 'NOAA 19': 137100000, 'METEOR-M 2': 137100000, } #turn the info into json data data = [] for p in passes: sat = p[0] sat_type = p[1] info = p[2] data.append({ #ALL TIMES ARE IN SECONDS SINCE EPOCH (UTC) #name of the sat 'satellite': sat, #the frequency in MHz the satellite transmits 'frequency': freqs[sat], #time the sat rises above the horizon 'aos': round(info.start), #time the sat reaches its max elevation 'tca': round(info.peak()['epoch']), #time the sat passes below the horizon 'los': round(info.end), #maximum degrees of elevation 'max_elevation': round(info.peak()['elevation'], 1), #duration of the pass in seconds 'duration': round(info.duration()), #status INCOMING, CURRENT or PASSED 'status': "INCOMING", #type of satellite 'type': sat_type, #azimuth at the aos 'azimuth_aos': round(info.at(info.start)['azimuth'], 1), #azimuth at the los 'azimuth_los': round(info.at(info.end)['azimuth'], 1), #either northbound or southbound 'direction': "northbound" if 90 < info.at(info.start)['azimuth'] > 270 else "southbound" }) #check if passes overlap and choose which one to prioritize i = 0 while i < len(data) - 2: if data[i]['los'] > data[i + 1]['aos']: #prioritize higher elevation passes priority1 = data[i]['max_elevation'] priority2 = data[i + 1]['max_elevation'] #meteor gets more priority if data[i]['satellite'] == "METEOR-M 2": priority1 += 30 elif data[i + 1]['satellite'] == "METEOR-M 2": priority2 += 30 #keep the pass with higher priority if priority1 >= priority2: data.pop(i + 1) elif priority2 > priority1: data.pop(i) else: i += 1 #write to the json file with open("/home/pi/website/weather/scripts/daily_passes.json", "w") as outfile: json.dump(data, outfile, indent=4, sort_keys=True) #schedule the passes for the day s = sched.scheduler(time.time, time.sleep) i = 0 for p in data: #create a job for every pass print("Scheduled a job for {} or {}".format( p['aos'], datetime.fromtimestamp( p['aos']).strftime("%B %-d, %Y at %-H:%M:%S %Z"))) s.enterabs(p['aos'], 1, process.start, argument=(i, )) i += 1 #commit changes to git repository print("STATUS {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) + "Commiting changes to github") os.system( "/home/pi/website/weather/scripts/commit.sh 'Automatically scheduled satellite passes for the next 24 hours'" ) print("STATUS {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) + "Finished scheduling") next_pass = data[0] print( "STATUS: {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) + "Waiting until {} for {}° {} pass...".format( datetime.fromtimestamp(next_pass['aos']).strftime( "%B %-d, %Y at %-H:%M:%S"), next_pass['max_elevation'], next_pass['satellite'])) s.run() run(hours)
def aoslos(satname, minElev, minElevMeteor, stationLat, stationLon, stationAlt, tleFile): tleNOAA15 = [] tleNOAA18 = [] tleNOAA19 = [] tleMETEOR = [] tlefile = open(str(tleFile)) tledata = tlefile.readlines() tlefile.close() for i, line in enumerate(tledata): if "NOAA 15" in line: for l in tledata[i:i + 3]: tleNOAA15.append(l.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "NOAA 18" in line: for m in tledata[i:i + 3]: tleNOAA18.append(m.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "NOAA 19" in line: for n in tledata[i:i + 3]: tleNOAA19.append(n.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "METEOR-M 2" in line: for n in tledata[i:i + 3]: tleMETEOR.append(n.strip('\r\n').rstrip()), qth = (float(stationLat), float(stationLon), float(stationAlt)) minElev = int(minElev) minElevMeteor = int(minElevMeteor) # Recording delay opoznienie = '1' # delay meteor to ~12° - 15° meteor_delay = '180' # Recording short skrocenie = '1' # Shorten meteor recording by ~12° - 15° meteor_short = '180' # Predicting if satname in "NOAA 15": p = predict.transits(tleNOAA15, qth) for i in range(1, 20): transit = p.next() przelot_start = int(transit.start) + int(opoznienie) przelot_czas = int( transit.duration()) - (int(skrocenie) + int(opoznienie)) przelot_koniec = int(przelot_start) + int(przelot_czas) if int(transit.peak()['elevation']) >= minElev: return (int(przelot_start), int(przelot_koniec), int(przelot_czas), int(transit.peak()['elevation'])) elif satname in "NOAA 18": p = predict.transits(tleNOAA18, qth) for i in range(1, 20): transit = p.next() przelot = int(transit.duration()) przelot_start = int(transit.start) + int(opoznienie) przelot_czas = int( transit.duration()) - (int(skrocenie) + int(opoznienie)) przelot_koniec = int(przelot_start) + int(przelot_czas) if int(transit.peak()['elevation']) >= minElev: return (int(przelot_start), int(przelot_koniec), int(przelot_czas), int(transit.peak()['elevation'])) elif satname in "NOAA 19": p = predict.transits(tleNOAA19, qth) for i in range(1, 20): transit = p.next() przelot_start = int(transit.start) + int(opoznienie) przelot_czas = int( transit.duration()) - (int(skrocenie) + int(opoznienie)) przelot_koniec = int(przelot_start) + int(przelot_czas) if int(transit.peak()['elevation']) >= minElev: return (int(przelot_start), int(przelot_koniec), int(przelot_czas), int(transit.peak()['elevation'])) elif satname in "METEOR-M 2": p = predict.transits(tleMETEOR, qth) for i in range(1, 20): transit = p.next() przelot_start = int(transit.start) + int(meteor_delay) przelot_czas = int( transit.duration()) - (int(meteor_short) + int(meteor_delay)) przelot_koniec = int(przelot_start) + int(przelot_czas) if int(transit.peak()['elevation']) >= minElevMeteor: return (int(przelot_start), int(przelot_koniec), int(przelot_czas), int(transit.peak()['elevation'])) else: print "NO TLE DEFINED FOR " + satname + " BAILING OUT"
def get_sat_passes(tles, location, days_to_forecast): ''' location -> (lat, lon, alt): provides location of the telescope ''' predictions = [predict.transits(tle, location, ending_after=time.time(), ending_before=(time.time() + days_to_forecast * (24*60*60))) for tle in tles] return predictions
async def on_message(message): if message.content.startswith("!predict"): command = message.content[9:] if "-u" in command: update_tle() command = command.replace("-u", "") await message.channel.send("TLE updated") if "-h" in command: command = command.replace("-h", "") await message.channel.send(embed=discord.Embed.from_dict(HELP_MSG)) #handle prediction commands if len(command.strip()) > 0: try: await message.delete() except: await message.channel.send( "Cannot Delete Message: Missing Permissions") try: #update the tle if it hasn't been updated in 12 hours if TLE_LAST_UPDATED == 0 or datetime.now().timestamp( ) - TLE_LAST_UPDATED > 43200: update_tle() await message.channel.send("TLE updated") #get command arguments sat_name, loc, pass_count = parse_args(command) loc = (round(loc[0] + randint(-10, 10) / 100, 4), round(loc[1] + randint(-10, 10) / 100, 4), round(loc[2] + randint(-10, 10), 4)) names = [ name.strip() for name in open(TLE_FILE).read().split("\n")[0::3] ] matches = difflib.get_close_matches(sat_name.upper(), names) if len(matches) == 0: await message.channel.send( "Error: Failed to find satellite") return sat_name = matches[0] #find the tle for the specifed sat in the tle file tle = find_sat_in_tle(sat_name, TLE_FILE) tf = TimezoneFinder() tz = tf.timezone_at(lat=loc[0], lng=loc[1]) utc_offset = datetime.now(pytz.timezone(tz)).strftime("%z") #predict the passes and add them to a list p = predict.transits(tle, (loc[0], loc[1] * -1, loc[2])) passes = [] for i in range(pass_count): transit = next(p) #while transit.peak()["elevation"] < 20: # transit = next(p) aos = round(transit.start + randint(-30, 30)) tca = round(transit.peak()["epoch"] + randint(-30, 30)) los = round(transit.end + randint(-30, 30)) #get map image url url = "" if pass_count == 1: start = predict.observe(tle, loc, at=aos) middle = predict.observe(tle, loc, at=tca) end = predict.observe(tle, loc, at=los) url = "https://www.mapquestapi.com/staticmap/v5/map?start={},{}&end={},{}&locations={},{}&size=600,400@2x&key={}&routeArc=true&format=jpg70&zoom=3".format( start["latitude"], start["longitude"] - 360, end["latitude"], end["longitude"] - 360, middle["latitude"], middle["longitude"] - 360, mapquest_key) data = requests.get(url).content with open("temp-map.jpg", "wb") as image: image.write(data) passes.append({ "satellite": sat_name, "start": aos, "middle": tca, "end": los, "url": url, "peak_elevation": round( transit.peak()['elevation'] + (randint(-20, 20) / 10), 1), "duration": round(transit.duration()), "azimuth": round( transit.at(transit.start)['azimuth'] + (randint(-20, 20) / 10), 1) }) #respond with an embeded message image_file = None response = discord.Embed( title=sat_name + " passes over {} [UTC{}]".format(str(loc), utc_offset)) for ps in passes: if ps["url"] != "": image_file = discord.File("temp-map.jpg", filename="map.jpg") response.set_image(url="attachment://map.jpg") delta = datetime.utcfromtimestamp( ps['start']) - datetime.utcnow() hours, minutes = divmod(delta.seconds / 60, 60) response.add_field( name=datetime.utcfromtimestamp(ps['start']).strftime( "%B %-d, %Y at %-H:%M:%S UTC") + " (in {} hours and {} minutes)".format( round(hours), round(minutes)), value= "Peak Elevation: {}\nDuration: {}\nAzimuth: {}\nEnd: {}" .format( ps['peak_elevation'], ps['duration'], ps['azimuth'], datetime.utcfromtimestamp(ps['end']).strftime( "%B %-d, %Y at %-H:%M:%S UTC")), inline=False) await message.channel.send(file=image_file, embed=response) if os.path.isfile("temp-map.jpg"): os.remove("temp-map.jpg") except Exception as e: await message.channel.send( "Oops! Something went wrong. Use `!predict -h` for help.") print(e)
def transits(self, sat): """Get upcoming transits of a satellite""" return predict.transits(sat.tle, self.predict_qth)
def aoslos(satname, min_elev, min_elev_meteor, station_lat, station_lon, station_alt, tle_file): tle_noaa15 = [] tle_noaa18 = [] tle_noaa19 = [] tle_meteor = [] tlefile = open(str(tle_file)) tledata = tlefile.readlines() tlefile.close() for i, line in enumerate(tledata): if "NOAA 15" in line: for l in tledata[i:i + 3]: tle_noaa15.append(l.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "NOAA 18" in line: for m in tledata[i:i + 3]: tle_noaa18.append(m.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "NOAA 19" in line: for n in tledata[i:i + 3]: tle_noaa19.append(n.strip('\r\n').rstrip()), for i, line in enumerate(tledata): if "METEOR-M 2" in line: for n in tledata[i:i + 3]: tle_meteor.append(n.strip('\r\n').rstrip()), qth = (float(station_lat), float(station_lon), float(station_alt)) min_elev = int(min_elev) min_elev_meteor = int(min_elev_meteor) # Recording delay delay = '1' # delay meteor to ~12° - 15° meteor_delay = '180' # Recording short short = '1' # Shorten meteor recording by ~12° - 15° meteor_short = '180' # Predicting if satname in "NOAA 15": p = predict.transits(tle_noaa15, qth) for i in range(1, 20): transit = p.next() aos_start = int(transit.start) + int(delay) aos_time = int(transit.duration()) - (int(short) + int(delay)) aos_end = int(aos_start) + int(aos_time) if int(transit.peak()['elevation']) >= min_elev: return int(aos_start), int(aos_end), int(aos_time), \ int(transit.peak()['elevation']), transit, tle_noaa15 elif satname in "NOAA 18": p = predict.transits(tle_noaa18, qth) for i in range(1, 20): transit = p.next() aos_start = int(transit.start) + int(delay) aos_time = int(transit.duration()) - (int(short) + int(delay)) aos_end = int(aos_start) + int(aos_time) if int(transit.peak()['elevation']) >= min_elev: return int(aos_start), int(aos_end), int(aos_time), \ int(transit.peak()['elevation']), transit, tle_noaa18 elif satname in "NOAA 19": p = predict.transits(tle_noaa19, qth) for i in range(1, 20): transit = p.next() aos_start = int(transit.start) + int(delay) aos_time = int(transit.duration()) - (int(short) + int(delay)) aos_end = int(aos_start) + int(aos_time) if int(transit.peak()['elevation']) >= min_elev: return int(aos_start), int(aos_end), int(aos_time), \ int(transit.peak()['elevation']), transit, tle_noaa19 elif satname in "METEOR-M 2": p = predict.transits(tle_meteor, qth) for i in range(1, 20): transit = p.next() aos_start = int(transit.start) + int(meteor_delay) aos_time = int( transit.duration()) - (int(meteor_short) + int(meteor_delay)) aos_end = int(aos_start) + int(aos_time) if int(transit.peak()['elevation']) >= min_elev_meteor: return int(aos_start), int(aos_end), int(aos_time), \ int(transit.peak()['elevation']), transit, tle_meteor else: print "NO TLE DEFINED FOR " + satname + " BAILING OUT"
def get_future_passes(self, after=time.time(), pass_count=1): '''Returns a list of Pass objects of the next scheduled pass(es).''' global status #status = "Calculating future passes" if after == None: after = time.time() if pass_count == None: pass_count = 1 # download a new tle file if needed if time.time( ) - self.tle_updated_time > self.tle_update_frequency * 3600: utils.download_tle() self.tle_updated_time = time.time() utils.log("Calculating transits") predictors = {} # go over overy satellite specified for satellite in self.satellites: satellite = self.satellites[satellite] # store the specified minimum elevation and the transits iterator in a dict predictors[satellite["name"]] = { "minimum elevation": satellite["minimum elevation"], "transits": predict.transits(utils.parse_tle(local_path / "active.tle", satellite["name"]), self.loc, ending_after=after) } # get the first pass of every predictor first_passes = [] for predictor in predictors: predictor = predictors[predictor] # get the first pass above the minimum elevation and that starts after the specified time first_pass = next(predictor["transits"]) while predictor["minimum elevation"] > first_pass.peak( )["elevation"] or first_pass.start < after: first_pass = next(predictor["transits"]) # parse information from the pass and add it to the list first_passes.append(utils.parse_pass_info(first_pass)) # sort the passes by their start time first_passes.sort(key=lambda x: x["aos"]) passes = [] # go over the first passes i = 1 while i < len(first_passes) and len(passes) < pass_count: p = first_passes[i] if first_passes[0]["los"] > p["aos"]: # calculate the priorities (max elevation + preset priority) (higher elevation passes have more priority) priority1 = first_passes[0]["max_elevation"] + first_passes[0][ "priority"] priority2 = p["max_elevation"] + p["priority"] # keep the pass with highest priority if priority1 >= priority2: # calculate the next pass above the minimum elevation next_pass = next(predictors[p["satellite"]]["transits"]) while predictors[p["satellite"]][ "minimum elevation"] > next_pass.peak( )["elevation"] or next_pass.start < after: next_pass = next( predictors[p["satellite"]]["transits"]) # replace the pass in the list first_passes[i] = utils.parse_pass_info(next_pass) elif priority2 > priority1: # calculate the next pass above the minimum elevation next_pass = next( predictors[first_passes[0]["satellite"]]["transits"]) while predictors[first_passes[0]["satellite"]][ "minimum elevation"] > next_pass.peak( )["elevation"] or next_pass.start < after: next_pass = next(predictors[first_passes[0] ["satellite"]]["transits"]) # replace the pass in the list first_passes[0] = utils.parse_pass_info(next_pass) # re-sort the list by their start time first_passes.sort(key=lambda x: x["aos"]) # reset the counter i = 1 else: i += 1 # if we gone through all the first_passes list (found a good pass) if i >= len(first_passes): # add the pass the final passes list passes.append(first_passes[0]) # calculate the next pass above the minimum elevation next_pass = next( predictors[first_passes[0]["satellite"]]["transits"]) while predictors[first_passes[ 0]["satellite"]]["minimum elevation"] > next_pass.peak( )["elevation"] or next_pass.start < after: next_pass = next( predictors[first_passes[0]["satellite"]]["transits"]) # replace the pass in the list first_passes[0] = utils.parse_pass_info(next_pass) # re-sort the list by their start time first_passes.sort(key=lambda x: x["aos"]) # reset the counter i = 1 # return the first pass in the list return [Pass(p) for p in passes]
def genPassTable(howmany=20): '''generate a table with pass list, sorted''' passTable = {} for satellite in satellites: tleData = getTleData(satellite) priority = satellitesData[satellite]['priority'] if tleData: # if tle data was there in the file :: SATELLITES czasStart = time.time() p = predict.transits(tleData, qth, czasStart) for i in range(1, howmany): transit = p.next() # transitEnd = transit.start + transit.duration() - skipLast if not time.time() > transit.start + transit.duration( ) - skipLast - 1: # esttimate the end of the transit, minus last 10 seconds if int(transit.peak()['elevation']) >= minElev: passTable[transit.start] = [ satellite, int(transit.start + skipFirst), int(transit.duration() - skipFirst - skipLast), int(transit.peak()['elevation']), int(transit.peak()['azimuth']), priority ] # transit.start - unix timestamp else: # fixed time recording # cron = getFixedRecordingTime(satellite)["fixedTime"] cron = satellitesData[satellite]['fixedTime'] duration = getFixedRecordingTime(satellite)["fixedDuration"] delta = 0 for i in range(0, howmany): entry = CronTab(cron).next(now=time.time() + delta, default_utc=False) delta += entry start = delta + time.time() passTable[start] = [ satellite, int(start), int(duration), '0', '0', priority ] # Sort pass table passTableSorted = [] for start in sorted(passTable): passTableSorted.append(passTable[start]) # Clean the pass table according to the priority. If any pass overlaps, # remove one with less priority (lower priority number). passTableSortedPrioritized = passTableSorted[:] passCount = len(passTableSorted) for i in range(0, passCount - 1): # -1 or -2 :BUG? satelliteI, startI, durationI, peakI, azimuthI, priorityI = passTableSorted[ i] satelliteJ, startJ, durationJ, peakJ, azimuthJ, priorityJ = passTableSorted[ i + 1] endTimeI = startI + durationI if priorityI != priorityJ: if (startJ + priorityTimeMargin < endTimeI): # print "End pass:"******"--- Start # time:", satelliteJ, t2human(startJ) if priorityJ < priorityI: print " 1. discard %s, keep %s" % (satelliteI, satelliteJ) passTableSortedPrioritized[i] = '' elif priorityJ > priorityI: print " 2. discard %s, keep %s" % (satelliteJ, satelliteI) passTableSortedPrioritized[i + 1] = '' # let's clean the table and remove empty (removed) records # and remove the priority record, it will not be useful later -- x[:5] passTableSortedPrioritized = [ x[:5] for x in passTableSortedPrioritized if x != '' ] # pp.pprint(passTableSortedPrioritized) return passTableSortedPrioritized
freq = "436.795" elif sat == "LILACSAT-2": freq = "437.200 " elif sat == "IO-86": freq = "435.880" elif sat == "ISS": freq = "145.800" #Two elements data from any satellite or object tle = "%s\n%s%s" % (sat, tle1, tle2) #Latitude longitude in degress print "Buscando para %s %s %s" % (lat.rstrip(), longitude.rstrip(), alt.rstrip()) qth = (lat.rstrip(), longitude.rstrip(), alt.rstrip() ) # lat (N), long (W), alt (meters) p = predict.transits(tle, qth) for i in range(1, 2): transit = p.next() ts = int(transit.start) #Start two minutes before ts = ts - 120 #print(datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')) #print(datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')) day = datetime.fromtimestamp(ts).strftime('%Y-%m-%d') hour = datetime.fromtimestamp(ts).strftime('%H:%M') tmpduration = str(transit.duration()).split(".") # Add an extra minute to recording to ensure all conversation will be captured duration = int(tmpduration[0]) + 180 commandline = "/bin/echo './recordfm.sh %s %s %s' | at %s %s" % (