2025-01-18 09:10:52 +08:00

154 lines
6.0 KiB
Python

import struct
import logging
class Command08:
def __init__(self):
self.command = 0x08 # 08H命令码
def parse_08h(self, data):
"""
解析08H故障命令
:param data: 完整的08H命令报文
:return: 解析后的字典或None
"""
try:
# 验证基本帧格式
if len(data) < 14 or data[0:2] != b'JX' or data[2] != 0x08:
logging.warning("08H命令帧格式不正确")
return None
# 提取桩号
pile_id_bytes = data[3:11]
# 提取时间标识
time_bytes = data[14:20]
year = time_bytes[0] + 2000
month, day, hour, minute, second = time_bytes[1:6]
timestamp = f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}"
# 提取故障状态字节
current_index = 20
fault_states = {
# 从文档3.3.1节提取的故障状态映射
"汇流接触器": (data[current_index] & 0x01) != 0,
"输入接触器": (data[current_index] & 0x02) != 0,
"电表通讯": (data[current_index] & 0x04) != 0,
"读卡器通讯": (data[current_index] & 0x08) != 0,
"HMI通讯": (data[current_index] & 0x10) != 0,
"绝缘检测模块": (data[current_index] & 0x20) != 0,
"急停": (data[current_index] & 0x40) != 0,
"柜门打开": (data[current_index] & 0x80) != 0,
"温湿度传感器": (data[current_index + 1] & 0x01) != 0,
"风机": (data[current_index + 1] & 0x02) != 0,
"加热器": (data[current_index + 1] & 0x04) != 0,
"防雷器": (data[current_index + 1] & 0x08) != 0,
"控制板硬件": (data[current_index + 1] & 0x10) != 0,
"机柜过温": (data[current_index + 1] & 0x20) != 0,
"湿度过高": (data[current_index + 1] & 0x40) != 0,
"烟感报警": (data[current_index + 1] & 0x80) != 0
}
# 提取充电枪数量
current_index += 2
gun_count = data[current_index]
# 存储每个枪的故障状态
gun_faults = []
current_index += 1
for i in range(gun_count):
# 每个枪有多个故障位
gun_fault_bytes = data[current_index:current_index + 3]
gun_faults.append({
"gun_index": i + 1,
"output_short_circuit": (gun_fault_bytes[0] & 0x01) != 0,
"output_contactor": (gun_fault_bytes[0] & 0x02) != 0,
"electronic_lock": (gun_fault_bytes[0] & 0x04) != 0,
"meter_communication": (gun_fault_bytes[0] & 0x08) != 0,
"charging_module_communication": (gun_fault_bytes[0] & 0x10) != 0,
"slave_control_communication": (gun_fault_bytes[0] & 0x20) != 0,
"insulation_module_communication": (gun_fault_bytes[0] & 0x40) != 0,
"insulation_fault": (gun_fault_bytes[0] & 0x80) != 0,
"module_overtemperature": (gun_fault_bytes[1] & 0x01) != 0,
"module_pfc": (gun_fault_bytes[1] & 0x02) != 0,
"module_fan": (gun_fault_bytes[1] & 0x04) != 0,
"module_address_conflict": (gun_fault_bytes[1] & 0x08) != 0,
"module_input_overvoltage": (gun_fault_bytes[1] & 0x10) != 0,
"module_input_undervoltage": (gun_fault_bytes[1] & 0x20) != 0,
"module_input_phase_loss": (gun_fault_bytes[1] & 0x40) != 0,
"module_other_fault": (gun_fault_bytes[1] & 0x80) != 0
})
current_index += 3
# 打印解析结果
print("\n08H命令解析结果:")
print(f"桩号: {pile_id_bytes.hex()}")
print(f"时间标识: {timestamp}")
print("系统故障状态:")
for fault, state in fault_states.items():
if state:
print(f" {fault}: 故障")
print(f"充电枪数量: {gun_count}")
for gun_fault in gun_faults:
print(f"{gun_fault['gun_index']} 故障状态:")
for fault, state in gun_fault.items():
if fault != "gun_index" and state:
print(f" {fault}: 故障")
return {
"pile_id": pile_id_bytes.hex(),
"timestamp": timestamp,
"system_faults": {k: v for k, v in fault_states.items() if v},
"gun_count": gun_count,
"gun_faults": gun_faults
}
except Exception as e:
logging.error(f"解析08H命令失败: {str(e)}")
return None
def process_08h(self, data):
"""
处理08H故障命令
:param data: 完整的08H命令报文
:return: 是否成功处理
"""
try:
parsed_data = self.parse_08h(data)
if parsed_data is None:
logging.warning("08H命令解析失败")
return False
# 记录故障信息日志
fault_summary = f"桩号 {parsed_data['pile_id']} 报告故障: "
system_faults = list(parsed_data['system_faults'].keys())
gun_faults_count = len(parsed_data['gun_faults'])
if system_faults:
fault_summary += f"系统故障 {system_faults}, "
fault_summary += f"充电枪数量 {gun_faults_count}"
logging.warning(fault_summary)
return True
except Exception as e:
logging.error(f"处理08H命令出错: {str(e)}")
return False
# 测试用示例
if __name__ == "__main__":
# 示例报文
test_data = bytes.fromhex(
"4A 58 08 03 17 67 63 11 36 06 57 01 11 00 19 01 09 0A 05 04 00 00 00 00 02 00 00 00 00 00 00 66")
parser = Command08()
parser.process_08h(test_data)