def test_get_config_list_corrupt_2(self): class TestALH: def get(self, resource): s = "dev #0, Test, 2 configs:" return s.encode('ascii') alh = TestALH() s = SpectrumSensor(alh) self.assertRaises(CRCError, s.get_config_list)
def get_radio_info(self, platform_id): if platform_id == "sensor": sensor = SpectrumSensor(self.node) config_list = sensor.get_config_list() elif platform_id == "generator": generator = SignalGenerator(self.node) config_list = generator.get_config_list() else: config_list = str(platform_id) + ": Not supported! Try: sensor or generator" return config_list
def test_sweep_1(self): class MockALH(ALHProtocol): def _post(self, resource, data, *args): return b"\x00\x00\x01\x00\x02\x00D\xa4H;" alh = MockALH() ss = SpectrumSensor(alh) sc = self._get_sc() r = ss.sweep(sc) self.assertEqual(r.data, [0., .01, .02])
def test_get_config_list_corrupt_1(self): class TestALH: def get(self, resource): return "".encode('ascii') alh = TestALH() s = SpectrumSensor(alh) cl = s.get_config_list() self.assertEqual(cl.configs, []) self.assertEqual(cl.devices, [])
def get_measurements(self, params): if not self.sensor: self.sensor = SpectrumSensor(self.node) config_list = self.sensor.get_config_list() self.sweep_config = config_list.get_sweep_config(params[0], params[1], params[2]) if self.sweep_config is None: self.sensor = None raise Exception("Node can not scan specified frequency range.") sweep = self.sensor.sweep(self.sweep_config) f = list(self.sweep_config.get_hz_list()) p = sweep.data return {'frequency':f, 'power':p}
def test_sweep_2(self): class MockALH(ALHProtocol): def _post(self, resource, data, *args): # negative CRC return b"\x00\x00\x01\x00\x08\x00\xceL\xa7\xc1" alh = MockALH() ss = SpectrumSensor(alh) sc = self._get_sc() r = ss.sweep(sc) self.assertEqual(r.data, [0., .01, .08])
def __init__(self, txnode, rxnode): # We set up the SignalGenerator and SpectrumSensor objects here # for later use. We also query both nodes for their # corresponding lists of available hardware configurations. # # Since hardware will not change during the experiment, we only # do the query once in object constructor. This makes repeated # measurements faster. self.generator = SignalGenerator(txnode) self.generator_cl = self.generator.get_config_list() self.sensor = SpectrumSensor(rxnode) self.sensor_cl = self.sensor.get_config_list()
def test_get_config_list(self): class TestALH: def get(self, resource): s = "dev #0, Test, 1 configs:\n" \ " cfg #0: Test:\n" \ " base: 10 Hz, spacing: 1 Hz, bw: 1 Hz, channels: 10, time: 1 ms" return s.encode('ascii') alh = TestALH() s = SpectrumSensor(alh) cl = s.get_config_list() self.assertEqual(len(cl.devices), 1) self.assertEqual(len(cl.configs), 1)
def test_retrieve(self): class MockALH(ALHProtocol): def _get(self, resource, *args): if b"Info" in resource: return b"status=COMPLETE,size=14" else: return b"\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x91m\x00i" alh = MockALH() ss = SpectrumSensor(alh) sc = self._get_sc() p = SpectrumSensorProgram(sc, 0, 10, 1) r = ss.retrieve(p) self.assertEqual(len(r.sweeps), 1) self.assertEqual(r.sweeps[0].data, [0., .01, .02]) self.assertEqual(r.sweeps[0].timestamp, 0)
def setup(self, options): if not options.verbosity: options.verbosity = "warning" coor = get_coordinator(options) coor.post("prog/firstcall", "1") self.node = ALHProxy(coor, options.node) self.node.post("prog/firstcall", "1") self.spectrumsensor = SpectrumSensor(self.node) self.config_list = self.spectrumsensor.get_config_list() if not self.config_list.configs: raise Exception("Device returned no configurations. " "It is still scanning or not responding.") self.config = self.config_list.get_config(self.device_id, self.config_id)
def main(): # Turn on logging so that we can see ALH requests happening in the # background. logging.basicConfig(level=logging.INFO) coor = alh.ALHWeb("https://crn.log-a-tec.eu/communicator", 10001) # Node 19 is equipped with an UHF receiver (TDA18219 on SNE-ISMTV-UHF) node = alh.ALHProxy(coor, 19) # Node 17 is equipped with an 2.4 GHz receiver (CC2500 on SNE-ISMTV-24) #node = alh.ALHProxy(coor, 17) # Wrap an ALHProxy object with a SpectrumSensor object that provides an # convenient interface to spectrum sensing functionality of the node # exposed through ALH resources. sensor = SpectrumSensor(node) # Get a ConfigList object that contains a list of device configurations # supported by the chosen sensor node. config_list = sensor.get_config_list() # ConfigList.get_sweep_config() method will automatically choose # the best device and configuration that can cover the requested # frequency range. # # It returns an instance of SweepConfig class that describes all # the settings for a frequency sweep. # # First example defines a sweep starting at 550 MHz and ending at # 574 MHz with 2 MHz steps (use with node 19) # # Second example define a sweep starting at 2420 MHz and ending at # 2430 MHz with 400 kHz steps (use with node 17) sweep_config = config_list.get_sweep_config(550e6, 574e6, 1e6) #sweep_config = config_list.get_sweep_config(2420e6, 2430e6, 400e3) if sweep_config is None: raise Exception("Node can not scan specified frequency range.") pyplot.ion() while True: # Perform the sweep sweep = sensor.sweep(sweep_config) # Get the list of frequencies covered by the sweep f_hz = sweep_config.get_hz_list() # Convert list from Hz to MHz for nicer plot f_mhz = numpy.array(f_hz) / 1e6 pyplot.clf() pyplot.grid() pyplot.xlabel("frequency [MHz]") pyplot.ylabel("power [dBm]") # Plot data pyplot.plot(f_mhz, sweep.data) pyplot.axis([min(f_mhz), max(f_mhz), -110, -50]) pyplot.draw() pyplot.pause(1)
def main(): coor_industrial_zone = alh.ALHWeb(get_communicator_url(), 10001) time_start = time.time() + 30 # Set up transmissions for node_id in [10, 8, 7]: node = alh.ALHProxy(coor_industrial_zone, node_id) node.post("prog/firstCall", "1") su1 = SignalGenerator(alh.ALHProxy(coor_industrial_zone, 10)) su2 = SignalGenerator(alh.ALHProxy(coor_industrial_zone, 8)) mic = SignalGenerator(alh.ALHProxy(coor_industrial_zone, 7)) config_list = su1.get_config_list() tx_config = config_list.get_tx_config(0, 0) mic.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=790e6, power_dbm=0), time_start=time_start+30, time_duration=40) ) mic.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=807e6, power_dbm=0), time_start=time_start+80, time_duration=40) ) su1.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=787e6, power_dbm=0), time_start=time_start, time_duration=35) ) su1.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=780e6, power_dbm=0), time_start=time_start+35, time_duration=90) ) su2.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=795e6, power_dbm=0), time_start=time_start, time_duration=35) ) su2.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=800e6, power_dbm=0), time_start=time_start+35, time_duration=50) ) su2.program( SignalGeneratorProgram( config_list.get_tx_config(f_hz=797e6, power_dbm=0), time_start=time_start+85, time_duration=35) ) # Set up spectrum sensing sensor_node_ids = [ 19 ] sensor_nodes = [ alh.ALHProxy(coor_industrial_zone, id) for id in sensor_node_ids ] sensors = [ SpectrumSensor(sensor_node) for sensor_node in sensor_nodes ] config_list = sensors[0].get_config_list() sweep_config = config_list.get_sweep_config( start_hz=770000000, stop_hz=820000000, step_hz=400000) # -1 below is a work-around for an off-by-one error somewhere in the spectrum sensing # resource handler sweep_config.num_channels -= 1 program = SpectrumSensorProgram(sweep_config, time_start, time_duration=120, slot_id=5) for sensor in sensors: sensor.program(program) # Wait for the experiment to finish for sensor in sensors: while not sensor.is_complete(program): print "waiting..." time.sleep(2) if time.time() > (program.time_start + program.time_duration + 30): raise Exception("Something went wrong") print "experiment is finished. retrieving data." result = sensor.retrieve(program) try: os.mkdir("data") except OSError: pass result.write("data/node_%d.dat" % (sensor.alh.addr,))
def main(): coor_industrial_zone = alh.ALHWeb(get_communicator_url(), 10001) time_start = time.time() + 15 # Set up transmissions cognitive_terminal = SignalGenerator(alh.ALHProxy(coor_industrial_zone, 25)) config_list = cognitive_terminal.get_config_list() device_config = config_list.get_config(0, 0) cognitive_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 110, 0), time_start=(time_start + 5), time_duration=25)) cognitive_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 225, 0), time_start=(time_start + 32), time_duration=23)) legacy_terminal = SignalGenerator(alh.ALHProxy(coor_industrial_zone, 16)) legacy_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 114, 0), time_start=(time_start + 25), time_duration=30)) # Set up spectrum sensing sensor_node_ids = [2, 17, 6] sensor_nodes = [ alh.ALHProxy(coor_industrial_zone, id) for id in sensor_node_ids ] sensors = [SpectrumSensor(sensor_node) for sensor_node in sensor_nodes] config_list = sensors[0].get_config_list() sweep_config = config_list.get_config(0, 0).get_full_sweep_config() program = SpectrumSensorProgram(sweep_config, time_start, time_duration=60, slot_id=5) for sensor in sensors: sensor.program(program) # Wait for the experiment to finish for sensor in sensors: while not sensor.is_complete(program): print "waiting..." time.sleep(2) if time.time() > (program.time_start + program.time_duration + 60): raise Exception("Something went wrong") print "experiment is finished. retrieving data." result = sensor.retrieve(program) try: os.mkdir("data") except OSError: pass result.write("data/node_%d.dat" % (sensor.alh.addr, ))
def main(): # Turn on logging so that we can see requests and responses in the # terminal. This is useful to keep track of what is going on during the # experiment. logging.basicConfig(level=logging.INFO) # We must first create an object representing the coordinator node. # Each cluster in the LOG-a-TEC has its own coordinator and all # communication with the nodes must go through it. # # The parameters used here correspond to the LOG-a-TEC City Center # out-door cluster (see LOG-a-TEC documentation for other valid # options). # # Note that you must have a valid user name and password saved in an # "alhrc" file in order for this to work. See vesna-alh-tools README # for instructions on how to do that. # # Also make sure you reserved the cluster in the calendar before # running the experiment! coor = alh.ALHWeb("https://crn.log-a-tec.eu/communicator", 10002) # We will be using node 45 in this example. First we create a generic # node object for it. node = alh.ALHProxy(coor, 45) # We will use our node as a spectrum sensor. Here, we wrap the generic # node object with the SpectrumSensor class that provides a convenient # interface to the spectrum sensing capabilities of the node's radio # hardware. sensor = SpectrumSensor(node) # Request the list of spectrum sensing configurations that the node # supports. # # Node 45 is equipped with a SNE-ISMTV-2400 radio board that contains a # CC2500 reconfigurable transceiver. This tranceiver supports a number # of configurations that cover the 2.4 GHz ISM band. sensor_config_list = sensor.get_config_list() # Let's print the list out in a nice format for future reference. print print "Spectrum sensing devices and configurations available" print "=====================================================" print sensor_config_list print # For a demonstration, we'll choose to sense the whole ISM band between # 2.4 GHz and 2.5 GHz with 400 kHz steps. We create a SweepConfig object # that describes this frequency range. sweep_config = sensor_config_list.get_sweep_config(2400e6, 2500e6, 400e3) if sweep_config is None: raise Exception("Node can not scan specified frequency range.") # Take note of current time. now = time.time() # SpectrumSensorProgram object allows us to program a node to perform a # spectrum sensing task in advance. We'll setup a task for sensing the # frequency range we selected above, starting 5 seconds from now and # lasting for 30 seconds. # # Each node has local slots for temporary storage of spectrum sensing # results. Since we are only performing one scan of the spectrum, it # doesn't matter which slot we use. Let's pick slot 1. sensor_program = SpectrumSensorProgram(sweep_config, now + 5, 30, 1) # Now we actually send the programming instructions over the testbed's # management network to the node. sensor.program(sensor_program) # Wait until the programmed task has been completed. while not sensor.is_complete(sensor_program): print "patience..." time.sleep(2) # The task is complete. We must now retrieve spectrum sensing results # back from the node to our computer. This might take a while since the # management mesh network is slow. result = sensor.retrieve(sensor_program) # Finally, we write results into a CSV file for further analysis. # # Alternatively, we could do something else with the results directly # from this program. The SpectrumSensorResult object provides some # convenient methods for accessing the result of the scan. result.write("logatec.csv")
def main(): # Turn on logging so that we can see requests and responses in the # terminal. logging.basicConfig(level=logging.INFO) # We must first create an object representing the coordinator node. coor_campus = alh.ALHWeb("https://crn.log-a-tec.eu/communicator", 9501) # Our experiment will start 15 seconds into the future - this should # give us plenty of time to set up everything. time_start = time.time() + 15 # First we set up the two transmitting nodes: # # Node 53 in the LOG-a-TEC Campus Zone will be playing the role of # the cognitive terminal. cognitive_terminal = SignalGenerator(alh.ALHProxy(coor_campus, 53)) # All nodes we will be using are equipped with SNE-ISMTV-2400 radio # boards with CC2500 transceivers. From the available list of # signal generation configurations supported by this hardware, we # choose the first one: It allows to transmit in 200 kHz wide channels. config_list = cognitive_terminal.get_config_list() device_config = config_list.get_config(0, 0) # Here we program the "cognitive_terminal" node to transmit for 25 # seconds on channel 110 (2422.0 MHz) and then change to channel 225 # (2445.0 MHz). Transmission power is set to 0 dBm. cognitive_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 110, 0), time_start=(time_start + 5), time_duration=25)) cognitive_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 225, 0), time_start=(time_start + 32), time_duration=23)) # Node 54 in the LOG-a-TEC Campus Zone will be playing the role of # the legacy terminal. legacy_terminal = SignalGenerator(alh.ALHProxy(coor_campus, 54)) # The legacy terminal, lacking the capability to change channels on # demand, is programmed to just transmit for 30 seconds on channel 114 # (2422.8 MHz) legacy_terminal.program( SignalGeneratorProgram(TxConfig(device_config, 114, 0), time_start=(time_start + 25), time_duration=30)) # Now we setup some sensing nodes so that we can observe the # transmissions from different points in the testbed. # We will use nodes 51 and 58 for this purpose. sensor_node_ids = [51, 58] sensor_nodes = [alh.ALHProxy(coor_campus, id) for id in sensor_node_ids] sensors = [SpectrumSensor(sensor_node) for sensor_node in sensor_nodes] # For sensing, we will use the first sensing configuration (255 # channels starting at 2.4 GHz with 400 kHz bandwidth) config_list = sensors[0].get_config_list() sweep_config = config_list.get_config(0, 0).get_full_sweep_config() # We instruct the nodes to perform spectrum sensing for 60 seconds. program = SpectrumSensorProgram(sweep_config, time_start, time_duration=60, slot_id=5) for sensor in sensors: sensor.program(program) # All nodes have been programmed at this point - wait for the experiment to finish. for sensor in sensors: while not sensor.is_complete(program): print "waiting..." time.sleep(2) if time.time() > (program.time_start + program.time_duration + 60): raise Exception("Something went wrong") print "experiment is finished. retrieving data." result = sensor.retrieve(program) # We will save the sensing results in a "data/" subdirectory. # Create it, if it doesn't already exist. try: os.mkdir("data") except OSError: pass # For each sensing node, we write the results into a CSV file. # The CSV file can be easily imported and plotted into tools # like MatLab. For example, to plot the recorded spectrogram # using GNU Plot, use the following commands: # # gnuplot> set pm3d map # gnuplot> set xlabel "frequency [MHz]" # gnuplot> set ylabel "time [s]" # gnuplot> set cblabel "power [dBm]" # gnuplot> unset key # gnuplot> splot "node17.csv" using ($2/1e6):1:3 result.write("data/node_%d.csv" % (sensor.alh.addr, ))
def main(): # Turn on logging so that we can see ALH requests happening in the # background. logging.basicConfig(level=logging.INFO) coor = alh.ALHWeb("https://crn.log-a-tec.eu/communicator", 10001) # Nodes 16 and 17 are equipped with an 2.4 GHz tranceiver (CC2500 on # SNE-ISMTV-24) that is capable of transmitting and receiving on the # 2.4 GHz ISM band. node16 = alh.ALHProxy(coor, 16) node17 = alh.ALHProxy(coor, 17) # We will use node 16 as a signal generator. We wrap its ALHProxy # object with a SignalGenerator object for convenience. generator = SignalGenerator(node16) # Set up a transmission configuration for 2.425 GHz and 0 dBm generator_config_list = generator.get_config_list() tx_config = generator_config_list.get_tx_config(2425e6, 0) if tx_config is None: raise Exception("Node can not scan specified frequency range.") # We will use node 17 as a spectrum sensor. Again, we wrap it with a # SpectrumSensor object for convenience. sensor = SpectrumSensor(node17) # We set up a frequency sweep configuration covering 2.40 GHz to 2.45 # GHz band with 400 kHz steps. sensor_config_list = sensor.get_config_list() sweep_config = sensor_config_list.get_sweep_config(2400e6, 2450e6, 400e3) if sweep_config is None: raise Exception("Node can not scan specified frequency range.") # Take note of current time. now = time.time() # SignalGeneratorProgram and SpectrumSensorProgram objects allow us to # program signal generation and spectrum sensing tasks in advance. # # In this case, we setup a signal generation task using the # configuration we prepared above starting 10 seconds from now and # lasting for 20 seconds. # # Similarly for spectrum sensing, we setup a task using frequency sweep # we prepared above starting 5 seconds from now and lasting for 30 # seconds. Results of the measurement will be stored in slot 4. generator_program = SignalGeneratorProgram(tx_config, now + 10, 20) sensor_program = SpectrumSensorProgram(sweep_config, now + 5, 30, 4) # Now actually send instructions over the management network to nodes # in the testbed. generator.program(generator_program) sensor.program(sensor_program) # Query the spectrum sensing node and wait until the task has been # completed. while not sensor.is_complete(sensor_program): print "waiting..." time.sleep(2) # Retrieve spectrum sensing results. This might take a while since the # management mesh network is slow. result = sensor.retrieve(sensor_program) # Write results into a CSV file. result.write("06-programmed-tasks.dat")