Exemple #1
0
 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()
Exemple #2
0
    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()
Exemple #3
0
    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
Exemple #4
0
    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()
Exemple #5
0
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()
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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()
Exemple #9
0
    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()
Exemple #10
0
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()