from .audio import AudioChopperProfile from .parser import Parser import re from js8py import Js8 from js8py.frames import Js8FrameHeartbeat, Js8FrameCompound from owrx.map import Map, LocatorLocation from owrx.pskreporter import PskReporter from owrx.metrics import Metrics, CounterMetric from abc import ABCMeta, abstractmethod import logging logger = logging.getLogger(__name__) class Js8Profile(AudioChopperProfile, metaclass=ABCMeta): def getFileTimestampFormat(self): return "%y%m%d_%H%M%S" def decoder_commandline(self, file): return ["js8", "--js8", "-b", self.get_sub_mode(), "-d", str(self.decoding_depth("js8")), file] @abstractmethod def get_sub_mode(self): pass class Js8NormalProfile(Js8Profile): def getInterval(self): return 15 def get_sub_mode(self): return "A" class Js8SlowProfile(Js8Profile): def getInterval(self): return 30 def get_sub_mode(self): return "E" class Js8Parser(Parser): decoderRegex = re.compile(" ?") def parse(self, messages): for raw in messages: try: freq, raw_msg = raw self.setDialFrequency(freq) msg = raw_msg.decode().rstrip() if Js8Parser.decoderRegex.match(msg): return if msg.startswith(" EOF on input file"): return logger.debug(msg) frame = Js8().parse_message(msg) self.handler.write_js8_message(frame, self.dial_freq) logger.debug(frame) self.pushDecode() if (isinstance(frame, Js8FrameHeartbeat) or isinstance(frame, Js8FrameCompound)) and frame.grid: Map.getSharedInstance().updateLocation( frame.callsign, LocatorLocation(frame.grid), "JS8", self.band ) PskReporter.getSharedInstance().spot({ "callsign": frame.callsign, "mode": "JS8", "locator": frame.grid, "freq": self.dial_freq + frame.freq, "db": frame.db, "timestamp": frame.timestamp, "msg": str(frame) }) except Exception: logger.exception("error while parsing js8 message") def pushDecode(self): metrics = Metrics.getSharedInstance() band = "unknown" if self.band is not None: band = self.band.getName() if band is None: band = "unknown" name = "js8call.decodes.{band}.JS8".format(band=band) metric = metrics.getMetric(name) if metric is None: metric = CounterMetric() metrics.addMetric(name, metric) metric.inc()