import functools def return_false_on_error(func): """装饰器:当函数执行出现异常时返回 False""" @functools.wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: print(f"Error in {func.__name__}: {e}") return False return wrapper class ConfigManager: def __init__(self, device_control): self.CONFIG_METADATA = {} self.CONFIG_METADATA_BY_ADDR = {} self.device_control = device_control # 初始化配置项 self._init_config_keys() def _set_key_float(self, _key, _addr, _tips="", _readonly=False, _precision=1): self.CONFIG_METADATA[_key] = { "addr": _addr, "tips": _tips, "readonly": _readonly, "type": "float", "precision": _precision, } if _addr in self.CONFIG_METADATA_BY_ADDR: print("{} 有重复".format(_addr)) raise Exception("地址重复") self.CONFIG_METADATA_BY_ADDR[_addr] = _key def _set_key_int(self, _key, _addr, _tips="", _readonly=False, _precision=0): self.CONFIG_METADATA[_key] = { "addr": _addr, "tips": _tips, "readonly": _readonly, "type": "int", "precision": _precision, } if _addr in self.CONFIG_METADATA_BY_ADDR: print("{} 有重复".format(_addr)) raise Exception("地址重复") self.CONFIG_METADATA_BY_ADDR[_addr] = _key def get_dynamic_value(self, data): cmd = [124] addr = data["addr"] cmd.extend([0xff & addr >> 8, 0xff & addr]) data = self.device_control.get_basic_info_mcu_without_async(data=cmd) if not data: return False return_data = self.analysis_data(data[1:]) if return_data: return str(return_data["value"]) return False # 地址、正负、类型(整数、浮点)、精度(0.01)、数据(6个字节)、是否只读 def set_dynamic_value(self, data): try: value = float(data["value"]) except: return False addr = data['addr'] print("config_data", value, addr) cmd = [125] cmd.extend(self.read_addr_value(value, addr)) print("config_data cmd", cmd) data = self.device_control.get_basic_info_mcu_without_async(data=cmd) if not data: return False return_data = self.analysis_data(data[1:]) if return_data: print("参数设置成功", return_data) return True return False def read_addr_value(self, value, addr): if addr not in self.CONFIG_METADATA_BY_ADDR: return [] try: buf = [] # 地址、正负、类型(整数、浮点)、精度(0.01)、数据(6个字节)、是否只读 __key_name = self.CONFIG_METADATA_BY_ADDR[addr] __meta = self.CONFIG_METADATA[__key_name] buf.extend([0xff & addr >> 8, 0xff & addr]) # 地址 _read_only = 1 if __meta["readonly"] else 0 # 是否只读 _dir = 1 if value >= 0 else 0 # 是否正负 _type = 1 if __meta["type"] == "int" else 0 # 是否整数 _precision = __meta["precision"] # 精度 abs_int_value = int(abs(value * 10 ** __meta["precision"])) buf.extend([0xff & abs_int_value >> 40, 0xff & abs_int_value >> 32, 0xff & abs_int_value >> 24, 0xff & abs_int_value >> 16, 0xff & abs_int_value >> 8, 0xff & abs_int_value]) buf.extend([_read_only, _dir, _type, _precision]) print("127----buf-{}:{}".format(addr, buf)) return buf except: return [] @return_false_on_error def analysis_data(self, _data): _addr = _data[0] << 8 | _data[1] if _addr not in self.CONFIG_METADATA_BY_ADDR: return False start = 2 _value = _data[start] << 40 | _data[start + 1] << 32 | _data[start + 2] << 24 | _data[start + 3] << 16 | \ _data[start + 4] << 8 | _data[start + 5] start = start + 5 _read_only = True if _data[start + 1] == 1 else False # 是否只读 _dir = 1 if _data[start + 2] == 1 else -1 _type = "int" if _data[start + 3] == 1 else "float" _precision = _data[start + 4] if _dir < 0: _value = _value * _dir if _type == "float": if _precision > 0: _round_x = _precision _precision = _precision * -1 _value = _value * 10 ** _precision _value = round(_value, _round_x) else: _value = int(_value) return_data = {"addr": _addr, "key_name": self.CONFIG_METADATA_BY_ADDR[_addr], "readonly": _read_only, "value": _value} return return_data def is_camera_has_focal(self): """ 是否有定焦器 """ data = {"addr": 208} is_camera_has_focal = self.get_dynamic_value(data) if is_camera_has_focal: return True return False def _init_config_keys(self): # test keys # self.test_key1 = 0.5 # self._set_key_float(_key="test_key1", _addr=1, _precision=2) # self.test_key2 = 1 # self._set_key_int(_key="test_key2", _addr=2, _tips="测试-2") # 升降机上次命令位置 self.camera_high_motor_target_value = 0 self._set_key_float( _key="camera_high_motor_target_value", _addr=3, _tips="升降机当前位置", _readonly=True, ) # 相机角度上次命令位置 self.camera_steering_target_value = 0 self._set_key_float( _key="camera_steering_target_value", _addr=4, _tips="相机角度上次命令位置", _readonly=True, ) # ---------------------50开始处理-------------------- # 升降机当前实时位置 self.camera_high_motor_current_value = 0 self._set_key_float( _key="camera_high_motor_current_value", _addr=51, _tips="升降机当前实时位置", _readonly=True, ) # 相机角度当前实时位置 self.camera_steering_current_value = 0 self._set_key_float( _key="camera_steering_current_value", _addr=52, _tips="相机角度当前实时位置", _readonly=True, ) # 转盘角度当前实时位置 self.turntable_steering_current_value = 0 self._set_key_float( _key="turntable_steering_current_value", _addr=53, _tips="转盘角度当前实时位置", _readonly=True, ) # 转盘前后当前实时位置 self.move_turntable_steering_current_value = 0 self._set_key_float( _key="move_turntable_steering_current_value", _addr=54, _tips="转盘前后当前实时位置", _readonly=True, ) # 翻板通讯是否正常 self.over_steering_is_online = 0 self._set_key_int( _key="over_steering_is_online", _addr=55, _tips="翻板是否在线", _readonly=True, ) # --------------------------基础设置--------------从ID 100开始 # 自动关机时间;单位秒 self.auto_power_off_diff_time = 7200 self._set_key_int( _key="auto_power_off_diff_time", _addr=101, _tips="自动关机时间单位秒" ) # 自动去使能;单位秒 MOTOR_TO_DISABLE self.auto_motor_disable_diff_time = 180 self._set_key_int( _key="auto_motor_disable_diff_time", _addr=102, _tips="自动去使能时间单位秒" ) # 220V继电器是否转换方向 self.relay_220v_is_change_dir = 0 self._set_key_int( _key="relay_220v_is_change_dir", _addr=103, _tips="220V继电器是否转换方向" ) # 伺服急停继电器是否转换方向 self.relay_motor_stop_is_change_dir = 0 self._set_key_int( _key="relay_motor_stop_is_change_dir", _addr=104, _tips="伺服急停继电器是否转换方向", ) # 刹车继电器是否转换方向 self.relay_brake_is_change_dir = 0 self._set_key_int( _key="relay_brake_is_change_dir", _addr=105, _tips="刹车继电器是否转换方向" ) # 增加升降的限位高度,单位mm self.camera_high_motor_max_height = 387 self._set_key_int( _key="camera_high_motor_max_height", _addr=106, _tips="升降的限位高度" ) # 是否检查设备是否在线 self.is_check_motor_online = 1 self._set_key_int( _key="is_check_motor_online", _addr=107, _tips="是否检查设备是否在线" ) # 是否检查设备是否堵转 self.is_check_motor_blocked = 1 self._set_key_int( _key="is_check_motor_blocked", _addr=108, _tips="是否检查设备是否堵转" ) # 是否完成设备自动参数设定 self.has_been_set_motor_config = 0 self._set_key_int( _key="has_been_set_motor_config", _addr=109, _tips="是否完成设备自动参数设定", ) # 校准角度方向 self.angle_diff_dir = 0 self._set_key_int(_key="angle_diff_dir", _addr=110, _tips="校准角度方向") # LED的默认亮度 self.led_default_brightness = 60 self._set_key_int( _key="led_default_brightness", _addr=111, _tips="LED的默认亮度" ) # 是否自动关闭使能 self.is_auto_motor_to_disable = 1 self._set_key_int( _key="is_auto_motor_to_disable", _addr=112, _tips="是否自动关闭使能" ) # 转盘转速比 self.turntable_steering_angle_ratio = 35.6 self._set_key_float( _key="turntable_steering_angle_ratio", _addr=113, _tips="转盘转速比" ) # LED灯的数量 self.led_count = 20 self._set_key_int(_key="led_count", _addr=114, _tips="LED灯的数量") # 转盘前后移动设备的初始化模式 1表示碰撞 0表示限位 self.turntable_move_to_init_mode = 0 self._set_key_int( _key="turntable_move_to_init_mode", _addr=115, _tips="转盘前后移动设备的初始化模式 1表示碰撞 0表示限位", ) # 是否测试 self.is_test = 0 self._set_key_int(_key="is_test", _addr=116, _tips="is_test") # 电机停止速度检测 self.low_speed = 300 self._set_key_int(_key="low_speed", _addr=117, _tips="电机停止速度检测") # 自动发送基础信息 self.is_auto_send_base_info = 0 self._set_key_int( _key="is_auto_send_base_info", _addr=118, _tips="自动发送基础信息" ) # 失去使能升降自动归零 self.disable_camera_high_to_zero = 0 self._set_key_int( _key="disable_camera_high_to_zero", _addr=119, _tips="失去使能升降自动归零" ) # 前后移动电机初始化后距离 self.front_rear_motor_init_distance = 0 self._set_key_int( _key="front_rear_motor_init_distance", _addr=120, _tips="前后移动电机初始化后距离", ) # 每秒自动检查电机是否停止 self.auto_check_motor_stop = 0 self._set_key_int( _key="auto_check_motor_stop", _addr=121, _tips="每秒自动检查电机是否停止" ) # 前后移动电机是否存在 self.turntable_move_is_exist = 1 self._set_key_int( _key="turntable_move_is_exist", _addr=122, _tips="前后移动电机是否存在" ) # 升降电机的到位偏差 self.camera_high_motor_arrived_deviation = 100 self._set_key_int( _key="camera_high_motor_arrived_deviation", _addr=123, _tips="升降电机的到位偏差" ) # 相机角度电机的到位偏差 self.camera_steering_arrived_deviation = 100 self._set_key_int( _key="camera_steering_arrived_deviation", _addr=124, _tips="相机角度电机的到位偏差" ) # 焦段电机的到位偏差 self.camera_zoom_arrived_deviation = 100 self._set_key_int( _key="camera_zoom_arrived_deviation", _addr=125, _tips="焦段电机的到位偏差" ) # 前后移动电机的到位偏差 self.move_turntable_arrived_deviation = 100 self._set_key_int( _key="move_turntable_arrived_deviation", _addr=126, _tips="前后移动电机的到位偏差" ) # 转盘角度电机的到位偏差 self.turntable_steering_arrived_deviation = 100 self._set_key_int( _key="turntable_steering_arrived_deviation", _addr=127, _tips="转盘角度电机的到位偏差" ) # 转盘转速比例 self.turntable_speed_raito = 1.0 self._set_key_float( _key="turntable_speed_raito", _addr=128, _tips="转盘转速比例" ) # 变焦初始化力矩 self.c_torque_max_electric = 800 self._set_key_int( _key="c_torque_max_electric", _addr=129, _tips="变焦初始化力矩" ) # 变焦运动方向 self.zoom_dir = 0 self._set_key_int( _key="zoom_dir", _addr=130, _tips="变焦运动方向" ) # ------------------------------------- # 转盘偏移角度 单位1度 self.turntable_steering_deviation = 0 self._set_key_float( _key="turntable_steering_deviation", _addr=200, _tips="转盘偏移角度" ) # 相机偏移角度 单位1度 self.camera_steering_deviation = 0 self._set_key_float( _key="camera_steering_deviation", _addr=201, _tips="相机偏移角度" ) # 升降偏移距离mm self.camera_high_motor_deviation = 0 self._set_key_int( _key="camera_high_motor_deviation", _addr=202, _tips="升降偏移距离mm" ) # 翻板中位 单位1度 self.overturn_steering_middle = 95 self._set_key_float( _key="overturn_steering_middle", _addr=203, _tips="翻板中位 单位0.1度" ) # 翻板高位 单位1度 self.overturn_steering_high = 150 self._set_key_float( _key="overturn_steering_high", _addr=204, _tips="翻板高位 单位0.1度" ) # 翻板上升速度 self.overturn_steering_up_speed = 2 self._set_key_int( _key="overturn_steering_up_speed", _addr=205, _tips="翻板上升速度" ) # 翻板下降速度 self.overturn_steering_down_speed = 4 self._set_key_int( _key="overturn_steering_down_speed", _addr=206, _tips="翻板下降速度" ) # 是否完成初始化 self.has_been_set = 0 self._set_key_int( _key="has_been_set", _addr=207, _tips="是否完成初始化", _readonly=True ) # 相机调焦功能支持 self.camera_has_focal = 0 self._set_key_int(_key="camera_has_focal", _addr=208, _tips="相机调焦功能支持") # 相机焦段最大运动距离 self.camera_max_distance = 8000 self._set_key_int(_key="camera_max_distance", _addr=209, _tips="相机焦段最大运动距离") # 相机焦段步进ratio self.camera_focal_ratio = 0.0 self._set_key_float( _key="camera_focal_ratio", _addr=210, _tips="相机焦段步进ratio" ) # 相机焦段当前实时位置 self.camera_zoom_motor_current_value = 0 self._set_key_float( _key="camera_zoom_motor_current_value", _addr=211, _tips="相机焦段当前实时位置", _readonly=True, ) # 伺服电机每次运动后的偏移数值 self.servo_add_v = 0 self._set_key_int( _key="servo_add_v", _addr=212, _tips="伺服电机每次运动后的偏移数值" ) # ===================================================== # 获取剩余内存 self.get_memory = 0 self._set_key_float( _key="get_memory", _addr=300, _tips="获取剩余内存", _readonly=True ) # ===================================================== # ===============调试用====================== # 相机焦段功能设置 self.camera_focal_set = 0 self._set_key_float( _key="camera_focal_set", _addr=400, _tips="相机焦段功能设置", _readonly=True )