def get_next_passes(satellites, utctime, forward, coords, tle_file=None, aqua_terra_dumps=None): """Get the next passes for *satellites*, starting at *utctime*, for a duration of *forward* hours, with observer at *coords* ie lon (°E), lat (°N), altitude (km). Uses *tle_file* if provided, downloads from celestrack otherwise. Metop-A, Terra and Aqua need special treatment due to downlink restrictions. """ passes = {} if tle_file is None and 'TLES' not in os.environ: fp_, tle_file = mkstemp(prefix="tle", dir="/tmp") os.close(fp_) logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) if not os.path.exists(tle_file) and 'TLES' not in os.environ: logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) for sat in satellites: if not hasattr(sat, 'name'): from trollsched.schedule import Satellite sat = Satellite(sat, 0, 0) satorb = orbital.Orbital(sat.name, tle_file=tle_file) passlist = satorb.get_next_passes(utctime, forward, *coords) if sat.name == "metop-a": # Take care of metop-a passes["metop-a"] = get_metopa_passes(sat, passlist, satorb) elif sat.name in ["aqua", "terra"] and aqua_terra_dumps: # Take care of aqua (dumps in svalbard and poker flat) # Get the Terra/Aqua passes and fill the passes dict: get_terra_aqua_passes(passes, utctime, forward, sat, passlist, satorb, aqua_terra_dumps) else: if sat.name.upper() in VIIRS_PLATFORM_NAMES: instrument = "viirs" elif sat.name.lower().startswith("metop") or sat.name.lower().startswith("noaa"): instrument = "avhrr" elif sat.name.upper() in MERSI2_PLATFORM_NAMES: instrument = "mersi2" else: instrument = "unknown" passes[sat.name] = [ Pass(sat, rtime, ftime, orb=satorb, uptime=uptime, instrument=instrument) for rtime, ftime, uptime in passlist if ftime - rtime > timedelta(minutes=MIN_PASS) ] return set(fctools_reduce(operator.concat, list(passes.values())))
def update(self, urls): """fetch supplied list of urls into tle.txt""" tlefile.fetch('/home/stacstation/eclipse-workspace/tle.txt', urls) """create separate tle file for each satellite in tle.txt""" file = open('/home/stacstation/eclipse-workspace/tle.txt') buffer = [] i = 0 for line in file: buffer.append(line) i += 1 if i == 3: fileout = open( '/home/stacstation/eclipse-workspace/%s.txt' % (buffer[0].strip()), "w") for item in buffer: fileout.write(item) i = 0 buffer = []
def lambda_handler(event, context): tle_path = '/tmp/tle' now = datetime.utcnow() with open('./awesome_satellites.json') as file_data: awesome_satellites = json.load(file_data) tlefile.fetch(tle_path) for satellite in awesome_satellites: sat_orbital = orbital.Orbital(satellite['name'], tle_file=tle_path) next_passes = sat_orbital.get_next_passes(now, 24, event['lon'], event['lat'], event['alt']) for next_pass in next_passes: (start, end, maximum) = next_pass publish_sns({ 'satellite': satellite, 'pass_begin': start.isoformat(), 'pass_end': end.isoformat() })
def get_next_passes(satellites, utctime, forward, coords, tle_file=None, aqua_terra_dumps=None, min_pass=MIN_PASS, local_horizon=0): """Get the next passes for *satellites*, starting at *utctime*, for a duration of *forward* hours, with observer at *coords* ie lon (°E), lat (°N), altitude (km). Uses *tle_file* if provided, downloads from celestrack otherwise. Metop-A, Terra and Aqua need special treatment due to downlink restrictions. """ passes = {} if tle_file is None and 'TLES' not in os.environ: fp_, tle_file = mkstemp(prefix="tle", dir="/tmp") os.close(fp_) logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) if not os.path.exists(tle_file) and 'TLES' not in os.environ: logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) for sat in satellites: if not hasattr(sat, 'name'): from trollsched.schedule import Satellite sat = Satellite(sat, 0, 0) satorb = orbital.Orbital(sat.name, tle_file=tle_file) passlist = satorb.get_next_passes(utctime, forward, horizon=local_horizon, *coords) if sat.name.lower() == "metop-a": # Take care of metop-a special case passes["metop-a"] = get_metopa_passes(sat, passlist, satorb) elif sat.name.lower() in ["aqua", "terra"] and aqua_terra_dumps: # Take care of aqua (dumps in svalbard and poker flat) # Get the Terra/Aqua passes and fill the passes dict: get_terra_aqua_passes(passes, utctime, forward, sat, passlist, satorb, aqua_terra_dumps) else: if sat.name.upper() in VIIRS_PLATFORM_NAMES: instrument = "viirs" elif sat.name.lower().startswith( "metop") or sat.name.lower().startswith("noaa"): instrument = "avhrr" elif sat.name.lower() in ["aqua", "terra"]: # when aqua_terra_dumps=False instrument = "modis" elif sat.name.upper() in MERSI_PLATFORM_NAMES: instrument = "mersi" elif sat.name.upper() in MERSI2_PLATFORM_NAMES: instrument = "mersi-2" else: instrument = "unknown" passes[sat.name] = [ Pass(sat, rtime, ftime, orb=satorb, uptime=uptime, instrument=instrument) for rtime, ftime, uptime in passlist if ftime - rtime > timedelta(minutes=MIN_PASS) ] return set(fctools_reduce(operator.concat, list(passes.values())))
def get_next_passes(satellites, utctime, forward, coords, tle_file=None): """Get the next passes for *satellites*, starting at *utctime*, for a duration of *forward* hours, with observer at *coords* ie lon (°E), lat (°N), altitude (km). Uses *tle_file* if provided, downloads from celestrack otherwise. """ passes = {} orbitals = {} if tle_file is None: fp_, tle_file = mkstemp(prefix="tle", dir="/tmp") os.close(fp_) logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) if not os.path.exists(tle_file): logger.info("Fetch tle info from internet") tlefile.fetch(tle_file) for sat in satellites: satorb = orbital.Orbital(sat, tle_file=tle_file) orbitals[sat] = satorb passlist = satorb.get_next_passes(utctime, forward, *coords) if sat.lower().startswith("metop") or sat.lower().startswith("noaa"): instrument = "avhrr" elif sat in ["aqua", "terra"]: instrument = "modis" elif sat.endswith("npp"): instrument = "viirs" else: instrument = "unknown" # take care of metop-a if sat == "metop-a": metop_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist if rtime < ftime] passes["metop-a"] = [] for overpass in metop_passes: if overpass.pass_direction() == "descending": new_rise = overpass.slsearch(60) if new_rise is not None and new_rise < overpass.falltime: overpass.risetime = new_rise overpass.boundary = SwathBoundary(overpass) if overpass.seconds() > MIN_PASS * 60: passes["metop-a"].append(overpass) # take care of aqua (dumps in svalbard and poker flat) elif sat == "aqua": wpcoords = (-75.457222, 37.938611, 0) passlist_wp = satorb.get_next_passes(utctime - timedelta(minutes=30), forward + 1, *wpcoords) wp_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist_wp if rtime < ftime] svcoords = (15.399, 78.228, 0) passlist_sv = satorb.get_next_passes(utctime - timedelta(minutes=30), forward + 1, *svcoords) sv_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist_sv if rtime < ftime] pfcoords = (-147.43, 65.12, 0.51) passlist_pf = satorb.get_next_passes(utctime - timedelta(minutes=30), forward + 1, *pfcoords) pf_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist_pf if rtime < ftime] aqua_passes = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist if rtime < ftime] dumps = get_aqua_dumps_from_ftp(utctime - timedelta(minutes=30), utctime + timedelta(hours=forward + 0.5), satorb) # remove the known dumps for dump in dumps: # print "*", dump.station, dump, dump.max_elev logger.debug("dump from ftp: " + str((dump.station, dump, dump.max_elev))) for i, sv_pass in enumerate(sv_passes): if sv_pass.overlaps(dump, timedelta(minutes=40)): sv_elevation = sv_pass.orb.get_observer_look(sv_pass.uptime, *svcoords)[1] logger.debug("Computed " + str(("SG", sv_pass, sv_elevation))) del sv_passes[i] for i, pf_pass in enumerate(pf_passes): if pf_pass.overlaps(dump, timedelta(minutes=40)): pf_elevation = pf_pass.orb.get_observer_look(pf_pass.uptime, *pfcoords)[1] logger.debug("Computed " + str(("PF", pf_pass, pf_elevation))) del pf_passes[i] for i, wp_pass in enumerate(wp_passes): if wp_pass.overlaps(dump, timedelta(minutes=40)): wp_elevation = wp_pass.orb.get_observer_look(wp_pass.uptime, *wpcoords)[1] logger.debug("Computed " + str(("WP", wp_pass, wp_elevation))) del wp_passes[i] # sort out dump passes first # between sv an pf, we take the one with the highest elevation if # pf < 20°, pf otherwise # I think wp is also used if sv is the only other alternative used_pf = [] for sv_pass in sv_passes: found_pass = False for pf_pass in pf_passes: if sv_pass.overlaps(pf_pass): found_pass = True used_pf.append(pf_pass) sv_elevation = sv_pass.orb.get_observer_look(sv_pass.uptime, *svcoords)[1] pf_elevation = pf_pass.orb.get_observer_look(pf_pass.uptime, *pfcoords)[1] if pf_elevation > 20: dumps.append(pf_pass) elif sv_elevation > pf_elevation: dumps.append(sv_pass) else: dumps.append(pf_pass) break if not found_pass: dumps.append(sv_pass) for pf_pass in pf_passes: if pf_pass not in used_pf: dumps.append(pf_pass) passes["aqua"] = [] for overpass in aqua_passes: add = True for dump_pass in dumps: if dump_pass.overlaps(overpass): if (dump_pass.uptime < overpass.uptime and dump_pass.falltime > overpass.risetime): logger.debug("adjusting " + str(overpass) + " to new risetime " + str(dump_pass.falltime)) overpass.risetime = dump_pass.falltime overpass.boundary = SwathBoundary(overpass) elif (dump_pass.uptime >= overpass.uptime and dump_pass.risetime < overpass.falltime): logger.debug("adjusting " + str(overpass) + " to new falltime " + str(dump_pass.risetime)) overpass.falltime = dump_pass.risetime overpass.boundary = SwathBoundary(overpass) if overpass.falltime <= overpass.risetime: add = False logger.debug("skipping " + str(overpass)) if add and overpass.seconds() > MIN_PASS * 60: passes["aqua"].append(overpass) else: passes[sat] = [Pass(sat, rtime, ftime, satorb, uptime, instrument) for rtime, ftime, uptime in passlist if ftime - rtime > timedelta(minutes=MIN_PASS)] return set(reduce(operator.concat, passes.values()))
def updateTLEfromNet(self): tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/argos.txt", ) tlefile.fetch("TLE/argos.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/cubesat.txt", ) tlefile.fetch("TLE/cubesat.txt") tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/dmc.txt", ) tlefile.fetch("TLE/dmc.txt") tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/goes.txt", ) tlefile.fetch("TLE/goes.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/intelsat.txt", ) tlefile.fetch("TLE/intelsat.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/iridium.txt", ) tlefile.fetch("TLE/iridium.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/iridium-NEXT.txt", ) tlefile.fetch("TLE/iridium-NEXT.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/molniya.txt", ) tlefile.fetch("TLE/molniya.txt") tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/noaa.txt", ) tlefile.fetch("TLE/noaa.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/planet.txt", ) tlefile.fetch("TLE/planet.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/resource.txt", ) tlefile.fetch("TLE/resource.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/sarsat.txt", ) tlefile.fetch("TLE/sarsat.txt") tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/spire.txt", ) tlefile.fetch("TLE/spire.txt") tlefile.TLE_URLS = ("https://celestrak.com/NORAD/elements/tdrss.txt", ) tlefile.fetch("TLE/tdrss.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/tle-new.txt", ) tlefile.fetch("TLE/tle-new.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/visual.txt", ) tlefile.fetch("TLE/visual.txt") tlefile.TLE_URLS = ( "https://celestrak.com/NORAD/elements/weather.txt", ) tlefile.fetch("TLE/weather.txt")