def setup_connection(self): user = self.config["aprs"]["login"] password = self.config["aprs"]["password"] host = self.config["aprs"].get("host", "rotate.aprs.net") port = self.config["aprs"].get("port", 14580) connected = False backoff = 1 while not connected: try: LOG.info("Creating aprslib client") aprs_client = aprslib.IS(user, passwd=password, host=host, port=port) # Force the logging to be the same aprs_client.logger = LOG aprs_client.connect() connected = True backoff = 1 except Exception as e: LOG.error( "Unable to connect to APRS-IS server. '{}' ".format(e)) time.sleep(backoff) backoff = backoff * 2 continue LOG.debug("Logging in to APRS-IS with user '%s'" % user) return aprs_client
def start(self): self.ais = aprslib.IS("W1XM-RT", host="cwop.mesowest.org", port=30010) self.ais.set_filter("b/" + self.station) self.wx_thread = threading.Thread(target=self._run, name="weather", daemon=True) self.wx_thread.start()
def _consume(self): """Blocking function to receive and parse messages. Note: This function is meant to be started as a separate thread and only exits when StopIteration is raised in the callback. """ # Setup connection. ais = aprslib.IS(self._callsign, host=self._server, port=self._port) if self._aprs_filter: ais.set_filter(self._aprs_filter) ais.connect(blocking=False) # Actually consume APRS packets. self._abort_consume = False self._packet_count = 0 self._consume_start = time.time() if self._db_string: self._db = sqlite3.connect(self._db_string) ais.consumer(self._callback, raw=False, blocking=True, immortal=True) # The above is blocking. This will be called once we're done. self._consumer_thread = None if self._db: self._db.close() self._db = None
def load(self, config, log_handler): """Connects to APRS-IS to get ready for packet upload. Args: config: The related app configuration. log_handler: The log handler for the app. """ self.config = config self.log_handler = log_handler username = self.config.username() password = self.config.password() if not username or not password: self.log_handler.log_warn( 'Username or password for APRS-IS not set, will not be uploading. See README for more info.' ) return host = self.config.host(self.get_name()) self.is_client = aprslib.IS(username, passwd=password, host=host, port=14580) try: self.__is_connect() except LoginError: self.log_handler.log_error( 'Unable to log into APRS-IS with the specified credentials, cannot upload.' ) except ConnectionError: self.log_handler.log_info('Unable to connect to APRS-IS.')
def cli(): """Command Line interface for APRS Cursor-on-Target Gateway.""" parser = argparse.ArgumentParser() parser.add_argument('-d', '--debug', help='Enable debug logging', action='store_true') parser.add_argument('-c', '--callsign', help='callsign', required=True) parser.add_argument('-p', '--passcode', help='passcode', required=True) parser.add_argument('-C', '--cot_host', help='Cursor-on-Target Host', required=True) parser.add_argument('-f', '--aprs_filter', help='APRS Filter', default='m/1000') opts = parser.parse_args() aprs_i = aprslib.IS(opts.callsign, opts.passcode, port=14580) aprs_i.set_filter(opts.aprs_filter) aprscot_i = aprscot.APRSCOT(aprs_i, opts.cot_host) try: aprscot_i.start() while aprscot_i.is_alive(): time.sleep(0.01) except KeyboardInterrupt: aprscot_i.stop() finally: aprscot_i.stop()
def setUp(self): self.ais = aprslib.IS("LZ1DEV-99") self.ais._connected = True self.m = mox.Mox() self.m.StubOutWithMock(self.ais, "_socket_readlines") self.m.StubOutWithMock(self.ais, "_parse") self.m.StubOutWithMock(self.ais, "connect") self.m.StubOutWithMock(self.ais, "close")
def callback(lat,lon,mag): # print(packet) # # a valid passcode for the callsign is required in order to send AIS = aprslib.IS("5B4ANU", passwd="15540", host = "asia.aprs2.net" ,port=14580) AIS.connect() # # send a single status message AIS.sendall("5B4ANU-12>APRS15,WIDE1-1:>""3506.19N/""03321.63E")
def start(): try: aprs = aprslib.IS(call, passwd=passwd) aprs.connect() # send a packet #aprs.sendall("TWITR>APRS,TCPIP*:>Python HamRadioTweets Server Started") #tweet('Python Dev Server Started') aprs.consumer(parse, raw=True) except: start()
def main(): """Main function of aprs2influxdb Reads in configuration values and starts connection to APRS-IS with aprslib. Then two threads are started, one to monitor for APRS-IS packets and another to periodically send status packets to APRS-IS in order to keep the connection alive. """ # Create logger, must be global for functions and threads global logger # Create telemetry dictionary global telemetryDictionary telemetryDictionary = {} # Log to sys.prefix + aprs2influxdb.log log = os.path.join(sys.prefix, "aprs2influxdb.log") logger = createLog(log, args.debug) # Start login for APRS-IS logger.info("Logging into APRS-IS as {0} on port {1}".format( args.callsign, args.port)) if args.callsign == "nocall": logger.warning("APRS-IS ignores the callsign \"nocall\"!") # Open APRS-IS connection passcode = aprslib.passcode(args.callsign) AIS = aprslib.IS(args.callsign, passwd=passcode, port=args.port) # Set aprslib logger equal to aprs2influxdb logger AIS.logger = logger # Connect to APRS-IS servers try: AIS.connect() except aprslib.exceptions.LoginError: # An error occured logger.error('An aprslib LoginError occured', exc_info=True) except aprslib.exceptions.ConnectionError: # An error occured logger.error('An aprslib ConnectionError occured', exc_info=True) # Create heartbeat t1 = threading.Thread(target=heartbeat, args=(AIS, args.callsign, args.interval)) # Create consumer t2 = threading.Thread(target=consumer, args=(AIS, )) # Start threads t1.start() t2.start()
def aprs_connect(self): """connects to APRS""" self.ais = aprslib.IS("N0CALL", "13023", port=14580) self.ais.set_filter("p/KK6GPV") while True: try: self.ais.connect() self.logger.info("Connected to APRS") self.ais.consumer(self.unpack_dict, raw=False, immortal=True) except Exception as e: print(str(e))
def connected(self) -> bool: aprs_is = aprslib.IS("NOCALL", "-1", self.hostname, self.port) for _ in range(5): try: aprs_is.connect() aprs_is.close() return True except: sleep(1) continue else: return False
def main(): """the main function""" print("starting listener: ") print(" BADASH_API_URL: {}".format(BADASH_API_URL)) print(" BADASH_API_KEY: {}".format(BADASH_API_KEY)) print(" BADASH_JOB: {}".format(BADASH_JOB)) print(" CALL SIGN: {}".format(sys.argv[1])) aprs = aprslib.IS('N0CALL') aprs.set_server('rotate.aprs.net', 14580) aprs.set_filter('p/{}'.format(sys.argv[1])) aprs.connect() aprs.consumer(aprs_callback)
def ais_connect(config): ais = aprslib.IS(config.call, passwd=config.passcode, port=DEFAULT_PORT) for retry in range(5): try: ais.connect() except ConnectionError as err: logging.warning(err) time.sleep(10) else: return ais logging.error('Connection error exiting') sys.exit(os.EX_NOHOST)
def send_data(self, data, config): packet = self.make_packet(data, config) if config['aprs']['sendall']: for server in config['aprs']['servers']: AIS = aprslib.IS(config['aprs']['callsign'], str(config['aprs']['passwd']), config['aprs']['servers'][server], config['aprs']['port']) try: AIS.connect() AIS.sendall(packet) logging.info(f"Packet transmitted to {config['aprs']['servers'][server]} at {time.strftime('%Y-%m-%d %H:%M', time.gmtime())} UTC time") except Exception as e: logging.exception(f"An exception occured trying to send packet to {server}\nException: {e}") finally: AIS.close()
def getAprsFeed(): AIS = aprslib.IS("KI5GVH", host="rotate.aprs.net", port=14580, skip_login=False) AIS.filter = "s/O" # balloon symbol only # IS.filter = "g/APLIG*" # ToCall = LightAPRS # https://github.com/hessu/aprs-deviceid/blob/master/tocalls.yaml # IS.filter = "b/KI5GVH*/K6RPT*" # From a list of calls AIS.connect(blocking=True) AIS.consumer(callback, raw=True) print("Connected.") time.sleep(15) AIS.close()
def run(self): login = self.config.get_aprs_login() host = self.config.get_aprs_host() port = self.config.get_aprs_port() for f in self.config.get_consumers(): rule = f['filter'] topic = f['topic'] self.logger.info( f'adding consumer {login}@{host}:{port} - {rule} => {topic}') ais = aprslib.IS(login, host=host, port=port) ais.connect() ais.set_filter(rule) ais.consumer(partial(self.handler, f), raw=False) self.consumers.append(ais)
def __init__(self, callsign: str, password: str, host: str, server_filter: str, see): """Initialize the class.""" super().__init__() self.callsign = callsign self.host = host self.start_event = threading.Event() self.see = see self.server_filter = server_filter self.start_message = "" self.start_success = False self.ais = aprslib.IS(self.callsign, passwd=password, host=self.host, port=FILTER_PORT)
def __init__(self, callsign: str, aprs_host: str, aprs_server_filter: str, traccar_host: str, aprs_password: str = DEFAULT_APRS_PASSWORD): """Initialize the class.""" super().__init__() self.callsign = callsign self.aprs_server_filter = aprs_server_filter self.traccar_host = traccar_host self.ais = aprslib.IS(self.callsign, passwd=aprs_password, host=aprs_host, port=FILTER_PORT)
def senden(call, msg): # ZIEL-CALL mit 9 Stellen indizieren und durch Zielcall ersetzten zielcall = [" ", " ", " ", " ", " ", " ", " ", " ", " "] for i in range(0, len(call)): zielcall[i] = str(call[i]) # Zusammensetzen der MSg ackNo = random.randrange(1, 999) beacon_ack_buff = ":" + ''.join(zielcall) + ":" + msg + " {" + str(ackNo) command = meinemsgid + ">APR7TA,TCPIP:" + beacon_ack_buff AIS = aprslib.IS(meinemsgid, passwd, port=14580) AIS.connect() # senden message AIS.sendall(command) print("Msg -> " + command + "\nan " + call + " um " + strftime("%H:%M:%S") + " gesendet.") return
def aprsis_dstar_callback(dstar_stream): logger = logging.getLogger(__name__) if '$GPGGA' in dstar_stream['gps']: # detect kenwood HTs and send aprs beacons. # Connect to APRS-IS network if not already connected for the specific rpt module. frame = get_beacon_gpgga(dstar_stream['my'], dstar_stream['sfx'], dstar_stream['message'], dstar_stream['gps']['$GPGGA']) elif 'DPRS' in dstar_stream['gps']: #detect ICOM GPS-A dprs format and send aprs beacon frame = get_beacon_dprs(dstar_stream['gps']['DPRS']) else: logger.info("Nothing to do with: %s /%s" % (dstar_stream['my'], dstar_stream['sfx'])) return rpt_callsign = to_aprs_callsign(dstar_stream['rpt1']) logger.info("Sending frame: %s" % frame) aprs = aprslib.IS(rpt_callsign, passcode_generator(rpt_callsign)) aprs.connect() aprs.sendall(frame) aprs.close()
def ack_senden(absender, msgnummer): asc_nr = int(msgnummer) print("Sende an ", absender, " ACK {a:03d} aus".format(a=asc_nr)) # ZIEL-CALL mit 9 Stellen indizieren und durch Zielcall ersetzten zielcall = [" ", " ", " ", " ", " ", " ", " ", " ", " "] for i in range(0, len(absender)): zielcall[i] = str(absender[i]) # erzeugen der ack-MSg beacon_ack_buff = ":" + ''.join(zielcall) + ":ack" + "{a:02d}".format( a=asc_nr) command = meinemsgid + ">APRS,TCPIP*:" + beacon_ack_buff #+ "\"" # a valid passcode for the callsign is required in order to send AIS = aprslib.IS(meinemsgid, ata_passwd, port=14580) AIS.connect() # senden ack-message AIS.sendall(command) print("Gesendet: ", command, "\n") return
def main() -> int: # Handle program arguments ap = argparse.ArgumentParser(prog='', description='') ap.add_argument("port", help="Serial port", default="/dev/ttyACM0") ap.add_argument("-b", "--baud-rate", help="Serial baud", default=9600, type=int) ap.add_argument("-c", "--callsign", help="APRS callsign", required=True) args = ap.parse_args() # Open serial connection ser = serial.Serial(args.port, args.baud_rate, timeout=.1) # Open APRS-IS connection AIS = aprslib.IS(args.callsign, passwd=aprslib.passcode(args.callsign), port=14580) AIS.connect() # Handle incoming data try: while True: # Serial line line = str(ser.readline().decode().strip('\r\n')) if not line: continue # Ignore debug data if line[0] == "#": continue # Log print(line) # Send AIS.sendall(line) except KeyboardInterrupt as e: pass return 0
def connect_aprs(callsign, dwell_time=10): """ This function connects to the APRS.fi server and returns the aprs connection to be used by the clean_data function. Added exception handling to test for stability. """ aprs = aprslib.IS('0') aprs.set_server('rotate.aprs.net', 14580) aprs.filter = callsign aprs.connect() if aprs: # If aprs was successful, then tell the user that we connected print("successfully connected to aprs") # Return the aprs object return aprs else: # If you cannot connect, you must reconnect print("could not connect to aprs! check connection!")
def send(self, packets: List[APRSPacket]): if not isinstance(packets, Sequence) or isinstance(packets, str): packets = [packets] packets = [ packet if not isinstance(packet, str) else APRSPacket.from_frame(packet) for packet in packets ] if len(self.__send_buffer) > 0: packets.extend(self.__send_buffer) self.__send_buffer.clear() callsigns = {packet.from_callsign for packet in packets} packets = { callsign: [packet for packet in packets if packet.from_callsign == callsign] for callsign in callsigns } if len(packets) > 0: logging.info( f"sending {len(packets)} packet(s) to {self.location}: {packets}" ) for callsign, callsign_packets in packets.items(): try: frames = [packet.frame for packet in callsign_packets] aprs_is = aprslib.IS(callsign, aprslib.passcode(callsign), self.hostname, self.port) aprs_is.connect() if len(frames) > 0: aprs_is.sendall(r"\rn".join(frames)) aprs_is.close() except ConnectionError as error: logging.info( f"could not send packet(s) ({error}); reattempting on next iteration", ) self.__send_buffer.extend(packets)
def __init__(self): self.command = "message" self.syntax = "message <callsign> <message>" self.help = "Send an APRS message to the callsign." # check if APRS is configured APRS_CALLSIGN = os.environ.get('APRS_CALLSIGN') APRS_PASSWORD = os.environ.get('APRS_PASSWORD') if not APRS_CALLSIGN: logger.warning('APRS message sending not enabled. APRS_CALLSIGN must be set in environment.') raise RuntimeError('APRS_CALLSIGN must be set in environment.') if not APRS_PASSWORD: logger.warning('APRS message sending not enabled. APRS_PASSWORD must be set in environment.') raise RuntimeError('APRS_PASSWORD must be set in environment.') self.APRS_CALLSIGN = APRS_CALLSIGN self.APRS_PASSWORD = APRS_PASSWORD # configure aprslib self.ais = aprslib.IS(self.APRS_CALLSIGN, passwd=self.APRS_PASSWORD, port=14580) self.ais.connect() # instance variable to track message IDs self.message_id = 1
config.get('Position', 'Pos_N') + "/" + config.get('Position', 'Pos_E') + "- " + config.get('Main config', 'APRS_Desc')) AIS.sendall( config.get('Main config', 'APRS_User') + ">APRS,TCPIP*:>Currently QRV - QRG VFO1: " + string_vfo1 + " | QRG VFO2: " + string_vfo2) # Check, if INI file exists. If not, create it and ask user for Callsign/PW init_of_config() # Connect to HRD IP Server connect_to_HRD() # Connect to APRS service AIS = aprslib.IS(config.get('Main config', 'APRS_User'), passwd=config.get('Main config', 'APRS_PW'), port=14580) AIS.connect() radiostring = sendframe("get radios") print("Radio: " + radiostring) # loop while 1: get_frequency_and_send_APRS() time.sleep(60)
if pto == 'N0CALL' and pformat == 'message': #put the callsign from APRS you want the messages forward from in pto == print(pto + " " + pfrom + " " + packet['message_text']) msg = '{} {} {}'.format( 'N0CALL-2', pfrom, packet['message_text'] ).encode( 'utf-8' ) #put the callsign of the LoRaMaDor board you wish to recieve your message at print("Sending message...") print(msg) ser = serial.Serial( '/dev/ttyUSB0', 115200 ) #You may need to change the serial port here, the speed should be the same ser.write(msg) ser.write(b'\n\r') ser.close() AIS = aprslib.IS("N0CALL", passwd='999999', port=14580) #at this point a passwd probably isn't required. AIS.connect() AIS.set_filter("t/m") #message filter #AIS.consumer(callback, raw=True) AIS.consumer(callback, raw=False) #{'raw': 'HS0QKD-9>APGJW6-1,WIDE1-1,qAS,E27HCD-1:!1305.41N/10055.29Ev080/007/A=000085', 'from': 'HS0QKD-9', 'to': 'APGJW6-1', 'path': ['WIDE1-1', 'qAS', 'E27HCD-1'], 'via': 'E27HCD-1', 'messagecapable': False, 'format': 'uncompressed', 'posambiguity': 0, 'symbol': 'v', 'symbol_table': '/', 'latitude': 13.090166666666667, 'longitude': 100.9215, 'course': 80, 'speed': 12.964, 'altitude': 25.908, 'comment': ''} # I am pretty new to python, so there is still a lot I need to learn, please feel free to update this with improvements # but please share so I can see and learn something. Thanks, LeRoy KD8BXP # Idea for next version - make it a 2 way system, so that it can also send a message back into the APRS system passwd would be required for that.
h = 9 g = round(gain) if g > 9: g = 9 if dir <= -1: d = 0 else: d = round(dir / 45) if d > 9: d = 9 return ('PHG' + "{:.0f}".format(p) + "{:.0f}".format(h) + "{:.0f}".format(g) + "{:.0f}".format(d)) #open the link to APRS-IS. If connnection can't be established, print warning to console, print warning to error log and bail out AIS = aprslib.IS(aprsisusername, passwd=aprsispassword, port=14580) try: AIS.connect() except: print('Invalid APRS credentials') logger.error('Invalid APRS credentials') sys.exit(0) else: #connection to APRS-IS has been established, now continue #create the complete URL to send to DAPNET http = urllib3.PoolManager() headers = urllib3.util.make_headers(basic_auth=hampagerusername + ':' + hampagerpassword) try:
def prepare_connection(self, **kwargs): self.AIS = aprslib.IS(self.callsign)#, host='noam.aprs2.net', port=14580) self.delay_before_check = kwargs.get('delay', 0.5)
dest = run_predict(x['latitude'], x['longitude'], x['altitude'], current_rate, burst) if dest: set_dest(dest['latitude'], dest['longitude']) if 'addresse' in x.keys(): if x['addresse'] in control: if x['msgNo'] <= msgNo[x['addresse']]: return else: msgNo[x['addresse']] = x['msgNo'] print("control[{}]:".format(x['msgNo']), x['message_text']) if x['message_text'] == "burst": burst = True print("Now assuming the balloon has burst.") elif x['message_text'] == "!burst": burst = False print("Now assuming the balloon is intact.") elif x['message_text'].startswith("asc"): global ascent_rate ascent_rate = float(x['message_text'].split(":")[1]) print("Setting ascent rate to {}".format(ascent_rate)) elif x['message_text'].startswith("desc"): global descent_rate descent_rate = float(x['message_text'].split(":")[1]) print("Setting descent rate to {}".format(ascent_rate)) AIS = aprslib.IS("KC3HOB") AIS.connect() AIS.consumer(packet)