mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-04-22 11:29:02 -04:00
Web API: AM demod and AirspyHF: many fixes
This commit is contained in:
parent
0cf53e1dc9
commit
1204734b58
plugins/channelrx/demodam
sdrbase/webapi
swagger/sdrangel/examples
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
54
swagger/sdrangel/examples/nfm_scanner.py → swagger/sdrangel/examples/scanner.py
Normal file → Executable file
54
swagger/sdrangel/examples/nfm_scanner.py → swagger/sdrangel/examples/scanner.py
Normal file → Executable 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)
|
||||
|
Loading…
Reference in New Issue
Block a user