#!/usr/bin/python3 import serial,re import base91 import sys import argparse import telnetlib import time import sqlite3 import image import position # Parse arguments from terminal parser = argparse.ArgumentParser(description='APRS/SSDV decoder') parser.add_argument('-c', '--call', help='Callsign of the station', required=True) parser.add_argument('-n', '--grouping', help='Amount packets that will be sent to the SSDV server in one request', default=1, type=int) parser.add_argument('-d', '--device', help='Serial device (\'-\' for stdin)', default='-') parser.add_argument('-b', '--baudrate', help='Baudrate for serial device', default=9600, type=int) parser.add_argument('-s', '--server', help='SSDV server URL', default='https://ssdv.habhub.org/api/v0/packets') args = parser.parse_args() # Open SQLite database sqlite = sqlite3.connect("decoder.sqlite") sqlite.cursor().execute(""" CREATE TABLE IF NOT EXISTS position ( call TEXT, time INTEGER, org TEXT, lat FLOAT, lon FLOAT, alt INTEGER, comment TEXT, sequ INTEGER, tel1 INTEGER, tel2 INTEGER, tel3 INTEGER, tel4 INTEGER, tel5 INTEGER, PRIMARY KEY (call, time) ) """) sqlite.cursor().execute(""" CREATE TABLE IF NOT EXISTS image ( call TEXT, time INTEGER, imageID INTEGER, packetID INTEGER, lat FLOAT, lon FLOAT, alt INTEGER, data TEXT, PRIMARY KEY (call, time, imageID, packetID) ) """) """ Packet handler for received APRS packets""" def received_data(data): # Debug print('====================================================================================================') print(data) print('----------------------------------------------------------------------------------------------------') # Parse line and detect data # Position (.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})(.*?)\|(.*)\| # Image (.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})I(.*) # Log (.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})L(.*) all = re.search("(.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})", data) pos = re.search("(.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})(.*?)\|(.*)\|", data) dat = re.search("(.*)\>APECAN(.*?):\/([0-9]{6}h)(.{13})(I|L)(.*)", data) if all: call = all.group(1) rxer = all.group(2).split(',')[-1] tim = all.group(3) posi = all.group(4) if pos: # Position packet (with comment and telementry) comm = pos.group(5) tel = pos.group(6) position.insert_position(sqlite, call, tim, posi, comm, tel) elif dat: # Data packet typ = dat.group(5) data_b91 = dat.group(6) data = base91.decode(data_b91) # Decode Base91 if typ is 'I': # Image packet image.insert_image(sqlite, rxer, call, tim, posi, data, args.server, args.grouping) elif typ is 'L': # Log packet position.insert_log(sqlite, call, data) if args.device == 'I': # Source APRS-IS print('Connect to APRS-IS') try: tn = telnetlib.Telnet("rotate.aprs2.net", 14580, 3) tn.write(("user %s filter u/APECAN\n" % args.call).encode('ascii')) print('Connected') except Exception as e: print('Could not connect to APRS-IS: %s' % str(e)) print('exit...') sys.exit(1) wdg = time.time() + 1 # Connection watchdog buf = '' while True: # Read data try: buf += tn.read_eager().decode('ascii') except EOFError: # Server has connection closed wdg = 0 # Tell watchdog to restart connection # Line handler if '\n' in buf: pbuf = buf.split('\n') for i in range(len(pbuf)-1): # Separate lines handled here # Watchdog reload if '# aprsc' in pbuf[i]: print('Ping from APRS-IS') wdg = time.time() + 30 continue # Data handling received_data(pbuf[i]) buf = pbuf[-1] # Watchdog reconnection if wdg < time.time(): print('APRS-IS connection lost... reconnect') try: tn = telnetlib.Telnet("rotate.aprs2.net", 14580, 3) tn.write(("user %s filter u/APECAN\n" % args.call).encode('ascii')) print('Connected') wdg = time.time() + 1 except Exception as e: print('Could not connect to APRS-IS: %s' % str(e)) print('Try again...') time.sleep(0.1) elif args.device is '-': # Source stdin while True: data = sys.stdin.readline() received_data(data) else: # Source Serial connection try: serr = serial.Serial( port=args.device, baudrate=args.baudrate, ) except: sys.stderr.write('Error: Could not open serial port\n') sys.exit(1) while True: data = '' while True: b = serr.read(1) if b == '\r' or b == '\n': break data += b received_data(data)