def run(aprs_user='******', logfile='main.log', loglevel='INFO'): """Run the aprs client.""" # User input validation if len(aprs_user) < 3 or len(aprs_user) > 9: print('aprs_user must be a string of 3-9 characters.') return if loglevel not in log_levels: print('loglevel must be an element of {}.'.format(log_levels)) return # Enable logging log_handlers = [logging.StreamHandler()] if logfile: log_handlers.append(logging.FileHandler(logfile)) logging.basicConfig(format=logging_formatstr, level=loglevel, handlers=log_handlers) print('Start ogn gateway') client = AprsClient(aprs_user) client.connect() try: client.run(callback=process_beacon, autoreconnect=True) except KeyboardInterrupt: print('\nStop ogn gateway') client.disconnect() logging.shutdown()
def aprs_connect(): """Run the aprs client.""" from ogn.client import AprsClient client = AprsClient("Silent Wings Interface") client.connect() try: client.run(callback=lambda x: print(x), autoreconnect=True) except KeyboardInterrupt: print('\nStop ogn gateway') client.disconnect()
def printout(aprs_filter): """Run the aprs client and just print out the data stream.""" current_app.logger.warning("Start ogn gateway") client = AprsClient(current_app.config['APRS_USER'], aprs_filter=aprs_filter) client.connect() try: client.run(callback=lambda x: print(f"{datetime.utcnow()}: {x}"), autoreconnect=True) except KeyboardInterrupt: current_app.logger.warning("\nStop ogn gateway") client.disconnect()
def run(aprs_user="******"): """Run the aprs client and feed the DB with incoming data.""" # User input validation if len(aprs_user) < 3 or len(aprs_user) > 9: print("aprs_user must be a string of 3-9 characters.") return current_app.logger.warning("Start ogn gateway") client = AprsClient(aprs_user) client.connect() with DbFeeder(prefix='continuous_import', reference_timestamp=datetime.utcnow, reference_timestamp_autoupdate=True) as feeder: try: client.run(callback=lambda x: feeder.add(x), autoreconnect=True) except KeyboardInterrupt: current_app.logger.warning("\nStop ogn gateway") client.disconnect()
def run(aprs_user="******"): """Run the aprs client.""" saver = ContinuousDbFeeder() # User input validation if len(aprs_user) < 3 or len(aprs_user) > 9: print("aprs_user must be a string of 3-9 characters.") return app.logger.warning("Start ogn gateway") client = AprsClient(aprs_user) client.connect() try: client.run(callback=saver.add, autoreconnect=True) except KeyboardInterrupt: app.logger.warning("\nStop ogn gateway") saver.flush() client.disconnect()
def main(): # read the config file config = configparser.ConfigParser() config.read(config_file) # create logger logging.config.fileConfig(config_file) # logging.config.fileConfig(config) logger = logging.getLogger('acph.main') # start ACPH Flights logbook daemon logger.warning( 'ACPH Flights logbook starting with config file = {} (process ID is {}).' .format(config_file, os.getpid())) # load the OGN devices database from a local file or remote server try: if 'logbook' in config and config['logbook']['ognddb'] == 'remote': ogndb = OgnDevicesDatabase.withURL() else: json_filepath = './ogn-devices-ddb.json' ogndb = OgnDevicesDatabase.withJsonFile(json_filepath) except IOError as err: logger.error( "Unable to load OGN devices database. Error is {}".format(err)) sys.exit() # load the airport database from a local file or remotly try: if 'logbook' in config and config['logbook']['acdb'] == 'remote': airports_db = OurAirportsDatabase.withUrl() else: airports_db = OurAirportsDatabase.withCsvFile('.') # Airports DB only with european airports. # listOfAirportsFiltered = airports_db.filterByContinent('EU') # logger.info('After filtering on european airport, size of airport code database is {}'.format(len(listOfAirportsFiltered))) # Airports DB only with french airports. listOfAirportsFiltered = airports_db.filterByCountry('FR') logger.warning( 'After filtering on French airport, size of airport code database is {}' .format(len(listOfAirportsFiltered))) except IOError: logger.exception("File does not exist. Exiting...") sys.exit() # to handle CTRL-C, Kill,.... signal.signal(signal.SIGTERM, handle_exit) # Create the persistence engine to store results on the fly: could be JSON or MySql pdo_engine = FlightLogPDO.factory( config['logbook']['persistence'] if 'logbook' in config else 'JSON') # pdo_engine.open(config_file) pdo_engine.open(config['mysql_connector_python']) # take the opportunity to purge data hold in the persistence engine pdo_engine.purge(config['logbook'].getint('purge')) # start the APRS client if 'aprs' in config: # client = AcphAprsClient(aprs_user=config['aprs']['user'], aprs_passcode=config['aprs']['passcode'], aprs_filter=config['aprs']['filter']) client = AprsClient(aprs_user=config['aprs']['user'], aprs_filter=config['aprs']['filter']) else: client = AprsClient(aprs_user='******') client.connect() # create the ACPH Flight logbook # logbook = FlightsLogBook(receivers_filter={'LFHA', 'LFHP'}) logbook = FlightsLogBook(receivers_filter=None, ogndb=ogndb, airports_db=listOfAirportsFiltered, pdo_engine=pdo_engine) try: client.run(callback=logbook.handleBeacon, autoreconnect=True) except (KeyboardInterrupt, SystemExit): # close the logbook persistent engine logbook.pdo_engine.close() # close the connection to aprs server. client.disconnect() logger.warning('ACPH Flights logbook stopped...')
def db_init(name): db = sqlite3.connect(name) db.execute("CREATE TABLE IF NOT EXISTS positions (id INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT, timestamp INTEGER, reference_timestamp INTEGER, latitude REAL, longitude REAL, climbrate REAL, turnrate REAL, groundspeed REAL, altitude REAL)") db.execute("PRAGMA JOURNAL_MODE=WAL") return db def db_commit(): global commit_counter, db commit_counter+=1 if commit_counter%100==0: print("Commiting DB...") db.commit() db_check_connect() client = AprsClient(aprs_user='******', aprs_filter='r/49.856/15.490/300.0') client.connect() try: client.run(callback=process_beacon, autoreconnect=True) except KeyboardInterrupt: print('\nStop glidernet scraper') db.commit() db.close() client.disconnect()
class ognSkylinesGateway: def forward_aircraft_beacon(self, beacon): try: user = self.session.query(User).filter(User.ogn_address == beacon['address']).one() except (MultipleResultsFound, NoResultFound): return skylines_key = user.skylines_key logger.info("TRACKED {} with key: {}".format(beacon['address'], user.skylines_key_hex)) logger.debug(fix_message_str(beacon)) message = create_fix_message(skylines_key, # NOTE: equivalent is (now - now.replace(hour=0, minute=0, second=0, microsecond=0)).seconds * 1000 (((beacon['timestamp'].hour * 60) + beacon['timestamp'].minute) * 60 + beacon['timestamp'].second) * 1000, beacon['latitude'], beacon['longitude'], beacon['track'], beacon['ground_speed'] / 3.6, 0, int(beacon['altitude']), beacon['climb_rate'], 0) self.socket.sendto(message, self.address) def update_devices_list(self, beacon): try: device = self.session.query(Device).filter(Device.ogn_address == beacon['address']).one() except (MultipleResultsFound, NoResultFound): return device.timestamp = beacon['timestamp'] device.set_location(longitude=beacon['longitude'], latitude=beacon['latitude']) self.session.commit() logger.debug(" {} SEEN AT {}".format(device.ogn_address, device.timestamp)) def process_beacon(self, raw_message): if raw_message[0] == '#': return try: beacon = parse_aprs(raw_message) beacon.update(parse_ogn_beacon(beacon['comment'])) except ParseError as e: logger.error(e.message) return if beacon['beacon_type'] == 'aircraft_beacon': self.forward_aircraft_beacon(beacon) self.update_devices_list(beacon) def __init__(self, session, aprs_user, host, port): self.session = session self.client = AprsClient(aprs_user) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.address = (host, port) def run(self): self.client.connect() self.client.run(callback=self.process_beacon, autoreconnect=True) def disconnect(self): self.client.disconnect()
def run(aprs_filter): """ Run the aprs client, parse the incoming data and put it to redis. """ import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s %(name)-17s %(levelname)-8s %(message)s') current_app.logger.warning("Start ogn gateway") client = AprsClient(current_app.config['APRS_USER'], aprs_filter) client.connect() def insert_into_redis(aprs_string): # Convert aprs_string to message dict, add MGRS Position, flatten gps precision, etc. etc. ... message = aprs_string_to_message(aprs_string) if message is None: return # separate between tables (receiver/sender) and aprs_type (status/position) if message['beacon_type'] in ('aprs_receiver', 'receiver'): if message['aprs_type'] == 'status': redis_target = 'receiver_status' csv_string = receiver_status_message_to_csv_string( message, none_character=r'\N') elif message['aprs_type'] == 'position': redis_target = 'receiver_position' csv_string = receiver_position_message_to_csv_string( message, none_character=r'\N') else: return else: if message['aprs_type'] == 'status': return # no interesting data we want to keep elif message['aprs_type'] == 'position': redis_target = 'sender_position' csv_string = sender_position_message_to_csv_string( message, none_character=r'\N') else: return mapping = {csv_string: str(time.time())} redis_client.zadd(name=redis_target, mapping=mapping, nx=True) insert_into_redis.beacon_counter += 1 current_minute = datetime.utcnow().minute if current_minute != insert_into_redis.last_minute: current_app.logger.info( f"{insert_into_redis.beacon_counter:7d}/min") insert_into_redis.beacon_counter = 0 insert_into_redis.last_minute = current_minute insert_into_redis.beacon_counter = 0 insert_into_redis.last_minute = datetime.utcnow().minute try: client.run(callback=insert_into_redis, autoreconnect=True) except KeyboardInterrupt: current_app.logger.warning("\nStop ogn gateway") client.disconnect()