openwebrx-clone/owrx/service.py

151 lines
4.2 KiB
Python
Raw Normal View History

2019-07-21 21:39:11 +00:00
import threading
from owrx.source import SdrService
from owrx.bands import Bandplan
from csdr import dsp, output
from owrx.wsjt import WsjtParser
from owrx.aprs import AprsParser
2019-07-28 11:29:45 +00:00
from owrx.config import PropertyManager
2019-07-21 21:39:11 +00:00
import logging
logger = logging.getLogger(__name__)
class ServiceOutput(output):
def __init__(self, frequency):
self.frequency = frequency
def getParser(self):
# abstract method; implement in subclasses
pass
def receive_output(self, t, read_fn):
parser = self.getParser()
parser.setDialFrequency(self.frequency)
target = self.pump(read_fn, parser.parse)
2019-07-21 21:39:11 +00:00
threading.Thread(target=target).start()
class WsjtServiceOutput(ServiceOutput):
def getParser(self):
return WsjtParser(WsjtHandler())
def supports_type(self, t):
2019-08-11 09:37:45 +00:00
return t == "wsjt_demod"
2019-07-21 21:39:11 +00:00
class AprsServiceOutput(ServiceOutput):
def getParser(self):
return AprsParser(AprsHandler())
def supports_type(self, t):
return t == "packet_demod"
2019-07-21 21:39:11 +00:00
class ServiceHandler(object):
def __init__(self, source):
self.services = []
self.source = source
self.startupTimer = None
2019-07-21 21:39:11 +00:00
self.source.addClient(self)
self.source.getProps().collect("center_freq", "samp_rate").wire(self.onFrequencyChange)
self.scheduleServiceStartup()
2019-07-21 21:39:11 +00:00
def onSdrAvailable(self):
self.scheduleServiceStartup()
2019-07-21 21:39:11 +00:00
def onSdrUnavailable(self):
self.stopServices()
def isSupported(self, mode):
2019-07-28 11:29:45 +00:00
return mode in PropertyManager.getSharedInstance()["services_decoders"]
2019-07-21 21:39:11 +00:00
def stopServices(self):
for service in self.services:
service.stop()
self.services = []
def startServices(self):
for service in self.services:
service.start()
def onFrequencyChange(self, key, value):
self.stopServices()
2019-07-21 21:39:11 +00:00
if not self.source.isAvailable():
return
self.scheduleServiceStartup()
def scheduleServiceStartup(self):
if self.startupTimer:
self.startupTimer.cancel()
self.startupTimer = threading.Timer(10, self.updateServices)
self.startupTimer.start()
2019-07-28 10:11:22 +00:00
def updateServices(self):
logger.debug("re-scheduling services due to sdr changes")
2019-07-21 21:39:11 +00:00
self.stopServices()
cf = self.source.getProps()["center_freq"]
srh = self.source.getProps()["samp_rate"] / 2
frequency_range = (cf - srh, cf + srh)
2019-08-11 09:37:45 +00:00
self.services = [
self.setupService(dial["mode"], dial["frequency"])
for dial in Bandplan.getSharedInstance().collectDialFrequencies(frequency_range)
if self.isSupported(dial["mode"])
]
2019-07-21 21:39:11 +00:00
def setupService(self, mode, frequency):
logger.debug("setting up service {0} on frequency {1}".format(mode, frequency))
# TODO selecting outputs will need some more intelligence here
if mode == "packet":
output = AprsServiceOutput(frequency)
else:
output = WsjtServiceOutput(frequency)
d = dsp(output)
d.nc_port = self.source.getPort()
2019-07-21 21:39:11 +00:00
d.set_offset_freq(frequency - self.source.getProps()["center_freq"])
2019-08-11 22:02:39 +00:00
if mode == "packet":
d.set_demodulator("nfm")
d.set_bpf(-4000, 4000)
else:
d.set_demodulator("usb")
d.set_bpf(0, 3000)
2019-07-21 21:39:11 +00:00
d.set_secondary_demodulator(mode)
d.set_audio_compression("none")
d.set_samp_rate(self.source.getProps()["samp_rate"])
d.start()
return d
class WsjtHandler(object):
def write_wsjt_message(self, msg):
pass
class AprsHandler(object):
def write_aprs_data(self, data):
pass
2019-07-21 21:39:11 +00:00
class ServiceManager(object):
sharedInstance = None
2019-08-11 09:37:45 +00:00
2019-07-21 21:39:11 +00:00
@staticmethod
def getSharedInstance():
if ServiceManager.sharedInstance is None:
ServiceManager.sharedInstance = ServiceManager()
return ServiceManager.sharedInstance
def start(self):
2019-07-28 11:29:45 +00:00
if not PropertyManager.getSharedInstance()["services_enabled"]:
return
2019-07-21 21:39:11 +00:00
for source in SdrService.getSources().values():
ServiceHandler(source)
class Service(object):
pass
class WsjtService(Service):
pass