from owrx.form import Input, CheckboxInput, DropdownInput, DropdownEnum, TextInput from owrx.form.converter import OptionalConverter, EnumConverter from owrx.soapy import SoapySettings class GainInput(Input): def __init__(self, id, label, gain_stages=None): super().__init__(id, label) self.gain_stages = gain_stages def render_input(self, value): try: display_value = float(value) except (ValueError, TypeError): display_value = "0.0" return """
{stageoption}
""".format( id=self.id, classes=self.input_classes(), value=display_value, label=self.label, options=self.render_options(value), stageoption="" if self.gain_stages is None else self.render_stage_option(value), disabled="disabled" if self.disabled else "" ) def render_options(self, value): options = [ ("auto", "Enable hardware AGC"), ("manual", "Specify manual gain"), ] if self.gain_stages: options.append(("stages", "Specify gain stages individually")) mode = self.getMode(value) return "".join( """ """.format( value=v[0], text=v[1], selected="selected" if mode == v[0] else "" ) for v in options ) def getMode(self, value): if value is None or value == "auto": return "auto" try: float(value) return "manual" except (ValueError, TypeError): pass return "stages" def render_stage_option(self, value): try: value_dict = {k: v for item in SoapySettings.parse(value) for k, v in item.items()} except (AttributeError, ValueError): value_dict = {} return """ """.format( inputs="".join( """
""".format( id=self.id, stage=stage, value=value_dict[stage] if stage in value_dict else "", classes=self.input_classes(), disabled="disabled" if self.disabled else "", ) for stage in self.gain_stages ) ) def parse(self, data): def getStageValue(stage): input_id = "{id}-{stage}".format(id=self.id, stage=stage) if input_id in data: return data[input_id][0] else: return None select_id = "{id}-select".format(id=self.id) if select_id in data: if data[select_id][0] == "manual": input_id = "{id}-manual".format(id=self.id) value = 0.0 if input_id in data: try: value = float(data[input_id][0]) except ValueError: pass return {self.id: value} if self.gain_stages is not None and data[select_id][0] == "stages": settings_dict = [{s: getStageValue(s)} for s in self.gain_stages] # filter out empty ones settings_dict = [s for s in settings_dict if next(iter(s.values()))] return {self.id: SoapySettings.encode(settings_dict)} return {self.id: None} class BiasTeeInput(CheckboxInput): def __init__(self): super().__init__( "bias_tee", "Enable Bias-Tee power supply", converter=OptionalConverter(defaultFormValue=False) ) class DirectSamplingOptions(DropdownEnum): DIRECT_SAMPLING_OFF = (0, "Off") DIRECT_SAMPLING_I = (1, "Direct Sampling (I branch)") DIRECT_SAMPLING_Q = (2, "Direct Sampling (Q branch)") def __new__(cls, *args, **kwargs): value, description = args obj = object.__new__(cls) obj._value_ = value obj.description = description return obj def __str__(self): return self.description class DirectSamplingInput(DropdownInput): def __init__(self): super().__init__( "direct_sampling", "Direct Sampling", DirectSamplingOptions, converter=OptionalConverter( EnumConverter(DirectSamplingOptions), defaultFormValue=DirectSamplingOptions.DIRECT_SAMPLING_OFF.name, ), ) class RemoteInput(TextInput): def __init__(self): super().__init__( "remote", "Remote IP and Port", infotext="Remote hostname or IP and port to connect to. Format = IP:Port" )