diff --git a/owrx/controllers/settings/sdr.py b/owrx/controllers/settings/sdr.py index 6dfb68c..871dcb9 100644 --- a/owrx/controllers/settings/sdr.py +++ b/owrx/controllers/settings/sdr.py @@ -48,10 +48,11 @@ class SdrDeviceListController(AuthorizationMixin, WebpageController): ) state_info = ", ".join( - s for s in [ + s + for s in [ str(source.getState()), None if source.isEnabled() else "Disabled", - "Failed" if source.isFailed() else None + "Failed" if source.isFailed() else None, ] if s is not None ) @@ -276,7 +277,11 @@ class NewSdrDeviceController(SettingsFormController): Section( "New device settings", TextInput("name", "Device name", validator=RequiredValidator()), - DropdownInput("type", "Device type", [Option(name, name) for name in SdrDeviceDescription.getTypes()]), + DropdownInput( + "type", + "Device type", + [Option(sdr_type, name) for sdr_type, name in SdrDeviceDescription.getTypes().items()], + ), TextInput("id", "Device ID", validator=RequiredValidator()), ) ] diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py index dcdf338..e97709e 100644 --- a/owrx/source/__init__.py +++ b/owrx/source/__init__.py @@ -17,6 +17,7 @@ from owrx.form.converter import OptionalConverter from owrx.form.device import GainInput, SchedulerInput, WaterfallLevelsInput from owrx.form.validator import RequiredValidator from owrx.controllers.settings import Section +from owrx.feature import FeatureDetector from typing import List from enum import Enum @@ -543,14 +544,27 @@ class SdrDeviceDescription(object): @staticmethod def getTypes(): - def has_description(module_name): + def get_description(module_name): try: - SdrDeviceDescription.getByType(module_name) - return True + description = SdrDeviceDescription.getByType(module_name) + return description.getName() except SdrDeviceDescriptionMissing: - return False + return None - return [module_name for _, module_name, _ in pkgutil.walk_packages(__path__) if has_description(module_name)] + descriptions = { + module_name: get_description(module_name) for _, module_name, _ in pkgutil.walk_packages(__path__) + } + # filter out empty names and unavailable types + fd = FeatureDetector() + return {k: v for k, v in descriptions.items() if v is not None and fd.is_available(k)} + + def getName(self): + """ + must be overridden with a textual representation of the device, to be used for device type selection + + :return: str + """ + return None def getDeviceInputs(self) -> List[Input]: keys = self.getDeviceMandatoryKeys() + self.getDeviceOptionalKeys() diff --git a/owrx/source/airspy.py b/owrx/source/airspy.py index ab201dd..0ee349d 100644 --- a/owrx/source/airspy.py +++ b/owrx/source/airspy.py @@ -20,6 +20,9 @@ class AirspySource(SoapyConnectorSource): class AirspyDeviceDescription(SoapyConnectorDeviceDescription): + def getName(self): + return "Airspy R2 or Mini" + def getInputs(self) -> List[Input]: return super().getInputs() + [ BiasTeeInput(), diff --git a/owrx/source/airspyhf.py b/owrx/source/airspyhf.py index 5995b4b..82cc03b 100644 --- a/owrx/source/airspyhf.py +++ b/owrx/source/airspyhf.py @@ -7,4 +7,5 @@ class AirspyhfSource(SoapyConnectorSource): class AirspyhfDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "Airspy HF+ or Discovery" diff --git a/owrx/source/fcdpp.py b/owrx/source/fcdpp.py index 342ad73..8f9b7af 100644 --- a/owrx/source/fcdpp.py +++ b/owrx/source/fcdpp.py @@ -7,4 +7,5 @@ class FcdppSource(SoapyConnectorSource): class FcdppDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "FunCube Dongle Pro+" diff --git a/owrx/source/fifi_sdr.py b/owrx/source/fifi_sdr.py index 700cb53..cf6e3e7 100644 --- a/owrx/source/fifi_sdr.py +++ b/owrx/source/fifi_sdr.py @@ -40,4 +40,5 @@ class FifiSdrSource(DirectSource): class FifiSdrDeviceDescription(DirectSourceDeviceDescription): - pass + def getName(self): + return "FiFi SDR" diff --git a/owrx/source/hackrf.py b/owrx/source/hackrf.py index db67d0b..59d2499 100644 --- a/owrx/source/hackrf.py +++ b/owrx/source/hackrf.py @@ -15,6 +15,9 @@ class HackrfSource(SoapyConnectorSource): class HackrfDeviceDescription(SoapyConnectorDeviceDescription): + def getName(self): + return "HackRF" + def getInputs(self) -> List[Input]: return super().getInputs() + [BiasTeeInput()] diff --git a/owrx/source/hpsdr.py b/owrx/source/hpsdr.py index 63571d0..b0ee66c 100644 --- a/owrx/source/hpsdr.py +++ b/owrx/source/hpsdr.py @@ -36,4 +36,5 @@ class HpsdrSource(ConnectorSource): class HpsdrDeviceDescription(ConnectorDeviceDescription): - pass + def getName(self): + return "HPSDR devices (Hermes / Hermes Lite 2 / Red Pitaya)" diff --git a/owrx/source/lime_sdr.py b/owrx/source/lime_sdr.py index dedfacf..f7e6ba4 100644 --- a/owrx/source/lime_sdr.py +++ b/owrx/source/lime_sdr.py @@ -7,4 +7,5 @@ class LimeSdrSource(SoapyConnectorSource): class LimeSdrDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "LimeSDR device" diff --git a/owrx/source/perseussdr.py b/owrx/source/perseussdr.py index 3a8d4d4..2b961fa 100644 --- a/owrx/source/perseussdr.py +++ b/owrx/source/perseussdr.py @@ -50,6 +50,9 @@ class AttenuatorOptions(DropdownEnum): class PerseussdrDeviceDescription(DirectSourceDeviceDescription): + def getName(self): + return "Perseus SDR" + def getInputs(self) -> List[Input]: return super().getInputs() + [ DropdownInput("attenuator", "Attenuator", options=AttenuatorOptions), diff --git a/owrx/source/pluto_sdr.py b/owrx/source/pluto_sdr.py index 1f6dad1..593b5c7 100644 --- a/owrx/source/pluto_sdr.py +++ b/owrx/source/pluto_sdr.py @@ -7,4 +7,5 @@ class PlutoSdrSource(SoapyConnectorSource): class PlutoSdrDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "PlutoSDR" diff --git a/owrx/source/radioberry.py b/owrx/source/radioberry.py index 2ec0e09..932a5e4 100644 --- a/owrx/source/radioberry.py +++ b/owrx/source/radioberry.py @@ -7,4 +7,5 @@ class RadioberrySource(SoapyConnectorSource): class RadioberryDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "RadioBerry" diff --git a/owrx/source/rtl_sdr.py b/owrx/source/rtl_sdr.py index 1c84ab0..fc6a2d0 100644 --- a/owrx/source/rtl_sdr.py +++ b/owrx/source/rtl_sdr.py @@ -16,6 +16,9 @@ class RtlSdrSource(ConnectorSource): class RtlSdrDeviceDescription(ConnectorDeviceDescription): + def getName(self): + return "RTL-SDR device" + def getInputs(self) -> List[Input]: return super().getInputs() + [ TextInput( diff --git a/owrx/source/rtl_sdr_soapy.py b/owrx/source/rtl_sdr_soapy.py index 8016e7c..0908c5e 100644 --- a/owrx/source/rtl_sdr_soapy.py +++ b/owrx/source/rtl_sdr_soapy.py @@ -15,6 +15,9 @@ class RtlSdrSoapySource(SoapyConnectorSource): class RtlSdrSoapyDeviceDescription(SoapyConnectorDeviceDescription): + def getName(self): + return "RTL-SDR device (via SoapySDR)" + def getInputs(self) -> List[Input]: return super().getInputs() + [BiasTeeInput(), DirectSamplingInput()] diff --git a/owrx/source/rtl_tcp.py b/owrx/source/rtl_tcp.py index 59047bd..fe65181 100644 --- a/owrx/source/rtl_tcp.py +++ b/owrx/source/rtl_tcp.py @@ -22,6 +22,9 @@ class RtlTcpSource(ConnectorSource): class RtlTcpDeviceDescription(ConnectorDeviceDescription): + def getName(self): + return "RTL-SDR device (via rtl_tcp)" + def getInputs(self) -> List[Input]: return super().getInputs() + [RemoteInput()] diff --git a/owrx/source/runds.py b/owrx/source/runds.py index 09927ff..cd3f342 100644 --- a/owrx/source/runds.py +++ b/owrx/source/runds.py @@ -37,6 +37,9 @@ class ProtocolOptions(DropdownEnum): class RundsDeviceDescription(ConnectorDeviceDescription): + def getName(self): + return "R&S device using EB200 or Ammos protocol" + def getInputs(self) -> List[Input]: return super().getInputs() + [ RemoteInput(), diff --git a/owrx/source/sddc.py b/owrx/source/sddc.py index b9d8916..5c3255f 100644 --- a/owrx/source/sddc.py +++ b/owrx/source/sddc.py @@ -7,5 +7,8 @@ class SddcSource(ConnectorSource): class SddcDeviceDescription(ConnectorDeviceDescription): + def getName(self): + return "BBRF103 / RX666 / RX888 device (libsddc)" + def hasAgc(self): return False diff --git a/owrx/source/sdrplay.py b/owrx/source/sdrplay.py index b3a7741..25745f3 100644 --- a/owrx/source/sdrplay.py +++ b/owrx/source/sdrplay.py @@ -33,6 +33,9 @@ class IfModeOptions(DropdownEnum): class SdrplayDeviceDescription(SoapyConnectorDeviceDescription): + def getName(self): + return "SDRPlay device (RSP1, RSP2, RSPDuo, RSPDx)" + def getGainStages(self): return ["RFGR", "IFGR"] diff --git a/owrx/source/soapy_remote.py b/owrx/source/soapy_remote.py index 7abe1e4..bc507a2 100644 --- a/owrx/source/soapy_remote.py +++ b/owrx/source/soapy_remote.py @@ -21,6 +21,9 @@ class SoapyRemoteSource(SoapyConnectorSource): class SoapyRemoteDeviceDescription(SoapyConnectorDeviceDescription): + def getName(self): + return "Device connected to a SoapyRemote server" + def getInputs(self) -> List[Input]: return super().getInputs() + [ RemoteInput(), diff --git a/owrx/source/uhd.py b/owrx/source/uhd.py index 97418d8..56f66b6 100644 --- a/owrx/source/uhd.py +++ b/owrx/source/uhd.py @@ -7,4 +7,5 @@ class UhdSource(SoapyConnectorSource): class UhdDeviceDescription(SoapyConnectorDeviceDescription): - pass + def getName(self): + return "Ettus Research USRP device"