def tearDownClass(cls): _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() flex.restore_state(cls.initial_state) flex.close()
def setUpClass(cls): _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() cls.initial_state = flex.save_current_state() flex.close()
def setUpClass(cls): """setUpClass() """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() cls.initial_state = flex.save_current_state() flex.close() postproc.enable_bands(['10', '20'])
class Testnoisefloor(unittest.TestCase): def setUp(self): """setUp() """ _ui = UserInput() _ui.request('com4') self.flex = Flex(_ui) self.flex.open() self.flex.do_cmd_list(postproc.INITIALZE_FLEX) def tearDown(self): """tearDown() """ self.flex.close() @classmethod def setUpClass(cls): """setUpClass() """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() cls.initial_state = flex.save_current_state() flex.close() postproc.enable_bands(['10', '20']) @classmethod def tearDownClass(cls): """tearDownClass() """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() flex.restore_state(cls.initial_state) flex.close() def test_A01SMeter(self): try: smeter = SMeter(SMArgkeys( 'ZZSM000;', 5_000_000, )) self.assertEqual('[SMeter: freq:5000000, -140.00000dBm, S0]', str(smeter)) gg = repr(smeter) self.assertEqual('SMeter: freq:5000000, -140.00000dBm, S0', gg) # repr(smeter)) except: a = 0 a = 1 def test_A02Noisefloor_inst(self): dataq = QUEUES[QK.dQ] #stope = STOP_EVENTS['acquireData'] stope = STOP_EVENTS[SEK.ad] # , testdata='noisefloordata.pickle') nf: Noisefloor = Noisefloor(self.flex, dataq, stope) self.assertTrue(nf.open(), 'smartSDR not running') nf.doit(loops=10, testdatafile='nfrlistdata.pickle', dups=True) self.assertTrue(nf.close()) results: List[NFResult] = [] try: while True: results.append(dataq.get(timeout=3)) except QEmpty: pass self.assertEqual(10, len(results)) samp: NFResult = results[2].get() self.assertEqual('Jul 15 2020 11:14:43', samp.starttime) self.assertEqual('Jul 15 2020 11:15:49', samp.endtime) r0bss: SMeterAvg = samp.readings[0] self.assertEqual('40', r0bss.band) self.assertEqual(-86.5, r0bss.dBm['mdBm']) def test_B01NoiseFloorStopEvent(self): """test_005NoiseFloorStopEvent The two seperate operations in this section make sure that 1) shutdown works with no threads, first and 3rd thread and 3rd and 5th threads 2) disabled threads start and end correctly 3) that all the threads can be started and operate reaonable (with test data) the only data sent on a queue is to the TESTQ which basically the result of myprint calls and the debug text output for this is disabled by default. these tests check operation of trackermain.timedwork, but not much else as all the test functions are in the test routine """ # must release the flex and ui setup in the per test setup for this test self.flex.close() #from queuesandevents import QUEUES, STOP_EVENTS from qdatainfo import NFQ barrier: CTX.Barrier = CTX.Barrier(0) # timesdic = {'tf': 15, 'nf': 4, 'dqr': 5, 'da': 6, 'db': 7} def tf(arg: Threadargs ): # the program periodically executed by the timer thread """tf() """ pass # # Threadargs = namedtuple('Threadargs', ['execute', 'barrier', 'stope', # 'qs', 'name', 'interval', 'doit']) # def nf(arg: Threadargs, **kwargs): """ noisefloor proxy arg is named tuple Threadargs Justs writes the routine name, thread name and time to TESTQ and maybe the consule """ def doita( ): # the program to be run by _thread_template the return 0 says that no work need be done when stopping try: UI: UserInput = UserInput() UI.request(port='com4') flexr: Flex = Flex(UI) nf: Noisefloor = Noisefloor(flexr, arg.qs[QK.dQ], arg.stope, run_till_stopped=True) nf.open() nf.doit(loops=0, runtime=0, interval=100, dups=True) except StopEventException as see: nf.close() raise see # update the interval and function mma: Threadargs = arg._replace(doit=doita) # run it return _thread_template(mma, printfun=myprint, **kwargs) def dqr(arg: Threadargs, **kwargs): """ noisefloor proxy arg is named tuple Threadargs Justs writes the routine name, thread name and time to TESTQ and maybe the consule """ def doita( ): # the program to be run by _thread_template the return 0 says that no work need be done when stopping pass mma = arg._replace(interval=1, doit=doita) # run it return _thread_template(mma, printfun=myprint, **kwargs) def daf(arg: Threadargs, **kwargs): """ noisefloor proxy arg is named tuple Threadargs Justs writes the routine name, thread name and time to TESTQ and maybe the consule """ def doita( ): # the program to be run by _thread_template the return 0 says that no work need be done when stopping pass mma = arg._replace(interval=1, doit=doita) # run it return _thread_template(mma, printfun=myprint, **kwargs) def dbf(arg: Threadargs, **kwargs): """ noisefloor proxy arg is named tuple Threadargs Justs writes the routine name, thread name and time to TESTQ and maybe the consule """ def doita( ): # the program to be run by _thread_template the return 0 says that no work need be done when stopping pass mma = arg._replace(interval=1, doit=doita) # run it return _thread_template(mma, printfun=myprint, **kwargs) # def runthreads(calls: Tuple[Callable, ...], argdicin: Dict[str, Threadargs], tpex) -> Dict[str, Any]: #futures: Dict[str, Any] = {} # futures[FK.w] = tpex.submit( # calls.w, argdicin[AK.w], printfn=myprint) # gets banddata data #futures[FK.n] = tpex.submit(calls.n, argdicin[AK.n]) # reads the dataQ and sends to the data processing queue dpq #futures[FK.t] = tpex.submit(calls.t, argdicin[AK.t]) # looks at the data and generates the approprate sql to send to dbwriter #futures[FK.da] = tpex.submit(calls.da, argdicin[AK.da]) # reads the database Q and writes it to the database #futures[FK.db] = tpex.submit(calls.db, argdicin[AK.db]) # _ = tpex.submit(breakwait, barrier) # break the barrier # _.add_done_callback(bwdone) # return futures # turn off all selected thread routines bollst: Tuple[bool, ...] = ENABLES( w=False, n=False, t=False, da=False, db=False, ) """ # Check empty submit works with tracker.shutdown """ calls: Tuple[Callable, ...] = ENABLES(w=trackermain.timed_work, n=nf, t=dqr, da=daf, db=dbf) # no threads running futures: Dict[str, Any] = {} waitresults: Tuple[Set, Set] = trackermain.shutdown(futures, QUEUES, STOP_EVENTS) self.assertTrue(waitresults is None) """ # Check submit and shutdown works with all threads disabled """ argdic: Dict[int, Threadargs] = genargs(barrier, bollst) #tpex = None """ This did not work when placed in a with construct, and it stops the diagnostic from completing! No idea why not """ if False: if True: tpex = concurrent.futures.ThreadPoolExecutor( max_workers=10, thread_name_prefix='dbc-') futures: Dict[str, Any] = runthreads(barrier, calls, argdic, tpex) for _ in range(1): Sleep(1) # wait for a while to let the threads work waitresults = trackermain.shutdown(futures, QUEUES, STOP_EVENTS, time_out=1) a = 0 # wait = True cause hang, false doesn't let the diagnostic end tpex.shutdown(wait=True) # all 5 threads ran to completion self.assertEqual(5, len(waitresults.done)) self.assertEqual(0, len(waitresults.not_done)) cleartestq() bollst: Tuple[bool, ...] = ENABLES( w=False, n=False, t=False, da=False, db=False, ) bc: int = sum([1 for _ in bollst if _]) + 1 # count them for barrier barrier = CTX.Barrier(bc) myprint('starting') argdic: Dict[int, Threadargs] = genargs(barrier, bollst) # mods for test argdic[AK.w] = argdic[AK.w]._replace(name='timed_work', interval=10.5, doit=tf) """ Start the threads, all should just activate and then exit leaving a trace this time """ # mythreadname = threading.currentThread().getName() # mythread = threading.currentThread() with concurrent.futures.ThreadPoolExecutor( max_workers=10, thread_name_prefix='dbc-') as tpex: futures: Dict[str, Any] = runthreads(barrier, calls, argdic, tpex) for _ in range(1): Sleep(1) waitresults = trackermain.shutdown(futures, QUEUES, STOP_EVENTS) self.assertEqual(5, len(waitresults.done)) self.assertEqual(0, len(waitresults.not_done)) # check that the results were expected for _ in waitresults.done: self.assertTrue(_.done()) rrr = repr(_.result()) self.assertTrue(rrr in ['[]', 'None', 'deque([], maxlen=10)']) # turn on noisefloor thread bollst: Tuple[bool, ...] = ENABLES(False, True, False, False, False) # count them for barrier the plus 1 is for starting thread bc = sum([1 for _ in bollst if _]) + 1 barrier = CTX.Barrier(bc) runtime = 90 # either 60, or 120 if not one of these, some of the asserts are ignored cleartestq() RESET_STOP_EVENTS() argdic: Dict[int, Threadargs] = genargs(barrier, bollst) # mods for test argdic[AK.w] = argdic[AK.w]._replace(interval=1, doit=tf) argdic[AK.n] = argdic[AK.n]._replace(interval=None) argdic[AK.t] = argdic[AK.t]._replace(interval=1) argdic[AK.da] = argdic[AK.da]._replace(interval=1) argdic[AK.db] = argdic[AK.db]._replace(interval=1) """ Try running the noise floor for real on a thread check that shutdown will actually stop it """ start = monotonic() futures: Dict[str, Any] = None with concurrent.futures.ThreadPoolExecutor( max_workers=10, thread_name_prefix='dbc-') as tpex: futures: Dict[str, Any] = runthreads(barrier, calls, argdic, tpex) for _ in range( runtime): # wait for a while to let the threads work Sleep(1) waitresults = trackermain.shutdown( futures, QUEUES, STOP_EVENTS, time_out=120) # wait max 60 for the threads to stop end = monotonic() elapsed = end - start myprint( f'elapsed: {elapsed}, runtime set to: {runtime}, 120 sec timeout delay' ) # took the expected one reading self.assertEqual(1, QUEUES[QK.dQ].qsize()) nfqdta: NFQ = QUEUES[QK.dQ].get_nowait() nfr: NFResult = nfqdta.get() if (nfr is None): print('nfr is none') else: self.assertTrue(nfr._started and nfr._ended) self.assertEqual(4, len(nfr.readings)) # got all 4 bands bollst: Tuple[bool, ...] = ENABLES(w=False, n=True, t=False, da=False, db=False) # count them for barrier the plus 1 is for starting thread bc = sum([1 for _ in bollst if _]) + 1 barrier = CTX.Barrier(bc) # runtime = 100 # either 60, or 120 if not one of these, some of the asserts are ignored cleartestq() RESET_STOP_EVENTS() argdic: Dict[int, Threadargs] = genargs(barrier, bollst) # mods for test argdic[AK.w] = argdic[AK.w]._replace(interval=1, doit=tf) argdic[AK.n] = argdic[AK.n]._replace(interval=None) argdic[AK.t] = argdic[AK.t]._replace(interval=1) argdic[AK.da] = argdic[AK.da]._replace(interval=1) argdic[AK.db] = argdic[AK.db]._replace(interval=1) """ Try running the noise floor for real on a thread check that setting stop event will stop it Set to stop in the mid band scan """ start = monotonic() with concurrent.futures.ThreadPoolExecutor( max_workers=10, thread_name_prefix='dbc-') as tpex: futures: Dict[str, Any] = runthreads(barrier, calls, argdic, tpex) for _ in range(int(runtime / 3)): # wait for a while to let the threads work Sleep(1) STOP_EVENTS[SEK.da].set() # stop the the data acquisition waitresults = trackermain.shutdown( futures, QUEUES, STOP_EVENTS, time_out=120) # wait max 60 for the threads to stop end = monotonic() elapsed = end - start # aborted before it could complete a cycle self.assertEqual(0, QUEUES[QK.dQ].qsize()) myprint( f'elapsed: {elapsed}, runtime set to: {int(runtime/3)}, 120 sec timeout delay' ) a = 0 def test_A03Noisefloortestfiles(self): from qdatainfo import NFQ from math import isclose from datetime import datetime as DT from datetime import timedelta as TD nfqldata: List[NFQ] = [] with open('nfqlistdata.pickle', 'rb') as jso: nfqldata = pickle.load(jso) self.assertEqual(90, len(nfqldata)) nfrldata: List[NFResult] = [] with open('nfrlistdata.pickle', 'rb') as jso: nfrldata = pickle.load(jso) self.assertEqual(90, len(nfrldata)) smavdata: List[SMeterAvg] = [] with open('smavflistdata.pickle', 'rb') as jso: smavdata = pickle.load(jso) self.assertEqual(270, len(smavdata)) nfq = nfqldata[0] nfqtimel: List[Tuple[int, TD, DT, DT, ]] = [] for i in range(1, len(nfqldata)): t1: DT = nfqldata[i].utctime t0: DT = nfqldata[i - 1].utctime td: TD = t1 - t0 if not isclose(td.total_seconds(), 90.0, abs_tol=0.5): nfqtimel.append(( i, td, t0, t1, )) self.assertEqual(4, len(nfqtimel)) # index, time delta between starts, time taken nfrlderr: List[Tuple[int, TD, TD]] = [] for i in range(1, len(nfrldata)): st1: DT = DT.strptime(nfrldata[i].starttime, '%b %d %Y %H:%M:%S') st0: DT = DT.strptime(nfrldata[i - 1].starttime, '%b %d %Y %H:%M:%S') et: DT = DT.strptime(nfrldata[i].endtime, '%b %d %Y %H:%M:%S') sd: TD = st1 - st0 dur: TD = et - st1 if not isclose(sd.seconds, 90.0, abs_tol=0.5) or not isclose( dur.seconds, 65.0, abs_tol=3.0): nfrlderr.append((i, sd, dur)) self.assertEqual(3, len(nfrlderr))
class Testflex(unittest.TestCase): """Testflex unit testing for the flex class """ # def initialize_flex(self): # """initialize_flex() # """ # _ui = UserInput() # _ui.request('com4') # self.flex = Flex(_ui) # self.flex.open() # self.initialize_flex() # self.flex.do_cmd_list(postproc.INITIALZE_FLEX) # results = self.flex.do_cmd_list(postproc.INITIALZE_FLEX) # return results def setUp(self): _ui = UserInput() _ui.request('com4') self.flex = Flex(_ui) self.flex.open() _ = self.flex.do_cmd_list(postproc.INITIALZE_FLEX) self.assertEqual(13, len(_)) def tearDown(self): self.flex.close() @classmethod def setUpClass(cls): _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() cls.initial_state = flex.save_current_state() flex.close() @classmethod def tearDownClass(cls): _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() flex.restore_state(cls.initial_state) flex.close() def test01_instantiate(self): """test_instantiate() check if Flex instiantiates and has expected str and repr without flex being opened """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) self.assertEqual('Flex cat: com4, opened: False', str(flex)) self.assertEqual('[Flex] Flex cat: com4, opened: False', repr(flex)) flex.close() def test02_open_close(self): """test_open_close() check if Flex instiantiates and opens and has expected str and repr flex verifies that flex closes verifies re-open and can do a simple do_cmd """ self.assertEqual('Flex cat: com4, opened: True', str(self.flex)) self.assertEqual('[Flex] Flex cat: com4, opened: True', repr(self.flex)) self.flex.close() self.assertEqual('Flex cat: com4, opened: False', str(self.flex)) self.assertEqual('[Flex] Flex cat: com4, opened: False', repr(self.flex)) self.flex.open() result = self.flex.do_cmd('ZZIF;') self.assertEqual(41, len(result)) def test03_do_cmd(self): """test_do_cmd() checks error conditions on do_cmd """ result = self.flex.do_cmd('ZZIF;') self.assertEqual(41, len(result)) result = self.flex.do_cmd('ZZIF') self.assertEqual(41, len(result)) result = self.flex.do_cmd('') self.assertEqual('??;', result) result = self.flex.do_cmd('junk') self.assertEqual('??;', result) def test04_save_current_state(self): """test_save_current_state() checks that flex state can be saved, modified and restored """ savedstate = self.flex.save_current_state() self.assertEqual(savedstate, self.flex.saved_state[:]) self.flex.restore_saved_state() newsavedstate = self.flex.save_current_state() self.assertEqual(savedstate, newsavedstate) _aa = int([i for i in newsavedstate if 'ZZFA' in i][0][-12:-1]) _aa = 14000000 if _aa != 14000000 else 15000000 # aat = f'ZZFA{_aa:011};' self.flex.do_cmd(f'ZZFA{_aa:011};') modstate = self.flex.save_current_state() self.assertNotEqual(modstate, newsavedstate) restore_results = self.flex.restore_state(newsavedstate) self.assertEqual(19, len(restore_results)) self.assertEqual(newsavedstate, self.flex.saved_state) def test10_get_cat_data(self): """testget_cat_data() """ gdata1 = [ CMDListEnt( 'wait0.5', None, ), CMDListEnt( 'ZZIF;', postproc.zzifpost, ), ] stime = time.perf_counter() results = self.flex.get_cat_data([], 14_000_000) etime = time.perf_counter() dtime = etime - stime self.assertAlmostEqual(0.00, dtime, delta=0.001) stime = time.perf_counter() results = self.flex.get_cat_data([CMDListEnt( 'wait0.5', None, )], 14_000_000) etime = time.perf_counter() dtime = etime - stime self.assertAlmostEqual(0.50, dtime, delta=0.1) results = self.flex.get_cat_data(gdata1, 14_000_000) dtime = etime - stime self.assertAlmostEqual(0.50, dtime, delta=0.1) self.assertEqual(1, len(results)) def test05_jsonpickel(self): import jsonpickle try: self.flex.close() jsonpickelst = jsonpickle.encode( self.flex) # _ui cannot be pickeled testob = jsonpickle.decode(jsonpickelst) rp1 = repr(self.flex) rp2 = repr(testob) self.assertEqual(rp1, rp2) except Exception as ex: self.fail("unexpected exception") a = 0 b = 0 def test000011_get_cat_dataA(self): myband: BandPrams = BANDS['20'] proto: List[Tuple[Any, Any]] = GET_SMETER_PROTO[:] cmdlst: List[Tuple[Any, Any]] = [] for cmdt in myband.get_freq_cmds(): cmdlst.extend([CMDListEnt(cmdt, None)]) cmdlst.extend(proto) cmdresult: List[Any] = self.flex.get_cat_dataA(cmdlst) sm_readings: List[SMeter] = [ _ for _ in cmdresult if isinstance(_, SMeter) ] sm_readings.sort() cmdresultB: List[Any] = [ _ for _ in cmdresult if not isinstance(_, SMeter) ] cmdrestup = tuple(cmdresultB) self.assertEqual(myband.get_freq_cmds(), cmdrestup) maplist: List[Mapping[str, float]] = [ list(_.signal_st.items()) for _ in sm_readings ] keyset: Set[str] = set( [list(sm.signal_st.items())[0][1] for sm in sm_readings]) noisedic: Dict[str, List[SMeter]] = {} for k in keyset: noisedic.setdefault(k, []) for ls in maplist: noisedic[ls[0][1]].append(ls[1][1]) key = sorted(list(noisedic.keys()))[0] dkdk: List[SMeter] = [ sm for sm in sm_readings if sm.signal_st['sl'] == key ] sma: SMeterAvg = SMeterAvg(dkdk, myband.bandid) a = 0
def main(stop_events: Mapping[str, CTX.Event], queues: Mapping[str, CTX.JoinableQueue]): from smeteravg import SMeterAvg UI = UserInput() NOISE = None UI.request(port='com4') flexr = Flex(UI) initial_state = None try: if not flexr.open(): raise (RuntimeError('Flex not connected to serial serial port')) print('saving current flex state') initial_state = flexr.save_current_state() print('initializing dbg flex state') flexr.do_cmd_list(INITIALZE_FLEX) flexr.close() resultQ = queues.get(QK.dQ) stop_event = stop_events.get(SEK.da) NOISE = Noisefloor(flexr, resultQ, stop_event) NOISE.open() # loops must be less than 100 as that is the queue size and I am not emptying it here NOISE.doit(loops=90, interval=90, dups=True) # NOISE.doit(runtime=1, interval=60) try: stop_event.set() except StopEventException: pass if NOISE and NOISE.is_open: flexr.restore_state(initial_state) NOISE.close() indata: List[NFQ] = [] deck: Deck = Deck(1000) deck.q2deck(resultQ, mark_done=True) indata = deck.deck2lst() # try: # while True: #indata.append(resultQ.get(True, 1)) # resultQ.task_done() # except QEmpty: # pass # q is empty # except Exception as ex: # print(ex) #raise ex with open('nfqlistdata.pickle', 'wb') as jso: pickle.dump(indata, jso) unpacked: List[NFResult] = [npq.get() for npq in indata] with open('nfrlistdata.pickle', 'wb') as jso: pickle.dump(unpacked, jso) reads: List[SMeterAvg] = [] for nfr in unpacked: reads.extend(nfr.readings) with open('smavflistdata.pickle', 'wb') as jso: pickle.dump(reads, jso) up0: NFResult = unpacked[0] outdata = [] with open('nfqlistdata.pickle', 'rb') as jsi: outdata = pickle.load(jsi) brlst: List[Bandreadings] = [] for nfq in outdata: br: Bandreadings = nfq.get() brlst.append(br) a = indata[0] b = outdata[0] except(Exception, KeyboardInterrupt) as exc: if NOISE and NOISE.is_open: flexr.restore_state(initial_state) NOISE.close() UI.close() raise exc finally: print('restore flex prior state') if NOISE and NOISE.is_open: flexr.restore_state(initial_state) NOISE.close() UI.close()
class TestBandreadings(unittest.TestCase): """TestBandreadings """ def setUp(self): """setUp() """ _ui = UserInput() _ui.request('com4') self.flex = Flex(_ui) self.flex.open() self.flex.do_cmd_list(postproc.INITIALZE_FLEX) def tearDown(self): """tearDown() """ self.flex.close() @classmethod def setUpClass(cls): """setUpClass() """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() cls.initial_state = flex.save_current_state() flex.close() postproc.enable_bands(['10', '20']) @classmethod def tearDownClass(cls): """tearDownClass() """ _ui = UserInput() _ui.request('com4') flex = Flex(_ui) flex.open() flex.restore_state(cls.initial_state) flex.close() def test01_instat(self): """test01_instat() """ postproc.enable_bands('80', False) postproc.enable_bands('10') _br: Bandreadings = None try: _br = Bandreadings(None, self.flex) self.fail('should have had a KeyError') except KeyError as ke: pass try: _br = Bandreadings('80', self.flex) self.fail('should have had a ValueError') except ValueError as ve: pass _br = Bandreadings('10', self.flex) self.assertEqual('no reading, band 10', str(_br)) self.assertEqual('Bandreadings: no reading, band 10', repr(_br)) self.assertEqual('10', _br.bandid) _br = Bandreadings('20', self.flex) self.assertEqual('no reading, band 20', str(_br)) self.assertEqual('Bandreadings: no reading, band 20', repr(_br)) self.assertEqual('20', _br.bandid) _br = Bandreadings( '20', self.flex) # these freqs in 20m band self.assertEqual('no reading, band 20', str(_br)) self.assertEqual('Bandreadings: no reading, band 20', repr(_br)) self.assertEqual('20', _br.bandid) def test02_radioaccess(self): """test02_radioaccess() """ import multiprocessing as mp import queue CTX = mp.get_context('spawn') # threading context dataq = CTX.JoinableQueue(maxsize=100) try: _br: Bandreadings = Bandreadings( '20', self.flex) _br.get_readings(testing='./quiet20band.json') self.assertEqual( '[SMeterAvg: b:20, -103.45833adBm, -103.50000mdBm, S3, var: 0.15720, stddv: 0.39648]', repr(_br.band_signal_strength)) bss0: SMeterAvg = _br.band_signal_strength _br.flexradio = None # must be done to allow pikceling in the que dataq.put(_br) _br.get_readings(testing='./noisy20band.json') self.assertEqual( '[SMeterAvg: b:20, -102.06250adBm, -103.50000mdBm, S3, var: 12.79583, stddv: 3.57713]', repr(_br.band_signal_strength)) bss1: SMeterAvg = _br.band_signal_strength dataq.put(_br) # if _br.band_signal_strength.signal_st.get('stddv') > 1.5: # _br.changefreqs( # testing='./focusedbadspotreading.json') # self.assertEqual( #'[SMeterAvg: -103.32090adBm, -103.50000mdBm, S3, var: 0.74774, stddv: 0.86472]', # repr(_br.band_signal_strength)) datain: List[SMeterAvg] = [] try: while True: datain.append(dataq.get(True, 0.005)) dataq.task_done() except queue.Empty as mt: b = 0 pass except Exception as ex: a = 0 pass self.assertEqual(2, len(datain)) self.assertEqual( '[Bandreadings: SMeterAvg: [band:20, avgsignal: -103.45833dBm, S3, var: 0.15720, stddv: 0.39648]]', repr(datain[0])) tbr = datain[0] self.assertEqual( 'band:20, enabled: True, chan: False, [14000000, 14035000, 14070000, 14105000, 14140000, 14175000, 14210000, 14245000, 14280000, 14315000, 14350000]', str(tbr.myband)) # self.assertFalse(tbr.useable) bss0a = datain[0].band_signal_strength bss1a = datain[1].band_signal_strength self.assertEqual(repr(bss0), repr(bss0a)) self.assertEqual(repr(bss1), repr(bss1a)) except(Exception, KeyboardInterrupt) as exc: excs = str(exc) self.fail(f'unexpected exception {excs}') def test03_get_readings(self): """test03_get_readings() """ _br = Bandreadings( '20', self.flex) # 14000000 _br.get_readings(testing='./noisy20band.json') smar = _br.band_signal_strength self.assertEqual(16, len(smar.smlist)) self.assertEqual( 'SMeter: freq:14000000, -105.00000dBm, S3', repr(smar.smlist[0])) self.assertEqual( 'SMeter: freq:14074000, -96.00000dBm, S5', repr(smar.smlist[6])) self.assertEqual( '[SMeterAvg: b:20, -102.06250adBm, -103.50000mdBm, S3, var: 12.79583, stddv: 3.57713]', repr(smar))