本文详解如何将 modbus 读取的多个 16 位寄存器(如 `[3468, 204, 0, 2080]`)按特定十进制位置规则拼接为完整整数(如 `20434682080`),适用于电表等设备的非标准数据编码场景。
在使用 pymodbus 读取电表等工业设备时,常遇到一种非标准数值编码方式:设备并非采用常规的 IEEE 754 浮点或标准大端/小端整数格式,而是将一个长整数(如 20434682080)按十进制位数切分后,分别存入多个 16 位寄存器。例如:
最终拼接逻辑为:
20434682080 = 2080 × 10⁸ + 204 × 10⁴ + 3468 × 10⁰ + 0 × 10¹²?
但实际观察目标值 20434682080 的结构可拆解为:
204 3468 2080 ← 按空格分组(注意:中间无 0 占位) → 实际顺序是:[寄存器1][寄存器0][寄存器3],而寄存器2=0未参与显示
更准确地,从结果反推其拼接规则:
因此,该案例本质不是字节序(endianness)问题,而是设备厂商自定义的“十进制寄存器映射规则”。它不遵循 BinaryPayloadDecoder 所支持的 BIG/LITTLE 字节序或字序,而是一种人工拼接逻辑。
✅ 正确处理方式:直接按业务规则解析寄存器列表,用幂运算组合:
registers = [3468, 204, 0, 2080] # result_ups.registers # 根据实测目标值 20434682080 反推:204 | 3468 | 2080 → 即 reg[1]+ reg[0] + reg[3] # 注意:reg[2] = 0 未被使用,可能是保留位或错误读取 kwh_ups = ( registers[1] * 10**8 # 204 → 占高位 3 位 → × 10^8 得 20400000000 + registers[0] * 10**4 # 3468 → 占中位 4 位 → × 10^4 得 34680000 + registers[3] # 2080 → 占低位 4 位 → 直接加 ) # 结果:20400000000 + 34680000 + 2080 = 20434682080 ✅
⚠️ 注意事项:
? 总结:当 pymodbus 返回的 registers 无法通过标准 Endian 解码得到预期值时,请优先怀疑是否为厂商自定义的十进制分段存储。此时最可靠的方法是:*依据实测数据与寄存器值,手工建立映射公式,并用 ` 10n` 精确拼接——这比逆向字节序更高效、更准确。