better timestamping and overhaul

This commit is contained in:
Jakob Ketterl 2019-07-20 12:47:10 +02:00
parent abd5cf0795
commit 18b65f769f
1 changed files with 42 additions and 34 deletions

View File

@ -1,6 +1,6 @@
import threading
import wave
from datetime import datetime, timedelta, date
from datetime import datetime, timedelta, date, timezone
import time
import sched
import subprocess
@ -31,7 +31,7 @@ class WsjtChopper(threading.Thread):
filename = "{tmp_dir}/openwebrx-wsjtchopper-{id}-{timestamp}.wav".format(
tmp_dir = self.tmp_dir,
id = id(self),
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
timestamp = datetime.utcnow().strftime(self.fileTimestampFormat)
)
wavefile = wave.open(filename, "wb")
wavefile.setnchannels(1)
@ -71,9 +71,9 @@ class WsjtChopper(threading.Thread):
self._scheduleNextSwitch()
def decoder_commandline(self, file):
'''
"""
must be overridden in child classes
'''
"""
return []
def decode(self):
@ -128,6 +128,7 @@ class WsjtChopper(threading.Thread):
class Ft8Chopper(WsjtChopper):
def __init__(self, source):
self.interval = 15
self.fileTimestampFormat = "%y%m%d_%H%M%S"
super().__init__(source)
def decoder_commandline(self, file):
@ -138,6 +139,7 @@ class Ft8Chopper(WsjtChopper):
class WsprChopper(WsjtChopper):
def __init__(self, source):
self.interval = 120
self.fileTimestampFormat = "%y%m%d_%H%M"
super().__init__(source)
def decoder_commandline(self, file):
@ -148,6 +150,7 @@ class WsprChopper(WsjtChopper):
class Jt65Chopper(WsjtChopper):
def __init__(self, source):
self.interval = 60
self.fileTimestampFormat = "%y%m%d_%H%M"
super().__init__(source)
def decoder_commandline(self, file):
@ -158,6 +161,7 @@ class Jt65Chopper(WsjtChopper):
class Jt9Chopper(WsjtChopper):
def __init__(self, source):
self.interval = 60
self.fileTimestampFormat = "%y%m%d_%H%M"
super().__init__(source)
def decoder_commandline(self, file):
@ -167,8 +171,6 @@ class Jt9Chopper(WsjtChopper):
class WsjtParser(object):
locator_pattern = re.compile(".*\\s([A-Z0-9]+)\\s([A-R]{2}[0-9]{2})$")
jt9_pattern = re.compile("^([0-9]{6}|\\*{4}) .*")
wspr_pattern = re.compile("^[0-9]{4} .*")
wspr_splitter_pattern = re.compile("([A-Z0-9]*)\\s([A-R]{2}[0-9]{2})\\s([0-9]+)")
def __init__(self, handler):
@ -191,38 +193,45 @@ class WsjtParser(object):
if msg.startswith(" EOF on input file"):
return
out = {}
if WsjtParser.jt9_pattern.match(msg):
modes = list(WsjtParser.modes.keys())
if msg[21] in modes or msg[19] in modes:
out = self.parse_from_jt9(msg)
elif WsjtParser.wspr_pattern.match(msg):
else:
out = self.parse_from_wsprd(msg)
self.handler.write_wsjt_message(out)
except ValueError:
logger.exception("error while parsing wsjt message")
def parse_timestamp(self, instring, dateformat):
ts = datetime.strptime(instring, dateformat).replace(tzinfo=timezone.utc)
return int(datetime.combine(date.today(), ts.time(), timezone.utc).timestamp() * 1000)
def parse_from_jt9(self, msg):
# ft8 sample
# '222100 -15 -0.0 508 ~ CQ EA7MJ IM66'
# jt65 sample
# '**** -10 0.4 1556 # CQ RN6AM KN95'
out = {}
if msg.startswith("****"):
out["timestamp"] = int(datetime.now().timestamp() * 1000)
msg = msg[5:]
# '2352 -7 0.4 1801 # R0WAS R2ABM KO85'
# '0003 -4 0.4 1762 # CQ R2ABM KO85'
modes = list(WsjtParser.modes.keys())
if msg[19] in modes:
dateformat = "%H%M"
else:
ts = datetime.strptime(msg[0:6], "%H%M%S")
out["timestamp"] = int(datetime.combine(date.today(), ts.time(), datetime.now().tzinfo).timestamp() * 1000)
msg = msg[7:]
out["db"] = float(msg[0:3])
out["dt"] = float(msg[4:8])
out["freq"] = int(msg[9:13])
dateformat = "%H%M%S"
timestamp = self.parse_timestamp(msg[0:len(dateformat)], dateformat)
msg = msg[len(dateformat) + 1:]
modeChar = msg[14:15]
out["mode"] = mode = WsjtParser.modes[modeChar] if modeChar in WsjtParser.modes else "unknown"
mode = WsjtParser.modes[modeChar] if modeChar in WsjtParser.modes else "unknown"
wsjt_msg = msg[17:53].strip()
self.parseLocator(wsjt_msg, mode)
out["msg"] = wsjt_msg
return out
return {
"timestamp": timestamp,
"db": float(msg[0:3]),
"dt": float(msg[4:8]),
"freq": int(msg[9:13]),
"mode": mode,
"msg": wsjt_msg
}
def parseLocator(self, msg, mode):
m = WsjtParser.locator_pattern.match(msg)
@ -237,19 +246,18 @@ class WsjtParser(object):
def parse_from_wsprd(self, msg):
# wspr sample
# '2600 -24 0.4 0.001492 -1 G8AXA JO01 33'
out = {}
now = datetime.now()
ts = datetime.strptime(msg[0:4], "%M%S").replace(hour=now.hour)
out["timestamp"] = int(datetime.combine(date.today(), ts.time(), now.tzinfo).timestamp() * 1000)
out["db"] = float(msg[5:8])
out["dt"] = float(msg[9:13])
out["freq"] = float(msg[14:24])
out["drift"] = int(msg[25:28])
out["mode"] = "WSPR"
# '0052 -29 2.6 0.001486 0 G02CWT IO92 23'
wsjt_msg = msg[29:].strip()
out["msg"] = wsjt_msg
self.parseWsprMessage(wsjt_msg)
return out
return {
"timestamp": self.parse_timestamp(msg[0:4], "%H%M"),
"db": float(msg[5:8]),
"dt": float(msg[9:13]),
"freq": float(msg[14:24]),
"drift": int(msg[25:28]),
"mode": "WSPR",
"msg": wsjt_msg
}
def parseWsprMessage(self, msg):
m = WsjtParser.wspr_splitter_pattern.match(msg)