Skip to content

P1Q Wifi packet format

Units of measurement

#define UNIT_TYPE_C   0     /**< C = celsius */
#define UNIT_TYPE_PA  1     /**< Pa = pascal */
#define UNIT_TYPE_KPA 2     /**< kPa = kilopascal */
#define UNIT_TYPE_MPA 3     /**< MPa = megapascal */

Example parser

Python3

#!/usr/bin/env python3

from pprint import pprint
import struct


def parse(packet):
    d = {}
    by = bytes(packet)

    # device serial number - as notes on device label
    d["device_serial"] = struct.unpack("<I", by[0:4])[0]

    # unit of measurement that follows
    # 2 = kPa = kilopascal
    d["unit"] = int(by[4])

    # minimum value measured between transmit cycles
    d["value_mini"] = struct.unpack("<f", by[5:9])[0]
    d["value_mini_bytes_12"] = struct.unpack("<h", by[5:7])[0]
    d["value_mini_bytes_34"] = struct.unpack("<h", by[7:9])[0]

    # maximum value measured between transmit cycles
    d["value_maxi"] = struct.unpack("<f", by[9:13])[0]
    d["value_maxi_bytes_12"] = struct.unpack("<h", by[9:11])[0]
    d["value_maxi_bytes_34"] = struct.unpack("<h", by[11:13])[0]

    # average value measured between transmit cycles
    d["value_avrg"] = struct.unpack("<f", by[13:17])[0]
    d["value_avrg_bytes_12"] = struct.unpack("<h", by[13:15])[0]
    d["value_avrg_bytes_34"] = struct.unpack("<h", by[15:17])[0]

    # last value measured in transmit cycle
    d["value_last"] = struct.unpack("<f", by[17:21])[0]

    # battery level as described in https://docs.quorumprecision.com/p1ap-manual/#battery-level-information
    d["battery_level"] = int(by[-1])

    return d


if __name__ == "__main__":
    packets = ("7B00000002608BBDBE608BBDBE608BBDBE608BBDBEE9",)
    for p in packets:
        print("Parsing len: {} (expecting 22 bytes) -> {}".format(int(len(p) / 2), p))
        packet = bytes.fromhex(p)
        parsed_data = parse(packet)
        pprint(parsed_data)

Contacts

For support please contact your distributor or manufacturer directly via www.moirelabs.com