kopia lustrzana https://github.com/DL7AD/pecanpico9
181 wiersze
4.3 KiB
Python
Executable File
181 wiersze
4.3 KiB
Python
Executable File
#!/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', default='N0CALL')
|
|
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,
|
|
isnew 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,
|
|
data1 TEXT,
|
|
data2 TEXT,
|
|
crc TEXT,
|
|
PRIMARY KEY (call, time, imageID, packetID)
|
|
)
|
|
""")
|
|
|
|
|
|
""" Packet handler for received APRS packets"""
|
|
def received_data(data):
|
|
# 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|J|L)(.*)", data)
|
|
|
|
if all:
|
|
# Debug
|
|
print('='*100)
|
|
print(data)
|
|
print('-'*100)
|
|
|
|
call = all.group(1).split(' ')[-1]
|
|
rxer = all.group(2).split(',')[-1]
|
|
if not len(rxer): rxer = args.call
|
|
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' or typ is 'J': # Image packet
|
|
image.insert_image(sqlite, rxer, call, tim, posi, data, typ, 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)
|
|
|