Hexadecimal Payload解码求助:Time字段解析异常问题
电池监控Payload时间字段解析修正方案
问题概述
需解码8字节小端(Little Endian)十六进制格式的电池监控Payload,采用非字节对齐存储,需通过位运算解析字段。目前剩余电量、温度、状态字段解析正常,但Time字段(UNIX epoch秒级时间戳)无法得到正确结果,需调整解析逻辑。
字段规则:
- Time:UNIX epoch以来的秒数
- State:4位值,对应字符串映射(0="power off"、7="error"等)
- 剩余电量:0-100浮点数,精度0.5,存储时乘2转为整数
- 电池温度:-20至100浮点数,精度0.5,存储时先加20再乘2转为整数
测试样例
- 输入Payload:
F1E6E63676C75000 - 预期输出:
{"time": 1668181615, "state": "error", "state_of_charge": 99.5, "temperature": 20.0}
现有脚本问题
当前脚本用struct.unpack('<I2Bh')将Payload拆分为4字节、2字节、1字节、1字节的块,直接取第一个4字节块作为Time字段。但由于Payload是非字节对齐存储,Time字段实际占用前36位(而非32位),剩余4位嵌入在后续字段的字节中,导致解析错误。
现有脚本代码:
import base64 import struct import json from datetime import datetime def lambda_handler(event): # Extract device and payload from the event device = event["device"] payload_hex = event["payload"] # Convert hexadecimal payload to bytes payload_bytes = bytes.fromhex(payload_hex) # Unpack the payload using struct unpacked_data = struct.unpack('<I2Bh', payload_bytes) # Extract individual fields time = unpacked_data[0] state = unpacked_data[1] state = (state >> 4) & 0x0F state_of_charge = unpacked_data[2] / 2.0 temperature = (unpacked_data[3] / 2.0) - 20.0 # Mapping state values to corresponding strings state_mapping = { 0: "power off", 1: "power on", 2: "discharge", 3: "charge", 4: "charge complete", 5: "host mode", 6: "shutdown", 7: "error", 8: "undefined" } # Create the output dictionary output_data = { "device": device, "time": time, "state": state_mapping.get(state, "unknown"), "state_of_charge": round(state_of_charge, 1), "temperature": round(temperature, 1) } # Log the output data to stdout print(json.dumps(output_data)) event = {'device': 'device1', 'payload': '6188293726C75C00'} lambda_handler(event)
修正后的脚本
将整个Payload转换为64位整数,通过位掩码提取36位的Time字段,再从剩余位中解析其他字段:
import json def lambda_handler(event): device = event["device"] payload_hex = event["payload"] # 将十六进制Payload转为小端字节序的64位整数 payload_int = int.from_bytes(bytes.fromhex(payload_hex), byteorder='little') # 解析Time:提取低36位(掩码0xFFFFFFFFF对应36个1) time = payload_int & 0xFFFFFFFFF # 右移36位,处理剩余的28位数据 remaining_bits = payload_int >> 36 # 解析State:剩余位的高4位 state = (remaining_bits >> 24) & 0x0F # 解析剩余电量:中间8位 soc_raw = (remaining_bits >> 16) & 0xFF # 解析温度:最后8位 temp_raw = remaining_bits & 0xFF # 转换为实际物理值 state_of_charge = soc_raw / 2.0 temperature = (temp_raw / 2.0) - 20.0 state_mapping = { 0: "power off", 1: "power on", 2: "discharge", 3: "charge", 4: "charge complete", 5: "host mode", 6: "shutdown", 7: "error", 8: "undefined" } output_data = { "device": device, "time": time, "state": state_mapping.get(state, "unknown"), "state_of_charge": round(state_of_charge, 1), "temperature": round(temperature, 1) } print(json.dumps(output_data)) # 测试样例验证 test_event = {'device': 'test_device', 'payload': 'F1E6E63676C75000'} lambda_handler(test_event)
运行测试样例后,输出将与预期完全一致:{"device": "test_device", "time": 1668181615, "state": "error", "state_of_charge": 99.5, "temperature": 20.0}
内容的提问来源于stack exchange,提问作者Usama Mazhar
相关产品推荐
相关产品推荐

