Efento Bluetooth Low Energy sensors – decoding advertising data

All Efento sensors (both Bluetooth Low Energy and NB-IoT) are equipped with a Bluetooth interface. This allows mobile phones, BLE gateways and custom hardware to communicate with the sensors, read the measurements taken by them and/or change their configuration. In this tutorial, we will show how to parse the data sent by Efento sensors in Bluetooth Low Energy advertisement frames.

Bluetooth Low Energy advertising transmissions

Bluetooth defines two transmissions types: data and advertising transmissions. Bluetooth advertising transmission is used by BLE equipped devices to broadcast useful data to others around. Bluetooth Low Energy advertising packets are used to initiate the communication between the devices (e.g. a smartwatch that wants to connect to a mobile phone) or simply send a small message to nearby devices (e.g. a wireless sensor broadcasting temperature to anyone who wants to listen).

When using the advertising transmission, no connection is established between the devices – any Bluetooth Low Energy can receive the advertising packets sent by the others. As the data is sent in broadcast, the messages do not need to be acknowledged by the receiving side. Advertising packet structure is defined by BLE standard, and you can find its full specification here.

Efento sensors – BLE advertising transmissions

Efento sensors use Bluetooth advertising transmissions to share the most recent measurement and some important technical information with the nearby devices. Each advertisement data packet contains: the current measurement along with its type, information about battery level, software version, calibration date (optional) and measurement period. The advertising packets sent by Efento sensors can be encrypted, so only devices with a proper encryption key will be able to decrypt and parse the payload.

Receiving the data

Efento sensors broadcast the advertisement packets by default and it is impossible to turn off these transmissions (it is possible to completely disable Bluetooth, but as long as it’s enabled the device will broadcast the advertisement packets). The data is received by all the nearby BLE equipped devices (phones, tablets, laptops, etc.).

One of the easiest ways to read the advertising data is to download Nordic Semiconductor’s nRF connect mobile application for Android or iOS. The application shows advertising data sent by all nearby Bluetooth devices (“Manufacturer data” on the screenshot below).

Important! If you are integrating Efento sensors to your custom hardware or a computer program, the program / device needs to do active scanning in order to receive the advertising packet.

Parsing the data – FW 6.X.X (Efento NB-IoT and Bluetooth Low Energy sensors)

Efento sensors broadcast their current status using Bluetooth Low Energy advertisement frames. The gateway needs to perform active scanning and the sensor will send its current measurements in the scan response. In order to get the full information about the sensor status along with its current measurements, the gateway must parse both frames. 

Efento devices with firmware version 6.X.X end the data in two frames. The first frame (advertisement) contain information about the device, the second frame (scan response) contain measurements taken by the device.

Decoding advertisement frame

  • Byte 1-2:  Manufacturer ID – unique identifier of Bluetooth Low Energy equipped devices manufacturer. In case of Efento it is always “6C-02”
  • Byte 3: Manufacturing data version –  set to “03” for Bluetooth advertisement frames
  • Byte 4-9: Device’s serial number (BLE MAC address)
  • Byte 10-11: Firmware version
    • Bit 0-4: Long term support version
    • Bit 5-10: Minor version
    • Bit 11-15 Major version
  • Byte 12: Status byte:
    • Bit 0: Battery level; 1 – Battery OK, 0 – Battery discharged
    • Bit 1-2: External power supply status: 00 – Battery only device, 01 – External power supply connected, 10 – external power supply disconnected, 11 – Power supply error
    • Bit 3: Encryption status: 0 – disabled, 1 – enabled
    • Bit 4: Time synchronisation: 0 – time synchronised, 1 – time not synchronised
    • Bit 5: Runtime error and modem info logging: 0 – no runtime errors and modem logs disabled, 1 – runtime error or modem logs enabled
    • Bit 6-7: Cellular status: 00 – BLE only device, 01 – cellular device working correctly, 10 – no connection to the server, 11 – network issue or device is not registered in the networkByte 7-10: Measurement counter, incremented at each measurement (used also as CTR counter for AES128-CTR encryption), 32-bit value encoded in big endian (most significant byte first)
  • Byte 13-16: Measurement timestamp in POSIX format
  • Byte 17-18: Measurement period base
  • Byte 19-20: Measurement period factor
  • Byte 21-22: Calibration date – optional field set by Efento and stored in nonvolatile memory
  • Byte 23-24: Checksum; CRC16 calculated from 6-byte serial number (MAC address, starting from first byte) and bytes 1 – 22

    Example:

    6C 02 03 28 2C 02 4F 00 12 31 44 11 64 21 56 24 00 B4 00 01 00 00 9E 04

    Byte(s) Value Decoded
    1, 2 6C 02 Manufacturing specific data (always “06 02”)
    3 03 Manufacturing data format (always “03” for Efento fw 6.X.X advertisement frame)
    4, 5, 6, 7, 8, 9 28 2C 02 4F 00 12 Serial number:
    MAC – 282C024F0012
    10, 11 31 44 Firmware version

    HEX 31 44 = BIN 00110 001010 00100

    Bit 0-4  = BIN 00100 = DEC 4 (LTS version)
    Bit 5-10 = BIN 001010 = DEC 10 (Minor version)
    Bit 11-15 = BIN 00110 = DEC 6 (Major version)

    FW: 6.10.4

    12 11 HEX 11 = Binary 00 0 1 0 00 1

    Battery level:
    Bit 0 = 1: Battery – OK

    External power supply status:
    Bit 1-2 = 00: Battery-operated device only

    Encryption status:
    Bit 3 = 0: Disabled

    Time synchronisation:
    Bit 4 = 0: Time not synchronised

    Runtime error and logging on to the modem is inactive:
    Bit 5 = 0: Runtime error table is empty and logging on to the modem is inactive

    Cellular status:
    Bit 6-7 = 00: BLE only device

    13, 14, 15, 16 64 21 56 24 Measurements timestamp:

    HEX 64 21 56 24 = 1679906340 = 27 March 2023 08:39:00 UTC

    17, 18 00 B4 Measurement period base:
    HEX 00B4 = DEC 180 seconds
    19, 20 00 01 Measurement period factor:
    HEX 0001 = DEC 1
    21, 22 00 00  No calibration date set
    23, 24 9E 04 CRC16

    Decoding scan response frame

    • Byte 1-2:  Manufacturer ID – unique identifier of Bluetooth Low Energy equipped devices manufacturer. In case of Efento it is always “6C-02”
    • Byte 3: Manufacturing data version –  set to “04” for scan response frames
    • Byte 4: Type of measurement on slot 1
    • Byte 5-7: Measurement value (slot 1)
    • Byte 8: Type of measurement on slot 2 (optional)
    • Byte 9-11: Measurement value (slot 2) (optional)
    • Byte 12: Type of measurement on slot 3 (optional)
    • Byte 13-15: Measurement value (slot 3) (optional)
    • Byte 16: Type of measurement on slot 4 (optional)
    • Byte 17-19: Measurement value (slot 4) (optional)
    • Byte 20: Type of measurement on slot 5 (optional)
    • Byte 21-23: Measurement value (slot 5) (optional)
    • Byte 24: Type of measurement on slot 6 (optional)
    • Byte 25-27: Measurement value (slot 6) (optional)
    • Byte 28-29: Checksum, CRC16 calculated from 6-bytes serial number (MAC address, starting from first byte) and bytes 1 to 22 from manufacturing format 3 and bytes from  1 to (3+ (channel_number * 4)) from manufacturing format 4. 

    Measurement types

    Efento sensors with firmware version 6.X.X can be equipped with up to six slots and measure up to six values.

    Measurements represent physicals values that are measured by the sensor assigned to a device slot. Measurement types are divided into two groups: Continuous and Binary measurements.

    Each binary measurement can only have 2 states: positive or negative that are translated into appropriate value.

    Each continuous measurement consists of a value and optional metadata. Value and metadata are defined by the following formulas:

    Value = IntegerPart(raw_value / metadata_factor) * resolution

    Metadata = |raw_value| mod metadata_factor

    Values are encoded using ZigZag.

    Metadata factor and resolution is defined for each measurement type:

    Type (HEX) Type Min Value Max Value Resolution Unit Continuous/
    binary
    Metadata
    factor
    Summary
    0x01 TEMPERATURE -273.2 4 000.0 0.1 °C continuous 1 Temperature
    0x02 HUMIDITY 0 100 1.0 % continuous 1 Humidity
    0x03 ATMOSPHERIC_PRESSURE 1.0 2 000.0 0.1 hPa continuous 1 Atmospheric pressure
    0x04 DIFFERENTIAL_PRESSURE -10 000 10 000 1.0 Pa continuous 1 Differential pressure
    0x05 OK_ALARM [-] [+] binary 1 Binary format for indicates state OK/Alarm
    0x06 IAQ 0 500 1.0 continuous 3 Indoor air quality
    0x07 FLOODING [-] [+] binary 1 Binary format for flooding
    0x08 PULSE_CNT 0 8 000 000 1.0 continuous 1 Pulse counter
    0x09 ELECTRICITY_METER 0 8 000 000 1.0 Wh continuous 1 Electricity meter (pulse counter)
    0x0A WATER_METER 0 8 000 000 1.0 l continuous 1 Water meter (pulse counter)
    0x0B SOIL_MOISTURE -1000 0 1.0 kPa continuous 1 Soil moisture
    0x0C CO_GAS 0 1 000 000 1.0 ppm continuous 1 Carbon monoxide
    0x0D NO2_GAS 0 1 000 000 1.0 ppm continuous 1 Nitrogen dioxide
    0x0E H2S_GAS 0 80 000.00 0.01 ppm continuous 1 Hydrogen sulfide
    0x0F AMBIENT_LIGHT 0 100 000.0 0.1 lx continuous 1 Illuminance
    0x10 PM_1_0 0 1 000 1.0 µg/m^3 continuous 1 Mass concentration of particles less than 1µm
    0x11 PM_2_5 0 1 000 1.0 µg/m^3 continuous 1 Mass concentration of particles less than 2.5µm
    0x12 PM_10_0 0 1 000 1.0 µg/m^3 continuous 1 Mass concentration of particles less than 10µm
    0x13 NOISE_LEVEL 0 200.0 0.1 dB continuous 1 Noise level
    0x14 NH3_GAS 0 1 000 000 1.0 ppm continuous 1 Ammonia
    0x15 CH4_GAS 0 1 000 000 1.0 ppm continuous 1 Methane
    0x16 HIGH_PRESSURE 0 200 000 1.0 kPa continuous 1 High pressure
    0x17 DISTANCE_MM 0 100 000 1.0 mm continuous 1 Distance
    0x18 WATER_METER_ACC_MINOR 0 99 1.0 liter continuous 6 Accumulative water meter (pulse counter) 
    0x19 WATER_METER_ACC_MAJOR 0 999 999 1.0 hectoliter continuous 4 Accumulative water meter (pulse counter)
    0x1A CO2_GAS 0 1 000 000 1.0 ppm continuous 3 Carbon dioxide
    0x1B HUMIDITY_ACCURATE 0.0 100.0 0.1 % continuous 1 Humidity
    0x1C STATIC_IAQ 0 10 000 1.0 continuous 3 Static indoor air quality
    0x1D CO2_EQUIVALENT 0 1 000 000 1.0 ppm continuous 3 Carbon dioxide equivalent estimate
    0x1E BREATH_VOC 0 100 000 1.0 ppm continuous 3 Breath-VOC estimate
    0x1F CELLULAR_GATEWAY 0 4 194 303 continuous 1 Cellular gateway
    0x20 PERCENTAGE 0.00 100.00 0.01 % continuous 1 Percentage
    0x21 VOLTAGE 0.0 100 000.0 0.1 mV continuous 1 Voltage
    0x22 CURRENT 0.0 10 000.00 0.01 mA continuous 1 Current
    0x23 PULSE_CNT_ACC_MINOR 0 999 1.0 Pulses continuous 6 Accumulative pulse counter
    0x24 PULSE_CNT_ACC_MAJOR 0 999 999 1.0 Kilo Pulses continuous 4 Accumulative pulse counter
    0x25 ELEC_METER_ACC_MINOR 0 999 1.0 Wh continuous 6 Accumulative electricity meter (pulse counter)
    0x26 ELEC_METER_ACC_MAJOR 0 999 999 1.0 kWh continuous 4 Accumulative electricity meter (pulse counter)

    Decoding example (continuous sensor type):

    6C 02 04 01 00 01 C0 02 00 00 4C 28 30

    Byte(s) Value Decoded
    1, 2 6C 02 Manufacturing specific data (always “06 02”)
    3 04 Manufacturing data format (always “04” for Efento fw 6.X.X scan response frame)
    4 01 Slot type:
    1 – Temperature
    5, 6, 7 00 01 C0 HEX 01 C0 = DEC 448
    ZIGZAG 448 = 224/10 = 22,4 Slot 1 measurement value: 22,4°C
    8 Slot type:
    2 – Humidity
    9, 10, 11 00 00 4C HEX 4C = DEC 76
    ZIGZAG 76 = 38 Slot 2 measurement value: 38%
    12, 13 28 30 CRC16

     

    Parsing the data – FW 5.X (Old version of Efento Bluetooth Low Energy sensors)

    The data broadcasted by Efento Bluetooth Low Energy sensors has the following format:

    • Byte 1-2:  Manufacturer ID – unique identifier of Bluetooth Low Energy equipped devices manufacturer. In case of Efento it is always “6C-02”
    • Byte 3: Manufacturing data version –  set to “02” for Bluetooth sensors
    • Byte 4: Major SW version
    • Byte 5: Minor SW version
    • Byte 6:
      • Bit 0: Battery level; 1 – Battery OK, 0 – Battery discharged
      • Bit 1: Encryption enabled; 1 – bytes 11 to 26 are encrypted using AES128-CTR, 0 – bytes 11 to 26 are not encrypted
      • Bit 2: Indicates storage error; 1 – storage error occurred (some measurements are lost), 0 – correct operation
      • Bit 3: Sensor binary flag
      • Bit 4-7: Reserved, set to 0
    • Byte 7-10: Measurement counter, incremented at each measurement (used also as CTR counter for AES128-CTR encryption), 32-bit value encoded in big endian (most significant byte first)
    • Byte 11-12: Measurement period
      • Bit 0-14: Period value in units specified by bit 15, encoded in big endian (most significant byte first)
      • Bit 15: Period unit; 1 – in seconds, 0 – in minutes
    • Byte 13:  Reserved, always set to 0
    • Byte 14: Sensor type – Slot 1
    • Byte 15: Sensor type – Slot 2
    • Byte 16: Sensor type – Slot 3
    • Byte 17-18: Measurement slot 1 – encoding big endian. Format of the data depends on the slot type (described below)
    • Byte 19-20: Measurement slot 2 – encoding big endian. Format of the data depends on the slot type (described below)
    • Byte 21-22: Measurement slot 3 – encoding big endian. Format of the data depends on the slot type (described below)
    • Byte 23-24: Calibration date; optional field set by Efento and stored in nonvolatile memory
    • Byte 25-26: Checksum; CRC16 calculated from 6-byte serial number (MAC address, starting from first byte) and bytes 1 – 24

    Measurement types

    Efento Bluetooth Low Energy sensors are equipped with three slots and can measure up to three values (e.g. temperature, humidity, air pressure or temperature, temperature, temperature). The types of slots are defined by Bytes 14-16. If a slot is empty (e.g. sensor uses only one slot), Bytes will be set to 0. Slot types are defined as below:

    Type

    Slot type

    Values

    None 0 (0x00)
    Temperature 1 (0x01) Temperature is represented as a 16-bit big endian value. Most significant bit indicates the range and resolution. The value is expressed in Celsius degrees in the following way:

    • 0x0000 – 0x7530: temperature in range -150.0C to 150.0C with 0.01C resolution
    • 0x0000: -150.00C
    • 0x0001: -149.99C

    • 0x752F: 149.99C
    • 0x7530: 150.00C
    • 0xFED4 – 0xFFFE: error codes:
    • 0xFFD4 – 0xFFFC: for future use
    • 0xFFFD: temperature out of range
    • 0xFFFE: sensor error
    Humidity 2 (0x02) Humidity is expressed in percents as a 8-bit value in the following way:

     

    • 0x00 – 0x64: humidity in percents:
    • 0x00: 0%

    • 0x64: 100%
    • 0x65 – 0xFC: for future use
    • 0xFD: humidity out of range
    • 0xFE: sensor error
    • 0xFF: no measurement, e.g. slot not used.
    Air pressure 3 (0x03) Pressure is expressed in dPa (0.1 hPa) as a 16-bit value in the following way:

    • 0x0000 – 0xFF00: Pressure in dPa:
    • 0x0000: 0 hPa
    • 0x0001: 0.1 hPa

    • 0xFEFE: 6527.8 hPa
    • 0xFEFF: 6527.9 hPa    

     

    • 0xFF00 – 0xFFFC: for future use
    • 0xFFFD: measured pressure is out of range of sensor
    • 0xFFFE: sensor failure

     

    • 0xFFFF: no measurement, e.g. slot not used.
    Differential pressure 4 (0x04) Differential pressure is expressed in Pa as a 16-bit value in the following way:

     

    • 0x00 – 0xFF: Reserved
    • 0x100 – 0xFEFF: Differential pressure in Pa:
    • 0x100: -32512 Pa
    • 0x101: -32511 Pa

    • 0x8000: 0 Pa

    • 0xFEFE: 32510 Pa
    • 0xFEFF: 32511 Pa
    • 0xFF00 – 0xFFFC: for future use
    • 0xFFFD: measured differential pressure is out of range of sensor
    • 0xFFFE: sensor error
    • 0xFFFF: no measurement, e.g. slot not used.
    OK / Alarm
    (binary sensor)
    5 (0x05) Ok / Alarm is a two state sensor, decoded as follows:

    • Bit set to 1 – Alarm
    • Bit set to 0 – Ok

     

    Bits 0-8:

    Each bit represents state at timestamp:

    Timestamp = currentTime – (currentTime mod period) – N*period

    Where:

    currentTime – time of the frame reception

    Period – sensor period

    N – bit position

    Bit 14 – always set to 1; sensor error otherwise

    Bit 15 – alway set to 0; sensor error otherwise

    Indoor Air Quality (VOC) 6 (0x06) IAQ sensor value is a combination of internal air quality value and calibration status of the sensor. Air quality is coded on bits 0-8 (0x0000 – 0x01F4), accuracy is coded on bits 9 and 10, (0x00 – 0x03 shifted 9 positions to left).

    Bits 0-8 value:

    • 0x000 – 0x1F4: air quality value:
    • 0x000: 0 IAQ

    • 0x01F4: 500 IAQ

        Bits 9 and 10:

    • 0x00 – 0x03 calibration status:
    • 0x00: Sensor not stabilised (always returns 25 IAQ value)
    • 0x01: Calibration required (sensor returns not accurate values)
    • 0x02: Calibration on-going (sensor returns not accurate values)
    • 0x03: Calibration done (best accuracy of IAQ sensor)

        Bit 11:

    • 0x01 – always 1

        Bits 12, 13, 14, 15:

    • If the value is ok, this bit should be set to 0

        Error codes:

    • 0xFFFD: value out of range
    • 0xFFFE: sensor error
    • 0xFFFF: no measurement, e.g. slot not used.
    Water leakage 7 (0x07) Water leak sensor is a two state sensor, decoded as follows:

    • Bit set to 1 – Water detected
    • Bit set to 0 – Water not detected

     

    Bits 0-8:

    Each bit represents state at timestamp:

    Timestamp = currentTime – (currentTime mod period) – N*period

    Where:

    currentTime – time of frame reception

    Period – sensor period

    N – bit position

    Bit 14 – always set to 1; sensor error otherwise

    Bit 15 – alway set to 0; sensor error otherwise

    Pulse counter 8 (0x08) 0x0000: marker value

     

    0x0001 – 0xFEFF: number of pulses measured in the period (with offset = 1):

    0x0001: 0 pulses

    0xFEFF: 65278 pulses

     

    0xFF00 – 0xFFFB: reserved (error)

    0xFFFC: measurements incomplete

    0xFFFD: counter overflow

    0xFFFE: sensor error

    0xFFFF: no measurement, e.g. slot not used

    Pulse counter (electricity) 9 (0x09) 0x0000: marker value

     

    0x0001 – 0xFEFF: number of watt-hours measured in the period (with offset = 1):

    0x0001: 0 [Wh]

    0xFEFF: 65278 [Wh]

     

    0xFF00 – 0xFFFB: reserved (error)

    0xFFFC: measurements incomplete

    0xFFFD: counter overflow

    0xFFFE: sensor error

    0xFFFF: no measurement, e.g. slot not used

    Pulse counter (water) 10 (0x0A) 0x0000: marker value

     

    0x0001 – 0xFEFF: number of litres measured in the period (with offset = 1):

    0x0001: 0 [l]

    0xFEFF: 65278 [l]

     

    0xFF00 – 0xFFFB: reserved (error)

    0xFFFC: measurements incomplete

    0xFFFD: counter overflow

    0xFFFE: sensor error

    0xFFFF: no measurement, e.g. slot not used

    Soil moisture 11 (0x0B) Soil Moisture Sensor (measurement method: soil water tension) is expressed in -1[kPa] as a 8-bit value in the following way:

    0x01 – 0xEF: Soil water tension in -1[kPa]:

    0x01: 0 [kPa]

    0x02: -1 [kPa]

    0xEF: -238 [kPa]

    0xFD: soil water tension out of range

    0xFE: sensor error

    0xFF: no measurement, e.g. slot not used.

    Soil water tension calculation formula:

    https://www.irrometer.com/200ss.html

    Note that a fully wet sensor should measure 550 Ohms = 0 [kPa].

    High pressure 22 (0x16) Pressure is expressed in KPa as a 16-bit value in the following way:

    • 0x0000: Reserved
    • 0x0001: 0 KPa
    • 0x0002: 1 KPa

    • 0xFEFE: 65277 KPa
    • 0xFEFF: 65278 hPa    

     

    • 0xFF00 – 0xFFFC: for future use
    • 0xFFFD: measured pressure is out of range of sensor
    • 0xFFFE: sensor fail
    • 0xFFFF: no measurement, e.g. slot not used.

    Decoding example

    Advertising data:

    6c 02 02 05 09 01 00 00 2c 07 80 3c 00 01 02 06 45 c1 00 3d 0e 80 00 00 5d 5d

     

    Byte(s) Value Decoded
    1,2 6c 02 Manufacturing specific data
    3 02 Version 2
    4,5 05 09 Software version: 05.09
    6 01 Binary: 00000001

    Bit 0 = 1: Battery – ok

    Bit 1 = 0: Encryption disabled

    Bit 2 = 0: NV storage ok

    Bit 3 = 0: non binary sensor

    Bit 4 = 0: NB-IoT N/A

    Bit 5 =0: LTE-M N/A

    Bit 6-7: 0

    7,8,9,10 00 00 2c 07 Measurement counter value: 11271
    11,12 80 3c Binary: 1000000000111100

    Bit 0-14 (000000000111100): Measurement period: 60

    Bit 15 = 1:  Measurement period value in seconds

    13 00 Reserved (always 0)
    14 01 Slot 1: Temperature sensor
    15 02 Slot 2: Humidity sensor 
    16 06 Slot 3: VOC sensor 
    17,18 45 c1 Temperature value: 28.57 C

    Hex 45c1 = Dec 17857

    17857 / 100 -150 = 28.57

    19,20 00 3d Humidity value: 61 % RH

    Hec 003d = Dec 61

    21,22 0e 80 Binary: 00111010000000

    Bit 0-8 (010000000): 128 IAQ

    Bit 9,10 (Bin 11 = Dec 3): Sensor calibrated and returns accurate values

    Bit 11: Always set to 1

    Bit 12-15: Set to 0 – value ok

    23,24 00 00 No calibration date set
    25,26 5d 5d CRC16

        [socials goes here]

        Related products