Ejemplo n.º 1
0
    def decode(self, job: QueueJob):
        logging.debug("processing file %s", job.file)
        file = os.path.realpath(job.file)
        decoder = subprocess.Popen(
            ["nice", "-n", "10"] + self._profile.decoder_commandline(file),
            stdout=subprocess.PIPE,
            cwd=os.path.dirname(file),
            close_fds=True,
        )

        messages = []
        for line in decoder.stdout:
            logging.debug(line)
            messages.append((self._profile, job.freq, line))

        # set grid & antenna information from kiwi station, if we can't found them at config
        if not "grid" in Config.get()["STATIONS"][self._options.station]:
            Config.get()[
                "STATIONS"][self._options.station]["grid"] = self._rx_grid
        if not "antenna" in Config.get()["STATIONS"][self._options.station]:
            Config.get()[
                "STATIONS"][self._options.station]["antenna"] = self._rx_antenna

        # parse raw messages
        self._parser.parse(messages)

        try:
            rc = decoder.wait(timeout=10)
            if rc != 0:
                logging.warning("decoder return code: %i", rc)

        except subprocess.TimeoutExpired:
            logging.warning(
                "subprocess (pid=%i}) did not terminate correctly; sending kill signal.", decoder.pid)
            decoder.kill()
Ejemplo n.º 2
0
    def __init__(self, station: str):
        self.spots = []
        self.spotLock = threading.Lock()
        self.station = station
        self.timer = None

        # prepare tmpdir for uploader
        self.tmpdir = os.path.join(Config.tmpdir(), station, "WSPR",
                                   "wsprnet.uploader")
        self.logdir = os.path.join(Config.logdir(), "spots", "wsprnet",
                                   station)
        os.makedirs(self.tmpdir, exist_ok=True)
        os.makedirs(self.logdir, exist_ok=True)

        self.uploader = Uploader(station, self.tmpdir, self.logdir)
Ejemplo n.º 3
0
    def getInterval(self):
        conf = Config.get()
        if "WSJTX" in conf:
            conf = conf["WSJTX"]
            if "interval" in conf and self.getMode() in conf["interval"]:
                return conf["interval"][self.getMode()] if conf["interval"][self.getMode()] in self.availableIntervals else self.availableIntervals[0]

        # default when no setting is provided
        return self.availableIntervals[0]
Ejemplo n.º 4
0
    def savelog(self, spots):
        spot_lines = []
        for s in spots:
            spot_lines.append(
                "%s %s %s  %s %s %s %s\n" %
                (time.strftime("%H%M%S", time.localtime(s["timestamp"])),
                 ("%2.1f" % s["db"]).rjust(5, " "),
                 ("%2.1f" % s["dt"]).rjust(5, " "),
                 ("%2.6f" % s["freq"]).rjust(10, " "),
                 PskReporter.supportedModes[s["mode"]], s["callsign"].ljust(
                     6, " "), s["locator"]))

        if "LOG_SPOTS" in Config.get() and Config.get()["LOG_SPOTS"]:
            file = os.path.join(
                self.logdir,
                "%s.log" % time.strftime("%y%m%d", time.localtime()))
            with open(file, "a") as f:
                f.writelines(spot_lines)
Ejemplo n.º 5
0
    def __init__(self, station: str):
        self.spots = []
        self.spotLock = threading.Lock()
        self.uploader = Uploader(station)
        self.station = station
        self.timer = None

        # prepare logdir for uploader
        self.logdir = os.path.join(Config.logdir(), "spots", "pskreport",
                                   station)
        os.makedirs(self.logdir, exist_ok=True)
Ejemplo n.º 6
0
    def instance():
        with DecoderQueue.creationLock:
            if DecoderQueue.sharedInstance is None:
                conf = Config.get()
                maxsize, workers = 10, 3
                if "DECODER_QUEUE" in conf:
                    conf = conf["DECODER_QUEUE"]
                    maxsize = conf["maxsize"] if "maxsize" in conf else maxsize
                    workers = conf["workers"] if "workers" in conf else workers

                DecoderQueue.sharedInstance = DecoderQueue(maxsize, workers)
        return DecoderQueue.sharedInstance
Ejemplo n.º 7
0
    def decoding_depth(self, mode):
        conf = Config.get()
        if "WSJTX" in conf:
            conf = conf["WSJTX"]
            # mode-specific setting?
            if "decoding_depth_modes" in conf and mode in conf["decoding_depth_modes"]:
                return conf["decoding_depth_modes"][mode]
            # return global default
            if "decoding_depth_global" in conf:
                return conf["decoding_depth_global"]

        # default when no setting is provided
        return 3
Ejemplo n.º 8
0
    def _get_output_filename(self):
        if self._options.test_mode:
            return os.devnull

        if self._options.filename != '':
            filename = '%s-%s.wav' % (self._options.filename,
                                      self._profile.getMode())
        else:
            ts = time.strftime(
                self._profile.getFileTimestampFormat(), self._start_ts)
            filename = '%s.wav' % ts

        filename = os.path.join(Config.tmpdir(), self._options.station, self._profile.getMode(), self._band, filename)
        return filename
Ejemplo n.º 9
0
 def __init__(self, station: str, tmpdir, logdir):
     self.station = Config.get()["STATIONS"][station]
     self.station["name"] = station
     self.tmpdir = tmpdir
     self.logdir = logdir
     self.event = threading.Event()
Ejemplo n.º 10
0
 def savelog(self, spot_lines, type):
     if "LOG_SPOTS" in Config.get() and Config.get()["LOG_SPOTS"]:
         file = os.path.join(
             self.logdir,
             "%s%s.log" % (time.strftime("%y%m%d", time.localtime()), type))
         self.save(spot_lines, file)
Ejemplo n.º 11
0
    def upload(self, spots):
        logging.warning("uploading %i spots to wsprnet", len(spots))

        allmet = os.path.join(
            self.tmpdir, "allmet_%d.txt" %
            (int(time.time() + random.uniform(0, 99)) & 0xffff))

        conf = Config.get()
        spot_lines = []
        for spot in spots:
            # The 11th field is identification of WSPR and FST4W (http://wsprnet.org/drupal/node/8500)            #
            # the `mode` according to 4 values:
            # "2"
            # "15" for the current WSPR modes -2 & -15
            # "5
            # "30" for the FST4W modes 300 & 1800
            #
            # example:
            # 200804 1916  0.26 -18  0.96   7.040176 JA5NVN         PM74   37  0  15

            mode = 2 if spot["mode"] == "WSPR" else conf["WSJTX"]["interval"]["FST4W"] / 60 \
                if "WSJTX" in conf and "interval" in conf["WSJTX"] and "FST4W" in conf["WSJTX"]["interval"] else 2
            spot_lines.append(
                "%s  %1.2f %d  %1.2f   %2.6f %s         %s   %d  %d  %d\n" % (
                    # wsprnet needs GMT time
                    time.strftime("%y%m%d %H%M", time.gmtime(
                        spot["timestamp"])),
                    spot["sync_quality"],
                    spot["db"],
                    spot["dt"],
                    # freq in MHz for wsprnet
                    spot["freq"],
                    spot["callsign"],
                    spot["locator"],
                    spot["watt"],
                    spot["drift"],
                    mode))

        self.save(spot_lines, allmet)
        self.saveall(spot_lines)

        postfiles = {"allmept": open(allmet, "r")}
        params = {
            "call": self.station["callsign"],
            "version": "DS_" + config.VERSION,
            "grid": self.station["grid"]
        }

        max_retries = 3
        retries = 0
        resp = None

        while True:
            try:
                requests.adapters.DEFAULT_RETRIES = 5
                s = requests.session()
                s.keep_alive = False
                resp = s.post("http://wsprnet.org/post",
                              files=postfiles,
                              params=params,
                              timeout=300)

                if resp.status_code == 200:
                    # if we can not find the text of success
                    if resp.text.find("spot(s) added") == -1:
                        self.savefail(spot_lines)
                    break

            # TODO: handle with retry
            except requests.ConnectionError or requests.exceptions.Timeout as e:
                logging.error("Wsprnet connection error %s", e)
                if retries >= max_retries:
                    logging.warning("Saving %d spot to wspr_upload_fail.log",
                                    len(spot_lines))
                    self.savefail(spot_lines)
                    break
                else:
                    retries += 1
                    logging.warning("wait 10s to try again...->%d", retries)
                    self.event.wait(timeout=10)
                    continue
            except requests.exceptions.ReadTimeout as e:
                logging.error("Wsprnet read timeout error %s", e)
                self.savefail(spot_lines)
                break

        logging.debug("delete %s", allmet)
        os.unlink(allmet)
Ejemplo n.º 12
0
 def __init__(self, station: str):
     self.station = Config.get()["STATIONS"][station]
     self.station["name"] = station
     # logging.debug("Station: %s", self.station)
     self.sequence = 0
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)