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).
| Attribute | ID | Type | Access | Description |
|---|---|---|---|---|
| MeasuredValue | 0x0000 | I16 | Report | Current temperature × 100 |
| MinMeasuredValue | 0x0001 | I16 | Read | Minimum measurable |
| MaxMeasuredValue | 0x0002 | I16 | Read | Maximum measurable |
| Tolerance | 0x0003 | U16 | Read | Measurement 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).
| Attribute | ID | Type | Access | Description |
|---|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report | Current humidity × 100 |
| MinMeasuredValue | 0x0001 | U16 | Read | Minimum measurable |
| MaxMeasuredValue | 0x0002 | U16 | Read | Maximum measurable |
| Tolerance | 0x0003 | U16 | Read | Measurement 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.
| Attribute | ID | Type | Access | Description |
|---|---|---|---|---|
| MeasuredValue | 0x0000 | I16 | Report | Pressure in 0.1 kPa |
| MinMeasuredValue | 0x0001 | I16 | Read | Minimum measurable |
| MaxMeasuredValue | 0x0002 | I16 | Read | Maximum measurable |
| Tolerance | 0x0003 | U16 | Read | Measurement tolerance |
| ScaledValue | 0x0010 | I16 | Report | High-precision pressure |
| MinScaledValue | 0x0011 | I16 | Read | Minimum scaled |
| MaxScaledValue | 0x0012 | I16 | Read | Maximum scaled |
| ScaledTolerance | 0x0013 | U16 | Read | Scaled tolerance |
| Scale | 0x0014 | I8 | Read | 10^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.
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report |
| MinMeasuredValue | 0x0001 | U16 | Read |
| MaxMeasuredValue | 0x0002 | U16 | Read |
| Tolerance | 0x0003 | U16 | Read |
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.
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report |
| MinMeasuredValue | 0x0001 | U16 | Read |
| MaxMeasuredValue | 0x0002 | U16 | Read |
| Tolerance | 0x0003 | U16 | Read |
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::flow_measurement::FlowMeasurementCluster;
}
Occupancy Sensing (0x0406)
Binary occupancy detection with configurable sensor type.
| Attribute | ID | Type | Access | Description |
|---|---|---|---|---|
| Occupancy | 0x0000 | Bitmap8 | Report | Bit 0 = occupied |
| OccupancySensorType | 0x0001 | Enum8 | Read | 0=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).
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasurementType | 0x0000 | Bitmap32 | Read |
| RmsVoltage | 0x0505 | U16 | Report |
| RmsCurrent | 0x0508 | U16 | Report |
| ActivePower | 0x050B | I16 | Report |
| PowerFactor | 0x0510 | I8 | Read |
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::electrical::ElectricalMeasurementCluster;
}
PM2.5 Measurement (0x042A)
Particulate matter (PM2.5) concentration.
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report |
| MinMeasuredValue | 0x0001 | U16 | Read |
| MaxMeasuredValue | 0x0002 | U16 | Read |
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::pm25::Pm25Cluster;
}
Carbon Dioxide (0x040D)
CO₂ concentration measurement in PPM.
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report |
| MinMeasuredValue | 0x0001 | U16 | Read |
| MaxMeasuredValue | 0x0002 | U16 | Read |
#![allow(unused)]
fn main() {
use zigbee_zcl::clusters::carbon_dioxide::CarbonDioxideCluster;
}
Soil Moisture (0x0408)
Soil moisture level in 0.01% units.
| Attribute | ID | Type | Access |
|---|---|---|---|
| MeasuredValue | 0x0000 | U16 | Report |
| MinMeasuredValue | 0x0001 | U16 | Read |
| MaxMeasuredValue | 0x0002 | U16 | Read |
#![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