kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			Web API: NFM scanner Python script example (1)
							rodzic
							
								
									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` | ||||
|  |  | |||
|  | @ -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() | ||||
| 
 | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 f4exb
						f4exb