introduce the basic concept of optional keys
This commit is contained in:
parent
683a711b49
commit
770fd749cd
@ -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 []
|
||||
|
@ -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)
|
||||
|
@ -22,17 +22,21 @@ class AirspySource(SoapyConnectorSource):
|
||||
|
||||
class AirspyDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
BiasTeeInput(),
|
||||
CheckboxInput(
|
||||
"bitpack",
|
||||
"",
|
||||
checkboxText="Enable bit-packing",
|
||||
infotext="Packs two 12-bit samples into 3 bytes."
|
||||
+ " Lowers USB bandwidth consumption, increases CPU load",
|
||||
converter=OptionalConverter(defaultFormValue=False),
|
||||
),
|
||||
],
|
||||
)
|
||||
return super().getInputs() + [
|
||||
BiasTeeInput(),
|
||||
CheckboxInput(
|
||||
"bitpack",
|
||||
"",
|
||||
checkboxText="Enable bit-packing",
|
||||
infotext="Packs two 12-bit samples into 3 bytes."
|
||||
+ " 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
|
||||
|
@ -76,23 +76,23 @@ class ConnectorSource(SdrSource):
|
||||
|
||||
class ConnectorDeviceDescription(SdrDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
NumberInput(
|
||||
"rtltcp_compat",
|
||||
"Port for rtl_tcp compatible data",
|
||||
infotext="Activate an rtl_tcp compatible interface on the port number specified.<br />"
|
||||
+ "Note: Port is only available on the local machine, not on the network.<br />"
|
||||
+ "Note: IQ data may be degraded by the downsampling process to 8 bits.",
|
||||
converter=OptionalConverter(IntConverter()),
|
||||
),
|
||||
CheckboxInput(
|
||||
"iqswap",
|
||||
"",
|
||||
checkboxText="Swap I and Q channels",
|
||||
infotext="Swapping inverts the spectrum, so this is useful in combination with an inverting mixer",
|
||||
converter=OptionalConverter(defaultFormValue=False),
|
||||
),
|
||||
],
|
||||
)
|
||||
return super().getInputs() + [
|
||||
NumberInput(
|
||||
"rtltcp_compat",
|
||||
"Port for rtl_tcp compatible data",
|
||||
infotext="Activate an rtl_tcp compatible interface on the port number specified.<br />"
|
||||
+ "Note: Port is only available on the local machine, not on the network.<br />"
|
||||
+ "Note: IQ data may be degraded by the downsampling process to 8 bits.",
|
||||
converter=OptionalConverter(IntConverter()),
|
||||
),
|
||||
CheckboxInput(
|
||||
"iqswap",
|
||||
"",
|
||||
checkboxText="Swap I and Q channels",
|
||||
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"]
|
||||
|
@ -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
|
||||
|
@ -18,16 +18,16 @@ class RtlSdrSource(ConnectorSource):
|
||||
|
||||
class RtlSdrDeviceDescription(ConnectorDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
TextInput(
|
||||
"device",
|
||||
"Device identifier",
|
||||
infotext="Device serial number or index",
|
||||
converter=OptionalConverter(),
|
||||
),
|
||||
BiasTeeInput(),
|
||||
DirectSamplingInput()
|
||||
],
|
||||
)
|
||||
return super().getInputs() + [
|
||||
TextInput(
|
||||
"device",
|
||||
"Device identifier",
|
||||
infotext="Device serial number or index",
|
||||
converter=OptionalConverter(),
|
||||
),
|
||||
BiasTeeInput(),
|
||||
DirectSamplingInput()
|
||||
]
|
||||
|
||||
def getOptionalKeys(self):
|
||||
return super().getOptionalKeys() + ["device", "bias_tee", "direct_sampling"]
|
||||
|
@ -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"]
|
||||
|
@ -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"]
|
||||
|
@ -39,13 +39,13 @@ class ProtocolOptions(DropdownEnum):
|
||||
|
||||
class RundsDeviceDescription(ConnectorDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
RemoteInput(),
|
||||
DropdownInput("protocol", "Protocol", ProtocolOptions),
|
||||
CheckboxInput(
|
||||
"long", "", "Use 32-bit sample size (LONG)", converter=OptionalConverter(defaultFormValue=False)
|
||||
),
|
||||
],
|
||||
)
|
||||
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"]
|
||||
|
@ -38,29 +38,29 @@ class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
return ["RFGR", "IFGR"]
|
||||
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
BiasTeeInput(),
|
||||
CheckboxInput(
|
||||
"rf_notch",
|
||||
"",
|
||||
checkboxText="Enable RF notch filter",
|
||||
converter=OptionalConverter(defaultFormValue=True),
|
||||
return super().getInputs() + [
|
||||
BiasTeeInput(),
|
||||
CheckboxInput(
|
||||
"rf_notch",
|
||||
"",
|
||||
checkboxText="Enable RF notch filter",
|
||||
converter=OptionalConverter(defaultFormValue=True),
|
||||
),
|
||||
CheckboxInput(
|
||||
"dab_notch",
|
||||
"",
|
||||
checkboxText="Enable DAB notch filter",
|
||||
converter=OptionalConverter(defaultFormValue=True),
|
||||
),
|
||||
DropdownInput(
|
||||
"if_mode",
|
||||
"IF Mode",
|
||||
IfModeOptions,
|
||||
converter=OptionalConverter(
|
||||
EnumConverter(IfModeOptions), defaultFormValue=IfModeOptions.IFMODE_ZERO_IF.name
|
||||
),
|
||||
CheckboxInput(
|
||||
"dab_notch",
|
||||
"",
|
||||
checkboxText="Enable DAB notch filter",
|
||||
converter=OptionalConverter(defaultFormValue=True),
|
||||
),
|
||||
DropdownInput(
|
||||
"if_mode",
|
||||
"IF Mode",
|
||||
IfModeOptions,
|
||||
converter=OptionalConverter(
|
||||
EnumConverter(IfModeOptions), defaultFormValue=IfModeOptions.IFMODE_ZERO_IF.name
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
]
|
||||
|
||||
def getOptionalKeys(self):
|
||||
return super().getOptionalKeys() + ["bias_tee", "rf_notch", "dab_notch", "if_mode"]
|
||||
|
@ -84,27 +84,27 @@ class SoapyConnectorSource(ConnectorSource, metaclass=ABCMeta):
|
||||
|
||||
class SoapyConnectorDeviceDescription(ConnectorDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
TextInput(
|
||||
"device",
|
||||
"Device Identifier",
|
||||
infotext='SoapySDR device identifier string (example: "serial=123456789")',
|
||||
converter=OptionalConverter()
|
||||
),
|
||||
GainInput(
|
||||
"rf_gain",
|
||||
"Device Gain",
|
||||
gain_stages=self.getGainStages(),
|
||||
),
|
||||
TextInput(
|
||||
"antenna",
|
||||
"Antenna",
|
||||
converter=OptionalConverter(),
|
||||
),
|
||||
],
|
||||
)
|
||||
return super().getInputs() + [
|
||||
TextInput(
|
||||
"device",
|
||||
"Device Identifier",
|
||||
infotext='SoapySDR device identifier string (example: "serial=123456789")',
|
||||
converter=OptionalConverter()
|
||||
),
|
||||
GainInput(
|
||||
"rf_gain",
|
||||
"Device Gain",
|
||||
gain_stages=self.getGainStages(),
|
||||
),
|
||||
TextInput(
|
||||
"antenna",
|
||||
"Antenna",
|
||||
converter=OptionalConverter(),
|
||||
),
|
||||
]
|
||||
|
||||
def getOptionalKeys(self):
|
||||
return super().getOptionalKeys() + ["device", "rf_gain", "antenna"]
|
||||
|
||||
def getGainStages(self):
|
||||
return None
|
||||
|
@ -22,12 +22,12 @@ class SoapyRemoteSource(SoapyConnectorSource):
|
||||
|
||||
class SoapyRemoteDeviceDescription(SoapyConnectorDeviceDescription):
|
||||
def getInputs(self) -> List[Input]:
|
||||
return self.mergeInputs(
|
||||
super().getInputs(),
|
||||
[
|
||||
RemoteInput(),
|
||||
TextInput(
|
||||
"remote_driver", "Remote driver", infotext="SoapySDR driver to be used on the remote SoapySDRServer"
|
||||
),
|
||||
],
|
||||
)
|
||||
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"]
|
||||
|
Loading…
Reference in New Issue
Block a user