def updateServices(self): with self.lock: logger.debug("re-scheduling services due to sdr changes") self.stopServices() if not self.source.isAvailable(): logger.debug("sdr source is unavailable") return cf = self.source.getProps()["center_freq"] sr = self.source.getProps()["samp_rate"] srh = sr / 2 frequency_range = (cf - srh, cf + srh) dials = [ dial for dial in Bandplan.getSharedInstance(). collectDialFrequencies(frequency_range) if self.isSupported(dial["mode"]) ] if not dials: logger.debug("no services available") return groups = self.optimizeResampling(dials, sr) if groups is None: for dial in dials: self.services.append( self.setupService(dial["mode"], dial["frequency"], self.source)) else: for group in groups: if len(group) > 1: cf = self.get_center_frequency(group) bw = self.get_bandwidth(group) logger.debug( "group center frequency: {0}, bandwidth: {1}". format(cf, bw)) resampler_props = PropertyLayer() resampler_props["center_freq"] = cf resampler_props["samp_rate"] = bw resampler = Resampler(resampler_props, self.source) resampler.start() for dial in group: self.services.append( self.setupService(dial["mode"], dial["frequency"], resampler)) # resampler goes in after the services since it must not be shutdown as long as the services are # still running self.services.append(resampler) else: dial = group[0] self.services.append( self.setupService(dial["mode"], dial["frequency"], self.source))
def updateServices(self): logger.debug("re-scheduling services due to sdr changes") self.stopServices() if not self.source.isAvailable(): logger.debug("sdr source is unavailable") return cf = self.source.getProps()["center_freq"] sr = self.source.getProps()["samp_rate"] srh = sr / 2 frequency_range = (cf - srh, cf + srh) dials = [ dial for dial in Bandplan.getSharedInstance().collectDialFrequencies( frequency_range) if self.isSupported(dial["mode"]) ] if not dials: logger.debug("no services available") return with self.lock: self.services = [] groups = self.optimizeResampling(dials, sr) if groups is None: for dial in dials: self.services.append( self.setupService(dial["mode"], dial["frequency"], self.source)) else: for group in groups: frequencies = sorted([f["frequency"] for f in group]) min = frequencies[0] max = frequencies[-1] cf = (min + max) / 2 bw = max - min logger.debug( "group center frequency: {0}, bandwidth: {1}".format( cf, bw)) resampler_props = PropertyLayer() resampler_props["center_freq"] = cf # TODO the + 24000 is a temporary fix since the resampling optimizer does not account for required bandwidths resampler_props["samp_rate"] = bw + 24000 resampler = Resampler(resampler_props, self.source) resampler.start() for dial in group: self.services.append( self.setupService(dial["mode"], dial["frequency"], resampler)) # resampler goes in after the services since it must not be shutdown as long as the services are still running self.services.append(resampler)
def sendConfig(key, value): config = dict((key, configProps[key]) for key in OpenWebRxReceiverClient.config_keys) # TODO mathematical properties? hmmmm config["start_offset_freq"] = configProps["start_freq"] - configProps["center_freq"] # TODO this is a hack to support multiple sdrs config["sdr_id"] = self.sdr.getId() self.write_config(config) cf = configProps["center_freq"] srh = configProps["samp_rate"] / 2 frequencyRange = (cf - srh, cf + srh) self.write_dial_frequendies(Bandplan.getSharedInstance().collectDialFrequencies(frequencyRange)) bookmarks = [b.__dict__() for b in Bookmarks.getSharedInstance().getBookmarks(frequencyRange)] self.write_bookmarks(bookmarks)
def sendBookmarks(*args): cf = configProps["center_freq"] srh = configProps["samp_rate"] / 2 dial_frequencies = [] bookmarks = [] if "center_freq" in configProps and "samp_rate" in configProps: frequencyRange = (cf - srh, cf + srh) dial_frequencies = Bandplan.getSharedInstance( ).collectDialFrequencies(frequencyRange) bookmarks = [ b.__dict__() for b in Bookmarks.getSharedInstance().getBookmarks(frequencyRange) ] self.write_dial_frequencies(dial_frequencies) self.write_bookmarks(bookmarks)
def parse(self, profile: AudioChopperProfile, freq: int, raw_msg: bytes): try: band = None if freq is not None: band = Bandplan.getSharedInstance().findBand(freq) msg = raw_msg.decode().rstrip() if Js8Parser.decoderRegex.match(msg): return if msg.startswith(" EOF on input file"): return frame = Js8().parse_message(msg) self.pushDecode(band) if (isinstance(frame, Js8FrameHeartbeat) or isinstance(frame, Js8FrameCompound)) and frame.grid: Map.getSharedInstance().updateLocation( frame.callsign, LocatorLocation(frame.grid), "JS8", band) ReportingEngine.getSharedInstance().spot({ "callsign": frame.callsign, "mode": "JS8", "locator": frame.grid, "freq": freq + frame.freq, "db": frame.db, "timestamp": frame.timestamp, "msg": str(frame), }) out = { "mode": "JS8", "msg": str(frame), "timestamp": frame.timestamp, "db": frame.db, "dt": frame.dt, "freq": freq + frame.freq, "thread_type": frame.thread_type, "js8mode": frame.mode, } return out except Exception: logger.exception("error while parsing js8 message")
def parse(self, profile: WsjtProfile, freq: int, raw_msg: bytes): try: band = None if freq is not None: band = Bandplan.getSharedInstance().findBand(freq) msg = raw_msg.decode().rstrip() # known debug messages we know to skip if msg.startswith("<DecodeFinished>"): return if msg.startswith(" EOF on input file"): return mode = profile.getMode() if mode in ["WSPR", "FST4W"]: messageParser = BeaconMessageParser() else: messageParser = QsoMessageParser() if mode == "WSPR": decoder = WsprDecoder(profile, messageParser) else: decoder = Jt9Decoder(profile, messageParser) out = decoder.parse(msg, freq) if isinstance(profile, Q65Profile) and not out["msg"]: # all efforts in vain, it's just a potential signal indicator return out["mode"] = mode out["interval"] = profile.getInterval() self.pushDecode(mode, band) if "callsign" in out and "locator" in out: Map.getSharedInstance().updateLocation( out["callsign"], LocatorLocation(out["locator"]), mode, band ) ReportingEngine.getSharedInstance().spot(out) return out except Exception: logger.exception("Exception while parsing wsjt message")
def setDialFrequency(self, freq): self.band = Bandplan.getSharedInstance().findBand(freq)