├── README.md ├── doc └── electrosense-openapi.pdf └── python ├── MapSensors ├── mapSensors.py └── resources │ └── mapsensors.jpg ├── README.md ├── SpectrumCountries ├── resources │ ├── spectrumCountries.jpg │ └── spectrumCountries.pdf └── spectrumCountries.py └── WaterfallPlot ├── resources ├── waterfall.jpg └── waterfall.pdf └── waterfall.py /README.md: -------------------------------------------------------------------------------- 1 | # API Examples 2 | 3 | The Electrosense REST API allows retrieval of raw and aggregated spectrum data as well as information about sensors. 4 | For more details about the API and its functionality check out the [specification](https://electrosense.org/app.html#!/api-spec). 5 | 6 | Subdirectories in this repository contain examples for certain programming languages. 7 | -------------------------------------------------------------------------------- /doc/electrosense-openapi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/doc/electrosense-openapi.pdf -------------------------------------------------------------------------------- /python/MapSensors/mapSensors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (C) IMDEA Networks Institute 2016 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see http://www.gnu.org/licenses/. 17 | # 18 | # Authors : Roberto Calvo [-p ]") 32 | parser.add_option("-u", "--user", dest="username", 33 | type="string", 34 | help="API username") 35 | parser.add_option("-p", "--pass", dest="password", 36 | type="string", help="API password") 37 | 38 | (options, args) = parser.parse_args() 39 | if not options.username: 40 | parser.error("Username not specified") 41 | 42 | if not options.password: 43 | options.password = getpass.getpass('Password:') 44 | 45 | # Electrosense API Credentials 46 | username=options.username 47 | password=options.password 48 | 49 | # Electrosense API 50 | MAIN_URI ='https://electrosense.org/api' 51 | SENSOR_LIST=MAIN_URI + '/sensor/list/' 52 | 53 | 54 | # Google maps URI 55 | url = 'http://maps.google.com/maps/api/staticmap?center=46.1671105,3.7804881&zoom=5&size=1024x1024&maptype=roadmap&format=jpg&' 56 | 57 | r = requests.get(SENSOR_LIST, auth=HTTPBasicAuth(username, password)) 58 | slist_json = json.loads(r.content) 59 | 60 | markers = "" 61 | 62 | for sensor in slist_json: 63 | color = "red" 64 | state = "" 65 | if (sensor['sensing']): 66 | color = "green" 67 | state = "S" 68 | 69 | markers = markers + "markers=color:" + color + "|label:"+ state + "|" + str(sensor['position']['latitude']) + "," + str(sensor['position']['longitude']) + "&" 70 | 71 | 72 | image_file = tempfile.gettempdir() + "/map.jpg" 73 | 74 | r = requests.get (url + markers, stream=True) 75 | if r.status_code == 200: 76 | with open(image_file, 'wb') as f: 77 | r.raw.decode_content = True 78 | shutil.copyfileobj(r.raw, f) 79 | 80 | webbrowser.open(image_file) 81 | -------------------------------------------------------------------------------- /python/MapSensors/resources/mapsensors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/python/MapSensors/resources/mapsensors.jpg -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | 2 | # API 3 | 4 | 5 | The Electrosense REST API allows retrieval of raw and aggregated spectrum data as well as information about sensors. For more details about the API and its functionality check out the [specification](https://electrosense.org/app.html#!/api-spec). 6 | 7 | # Examples 8 | 9 | This folder contains a few examples of how to use the Electrosense API using Python language 10 | 11 | ## MapSensors 12 | 13 | It shows sensing sensors (green) and non-sensing sensors (red) of the network in a map. 14 | 15 | ![alt tag](https://github.com/electrosense/api-examples/raw/master/python/MapSensors/resources/mapsensors.jpg) 16 | 17 | ## WaterfallPlot 18 | 19 | It makes a waterfall plot with different frequency resolutions. 20 | 21 | ![alt tag](https://github.com/electrosense/api-examples/raw/master/python/WaterfallPlot/resources/waterfall.jpg) 22 | 23 | 24 | ## SpectrumCountries 25 | 26 | It shows spectrum usage of different countries. 27 | 28 | ![alt tag](https://github.com/electrosense/api-examples/raw/master/python/SpectrumCountries/resources/spectrumCountries.jpg) 29 | -------------------------------------------------------------------------------- /python/SpectrumCountries/resources/spectrumCountries.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/python/SpectrumCountries/resources/spectrumCountries.jpg -------------------------------------------------------------------------------- /python/SpectrumCountries/resources/spectrumCountries.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/python/SpectrumCountries/resources/spectrumCountries.pdf -------------------------------------------------------------------------------- /python/SpectrumCountries/spectrumCountries.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (C) IMDEA Networks Institute 2016 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see http://www.gnu.org/licenses/. 17 | # 18 | # Authors : Roberto Calvo [-p ]") 35 | parser.add_option("-u", "--user", dest="username", 36 | type="string", 37 | help="API username") 38 | parser.add_option("-p", "--pass", dest="password", 39 | type="string", help="API password") 40 | 41 | (options, args) = parser.parse_args() 42 | if not options.username: 43 | parser.error("Username not specified") 44 | 45 | if not options.password: 46 | options.password = getpass.getpass('Password:') 47 | 48 | # Electrosense API Credentials 49 | username=options.username 50 | password=options.password 51 | 52 | # Electrosense API 53 | MAIN_URI ='https://electrosense.org/api' 54 | SENSOR_LIST = MAIN_URI + '/sensor/list/' 55 | SENSOR_AGGREGATED = MAIN_URI + "/spectrum/aggregated" 56 | 57 | 58 | def get_spectrum_data (sensor_id, timeBegin, timeEnd, aggFreq, aggTime): 59 | 60 | params = OrderedDict([('sensor', sensor_id), 61 | ('timeBegin', timeBegin), 62 | ('timeEnd', timeEnd), 63 | ('freqMin', int(24*1e6)), 64 | ('freqMax', int(1766*1e6)), 65 | ('aggFreq', aggFreq), 66 | ('aggTime', aggTime), 67 | ('aggFun','AVG')]) 68 | 69 | 70 | r = requests.get(SENSOR_AGGREGATED, auth=HTTPBasicAuth(username, password), params=urlencode(params)) 71 | 72 | if r.status_code == 200: 73 | return json.loads(r.content) 74 | else: 75 | print "Response: %d" % (r.status_code) 76 | return None 77 | 78 | 79 | # Main 80 | 81 | epoch_time = int(time.time()) 82 | #timeBegin = epoch_time - (3600*24*4) - 3600*8 83 | #timeEnd = timeBegin + (3600*23*1) 84 | 85 | timeBegin=1481334714 #1481331114 86 | timeEnd=1481406714#1481403114 87 | 88 | 89 | sensors_id = [202481594668072 ,202481592720557] 90 | sensors_loc = ['Madrid (Spain)', 'Leuven (Belgium)'] 91 | plot_id = [211, 212] 92 | 93 | for i, s in enumerate(sensors_id): 94 | 95 | response = get_spectrum_data (sensors_id[i], timeBegin, timeEnd, int(4e6), 60*15) 96 | 97 | 98 | if (response != None): 99 | 100 | A = np.array([ np.array(xi) for xi in response['values'] ]) 101 | 102 | sp1 = plt.subplot(plot_id[i]) 103 | plt.imshow(A) 104 | plt.title('Spectrum usage (' + time.strftime("%D", time.gmtime(timeBegin)) + ') - ' + sensors_loc[i]) 105 | 106 | sp1.set_xticklabels ( np.array(map(str,(np.array(sp1.get_xticks().tolist())*4).tolist())).tolist()) 107 | plt.xlabel('Frequency (MHz)') 108 | 109 | date_values = np.linspace(timeBegin, timeEnd, (len(sp1.get_yticklabels())-2)) 110 | date_text = np.array([ np.array (time.strftime("%H:%M:%S", time.gmtime(xi))) for xi in date_values]) 111 | date_text = np.insert(date_text, 0, '') 112 | date_text = np.append(date_text, '') 113 | #print date_values 114 | #print date_text 115 | sp1.set_yticklabels (date_text) 116 | 117 | plt.colorbar() 118 | 119 | 120 | 121 | plt.show() 122 | 123 | 124 | -------------------------------------------------------------------------------- /python/WaterfallPlot/resources/waterfall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/python/WaterfallPlot/resources/waterfall.jpg -------------------------------------------------------------------------------- /python/WaterfallPlot/resources/waterfall.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/electrosense/api-examples/d633f6a8fc076192877f48c92bd30b4b62a7b731/python/WaterfallPlot/resources/waterfall.pdf -------------------------------------------------------------------------------- /python/WaterfallPlot/waterfall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (C) IMDEA Networks Institute 2016 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see http://www.gnu.org/licenses/. 17 | # 18 | # Authors : Roberto Calvo [-p ]") 35 | parser.add_option("-u", "--user", dest="username", 36 | type="string", 37 | help="API username") 38 | parser.add_option("-p", "--pass", dest="password", 39 | type="string", help="API password") 40 | 41 | (options, args) = parser.parse_args() 42 | if not options.username: 43 | parser.error("Username not specified") 44 | 45 | if not options.password: 46 | options.password = getpass.getpass('Password:') 47 | 48 | # Electrosense API Credentials 49 | username=options.username 50 | password=options.password 51 | 52 | # Electrosense API 53 | MAIN_URI ='https://electrosense.org/api' 54 | SENSOR_LIST = MAIN_URI + '/sensor/list/' 55 | SENSOR_AGGREGATED = MAIN_URI + "/spectrum/aggregated" 56 | 57 | r = requests.get(SENSOR_LIST, auth=HTTPBasicAuth(username, password)) 58 | 59 | if r.status_code != 200: 60 | print r.content 61 | exit(-1) 62 | 63 | slist_json = json.loads(r.content) 64 | 65 | 66 | for i, sensor in enumerate(slist_json): 67 | print "[%d] %s (%d) - Sensing: %s" % (i, sensor['name'], sensor['serial'], sensor['sensing']) 68 | print str(sensor['serial']) + "," + str(sensor['position']['latitude']) + "," + str(sensor['position']['longitude']) 69 | 70 | print "" 71 | pos = int( raw_input("Please enter the sensor: ")) 72 | 73 | print "" 74 | print "Asking for 20 hours of spectrum data : " 75 | print " %s (%d) - %s" % (slist_json[pos]['name'], slist_json[pos]['serial'], slist_json[pos]['sensing']) 76 | 77 | 78 | # Ask for 5 minutes of aggregatd spectrum data 79 | 80 | def get_spectrum_data (sensor_id, timeBegin, timeEnd, aggFreq, aggTime): 81 | 82 | params = OrderedDict([('sensor', sensor_id), 83 | ('timeBegin', timeBegin), 84 | ('timeEnd', timeEnd), 85 | ('freqMin', int(24*1e6)), 86 | ('freqMax', int(1766*1e6)), 87 | ('aggFreq', aggFreq), 88 | ('aggTime', aggTime), 89 | ('aggFun','AVG')]) 90 | 91 | 92 | r = requests.get(SENSOR_AGGREGATED, auth=HTTPBasicAuth(username, password), params=urlencode(params)) 93 | 94 | 95 | if r.status_code == 200: 96 | return json.loads(r.content) 97 | else: 98 | print "Response: %d" % (r.status_code) 99 | return None 100 | 101 | sp1 = None 102 | sp2 = None 103 | sp3 = None 104 | 105 | epoch_time = int(time.time()) 106 | timeBegin = epoch_time - (3600*24*2) 107 | timeEnd = timeBegin + (3600*20*2) 108 | 109 | response = get_spectrum_data (slist_json[pos]['serial'], timeBegin, timeEnd, int(2e6), 60*15) 110 | 111 | date_values = np.arange(timeBegin, timeEnd, (timeEnd-timeBegin)/10) 112 | date_text = np.array([ np.array (time.strftime("%H:%M:%S", time.gmtime(xi))) for xi in date_values]) 113 | 114 | if (response != None): 115 | 116 | A = np.array([ np.array(xi) for xi in response['values'] ]) 117 | 118 | sp1 = plt.subplot(311) 119 | plt.imshow(A) 120 | plt.title('Frequency Resolution: 2 MHz') 121 | sp1.set_xticklabels ( np.array(map(str,(np.array(sp1.get_xticks().tolist())*2).tolist())).tolist()) 122 | sp1.set_yticklabels (date_text) 123 | plt.colorbar() 124 | 125 | response = get_spectrum_data (slist_json[pos]['serial'], timeBegin, timeEnd, int(5e6), 60*15) 126 | 127 | if (response != None): 128 | 129 | A = np.array([ np.array(xi) for xi in response['values'] ]) 130 | sp2 = plt.subplot(312) 131 | plt.imshow(A) 132 | plt.title('Frequency Resolution: 5 MHz') 133 | sp2.set_xticklabels ( np.array(map(str,(np.array(sp2.get_xticks().tolist())*5).tolist())).tolist()) 134 | sp2.set_yticklabels (date_text) 135 | plt.colorbar() 136 | 137 | response = get_spectrum_data (slist_json[pos]['serial'], timeBegin, timeEnd, int(10e6), 60*15) 138 | 139 | if (response != None): 140 | 141 | A = np.array([ np.array(xi) for xi in response['values'] ]) 142 | 143 | sp3 = plt.subplot(313) 144 | plt.imshow(A) 145 | plt.title('Frequency Resolution: 10 MHz') 146 | sp3.set_xticklabels ( np.array(map(str,(np.array(sp3.get_xticks().tolist())*10).tolist())).tolist()) 147 | sp3.set_yticklabels (date_text) 148 | plt.colorbar() 149 | plt.show() 150 | 151 | 152 | --------------------------------------------------------------------------------