def cr_led_mode(self, on_off, cr=None, cr_volt=None): """ CR_LED功能 :param on_off: (type str) CR_LED功能开关, 当此值设置为OFF|0时, 后面的设置参数将忽略 :param cr: (type float) CR_LED功能恒阻阻值, 默认单位为Ω, 最小值为1mΩ :param cr_volt: (type float) CR_LED功能关断电压, 默认单位为V, 最小值为1mV :return: CR_LED功能恒阻阻值, CR_LED功能关断电压 """ if on_off in TUPLE_ON: mode, value = self.load_mode(CR, cr) self.write([It8500PlusCmd.CR_LED_FUNC_SET, 1]) self.write(_value_command([It8500PlusCmd.CR_LED_CUTOFF_VOLT_SET, ], cr_volt, magnif=1000)) data = self.query([It8500PlusCmd.CR_LED_FUNC_GET, ]) assert data[3] == 1 data = self.query([It8500PlusCmd.CR_LED_CUTOFF_VOLT_GET, ]) volt = utils.hex_to_value(data[3:7], magnif=1000) return value, volt elif on_off in TUPLE_OFF: self.write([It8500PlusCmd.CR_LED_FUNC_SET, 0]) data = self.query([It8500PlusCmd.CR_LED_FUNC_GET, ]) assert data[3] == 0 else: self._logger.error('Error remote parameter, value is %s' % on_off) raise ParamException( 'The param "on_off" expect value "ON", "OFF", "0" or "1" not: %s' % on_off)
def curr_protection(self, enable=True, curr=None, curr_del=None): """ 过电流保护设置或查询 :param enable: 过电流保护使能 :param curr: 过电流保护设置值 :param curr_del: 过电流保护延时设置值 :return: 过电流保护使能, 过电流保护设置值, 过电流保护延时设置值 """ if enable is False: self.write([It8500PlusCmd.PC_ENABLE_SET, 0]) elif enable is True: self.write([It8500PlusCmd.PC_ENABLE_SET, 1]) self.write(_value_command([It8500PlusCmd.P_CURR_SET, ], curr, magnif=10000)) self.write(_value_command([It8500PlusCmd.PC_DELAY_SET, ], curr_del, magnif=1000)) else: self._logger.warn('Invalid parameter %s', enable) raise ParamException( 'The param "enable" expect value True or False not: %s' % enable) data = self.query([It8500PlusCmd.PC_ENABLE_GET, ]) return_enable = data[3] data = self.query([It8500PlusCmd.P_CURR_GET, ]) return_curr = utils.hex_to_value(data[3:7], magnif=10000) data = self.query([It8500PlusCmd.PC_DELAY_GET, ]) return_curr_del = utils.hex_to_value(data[3:7], magnif=1000) return return_enable, return_curr, return_curr_del
def __check_endian(data, endian): if endian == BIG_ENDIAN: data.reverse() elif endian == LITTLE_ENDIAN: pass else: raise ParamException('The endian expect value "%s" or "%s" not "%s"' % (BIG_ENDIAN, LITTLE_ENDIAN, endian))
def call(self, s): def ma(): print('a') def mb(): print('b') switch = {'a': ma, 'b': mb} return switch.get(s, lambda: utils.raiser(ParamException()))
def load_mode(self, mode: str, value: float = None, lower: float = None, upper: float = None) -> tuple: """ 设置获取负载的负载模式 :param mode: (type str): 工作模式, 可选值 {CC|CV|CW|CR} :param value: (type float) 对应模式的设置值 :param lower: (type float) 对应模式的相应上下限限制: 定电流时电压上下限; 定电压时电流上下限; 定功率时电压上下限; 定电阻时电压上下限; :param upper: (type float) 参考 lower :return ('CC', 'CV', 'CW' or 'CR'), value, lower, upper """ return_mode = self._load_mode(mode) # 设置相关参数 self.write(_value_command(It85xxCmd.CC_VALUE_SET if CC == mode else It85xxCmd.CV_VALUE_SET if CV == mode else It85xxCmd.CR_VALUE_SET if CR == mode else It85xxCmd.CW_VALUE_SET if CW == mode else utils.raiser(ParamException('Unsupported load mode')), value=value, endian='little', size=4, magnif=10000 if CC == mode else 1000)) data = self.query(It85xxCmd.CC_VALUE_GET if CC == mode else It85xxCmd.CV_VALUE_GET if CV == mode else It85xxCmd.CR_VALUE_GET if CR == mode else It85xxCmd.CW_VALUE_GET if CW == mode else utils.raiser(ParamException('Unsupported load mode'))) return_value = utils.hex_to_value(data=data[3:7], endian='little', magnif=10000 if CC == mode else 1000) return_lower, return_upper = (None, None) if lower is not None: self.write(_value_command(It8500PlusCmd.DICT_CM_LOWER_SET_SET.get(mode), upper, magnif=10000 if CC == mode else 1000)) data = self.query(It8500PlusCmd.DICT_CM_LOWER_GET.get(mode)) return_lower = utils.hex_to_value(data=data[3:7], endian='little', magnif=10000 if CC == mode else 1000) if upper is not None: self.write(_value_command(It8500PlusCmd.DICT_CM_UPPER_SET_SET.get(mode), upper, magnif=10000 if CC == mode else 1000)) data = self.query(It8500PlusCmd.DICT_CM_UPPER_GET.get(mode)) return_upper = utils.hex_to_value(data=data[3:7], endian='little', magnif=10000 if CC == mode else 1000) return return_mode, return_value, return_lower, return_upper
def remote(self, on_off) -> None: if on_off in TUPLE_ON: self.write([It85xxCmd.LOCAL_REMOTE_SET, 1]) self.write([It85xxCmd.LOCAL_EN_SET, 1]) elif on_off in TUPLE_OFF: self.write([It85xxCmd.LOCAL_REMOTE_SET, 0]) self.write([It85xxCmd.LOCAL_REMOTE_SET, 0]) else: self._logger.error('Error remote parameter, value is %s' % on_off) raise ParamException( 'The param "on_off" expect value "ON", "OFF", "0" or "1" not: %s' % on_off)
def zero_threshold(self, on_off): """ 设置零值门限开关 :param on_off: (type str): 可选值为 {ON|1|OFF|0} :return: 如果指令执行成功返回True,否则返回False """ if on_off in TUPLE_ON: param = (0x00, ) elif on_off in TUPLE_OFF: param = (0x01, ) else: raise ParamException('not support parameter: %s' % on_off) resp = self.query(self.__cmd(An8721pCmd.ZERO_THRESHOLD, param)) return An8721pCmd.SUCCESS == self.__parse_resp(resp, 1)
def remote(self, on_off): """ Override(远程操作开关) :param on_off: (type str) 可选值 {ON|1|OFF|0} :return: 如果指令执行成功返回True,否则返回False """ if on_off in TUPLE_ON: param = (0x01, ) elif on_off in TUPLE_OFF: param = (0x00, ) else: raise ParamException('not support parameter %s' % on_off) resp = self.query(self.__cmd(An8721pCmd.KEY_LOCK, param)) return An8721pCmd.SUCCESS == self.__parse_resp(resp, 1)
def warning_buzzer(self, on_off): """ 设置报警蜂鸣器开关 :param on_off: 可选值为 {ON|1|OFF|0} :return: 如果指令执行成功返回True,否则返回False """ if on_off in TUPLE_ON: param = (0x00, ) elif on_off in TUPLE_OFF: param = (0x01, ) else: raise ParamException('not support parameter: %s' % on_off) resp = self.query(self.__cmd(An8721pCmd.WARNING_BUZZER, param)) return An8721pCmd.SUCCESS == self.__parse_resp(resp, 1)
def short(self, on_off: str = None) -> bool: """ 负载短路开启关断 :param on_off: (type str): 可选值为 {ON|1|OFF|0} :return: True or false """ if on_off in TUPLE_ON: res = self._work_mode(SHORT) elif on_off in TUPLE_OFF: res = self._work_mode(FIXED) else: self._logger.error('Error remote parameter, value is %s' % on_off) raise ParamException( 'The param "on_off" expect value "ON", "OFF", "0" or "1" not: %s' % on_off) return SHORT == res
def auto_test_mode(self, is_load=False, nrf=1, stop_cond=COMPLETE, *steps): """ 自动测试, 注意避免如下情况: 自动测试文件最后一步短路; 自动测试文件最后一步测试时输入电压小于设置之开始电压. :param is_load: (type bool)是否为加载文件, 如果为True, 则表示加载自动测试文件并直接进入自动测试, 否则为设置自动测试的步骤 :param nrf: (type int)加载或保存的文件编号, 范围 1~10 :param stop_cond: (type str) 停止条件, 可选值{complete|failure}, 分别表示测试完成时停止和测试失败时停止 :param steps: (type list or tuple of dict)自动测试的步数, 最多支持10步, 每一步为一个dict, 其中字典说明如下: is_pause: (type bool)当前步是否暂停 is_short: (type bool)当前步是否短路 load_time: (type float)带载时间, 单位S test_time: (type float)测试时间, 单位S unload_time: (type float)卸载时间, 单位S :return: 当前自动测试的步数 """ if is_load is True: self.write([It8500PlusCmd.AUTO_TEST_CALL, nrf]) elif is_load is False: step_count = 1 for step in steps: # 1. 设置步 self.write(_value_command([It8500PlusCmd.AUTO_TEST_STEP_SET, ], step_count, magnif=1)) is_pause = step.get('stop', False) if is_pause is True: self.write(_value_command([It8500PlusCmd.AUTO_TEST_PAUSE_STEP_SET, ], step_count, magnif=1)) is_short = step.get('short', False) if is_short is True: self.write(_value_command([It8500PlusCmd.AUTO_TEST_SHORT_STEP_SET, ], step_count, magnif=1)) load_time = step.get('load_time', None) self.write(_value_command([It8500PlusCmd.AUTO_TEST_LOAD_TIME_SET, ], load_time, magnif=1000)) test_time = step.get('test_time', None) self.write(_value_command([It8500PlusCmd.AUTO_TEST_TEST_TIME_SET, ], test_time, magnif=1000)) unload_time = step.get('unload_time', None) self.write(_value_command([It8500PlusCmd.AUTO_TEST_UNLOAD_TIME_SET, ], unload_time, magnif=1000)) link = step.get('link', 0) self.write([It8500PlusCmd.AUTO_TEST_LINK_SET, link, ]) step_count += 1 self.write([It8500PlusCmd.AUTO_TEST_STOP_SET, TUPLE_STOP_COND.index(stop_cond), ]) self.write([It8500PlusCmd.AUTO_TEST_SAVE, ]) return step_count - 1 else: self._logger.warn('Invalid parameter %s', is_load) raise ParamException( 'The param "is_load" expect value True or False not: %s' % is_load)
def _tran_mode(self, is_new, eload_mode, level_a, time_a, level_b, time_b, tran) -> tuple: """ TRAN模式操作, 注意: 当设置负载模式为CC时, 记得调用curr_slew()设置电流上升下降斜率 设置完成之后, 记得调用load()开启负载 :param is_new: 是否为新指令, 针对于IT8500和IT8500+电流a, b值的时间设置最小值分别为0.1ms和0.01ms :param eload_mode: (type srt): 电子负载工作模式, 可选值为{CC|CV|CW|CR}, 分别对应恒流, 恒压, 恒功率, 恒阻 :param level_a: (type float): A值 :param time_a: (type float): A值持续时间, 单位为S, 当tran为toggle时, 此值无效 :param level_b: (type float): B值 :param time_b: (type float): B值持续时间, 单位为S, 当tran为toggle时, 此值无效 :param tran: (type str): TRAN模式, 可选值为{continuous|pulse|toggle} 注意: eload_mode为CV或CW 时, tran只能为toggle eload_mode为CR 时, tran只能为pulse或toggle :return: (type tuple) 当前设置的level_A, time_A, level_B, time_B, 当前动态模式(0表示continuous, 1表示pulse, 2表示toggle) """ # 设置负载模式 self._load_mode(eload_mode) # 设置负载工作模式为transition self._work_mode(TRANSITION) # 设置transition参数 cmd = [] cmd.extend([ It8500PlusCmd.DYN_CURR_SET if is_new is True else It85xxCmd.DYN_CURR_SET if CC == eload_mode else It85xxCmd.DYN_VOLT_SET if CV == eload_mode else It85xxCmd.DYN_POWER_SET if CW == eload_mode else It85xxCmd.DYN_RES_SET if CR == eload_mode else utils.raiser(ParamException('Unsupported load mode')), ]) cmd.extend(utils.value_to_hex(value=level_a, endian='little', size=4, magnif=10000 if CC == eload_mode else 1000)) cmd.extend(utils.value_to_hex(value=time_a, endian='little', size=4, magnif=100000 if is_new is True else 10000)) cmd.extend(utils.value_to_hex(value=level_b, endian='little', size=4, magnif=10000 if CC == eload_mode else 1000)) cmd.extend(utils.value_to_hex(value=time_b, endian='little', size=4, magnif=100000 if is_new is True else 10000)) cmd.extend( [0, ] if CONTINUOUS == tran else [1, ] if PULSE == tran else [2, ] if TOGGLE == tran else utils.raiser(ParamException('Unsupported transition mode')) ) self.write(cmd) # 读取相关参数 data = self.query([ It8500PlusCmd.DYN_CURR_GET if is_new is True else It85xxCmd.DYN_CURR_GET if CC == eload_mode else It85xxCmd.DYN_VOLT_GET if CV == eload_mode else It85xxCmd.DYN_POWER_GET if CW == eload_mode else It85xxCmd.DYN_RES_GET if CR == eload_mode else utils.raiser(ParamException('Unsupported load mode')), ]) return_level_a = utils.hex_to_value(data=data[3:7], endian='little', magnif=10000 if CC == eload_mode else 1000) return_a_time = utils.hex_to_value(data=data[7:11], endian='little', magnif=100000 if is_new is True else 10000) return_level_b = utils.hex_to_value(data=data[11:15], endian='little', magnif=10000 if CC == eload_mode else 1000) return_time_b = utils.hex_to_value(data=data[15:19], endian='little', magnif=100000 if is_new is True else 10000) return_tran = data[19:20][0] return return_level_a, return_a_time, return_level_b, return_time_b, TUPLE_TRAN_MODE[return_tran]
def normal_all_setting(self, volt_r, curr_r, calc_m, calc_p, volt_ratio, curr_ratio, curr_thr, e_time, buzzer=ON): """ 设置所有常规参数值(所有参数均应该设置合理值) :param volt_r: (type int): 电压量程, 范围0-4, 0: LOW 档,1: HI 档,2: 保留,3: 保留,4: 自动 :param curr_r: (type int): 电流量程, 范围0-4, 0: LOW 档,1: HI 档,2: 保留,3: 保留,4: 自动 :param calc_m: (type int): 计算模式, 范围0-2; 0: RMS,1: DC,2: MEAN :param calc_p: (type int): 计算周期, 范围 0-2,0: 0.25(S),1: 0.5(S),2: 1.0(S) :param volt_ratio: (type float): 电压变比, 范围0-1000 :param curr_ratio: (type float): 电流变比, 范围1-1000 :param curr_thr: (type float): 电能量累积电流门限, 范围1-22, 单位A :param e_time: (type float): 电能量计时时间, 范围0-35999940, 单位S :param buzzer: (type str): 蜂鸣器开关, 可选值为{ON|1|OFF|0}, 默认值为ON :return: 如果指令执行成功返回True,否则返回False """ param = [] param.extend( utils.value_to_hex(value=volt_r, endian=utils.BIG_ENDIAN, size=1, magnif=1)) param.extend( utils.value_to_hex(value=curr_r, endian=utils.BIG_ENDIAN, size=1, magnif=1)) param.extend( utils.value_to_hex(value=calc_m, endian=utils.BIG_ENDIAN, size=1, magnif=1)) param.extend( utils.value_to_hex(value=calc_p, endian=utils.BIG_ENDIAN, size=1, magnif=1)) param.extend( utils.value_to_hex(value=volt_ratio, endian=utils.BIG_ENDIAN, size=2, magnif=10)) param.extend( utils.value_to_hex(value=curr_ratio, endian=utils.BIG_ENDIAN, size=2, magnif=10)) param.extend( utils.value_to_hex(value=curr_thr, endian=utils.BIG_ENDIAN, size=2, magnif=1000)) param.extend( utils.value_to_hex(value=e_time, endian=utils.BIG_ENDIAN, size=4, magnif=1)) param.extend( utils.value_to_hex( value=1 if buzzer in TUPLE_ON else 0 if buzzer in TUPLE_OFF else utils.raiser( ParamException('Parameter buzzer expect {ON|1|OFF|0}')), endian=utils.BIG_ENDIAN, size=1, magnif=1)) resp = self.query(self.__cmd(An8721pCmd.PARAMETERS, param)) return An8721pCmd.SUCCESS == self.__parse_resp(resp, 1)