JS 从缓冲区中读取字节

JS reading bytes out of a buffer

我可以通过一些 String 技巧来解析缓冲区,但是必须有一种更直接的方法来从缓冲区数据到最终值。 我一直在尝试使用一些 buffer.readInt8readInt16LE 等,但还没有成功。第一个和最后一个值占 2 个字节;如果我理解这里涉及的词汇。其他二对一

从下面的示例中,我本希望通过 parseInt(buffer.readUInt16BE(6) | (buffer.readUInt16BE(7) << 8), 16) 获得温度 (228)。但这给出了 345314198,轻轻地表明我错过了一些东西。

代码

    // (example data in comments)
    
    const buffer = peripheral.advertisement.serviceData[0].data;
    // a4c1380a701400e4233c0ac5c2

    const lameParsing = {
      // Starts with the address a4:c1:38:0a:70:14, then the values
      temperatureC: parseInt(buffer.toString("hex").slice(12, 16), 16) / 10,
      // 22.8
      humidity: parseInt(buffer.toString("hex").slice(16, 18), 16),
      // 35
      battery: parseInt(buffer.toString("hex").slice(18, 20), 16),
      // 60
      batteryV: parseInt(buffer.toString("hex").slice(20, 24), 16) / 1000
      // 2.757
    };

上下文

尝试从自定义固件中解码来自小米温度计的蓝牙广告数据described in the docs

这应该是您要查找的内容:

let Buf = Buffer.from("a4c1380a701400e4233c0ac5c2", "hex");
// Let Buf be the buffer from the Bluetooth thermometer.
// Sample data is used here, which matches in your problem.
let TemperatureC = Buf.readUInt16BE(6) / 10
let Humidity = Buf.readUIntBE(8,1)
let Battery = Buf.readUIntBE(9,1)
let BatteryV = (Buf.readUInt16BE(10)) / 1000
// Just to confirm it works...
console.log(TemperatureC,Humidity,Battery,BatteryV)
// Sample output: 22.8 35 60 2.757 (Correct)

每个字节都在偏移量上 1。因此,如果我们将 6 读取为 2 个字节,然后读取 7,我们实际上是从温度中读取第二个字节。记住要考虑到 16 位是 2 个字节;和 NodeJS 按字节偏移。