From 5b36c2385551563c702f6fc36cd1022feb01f160 Mon Sep 17 00:00:00 2001 From: Cees Bassa Date: Fri, 30 Nov 2018 15:40:18 +0100 Subject: [PATCH] Fix PEP8 styling issues --- schedule_single_station.py | 294 +++++++++++++++++++++++++------------ 1 file changed, 202 insertions(+), 92 deletions(-) diff --git a/schedule_single_station.py b/schedule_single_station.py index 996f469..42762cc 100755 --- a/schedule_single_station.py +++ b/schedule_single_station.py @@ -13,6 +13,7 @@ import glob import lxml.html import argparse + class twolineelement: """TLE class""" @@ -22,11 +23,11 @@ class twolineelement: self.tle0 = tle0 self.tle1 = tle1 self.tle2 = tle2 - if tle0[:2]=="0 ": + if tle0[:2] == "0 ": self.name = tle0[2:] else: self.name = tle0 - if tle1.split(" ")[1]=="": + if tle1.split(" ")[1] == "": self.id = int(tle1.split(" ")[2][:4]) else: self.id = int(tle1.split(" ")[1][:5]) @@ -48,6 +49,7 @@ class satellite: self.good_count = good_count self.data_count = data_count + def get_scheduled_passes_from_network(ground_station, tmin, tmax): # Get first page client = requests.session() @@ -55,61 +57,75 @@ def get_scheduled_passes_from_network(ground_station, tmin, tmax): # Loop start = True scheduledpasses = [] - + while True: if start: - r = client.get("https://network.satnogs.org/api/observations/?ground_station=%d"%ground_station) + r = client.get( + "https://network.satnogs.org/api/observations/?ground_station=%d" % + ground_station) start = False else: nextpage = r.links.get("next") r = client.get(nextpage["url"]) - + # r.json() is a list of dicts for o in r.json(): - satpass = {"id": o['norad_cat_id'], - "tr": datetime.strptime(o['start'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S"), - "ts": datetime.strptime(o['end'].replace("Z", ""), "%Y-%m-%dT%H:%M:%S"), - "scheduled": True} + satpass = { + "id": o['norad_cat_id'], + "tr": datetime.strptime( + o['start'].replace( + "Z", + ""), + "%Y-%m-%dT%H:%M:%S"), + "ts": datetime.strptime( + o['end'].replace( + "Z", + ""), + "%Y-%m-%dT%H:%M:%S"), + "scheduled": True} - if satpass['ts']>tmin and satpass['tr'] tmin and satpass['tr'] < tmax: scheduledpasses.append(satpass) - if satpass['ts']=scheduledpass['tr'] and satpass['ts']= scheduledpass['tr'] and satpass['ts'] < scheduledpass['ts']: overlap = True # Scheduled pass falls within test pass - elif scheduledpass['tr']>=satpass['tr'] and scheduledpass['ts']= satpass['tr'] and scheduledpass['ts'] < satpass['ts']: overlap = True # Pass start falls within pass - elif satpass['tr']>=scheduledpass['tr'] and satpass['tr']= scheduledpass['tr'] and satpass['tr'] < scheduledpass['ts']: overlap = True # Pass end falls within end - elif satpass['ts']>=scheduledpass['tr'] and satpass['ts']= scheduledpass['tr'] and satpass['ts'] < scheduledpass['ts']: overlap = True - if overlap == True: + if overlap: break - + return overlap - + + def ordered_scheduler(passes, scheduledpasses): """Loop through a list of ordered passes and schedule each next one that fits""" # Loop over passes for satpass in passes: # Schedule if there is no overlap with already scheduled passes - if overlap(satpass, scheduledpasses)==False: + if not overlap(satpass, scheduledpasses): scheduledpasses.append(satpass) - + return scheduledpasses + def random_scheduler(passes, scheduledpasses): """Schedule passes based on random ordering""" # Shuffle passes @@ -117,24 +133,29 @@ def random_scheduler(passes, scheduledpasses): return ordered_scheduler(passes, scheduledpasses) + def efficiency(passes): # Loop over passes start = False for satpass in passes: - if start==False: - dt = satpass['ts']-satpass['tr'] + if not start: + dt = satpass['ts'] - satpass['tr'] tmin = satpass['tr'] tmax = satpass['ts'] start = True else: - dt += satpass['ts']-satpass['tr'] - if satpass['tr']tmax: tmax=satpass['ts'] + dt += satpass['ts'] - satpass['tr'] + if satpass['tr'] < tmin: + tmin = satpass['tr'] + if satpass['ts'] > tmax: + tmax = satpass['ts'] # Total time covered - dttot = tmax-tmin - - return dt.total_seconds(),dttot.total_seconds(), dt.total_seconds()/dttot.total_seconds() + dttot = tmax - tmin + + return dt.total_seconds(), dttot.total_seconds( + ), dt.total_seconds() / dttot.total_seconds() + def find_passes(satellites, observer, tmin, tmax, minimum_altitude): # Loop over satellites @@ -143,7 +164,7 @@ def find_passes(satellites, observer, tmin, tmax, minimum_altitude): for satellite in satellites: # Set start time observer.date = ephem.date(tmin) - + # Load TLE try: sat_ephem = ephem.readtle(str(satellite.tle0), @@ -204,12 +225,14 @@ def find_passes(satellites, observer, tmin, tmax, minimum_altitude): 'data_count': satellite.data_count, 'scheduled': False} passes.append(satpass) - observer.date = ephem.Date(ts).datetime() + timedelta(minutes=1) + observer.date = ephem.Date( + ts).datetime() + timedelta(minutes=1) else: keep_digging = False return passes + def get_groundstation_info(ground_station_id): # Get first page client = requests.session() @@ -242,6 +265,7 @@ def get_groundstation_info(ground_station_id): else: return {} + def get_active_transmitter_info(fmin, fmax): # Open session client = requests.session() @@ -250,13 +274,14 @@ def get_active_transmitter_info(fmin, fmax): # Loop transmitters = [] for o in r.json(): - if o["alive"] and o["downlink_low"]>fmin and o["downlink_low"]<=fmax: + if o["alive"] and o["downlink_low"] > fmin and o["downlink_low"] <= fmax: transmitter = {"norad_cat_id": o["norad_cat_id"], "uuid": o["uuid"]} transmitters.append(transmitter) return transmitters + def get_last_update(fname): try: fp = open(fname, "r") @@ -267,22 +292,31 @@ def get_last_update(fname): return None -def schedule_observation(username, password, norad_cat_id, uuid, ground_station_id, starttime, endtime): - loginUrl = "https://network.satnogs.org/accounts/login/" #login URL +def schedule_observation( + username, + password, + norad_cat_id, + uuid, + ground_station_id, + starttime, + endtime): + loginUrl = "https://network.satnogs.org/accounts/login/" # login URL session = requests.session() - login = session.get(loginUrl) #Get login page for CSFR token + login = session.get(loginUrl) # Get login page for CSFR token login_html = lxml.html.fromstring(login.text) - login_hidden_inputs = login_html.xpath(r'//form//input[@type="hidden"]') #Get CSFR token + login_hidden_inputs = login_html.xpath( + r'//form//input[@type="hidden"]') # Get CSFR token form = {x.attrib["name"]: x.attrib["value"] for x in login_hidden_inputs} - form["login"] = username + form["login"] = username form["password"] = password - session.post(loginUrl, data=form, headers={'referer':loginUrl}) #Login - - obsURL = "https://network.satnogs.org/observations/new/" #Observation URL - obs = session.get(obsURL) #Get the observation/new/ page to get the CSFR token - obs_html = lxml.html.fromstring(obs.text) + session.post(loginUrl, data=form, headers={'referer': loginUrl}) # Login + + obsURL = "https://network.satnogs.org/observations/new/" # Observation URL + # Get the observation/new/ page to get the CSFR token + obs = session.get(obsURL) + obs_html = lxml.html.fromstring(obs.text) hidden_inputs = obs_html.xpath(r'//form//input[@type="hidden"]') - form = {x.attrib["name"]: x.attrib["value"] for x in hidden_inputs} + form = {x.attrib["name"]: x.attrib["value"] for x in hidden_inputs} form["satellite"] = norad_cat_id form["transmitter"] = uuid form["start-time"] = starttime @@ -291,34 +325,51 @@ def schedule_observation(username, password, norad_cat_id, uuid, ground_station_ form["0-ending_time"] = endtime form["0-station"] = ground_station_id form["total"] = str(1) - session.post(obsURL, data=form, headers={'referer':obsURL}) + session.post(obsURL, data=form, headers={'referer': obsURL}) + def get_transmitter_success_rate(norad, uuid): - transmitters = requests.get("https://network.satnogs.org/transmitters/"+str(norad)).json()["transmitters"] + transmitters = requests.get( + "https://network.satnogs.org/transmitters/" + + str(norad)).json()["transmitters"] success_rate = 0 good_count = 0 data_count = 0 for transmitter in transmitters: - if transmitter["uuid"]==uuid: + if transmitter["uuid"] == uuid: success_rate = transmitter["success_rate"] good_count = transmitter["good_count"] data_count = transmitter["data_count"] break - + return success_rate, good_count, data_count - + + if __name__ == "__main__": # Parse arguments - parser = argparse.ArgumentParser(description="Automatically schedule observations on a SatNOGS station.") + parser = argparse.ArgumentParser( + description="Automatically schedule observations on a SatNOGS station.") parser.add_argument("-s", "--station", help="Ground station ID", type=int) - parser.add_argument("-t", "--starttime", help="Start time (YYYY-MM-DD HH:MM:SS) [default: now]", - default=datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")) - parser.add_argument("-d", "--duration", help="Duration to schedule [hours]", type=int, default=1) + parser.add_argument( + "-t", + "--starttime", + help="Start time (YYYY-MM-DD HH:MM:SS) [default: now]", + default=datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")) + parser.add_argument( + "-d", + "--duration", + help="Duration to schedule [hours]", + type=int, + default=1) parser.add_argument("-u", "--username", help="SatNOGS username") parser.add_argument("-p", "--password", help="SatNOGS password") - parser.add_argument("-n", "--dryrun", help="Dry run (do not schedule passes)", action="store_true") + parser.add_argument( + "-n", + "--dryrun", + help="Dry run (do not schedule passes)", + action="store_true") args = parser.parse_args() - + # Settings ground_station_id = args.station length_hours = args.duration @@ -331,7 +382,7 @@ if __name__ == "__main__": # Set time range tnow = datetime.strptime(args.starttime, "%Y-%m-%dT%H:%M:%S") tmin = tnow - tmax = tnow+timedelta(hours=length_hours) + tmax = tnow + timedelta(hours=length_hours) # Get ground station information ground_station = get_groundstation_info(ground_station_id) @@ -341,49 +392,81 @@ if __name__ == "__main__": os.mkdir(cache_dir) # Get last update - tlast = get_last_update(os.path.join(cache_dir, "last_update_%d.txt"%ground_station_id)) + tlast = get_last_update( + os.path.join( + cache_dir, + "last_update_%d.txt" % + ground_station_id)) # Update logic update = False - if tlast==None or (tnow-tlast).total_seconds()>data_age_hours*3600: + if tlast is None or (tnow - tlast).total_seconds() > data_age_hours * 3600: update = True - if not os.path.isfile(os.path.join(cache_dir, "transmitters_%d.txt"%ground_station_id)): + if not os.path.isfile( + os.path.join( + cache_dir, + "transmitters_%d.txt" % + ground_station_id)): update = True - if not os.path.isfile(os.path.join(cache_dir, "tles_%d.txt"%ground_station_id)): + if not os.path.isfile( + os.path.join( + cache_dir, + "tles_%d.txt" % + ground_station_id)): update = True - + # Update if update: # Store current time - with open(os.path.join(cache_dir, "last_update_%d.txt"%ground_station_id), "w") as fp: - fp.write(tnow.strftime("%Y-%m-%dT%H:%M:%S")+"\n") + with open(os.path.join(cache_dir, "last_update_%d.txt" % ground_station_id), "w") as fp: + fp.write(tnow.strftime("%Y-%m-%dT%H:%M:%S") + "\n") # Get active transmitters in frequency range of each antenna transmitters = [] for antenna in ground_station['antenna']: - transmitters.append(get_active_transmitter_info(antenna["frequency"], antenna["frequency_max"])) + transmitters.append( + get_active_transmitter_info( + antenna["frequency"], + antenna["frequency_max"])) transmitters = list(itertools.chain.from_iterable(transmitters)) # Store transmitters - fp = open(os.path.join(cache_dir, "transmitters_%d.txt"%ground_station_id), "w") + fp = open( + os.path.join( + cache_dir, + "transmitters_%d.txt" % + ground_station_id), + "w") for transmitter in transmitters: success_rate, good_count, data_count = get_transmitter_success_rate( transmitter["norad_cat_id"], transmitter["uuid"]) - fp.write("%05d %s %d %d %d\n"%(transmitter["norad_cat_id"], transmitter["uuid"], success_rate, good_count, data_count)) + fp.write( + "%05d %s %d %d %d\n" % + (transmitter["norad_cat_id"], + transmitter["uuid"], + success_rate, + good_count, + data_count)) fp.close() - + # Get NORAD IDs - norad_cat_ids = sorted(set([transmitter["norad_cat_id"] for transmitter in transmitters])) + norad_cat_ids = sorted( + set([transmitter["norad_cat_id"] for transmitter in transmitters])) # Get TLEs tles = fetch_tles(norad_cat_ids) # Store TLEs - fp = open(os.path.join(cache_dir, "tles_%d.txt"%ground_station_id), "w") + fp = open( + os.path.join( + cache_dir, + "tles_%d.txt" % + ground_station_id), + "w") for norad_cat_id, (source, tle) in tles.items(): - fp.write("%s\n%s\n%s\n"%(tle[0], tle[1], tle[2])) + fp.write("%s\n%s\n%s\n" % (tle[0], tle[1], tle[2])) fp.close() - + # Set observer observer = ephem.Observer() observer.lon = str(ground_station['lng']) @@ -392,21 +475,28 @@ if __name__ == "__main__": minimum_altitude = ground_station['min_horizon'] # Read tles - with open(os.path.join(cache_dir, "tles_%d.txt"%ground_station_id), "r") as f: + with open(os.path.join(cache_dir, "tles_%d.txt" % ground_station_id), "r") as f: lines = f.readlines() - tles = [twolineelement(lines[i], lines[i+1], lines[i+2]) + tles = [twolineelement(lines[i], lines[i + 1], lines[i + 2]) for i in range(0, len(lines), 3)] # Read transmitters satellites = [] - with open(os.path.join(cache_dir, "transmitters_%d.txt"%ground_station_id), "r") as f: + with open(os.path.join(cache_dir, "transmitters_%d.txt" % ground_station_id), "r") as f: lines = f.readlines() for line in lines: item = line.split() - norad_cat_id, uuid, success_rate, good_count, data_count = int(item[0]), item[1], float(item[2])/100.0, int(item[3]), int(item[4]) + norad_cat_id, uuid, success_rate, good_count, data_count = int( + item[0]), item[1], float(item[2]) / 100.0, int(item[3]), int(item[4]) for tle in tles: if tle.id == norad_cat_id: - satellites.append(satellite(tle, uuid, success_rate, good_count, data_count)) + satellites.append( + satellite( + tle, + uuid, + success_rate, + good_count, + data_count)) # Find passes passes = find_passes(satellites, observer, tmin, tmax, minimum_altitude) @@ -414,11 +504,14 @@ if __name__ == "__main__": # Priorities # priorities = {"40069": 1.000, "25338": 0.990, "28654": 0.990, "33591": 0.990} priorities = {} - + # List of scheduled passes - scheduledpasses = get_scheduled_passes_from_network(ground_station_id, tmin, tmax) - print("Found %d scheduled passes between %s and %s on ground station %d\n"%(len(scheduledpasses), tmin, tmax, ground_station_id)) - + scheduledpasses = get_scheduled_passes_from_network( + ground_station_id, tmin, tmax) + print( + "Found %d scheduled passes between %s and %s on ground station %d\n" % + (len(scheduledpasses), tmin, tmax, ground_station_id)) + # Get passes of priority objects prioritypasses = [] normalpasses = [] @@ -428,37 +521,54 @@ if __name__ == "__main__": satpass['priority'] = priorities[satpass['id']] prioritypasses.append(satpass) else: - satpass['priority'] = (float(satpass['altt'])/90.0)*satpass['success_rate'] + satpass['priority'] = ( + float(satpass['altt']) / 90.0) * satpass['success_rate'] normalpasses.append(satpass) - + # Priority scheduler - prioritypasses = sorted(prioritypasses, key=lambda satpass: -satpass['priority']) + prioritypasses = sorted( + prioritypasses, + key=lambda satpass: - + satpass['priority']) scheduledpasses = ordered_scheduler(prioritypasses, scheduledpasses) # Random scheduler - normalpasses = sorted(normalpasses, key=lambda satpass: -satpass['priority']) + normalpasses = sorted( + normalpasses, + key=lambda satpass: - + satpass['priority']) scheduledpasses = ordered_scheduler(normalpasses, scheduledpasses) dt, dttot, eff = efficiency(scheduledpasses) - print("%d passes scheduled out of %d, %.0f s out of %.0f s at %.3f%% efficiency"%(len(scheduledpasses), len(passes), dt, dttot, 100*eff)) - + print( + "%d passes scheduled out of %d, %.0f s out of %.0f s at %.3f%% efficiency" % + (len(scheduledpasses), len(passes), dt, dttot, 100 * eff)) + # Find unique objects satids = sorted(set([satpass['id'] for satpass in passes])) for satpass in sorted(scheduledpasses, key=lambda satpass: satpass['tr']): - if satpass['scheduled']==False: - print("%05d %s %s %3.0f %4.3f %s %s"%(int(satpass['id']), satpass['tr'].strftime("%Y-%m-%dT%H:%M:%S"), satpass['ts'].strftime("%Y-%m-%dT%H:%M:%S"), float(satpass['altt']), satpass['priority'], satpass['uuid'], satpass['name'].rstrip())) + if not satpass['scheduled']: + print( + "%05d %s %s %3.0f %4.3f %s %s" % + (int( + satpass['id']), + satpass['tr'].strftime("%Y-%m-%dT%H:%M:%S"), + satpass['ts'].strftime("%Y-%m-%dT%H:%M:%S"), + float( + satpass['altt']), + satpass['priority'], + satpass['uuid'], + satpass['name'].rstrip())) # Schedule passes for satpass in sorted(scheduledpasses, key=lambda satpass: satpass['tr']): - if satpass['scheduled']==False: + if not satpass['scheduled']: if schedule: schedule_observation(username, password, int(satpass['id']), satpass['uuid'], ground_station_id, - satpass['tr'].strftime("%Y-%m-%d %H:%M:%S")+".000", - satpass['ts'].strftime("%Y-%m-%d %H:%M:%S")+".000") - - + satpass['tr'].strftime("%Y-%m-%d %H:%M:%S") + ".000", + satpass['ts'].strftime("%Y-%m-%d %H:%M:%S") + ".000")