Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Measurement & Sensing Clusters

Measurement clusters are server-side, read-only clusters used by sensors. They share a common pattern: a MeasuredValue attribute (reportable) plus MinMeasuredValue and MaxMeasuredValue bounds. The application updates the measured value via a setter method; the runtime handles attribute reads and reporting.

None of these clusters define cluster-specific commands — handle_command() always returns UnsupClusterCommand.


Temperature Measurement (0x0402)

Values in 0.01°C units (e.g. 2250 = 22.50°C).

AttributeIDTypeAccessDescription
MeasuredValue0x0000I16ReportCurrent temperature × 100
MinMeasuredValue0x0001I16ReadMinimum measurable
MaxMeasuredValue0x0002I16ReadMaximum measurable
Tolerance0x0003U16ReadMeasurement tolerance
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::temperature::TemperatureCluster;

let mut temp = TemperatureCluster::new(-4000, 8500); // -40°C to 85°C
temp.set_temperature(2250); // 22.50°C
}

Relative Humidity (0x0405)

Values in 0.01% RH units (e.g. 5000 = 50.00% RH).

AttributeIDTypeAccessDescription
MeasuredValue0x0000U16ReportCurrent humidity × 100
MinMeasuredValue0x0001U16ReadMinimum measurable
MaxMeasuredValue0x0002U16ReadMaximum measurable
Tolerance0x0003U16ReadMeasurement tolerance
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::humidity::HumidityCluster;

let mut hum = HumidityCluster::new(0, 10000); // 0–100%
hum.set_humidity(5000); // 50.00% RH
}

Pressure Measurement (0x0403)

Values in 0.1 kPa units (e.g. 10132 = 1013.2 hPa). Also supports extended precision with scaled attributes.

AttributeIDTypeAccessDescription
MeasuredValue0x0000I16ReportPressure in 0.1 kPa
MinMeasuredValue0x0001I16ReadMinimum measurable
MaxMeasuredValue0x0002I16ReadMaximum measurable
Tolerance0x0003U16ReadMeasurement tolerance
ScaledValue0x0010I16ReportHigh-precision pressure
MinScaledValue0x0011I16ReadMinimum scaled
MaxScaledValue0x0012I16ReadMaximum scaled
ScaledTolerance0x0013U16ReadScaled tolerance
Scale0x0014I8Read10^Scale multiplier
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::pressure::PressureCluster;

let mut press = PressureCluster::new(3000, 11000); // 300–1100 hPa
press.set_pressure(10132); // 1013.2 hPa
}

Illuminance Measurement (0x0400)

Measures ambient light level.

AttributeIDTypeAccess
MeasuredValue0x0000U16Report
MinMeasuredValue0x0001U16Read
MaxMeasuredValue0x0002U16Read
Tolerance0x0003U16Read

Values use a logarithmic formula: MeasuredValue = 10,000 × log10(lux) + 1.

#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::illuminance::IlluminanceCluster;
}

Flow Measurement (0x0404)

Measures flow rate in 0.1 m³/h units.

AttributeIDTypeAccess
MeasuredValue0x0000U16Report
MinMeasuredValue0x0001U16Read
MaxMeasuredValue0x0002U16Read
Tolerance0x0003U16Read
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::flow_measurement::FlowMeasurementCluster;
}

Occupancy Sensing (0x0406)

Binary occupancy detection with configurable sensor type.

AttributeIDTypeAccessDescription
Occupancy0x0000Bitmap8ReportBit 0 = occupied
OccupancySensorType0x0001Enum8Read0=PIR, 1=Ultrasonic, 2=PIR+US
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::occupancy::OccupancyCluster;
}

Electrical Measurement (0x0B04)

Real-time electrical measurements (voltage, current, power, power factor).

AttributeIDTypeAccess
MeasurementType0x0000Bitmap32Read
RmsVoltage0x0505U16Report
RmsCurrent0x0508U16Report
ActivePower0x050BI16Report
PowerFactor0x0510I8Read
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::electrical::ElectricalMeasurementCluster;
}

PM2.5 Measurement (0x042A)

Particulate matter (PM2.5) concentration.

AttributeIDTypeAccess
MeasuredValue0x0000U16Report
MinMeasuredValue0x0001U16Read
MaxMeasuredValue0x0002U16Read
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::pm25::Pm25Cluster;
}

Carbon Dioxide (0x040D)

CO₂ concentration measurement in PPM.

AttributeIDTypeAccess
MeasuredValue0x0000U16Report
MinMeasuredValue0x0001U16Read
MaxMeasuredValue0x0002U16Read
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::carbon_dioxide::CarbonDioxideCluster;
}

Soil Moisture (0x0408)

Soil moisture level in 0.01% units.

AttributeIDTypeAccess
MeasuredValue0x0000U16Report
MinMeasuredValue0x0001U16Read
MaxMeasuredValue0x0002U16Read
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::soil_moisture::SoilMoistureCluster;
}

Common Sensor Pattern

All measurement clusters follow the same usage pattern:

#![allow(unused)]
fn main() {
// 1. Create with min/max bounds
let mut sensor = TemperatureCluster::new(-4000, 8500);

// 2. Register on an endpoint via the builder
builder.add_cluster(ClusterId::TEMPERATURE, sensor);

// 3. In your sensor read callback, update the value:
sensor.set_temperature(read_adc_temperature());

// 4. The runtime handles:
//    - Read Attributes responses
//    - Attribute reporting (when configured)
//    - Discover Attributes responses
}

Reporting Configuration Example

A coordinator typically configures measurement clusters to report on change:

Configure Reporting for TemperatureMeasurement (0x0402):
  Attribute: MeasuredValue (0x0000)
  Type: I16
  Min Interval: 30 seconds
  Max Interval: 300 seconds
  Reportable Change: 50 (= 0.50°C)

The ReportingEngine tracks the last reported value and sends a new report when:

  • The value changes by more than 0.50°C and at least 30 seconds have passed, or
  • 300 seconds have passed regardless of change