| Crates.io | ruuvi-decoders |
| lib.rs | ruuvi-decoders |
| version | 1.0.0 |
| created_at | 2025-10-13 14:45:01.210388+00 |
| updated_at | 2025-11-02 21:24:36.089018+00 |
| description | Ruuvi BLE advertisement decoders for Data Formats v5, v6, and E1 |
| homepage | |
| repository | https://github.com/viljami/ruuvi-decoders |
| max_upload_size | |
| id | 1880615 |
| size | 105,253 |
High-performance Rust library for decoding Ruuvi sensor BLE advertisements. Supports all major Ruuvi data formats with comprehensive validation and type safety.
| Format | Status | Description |
|---|---|---|
| v5 (RAWv2) | โ Complete | Temperature, humidity, pressure, acceleration, battery |
| v6 | โ Complete | Adds PM2.5, CO2, VOC, NOX, luminosity |
| E1 | โ Complete | Extended format with PM1.0/2.5/4.0/10.0 |
Add this to your Cargo.toml:
[dependencies]
ruuvi-decoders = "0.2"
use ruuvi_decoders::{decode, extract_ruuvi_from_ble};
// From a full BLE advertisement
let ble_data = "02010603031691FF990405159F7C025A8BC4A53C00FB00000000E7FEE7FE00E7FE";
let ruuvi_hex = extract_ruuvi_from_ble(ble_data).unwrap();
let decoded = decode(&ruuvi_hex).unwrap();
match decoded {
ruuvi_decoders::RuuviData::V5(data) => {
println!("Temperature: {}ยฐC", data.temperature.unwrap());
println!("Humidity: {}%", data.humidity.unwrap());
println!("Pressure: {} Pa", data.pressure.unwrap());
println!("MAC: {}", data.mac_address);
},
// Handle v6 and E1 formats...
_ => println!("Other format"),
}
use ruuvi_decoders::decode;
// Direct Ruuvi payload (without BLE wrapper)
let hex_data = "0512FC5394C37C0004FFFC040CAC364200CDCBB8334C884F";
let result = decode(hex_data).unwrap();
if let ruuvi_decoders::RuuviData::V5(data) = result {
assert_eq!(data.temperature, Some(24.3));
assert_eq!(data.humidity, Some(53.49));
assert_eq!(data.pressure, Some(100044.0));
}
The most common format used by RuuviTag sensors:
use ruuvi_decoders::v5::decode;
let bytes = hex::decode("0512FC5394C37C0004FFFC040CAC364200CDCBB8334C884F").unwrap();
let data = decode(&bytes).unwrap();
println!("Sensor Data:");
println!(" MAC: {}", data.mac_address);
println!(" Temperature: {:.2}ยฐC", data.temperature.unwrap_or(0.0));
println!(" Humidity: {:.2}%", data.humidity.unwrap_or(0.0));
println!(" Pressure: {:.0} Pa", data.pressure.unwrap_or(0.0));
println!(" Battery: {} mV", data.battery_voltage.unwrap_or(0));
println!(" TX Power: {} dBm", data.tx_power.unwrap_or(0));
The library provides comprehensive error handling:
use ruuvi_decoders::{decode, DecodeError};
match decode("invalid_hex") {
Ok(data) => println!("Decoded: {:?}", data),
Err(DecodeError::InvalidHex(msg)) => eprintln!("Invalid hex: {}", msg),
Err(DecodeError::UnsupportedFormat(format)) => {
eprintln!("Unsupported format: 0x{:02X}", format)
},
Err(DecodeError::InvalidLength(msg)) => eprintln!("Wrong length: {}", msg),
Err(e) => eprintln!("Other error: {}", e),
}
All data structures support serialization:
use ruuvi_decoders::decode;
let hex_data = "0512FC5394C37C0004FFFC040CAC364200CDCBB8334C884F";
let decoded = decode(hex_data).unwrap();
// Serialize to JSON
let json = serde_json::to_string(&decoded).unwrap();
println!("JSON: {}", json);
// Deserialize from JSON
let restored: ruuvi_decoders::RuuviData = serde_json::from_str(&json).unwrap();
The library properly handles invalid/unavailable sensor readings:
use ruuvi_decoders::v5::decode;
// Test with invalid values (from official test vectors)
let invalid_data = hex::decode("058000FFFFFFFF800080008000FFFFFFFFFFFFFFFFFFFFFF").unwrap();
let result = decode(&invalid_data).unwrap();
// All sensor readings will be None for invalid data
assert_eq!(result.temperature, None);
assert_eq!(result.humidity, None);
assert_eq!(result.pressure, None);
assert_eq!(result.mac_address, "invalid");
Ruuvi Decoders is optimized for high-throughput scenarios:
Run benchmarks:
cargo bench
See the examples/ directory for complete examples:
basic_usage.rs - Simple decodingble_scanner.rs - BLE advertisement parsingerror_handling.rs - Comprehensive error handlingRun an example:
cargo run --example basic_usage
This library implements the official Ruuvi specifications:
All test vectors from the official documentation are included and pass.
git clone https://github.com/ruuvi/ruuvi-decoders
cd ruuvi-decoders
cargo build
# Run all tests
cargo test
Contributions are welcome! Please:
This project is licensed under the MIT License - see the LICENSE file for details.