Switching TextParser to LineBasedModule base.

This commit is contained in:
Marat Fayzullin 2023-09-11 21:33:19 -04:00
parent 1513263655
commit 7719070885
4 changed files with 34 additions and 70 deletions

View File

@ -150,7 +150,7 @@ class AdsbDemodulator(ServiceDemodulator, DialFrequencyReceiver):
self.parser = AdsbParser(service=service)
workers = [
Convert(Format.COMPLEX_FLOAT, Format.COMPLEX_SHORT),
Dump1090Module(rawOutput = not service),
Dump1090Module(rawOutput = True),
self.parser,
]
# Connect all the workers

View File

@ -1,3 +1,4 @@
from csdr.module import LineBasedModule
from owrx.toolbox import TextParser, ColorCache
from owrx.map import Map, LatLngLocation
from owrx.aprs import getSymbolData
@ -219,7 +220,7 @@ class AircraftManager(object):
# Base class for aircraft message parsers.
#
class AircraftParser(TextParser):
def __init__(self, filePrefix: str, service: bool = False):
def __init__(self, filePrefix: str = None, service: bool = False):
super().__init__(filePrefix=filePrefix, service=service)
def parseAcars(self, data, out):
@ -403,14 +404,14 @@ class Vdl2Parser(AircraftParser):
#
class AdsbParser(AircraftParser):
def __init__(self, service: bool = False):
super().__init__(filePrefix="ADSB", service=service)
super().__init__(filePrefix=None, service=service)
self.smode_parser = ModeSParser()
def parse(self, msg: str):
def process(self, line: bytes) -> any:
# If it is a valid Mode-S message...
if msg.startswith("*") and msg.endswith(";") and len(msg) in [16, 30]:
if line.startswith(b"*") and line.endswith(b";") and len(line) in [16, 30]:
# Parse Mode-S message
out = self.smode_parser.process(bytes.fromhex(msg[1:-1]))
out = self.smode_parser.process(bytes.fromhex(line[1:-1].decode("utf-8")))
#logger.debug("@@@ PARSE OUT: {0}".format(out))
# Only consider position and identification reports for now
if "identification" in out or "groundspeed" in out or ("lat" in out and "lon" in out):
@ -478,7 +479,7 @@ class AcarsParser(AircraftParser):
data = json.loads(msg)
pm = Config.get()
ts = data["timestamp"]
logger.debug("@@@ ACARS: {0}".format(data))
#logger.debug("@@@ ACARS: {0}".format(data))
# Collect basic data first
out = {
"mode" : "ACARS",

View File

@ -135,9 +135,9 @@ class Modes(object):
DigitalMode("bpsk31", "BPSK31", underlying=["usb"]),
DigitalMode("bpsk63", "BPSK63", underlying=["usb"]),
# Testing jketterl's RTTY decoder
DigitalMode("jkrtty170", "RTTY 45/170", underlying=["usb", "lsb"]),
DigitalMode("jkrtty450", "RTTY 50N/450", underlying=["lsb", "usb"]),
DigitalMode("jkrtty85", "RTTY 50N/85", underlying=["lsb", "usb"]),
DigitalMode("jkrtty170", "RTTY-170 / 45", underlying=["usb", "lsb"]),
DigitalMode("jkrtty450", "RTTY-450 / 50N", underlying=["usb", "lsb"]),
DigitalMode("jkrtty85", "RTTY-85 / 50N", underlying=["usb", "lsb"]),
WsjtMode("ft8", "FT8"),
WsjtMode("ft4", "FT4"),
WsjtMode("jt65", "JT65"),
@ -205,14 +205,14 @@ class Modes(object):
DigitalMode(
"selcall",
"SelCall",
underlying=["empty"],
underlying=["nfm"],
requirements=["selcall"],
squelch=True
),
DigitalMode(
"zvei",
"Zvei",
underlying=["empty"],
underlying=["nfm"],
requirements=["selcall"],
squelch=True
),

View File

@ -1,6 +1,6 @@
from owrx.storage import Storage
from owrx.config import Config
from csdr.module import ThreadModule
from csdr.module import LineBasedModule
from pycsdr.types import Format
from datetime import datetime
import pickle
@ -45,8 +45,8 @@ class ColorCache:
del self.colorBuf[old_id]
class TextParser(ThreadModule):
def __init__(self, filePrefix: str = "LOG", service: bool = False):
class TextParser(LineBasedModule):
def __init__(self, filePrefix: str = None, service: bool = False):
self.service = service
self.frequency = 0
self.data = bytearray(b'')
@ -88,7 +88,7 @@ class TextParser(ThreadModule):
def writeFile(self, data):
# If no file open, create and open a new file
if self.file is None:
if self.file is None and self.filePfx is not None:
self.newFile(Storage().makeFileName(self.filePfx+"-{0}", self.frequency))
# If file open now...
if self.file is not None:
@ -127,68 +127,31 @@ class TextParser(ThreadModule):
# By default, do not parse, just return the string
return msg
# ONLY IMPLEMENT THIS FUNCTION WHEN REPORTING LOCATION FROM SERVICE!
def updateLocation(self, msg: str):
# By default, do nothing
pass
def run(self):
logger.debug("%s starting..." % self.myName())
# Run while there is input data
while self.doRun:
# Read input data
inp = self.reader.read()
# Terminate if no input data
if inp is None:
logger.debug("%s exiting..." % self.myName())
self.doRun = False
break
# Add read data to the buffer
self.data = self.data + inp.tobytes()
# Process buffer contents
out = self.process()
# Keep processing while there is input to parse
while out is not None:
if len(out)>0:
if isinstance(out, bytes):
self.writer.write(out)
elif isinstance(out, str):
self.writer.write(bytes(out, 'utf-8'))
else:
self.writer.write(pickle.dumps(out))
out = self.process()
super().run()
logger.debug("%s exiting..." % self.myName())
def process(self):
def process(self, line: bytes) -> any:
# No result yet
out = None
# Search for end-of-line
eol = self.data.find(b'\n')
try:
msg = line.decode(encoding="utf-8", errors="replace")
#logger.debug("%s: %s" % (self.myName(), msg))
# If running as a service with a log file...
if self.service and self.filePfx is not None:
# Write message into open log file, including end-of-line
self.writeFile(line)
self.writeFile(b"\n")
else:
# Let parse() function do its thing
out = self.parse(msg)
# If found end-of-line...
if eol>=0:
try:
msg = self.data[0:eol].decode(encoding="utf-8", errors="replace")
#logger.debug("%s: %s" % (self.myName(), msg))
# If running as a service...
if self.service:
# Write message into open log file, including end-of-line
self.writeFile(self.data[0:eol+1])
# Optionally, parse and report location
self.updateLocation(msg)
# Empty result
out = {}
else:
# Let parse() function do its thing
out = self.parse(msg)
except Exception as exptn:
logger.debug("%s: Exception parsing: %s" % (self.myName(), str(exptn)))
except Exception as exptn:
logger.debug("%s: Exception parsing: %s" % (self.myName(), str(exptn)))
# Remove parsed message from input, including end-of-line
del self.data[0:eol+1]
# Return parsed result or None if no result yet
# Return parsed result if any
return out