def init_all(self, fsvconf, bdconf, thconf): try: fsvip = fsvconf['IP'] exlpath = fsvconf['DIR'] fsvoffset = float(fsvconf.get('OFFSET', 41)) self.fsv.set_offset(fsvoffset) # 设置衰减值 # for test self.fsv.init_fsv(fsvip) excel_path = self.make_dirs(exlpath) # 复制excel模板 cellid = str(bdconf.get('CELL', '0')) type, freqpoint_dict, freq_dict, ul_freq_dict = self.read_boardtype(excel_path, cellid) if type == '8125': self.bd = B8125Handler(**bdconf) elif type == 'T2K': self.bd = BT2KHandler(**bdconf) self.th_dev = None if thconf: self.th_dev = THDevice() # 高低温箱初始化 params_lst = [excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict] self.gd_test(*params_lst, **thconf) self.rpt_message('测试完成ok') # self.do_test(*params_lst,**temp_dict) except Exception as e: logger.error('error.{}.'.format(e)) self.rpt_message('ERROR:{}'.format(e)) self.rpt_message('测试失败') return False else: return True finally: self.bdexl.close_file() self.fsv.close_fsv()
def init_all(self, fsvconf, bdconf, thconf): try: fsvip = fsvconf['IP'] exlpath = fsvconf['DIR'] self.bd = BT2KHandler(**bdconf) bip = bdconf['IP'] # 设备IP if thconf: self.th_dev = THDevice() # 高低温箱初始化 ret = self.bd.read_bb_sn() if ret is None: raise RuntimeError('no serial number or productno') bbver, sn, productno = ret # 返回BB版本,序列号,物料号 excel_path = self.make_dirs(exlpath, sn, bbver, productno) # 复制excel模板 fsvoffset = self.read_offset(excel_path) # for test self.fsv.init_inst(fsvip) self.fsv.set_offset(fsvoffset) # 设置衰减值 self.fsv.reset_fsv() self.fsv.close_inst() params_lst = [productno, excel_path, bip, fsvip] self.gd_test(*params_lst, **thconf) return True, excel_path except Exception as e: self.logger.error('error.{}.'.format(e)) self.rpt_message('ERROR.{}.'.format(e)) return False finally: self.bdexl.close_file() self.fsv.close_inst()
def __init__(self, chl_name, chl_layer, log): self.zvlexl = ZVLExcel() self.th_dev = THDevice() self.zvl = ZVLCtrl() self.channel_name = chl_name self.channel_layer = chl_layer self.logger = log
def init_all(self, smbvconf, bdconf, thconf): try: exlpath = bdconf['DIR'] smbvip = smbvconf['IP'] # 信号源IP地址 exepath = smbvconf['PATH'] # 灵敏度测试软件路径 self.smbv.set_offset(float(smbvconf['OFFSET'])) # for test self.smbv.init_inst(smbvip) self.smbv.reset_smbv() self.smbv.close_inst() excel_path = self.make_dirs(exlpath) # 复制excel模板 cellid = str(bdconf.get('CELL', '0')) type, freqpoint_dict, freq_dict, ul_freq_dict = self.read_boardtype( excel_path, cellid) logger.debug(freqpoint_dict) # 下行频点 logger.debug(ul_freq_dict) # 上行频率 self.rpt_message('INFO:{}'.format(freqpoint_dict)) self.rpt_message('INFO:{}'.format(ul_freq_dict)) if type == '8125': self.bd = B8125Handler(**bdconf) elif type == 'T2K': self.bd = BT2KHandler(**bdconf) # T2K不区分主从片 boardip = bdconf['IP'] # if cellid == '1' and bb_conf: # conf.json中有b_BOARD的配置且cellid='1'才启用 # self.b_board = B8125Handler(**bb_conf) # 用于同步的8124/8125基带板 self.th_dev = None if thconf: self.th_dev = THDevice() params_lst = [ excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict ] self.gd_test(*params_lst, **thconf) self.rpt_message('测试完成OK') except Exception as e: logger.error('error.{}.'.format(e)) self.rpt_message('ERROR:{}.'.format(e)) self.rpt_message('测试失败') return False else: return True finally: self.bdexl.close_file() # self.powsup.close_ps() self.smbv.close_inst()
class DoULTest(object): def __init__(self, chl_name, chl_layer): # self.powsup = PowerSupply_SCPI() # 电源 self.smbv = SMBVBase() # 信号源 self.bd = None # T2K # self.b_board = None # 另一块8124/8125用于同步 self.bdexl = BoardExcel() # excel模板 self.channel_name = chl_name self.channel_layer = chl_layer atexit.register(self.clean) def clean(self): self.smbv.close_inst() self.bdexl.close_file() def rpt_message(self, msg): try: if self.channel_layer and self.channel_name: print('rpt_msg') async_to_sync(self.channel_layer.send)(self.channel_name, { "type": "send.message", "message": msg }) except Exception as e: print('rpt_msg error:{}'.format(e)) def init_all(self, smbvconf, bdconf, thconf): try: exlpath = bdconf['DIR'] smbvip = smbvconf['IP'] # 信号源IP地址 exepath = smbvconf['PATH'] # 灵敏度测试软件路径 self.smbv.set_offset(float(smbvconf['OFFSET'])) # for test self.smbv.init_inst(smbvip) self.smbv.reset_smbv() self.smbv.close_inst() excel_path = self.make_dirs(exlpath) # 复制excel模板 cellid = str(bdconf.get('CELL', '0')) type, freqpoint_dict, freq_dict, ul_freq_dict = self.read_boardtype( excel_path, cellid) logger.debug(freqpoint_dict) # 下行频点 logger.debug(ul_freq_dict) # 上行频率 self.rpt_message('INFO:{}'.format(freqpoint_dict)) self.rpt_message('INFO:{}'.format(ul_freq_dict)) if type == '8125': self.bd = B8125Handler(**bdconf) elif type == 'T2K': self.bd = BT2KHandler(**bdconf) # T2K不区分主从片 boardip = bdconf['IP'] # if cellid == '1' and bb_conf: # conf.json中有b_BOARD的配置且cellid='1'才启用 # self.b_board = B8125Handler(**bb_conf) # 用于同步的8124/8125基带板 self.th_dev = None if thconf: self.th_dev = THDevice() params_lst = [ excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict ] self.gd_test(*params_lst, **thconf) self.rpt_message('测试完成OK') except Exception as e: logger.error('error.{}.'.format(e)) self.rpt_message('ERROR:{}.'.format(e)) self.rpt_message('测试失败') return False else: return True finally: self.bdexl.close_file() # self.powsup.close_ps() self.smbv.close_inst() def make_dirs(self, exlpath): ''' 根据excel测试模板复制一份excel :param exlpath: :return: ''' if self.bdexl.open_excel(exlpath): arm_id, bb_id = self.bdexl.get_id() dirname = os.path.dirname(exlpath) if arm_id: new_path = os.path.join(os.path.join(dirname, str(arm_id)), str(bb_id)) else: new_path = dirname if not os.path.exists(new_path): os.makedirs(new_path) newexl_name = str(bb_id) + '.xlsx' end_path = os.path.join(new_path, newexl_name) if os.path.exists(end_path): return end_path else: copyfile(exlpath, end_path) return end_path else: return None def check_temp(self, target_temp): i = 0 j = 0 logger.debug('check temp {}'.format(target_temp)) while True: pv = self.th_dev.get_temp_pv() if not pv: time.sleep(60) j = j + 1 if j >= 3: raise StopIteration('dev not online**') continue if pv >= target_temp - 10 and pv <= target_temp + 10: # 上下1度 logger.info('i={},hit target {}'.format(i, target_temp)) if i >= 3: logger.info('高低温箱达到温度{}'.format(target_temp)) break i = i + 1 else: i = 0 time.sleep(30) def handle_test(self, target_temp, period): ''' 设置高低温温度 :param target_temp: period:以分钟为单位,到达温度后的持续时间 :return: ''' self.check_temp(target_temp) logger.info('到达温度后开始等待{}分钟'.format(period)) time.sleep(60 * int(period)) # 使用矢网测试 logger.info('start 基带板测试....') def gd_test(self, *args, **kwargs): try: excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, \ ul_freq_dict = args thconf = kwargs # if not thconf: # raise ModuleNotFoundError('高低温箱没有配置项') logger.debug(exepath) port = thconf.get('PORT', None) norm_temp = thconf.get('NORM_TEMP', None) low_temp = thconf.get('LOW_TEMP', None) high_temp = thconf.get('HIGH_TEMP', None) period = thconf.get('PERIOD', 20) # 平衡持续时间,以分钟为单位 if self.th_dev is None or not port: # 只进行常温测试 self.do_test(excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict) return if self.th_dev.connect_th(PORT='COM{}'.format(port)): logger.info('高低温箱connected**') self.th_dev.set_fixed_mode() if norm_temp is not None: logger.info('start 常温测试') self.th_dev.set_temp_sv(int(norm_temp) * 10) self.th_dev.start_dev() # 开始运行 if norm_temp is not None: self.handle_test(int(norm_temp) * 10, period) self.do_test(excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict, 1) logger.debug('******常温测试 finished****') if low_temp is not None: logger.info('start 低温测试') self.th_dev.set_temp_sv(int(low_temp) * 10) self.handle_test(int(low_temp) * 10, period) self.do_test(excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict, 0) logger.debug('******低温测试 finished****') if high_temp is not None: logger.info('start 高温测试') self.th_dev.set_temp_sv(int(high_temp) * 10) self.handle_test(int(high_temp) * 10, period) self.do_test(excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict, 2) logger.debug('******高温测试 finished****') logger.debug('高低温箱停止运行') self.th_dev.stop_dev() # 停止运行 except modbus_tk.modbus.ModbusError as e: logger.exception('th_dev {}'.format(e)) raise StopIteration('th_dev') except Exception as e: logger.error('gd_test:{}'.format(e)) raise StopIteration('gd_test:{}'.format(e)) def get_workmode_funid(self, bandsdict): ''' :param bandsdict: {'cell0':[],'cell1':[]} :return: ''' logger.debug(bandsdict) cell0 = bandsdict['cell0'] band0 = cell0[0] if len(cell0) > 0 else 'E' cell1 = bandsdict['cell1'] band1 = cell1[0] if len(cell1) > 0 else 'B1' lst = list(band_dict[band0]) + list(band_dict[band1]) return lst def do_test(self, excel_path, exepath, smbvip, boardip, cellid, freqpoint_dict, ul_freq_dict, temp=1): if excel_path is None: raise RuntimeError('excel does not exist!') if not self.bd.kill_arm_process(): raise RuntimeError('KILL ARM FAILED') key_bands = freqpoint_dict.keys() sens_dict = dict() # 灵敏度 {'E':[高,中,低],} # workmode_funid_lst = self.get_workmode_funid(bandsdict) for band in key_bands: mode = 'TDD' if band in ['B41', 'E', 'F'] else 'FDD' logger.info('开始测试band={}'.format(band)) self.rpt_message('INFO:开始测试band={}'.format(band)) cell_band = 'cell{}_{}'.format(cellid, band) sens_norm_list = self.read_sens_norm_from_excel( excel_path, cell_band) # 读取每个band灵敏度指标 if sens_norm_list is None: raise NotImplementedError('灵敏度指标为空') logger.debug('sens指标{}'.format(sens_norm_list)) sens_on_band = [] # 灵敏度 freq_points = freqpoint_dict[band] # 频点[高,中,低] try: self.conf_device(smbvip) # 初始化仪器仪表 flag = self.conf_board() # 设置T2K协程 if not flag: logger.error('基带板初始化设置异常') self.rpt_message('ERROR:基带板初始化设置异常') continue self.bd.conf_board_txatt() # TDD和FDD的初始txatt不同 for idx, freq_point in enumerate(freq_points): self.smbv.reset_smbv() # 关信号源 uplink_freq = ul_freq_dict[band][idx] # 对应的上行频率 ret, pci = self.conf_board_on_some_freq( freq_point) # 设置基带板一类参数,并返回PCI if not ret: logger.error('T2K 设置异常') self.rpt_message('ERROR:T2K 设置异常') continue if pci is None: logger.error('T2K 一类参数异常') self.rpt_message('ERROR:T2K 一类参数异常') continue sens = self.repeat_sens_on_freq(cellid, smbvip, uplink_freq, mode, pci, boardip, exepath, sens_norm_list) sens_on_band.append(sens) # FDD测试重启T2K # self.bd.reboot() # time.sleep(1) sens_dict.setdefault(cell_band, sens_on_band) # 灵敏度 except Exception as e: logger.error(e) finally: self.smbv.close_inst() if self.bdexl.open_excel(excel_path): self.bdexl.write_sens(temp, **sens_dict) self.bdexl.close_file() def conf_board(self): ''' 设置T2K :return: ''' if self.bd is None: return True return self.bd.do_test() def conf_board_on_some_freq(self, freq): ''' 基于某频点 freq:频点 :return: ''' try: logger.info('开始测试freq={}'.format(freq)) self.rpt_message('INFO:开始测试freq={}'.format(freq)) return self.bd.conf_para(freq) # 设置频点并打开功放 except Exception as e: logger.error(e) self.rpt_message('ERROR:{}'.format(e)) return False def get_ul_center(self, ul_list): ''' 获取上行频率的中心频率 ul_list:[] :return: ''' start = ul_list[2] - 2.5 stop = ul_list[0] + 2.5 logger.debug('ul={},{}'.format(start, stop)) return start, stop def read_excel_txatt_norm(self, excel_path): ''' 读取excel的上下行功率,频点等参数 :param excel_path: :return: ''' try: if self.bdexl.open_excel(excel_path): indicator = self.bdexl.get_txatt_norm()['标准值'] # 获取txatt指标 return indicator except Exception as e: raise RuntimeError(e) finally: self.bdexl.close_file() def read_sens_norm_from_excel(self, excel_path, cell_band): ''' 读取灵敏度指标范围 :param excel_path: :return: [下限,上限] ''' try: if self.bdexl.open_excel(excel_path): lowup = self.bdexl.get_sens_norm(cell_band) return lowup except Exception as e: raise RuntimeError(e) finally: self.bdexl.close_file() def read_boardtype(self, excel_path, cellid): ''' 从excel中读取board类型及主从片频点,频率 :param excel_path: cellid :0/1 :return: ''' try: if self.bdexl.open_excel(excel_path): self.bdexl.get_dl_rows() self.bdexl.get_ul_rows() # self.bdexl.get_normaltemp_level_rows() type, freqpoint_dict, freq_dict = self.bdexl.get_set_condition( cellid) ul_freq_dict = self.bdexl.get_ul_freq(cellid) # bandsdict = self.bdexl.get_bands() return type, freqpoint_dict, freq_dict, ul_freq_dict except Exception as e: raise RuntimeError('read_boardtype ERROR:{}'.format(e)) finally: self.bdexl.close_file() def conf_powersupply(self, port): ''' 设置电源的电压为12V,电流最大,给基带板供电 :return: ''' pass # self.powsup.init_ps(port) # time.sleep(1) # self.powsup.reset_ps() # time.sleep(3) # self.powsup.set_voltage(12) # maxcur = self.powsup.read_maxcurrent() # if maxcur is None: # maxcur = 20 # self.powsup.set_current(maxcur) # self.powsup.set_output(1) # 打开输出开关 def conf_smbv(self, ip, freq, mode, pci): ''' 设置信号源,level没有设置 :param ip: :param freq: 频率,MHz为单位 :param mode: TDD/FDD pci:从基带板读取的 :return: ''' i = 0 while 1: i = i + 1 if i > 3: raise ModuleNotFoundError('SMBV NOT ONLINE') try: self.smbv.init_inst(ip) break except Exception: time.sleep(5) self.smbv.close_inst() continue self.smbv.reset_smbv() print('***********') self.smbv.set_freq(freq) if mode == 'TDD': self.smbv.set_TDD_lte(pci) elif mode == 'FDD': self.smbv.set_FDD_lte(pci) self.smbv.set_rf_on() def repeat_sens_on_freq(self, cellid, ip, freq, mode, pci, boardip, exepath, normlist): ''' 重复获取灵敏度,有时读中兴软件会失败 :return: ''' i = 0 while 1: flag = self.sens_on_somefreq(cellid, ip, freq, mode, pci, boardip, exepath, normlist) if i > 3: logger.error('无法操作中兴灵敏度软件') self.rpt_message('ERROR:无法操作中兴灵敏度软件') raise NotImplementedError('无法操作中兴灵敏度软件') if flag is False: logger.debug('操作中兴软件失败') self.rpt_message('ERROR:操作中兴软件失败') i = i + 1 time.sleep(5) continue return flag def sens_on_somefreq(self, cellid, ip, freq, mode, pci, boardip, exepath, normlist): ''' 测试灵敏度,需要结合中兴的软件和信号源,顺序无所谓,只要基带板先配置 cellid:0/1 ip:信号源ip freq:信号源频率,上行 mode:TDD/FDD pci:基带板pci boardip:基带板IP exepath:中兴软件路径 normlist:灵敏度上下限 :return:int level ''' # if type == 'T2K': exeauto = T2KEXEOperate() # elif type == '8125': # exeauto = EXEOperate() if exeauto is None: logger.error('基带板类型wrong') return False try: # 设置信号源 self.conf_smbv(ip, freq, mode, pci) # 启动中兴软件 print('**start exe****') exeauto.start_exe(boardip, exepath) if not exeauto.site_manage(): logger.error('操作灵敏度软件错误') return False if not exeauto.enter_test_mode(cellid, mode): logger.error('操作灵敏度软件错误') return False if not exeauto.create_ue(): logger.error('操作灵敏度软件错误') return False coord = exeauto.ready_for_check() # 返回误码率表格所在位置 low_sens = int(normlist[0]) # 灵敏度下限 upper_sens = int(normlist[1]) # 灵敏度上限 sens = low_sens i = 0 while sens <= upper_sens: if i > 3: raise ModuleNotFoundError('bbSMBV not online') if not self.smbv.set_level(sens): # 设置信号源 time.sleep(3) logger.debug('conf_smbv') # self.conf_smbv(ip, freq, mode, pci) i = i + 1 continue i = 0 logger.debug('设置level={}'.format(sens)) self.rpt_message('INFO:设置level={}'.format(sens)) time.sleep(1) berlist = exeauto.check_result(coord) # 误码率 logger.debug('berlist={}'.format(berlist)) self.rpt_message('INFO:berlist={}'.format(berlist)) if not berlist: time.sleep(3) continue if self.check_sens_ok(berlist): # 误码率达标 return sens sens += 1 time.sleep(.5) # T2K FDD测试经常100,需要重启多次 return None # 在灵敏度指标范围内没有找到误码率为0的level except Exception as e: logger.error(e) return False finally: try: if exeauto: exeauto.close_exe() except Exception as e: pass def check_sens_ok(self, lst): ''' 判断误码率每个值是否都小于3 lst:float list :return: ''' retlist = [True if item < 5 else False for item in lst] return all(retlist) def conf_device(self, smbvip): ''' 仪器初始化 :return: ''' # 初始化信号源 logger.debug('设置信号源') self.smbv.init_inst(smbvip) self.smbv.reset_smbv() # self.powsup.init_ps(spport) # time.sleep(1) # self.powsup.reset_ps() # time.sleep(2) def reset_smbv(self, smbvip): # 初始化信号源 self.smbv.init_inst(smbvip) self.smbv.reset_smbv()
class LVBOQITest(object): def __init__(self, chl_name, chl_layer, log): self.zvlexl = ZVLExcel() self.th_dev = THDevice() self.zvl = ZVLCtrl() self.channel_name = chl_name self.channel_layer = chl_layer self.logger = log def rpt_message(self, msg): try: if self.channel_layer and self.channel_name: print('rpt_msg') async_to_sync(self.channel_layer.send)(self.channel_name, { "type": "send.message", "message": msg }) except Exception as e: print('rpt_msg error:{}'.format(e)) def init_zvl(self, cfg): try: config = copy.deepcopy(cfg) if config: if 'ZVL' not in config.keys(): self.logger.debug('no ZVL in config') return False zvlcfg = config['ZVL'] if 'IP' not in zvlcfg.keys() or 'DIR' not in zvlcfg.keys( ) or 'BAND' not in zvlcfg.keys(): self.logger.error('no IP/DIR/BAND in zvl config') return False ip = zvlcfg['IP'] dir = zvlcfg['DIR'] band = zvlcfg['BAND'] maxfreq = float(zvlcfg['MAX']) self.logger.debug('load config={}'.format(config)) self.rpt_message('load config={}'.format(config)) if not ip: self.logger.debug('ip is empty in zvl config') return False # for test self.zvl.init_inst(ip) self.zvl.reset_zvl() # 初始化zvl th_flag = False # 高低温配置 thconf = config.get('THDEV', {}) port = thconf.get('PORT', '') if not port: th_flag = False else: th_flag = True end_path = self.handle_path(dir, band) if not end_path: self.logger.error('no excel path') self.rpt_message('ERROR:no excel path') return False # 初始化连接zvl if not th_flag: self.logger.debug('常温测试') # 读取excel配置文件 ret = self.handle_content(end_path, band, maxfreq) self.logger.debug('******test finished****') self.rpt_message('INFO:******test finished****') return ret, end_path else: self.logger.debug('高低温测试') params = [end_path, band, maxfreq] ret = self.gd_test(*params, **thconf) return ret, end_path # loop = asyncio.get_event_loop() # params=[instr, end_path, band,maxfreq] # loop.run_until_complete(gd_test(*params,**thconf)) # loop.close() except Exception as e: self.logger.error('init_zvl error:{}'.format(e)) self.rpt_message('ERROR:init_zvl error:{}'.format(e)) return False def check_temp(self, target_temp): i = 0 j = 0 self.logger.debug('check temp {}'.format(target_temp)) while True: pv = self.th_dev.get_temp_pv() if not pv: time.sleep(60) j = j + 1 if j >= 3: raise StopIteration('dev not online**') continue if pv >= target_temp - 10 and pv <= target_temp + 10: # 上下1度 self.logger.info('i={},hit target {}'.format(i, target_temp)) if i >= 3: break i = i + 1 else: i = 0 time.sleep(30) def handle_test(self, target_temp, period): ''' :param target_temp: :param period: 以分钟为单位 :return: ''' self.check_temp(target_temp) self.logger.info('到达温度后开始等待{}分钟'.format(period)) time.sleep(60 * float(period)) # 使用矢网测试 self.logger.info('start zvl test....') def gd_test(self, *args, **kwargs): ''' 高低温测试 :return: ''' try: # th_dev = THDevice() ret = False end_path, band, maxfreq = args thconf = kwargs port = thconf.get('PORT') low_temp = thconf.get('LOW_TEMP', None) # 高低温箱的低温 high_temp = thconf.get('HIGH_TEMP', None) # 高低温箱的高温 norm_temp = thconf.get('NORM_TEMP', None) period = thconf.get('PERIOD', 20) if self.th_dev.connect_th(PORT='COM{}'.format(port)): self.logger.info('th connected**') self.th_dev.set_fixed_mode() if norm_temp is not None: self.logger.info('start 常温测试') self.th_dev.set_temp_sv(int(norm_temp) * 10) self.th_dev.start_dev() if norm_temp is not None: self.handle_test(int(norm_temp) * 10, period) ret = self.handle_content(end_path, band, maxfreq, 0) self.logger.debug('******常温测试 finished****') if low_temp is not None: self.logger.info('start 低温测试') self.th_dev.set_temp_sv(int(low_temp) * 10) self.handle_test(int(low_temp) * 10, period) ret = self.handle_content(end_path, band, maxfreq, 1) self.logger.debug('******低温测试 finished****') if high_temp is not None: self.logger.info('start 高温测试') self.th_dev.set_temp_sv(int(high_temp) * 10) self.handle_test(int(high_temp) * 10, period) ret = self.handle_content(end_path, band, maxfreq, 2) self.logger.debug('******高温测试 finished****') self.logger.debug('高低温箱停止运行') self.th_dev.stop_dev() return ret except modbus_tk.modbus.ModbusError as e: self.logger.exception('{}'.format(e)) raise StopIteration('th_dev') def handle_path(self, path, band): ''' 根据config目录下的test_conf.json文件中测试模板的路径path,生成对应器件id和序列号的文件夹及文件 :param path: :return:新生成的测试模板路径 ''' try: end_path = '' device_id_path = '' if self.zvlexl.open_excel(path): device_type, device_id = self.zvlexl.get_id( band) # 获取模板中待测试器件的类型及序列号 dirname = os.path.dirname(path) if device_type is not None: device_type_path = os.path.join(dirname, str(device_type)) if device_id is not None: device_id_path = os.path.join(device_type_path, str(device_id)) else: device_id_path = device_type_path else: device_type_path = dirname device_id_path = dirname if not os.path.exists(device_type_path): os.makedirs(device_type_path) if not os.path.exists(device_id_path): os.makedirs(device_id_path) excelname = os.path.basename(path) # 获取excel文件名 newexcelname = str(device_type) + '_' + str( device_id) + '.xlsx' # 新的excel表名 end_path = os.path.join(device_id_path, newexcelname) if os.path.exists(end_path): pass else: copyfile(path, end_path) else: return None self.logger.debug('end_path={}'.format(end_path)) except Exception as e: self.logger.error('{}'.format(e)) return None return end_path def handle_content(self, end_path, band, END_EDGE, temp=0): ''' 将图片保存到器件类型文件夹下序列号所在文件夹,根据器件类型创建文件夹,再创建序列号子文件夹 :param path: :param band: :param END_EDGE: :return: ''' try: temp_dict = {0: '常温', 1: '低温', 2: '高温'} if end_path: device_id_path = os.path.dirname(end_path) if self.zvlexl.open_excel(end_path): self.zvl.remove_allmarker(1) dfcontent = self.zvlexl.read_testitems( band) # 读取到Band区域所有行列的内容 if dfcontent is None: self.logger.error('zvl excel is empty') self.rpt_message('ERROR:zvl excel is empty') return False results = [] # 实测值及测试结果 # 先设置带内freq span low_edge, up_edge, leftlow_edge, rightup_edge = self.zvlexl.get_bandx_edge( band) self.logger.debug( 'low/up_edge,left/right={},{},{},{}'.format( low_edge, up_edge, leftlow_edge, rightup_edge)) self.set_edge(low_edge, up_edge) indicators = self.zvlexl.get_inband_indicator(dfcontent) self.logger.debug('indicators={}'.format(indicators)) tracen = 1 markern = 1 # 最大平均损耗S21 if self.set_trace(tracen, 'MLOG', 'S21'): results.append( self.get_max_avg_s21(tracen, markern, low_edge, up_edge, indicators[1])) else: results.append(None) # 最大插入损耗S21 results.insert( 0, self.get_min_loss(tracen, markern, indicators[0])) self.logger.debug('results={}'.format(results)) # S11 tracen += 1 if self.add_new_trace(tracen, 'MLOG', 'S11'): results.append( self.get_max_loss(tracen, 1, indicators[2])) else: results.append(None) self.logger.debug('results={}'.format(results)) # S22 tracen += 1 if self.add_new_trace(tracen, 'MLOG', 'S22'): results.append( self.get_max_loss(tracen, 1, indicators[3])) else: results.append(None) # 带内波动 results.append(self.get_ripple_in_bw(1, 1, indicators[4])) self.logger.debug( 'device_id_path={}'.format(device_id_path)) # auto scale # zvl.auto_scale(instr.zvlHandle,tracen) # 保存带内测试图片 inbandpngpath = os.path.join( device_id_path, '{}zvl_inband{}.PNG'.format(temp_dict[temp], band)) self.zvl.save_screenshot(r'c:\\Temp\\1.PNG', r'{}'.format(inbandpngpath)) # 删除trace s11,s22 self.zvl.delete_trace(2) self.zvl.delete_trace(3) self.zvl.remove_allmarker(1) time.sleep(1) # 带外抑制 outbanddf = self.zvlexl.get_outband_items( dfcontent) # dataframe markerxlist = [] # 带外的marker x,float,单位MHz for _, rows in outbanddf.iterrows(): # low_edge,up_edge,indicator_operator,indicator up_edge = rows[1] if rows[0] >= END_EDGE: break if rows[1] > END_EDGE: up_edge = END_EDGE markerxlist.extend([rows[0], up_edge]) self.set_edge(rows[0], up_edge) minabsy, minx = self.set_fixed_marker(rows[0], up_edge) self.logger.debug('absys={}'.format(minabsy)) results.append( self.get_outband_rejection(minabsy, minx, rows[2], rows[3])) filtered_markerxlist = [] # 去重后的markerx列表 for item in markerxlist: if item not in filtered_markerxlist: filtered_markerxlist.append(item) # self.set_edge(rows[0], up_edge) # time.sleep(0.3) # markerxy = self.get_min_rejection_marker(1, 1) # # zvl.auto_scale(instr.zvlHandle,1) # if markerxy: # # 保存图片 # outpngpath = os.path.join(device_id_path, # '{}band{}_out_{}.PNG'.format(temp_dict[temp], band, rows[0])) # outpngs.append(outpngpath) # zvl.save_screenshot(self.instr.zvlHandle, r'c:\\Temp\\1.PNG', r'{}'.format(outpngpath)) # # markerx, absy = markerxy # markerxlist.append(markerx) # 换算成MHz单位 # results.append(self.get_min_rejection(absy, rows[2], rows[3])) # 's21' # else: # results.append(None) # self.logger.debug('results={}'.format(results)) # 生成带外测试图 # outband_lowedge = outbanddf.iloc[0, 0] # 第一个带外点 # outband_upedge=outbanddf.iloc[-1,1] #最后一个带外点 # 截图 outband_lowedge = filtered_markerxlist[0] outband_upedge = filtered_markerxlist[-1] self.set_edge(outband_lowedge, outband_upedge) self.logger.debug( 'markerxlist={}'.format(filtered_markerxlist)) length = len(filtered_markerxlist) divided_marker = [ filtered_markerxlist[i:i + 10] for i in range(0, length, 10) ] # 10个marker为一组,分成多个子列表 idx = 0 outbandpngpaths = [] for part in divided_marker: self.logger.debug('part={}'.format(part)) self.set_outband_trace_marker(1, 1, part) outbandpngpath = os.path.join( device_id_path, '{}zvl_outband{}_{}.PNG'.format( temp_dict[temp], band, idx)) self.zvl.save_screenshot(r'c:\\Temp\\2.PNG', r'{}'.format(outbandpngpath)) time.sleep(.3) self.zvl.remove_allmarker(1) outbandpngpaths.append(outbandpngpath) idx += 1 self.set_edge(leftlow_edge, rightup_edge) filteredmarkerlist = [ item for item in filtered_markerxlist if leftlow_edge <= item <= rightup_edge ] self.logger.debug( 'filtered markerxlist={}'.format(filteredmarkerlist)) length = len(filteredmarkerlist) divided_marker = [ filteredmarkerlist[i:i + 10] for i in range(0, length, 10) ] # 10个marker为一组,分成多个子列表 for part in divided_marker: self.logger.debug('part={}'.format(part)) self.set_outband_trace_marker(1, 1, part) outbandpngpath = os.path.join( device_id_path, '{}zvl_outband{}_{}.PNG'.format( temp_dict[temp], band, idx)) self.zvl.save_screenshot(r'c:\\Temp\\2.PNG', r'{}'.format(outbandpngpath)) time.sleep(.3) self.zvl.remove_allmarker(1) outbandpngpaths.append(outbandpngpath) idx += 1 self.zvlexl.save_band_png(band, inbandpngpath, outbandpngpaths) # 结果写入excel self.zvlexl.write_results(band, results, temp) return True except Exception as e: raise RuntimeError('ERROR:{}'.format(e)) return False finally: self.zvlexl.close_file() self.zvl.close_inst() def set_edge(self, low_edge, up_edge): ''' :param low_edge: float单位MHz :param up_edge: float单位MHz :return: ''' try: low = '{}MHz'.format(low_edge) up = '{}MHz'.format(up_edge) self.zvl.set_freq(low, up) return True except Exception as e: self.logger.error('set_edge error {}'.format(e)) return False def set_trace(self, tracen, form, means): ''' :param tracen: int form:str, means:str,'S11','S12','S21','S22' :return: ''' try: self.zvl.set_trace_form(tracen, form) self.zvl.change_trace_meas(tracen, means) if form == 'MLOG': self.zvl.set_div_value(tracen, 10) # zvl.set_ref_value(zvlhandler, tracen, -40) return True except Exception as e: self.logger.error('set_trace error {}'.format(e)) return False def add_new_trace(self, tracen, form, means): try: self.zvl.add_trace(tracen, means, form) if form == 'MLOG': self.zvl.set_div_value(tracen, 10) # zvl.set_ref_value(zvlhandler, tracen, -40) return True except Exception as e: self.logger.error('add_new_trace error {}'.format(e)) return False def get_max_loss(self, tracen, markern, indicator): ''' 带内最大回波损耗S21/S11/S22,max marker 绝对值 :param tracen:int :param markern:int :param indicator:float :return: ''' try: self.zvl.create_max_marker(tracen, markern) # max marker # create_max_marker(zvlhandler, tracen, markern + 1) # max marker _, marker1y = self.zvl.query_marker(tracen, markern) absy = abs(marker1y) opstr = str(absy) + indicator[0] + str(indicator[1]) if eval(opstr): # 满足指标 return (absy, True) else: return (absy, False) # 不满足指标 except Exception as e: self.logger.error('get_max_loss error {}'.format(e)) return None def get_min_loss(self, tracen, markern, indicator): ''' 带内最大插入损耗S21/S11/S22,min marker 绝对值 :param tracen:int :param markern:int :param indicator:float :return: ''' try: self.zvl.create_min_marker(tracen, markern) # max marker # create_max_marker(zvlhandler, tracen, markern + 1) # max marker _, marker1y = self.zvl.query_marker(tracen, markern) absy = abs(marker1y) opstr = str(absy) + indicator[0] + str(indicator[1]) if eval(opstr): # 满足指标 return (absy, True) else: return (absy, False) # 不满足指标 except Exception as e: self.logger.error('get_min_loss error {}'.format(e)) return None def get_max_avg_s21(self, tracen, markern, low_edge, up_edge, indicator): ''' 1个曲线最多建10个marker 带内最大平均损耗S21 :param tracen:int :param markern:int :param low_edge:float,单位MHz :param up_edge:float,单位MHz :param indicator:('<=',float) :return: ''' try: interval = 5 # MHz startpoint = low_edge n = markern avglist = [] pointlist = [] endpoint = startpoint while endpoint <= up_edge: startpoint = endpoint endpoint = endpoint + interval if endpoint >= up_edge: endpoint = up_edge break midpoint = (startpoint + endpoint) / 2.0 pointlist.append(midpoint) midpoint = (startpoint + endpoint) / 2.0 pointlist.append(midpoint) self.logger.debug('midpoints={}'.format(pointlist)) for point in pointlist: self.zvl.set_trace_marker(tracen, n, '{}MHz'.format(point)) _, markery = self.zvl.query_marker(tracen, n) avglist.append(abs(markery)) # n = n + 1 avg = sum(avglist) / len(avglist) opstr = str(avg) + indicator[0] + str(indicator[1]) self.logger.debug('opstr={}'.format(opstr)) if eval(opstr): return (avg, True) else: return (avg, False) except Exception as e: self.logger.error('get_max_avg_s21 error {}'.format(e)) return None def get_ripple_in_bw(self, tracen, markern, indicator): ''' 带内波动 indicator:float :return: ''' try: self.zvl.create_min_marker(tracen, markern) # min marker self.zvl.create_max_marker(tracen, markern + 1) # max marker _, marker1y = self.zvl.query_marker(tracen, markern) _, marker2y = self.zvl.query_marker(tracen, markern + 1) absy = abs(marker1y - marker2y) opstr = str(absy) + indicator[0] + str(indicator[1]) if eval(opstr): # 满足指标 return (absy, True) else: return (absy, False) # 不满足指标 except Exception as e: self.logger.error('get_ripple_in_bw error{}'.format(e)) return None def get_min_rejection_marker(self, tracen, markern): ''' 带外抑制 max marker 的x,y绝对值 :param tracen: :param markern: :param indicator: :return:x,y,x的单位是Hz ''' try: self.zvl.create_max_marker(tracen, markern) # max marker marker1x, marker1y = self.zvl.query_marker(tracen, markern) absy = abs(marker1y) return marker1x / 1000000.0, absy except Exception as e: self.logger.error('get_min_rejection_marker error {}'.format(e)) return None def get_min_rejection(self, absy, *indicator): try: opstr = str(absy) + indicator[0] + str(indicator[1]) if eval(opstr): # 满足指标 return absy, True else: return absy, False # 不满足指标 except Exception as e: self.logger.error('get_min_rejection error {}'.format(e)) return None def set_outband_trace_marker(self, tracen, markern, markerlist): try: for x in markerlist: markerx = '{}MHz'.format(x) self.zvl.set_trace_marker(tracen, markern, markerx) markern = markern + 1 except Exception as e: self.logger.error('set_outband_trace_marker error {}'.format(e)) def set_fixed_marker(self, *markerxs): ''' 获取对应markerx1和2的y1,y2值,并获取y1,y2绝对值中的最小值 :param markerx1: :param markerx2: :return:[] ''' try: markern = 1 minabsy = None mini = 0 for i in range(len(markerxs)): x = '{}MHz'.format(markerxs[i]) self.logger.debug('markerx={}'.format(x)) self.zvl.set_trace_marker(1, markern, x) time.sleep(.5) _, markery = self.zvl.query_marker(1, markern) self.logger.debug('markery={}'.format(markery)) time.sleep(.5) if minabsy is not None: if abs(markery) < minabsy: minabsy = abs(markery) mini = i else: minabsy = abs(markery) mini = i markern = markern + 1 return minabsy, markerxs[mini] except Exception as e: self.logger.error('set_two_fixed_marker error {}'.format(e)) return [] def get_outband_rejection(self, minabsy, minx, *indicator): ''' 获取带外抑制 :param minabsy: minx: :param indicator: :return:absys中的最小值,是否通过 ''' try: if minabsy is None: return None ret = False opstr = str(minabsy) + indicator[0] + str(indicator[1]) if eval(opstr): # 满足指标 ret = True else: ret = False # 不满足指标 return ','.join([str(minx), str(minabsy)]), ret except Exception as e: self.logger.error('get_outband_rejection error {}'.format(e)) return None
class DoDlTest(object): def __init__(self,chl_name,chl_layer): self.fsv = FSVCtrl() # 频谱仪 # self.powsup = PowerSupply_SCPI() # 电源 self.bd = None self.bdexl = BoardExcel() # excel模板 self.channel_name = chl_name self.channel_layer = chl_layer def rpt_message(self, msg): try: if self.channel_layer and self.channel_name: print('rpt_msg') async_to_sync(self.channel_layer.send)( self.channel_name, { "type": "send.message", "message": msg } ) except Exception as e: print('rpt_msg error:{}'.format(e)) def init_all(self, fsvconf, bdconf, thconf): try: fsvip = fsvconf['IP'] exlpath = fsvconf['DIR'] fsvoffset = float(fsvconf.get('OFFSET', 41)) self.fsv.set_offset(fsvoffset) # 设置衰减值 # for test self.fsv.init_fsv(fsvip) excel_path = self.make_dirs(exlpath) # 复制excel模板 cellid = str(bdconf.get('CELL', '0')) type, freqpoint_dict, freq_dict, ul_freq_dict = self.read_boardtype(excel_path, cellid) if type == '8125': self.bd = B8125Handler(**bdconf) elif type == 'T2K': self.bd = BT2KHandler(**bdconf) self.th_dev = None if thconf: self.th_dev = THDevice() # 高低温箱初始化 params_lst = [excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict] self.gd_test(*params_lst, **thconf) self.rpt_message('测试完成ok') # self.do_test(*params_lst,**temp_dict) except Exception as e: logger.error('error.{}.'.format(e)) self.rpt_message('ERROR:{}'.format(e)) self.rpt_message('测试失败') return False else: return True finally: self.bdexl.close_file() self.fsv.close_fsv() # self.powsup.close_ps() def make_dirs(self, exlpath): ''' 根据excel测试模板复制一份excel :param exlpath: :return: ''' try: if self.bdexl.open_excel(exlpath): arm_id, bb_id = self.bdexl.get_id() dirname = os.path.dirname(exlpath) if arm_id: new_path = os.path.join(os.path.join(dirname, str(arm_id)), str(bb_id)) else: new_path = dirname if not os.path.exists(new_path): os.makedirs(new_path) newexl_name = str(bb_id) + '.xlsx' end_path = os.path.join(new_path, newexl_name) if os.path.exists(end_path): return end_path else: copyfile(exlpath, end_path) return end_path else: return None except Exception as e: logger.error(e) finally: self.bdexl.close_file() def check_temp(self, target_temp): i = 0 j = 0 logger.debug('check temp {}'.format(target_temp)) while True: pv = self.th_dev.get_temp_pv() if not pv: time.sleep(60) j = j + 1 if j >= 3: raise StopIteration('dev not online**') continue if pv >= target_temp - 10 and pv <= target_temp + 10: # 上下1度 logger.info('i={},hit target {}'.format(i, target_temp)) if i >= 3: logger.info('高低温箱达到温度{}'.format(target_temp)) break i = i + 1 else: i = 0 time.sleep(30) def handle_test(self, target_temp, period): ''' 设置高低温温度 :param target_temp: period:以分钟为单位,到达温度后的持续时间 :return: ''' self.check_temp(target_temp) logger.info('到达温度后开始等待{}分钟'.format(period)) time.sleep(60 * int(period)) # 使用矢网测试 logger.info('start 基带板测试....') def gd_test(self, *args, **kwargs): try: excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict = args thconf = kwargs # if not thconf: # raise ModuleNotFoundError('高低温箱没有配置项') port = thconf.get('PORT', None) norm_temp = thconf.get('NORM_TEMP', None) low_temp = thconf.get('LOW_TEMP', None) high_temp = thconf.get('HIGH_TEMP', None) period = thconf.get('PERIOD', 20) # 平衡持续时间,以分钟为单位 if self.th_dev is None or not port: # 只进行常温测试 logger.info('只进行常温测试') self.do_test(excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict, 1) return if self.th_dev.connect_th(PORT='COM{}'.format(port)): logger.info('高低温箱connected**') self.th_dev.set_fixed_mode() if norm_temp is not None: logger.info('start 常温测试') self.th_dev.set_temp_sv(int(norm_temp) * 10) self.th_dev.start_dev() # 开始运行 if norm_temp is not None: self.handle_test(int(norm_temp) * 10, period) self.do_test(excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict, 1) logger.debug('******常温测试 finished****') if low_temp is not None: logger.info('start 低温测试') self.th_dev.set_temp_sv(int(low_temp) * 10) self.handle_test(int(low_temp) * 10, period) self.do_test(excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict, 0) logger.debug('******低温测试 finished****') if high_temp is not None: logger.info('start 高温测试') self.th_dev.set_temp_sv(int(high_temp) * 10) self.handle_test(int(high_temp) * 10, period) self.do_test(excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict, 2) logger.debug('******高温测试 finished****') logger.debug('高低温箱停止运行') self.th_dev.stop_dev() # 停止运行 except modbus_tk.modbus.ModbusError as e: logger.exception('{}'.format(e)) raise StopIteration('th_dev') def do_test(self, excel_path, fsvip, cellid, type, freqpoint_dict, freq_dict, ul_freq_dict, temp=1): if excel_path is None: raise RuntimeError('excel does not exist!') if not self.bd.kill_arm_process(): raise RuntimeError('KILL ARM FAILED') key_bands = freqpoint_dict.keys() power_txatt_dict = dict() # {'B41':[(高txatt,高power,adj lower,adj upper),(中),(低)],'E':[(),(),()]} # power_range_dict = dict() # {'B41':[[],[],[]]} evm_dict = dict() # {'B41':[,,],[,,]} ccdf_dict = dict() danl_dict = dict() # {'B41':[,,]} power_spectrum_dict = dict() # 占用带宽 {'B41':[,,],'E':[,,]} # current_dict = dict() # 读取 电流 {'E':[,,],} for band in key_bands: mode = 'TDD' if band in ['B41', 'E', 'F'] else 'FDD' logger.info('开始测试band={}'.format(band)) self.rpt_message('INFO:开始测试band={}'.format(band)) each_band_power_txatt = [] # power_range_on_band = [] evm_on_band = [] ccdf_on_band = [] danl_on_band = [] power_spectrum_on_band = [] # 每个band有高中低三个频点,对应有三个带宽 # current_on_band = [] # 工作电流 freq_points = freqpoint_dict[band] freqs = freq_dict[band] ul_start, ul_stop = self.get_ul_center(ul_freq_dict[band]) # 上行频率,用于测底噪用 indicator = self.read_excel_txatt_norm(excel_path) workmode, funid = band_dict[band] if self.bd.do_test(workmode, funid): default_txatt = self.bd.conf_board_txatt() # TDD和FDD的初始txatt不同 for idx, freq_point in enumerate(freq_points): if not self.conf_board_on_some_freq(freq_point): # 设置基带板一类参数,并返回PCI logger.error('设置一类参数异常') self.rpt_message('ERROR:设置一类参数异常') continue self.conf_device(fsvip) freq = freqs[idx] logger.debug('freq={}'.format(freq)) self.rpt_message('INFO:freq={}'.format(freq)) result = self.get_max_power(indicator, freq, default_txatt, type) logger.info('get_max_power={}'.format(result)) self.rpt_message('INFO:get_max_power={}'.format(result)) if result: each_band_power_txatt.append(result) #for test evm = self.evm_on_some_freq_and_txatt(mode, freq) logger.debug('evm={}'.format(evm)) if evm == 0: evm = None evm_on_band.append(evm) ccdf = self.ccdf_on_some_freq_and_txatt(mode, freq) logger.debug('ccdf={}'.format(ccdf)) ccdf_on_band.append(ccdf) #计算带宽 power_spectrum = self.bandwidth_on_some_freq_and_txatt(mode, freq) logger.debug('power_spectrum={}'.format(power_spectrum)) power_spectrum_on_band.append(power_spectrum) # 计算底噪 danl = self.DANL_ON_some_freq(temp, ul_start, ul_stop, excel_path, freq) danl_on_band.append(danl) # 5-9取消测试21个档位 # maxtxatt = result[0] # power_range_on_freq = self.txatt_range_test_on_some_freq(type, freq, maxtxatt, default_txatt) # power_range_on_band.append(power_range_on_freq) cell_band = 'cell{}_{}'.format(cellid, band) power_txatt_dict.setdefault(cell_band, each_band_power_txatt) # power_range_dict.setdefault(cell_band, power_range_on_band) #21个档位 evm_dict.setdefault(cell_band, evm_on_band) ccdf_dict.setdefault(cell_band, ccdf_on_band) danl_dict.setdefault(cell_band, danl_on_band) power_spectrum_dict.setdefault(cell_band, power_spectrum_on_band) # current_dict.setdefault(cell_band, current_on_band) # 工作电流 if self.bdexl.open_excel(excel_path): self.bdexl.write_max_txatt(temp, **power_txatt_dict) self.bdexl.write_ACPR(temp, **power_txatt_dict) # ACPR(LOWER/UPPER) # self.bdexl.write_power_range(temp, **power_range_dict) #21个档位输出功率 self.bdexl.write_ccdf(temp, **ccdf_dict) # PPM和峰均比 self.bdexl.write_EVM(temp, **evm_dict) # EVM self.bdexl.write_DANL(temp, **danl_dict) # 底噪 self.bdexl.write_powerspectrum(temp, **power_spectrum_dict) self.bdexl.close_file() def txatt_range_test_on_some_freq(self, type, freq, maxtxatt, default_txatt): ''' txatt档位测试,21个档位 衰减增大,功率越小 :return: ''' # fsv.set_for_txatt(freq) level_num = 20 power_lst = [] # [(),()] self.fsv.set_for_txatt(freq) if type == '8125': base = maxtxatt - default_txatt if base < -6: base = -6 ct = base for i in range(level_num): ct = ct + 1 self.bd.set_power_compensation(ct, 0) time.sleep(2) power = self.fsv.get_power(freq)[0] power_lst.append(power) elif type == 'T2K': ct = maxtxatt for i in range(level_num): ct = ct + 1 self.bd.set_txatt(ct) time.sleep(1) power = self.fsv.get_power(freq)[0] power_lst.append(power) # logger.debug('power_lst={}'.format(power_lst)) return power_lst def evm_on_some_freq_and_txatt(self, mode, freq): ''' 在基带板最大功率输出下的EVM :return: ''' return self.fsv.get_EVM(mode, freq) def ccdf_on_some_freq_and_txatt(self, mode, freq): ''' :param mode: :param freq: :return: (ppm,crest factor) ''' return self.fsv.get_CCDF(mode, freq) def bandwidth_on_some_freq_and_txatt(self, mode, freq): ''' :param mode: :param freq: :return: float Mhz ''' return self.fsv.get_power_spectrum(mode, freq) def DANL_ON_some_freq(self, temp, start, stop, exlpath, freq): ''' 底噪,基带板设置成某频点,频谱仪在其band的[高,低频率],且基带板要关闭射频开关 temp:0:低温 1:常温 2:高温 :param center_freq: :return: ''' tempstr = '' if temp == 0: tempstr = '低温' elif temp == 1: tempstr = '常温' elif temp == 2: tempstr = '高温' self.bd.set_rf(0) # 关闭射频 time.sleep(3) pngpath = os.path.join(os.path.dirname(exlpath), '{}_DANL_{}.PNG'.format(tempstr, freq)) danl = self.fsv.set_for_DANL(start, stop) self.fsv.save_screenshot(pngpath) # 打开射频 self.bd.set_rf(1) time.sleep(1) return danl def conf_board_on_some_freq(self, freq): ''' 基于某频点 freq:频点 :return: ''' logger.info('开始测试freq={}'.format(freq)) try: flag = self.bd.conf_para(freq) # 设置频点并打开功放 return flag except Exception as e: logger.error(e) return False def get_max_power(self, power_indicator, freq, default_txatt, type): ''' 获取基带板的最大输出功率及对应的txatt indicator:标准值 str freq:频率 str default_txatt :int type:str :return:(float power,int txatt) ''' norm = power_indicator # 标准值 current_txatt = self.bd.read_txatt() logger.debug('current_txatt={}'.format(current_txatt)) ref_level = 10 self.fsv.set_for_txatt(ref_level, freq) if current_txatt is not None: power = self.fsv.get_power(ref_level, freq)[0] logger.debug('current_power={}'.format(power)) if power is not None: if type == '8125': while True: delta = round(float(power)) - int(norm) + current_txatt - default_txatt logger.debug('delta={}'.format(delta)) if delta < -6: delta = -6 self.bd.set_power_compensation(delta, 0) time.sleep(2) current_txatt = self.bd.read_txatt() logger.debug('curr_txatt={}'.format(current_txatt)) if current_txatt is None: raise RuntimeError('read txatt error') time.sleep(1) plst = self.fsv.get_power(ref_level, freq) logger.debug('plst={}'.format(plst)) if plst is None: break power = plst[0] if abs(float(power) - int(norm)) < 1: return (current_txatt, float(power), float(plst[1]), float(plst[2])) if delta == -6: return (current_txatt, float(power), float(plst[1]), float(plst[2])) elif type == 'T2K': while True: delta = round(float(power)) - int(norm) new_txatt = current_txatt + delta logger.debug('new_txatt={}'.format(new_txatt)) if new_txatt < default_txatt: new_txatt = default_txatt self.bd.set_txatt(new_txatt) time.sleep(2) current_txatt = self.bd.read_txatt() logger.debug('curr_txatt={}'.format(current_txatt)) if current_txatt is None: raise RuntimeError('read txatt error') plst = self.fsv.get_power(ref_level, freq) logger.debug('plst={}'.format(plst)) if plst is None: break power = plst[0] if abs(float(power) - int(norm)) < 1: return (current_txatt, float(power), float(plst[1]), float(plst[2])) if current_txatt == default_txatt: return (current_txatt, float(power), float(plst[1]), float(plst[2])) return None def get_ul_center(self, ul_list): ''' 获取上行频率的中心频率 ul_list:[] :return: ''' start = ul_list[2] - 2.5 stop = ul_list[0] + 2.5 logger.debug('ul={},{}'.format(start, stop)) return start, stop def read_excel_txatt_norm(self, excel_path): ''' 读取excel的上下行功率,频点等参数 :param excel_path: :return: ''' try: if self.bdexl.open_excel(excel_path): indicator = self.bdexl.get_txatt_norm()[1] # 获取txatt指标 return indicator except Exception as e: raise RuntimeError(e) finally: self.bdexl.close_file() def read_boardtype(self, excel_path, cellid): ''' 从excel中读取board类型及主从片频点,频率 :param excel_path: cellid :0/1 :return: ''' try: if self.bdexl.open_excel(excel_path): self.bdexl.get_dl_rows() self.bdexl.get_ul_rows() # self.bdexl.get_normaltemp_level_rows() type, freqpoint_dict, freq_dict = self.bdexl.get_set_condition(cellid) ul_freq_dict = self.bdexl.get_ul_freq(cellid) return type, freqpoint_dict, freq_dict, ul_freq_dict except Exception as e: raise RuntimeError('read_boardtype ERROR:{}'.format(e)) finally: self.bdexl.close_file() def conf_powersupply(self, port): ''' 设置电源的电压为12V,电流最大,给基带板供电 :return: ''' pass # self.powsup.init_ps(port) # time.sleep(1) # self.powsup.reset_ps() # time.sleep(3) # self.powsup.set_voltage(12) # maxcur = self.powsup.read_maxcurrent() # if maxcur is None: # maxcur = 20 # self.powsup.set_current(maxcur) # self.powsup.set_output(1) # 打开输出开关 def conf_device(self, fsvip): ''' 仪器初始化 :return: ''' i = 0 while 1: if i > 3: raise ModuleNotFoundError('FSV NOT ONLINE') i = i + 1 try: self.fsv.init_fsv(fsvip) time.sleep(1) self.fsv.reset_fsv() time.sleep(1) break except Exception: time.sleep(3) continue
class TcompTEST(object): def __init__(self, chl_name, chl_layer, log): self.channel_name = chl_name self.channel_layer = chl_layer self.logger = log self.fsv = FSVCtrl() # 频谱仪 self.bd = None self.bdexl = BoardExcel() # excel模板 self.th_dev = None self.process_flat = FlatProcess() self.process_gain = GainProcess() self.adjust_evt = threading.Event() self.adjust_evt.clear() self.wait_evt = threading.Event() self.wait_evt.clear() self.wait_thread = PropagatingThread(target=self.check_cpu_temp) self.wait_thread.setDaemon(True) self.wait_thread.start() self.adjust_thread = None atexit.register(self.clean) def rpt_message(self, msg): try: if self.channel_layer and self.channel_name: print('rpt_msg') async_to_sync(self.channel_layer.send)(self.channel_name, { "type": "send.message", "message": msg }) except Exception as e: print('rpt_msg error:{}'.format(e)) def clean(self): self.fsv.close_inst() self.bdexl.close_file() def init_all(self, fsvconf, bdconf, thconf): try: fsvip = fsvconf['IP'] exlpath = fsvconf['DIR'] self.bd = BT2KHandler(**bdconf) bip = bdconf['IP'] # 设备IP if thconf: self.th_dev = THDevice() # 高低温箱初始化 ret = self.bd.read_bb_sn() if ret is None: raise RuntimeError('no serial number or productno') bbver, sn, productno = ret # 返回BB版本,序列号,物料号 excel_path = self.make_dirs(exlpath, sn, bbver, productno) # 复制excel模板 fsvoffset = self.read_offset(excel_path) # for test self.fsv.init_inst(fsvip) self.fsv.set_offset(fsvoffset) # 设置衰减值 self.fsv.reset_fsv() self.fsv.close_inst() params_lst = [productno, excel_path, bip, fsvip] self.gd_test(*params_lst, **thconf) return True, excel_path except Exception as e: self.logger.error('error.{}.'.format(e)) self.rpt_message('ERROR.{}.'.format(e)) return False finally: self.bdexl.close_file() self.fsv.close_inst() def make_dirs(self, exlpath, sn, bbver, pno): ''' 根据excel测试模板复制一份excel :param exlpath: :return: ''' try: today = datetime.date.today().strftime('%y-%m-%d') # 返回字符串 dirname = os.path.dirname(exlpath) new_path = os.path.join(dirname, today) if sn: new_path = os.path.join(new_path, sn) if not os.path.exists(new_path): os.makedirs(new_path) # newexl_name = str(sn) + '.xlsx' newexl_name = '1.xlsx' end_path = os.path.join(new_path, newexl_name) if os.path.exists(end_path): return end_path else: copyfile(exlpath, end_path) if self.bdexl.open_excel(end_path): # 写入bb ver,serialnumber self.bdexl.write_bbver_sn(bbver, sn) self.bdexl.write_productno(pno) else: return None return end_path except Exception as e: self.logger.error(e) finally: self.bdexl.close_file() def gd_test(self, *args, **kwargs): try: thconf = kwargs # if not thconf: # raise ModuleNotFoundError('高低温箱没有配置项') port = thconf.get('PORT', None) # for test # self.do_test(*args) if self.th_dev.connect_th(PORT='COM{}'.format(port)): self.logger.info('高低温箱connected**') self.th_dev.set_fixed_mode() self.th_dev.start_dev() self.do_test(*args) self.logger.debug('高低温箱20度运行') # self.th_dev.stop_dev() # 停止运行 self.th_dev.set_temp_sv(int(20 * 10)) # 设置成20度 except modbus_tk.modbus.ModbusError as e: self.logger.exception('{}'.format(e)) raise StopIteration('th_dev') def do_test(self, *args): productno, excel_path, bip, fsvip = args if excel_path is None: raise RuntimeError('excel does not exist!') if not self.bd.do_set_bd(): raise RuntimeError('强建小区失败') self.do_test_on_cellid(productno, excel_path, bip, fsvip) self.bd.switch_reboot() # 开启检测不到采集就重启的开关 def set_bd_rf(self, freqpoint_dict): key_bands = freqpoint_dict.keys() for cellband in key_bands: if 'CELL0' in cellband.upper(): cellid = '0' self.bd.set_rf('1', 0) else: cellid = '1' self.bd.set_rf('0', 0) freq_points = freqpoint_dict[str(cellband)] self.conf_board_on_some_freq(cellid, freq_points[0]) def do_test_on_cellid(self, productno, excel_path, bip, fsvip): freqpoint_dict, freq_dict = self.read_boardtype( excel_path) # 返回各band的频点,频率 self.logger.debug(freqpoint_dict) self.logger.debug(freq_dict) power_range, test_temp, centertemp = self.read_excel_txatt_norm( excel_path) # 功率的指标[下限,标准值,上限] self.logger.debug(power_range) test_temp = [float(item) for item in test_temp] centertemp = float(centertemp) if not self.bd.do_compensation('0'): return # 初始化温补,频补表 self.init_flat_and_gain_comp(productno, freqpoint_dict, test_temp, centertemp, bip, excel_path) # 打开该打开的射频开关并将档位设置成0档 self.set_bd_rf(freqpoint_dict) self.set_cpu_temp(centertemp, 0, 0) if self.process_flat.read_and_set(freqpoint_dict, centertemp): self.update_bb_flat_comp(productno, bip, excel_path) if self.process_gain.read_and_set(freqpoint_dict): self.update_bb_gain_comp(productno, bip, excel_path) # for test flg = self.repeat_flat_comp(centertemp, fsvip, freqpoint_dict, freq_dict, power_range, productno, bip, excel_path) if not flg: self.rpt_message('基准温度补偿失败') raise RuntimeError('基准温度补偿失败') self.repeat_gain_comp(test_temp, centertemp, fsvip, power_range, freqpoint_dict, freq_dict, productno, bip, excel_path) def repeat_gain_comp(self, test_temp, centertemp, fsvip, power_range, freqpoint_dict, freq_dict, productno, bip, excel_path): ''' 温度补偿 :return: ''' key_bands = freqpoint_dict.keys() target = power_range[1] length = len(test_temp) centeridx = test_temp.index(centertemp) # 测试不同温度下补偿值 self.logger.debug('开始温度补偿测试') self.rpt_message('开始温度补偿测试') # 温度[20,10,0,-10,-20,40,50,60,70] if centeridx >= 1: newrange = list(range(centeridx - 1, -1, -1)) + list( range(centeridx + 1, length)) # 序号[] else: newrange = list(range(centeridx + 1, length)) self.logger.debug(newrange) for index, idx in enumerate(newrange): # 按从基准温度降温到最低温度再升温度 temp = test_temp[idx] # 取温度 self.logger.debug('待测温度{}'.format(temp)) self.rpt_message('待测温度{}'.format(temp)) tempidx = self.process_gain.read_tempidx(temp) # 取下一温度的tempidx nexttemp = None nexttempidx = None if temp < centertemp: nexttemp = int(temp) - 10 # 减10度,20,10,0,-10,-20,... self.logger.debug('下一复制温度{}'.format(nexttemp)) nexttempidx = self.process_gain.read_tempidx(nexttemp) else: nexttemp = int(temp) + 10 # 加10度,40,50,60,70 nexttempidx = self.process_gain.read_tempidx(nexttemp) self.logger.debug('下一复制温度{}'.format(nexttemp)) if temp > 0: self.set_cpu_temp(temp - 1, 1, 1) # 低于目标温度1度即可,因为运行着温度会上升 else: self.set_cpu_temp(temp + 1, 1, -1) # 低温时,最好高于目标温度1度,因为温度会下降 # fg = self.set_temp_comp(fsvip, target, freqpoint_dict, freq_dict, tempidx, nexttempidx) # if not fg: # raise RuntimeError('温度补偿失败') # self.update_bb_gain_comp(productno, bip, excel_path) self.logger.debug('复测{}度'.format(temp)) power_dict = dict( ) # {'B41':[power,power,power],'E':[power,power,power]} d1 = dict() try: self.conf_device(fsvip) for cellband in key_bands: if 'CELL0' in cellband.upper(): cellid = '0' self.bd.set_rf('1', 0) else: cellid = '1' self.bd.set_rf('0', 0) bandstr = cellband.split('_')[-1] band = re.sub('\D', '', bandstr) # band的数字,1/3/41/38/39 freq_points = freqpoint_dict[str(cellband)] freqs = freq_dict[str(cellband)] power_dict.setdefault(cellband, [('', '')] * len(freq_points)) d1.setdefault(cellband, [''] * len(freq_points)) for ii, freq_point in enumerate(freq_points): if not freq_point: continue freq = freqs[ii] if not self.conf_board_on_some_freq( cellid, freq_point): # 设置基带板一类参数,并返回PCI self.logger.error('设置一类参数异常') continue i = 0 while True: i = i + 1 if i > 10: self.logger.error('{}-{}温补失败'.format( temp, freq_point)) self.rpt_message('{}-{}温补失败'.format( temp, freq_point)) self.fsv.close_inst() os.system('pause') break result = self.power_test_on_some_freq( cellid, fsvip, freq, power_range) if result is None: self.conf_board_on_some_freq( cellid, freq_point) continue if result[0]: power_dict[cellband][ii] = result[1:] break else: # if i > 7: # self.logger.error('{}-{}温补失败'.format(temp, freq_point)) # self.rpt_message('{}-{}温补失败'.format(temp, freq_point)) # self.fsv.close_inst() # os.system('pause') # break # for test currenttemp = self.bd.repeat_get_temp( ) # 获取基带板温度 self.logger.debug( '复补当前设备温度{}'.format(currenttemp)) self.rpt_message( '复补当前设备温度{}'.format(currenttemp)) if abs(currenttemp - temp) >= 2: if temp > 0: self.set_cpu_temp(temp - 1, 1, 1) else: self.set_cpu_temp(temp + 1, 1, -1) result = self.power_test_on_some_freq( cellid, fsvip, freq, power_range) if result is None: self.conf_board_on_some_freq( cellid, freq_point) continue power = result[1] # 获取功率 self.logger.debug( 'fsv read power={}'.format(power)) self.rpt_message( 'fsv read power={}'.format(power)) value = float(power) - float(target) # if i > 1: # value = value * 0.6 if abs(value) <= 0.4: value = 0.15 if value > 0 else -0.15 self.logger.debug( 'power-target={}'.format(value)) self.rpt_message( 'power-target={}'.format(value)) self.process_gain.set_bandinfo( tempidx, nexttempidx, band, freq_point, float('%6.2f' % value)) self.update_bb_gain_comp( productno, bip, excel_path) d1[cellband][ii] = self.process_gain.read_bandinfo( tempidx, band, freq_point) except Exception as e: self.logger.error(e) self.rpt_message('ERROR:{}'.format(e)) finally: self.fsv.close_inst() try: eid = (list(range(-20, 80, 10))).index(temp) if self.bdexl.open_excel(excel_path): self.bdexl.write_cali(eid, **d1) self.bdexl.write_power(eid, **power_dict) except Exception as e: self.logger.error(e) finally: self.bdexl.close_file() # 增加-30,-40度的补偿值,复制-20度的补偿值 self.process_gain.copy_30and40() self.process_gain.copy_70() self.update_bb_gain_comp(productno, bip, excel_path) def update_bb_gain_comp(self, productno, bip, excel_path): ''' 将本地温补表更新到BB :return: ''' self.logger.debug('update_bb_gain_comp') i = 0 while 1: if i > 3: raise RuntimeError('补偿文件异常') try: if self.bd.remove_gain_comp_json(): # 删除原gaincomp.json文件 if self.write_gain_comp_json(productno, bip, excel_path): # 写文件并上传 self.bd.refresh_comp() # 刷新 break else: self.reset_bd() time.sleep(3) i = i + 1 except Exception as e: self.reset_bd() i = i + 1 def update_bb_flat_comp(self, productno, bip, excel_path): self.logger.debug('update_bb_flat_comp') i = 0 while 1: if i > 3: raise RuntimeError('补偿文件异常') try: if self.bd.remove_flat_comp_json(): # 删除原gaincomp.json文件 if self.write_flat_comp_json(productno, bip, excel_path): # 写文件并上传 self.bd.refresh_comp() # 刷新 break else: self.reset_bd() time.sleep(3) i = i + 1 except Exception as e: self.reset_bd() i = i + 1 def init_flat_and_gain_comp(self, productno, freqpoint_dict, test_temp, centertemp, bip, excel_path): ''' 初始化温补,频补表到内存 :return: ''' ret = self.bd.read_flat_and_gain_json(productno) if ret is None: self.process_flat.init_flat_comp(freqpoint_dict, test_temp, centertemp) self.process_gain.init_gain_comp(freqpoint_dict, test_temp) self.update_bb_flat_comp(productno, bip, excel_path) self.update_bb_gain_comp(productno, bip, excel_path) else: fj, gj = ret if fj is None: self.process_flat.init_flat_comp(freqpoint_dict, test_temp, centertemp) self.update_bb_flat_comp(productno, bip, excel_path) else: self.process_flat.init_comp_from_file(fj) if gj is None: self.process_gain.init_gain_comp(freqpoint_dict, test_temp) self.update_bb_gain_comp(productno, bip, excel_path) else: self.process_gain.init_comp_from_file(gj) def repeat_flat_comp(self, centertemp, fsvip, freqpoint_dict, freq_dict, power_range, productno, bip, excel_path): ''' 多次平坦度补偿,直到达标 :return: ''' target = float(power_range[1]) lower = float(power_range[0]) # 下限 upper = float(power_range[2]) # 上限 freq_keys = freqpoint_dict.keys() freq_values = freqpoint_dict.values() tempidx = list(range(-20, 80, 10)).index(centertemp) # self.set_flat_comp(fsvip, target, freqpoint_dict, freq_dict, productno, bip, excel_path) # 基准温度下温补默认为0 temp_cali_dict = dict( zip(freq_keys, [[0] * len(list(freq_values)[0])] * len(freq_keys))) power_dict = dict( ) # {'B41':[power,power,power],'E':[power,power,power]} try: self.conf_device(fsvip) for cellband in freq_keys: self.logger.debug('cellband={}'.format(cellband)) self.rpt_message('cellband={}'.format(cellband)) if 'CELL0' in cellband.upper(): cellid = '0' self.bd.set_rf('1', 0) else: cellid = '1' self.bd.set_rf('0', 0) bandstr = cellband.split('_')[-1] band = re.sub('\D', '', bandstr) # band的数字,1/3/41/38/39 freq_points = freqpoint_dict[str(cellband)] freqs = freq_dict[str(cellband)] power_dict.setdefault(cellband, [('', '')] * len(freq_points)) for idx, point in enumerate(freq_points): freq = freqs[idx] self.conf_board_on_some_freq(cellid, point) # 设置基带板频点 i = 0 while 1: i = i + 1 if i > 9: return False # 复测 # for test plst = self.get_fsv_power(fsvip, target, freq) if plst is None: time.sleep(10) continue power = float(plst) # 读取频谱仪功率 if lower <= power <= upper: power_dict[cellband][idx] = power, 'PASS' break power_dict[cellband][idx] = power, 'FAIL' delta = power - target if abs(delta) <= 0.4: delta = 0.15 if delta > 0 else -0.15 self.logger.debug('flat delta={}'.format(delta)) cali = float('%.2f' % delta) self.process_flat.set_bandinfo(band, point, cali) # 更新设备频补补偿表 self.update_bb_flat_comp(productno, bip, excel_path) else: return True except Exception as e: self.logger.error(e) finally: self.fsv.close_inst() try: if self.bdexl.open_excel(excel_path): self.bdexl.write_power(tempidx, **power_dict) self.bdexl.write_cali(tempidx, **temp_cali_dict) except Exception: pass finally: self.bdexl.close_file() def power_test_on_some_freq(self, cellid, fsvip, freq, power_range): ''' freq:频率 power_range:功率标准[下限,理想值,上限,] :return: ''' lower = float(power_range[0]) # 下限 upper = float(power_range[2]) # 上限 # for test plst = self.get_fsv_power(fsvip, float(power_range[1]), freq) if plst is None: return None power = float(plst) # 读取频谱仪功率 # txatt = self.bd.read_txatt(cellid) if power >= lower and power <= upper: return True, power, 'PASS' elif power > upper: # self.bd.set_rf(cellid, 0) # 关闭射频 self.logger.error('功率{}超限'.format(power)) else: # self.bd.set_rf(cellid, 0) # 关闭射频 self.logger.error('功率{}不达标'.format(power)) return False, power, 'FAIL' def conf_board_on_some_freq(self, cellid, freq): ''' 基于某频点 freq:频点 :return: ''' self.logger.debug('conf_board_on_some_freq') try: flag = self.bd.conf_para(cellid, freq) # 设置频点并打开功放 return flag except Exception as e: self.logger.error(e) return False def get_and_send_powercali(self, cellid, fsvip, band, freq_points, freqs, target): ''' 遍历band的三个频点,得到功率补偿,发送给BB band: freq_points:频点,用于发给基带板 freqs:频率,用于设置频谱仪 target:功率理想值dBm return [[int(freq), float(cali),温度],,] ''' temp = self.bd.repeat_get_temp() # 获取基带板温度 if temp is None: raise IOError('get temp failed') self.logger.debug('current temp={}'.format(temp)) for idx, point in enumerate(freq_points): freq = freqs[idx] self.conf_board_on_some_freq(cellid, point) # 设置基带板频点 plst = self.get_fsv_power(fsvip, target, freq) if plst is None: raise IOError('read fsv power failed') power = plst self.logger.debug('fsv read power={}'.format(power)) value = float(power) - float(target) cali = float('%.2f' % value) self.process_flat.set_bandinfo(band, point, cali) # 更新内存 def get_fsv_power(self, fsvip, upper, freq): ''' 读取频谱仪功率 upper:输出功率上限,用来设置ref level,ref level=upper+3 :return: ''' i = 0 ref_level = float(upper) + 7 lowedge = float(upper) - 21 - 4 while 1: try: if i >= 3: return None i = i + 1 self.fsv.set_for_txatt(ref_level, freq) time.sleep(1) plst = [] j = 0 # sweep time 1s,读5次取平均值 # 12.23 频谱仪读平均值5次 while j < 1: power = self.fsv.get_power(ref_level, freq) # 读取频谱仪功率,返回列表 self.logger.debug('get_fsv_power={}'.format(power[0])) if power is not None: # plst.append(power) # for test if float(power[0]) > lowedge: plst.append(power) else: self.logger.error( 'before reset_bd,power={}'.format(power[0])) self.reset_bd() # 可能设备重启了,导致输出-19以下 return None else: break j = j + 1 if plst: plst = [float(item[0]) for item in plst] self.logger.debug('power list={}'.format(plst)) return sum(plst) / len(plst) time.sleep(3) except Exception as e: self.logger.error(e) time.sleep(3) self.fsv.close_inst() self.conf_device(fsvip) time.sleep(3) continue def reset_bd(self): if not self.bd.do_set_bd(): raise RuntimeError('强建小区失败') def read_excel_txatt_norm(self, excel_path): ''' 读取excel的上下行功率,频点等参数 :param excel_path: :return: ''' try: if self.bdexl.open_excel(excel_path): normlist = self.bdexl.get_txatt_norm() # 读取输出功率标准 templist = self.bdexl.read_cpu_temp() # 读取一系列待测温度 centertemp = self.bdexl.read_cpu_center_temp() # 读取基准温度 return normlist, templist, centertemp except Exception as e: raise RuntimeError(e) finally: self.bdexl.close_file() def read_boardtype(self, excel_path): ''' 从excel中读取board类型及主从片频点,频率 :param excel_path: :return: ''' try: if self.bdexl.open_excel(excel_path): freqpoint_dict, freq_dict = self.bdexl.get_set_condition() return freqpoint_dict, freq_dict except Exception as e: raise RuntimeError('read_boardtype ERROR:{}'.format(e)) finally: self.bdexl.close_file() def read_offset(self, excel_path): try: if self.bdexl.open_excel(excel_path): self.bdexl.get_dl_rows() offset = self.bdexl.get_offset() return offset except Exception as e: raise RuntimeError('read_offset ERROR:{}'.format(e)) finally: self.bdexl.close_file() def conf_device(self, fsvip): ''' 仪器初始化 :return: ''' self.logger.debug('conf_fsv') # for test i = 0 while 1: i = i + 1 if i >= 3: self.logger.error('fsv error') raise RuntimeError('fsv error') try: self.fsv.init_inst(fsvip) time.sleep(1) self.fsv.reset_fsv() time.sleep(1) except Exception as e: self.logger.error(e) time.sleep(10) self.fsv.close_inst() else: break def set_flat_comp(self, fsvip, target, freqpoint_dict, freq_dict, productno, bip, excel_path): ''' 平坦度补偿 :return: ''' try: self.logger.debug('基准平坦度补偿') key_bands = freqpoint_dict.keys() self.conf_device(fsvip) for cellband in key_bands: self.logger.debug('cellband={}'.format(cellband)) if 'CELL0' in cellband.upper(): cellid = '0' self.bd.set_rf('1', 0) else: cellid = '1' self.bd.set_rf('0', 0) bandstr = cellband.split('_')[-1] band = re.sub('\D', '', bandstr) # band的数字,1/3/41/38/39 freq_points = freqpoint_dict[str(cellband)] freqs = freq_dict[str(cellband)] self.get_and_send_powercali(cellid, fsvip, band, freq_points, freqs, target) # 写平坦度补偿表 # 更新设备频补补偿表 self.update_bb_flat_comp(productno, bip, excel_path) except Exception as e: self.logger.error(e) raise RuntimeError(e) finally: self.fsv.close_inst() def set_temp_comp(self, fsvip, target, freqpoint_dict, freq_dict, tempidx, nexttempidx): ''' 温度补偿 :return:补偿值{'':[],'':[]} ''' i = 0 while 1: if i > 3: return False try: key_bands = freqpoint_dict.keys() self.conf_device(fsvip) for cellband in key_bands: self.logger.debug('cellband={}'.format(cellband)) if 'CELL0' in cellband.upper(): cellid = '0' self.bd.set_rf('1', 0) else: cellid = '1' self.bd.set_rf('0', 0) bandstr = cellband.split('_')[-1] band = re.sub('\D', '', bandstr) # band的数字,1/3/41/38/39 # bandinfo=self.process_gain.read_bandinfo(int(band)) freq_points = freqpoint_dict[str(cellband)] freqs = freq_dict[str(cellband)] for idx, point in enumerate(freq_points): freq = freqs[idx] self.conf_board_on_some_freq(cellid, point) # 设置基带板频点 # for test plst = self.get_fsv_power(fsvip, target, freq) if plst is None: raise IOError('read fsv power failed') power = plst self.logger.debug('fsv read power={}'.format(power)) value = float(power) - float(target) self.process_gain.set_bandinfo(tempidx, nexttempidx, band, point, float('%6.2f' % value)) return True except Exception as e: self.logger.error(e) i = i + 1 finally: self.fsv.close_inst() def set_cpu_temp(self, target, bias, direction): ''' 设定设备到达某温度 target:温度 bias:偏离目标温度多少度 :return: ''' # for test # logger.debug('wait for test...') # time.sleep(10) self.logger.debug('温度设定目标{}'.format(target)) self.rpt_message('温度设定目标{}'.format(target)) # time.sleep(3) # for test if not self.adjust_thread or not self.adjust_thread.is_alive(): self.adjust_thread = PropagatingThread(target=self.adjust_cpu_temp, args=(target, bias, direction)) self.adjust_evt.set() self.adjust_thread.setDaemon(True) self.adjust_thread.start() self.adjust_thread.join() def write_gain_comp_json(self, productno, bip, excel_path): ''' 写文件并ftp上传给T2K :return: ''' myftp = MyFTP(str(bip)) try: js = self.process_gain.get_json() dirname = os.path.dirname(excel_path) pno = productno remote_file = '/mnt/flash/scbs/{}_GainComp.json'.format(pno) local_file = os.path.join(dirname, 'GainComp.json') with open(local_file, 'wb') as f: f.write( json.dumps(js, indent=4, ensure_ascii=False).encode('utf-8')) if myftp.rpt_json(local_file, remote_file): return True except Exception as e: self.logger.error('write_gain_comp_json ERROR:{}'.format(e)) return False finally: myftp.close() def write_flat_comp_json(self, productno, bip, excel_path): ''' 将本地频补表上传给BB :param productno: :param bip: :param excel_path: :return: ''' myftp = MyFTP(str(bip)) try: js = self.process_flat.get_json() dirname = os.path.dirname(excel_path) pno = productno remote_file = '/mnt/flash/scbs/{}_FlatComp.json'.format(pno) local_file = os.path.join(dirname, 'FlatComp.json') with open(local_file, 'wb') as f: f.write( json.dumps(js, indent=4, ensure_ascii=False).encode('utf-8')) if myftp.rpt_json(local_file, remote_file): return True except Exception as e: self.logger.error('write_flat_comp_json ERROR:{}'.format(e)) return False finally: myftp.close() def check_cpu_temp(self): ''' 读取设备温度 :return: ''' a, b, c, d, e = [-100] * 5 i = 0 MAX = 90 while True: if i > MAX: break if self.wait_evt.is_set(): temp = self.bd.repeat_get_temp() # 获取基带板温度 self.logger.debug('current cpu temp={}'.format(temp)) self.rpt_message('current cpu temp={}'.format(temp)) if temp is None: i = i + 1 continue f = temp a, b, c, d, e = b, c, d, e, f if a == e or abs(a - e) <= 1: self.logger.debug('cpu hit {}'.format(e)) self.rpt_message('cpu hit {}'.format(e)) self.wait_evt.clear() # self.adjust_flag = True self.adjust_evt.set() else: time.sleep(50) else: self.logger.debug('wait evt') self.wait_evt.wait() i = 0 a, b, c, d, e = [-100] * 5 i = i + 1 def adjust_cpu_temp(self, target, bias, direction=1): ''' :param target: :param bias: :param direction: 1,表示目标温度为正,-1表示目标温度为负或0 :return: ''' x = 0.7 y = 0.4 z = 0.7 i = 0 period = 1 oldt = None if bias == 0: trg = [0, 0] else: if direction > 0: trg = [-2, 0] else: trg = [0, 2] while True: Tset = self.th_dev.get_temp_pv() / 10.0 # 温箱温度 self.logger.debug('th temp={}'.format(Tset)) self.logger.debug('last th setvalue={}'.format(oldt)) if oldt is not None and abs(Tset - oldt) >= 0.3: time.sleep(30) self.logger.debug('wait th-dev hit setvalue') continue if oldt is not None and self.adjust_evt.is_set(): self.wait_evt.set() self.adjust_evt.clear() self.logger.debug('wait adjust_evt') self.adjust_evt.wait() try: if self.adjust_evt.is_set(): Tact = self.bd.repeat_get_temp() # 获取基带板温度 self.logger.debug('cpu temp={}'.format(Tact)) self.rpt_message('cpu temp={}'.format(Tact)) if Tact is None: raise IOError('get temp failed') delta = float(target) - float(Tact) self.logger.debug('temp delta={}'.format(delta)) if trg[0] <= delta <= trg[1]: i += 1 time.sleep(30) elif abs(delta) >= 10: i = 0 T = Tset + delta * x oldt = T self.logger.debug('SET T={}'.format(T)) self.th_dev.set_temp_sv(int(T * 10)) time.sleep(60 * 10) elif abs(delta) >= 3: i = 0 T = Tset + delta * y oldt = T self.logger.debug('SET T={}'.format(T)) self.th_dev.set_temp_sv(int(T * 10)) time.sleep(60 * int(period)) else: i = 0 if delta > 0: T = Tset + z else: T = Tset - z oldt = T self.th_dev.set_temp_sv(int(T * 10)) time.sleep(30 * 1) # 1分钟 if i >= 1: self.logger.debug('hit target') break except Exception as e: self.logger.error(e) self.reset_bd()
def init_all(self, conf_dict): ''' df_need 中 低 高 B1 DL 2140.0 2112.5 2167.5 UL 1950.0 1922.5 1977.5 B3 DL 1842.5 1807.5 1877.5 UL 1747.5 1712.5 1782.5 :param conf_dict: :return: ''' try: fsv_conf = conf_dict.get('FSV', {}) # 频谱仪 fsv_ip = fsv_conf['IP'] fsv_offset = fsv_conf['OFFSET'] zvl_conf = conf_dict.get('ZVL', {}) # 矢网 zvl_ip = zvl_conf['IP'] zvl_offset = zvl_conf.get('OFFSET', 41) smbv_conf = conf_dict.get('SMBV', {}) # 信号源 smbv_ip = smbv_conf['IP'] amp_conf = conf_dict.get('POWER', {}) # 功放配置 th_conf = conf_dict.get('THDEVICE', {}) # 高低温箱配置 if th_conf: self.th_dev = THDevice() epath = amp_conf['DIR'] excel_path = self.make_dirs(epath) if excel_path is None: raise RuntimeError('excel does not exist!') self.exlpath = excel_path logger.debug(self.exlpath) self.rpt_message('INFO:excel_path={}'.format(self.exlpath)) zvl_state = amp_conf['ZVLSTATE'] # 是否需要矢网,需要矢网就不需要频谱,信号源 if zvl_state == '1': self.zvl = HandleZVL(zvl_ip, zvl_offset) else: self.fsv_smbv = HandleFSVAndSMBV(fsv_ip, smbv_ip, fsv_offset) bands = amp_conf['BAND'].strip().split(',') # 需要测的band列表 isdl = str(amp_conf['DL']) # 是否是测下行 '1'测下行,'0'测上行 read_ul = False if isdl == '1': # 测下行 self.bdexl.set_sheetnum(0) # excel的第一个sheet else: # 测上行 self.bdexl.set_sheetnum(1) # excel的第二个sheet read_ul = True df = self.read_excel_para(excel_path, read_ul) band_lst = [item.upper() for item in bands] df_need = df.loc[band_lst] params_lst = [band_lst, df_need, isdl] self.gd_test(*params_lst, **th_conf) return True, excel_path # loop = asyncio.get_event_loop() # loop.run_until_complete(self.gd_test(*params_lst, **th_conf)) # loop.close() # self.do_test(band_lst, df_need) except Exception as e: logger.error(e) self.rpt_message('ERROR:{}'.format(e)) return False finally: self.bdexl.close_file() self.zvl.close_zvl() self.fsv_smbv.close_all()
class DOTEST(object): def __init__(self, chl_name, chl_layer): self.fsv_smbv = None # 信号源和频谱仪 self.zvl = None # 矢网 self.th_dev = None # 高低温箱 self.bdexl = BoardExcel() # 读写excel self.exlpath = None self.th1_evt = threading.Event() self.th1_evt.clear() self.que = queue.Queue() self.channel_name = chl_name self.channel_layer = chl_layer # self.th1 = threading.Thread(target=self.output_data) # 输出结果到excel # self.th1.setDaemon(True) # self.th1.start() def rpt_message(self, msg): try: if self.channel_layer and self.channel_name: print('rpt_msg') async_to_sync(self.channel_layer.send)(self.channel_name, { "type": "send.message", "message": msg }) except Exception as e: print('rpt_msg error:{}'.format(e)) def init_all(self, conf_dict): ''' df_need 中 低 高 B1 DL 2140.0 2112.5 2167.5 UL 1950.0 1922.5 1977.5 B3 DL 1842.5 1807.5 1877.5 UL 1747.5 1712.5 1782.5 :param conf_dict: :return: ''' try: fsv_conf = conf_dict.get('FSV', {}) # 频谱仪 fsv_ip = fsv_conf['IP'] fsv_offset = fsv_conf['OFFSET'] zvl_conf = conf_dict.get('ZVL', {}) # 矢网 zvl_ip = zvl_conf['IP'] zvl_offset = zvl_conf.get('OFFSET', 41) smbv_conf = conf_dict.get('SMBV', {}) # 信号源 smbv_ip = smbv_conf['IP'] amp_conf = conf_dict.get('POWER', {}) # 功放配置 th_conf = conf_dict.get('THDEVICE', {}) # 高低温箱配置 if th_conf: self.th_dev = THDevice() epath = amp_conf['DIR'] excel_path = self.make_dirs(epath) if excel_path is None: raise RuntimeError('excel does not exist!') self.exlpath = excel_path logger.debug(self.exlpath) self.rpt_message('INFO:excel_path={}'.format(self.exlpath)) zvl_state = amp_conf['ZVLSTATE'] # 是否需要矢网,需要矢网就不需要频谱,信号源 if zvl_state == '1': self.zvl = HandleZVL(zvl_ip, zvl_offset) else: self.fsv_smbv = HandleFSVAndSMBV(fsv_ip, smbv_ip, fsv_offset) bands = amp_conf['BAND'].strip().split(',') # 需要测的band列表 isdl = str(amp_conf['DL']) # 是否是测下行 '1'测下行,'0'测上行 read_ul = False if isdl == '1': # 测下行 self.bdexl.set_sheetnum(0) # excel的第一个sheet else: # 测上行 self.bdexl.set_sheetnum(1) # excel的第二个sheet read_ul = True df = self.read_excel_para(excel_path, read_ul) band_lst = [item.upper() for item in bands] df_need = df.loc[band_lst] params_lst = [band_lst, df_need, isdl] self.gd_test(*params_lst, **th_conf) return True, excel_path # loop = asyncio.get_event_loop() # loop.run_until_complete(self.gd_test(*params_lst, **th_conf)) # loop.close() # self.do_test(band_lst, df_need) except Exception as e: logger.error(e) self.rpt_message('ERROR:{}'.format(e)) return False finally: self.bdexl.close_file() self.zvl.close_zvl() self.fsv_smbv.close_all() def read_excel_para(self, excel_path, read_ul): ''' 获取频率参数 :return: ''' logger.debug('read excel para') try: if self.bdexl.open_excel(excel_path): self.bdexl.get_dl_rows() if read_ul: self.bdexl.get_ul_rows() df = self.bdexl.get_band_para() if df is None: raise NotImplementedError('excel para empty') return df except Exception as e: logger.error('read excel para error:{}'.format(e)) finally: self.bdexl.close_file() def make_dirs(self, exlpath): ''' 根据excel测试模板复制一份excel :param exlpath: :return: ''' try: logger.debug(exlpath) if self.bdexl.open_excel(exlpath): arm_id, bb_id = self.bdexl.get_id() dirname = os.path.dirname(exlpath) if arm_id: new_path = os.path.join(os.path.join(dirname, str(arm_id)), str(bb_id)) else: new_path = dirname if not os.path.exists(new_path): os.makedirs(new_path) newexl_name = str(bb_id) + '.xlsx' end_path = os.path.join(new_path, newexl_name) if os.path.exists(end_path): return end_path else: copyfile(exlpath, end_path) return end_path else: return None except Exception as e: logger.error(e) finally: self.bdexl.close_file() def check_temp(self, target_temp): i = 0 j = 0 logger.debug('check temp {}'.format(target_temp)) while True: pv = self.th_dev.get_temp_pv() if not pv: time.sleep(60) j = j + 1 if j >= 3: raise StopIteration('dev not online**') continue if pv >= target_temp - 10 and pv <= target_temp + 10: # 上下1度 logger.info('i={},hit target {}'.format(i, target_temp)) if i >= 3: logger.info('高低温箱达到温度{}'.format(target_temp)) break i = i + 1 else: i = 0 time.sleep(30) def handle_test(self, target_temp, period): ''' 设置高低温温度 :param target_temp: period:以分钟为单位,到达温度后的持续时间 :return: ''' self.check_temp(target_temp) logger.info('到达温度后开始等待{}分钟'.format(period)) time.sleep(60 * int(period)) # 使用矢网测试 logger.info('start 功放测试....') def gd_test(self, *args, **kwargs): try: thconf = kwargs # if not thconf: # raise ModuleNotFoundError('高低温箱没有配置项') port = thconf.get('PORT', None) norm_temp = thconf.get('NORM_TEMP', None) low_temp = thconf.get('LOW_TEMP', None) high_temp = thconf.get('HIGH_TEMP', None) period = thconf.get('PERIOD', 20) # 平衡持续时间,以分钟为单位 if self.th_dev is None or not port: # 只进行常温测试 logger.info('只进行常温测试') self.do_test(1, *args) return if self.th_dev.connect_th(PORT='COM{}'.format(port)): logger.info('高低温箱connected**') self.th_dev.set_fixed_mode() if norm_temp is not None: logger.info('start 常温测试') self.th_dev.set_temp_sv(int(norm_temp) * 10) self.th_dev.start_dev() # 开始运行 if norm_temp is not None: self.handle_test(int(norm_temp) * 10, period) self.do_test(1, *args) logger.debug('******常温测试 finished****') if low_temp is not None: logger.info('start 低温测试') self.th_dev.set_temp_sv(int(low_temp) * 10) self.handle_test(int(low_temp) * 10, period) self.do_test(0, *args) logger.debug('******低温测试 finished****') if high_temp is not None: logger.info('start 高温测试') self.th_dev.set_temp_sv(int(high_temp) * 10) self.handle_test(int(high_temp) * 10, period) self.do_test(2, *args) logger.debug('******高温测试 finished****') logger.debug('高低温箱停止运行') self.th_dev.stop_dev() # 停止运行 except modbus_tk.modbus.ModbusError as e: logger.exception('{}'.format(e)) raise StopIteration('th_dev') def do_test(self, temp=1, *args): ''' :param lband: ['B1','B3'] :param df: 中 低 高 B1 DL 2140.0 2112.5 2167.5 UL 1950.0 1922.5 1977.5 B3 DL 1842.5 1807.5 1877.5 UL 1747.5 1712.5 1782.5 :return: ''' lband, df, isdl = args # logger.debug('args={}'.format(args)) dl_ul = 'DL' if isdl == '1' else 'UL' # 是测上行还是下行 self.test_zvl(temp, lband, df, dl_ul) self.test_fsv_and_smbv(temp, lband, df, dl_ul) if self.fsv_smbv: self.fsv_smbv.close_rf() logger.debug('test finished') self.rpt_message('INFO:test finished') def test_zvl(self, temp, lbd, df, dl_ul): ''' 上行基于矢网测试 上行的增益,带内波动,带外抑制,vswr, 下行基于矢网的测试:vswr,带外抑制 :return: ''' if self.zvl is None: return flag = True if dl_ul == 'DL': flag = False logger.debug('test_zvl_ul') # self.que.put('0') #类型,写excel的类型 self.zvl.init_zvl(self.exlpath) gain_dict = dict(zip(lbd, [[]] * len(lbd))) # {'E':[高增益,中增益,低增益,带内波动],'F':[]} vswr_dict = dict(zip(lbd, [[]] * len(lbd))) # {'E':[x,y],'F':[x,y]} gain_freq_dict = dict(zip(lbd, [[]] * len(lbd))) # {'E':[,,,,,],'F':[,,,,,]} for band in lbd: freqlst = df.loc[band, dl_ul].loc[['高', '中', '低']].values logger.debug(freqlst) self.rpt_message('INFO:{}'.format(freqlst)) if flag: # 只有上行才用矢网测增益和带内波动 ret_gain = self.zvl.get_gain(*freqlst) # list gain_dict[band] = ret_gain vswr_ret = self.zvl.get_vswr(*freqlst, dl_ul, temp) # list vswr_dict[band] = vswr_ret markerlist = self.get_marker1(band) freq_ret = self.zvl.get_gain_vs_freq(markerlist, dl_ul, temp) # list gain_freq_dict[band] = freq_ret self.que.put([temp, '0', [gain_dict, vswr_dict, gain_freq_dict]]) time.sleep(.5) self.th1_evt.set() self.output_data() def get_marker1(self, band): ''' 读取excel的带外抑制点 :return:list ''' excel_path = copy.deepcopy(self.exlpath) try: if self.bdexl.open_excel(excel_path): return self.bdexl.get_gain_vs_freq_list(band) return None except Exception as e: logger.error('get_marker error {}'.format(e)) return None finally: self.bdexl.close_file() def test_fsv_and_smbv(self, temp, lband, df, dl_ul): ''' 测试下行的增益,带内波动,EVM :param temp: :param lband: :param df: :param dl_ul: :return: ''' if dl_ul == 'UL': return if self.fsv_smbv is None: return logger.debug('test_fsv_and_smbv') self.fsv_smbv.init_all() current_dict = dict(zip(lband, [[]] * len(lband))) # {'E':[(信号源输入,频谱仪输出,ACPR),(,,)]} evm_dict = dict( zip(lband, [[]] * len(lband))) # {'E':[(功放+信号源的evm,信号源的evm,功放的evm),()]} gain_dict = dict(zip( lband, [[]] * len(lband))) # {'E':[(信号源输入,频谱输出,增益),(),()],'F':[,,,,,]} ripple_dict = dict(zip(lband, [None] * len(lband))) # {'E':None,'F':None} try: for band in lband: logger.debug('测试band{}'.format(band)) self.rpt_message('INFO:测试band{}'.format(band)) freqlst = df.loc[band, dl_ul].loc[['高', '中', '低']].values target_power_for_gain = None target_power_for_evm = None evm_alone_lst = None # 信号源evm[高,中,低] markerlist = None if self.bdexl.open_excel(self.exlpath): target_power_for_gain = self.bdexl.get_target_power( band) # dBm target_power_for_evm = self.bdexl.get_target_power_for_evm( band) # dBm logger.debug( 'target_power_for_evm={}'.format(target_power_for_evm)) self.rpt_message('INFO:target_power_for_evm={}'.format( target_power_for_evm)) evm_alone_lst = self.bdexl.get_evm(temp, band) markerlist = self.bdexl.get_gain_dl_marker( band) # 增益的marker点 self.bdexl.close_file() if target_power_for_gain is None: raise NotImplementedError('no target power') if target_power_for_evm is None: raise NotImplementedError('no target power') # 增益,带内波动 if markerlist: gainlist = [] alllist = [] for marker in markerlist: level, power, gain = self.fsv_smbv.get_max_single_tone( marker, target_power_for_gain) gainlist.append(float(gain)) alllist.append((level, power, gain)) ripple = max(gainlist) - min(gainlist) # 带内波动 ripple_dict[band] = ripple gain_dict[band] = alllist for idx, freq in enumerate(freqlst): power_list = self.fsv_smbv.get_max_power( freq, target_power_for_evm) current_dict.setdefault(band, []).append(power_list) evm = self.fsv_smbv.get_evm(freq) evm_list = [None] * 3 if evm_alone_lst != [None] * 3 and evm: evm_of_amp = '%.2f' % (math.sqrt( pow(float(evm), 2) - pow(float(evm_alone_lst[idx]), 2))) evm_list = [evm, evm_alone_lst[idx], evm_of_amp] evm_dict.setdefault(band, []).append(evm_list) self.que.put( [temp, '1', [gain_dict, ripple_dict, current_dict, evm_dict]]) time.sleep(.3) self.th1_evt.set() self.output_data() except Exception as e: logger.error('test_fsv_and_smbv error {}'.format(e)) self.rpt_message('ERROR:test_fsv_and_smbv error {}'.format(e)) finally: self.bdexl.close_file() self.fsv_smbv.close_all() def output_data(self): ''' 输出数据到excel :return: ''' try: if self.th1_evt.is_set(): outlst = self.que.get() if len(outlst) < 3: logger.error('output error') temp, pattern, valst = outlst if pattern == '0': self.write_zvl_result(valst, temp) elif pattern == '1': self.write_fsv_result(valst, temp) self.th1_evt.clear() except Exception as e: logger.error(e) def write_zvl_result(self, retlst, temp): ''' 记录矢网的测试结果,包括增益,带内波动,带外抑制 retlst:[] :return: ''' logger.debug('write_zvl_result') self.rpt_message('INFO:write_zvl_result') gain_dict, vswr_dict, gain_freq_dict = retlst excel_path = copy.deepcopy(self.exlpath) try: if self.bdexl.open_excel(excel_path): self.bdexl.write_gain(temp, **gain_dict) self.bdexl.write_vswr(temp, **vswr_dict) self.bdexl.write_gain_vs_freq(temp, **gain_freq_dict) except Exception as e: logger.error('write zvl result error {}'.format(e)) finally: self.bdexl.close_file() def write_fsv_result(self, retlist, temp): logger.debug('write_fsv_result') self.rpt_message('INFO:write_fsv_result') gain_dict, ripple_dict, current_dict, evm_dict = retlist excel_path = copy.deepcopy(self.exlpath) ct = dict() # {'E':[(信号源输入,频谱输出),(信号源输入,频谱输出),()]} acpr_dict = dict() # {'E':[高,中,低]} try: if self.bdexl.open_excel(excel_path): if current_dict is not None: for key, item in current_dict.items(): lst1 = [io[:2] for io in item] ct[key] = lst1 lst2 = [io[2] for io in item] acpr_dict[key] = lst2 self.bdexl.write_current(temp, **ct) self.bdexl.write_ACPR(temp, **acpr_dict) self.bdexl.write_EVM(temp, **evm_dict) self.bdexl.write_dl_gain(temp, **gain_dict) self.bdexl.write_ripple(temp, **ripple_dict) except Exception as e: logger.error('write_fsv_result error {}'.format(e)) finally: self.bdexl.close_file()