2021-02-19 14:29:17 +00:00
|
|
|
from owrx.source import SdrSource, SdrDeviceDescription
|
2019-12-21 19:58:28 +00:00
|
|
|
from owrx.socket import getAvailablePort
|
2021-05-03 17:28:03 +00:00
|
|
|
from owrx.property import PropertyDeleted
|
2019-12-21 19:58:28 +00:00
|
|
|
import socket
|
2021-02-19 14:29:17 +00:00
|
|
|
from owrx.command import Flag, Option
|
2021-02-19 15:29:30 +00:00
|
|
|
from typing import List
|
2021-04-29 13:17:21 +00:00
|
|
|
from owrx.form.input import Input, NumberInput, CheckboxInput
|
2019-12-21 19:58:28 +00:00
|
|
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class ConnectorSource(SdrSource):
|
2019-12-31 14:24:11 +00:00
|
|
|
def __init__(self, id, props):
|
2019-12-21 19:58:28 +00:00
|
|
|
self.controlSocket = None
|
|
|
|
self.controlPort = getAvailablePort()
|
2019-12-31 18:14:05 +00:00
|
|
|
super().__init__(id, props)
|
|
|
|
|
|
|
|
def getCommandMapper(self):
|
2021-01-20 16:01:46 +00:00
|
|
|
return (
|
|
|
|
super()
|
|
|
|
.getCommandMapper()
|
|
|
|
.setMappings(
|
|
|
|
{
|
2022-08-11 22:41:52 +00:00
|
|
|
"samp_rate": Option("--samplerate"),
|
|
|
|
"tuner_freq": Option("--frequency"),
|
|
|
|
"port": Option("--port"),
|
|
|
|
"controlPort": Option("--control"),
|
|
|
|
"device": Option("--device"),
|
|
|
|
"iqswap": Flag("--iqswap"),
|
|
|
|
"rtltcp_compat": Option("--rtltcp"),
|
|
|
|
"ppm": Option("--ppm"),
|
|
|
|
"rf_gain": Option("--gain"),
|
2021-01-20 16:01:46 +00:00
|
|
|
}
|
|
|
|
)
|
2019-12-28 00:24:07 +00:00
|
|
|
)
|
2019-12-21 19:58:28 +00:00
|
|
|
|
2020-12-30 16:18:46 +00:00
|
|
|
def sendControlMessage(self, changes):
|
|
|
|
for prop, value in changes.items():
|
2021-05-03 17:28:03 +00:00
|
|
|
if value is PropertyDeleted:
|
|
|
|
value = None
|
2020-12-30 16:18:46 +00:00
|
|
|
logger.debug("sending property change over control socket: {0} changed to {1}".format(prop, value))
|
|
|
|
self.controlSocket.sendall("{prop}:{value}\n".format(prop=prop, value=value).encode())
|
2019-12-21 19:58:28 +00:00
|
|
|
|
2020-12-30 16:18:46 +00:00
|
|
|
def onPropertyChange(self, changes):
|
2019-12-27 23:26:45 +00:00
|
|
|
if self.monitor is None:
|
|
|
|
return
|
|
|
|
if (
|
2020-12-30 16:18:46 +00:00
|
|
|
("center_freq" in changes or "lfo_offset" in changes)
|
2020-03-24 21:52:17 +00:00
|
|
|
and "lfo_offset" in self.sdrProps
|
|
|
|
and self.sdrProps["lfo_offset"] is not None
|
2019-12-27 23:26:45 +00:00
|
|
|
):
|
2020-12-30 16:18:46 +00:00
|
|
|
changes["center_freq"] = self.sdrProps["center_freq"] + self.sdrProps["lfo_offset"]
|
|
|
|
changes.pop("lfo_offset", None)
|
|
|
|
self.sendControlMessage(changes)
|
2019-12-21 19:58:28 +00:00
|
|
|
|
|
|
|
def postStart(self):
|
|
|
|
logger.debug("opening control socket...")
|
|
|
|
self.controlSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
self.controlSocket.connect(("localhost", self.controlPort))
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
super().stop()
|
|
|
|
if self.controlSocket:
|
|
|
|
self.controlSocket.close()
|
|
|
|
self.controlSocket = None
|
|
|
|
|
2019-12-27 23:26:45 +00:00
|
|
|
def getControlPort(self):
|
|
|
|
return self.controlPort
|
2019-12-21 19:58:28 +00:00
|
|
|
|
2019-12-27 23:26:45 +00:00
|
|
|
def getCommandValues(self):
|
|
|
|
values = super().getCommandValues()
|
|
|
|
values["port"] = self.getPort()
|
|
|
|
values["controlPort"] = self.getControlPort()
|
|
|
|
return values
|
2021-02-19 14:29:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ConnectorDeviceDescription(SdrDeviceDescription):
|
2021-02-19 15:29:30 +00:00
|
|
|
def getInputs(self) -> List[Input]:
|
2021-02-21 23:35:47 +00:00
|
|
|
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.",
|
|
|
|
),
|
|
|
|
CheckboxInput(
|
|
|
|
"iqswap",
|
2021-02-21 23:57:02 +00:00
|
|
|
"Swap I and Q channels",
|
2021-02-21 23:35:47 +00:00
|
|
|
infotext="Swapping inverts the spectrum, so this is useful in combination with an inverting mixer",
|
|
|
|
),
|
|
|
|
]
|
|
|
|
|
2021-03-24 22:17:50 +00:00
|
|
|
def getDeviceOptionalKeys(self):
|
|
|
|
return super().getDeviceOptionalKeys() + ["rtltcp_compat", "iqswap"]
|
2021-02-23 17:32:23 +00:00
|
|
|
|
|
|
|
def getProfileOptionalKeys(self):
|
|
|
|
return super().getProfileOptionalKeys() + ["iqswap"]
|