Web API: AM demod and AirspyHF: many fixes

This commit is contained in:
f4exb 2018-03-22 06:34:51 +01:00
parent 0cf53e1dc9
commit 1204734b58
6 changed files with 129 additions and 26 deletions

View File

@ -390,6 +390,7 @@ int AMDemod::webapiSettingsPutPatch(
MsgConfigureAMDemod *msg = MsgConfigureAMDemod::create(settings, force);
m_inputMessageQueue.push(msg);
qDebug("AMDemod::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureAMDemod *msgToGUI = MsgConfigureAMDemod::create(settings, force);

View File

@ -91,9 +91,33 @@ bool AMDemodGUI::deserialize(const QByteArray& data)
bool AMDemodGUI::handleMessage(const Message& message __attribute__((unused)))
{
if (AMDemod::MsgConfigureAMDemod::match(message))
{
qDebug("AMDemodGUI::handleMessage: AMDemod::MsgConfigureAMDemod");
const AMDemod::MsgConfigureAMDemod& cfg = (AMDemod::MsgConfigureAMDemod&) message;
m_settings = cfg.getSettings();
blockApplySettings(true);
displaySettings();
blockApplySettings(false);
return true;
}
return false;
}
void AMDemodGUI::handleInputMessages()
{
Message* message;
while ((message = getInputMessageQueue()->pop()) != 0)
{
if (handleMessage(*message))
{
delete message;
}
}
}
void AMDemodGUI::channelMarkerChangedByCursor()
{
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
@ -201,7 +225,8 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
m_amDemod = (AMDemod*) rxChannel; //new AMDemod(m_deviceUISet->m_deviceSourceAPI);
m_amDemod = reinterpret_cast<AMDemod*>(rxChannel); //new AMDemod(m_deviceUISet->m_deviceSourceAPI);
m_amDemod->setMessageQueueToGUI(getInputMessageQueue());
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
@ -233,6 +258,7 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
displaySettings();
applySettings(true);

View File

@ -75,6 +75,7 @@ private slots:
void on_useRTP_toggled(bool checked);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages();
void tick();
};

View File

@ -1508,6 +1508,21 @@ bool WebAPIRequestMapper::validateDeviceSettings(
return false;
}
}
else if ((*deviceHwType == "AirspyHF") && (deviceSettings.getTx() == 0))
{
if (jsonObject.contains("airspyHFSettings") && jsonObject["airspyHFSettings"].isObject())
{
QJsonObject airspyHFSettingsJsonObject = jsonObject["airspyHFSettings"].toObject();
deviceSettingsKeys = airspyHFSettingsJsonObject.keys();
deviceSettings.setAirspyHfSettings(new SWGSDRangel::SWGAirspyHFSettings());
deviceSettings.getAirspyHfSettings()->fromJsonObject(airspyHFSettingsJsonObject);
return true;
}
else
{
return false;
}
}
else if ((*deviceHwType == "HackRF") && (deviceSettings.getTx() == 0))
{
if (jsonObject.contains("hackRFInputSettings") && jsonObject["hackRFInputSettings"].isObject())
@ -1608,7 +1623,21 @@ bool WebAPIRequestMapper::validateChannelSettings(
QString *channelType = channelSettings.getChannelType();
if (*channelType == "NFMDemod")
if (*channelType == "AMDemod")
{
if (channelSettings.getTx() == 0)
{
QJsonObject amDemodSettingsJsonObject = jsonObject["AMDemodSettings"].toObject();
channelSettingsKeys = amDemodSettingsJsonObject.keys();
channelSettings.setAmDemodSettings(new SWGSDRangel::SWGAMDemodSettings());
channelSettings.getAmDemodSettings()->fromJsonObject(amDemodSettingsJsonObject);
return true;
}
else {
return false;
}
}
else if (*channelType == "NFMDemod")
{
if (channelSettings.getTx() == 0)
{
@ -1668,7 +1697,21 @@ bool WebAPIRequestMapper::validateChannelReport(
QString *channelType = channelReport.getChannelType();
if (*channelType == "NFMDemod")
if (*channelType == "AMDemod")
{
if (channelReport.getTx() == 0)
{
QJsonObject amDemodReportJsonObject = jsonObject["AMDemodReport"].toObject();
channelReportKeys = amDemodReportJsonObject.keys();
channelReport.setAmDemodReport(new SWGSDRangel::SWGAMDemodReport());
channelReport.getAmDemodReport()->fromJsonObject(amDemodReportJsonObject);
return true;
}
else {
return false;
}
}
else if (*channelType == "NFMDemod")
{
if (channelReport.getTx() == 0)
{

View File

@ -64,12 +64,6 @@ It uses the following APIs:
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run`
- HTTP method: `POST`
<h2>nfm_scanner.py</h2>
Simple NFM scanner with multiple equally spaced NFM channels. Stops whenever any of the channels squelch opens.
Requires numpy
<h2>nfm_test.py</h2>
Example of creating NFM channels (demodulator and modulator) and changing the settings
@ -178,6 +172,24 @@ It uses the following APIs:
Combines `rx_test` and `tx_test` to create a pair of source and sink device sets. The APIs used are the same as in `rx_test` or `tx_test`.
<h2>scanner.py</h2>
Simple AM and NFM scanner with multiple equally spaced channels. Stops whenever any of the channels squelch opens. At the moment the following sampling devices can be used:
- AirspyHF
- HackRF
- LimeSDR
- RTLSDR
Requires numpy
In addition to some APIs being used in other script it uses:
- Get channels reports:
- Operation ID: `devicesetChannelsReportGet`
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channels/report`
- HTTP method: `GET`
<h2>start_stop.py</h2>
Starts or stops a device in the specified device set

View File

@ -3,7 +3,7 @@
"""
SDRangel REST API client script
Simple scanner for NFM channels. Builds an array of equally spaced channels. Moves device center frequency
Simple scanner for AM and NFM channels. Builds an array of equally spaced channels. Moves device center frequency
so that adjacent parts of the spectrum are scanned by the array of channels. Stops when any of the channels
is active. Resumes when none of the channels is active.
@ -48,10 +48,11 @@ def getInputOptions():
parser = OptionParser(usage="usage: %%prog [-t]\n")
parser.add_option("-a", "--address", dest="address", help="address and port", metavar="ADDRESS", type="string")
parser.add_option("-d", "--device-index", dest="device_index", help="device set index", metavar="INDEX", type="int", default=0)
parser.add_option("-D", "--device-hwid", dest="device_hwid", help="device hardware id", metavar="HWID", type="string", default="RTLSDR")
parser.add_option("-D", "--device-hwid", dest="device_hwid", help="device hardware id", metavar="ID", type="string", default="RTLSDR")
parser.add_option("-C", "--channel-id", dest="channel_id", help="channel id", metavar="ID", type="string", default="NFMDemod")
parser.add_option("-l", "--log2-decim", dest="log2_decim", help="log2 of the desired software decimation factor", metavar="LOG2", type="int", default=4)
parser.add_option("-n", "--num-channels", dest="num_channels", help="number of parallel channels", metavar="NUMBER", type="int", default=8)
parser.add_option("-s", "--freq-step", dest="freq_step", help="frequency step (Hz)", metavar="FREQUENCY", type="int", default=12500)
parser.add_option("-s", "--freq-step", dest="freq_step", help="frequency step (Hz)", metavar="FREQUENCY", type="float", default=12500)
parser.add_option("-S", "--freq-start", dest="freq_start", help="frequency start (Hz)", metavar="FREQUENCY", type="int", default=446006250)
parser.add_option("-T", "--freq-stop", dest="freq_stop", help="frequency stop (Hz)", metavar="FREQUENCY", type="int", default=446193750)
parser.add_option("-b", "--af-bw", dest="af_bw", help="audio babdwidth (kHz)", metavar="FREQUENCY_KHZ", type="int" ,default=3)
@ -88,7 +89,16 @@ def setupDevice(scan_control, options):
if settings is None:
exit(-1)
if options.device_hwid == "LimeSDR":
if options.device_hwid == "AirspyHF":
if scan_control.device_start_freq > 30000000:
settings["airspyHFSettings"]["bandIndex"] = 1
else:
settings["airspyHFSettings"]["bandIndex"] = 0
settings["airspyHFSettings"]["centerFrequency"] = scan_control.device_start_freq
settings["airspyHFSettings"]["devSampleRateIndex"] = 0
settings['airspyHFSettings']['log2Decim'] = options.log2_decim
settings['airspyHFSettings']['loPpmCorrection'] = int(options.lo_ppm * 10) # in tenths of PPM
elif options.device_hwid == "LimeSDR":
settings["limeSdrInputSettings"]["antennaPath"] = 0
settings["limeSdrInputSettings"]["devSampleRate"] = scan_control.device_sample_rate
settings["limeSdrInputSettings"]["log2HardDecim"] = 4
@ -111,7 +121,7 @@ def setupDevice(scan_control, options):
settings['rtlSdrSettings']['loPpmCorrection'] = int(options.lo_ppm)
settings['rtlSdrSettings']['rfBandwidth'] = scan_control.device_step_freq + 100000
elif options.device_hwid == "HackRF":
settings['hackRFInputSettings']['LOppmTenths'] = options.lo_ppm * 10 # in tenths of PPM
settings['hackRFInputSettings']['LOppmTenths'] = int(options.lo_ppm * 10) # in tenths of PPM
settings['hackRFInputSettings']['centerFrequency'] = scan_control.device_start_freq
settings['hackRFInputSettings']['dcBlock'] = 1
settings['hackRFInputSettings']['iqImbalance'] = 1
@ -131,7 +141,9 @@ def changeDeviceFrequency(fc, options):
if settings is None:
exit(-1)
if options.device_hwid == "LimeSDR":
if options.device_hwid == "AirspyHF":
settings["airspyHFSettings"]["centerFrequency"] = fc
elif options.device_hwid == "LimeSDR":
settings["limeSdrInputSettings"]["centerFrequency"] = fc + 500000
elif options.device_hwid == "RTLSDR":
settings['rtlSdrSettings']['centerFrequency'] = fc
@ -146,7 +158,7 @@ def changeDeviceFrequency(fc, options):
def setupChannels(scan_control, options):
i = 0
for shift in scan_control.channel_shifts:
settings = callAPI(deviceset_url + "/channel", "POST", None, {"channelType": "NFMDemod", "tx": 0}, "Create NFM demod")
settings = callAPI(deviceset_url + "/channel", "POST", None, {"channelType": options.channel_id, "tx": 0}, "Create NFM demod")
if settings is None:
exit(-1)
@ -154,14 +166,21 @@ def setupChannels(scan_control, options):
if settings is None:
exit(-1)
settings["NFMDemodSettings"]["inputFrequencyOffset"] = int(shift)
settings["NFMDemodSettings"]["afBandwidth"] = options.af_bw * 1000
settings["NFMDemodSettings"]["rfBandwidth"] = options.rf_bw
settings["NFMDemodSettings"]["squelch"] = options.squelch_db * 10 # centi-Bels
settings["NFMDemodSettings"]["squelchGate"] = options.squelch_gate / 10 # 10's of ms
settings["NFMDemodSettings"]["title"] = "Channel %d" % i
if options.channel_id == "NFMDemod":
settings["NFMDemodSettings"]["inputFrequencyOffset"] = int(shift)
settings["NFMDemodSettings"]["afBandwidth"] = options.af_bw * 1000
settings["NFMDemodSettings"]["rfBandwidth"] = options.rf_bw
settings["NFMDemodSettings"]["squelch"] = options.squelch_db * 10 # centi-Bels
settings["NFMDemodSettings"]["squelchGate"] = options.squelch_gate / 10 # 10's of ms
settings["NFMDemodSettings"]["title"] = "Channel %d" % i
elif options.channel_id == "AMDemod":
settings["AMDemodSettings"]["inputFrequencyOffset"] = int(shift)
settings["AMDemodSettings"]["rfBandwidth"] = options.rf_bw
settings["AMDemodSettings"]["squelch"] = options.squelch_db
settings["AMDemodSettings"]["title"] = "Channel %d" % i
settings["AMDemodSettings"]["bandpassEnable"] = 1 # bandpass filter
r = callAPI(deviceset_url + "/channel/%d/settings" % i, "PATCH", None, settings, "Change NFM demod")
r = callAPI(deviceset_url + "/channel/%d/settings" % i, "PATCH", None, settings, "Change demod")
if r is None:
exit(-1)
@ -172,11 +191,12 @@ def checkScanning(fc, options):
reports = callAPI(deviceset_url + "/channels/report", "GET", None, None, "Get channels report")
if reports is None:
exit(-1)
reportKey = "%sReport" % options.channel_id
for i in range(reports["channelcount"]):
channel = reports["channels"][i]
if "report" in channel:
if "NFMDemodReport" in channel["report"]:
if channel["report"]["NFMDemodReport"]["squelch"] == 1:
if reportKey in channel["report"]:
if channel["report"][reportKey]["squelch"] == 1:
f_channel = channel["deltaFrequency"]+fc
if f_channel not in options.excl_flist:
print("Stopped at %d Hz" % f_channel)
@ -256,7 +276,7 @@ def main():
if r is None:
exit(-1)
r = callAPI(deviceset_url + "/device", "PUT", None, {"hwType": "%s" % options.device_hwid, "tx": 0}, "setup device on Rx device set")
r = callAPI(deviceset_url + "/device", "PUT", None, {"hwType": options.device_hwid, "tx": 0}, "setup device on Rx device set")
if r is None:
exit(-1)