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)