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

137 lines
5.1 KiB
Python

import struct
import logging
class Command03:
def __init__(self):
self.command = 0x03 # 03H命令码
def parse_03h(self, data):
"""
解析03H登录信息命令
:param data: 完整的03H命令报文
:return: 解析后的字典或None
"""
try:
# 验证基本帧格式
if len(data) < 14 or data[0:2] != b'JX' or data[2] != 0x03:
logging.warning("03H命令帧格式不正确")
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}"
# 解析桩型号 (16字节ASCII)
pile_type = data[6:22].decode('ascii').rstrip('\x00')
# 解析硬件版本 (2字节压缩BCD)
hw_version_bytes = data[22:24]
hw_version_major = hw_version_bytes[0] >> 4
hw_version_minor = hw_version_bytes[0] & 0x0F
hw_version_patch = hw_version_bytes[1] >> 4
hw_version = f"{hw_version_major}.{hw_version_minor}.{hw_version_patch}"
# 解析软件版本 (2字节压缩BCD)
sw_version_bytes = data[24:26]
sw_version_major = sw_version_bytes[0] >> 4
sw_version_minor = sw_version_bytes[0] & 0x0F
sw_version_patch = sw_version_bytes[1] >> 4
sw_version = f"{sw_version_major}.{sw_version_minor}.{sw_version_patch}"
# 解析次级单元硬件版本
sub_hw_version_bytes = data[26:28]
sub_hw_version_major = sub_hw_version_bytes[0] >> 4
sub_hw_version_minor = sub_hw_version_bytes[0] & 0x0F
sub_hw_version_patch = sub_hw_version_bytes[1] >> 4
sub_hw_version = f"{sub_hw_version_major}.{sub_hw_version_minor}.{sub_hw_version_patch}"
# 解析次级单元软件版本
sub_sw_version_bytes = data[28:30]
sub_sw_version_major = sub_sw_version_bytes[0] >> 4
sub_sw_version_minor = sub_sw_version_bytes[0] & 0x0F
sub_sw_version_patch = sub_sw_version_bytes[1] >> 4
sub_sw_version = f"{sub_sw_version_major}.{sub_sw_version_minor}.{sub_sw_version_patch}"
# 解析直流模块类型
dc_module_type = data[30]
# 解析直流模块总数
dc_module_count = data[31]
# 解析直流模块单模块功率
dc_module_power = data[32]
# 解析计费模型版本
fee_model_version = struct.unpack("<H", data[33:35])[0]
# 打印解析结果
print("\n03H命令解析结果:")
print(f"桩号: {pile_id_bytes.hex()}")
print(f"时间标识: {timestamp}")
print(f"桩型号: {pile_type}")
print(f"硬件版本: {hw_version}")
print(f"软件版本: {sw_version}")
print(f"次级单元硬件版本: {sub_hw_version}")
print(f"次级单元软件版本: {sub_sw_version}")
print(f"直流模块类型: {dc_module_type}")
print(f"直流模块总数: {dc_module_count}")
print(f"直流模块单模块功率: {dc_module_power}kW")
print(f"计费模型版本: {fee_model_version}")
return {
"pile_id": pile_id_bytes.hex(),
"timestamp": timestamp,
"pile_type": pile_type,
"hw_version": hw_version,
"sw_version": sw_version,
"sub_hw_version": sub_hw_version,
"sub_sw_version": sub_sw_version,
"dc_module_type": dc_module_type,
"dc_module_count": dc_module_count,
"dc_module_power": dc_module_power,
"fee_model_version": fee_model_version
}
except Exception as e:
logging.error(f"解析03H命令失败: {str(e)}")
return None
def process_03h(self, data):
"""
处理03H登录信息命令
:param data: 完整的03H命令报文
:return: 是否成功处理
"""
try:
parsed_data = self.parse_03h(data)
if parsed_data is None:
logging.warning("03H命令解析失败")
return False
# 可以在这里添加额外的处理逻辑,比如记录日志、更新状态等
logging.info(f"成功解析03H登录信息: 桩号 {parsed_data['pile_id']}")
return True
except Exception as e:
logging.error(f"处理03H命令出错: {str(e)}")
return False
# 测试用示例
if __name__ == "__main__":
# 示例报文
test_data = bytes.fromhex(
"4A 58 03 03 17 67 63 11 36 06 57 01 42 00 19 01 09 09 37 1B 41 49 4F 44 43 32 50 31 42 56 39 30 30 00 00 00 00 00 01 04 00 00 00 00 00 00 00 1B 00 00 00 19 01 09 09 37 1B 0F 00 05 19 00 19 00 0F 00 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 0C")
parser = Command03()
parser.process_03h(test_data)