mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -05:00
Web API: NFM scanner Python script example (1)
This commit is contained in:
parent
5cb64c3daa
commit
a2e1f674d7
@ -64,6 +64,12 @@ 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
|
||||
@ -125,6 +131,53 @@ It uses the following APIs:
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
|
||||
- HTTP method: `PATCH`
|
||||
|
||||
<h2>rx_test.py</h2>
|
||||
|
||||
Sets specified Rx in existing source device set or create a new source device set with this Rx. Adds an NFM demodulator channel.
|
||||
|
||||
It uses the following APIs:
|
||||
|
||||
- Create a new device set:
|
||||
- Operation ID: `devicesetPost`
|
||||
- URI: `/sdrangel/deviceset`
|
||||
- HTTP method: `POST`
|
||||
- Get information on a device set:
|
||||
- Operation ID: `devicesetGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}`
|
||||
- HTTP method: `GET`
|
||||
- To select a device in a device set:
|
||||
- Operation ID: `devicesetDevicePut`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device`
|
||||
- HTTP method: `PUT`
|
||||
- To get the settings of a device:
|
||||
- OperationID: `devicesetDeviceSettingsGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
|
||||
- HTTP method: `GET`
|
||||
- To change the settings of a device:
|
||||
- OperationID: `devicesetDeviceSettingsPatch`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
|
||||
- HTTP method: `PATCH`
|
||||
- To create a new channel:
|
||||
- Operation ID: `devicesetChannelPost`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel`
|
||||
- HTTP method: `POST`
|
||||
- To get the settings of a channel:
|
||||
- OperationID: `devicesetChannelSettingsGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings`
|
||||
- HTTP method: `GET`
|
||||
- To change the settings of a channel:
|
||||
- OperationID: `devicesetChannelSettingsPatch`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings`
|
||||
- HTTP method: `PATCH`
|
||||
- Start a device streaming
|
||||
- OperationID: `devicesetDeviceRunPost`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run`
|
||||
- HTTP method: `POST`
|
||||
|
||||
<h2>rx_tx_test.py</h2>
|
||||
|
||||
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>start_stop.py</h2>
|
||||
|
||||
Starts or stops a device in the specified device set
|
||||
@ -155,4 +208,45 @@ It uses this API:
|
||||
- URI: `/sdrangel`
|
||||
- HTTP method: `DELETE`
|
||||
|
||||
<h2>tx_test.py</h2>
|
||||
|
||||
Sets specified Tx in existing sink device set or create a new sink device set with this Tx. Adds an NFM modulator channel.
|
||||
|
||||
It uses the following APIs:
|
||||
|
||||
- Create a new device set:
|
||||
- Operation ID: `devicesetPost`
|
||||
- URI: `/sdrangel/deviceset`
|
||||
- HTTP method: `POST`
|
||||
- Get information on a device set:
|
||||
- Operation ID: `devicesetGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}`
|
||||
- HTTP method: `GET`
|
||||
- To select a device in a device set:
|
||||
- Operation ID: `devicesetDevicePut`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device`
|
||||
- HTTP method: `PUT`
|
||||
- To get the settings of a device:
|
||||
- OperationID: `devicesetDeviceSettingsGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
|
||||
- HTTP method: `GET`
|
||||
- To change the settings of a device:
|
||||
- OperationID: `devicesetDeviceSettingsPatch`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
|
||||
- HTTP method: `PATCH`
|
||||
- To create a new channel:
|
||||
- Operation ID: `devicesetChannelPost`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel`
|
||||
- HTTP method: `POST`
|
||||
- To get the settings of a channel:
|
||||
- OperationID: `devicesetChannelSettingsGet`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings`
|
||||
- HTTP method: `GET`
|
||||
- To change the settings of a channel:
|
||||
- OperationID: `devicesetChannelSettingsPatch`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings`
|
||||
- HTTP method: `PATCH`
|
||||
- Start a device streaming
|
||||
- OperationID: `devicesetDeviceRunPost`
|
||||
- URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run`
|
||||
- HTTP method: `POST`
|
||||
|
143
swagger/sdrangel/examples/nfm_scanner.py
Normal file
143
swagger/sdrangel/examples/nfm_scanner.py
Normal file
@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import requests, json, traceback, sys
|
||||
from optparse import OptionParser
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
base_url = "http://127.0.0.1:8091/sdrangel"
|
||||
deviceset_url = ""
|
||||
|
||||
requests_methods = {
|
||||
"GET": requests.get,
|
||||
"PATCH": requests.patch,
|
||||
"POST": requests.post,
|
||||
"PUT": requests.put,
|
||||
"DELETE": requests.delete
|
||||
}
|
||||
|
||||
class ScanControl:
|
||||
def __init__(self, num_channels, channel_step, start_freq, stop_freq, log2_decim):
|
||||
self.channel_shifts = []
|
||||
if num_channels < 2:
|
||||
self.channel_shifts = [0]
|
||||
limit = 0
|
||||
else:
|
||||
limit = ((num_channels-1)*channel_step) / 2
|
||||
self.channel_shifts = list(np.linspace(-limit, limit, num_channels))
|
||||
self.device_start_freq = start_freq + limit
|
||||
self.device_stop_freq = stop_freq - limit
|
||||
self.device_step_freq = 2*limit + channel_step
|
||||
self.device_sample_rate = (2*limit + channel_step)*(1<<log2_decim)
|
||||
|
||||
# ======================================================================
|
||||
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("-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-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)
|
||||
parser.add_option("-r", "--rf-bw", dest="rf_bw", help="RF babdwidth (Hz). Sets to nearest available", metavar="FREQUENCY", type="int", default=10000)
|
||||
parser.add_option("-c", "--create", dest="create", help="create a new device set", metavar="BOOLEAN", action="store_true", default=False)
|
||||
parser.add_option("-m", "--mock", dest="mock", help="just print calculated values and exit", metavar="BOOLEAN", action="store_true", default=False)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if (options.address == None):
|
||||
options.address = "127.0.0.1:8091"
|
||||
|
||||
return options
|
||||
|
||||
# ======================================================================
|
||||
def printResponse(response):
|
||||
content_type = response.headers.get("Content-Type", None)
|
||||
if content_type is not None:
|
||||
if "application/json" in content_type:
|
||||
print(json.dumps(response.json(), indent=4, sort_keys=True))
|
||||
elif "text/plain" in content_type:
|
||||
print(response.text)
|
||||
|
||||
# ======================================================================
|
||||
def callAPI(url, method, params, json, text):
|
||||
request_method = requests_methods.get(method, None)
|
||||
if request_method is not None:
|
||||
r = request_method(url=base_url+url, params=params, json=json)
|
||||
if r.status_code / 100 == 2:
|
||||
print(text + " succeeded")
|
||||
printResponse(r)
|
||||
return r.json() # all 200 yield application/json response
|
||||
else:
|
||||
print(text + " failed")
|
||||
printResponse(r)
|
||||
return None
|
||||
|
||||
# ======================================================================
|
||||
def main():
|
||||
try:
|
||||
options = getInputOptions()
|
||||
scan_control = ScanControl(options.num_channels, options.freq_step, options.freq_start, options.freq_stop, options.log2_decim)
|
||||
|
||||
print("Channel shifts: %s" % scan_control.channel_shifts)
|
||||
print("Sample rate: %d" % scan_control.device_sample_rate)
|
||||
print("Start: %d" % scan_control.device_start_freq)
|
||||
print("Stop: %d" % scan_control.device_stop_freq)
|
||||
print("Step: %d" % scan_control.device_step_freq)
|
||||
|
||||
if scan_control.device_stop_freq < scan_control.device_start_freq:
|
||||
print("Frequency error")
|
||||
exit(1)
|
||||
|
||||
if options.mock:
|
||||
freqs = []
|
||||
fc = scan_control.device_start_freq
|
||||
while fc <= scan_control.device_stop_freq:
|
||||
freqs += [x+fc for x in scan_control.channel_shifts]
|
||||
fc += scan_control.device_step_freq
|
||||
print("Scanned frequencies: %s" % freqs)
|
||||
exit(0)
|
||||
|
||||
global base_url
|
||||
base_url = "http://%s/sdrangel" % options.address
|
||||
|
||||
# Set Rx
|
||||
|
||||
if options.create:
|
||||
r = callAPI("/deviceset", "POST", {"tx": 0}, None, "Add Rx device set")
|
||||
if r is None:
|
||||
exit(-1)
|
||||
|
||||
global deviceset_url
|
||||
deviceset_url = "/deviceset/%d" % options.device_index
|
||||
|
||||
r = callAPI(deviceset_url + "/device", "PUT", None, {"hwType": "%s" % options.device_hwid, "tx": 0}, "setup device on Rx device set")
|
||||
if r is None:
|
||||
exit(-1)
|
||||
|
||||
|
||||
|
||||
settings = callAPI("/deviceset/0/channel", "POST", None, {"channelType": "NFMDemod", "tx": 0}, "Create NFM demod")
|
||||
if settings is None:
|
||||
exit(-1)
|
||||
|
||||
settings["NFMDemodSettings"]["inputFrequencyOffset"] = 12500
|
||||
settings["NFMDemodSettings"]["afBandwidth"] = 5000
|
||||
|
||||
r = callAPI("/deviceset/0/channel/0/settings", "PATCH", None, settings, "Change NFM demod")
|
||||
if r is None:
|
||||
exit(-1)
|
||||
|
||||
|
||||
except Exception, msg:
|
||||
tb = traceback.format_exc()
|
||||
print >> sys.stderr, tb
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user