introduce the basic concept of optional keys

This commit is contained in:
Jakob Ketterl 2021-02-22 00:35:47 +01:00
parent 683a711b49
commit 770fd749cd
12 changed files with 146 additions and 122 deletions

View File

@ -71,7 +71,7 @@ class SdrDeviceController(SettingsFormController):
def getSections(self):
try:
description = SdrDeviceDescription.getByType(self.device["type"])
return [description.getSection()]
return [description.getSection(self.device)]
except SdrDeviceDescriptionMissing:
# TODO provide a generic interface that allows to switch the type
return []

View File

@ -376,6 +376,9 @@ class SdrDeviceDescriptionMissing(Exception):
class SdrDeviceDescription(object):
def __init__(self):
self.indexedInputs = {input.id: input for input in self.getInputs()}
@staticmethod
def getByType(sdr_type: str) -> "SdrDeviceDescription":
try:
@ -423,10 +426,14 @@ class SdrDeviceDescription(object):
# TODO `schedule`
]
def mergeInputs(self, *args):
# build a dictionary indexed by the input id to make sure every id only exists once
inputs = {input.id: input for input_list in args for input in input_list}
return inputs.values()
def getMandatoryKeys(self):
return ["name", "enabled"]
def getSection(self):
return Section("Device settings", *self.getInputs())
def getOptionalKeys(self):
return ["ppm", "always-on", "services", "rf_gain", "lfo_offset", "waterfall_min_level", "waterfall_max_level"]
def getSection(self, data):
visible_keys = set(self.getMandatoryKeys() + [k for k in self.getOptionalKeys() if k in data])
inputs = [input for k, input in self.indexedInputs.items() if k in visible_keys]
# TODO: render remaining keys in optional area
return Section("Device settings", *inputs)

View File

@ -22,9 +22,7 @@ class AirspySource(SoapyConnectorSource):
class AirspyDeviceDescription(SoapyConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
BiasTeeInput(),
CheckboxInput(
"bitpack",
@ -34,5 +32,11 @@ class AirspyDeviceDescription(SoapyConnectorDeviceDescription):
+ " Lowers USB bandwidth consumption, increases CPU load",
converter=OptionalConverter(defaultFormValue=False),
),
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["bias_tee", "bitpack"]
# TODO: find actual gain stages for airspay
# def getGainStages(self):
# return None

View File

@ -76,9 +76,7 @@ class ConnectorSource(SdrSource):
class ConnectorDeviceDescription(SdrDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
NumberInput(
"rtltcp_compat",
"Port for rtl_tcp compatible data",
@ -94,5 +92,7 @@ class ConnectorDeviceDescription(SdrDeviceDescription):
infotext="Swapping inverts the spectrum, so this is useful in combination with an inverting mixer",
converter=OptionalConverter(defaultFormValue=False),
),
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["rtltcp_compat", "iqswap"]

View File

@ -16,4 +16,11 @@ class HackrfSource(SoapyConnectorSource):
class HackrfDeviceDescription(SoapyConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(super().getInputs(), [BiasTeeInput()])
return super().getInputs() + [BiasTeeInput()]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["bias_tee"]
# TODO: find actual gain stages for hackrf
# def getGainStages(self):
# return None

View File

@ -18,9 +18,7 @@ class RtlSdrSource(ConnectorSource):
class RtlSdrDeviceDescription(ConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
TextInput(
"device",
"Device identifier",
@ -29,5 +27,7 @@ class RtlSdrDeviceDescription(ConnectorDeviceDescription):
),
BiasTeeInput(),
DirectSamplingInput()
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["device", "bias_tee", "direct_sampling"]

View File

@ -16,4 +16,7 @@ class RtlSdrSoapySource(SoapyConnectorSource):
class RtlSdrSoapyDeviceDescription(SoapyConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(super().getInputs(), [BiasTeeInput(), DirectSamplingInput()])
return super().getInputs() + [BiasTeeInput(), DirectSamplingInput()]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["bias_tee", "direct_sampling"]

View File

@ -23,4 +23,7 @@ class RtlTcpSource(ConnectorSource):
class RtlTcpDeviceDescription(ConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(super().getInputs(), [RemoteInput()])
return super().getInputs() + [RemoteInput()]
def getMandatoryKeys(self):
return super().getMandatoryKeys() + ["device"]

View File

@ -39,13 +39,13 @@ class ProtocolOptions(DropdownEnum):
class RundsDeviceDescription(ConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
RemoteInput(),
DropdownInput("protocol", "Protocol", ProtocolOptions),
CheckboxInput(
"long", "", "Use 32-bit sample size (LONG)", converter=OptionalConverter(defaultFormValue=False)
),
],
)
]
def getMandatoryKeys(self):
return super().getMandatoryKeys() + ["device"]

View File

@ -38,9 +38,7 @@ class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
return ["RFGR", "IFGR"]
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
BiasTeeInput(),
CheckboxInput(
"rf_notch",
@ -62,5 +60,7 @@ class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
EnumConverter(IfModeOptions), defaultFormValue=IfModeOptions.IFMODE_ZERO_IF.name
),
),
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["bias_tee", "rf_notch", "dab_notch", "if_mode"]

View File

@ -84,9 +84,7 @@ class SoapyConnectorSource(ConnectorSource, metaclass=ABCMeta):
class SoapyConnectorDeviceDescription(ConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
TextInput(
"device",
"Device Identifier",
@ -103,8 +101,10 @@ class SoapyConnectorDeviceDescription(ConnectorDeviceDescription):
"Antenna",
converter=OptionalConverter(),
),
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["device", "rf_gain", "antenna"]
def getGainStages(self):
return None

View File

@ -22,12 +22,12 @@ class SoapyRemoteSource(SoapyConnectorSource):
class SoapyRemoteDeviceDescription(SoapyConnectorDeviceDescription):
def getInputs(self) -> List[Input]:
return self.mergeInputs(
super().getInputs(),
[
return super().getInputs() + [
RemoteInput(),
TextInput(
"remote_driver", "Remote driver", infotext="SoapySDR driver to be used on the remote SoapySDRServer"
),
],
)
]
def getOptionalKeys(self):
return super().getOptionalKeys() + ["remote_driver"]