67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
# command_0A.py
|
||
import struct
|
||
import logging
|
||
|
||
class Command0A:
|
||
def build_0a_request(self, pile_id):
|
||
frame = bytearray([0x4A, 0x58, 0x0A]) # 帧头 + 命令
|
||
frame.extend(pile_id) # 桩号
|
||
frame.append(0x01) # 数据加密方式(不加密)
|
||
|
||
# 数据域:时间标识 + 记录类型
|
||
data = bytearray()
|
||
current_time = bytearray([0x19, 0x03, 0x0A, 0x13, 0x14, 0x00]) # 示例:2025-03-10 13:14:00
|
||
data.extend(current_time)
|
||
data.append(0x01) # 记录类型(0x01: 最近记录)
|
||
frame.extend(struct.pack('<H', len(data))) # 数据域长度
|
||
frame.extend(data)
|
||
|
||
# 计算校验码
|
||
checksum = 0
|
||
for b in frame[2:-1]:
|
||
checksum ^= b
|
||
frame.append(checksum)
|
||
return frame
|
||
|
||
def process_0a_response(self, data):
|
||
logging.debug(f"处理0A响应: {data.hex().upper()}")
|
||
if len(data) < 14:
|
||
logging.warning("0A数据长度不足")
|
||
return
|
||
|
||
pile_id = data[3:11]
|
||
data_start = 14
|
||
data_len = struct.unpack('<H', data[12:14])[0]
|
||
data_end = data_start + data_len
|
||
if len(data) < data_end + 1:
|
||
logging.warning("0A数据域长度不匹配")
|
||
return
|
||
|
||
# 提取字段
|
||
timestamp = data[data_start:data_start + 6]
|
||
record_type = data[data_start + 6]
|
||
offset = data_start + 7
|
||
|
||
# 假设数据域包含一条充电记录(开始时间、结束时间、电量等)
|
||
if offset + 19 > data_end: # 示例:6字节开始时间 + 6字节结束时间 + 4字节电量 + 1字节状态
|
||
logging.warning("0A记录数据不足")
|
||
return
|
||
|
||
start_time = data[offset:offset + 6]
|
||
end_time = data[offset + 6:offset + 12]
|
||
energy = struct.unpack('<f', data[offset + 12:offset + 16])[0] # 电量(kWh,浮点数)
|
||
status = data[offset + 16]
|
||
|
||
# 转换为键值对
|
||
parsed_data = {
|
||
"pile_id": pile_id.hex().upper(),
|
||
"timestamp": f"20{timestamp[0]:02X}-{timestamp[1]:02X}-{timestamp[2]:02X} {timestamp[3]:02X}:{timestamp[4]:02X}:{timestamp[5]:02X}",
|
||
"record_type": f"0x{record_type:02X}",
|
||
"record": {
|
||
"start_time": f"20{start_time[0]:02X}-{start_time[1]:02X}-{start_time[2]:02X} {start_time[3]:02X}:{start_time[4]:02X}:{start_time[5]:02X}",
|
||
"end_time": f"20{end_time[0]:02X}-{end_time[1]:02X}-{end_time[2]:02X} {end_time[3]:02X}:{end_time[4]:02X}:{end_time[5]:02X}",
|
||
"energy_kwh": energy,
|
||
"status": f"0x{status:02X}"
|
||
}
|
||
}
|
||
logging.info(f"0A解析结果: {parsed_data}") |