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()
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)
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]
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)
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)
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
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
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
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()
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)
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)
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)