allow underlying mode to be specified in bandplan
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
from owrx.modes import Modes
 | 
					from owrx.modes import Modes, DigitalMode
 | 
				
			||||||
from datetime import datetime, timezone
 | 
					from datetime import datetime, timezone
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
@@ -9,14 +9,14 @@ logger = logging.getLogger(__name__)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Band(object):
 | 
					class Band(object):
 | 
				
			||||||
    def __init__(self, dict):
 | 
					    def __init__(self, b_dict):
 | 
				
			||||||
        self.name = dict["name"]
 | 
					        self.name = b_dict["name"]
 | 
				
			||||||
        self.lower_bound = dict["lower_bound"]
 | 
					        self.lower_bound = b_dict["lower_bound"]
 | 
				
			||||||
        self.upper_bound = dict["upper_bound"]
 | 
					        self.upper_bound = b_dict["upper_bound"]
 | 
				
			||||||
        self.frequencies = []
 | 
					        self.frequencies = []
 | 
				
			||||||
        if "frequencies" in dict:
 | 
					        if "frequencies" in b_dict:
 | 
				
			||||||
            availableModes = [mode.modulation for mode in Modes.getAvailableModes()]
 | 
					            availableModes = [mode.modulation for mode in Modes.getAvailableModes()]
 | 
				
			||||||
            for (mode, freqs) in dict["frequencies"].items():
 | 
					            for (mode, freqs) in b_dict["frequencies"].items():
 | 
				
			||||||
                if mode not in availableModes:
 | 
					                if mode not in availableModes:
 | 
				
			||||||
                    logger.info(
 | 
					                    logger.info(
 | 
				
			||||||
                        'Modulation "{mode}" is not available, bandplan bookmark will not be displayed'.format(
 | 
					                        'Modulation "{mode}" is not available, bandplan bookmark will not be displayed'.format(
 | 
				
			||||||
@@ -27,14 +27,30 @@ class Band(object):
 | 
				
			|||||||
                if not isinstance(freqs, list):
 | 
					                if not isinstance(freqs, list):
 | 
				
			||||||
                    freqs = [freqs]
 | 
					                    freqs = [freqs]
 | 
				
			||||||
                for f in freqs:
 | 
					                for f in freqs:
 | 
				
			||||||
                    if not self.inBand(f):
 | 
					                    f_dict = {"frequency": f} if not isinstance(f, dict) else f
 | 
				
			||||||
 | 
					                    f_dict["mode"] = mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if not self.inBand(f_dict["frequency"]):
 | 
				
			||||||
                        logger.warning(
 | 
					                        logger.warning(
 | 
				
			||||||
                            "Frequency for {mode} on {band} is not within band limits: {frequency}".format(
 | 
					                            "Frequency for {mode} on {band} is not within band limits: {frequency}".format(
 | 
				
			||||||
                                mode=mode, frequency=f, band=self.name
 | 
					                                mode=mode, frequency=f_dict["frequency"], band=self.name
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                        continue
 | 
					                        continue
 | 
				
			||||||
                    self.frequencies.append({"mode": mode, "frequency": f})
 | 
					
 | 
				
			||||||
 | 
					                    if "underlying" in f_dict:
 | 
				
			||||||
 | 
					                        m = Modes.findByModulation(mode)
 | 
				
			||||||
 | 
					                        if not isinstance(m, DigitalMode):
 | 
				
			||||||
 | 
					                            logger.warning("%s is not a digital mode, cannot be used with \"underlying\" config", mode)
 | 
				
			||||||
 | 
					                            continue
 | 
				
			||||||
 | 
					                        if f_dict["underlying"] not in m.underlying:
 | 
				
			||||||
 | 
					                            logger.warning(
 | 
				
			||||||
 | 
					                                "%s is not a valid underlying mode for %s; skipping",
 | 
				
			||||||
 | 
					                                f_dict["underlying"],
 | 
				
			||||||
 | 
					                                mode
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    self.frequencies.append(f_dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def inBand(self, freq):
 | 
					    def inBand(self, freq):
 | 
				
			||||||
        return self.lower_bound <= freq <= self.upper_bound
 | 
					        return self.lower_bound <= freq <= self.upper_bound
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,6 +55,13 @@ class DigitalMode(Mode):
 | 
				
			|||||||
    def get_modulation(self):
 | 
					    def get_modulation(self):
 | 
				
			||||||
        return self.get_underlying_mode().get_modulation()
 | 
					        return self.get_underlying_mode().get_modulation()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def for_underlying(self, underlying: str):
 | 
				
			||||||
 | 
					        if underlying not in self.underlying:
 | 
				
			||||||
 | 
					            raise ValueError("{} is not a valid underlying mode for {}".format(underlying, self.modulation))
 | 
				
			||||||
 | 
					        return DigitalMode(
 | 
				
			||||||
 | 
					            self.modulation, self.name, [underlying], self.bandpass, self.requirements, self.service, self.squelch
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AudioChopperMode(DigitalMode, metaclass=ABCMeta):
 | 
					class AudioChopperMode(DigitalMode, metaclass=ABCMeta):
 | 
				
			||||||
    def __init__(self, modulation, name, bandpass=None, requirements=None):
 | 
					    def __init__(self, modulation, name, bandpass=None, requirements=None):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -123,13 +123,11 @@ class ServiceHandler(SdrSourceEventClient):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def updateServices(self):
 | 
					    def updateServices(self):
 | 
				
			||||||
        def addService(dial, source):
 | 
					        def addService(dial, source):
 | 
				
			||||||
            mode = dial["mode"]
 | 
					 | 
				
			||||||
            frequency = dial["frequency"]
 | 
					 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                service = self.setupService(mode, frequency, source)
 | 
					                service = self.setupService(dial, source)
 | 
				
			||||||
                self.services.append(service)
 | 
					                self.services.append(service)
 | 
				
			||||||
            except Exception:
 | 
					            except Exception:
 | 
				
			||||||
                logger.exception("Error setting up service %s on frequency %d", mode, frequency)
 | 
					                logger.exception("Error setting up service {mode} on frequency {frequency}".format(**dial))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.lock:
 | 
					        with self.lock:
 | 
				
			||||||
            logger.debug("re-scheduling services due to sdr changes")
 | 
					            logger.debug("re-scheduling services due to sdr changes")
 | 
				
			||||||
@@ -247,23 +245,26 @@ class ServiceHandler(SdrSourceEventClient):
 | 
				
			|||||||
            return None
 | 
					            return None
 | 
				
			||||||
        return best["groups"]
 | 
					        return best["groups"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setupService(self, mode, frequency, source):
 | 
					    def setupService(self, dial, source):
 | 
				
			||||||
        logger.debug("setting up service {0} on frequency {1}".format(mode, frequency))
 | 
					        logger.debug("setting up service {mode} on frequency {frequency}".format(**dial))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        modeObject = Modes.findByModulation(mode)
 | 
					        modeObject = Modes.findByModulation(dial["mode"])
 | 
				
			||||||
        if not isinstance(modeObject, DigitalMode):
 | 
					        if not isinstance(modeObject, DigitalMode):
 | 
				
			||||||
            logger.warning("mode is not a digimode: %s", mode)
 | 
					            logger.warning("mode is not a digimode: %s", dial["mode"])
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if "underlying" in dial:
 | 
				
			||||||
 | 
					            modeObject = modeObject.for_underlying(dial["underlying"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        demod = self._getDemodulator(modeObject.get_modulation())
 | 
					        demod = self._getDemodulator(modeObject.get_modulation())
 | 
				
			||||||
        secondaryDemod = self._getSecondaryDemodulator(modeObject.modulation)
 | 
					        secondaryDemod = self._getSecondaryDemodulator(modeObject.modulation)
 | 
				
			||||||
        center_freq = source.getProps()["center_freq"]
 | 
					        center_freq = source.getProps()["center_freq"]
 | 
				
			||||||
        sampleRate = source.getProps()["samp_rate"]
 | 
					        sampleRate = source.getProps()["samp_rate"]
 | 
				
			||||||
        bandpass = modeObject.get_bandpass()
 | 
					        bandpass = modeObject.get_bandpass()
 | 
				
			||||||
        if isinstance(secondaryDemod, DialFrequencyReceiver):
 | 
					        if isinstance(secondaryDemod, DialFrequencyReceiver):
 | 
				
			||||||
            secondaryDemod.setDialFrequency(frequency)
 | 
					            secondaryDemod.setDialFrequency(dial["frequency"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        chain = ServiceDemodulatorChain(demod, secondaryDemod, sampleRate, frequency - center_freq)
 | 
					        chain = ServiceDemodulatorChain(demod, secondaryDemod, sampleRate, dial["frequency"] - center_freq)
 | 
				
			||||||
        chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
 | 
					        chain.setBandPass(bandpass.low_cut, bandpass.high_cut)
 | 
				
			||||||
        chain.setReader(source.getBuffer().getReader())
 | 
					        chain.setReader(source.getBuffer().getReader())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user