mapping sdr device layer
This commit is contained in:
parent
620771eaf2
commit
916f19ac60
122
owrx/sdr.py
122
owrx/sdr.py
@ -1,49 +1,94 @@
|
||||
from owrx.config import Config
|
||||
from owrx.property import PropertyLayer
|
||||
from owrx.property import PropertyManager, PropertyDeleted, PropertyDelegator, PropertyLayer
|
||||
from owrx.feature import FeatureDetector, UnknownFeatureException
|
||||
from owrx.source import SdrSourceState
|
||||
from functools import partial
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SdrService(object):
|
||||
sdrProps = None
|
||||
sources = {}
|
||||
lastPort = None
|
||||
class MappedSdrSources(PropertyDelegator):
|
||||
def __init__(self, pm: PropertyManager):
|
||||
self.subscriptions = {}
|
||||
super().__init__(PropertyLayer())
|
||||
for key, value in pm.items():
|
||||
self._addSource(key, value)
|
||||
pm.wire(self.handleSdrDeviceChange)
|
||||
|
||||
@staticmethod
|
||||
def _loadProps():
|
||||
if SdrService.sdrProps is None:
|
||||
pm = Config.get()
|
||||
featureDetector = FeatureDetector()
|
||||
def handleSdrDeviceChange(self, changes):
|
||||
for key, value in changes.items():
|
||||
if value is PropertyDeleted:
|
||||
del self[key]
|
||||
else:
|
||||
self._addSource(key, value)
|
||||
|
||||
def sdrTypeAvailable(value):
|
||||
try:
|
||||
if not featureDetector.is_available(value["type"]):
|
||||
logger.error(
|
||||
'The SDR source type "{0}" is not available. please check requirements.'.format(
|
||||
value["type"]
|
||||
)
|
||||
)
|
||||
return False
|
||||
return True
|
||||
except UnknownFeatureException:
|
||||
logger.error(
|
||||
'The SDR source type "{0}" is invalid. Please check your configuration'.format(value["type"])
|
||||
def handleDeviceUpdate(self, key, value, changes):
|
||||
if self.isDeviceValid(value) and key not in self:
|
||||
self._addSource(key, value)
|
||||
elif not self.isDeviceValid(value) and key in self:
|
||||
self._removeSource(key)
|
||||
|
||||
def _addSource(self, key, value):
|
||||
if self.isDeviceValid(value):
|
||||
self[key] = self.buildNewSource(key, value)
|
||||
updateMethod = partial(self.handleDeviceUpdate, key, value)
|
||||
self.subscriptions[key] = [
|
||||
value.filter("type", "profiles").wire(updateMethod),
|
||||
value["profiles"].wire(updateMethod)
|
||||
]
|
||||
|
||||
def _removeSource(self, key):
|
||||
if key in self:
|
||||
self[key].shutdown()
|
||||
for sub in self.subscriptions[key]:
|
||||
sub.cancel()
|
||||
del self.subscriptions[key]
|
||||
|
||||
def isDeviceValid(self, device):
|
||||
return self._hasProfiles(device) and self._sdrTypeAvailable(device)
|
||||
|
||||
def _hasProfiles(self, device):
|
||||
return "profiles" in device and device["profiles"] and len(device["profiles"]) > 0
|
||||
|
||||
def _sdrTypeAvailable(self, value):
|
||||
featureDetector = FeatureDetector()
|
||||
try:
|
||||
if not featureDetector.is_available(value["type"]):
|
||||
logger.error(
|
||||
'The SDR source type "{0}" is not available. please check requirements.'.format(
|
||||
value["type"]
|
||||
)
|
||||
return False
|
||||
|
||||
# transform all dictionary items into PropertyManager object, filtering out unavailable ones
|
||||
SdrService.sdrProps = {
|
||||
name: value for (name, value) in pm["sdrs"].items() if sdrTypeAvailable(value)
|
||||
}
|
||||
logger.info(
|
||||
"SDR sources loaded. Available SDRs: {0}".format(
|
||||
", ".join(x["name"] for x in SdrService.sdrProps.values())
|
||||
)
|
||||
return False
|
||||
return True
|
||||
except UnknownFeatureException:
|
||||
logger.error(
|
||||
'The SDR source type "{0}" is invalid. Please check your configuration'.format(value["type"])
|
||||
)
|
||||
return False
|
||||
|
||||
def buildNewSource(self, id, props):
|
||||
sdrType = props["type"]
|
||||
className = "".join(x for x in sdrType.title() if x.isalnum()) + "Source"
|
||||
module = __import__("owrx.source.{0}".format(sdrType), fromlist=[className])
|
||||
cls = getattr(module, className)
|
||||
return cls(id, props)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key in self:
|
||||
self._removeSource(key)
|
||||
super().__setitem__(key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
if key in self:
|
||||
self._removeSource(key)
|
||||
super().__delitem__(key)
|
||||
|
||||
|
||||
class SdrService(object):
|
||||
sources = None
|
||||
|
||||
@staticmethod
|
||||
def getFirstSource():
|
||||
@ -58,21 +103,14 @@ class SdrService(object):
|
||||
sources = SdrService.getSources()
|
||||
if not sources:
|
||||
return None
|
||||
if not id in sources:
|
||||
if id not in sources:
|
||||
return None
|
||||
return sources[id]
|
||||
|
||||
@staticmethod
|
||||
def getSources():
|
||||
SdrService._loadProps()
|
||||
for id in SdrService.sdrProps.keys():
|
||||
if id not in SdrService.sources:
|
||||
props = SdrService.sdrProps[id]
|
||||
sdrType = props["type"]
|
||||
className = "".join(x for x in sdrType.title() if x.isalnum()) + "Source"
|
||||
module = __import__("owrx.source.{0}".format(sdrType), fromlist=[className])
|
||||
cls = getattr(module, className)
|
||||
SdrService.sources[id] = cls(id, props)
|
||||
if SdrService.sources is None:
|
||||
SdrService.sources = MappedSdrSources(Config.get()["sdrs"])
|
||||
return {
|
||||
key: s
|
||||
for key, s in SdrService.sources.items()
|
||||
|
Loading…
Reference in New Issue
Block a user