# 测试地址域输入处理 class TestAddressInput: def __init__(self): # 模拟SerialPortTool类的相关方法 self.base_commands = { "合闸": "FE FE FE FE 68 08 00 09 10 24 20 68 1C 10 35 89 67 45 B7 72 38 9C 4F 33 8C 8C 56 55 34 59 9A 16", "拉闸": "FE FE FE FE 68 08 00 09 10 24 20 68 1C 10 35 89 67 45 B7 72 38 9C 4D 33 8C 8C 56 54 34 59 97 16" } def hex_string_to_bytes(self, hex_str): """将带空格的十六进制字符串转换为字节数组""" hex_clean = hex_str.replace(" ", "") return bytes.fromhex(hex_clean) def calculate_cs(self, data_bytes): """计算校验和(XOR算法)""" cs = 0 for byte in data_bytes: cs ^= byte return cs def generate_command_with_id(self, base_command, command_type, device_input): """测试地址域输入处理""" try: # 将原指令拆分为列表 parts = base_command.split() # 确保指令长度正确 if len(parts) != 32: print(f"警告:指令长度不正确,预期32个部分,实际{len(parts)}个部分") # 修正指令长度,确保格式正确 parts = parts[:32] while len(parts) < 32: parts.append("00") # 首先处理合闸指令的4D替换,确保不会被其他逻辑影响 if command_type == "合闸": for i, part in enumerate(parts): if part == "4D": parts[i] = "4F" break # 处理设备输入:支持两种格式 # 1. 单个设备编号(如 "1" 或 "10") # 2. 完整的地址域字符串(如 "080009102420") if len(device_input) == 12 and device_input.isdigit(): # 完整的地址域字符串,需要拆分为6个2位十六进制部分 print(f"检测到完整地址域输入: {device_input}") # 将地址域字符串拆分为6个2位十六进制部分 address_parts = [device_input[i:i+2] for i in range(0, 12, 2)] print(f"地址域拆分结果: {address_parts}") # 替换地址域(索引5到10) if len(parts) >= 11: for i in range(6): if i < len(address_parts) and 5 + i < len(parts): parts[5 + i] = address_parts[i].upper() else: # 单个设备编号,转换为2位十六进制 print(f"检测到设备编号输入: {device_input}") device_id_int = int(device_input) device_id_hex = f"{device_id_int:02X}" # 替换设备编号:原指令中第11个位置(索引10)是设备编号位置 if len(parts) > 10: parts[10] = device_id_hex # 索引10是设备编号位置 # 移除旧的校验码,构建不带校验码的指令 command_without_cs = parts[:-2] # 移除校验码和结束符 command_str = " ".join(command_without_cs) # 计算校验码 command_bytes = self.hex_string_to_bytes(command_str) cs = self.calculate_cs(command_bytes) cs_hex = f"{cs:02X}" # 替换校验码:原指令中倒数第2个位置(索引-2) if len(parts) > 1: parts[-2] = cs_hex # 确保结束符正确 parts[-1] = "16" # 构建最终指令 final_command = " ".join(parts) # 调试:打印最终指令 print(f"命令类型: {command_type}") print(f"设备输入: {device_input}") print(f"最终指令: {final_command}") # 验证指令格式是否正确 final_parts = final_command.split() print(f"\n最终指令各部分索引和值:") for i, part in enumerate(final_parts): print(f"索引 {i}: {part}") print(f"\n指令长度: {len(final_parts)}") print(f"地址域(索引5-10): {' '.join(final_parts[5:11])}") print(f"指令格式是否正确: {len(final_parts) == 32 and final_parts[0] == 'FE' and final_parts[-1] == '16'}") return final_command except Exception as e: print(f"指令生成错误: {e}") return base_command # 测试 if __name__ == "__main__": test = TestAddressInput() # 测试1:完整地址域输入 "080009102420" print("=== 测试拉闸指令,完整地址域输入: 080009102420 ===") test.generate_command_with_id( test.base_commands["拉闸"], "拉闸", "080009102420" ) print("\n" + "="*50 + "\n") # 测试2:单个设备编号输入 "10" print("=== 测试合闸指令,单个设备编号输入: 10 ===") test.generate_command_with_id( test.base_commands["合闸"], "合闸", "10" ) print("\n" + "="*50 + "\n") # 测试3:完整地址域输入 "080009102408" print("=== 测试拉闸指令,完整地址域输入: 080009102408 ===") test.generate_command_with_id( test.base_commands["拉闸"], "拉闸", "080009102408" )