mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-04 05:30:32 -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`
 | 
					    - URI: `/sdrangel/deviceset/{deviceSetIndex}/device/run`
 | 
				
			||||||
    - HTTP method: `POST`
 | 
					    - 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>
 | 
					<h2>nfm_test.py</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example of creating NFM channels (demodulator and modulator) and changing the settings
 | 
					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`
 | 
					    - URI: `/sdrangel/deviceset/{deviceSetIndex}/device/settings`
 | 
				
			||||||
    - HTTP method: `PATCH`
 | 
					    - 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>
 | 
					<h2>start_stop.py</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Starts or stops a device in the specified device set
 | 
					Starts or stops a device in the specified device set
 | 
				
			||||||
@ -155,4 +208,45 @@ It uses this API:
 | 
				
			|||||||
    - URI: `/sdrangel`
 | 
					    - URI: `/sdrangel`
 | 
				
			||||||
    - HTTP method: `DELETE`
 | 
					    - 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user