# coding=gb2312 import binascii import re import threading import time import serial import serial.tools.list_ports from LogRecord.log_recorder import GLOBAL_LOG def crc16(data): # 初始化crc为0xFFFF crc = 0xFFFF # 循环处理每个数据字节 for byte in data: # 将每个数据字节与crc进行异或操作 crc ^= byte # 对crc的每一位进行处理 for _ in range(8): # 如果最低位为1,则右移一位并执行异或0xA001操作(即0x8005按位颠倒后的结果) if crc & 0x0001: crc = (crc >> 1) ^ 0xA001 # 如果最低位为0,则仅将crc右移一位 else: crc = crc >> 1 # 返回最终的crc值 return crc.to_bytes(2, byteorder='little', signed=False) # 检测uwb模块方法 def detect_uwb(ser): cmd = 'EB01FF4024' tx_str = bytes(bytearray.fromhex(cmd)) ser.write(tx_str) time.sleep(0.5) hex_str = binascii.b2a_hex(ser.read_all()).decode().upper().strip() if cmd in hex_str: return True else: return False # 标签状态 MODE_NORMAL = b"\xab" MODE_ALARM = b"\xee" # 标签警报状态 MODE_UNWEAR = 0 MODE_WEAR = 1 MODE_ILLEGAL = 2 ANCHOR_ID = "anchor_id" TAG_ID = "tag_id" BATTERY = "battery" STATUS = "status" DISTANCE = "distance" DYNAMIC_FREQ = "dynamic_freq" INACTIVE_FREQ = "inactive_freq" ALARM_FREQ = "alarm_freq" HR = "hr" BO = "bo" DETECT = "detect" HR_ALARM_VALUE_MAX = "hr_alarm_value_max" BO_ALARM_VALUE_MIN = "bo_alarm_value_min" HR_OPT_VALUE_MAX = "hr_opt_value_max" HR_OPT_VALUE_MIN = "hr_opt_value_min" BO_OPT_VALUE_MAX = "bo_opt_value_max" BO_OPT_VALUE_MIN = "bo_opt_value_min" ILLEGAL_ALARM_TIMES = "illegal_alarm_times" RECORD = "record_time" IS_SUCCESSFUL = "is_successful" FIRST_RSSI = "first_rssi" TOTAL_RSSI = "total_rssi" def data_decode_func_1_5(data): anchor_id_reverse = data[0: 8] tag_id_reverse = data[8: 14] tag_battery = data[14] tag_status = data[15:16] tag_is_successful = data[17] tag_distance = data[18:20] tag_first_rssi = data[20:22] tag_total_rssi = data[22:24] tag_dynamic_freq = data[25:27] tag_inactive_freq = data[27:29] tag_alarm_freq = data[29:21] tag_hr = data[34] tag_bo = data[35] tag_detect = data[38] hr_alarm_value_max = data[39] bo_alarm_value_min = data[40] hr_opt_value_max = data[41] hr_opt_value_min = data[42] bo_opt_value_max = data[43] bo_opt_value_min = data[44] illegal_alarm_times = data[45] # 数据解析 anchor_id = anchor_id_reverse[::-1].hex() tag_id = tag_id_reverse[::-1].hex() return { ANCHOR_ID: anchor_id, TAG_ID: tag_id, BATTERY: tag_battery, STATUS: tag_status, DISTANCE: int.from_bytes(tag_distance, byteorder="big", signed=False), IS_SUCCESSFUL: tag_is_successful, FIRST_RSSI: int.from_bytes(tag_first_rssi, byteorder="big", signed=True), TOTAL_RSSI: int.from_bytes(tag_total_rssi, byteorder="big", signed=True), DYNAMIC_FREQ: int.from_bytes(tag_dynamic_freq, byteorder="big", signed=False), INACTIVE_FREQ: int.from_bytes(tag_inactive_freq, byteorder="big", signed=False), ALARM_FREQ: int.from_bytes(tag_alarm_freq, byteorder="big", signed=False), HR: tag_hr, BO: tag_bo, DETECT: tag_detect, HR_ALARM_VALUE_MAX: hr_alarm_value_max, BO_ALARM_VALUE_MIN: bo_alarm_value_min, HR_OPT_VALUE_MAX: hr_opt_value_max, HR_OPT_VALUE_MIN: hr_opt_value_min, BO_OPT_VALUE_MAX: bo_opt_value_max, BO_OPT_VALUE_MIN: bo_opt_value_min, ILLEGAL_ALARM_TIMES: illegal_alarm_times, RECORD: time.time() } def data_decode_func(data): # 源数据解析 anchor_id_reverse = data[0: 8] tag_id_reverse = data[8: 14] tag_battery = data[14] tag_status = data[15:16] tag_distance = data[17:19] tag_dynamic_freq = data[24:26] tag_inactive_freq = data[26:28] tag_alarm_freq = data[28:30] tag_hr = data[33] tag_bo = data[34] tag_detect = data[37] hr_alarm_value_max = data[38] bo_alarm_value_min = data[39] hr_opt_value_max = data[40] hr_opt_value_min = data[41] bo_opt_value_max = data[42] bo_opt_value_min = data[43] illegal_alarm_times = data[44] # 数据解析 anchor_id = anchor_id_reverse[::-1].hex() tag_id = tag_id_reverse[::-1].hex() return { ANCHOR_ID: anchor_id, TAG_ID: tag_id, BATTERY: tag_battery, STATUS: tag_status, DISTANCE: int.from_bytes(tag_distance, byteorder="big", signed=False), DYNAMIC_FREQ: int.from_bytes(tag_dynamic_freq, byteorder="big", signed=False), INACTIVE_FREQ: int.from_bytes(tag_inactive_freq, byteorder="big", signed=False), ALARM_FREQ: int.from_bytes(tag_alarm_freq, byteorder="big", signed=False), HR: tag_hr, BO: tag_bo, DETECT: tag_detect, HR_ALARM_VALUE_MAX: hr_alarm_value_max, BO_ALARM_VALUE_MIN: bo_alarm_value_min, HR_OPT_VALUE_MAX: hr_opt_value_max, HR_OPT_VALUE_MIN: hr_opt_value_min, BO_OPT_VALUE_MAX: bo_opt_value_max, BO_OPT_VALUE_MIN: bo_opt_value_min, ILLEGAL_ALARM_TIMES: illegal_alarm_times, RECORD: time.time() } # 基站状态 MODE_FREE = 0 MODE_POSITION = 1 MODE_TWR = 2 # 指令类型 TYPE_DATA = b'\xa0' TYPE_READ_STATUS = b'\xa3' TYPE_WRITE_STATUS = b'\xc3' TYPE_WRITE_CONFIG = b'\xc4' TYPE_REBOOT = b'\xd0' TYPE_TWR = b'\xc5' TYPE_TWR_RESULT = b'\xa1' TYPE_TEMP = b'\xa5' TYPE_TAG_CONFIG = b'\xc7' TYPE_ANCHOR_CONFIG = b'\xa2' TYPE_SET_ANCHOR_CONFIG = b'\xc2' class MySerial(serial.Serial): def write(self, data): # TODO:调试 # GLOBAL_LOG.write("write:" + data.hex()) return super().write(data) def read(self, size=1): # TODO:调试 data = super().read(size) # GLOBAL_LOG.write("read:" + data.hex()) return data class UwbController: device_list = [] def __init__(self, uwb_timeout=0.1) -> None: super().__init__() """************************************线程信号初始化************************************""" self.__running = threading.Event() self.__running.set() self.__data_signal = threading.Event() self.__data_signal.clear() self.__resume = threading.Event() self.__resume.set() self.__get_new_position_data = threading.Event() self.__get_new_position_data.clear() """************************************初始化设备驱动************************************""" self.anchor_id = None self.anchor_version = None # 串口设置 self.ser = None for port in list(serial.tools.list_ports.comports()): self.ser = MySerial(timeout=uwb_timeout, baudrate=115200) # 初始化串口模块 if str(port.device) in UwbController.device_list: continue if 'CP210' in str(port.description): self.ser.port = str(port.device) try: self.ser.open() # 打开串口 self.set_anchor_status_directly(MODE_FREE) time.sleep(0.5) # 尝试获取UWB模块的信息 if detect_uwb(self.ser): UwbController.device_list.append(str(port.device)) self.anchor_id, self.anchor_version = self.get_anchor_mes() print(f"自身基站ID为:{self.anchor_id},基站版本为:{self.anchor_version}。") break except Exception: if self.ser.isOpen(): self.ser.close() """************************************设备状态测试************************************""" self.is_start = True if self.anchor_id is None: self.is_start = False if not self.ser.isOpen(): self.is_start = False """************************************数据初始化************************************""" self.buffer = b"" self.data_cache = {} self.decode_func = { TYPE_DATA: data_decode_func_1_5 } # 状态检测 def is_initialed(self): return self.is_start """************************************线程控制模块************************************""" def start(self): threading.Thread(target=self._threading_data_recv, daemon=True).start() threading.Thread(target=self._threading_data_decode, daemon=True).start() def pause(self): self.__resume.clear() def resume(self): self.__resume.set() def stop(self): self.__resume.set() self.__data_signal.set() self.__running.clear() """************************************上层驱动方法************************************""" def get_cache(self, _type): if _type not in self.data_cache.keys(): return None else: try: if self.data_cache.get(_type): return self.data_cache[_type].pop(0) else: return None except KeyError: return None def clear_cache(self, _type): if _type in self.data_cache.keys(): if self.data_cache[_type]: self.data_cache[_type].clear() def clear_all(self): self.data_cache = {} self.buffer = b"" def _threading_data_recv(self): while self.__running.is_set(): self.__resume.wait() try: bytes_data = self.ser.read(128) # print(len(bytes_data)) if bytes_data: self.buffer += bytes_data self.__data_signal.set() except: time.sleep(0.001) def _threading_data_decode(self): while self.__running.is_set(): self.__resume.wait() try: self.__data_signal.wait() self.__data_signal.clear() while True: eb_cmd_re = re.search(b"\xeb[\x00-\xff]{3,}", self.buffer[0:256]) if eb_cmd_re: # 获取指令的头尾坐标 re_start = eb_cmd_re.start() re_end = eb_cmd_re.end() # 更新缓存 self.buffer = self.buffer[re_start::] # 获得指令的长度 eb_len = self.buffer[1] # 判断是否已经接受到足够长的指令+CRC校验码长度2 if eb_len + 2 <= len(self.buffer[2::]): # 提取数据 data = self.buffer[3: 3 + eb_len + 1] # 获取指令类型 eb_type = self.buffer[2:3] # crc校验 whole_data = self.buffer[0: eb_len + 2] crc = crc16(whole_data) crc_got = self.buffer[eb_len + 2: eb_len + 2 + 2] # 更新缓存 self.buffer = self.buffer[1 + eb_len::] if crc_got != crc: # print("uwb接受到错误数据包,已丢弃!") continue # 获得指定指令方法 if eb_type in self.decode_func.keys(): decode_data = self.decode_func[eb_type](data) else: decode_data = data # 保存信息 self.data_cache.setdefault(eb_type, []) self.data_cache[eb_type].append(decode_data) if eb_type == TYPE_DATA: self.__get_new_position_data.set() else: break except Exception as e: continue print(f"发生错误:{e.args}") # 获得基站的版本信息 def get_anchor_mes(self): cmd = 'EB01C00034' tx_str = bytes(bytearray.fromhex(cmd)) try: self.ser.write(tx_str) time.sleep(0.5) bytes_data = self.ser.read_all() info = re.search(rb"(?<=\xEB\x0E\xC0)[\x00-\xFF]{13}", bytes_data).group() anchor_id_rev = [info[i:i + 1].hex() for i in range(8)] anchor_id_rev.reverse() anchor_id = "".join(anchor_id_rev) anchor_version = "{}.{}.{}.{}".format(int(info[8]), int(info[9]), int(info[10]), int(info[11])) return anchor_id, anchor_version except Exception as e: print(f"发生错误:{e.args}") return # 读取基站状态 def get_anchor_status(self, timeout=1): cmd = 'EB01A3401D' tx_str = bytes(bytearray.fromhex(cmd)) try: self.clear_cache(TYPE_READ_STATUS) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_READ_STATUS) if bytes_data: info = re.search(rb"[\x00-\xFF]{3}", bytes_data).group() status = info[0] return status except Exception as e: print(f"发生错误:{e.args}") return # 直接设置基站状态 def set_anchor_status_directly(self, status): status_bytes = status.to_bytes(1, byteorder='little', signed=False) tx_str = b"\xEB\x02\xC3" + status_bytes crc = crc16(tx_str) tx_str += crc try: self.ser.write(tx_str) except Exception as e: print(f"发生错误:{e.args}") # 关机模式:关闭周边所有的手环 def close_all_tag(self, ): tx_str = b"\xEB\x02\xC3\x04\xC5\x33" try: self.ser.write(tx_str) except Exception as e: print(f"发生错误:{e.args}") # 关闭关机模式:停止关闭周边所有的手环 def stop_close_all_tag(self): tx_str = b"\xEB\x02\xC3\x00\xC4\xF0" try: self.ser.write(tx_str) except Exception as e: print(f"发生错误:{e.args}") # 设置基站状态 def set_anchor_status(self, status, timeout=1): status_bytes = status.to_bytes(1, byteorder='little', signed=False) tx_str = b"\xEB\x02\xC3" + status_bytes crc = crc16(tx_str) tx_str += crc try: self.clear_cache(TYPE_WRITE_STATUS) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_WRITE_STATUS) if bytes_data: info = re.search(status_bytes + crc, bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False # 设置基站顺序和编号 def set_anchor_config(self, anchor_seq: int, anchor_no: int, timeout=1): anchor_seq_bytes = anchor_seq.to_bytes(1, byteorder='little', signed=False) anchor_no_bytes = anchor_no.to_bytes(2, byteorder='big', signed=False) tx_str = b"\xEB\x04\xC4" + anchor_seq_bytes + anchor_no_bytes crc = crc16(tx_str) tx_str += crc try: self.clear_cache(TYPE_WRITE_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_WRITE_CONFIG) if bytes_data: info = re.search(anchor_seq_bytes + anchor_no_bytes + crc, bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False # 重启基站 def reboot(self, timeout=5): cmd = 'EB01D001F8' tx_str = bytes(bytearray.fromhex(cmd)) try: self.clear_cache(TYPE_REBOOT) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_REBOOT) if bytes_data: info = re.search(b"\x01\xF8", bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False def twr(self, target_anchor: str, timeout=10): anchor_reverse = bytes(bytearray.fromhex(target_anchor))[::-1] cmd = 'EB0AC501' tx_str = bytes(bytearray.fromhex(cmd)) tx_str += anchor_reverse crc = crc16(tx_str) tx_str += crc check_code = "010690" check_code = bytes(bytearray.fromhex(check_code)) try: self.clear_cache(TYPE_TWR) self.clear_cache(TYPE_TWR_RESULT) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TWR) if bytes_data: info = re.search(check_code, bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False # 获得基站间的TWR测距值 def get_twr_result(self, timeout=10): start_time = time.time() while time.time() - start_time < timeout: try: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TWR_RESULT) if bytes_data: distance = int.from_bytes(bytes_data[0:2], byteorder="big", signed=False) success_time = int.from_bytes(bytes_data[2:4], byteorder="big", signed=False) return { "distance": distance, "success_time": success_time } except Exception as e: print(f"发生错误:{e.args}") # 获得模块温度 def get_temp(self, timeout=1): cmd = 'EB01A5C01F' tx_str = bytes(bytearray.fromhex(cmd)) try: self.clear_cache(TYPE_TEMP) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TEMP) if bytes_data: info = bytes_data[0:2] temp = int.from_bytes(info, byteorder="big", signed=False) * 0.01 return temp except Exception as e: print(f"发生错误:{e.args}") return False # 获取测距数据 def get_data(self, timeout=0.1): self.__get_new_position_data.wait(timeout=timeout) data = self.get_cache(TYPE_DATA) if not data: self.__get_new_position_data.clear() return data # 清理标签 def clear_tag(self, tag_id, timeout=5): tag_id_reverse = bytes(bytearray.fromhex(tag_id))[::-1] cmd = 'EB19C7' tx_str = bytes(bytearray.fromhex(cmd)) tx_str += tag_id_reverse tx_str += b"\x01" config_enable = b"\x00" d_freq_bytes = b"\x00\x00" i_freq_bytes = b"\x00\x00" a_freq_bytes = b"\x00\x00" tx_str += config_enable + d_freq_bytes + i_freq_bytes + a_freq_bytes # 功率 power_enable = b'\x00' power_config = b'\x00' tx_str += power_enable + power_config # 状态检测 hr_alarm_value_max_bytes = b"\x00" bo_alarm_value_min_bytes = b"\x00" hr_opt_value_max_bytes = b"\x00" hr_opt_value_min_bytes = b"\x00" bo_opt_value_max_bytes = b"\x00" bo_opt_value_min_bytes = b"\x00" tx_str += hr_alarm_value_max_bytes + bo_alarm_value_min_bytes \ + hr_opt_value_max_bytes + hr_opt_value_min_bytes \ + bo_opt_value_max_bytes + bo_opt_value_min_bytes # 警报 alarm_enable = b"\x02" alarm_config = b"\x00" tx_str += alarm_enable + alarm_config tx_str += crc16(tx_str) try: self.clear_cache(TYPE_TAG_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TAG_CONFIG) if bytes_data: info = re.search(b"\x41\xF6", bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False # 关闭标签 def close_tag(self, tag_id, timeout=5): tag_id_reverse = bytes(bytearray.fromhex(tag_id))[::-1] cmd = 'EB19C7' tx_str = bytes(bytearray.fromhex(cmd)) tx_str += tag_id_reverse tx_str += b"\x01" config_enable = b"\x00" d_freq_bytes = b"\x00\x00" i_freq_bytes = b"\x00\x00" a_freq_bytes = b"\x00\x00" tx_str += config_enable + d_freq_bytes + i_freq_bytes + a_freq_bytes # 功率 power_enable = b'\x00' power_config = b'\x00' tx_str += power_enable + power_config # 状态检测 hr_alarm_value_max_bytes = b"\x00" bo_alarm_value_min_bytes = b"\x00" hr_opt_value_max_bytes = b"\x00" hr_opt_value_min_bytes = b"\x00" bo_opt_value_max_bytes = b"\x00" bo_opt_value_min_bytes = b"\x00" tx_str += hr_alarm_value_max_bytes + bo_alarm_value_min_bytes \ + hr_opt_value_max_bytes + hr_opt_value_min_bytes \ + bo_opt_value_max_bytes + bo_opt_value_min_bytes # 警报 alarm_enable = b"\x03" alarm_config = b"\x00" tx_str += alarm_enable + alarm_config tx_str += crc16(tx_str) try: self.clear_cache(TYPE_TAG_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TAG_CONFIG) if bytes_data: info = re.search(b"\x41\xF6", bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False # 快速配置标签 def set_tag(self, tag_id, freq=None, alarm_status=None, detection_config=None, timeout=1): tag_id_reverse = bytes(bytearray.fromhex(tag_id))[::-1] cmd = 'EB19C7' tx_str = bytes(bytearray.fromhex(cmd)) tx_str += tag_id_reverse tx_str += b"\x01" if freq or detection_config: config_enable = b"\x01" else: config_enable = b"\x00" if freq: dynamic_freq, inactive_freq, alarm_freq = freq d_freq_bytes = int(dynamic_freq).to_bytes(length=2, byteorder="big", signed=False) i_freq_bytes = int(inactive_freq).to_bytes(length=2, byteorder="big", signed=False) a_freq_bytes = int(alarm_freq).to_bytes(length=2, byteorder="big", signed=False) else: d_freq_bytes = b"\x00\x00" i_freq_bytes = b"\x00\x00" a_freq_bytes = b"\x00\x00" tx_str += config_enable + d_freq_bytes + i_freq_bytes + a_freq_bytes # 功率 power_enable = b'\x00' power_config = b'\x00' tx_str += power_enable + power_config # 状态检测 if detection_config: hr_alarm_value_max, bo_alarm_value_min, \ hr_opt_value_max, hr_opt_value_min, \ bo_opt_value_max, bo_opt_value_min = detection_config hr_alarm_value_max_bytes = int(hr_alarm_value_max).to_bytes(length=1, byteorder="big", signed=False) bo_alarm_value_min_bytes = int(bo_alarm_value_min).to_bytes(length=1, byteorder="big", signed=False) hr_opt_value_max_bytes = int(hr_opt_value_max).to_bytes(length=1, byteorder="big", signed=False) hr_opt_value_min_bytes = int(hr_opt_value_min).to_bytes(length=1, byteorder="big", signed=False) bo_opt_value_max_bytes = int(bo_opt_value_max).to_bytes(length=1, byteorder="big", signed=False) bo_opt_value_min_bytes = int(bo_opt_value_min).to_bytes(length=1, byteorder="big", signed=False) else: hr_alarm_value_max_bytes = b"\x00" bo_alarm_value_min_bytes = b"\x00" hr_opt_value_max_bytes = b"\x00" hr_opt_value_min_bytes = b"\x00" bo_opt_value_max_bytes = b"\x00" bo_opt_value_min_bytes = b"\x00" tx_str += hr_alarm_value_max_bytes + bo_alarm_value_min_bytes \ + hr_opt_value_max_bytes + hr_opt_value_min_bytes \ + bo_opt_value_max_bytes + bo_opt_value_min_bytes # 警报 if alarm_status is not None: alarm_enable = b"\x01" if alarm_status: alarm_config = b"\x01" else: alarm_config = b"\x02" else: alarm_enable = b"\x00" alarm_config = b"\x00" tx_str += alarm_enable + alarm_config tx_str += crc16(tx_str) try: self.clear_cache(TYPE_TAG_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_TAG_CONFIG) if bytes_data: info = re.search(b"\x41\xF6", bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False def get_anchor_config(self, timeout=3): cmd = 'EB02A20FAD64' tx_str = bytes(bytearray.fromhex(cmd)) try: self.clear_cache(TYPE_ANCHOR_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_ANCHOR_CONFIG) if bytes_data: info = re.search(rb"[\x00-\xFF]+", bytes_data).group() return info except Exception as e: print(f"发生错误:{e.args}") return def set_anchor_power(self, power: int, timeout=5): power = max(min(255, power), 0) config = self.get_anchor_config(timeout) if config: config_array = bytearray(config) config_array[2] = power config_array[19] = 0 config = bytes(config_array[:-2]) tx_str = b"\xeb\x20\xc2" + config tx_str += crc16(tx_str) try: self.clear_cache(TYPE_SET_ANCHOR_CONFIG) self.ser.write(tx_str) start_time = time.time() while time.time() - start_time < timeout: time.sleep(0.05) bytes_data = self.get_cache(TYPE_SET_ANCHOR_CONFIG) if bytes_data: info = re.search(b"\x81\xF5", bytes_data).group() if info: return True else: return False except Exception as e: print(f"发生错误:{e.args}") return False else: return False # def set_auto_power(self, timeout):