Zum Inhalt

Ruuvi RuuviTag — BLE Advertising Data Format

Scope

This document describes the BLE advertising data format used by the RuuviTag wireless environmental sensor.

RuuviTag broadcasts sensor data in BLE advertising packets using Manufacturer Specific Data (AD Type = 0xFF). The current main format for RuuviTag is Data Format 5 / RAWv2.

Product summary

Item Value
Product RuuviTag
Sensor functions Temperature, humidity, air pressure, motion / acceleration, battery
Main BLE transport BLE advertising broadcast
Main AD Type 0xFF Manufacturer Specific Data
Ruuvi Manufacturer ID logical 0x0499
Raw manufacturer bytes 99 04
Current main data format Format 0x05 / RAWv2
RAWv2 payload length 24 bytes after manufacturer ID
Multi-byte byte order MSB first / big endian

Supported Ruuvi advertisement formats

Ruuvi documentation lists several data formats. For RuuviTag integration, the relevant ones are:

Format Name Lifecycle Notes
0x03 RAWv1 Deprecated Older RuuviTag firmware; no MAC address in payload
0x04 URL Obsolete Eddystone URL based format, older hardware/firmware
0x05 RAWv2 In production Current primary RuuviTag sensor format
0xC5 Cut-RAWv2 Beta Similar to RAWv2, acceleration removed

For a new gateway/parser, implement Format 5 / RAWv2 first.

BLE advertisement overview

A typical RuuviTag RAWv2 advertisement has this structure:

02 01 06
1B FF 99 04 <24-byte RAWv2 payload>

Meaning:

Part Meaning
02 01 06 Flags
1B AD length = 27 bytes following: AD type + manufacturer ID + payload
FF Manufacturer Specific Data
99 04 Ruuvi manufacturer ID 0x0499, transmitted little-endian in the BLE AD structure
<payload> Ruuvi payload; first payload byte is data format, e.g. 0x05

RAWv2 manufacturer-specific payload

If the parser receives only the payload after Ruuvi manufacturer bytes 99 04, use this table.

Payload offset Field Length Decode Unit / description
0 Data Format 1 0x05 RAWv2
1-2 Temperature 2 int16_be * 0.005 °C
3-4 Humidity 2 uint16_be * 0.0025 %RH
5-6 Pressure 2 uint16_be + 50000 Pa
7-8 Acceleration X 2 int16_be mg
9-10 Acceleration Y 2 int16_be mg
11-12 Acceleration Z 2 int16_be mg
13-14 Power Info 2 bitfield battery + TX power
15 Movement Counter 1 uint8_t incremented on motion interrupt
16-17 Measurement Sequence 2 uint16_be measurement sequence number
18-23 MAC Address 6 raw MAC bytes 48-bit MAC address

Power Info bitfield

Power Info is a 16-bit unsigned big-endian field.

Bits Field Decode
15-5 Battery voltage above 1.6 V battery_mv = ((power_info >> 5) & 0x07FF) + 1600
4-0 TX power above -40 dBm in 2 dBm steps tx_power_dbm = (power_info & 0x1F) * 2 - 40

Supported ranges:

Field Range
Battery voltage 1600 mV to 3646 mV
TX power -40 dBm to +20 dBm

Decoder formulas

static int16_t be_i16(const uint8_t *p)
{
    return (int16_t)(((uint16_t)p[0] << 8) | p[1]);
}

static uint16_t be_u16(const uint8_t *p)
{
    return ((uint16_t)p[0] << 8) | p[1];
}

uint8_t format = p[0]; // must be 0x05

float temperature_c = be_i16(&p[1]) * 0.005f;
float humidity_rh   = be_u16(&p[3]) * 0.0025f;
uint32_t pressure_pa = (uint32_t)be_u16(&p[5]) + 50000u;

int16_t acc_x_mg = be_i16(&p[7]);
int16_t acc_y_mg = be_i16(&p[9]);
int16_t acc_z_mg = be_i16(&p[11]);

uint16_t power_info = be_u16(&p[13]);
uint16_t battery_mv = ((power_info >> 5) & 0x07FFu) + 1600u;
int8_t tx_power_dbm = (int8_t)((power_info & 0x1Fu) * 2 - 40);

uint8_t movement_counter = p[15];
uint16_t measurement_sequence = be_u16(&p[16]);

Invalid / not available values

Ruuvi uses special values for missing data:

Field type Invalid value
Signed integer field smallest representable value, e.g. 0x8000 for int16
Unsigned integer field largest representable value, e.g. 0xFFFF for uint16
MAC address all bits set, FF:FF:FF:FF:FF:FF

Parser identification

Recommended detection:

Find AD Type 0xFF
AND manufacturer bytes == 99 04
AND first Ruuvi payload byte == 0x05
AND payload has at least 24 bytes

Then parse with RAWv2 offsets.

Do not identify Ruuvi data only by BLE address or device name. RuuviTag data is designed to be parsed from Manufacturer Specific Data.

Notes on older formats

Format 3 / RAWv1

RAWv1 is deprecated but may still appear in older deployed RuuviTags. It contains humidity, temperature, pressure, acceleration and battery voltage, but not the MAC address in the payload.

Format 4 / URL

Format 4 is obsolete and was packed inside Eddystone URL. It is not recommended for new parser work.

Format C5 / Cut-RAWv2

Format C5 is a beta format related to RuuviTag/Ruuvi Gateway. It resembles RAWv2 but omits acceleration to make space for other information.

Example capture template

Device: RuuviTag
MAC:
RSSI:
ADV raw:
SCAN_RSP raw:
Decoded:
  temperature_c:
  humidity_rh:
  pressure_pa:
  acc_x_mg:
  acc_y_mg:
  acc_z_mg:
  battery_mv:
  tx_power_dbm:
  movement_counter:
  measurement_sequence:
  mac_payload:

Sources

  • Ruuvi Bluetooth Advertisements documentation: https://docs.ruuvi.com/communication/bluetooth-advertisements
  • Ruuvi Data Format 5 / RAWv2: https://docs.ruuvi.com/communication/bluetooth-advertisements/data-format-5-rawv2
  • Ruuvi Data Format 3 / RAWv1: https://docs.ruuvi.com/communication/bluetooth-advertisements/data-format-3-rawv1
  • Ruuvi Data Format 4 / URL: https://docs.ruuvi.com/communication/bluetooth-advertisements/data-format-4-url
  • RuuviTag product page: https://ruuvi.com/ruuvitag/