73 lines
2.7 KiB
Python
73 lines
2.7 KiB
Python
# command_37_38.py
|
|
import struct
|
|
import logging
|
|
import time
|
|
|
|
class Command3738:
|
|
def build_37h_request(self, pile_id, billing_template):
|
|
"""
|
|
下发计费模版请求
|
|
:param pile_id: 8字节桩号
|
|
:param billing_template: 计费模版列表,格式 [(time_minutes, price_per_minute, total_seconds, total_cost), ...]
|
|
"""
|
|
frame = bytearray([0x4A, 0x58, 0x37]) # 帧头 + 命令
|
|
frame.extend(pile_id) # 桩号
|
|
frame.append(0x01) # 数据加密方式(不加密)
|
|
|
|
# 数据域
|
|
data = bytearray()
|
|
current_time = time.localtime()
|
|
time_bytes = bytearray([
|
|
current_time.tm_year - 2000,
|
|
current_time.tm_mon,
|
|
current_time.tm_mday,
|
|
current_time.tm_hour,
|
|
current_time.tm_min,
|
|
current_time.tm_sec
|
|
])
|
|
data.extend(time_bytes)
|
|
data.extend(b'\x1D\x00\x00\x00\x00\x00') # 未知字段,参考日志
|
|
|
|
# 计费模版数据
|
|
for entry in billing_template:
|
|
time_minutes, price_per_minute, total_seconds, total_cost = entry
|
|
data.extend(struct.pack('<H', time_minutes)) # 时间段(分钟)
|
|
data.extend(struct.pack('<H', price_per_minute)) # 单价(分/分钟)
|
|
data.extend(struct.pack('<I', total_seconds)) # 累计时间(秒)
|
|
data.extend(struct.pack('<I', total_cost)) # 累计金额(分)
|
|
|
|
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 parse_38h_response(self, data):
|
|
if len(data) < 14:
|
|
logging.warning("38H数据长度不足")
|
|
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("38H数据域长度不匹配")
|
|
return
|
|
|
|
timestamp = data[data_start:data_start + 6]
|
|
unknown_field = data[data_start + 6:data_start + 8]
|
|
result = struct.unpack('<H', data[data_start + 8:data_start + 10])[0]
|
|
|
|
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}",
|
|
"unknown_field": unknown_field.hex().upper(),
|
|
"result": "Success" if result == 0x0100 else "Failed",
|
|
"result_code": f"0x{result:04X}"
|
|
}
|
|
logging.info(f"38H计费模版下发结果: {parsed_data}") |