135 lines
5.5 KiB
Python
135 lines
5.5 KiB
Python
# 测试地址域输入处理
|
||
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"
|
||
) |