CarbonMonoxideConcentrationMeasurement Cluster
Cluster ID: 0x040C |
Endpoint: Typically on Endpoint 1 (application endpoint)
This Cluster reports the concentration of carbon monoxide (CO) in the air and belongs to the Matter Concentration Measurement family. It shares the same attribute structure, Feature bitmap, and enum definitions with other concentration measurement Clusters such as CO2 and PM2.5 — only the measurement target and safety thresholds differ.
Carbon monoxide poisoning is one of the leading causes of accidental death in homes. CO sensor data must be transmitted reliably with timely alerts. Apps must handle CO readings with extreme care:
- Do not over-smooth or delay CO readings — this can mask sudden spikes
- When LevelValue jumps to
Warningor above, push a notification immediately - This Cluster is typically used alongside SmokeCOAlarm (0x005C) — SmokeCOAlarm handles local audible/visual alarms, while this Cluster provides precise ppm values for remote monitoring and trend analysis
Feature Bitmap
Concentration measurement Clusters share the same set of Feature definitions. Devices declare their supported capabilities via FeatureMap (0xFFFC).
Features determine which attributes are available — always check before reading.
| Bit | Abbreviation | Name | Description |
|---|---|---|---|
| 0 | MEA | NumericMeasurement | Supports precise numeric measurement (MeasuredValue / Min / Max) |
| 1 | LEV | LevelIndication | Supports level indication (LevelValue: Low / Medium / High / Critical) |
| 2 | MED | MediumLevel | Extension of LEV — LevelValue can report the Medium level |
| 3 | CRI | CriticalLevel | Extension of LEV — LevelValue can report the Critical level |
| 4 | PEA | PeakMeasurement | Extension of MEA — records peak value (PeakMeasuredValue) |
| 5 | AVG | AverageMeasurement | Extension of MEA — records average value within a time window |
Most CO sensors support at least MEA + LEV (numeric value + level).
Higher-safety-rated devices add CRI (to distinguish critical levels) and PEA (to record peak values for post-incident analysis).
Attribute Overview
All attributes are read-only. The App retrieves data via Read / Subscribe.
| ID | Name | Type | Required Feature | Description |
|---|---|---|---|---|
0x0000 |
MeasuredValue | float (nullable) | MEA | Current CO concentration (unit per MeasurementUnit); null means invalid |
0x0001 |
MinMeasuredValue | float (nullable) | MEA | Minimum value the sensor can measure |
0x0002 |
MaxMeasuredValue | float (nullable) | MEA | Maximum value the sensor can measure (full-scale range) |
0x0003 |
PeakMeasuredValue | float (nullable) | PEA | Peak value within the time window |
0x0004 |
PeakMeasuredValueWindow | uint32 | PEA | Time window for peak measurement (seconds) |
0x0005 |
AverageMeasuredValue | float (nullable) | AVG | Average value within the time window |
0x0006 |
AverageMeasuredValueWindow | uint32 | AVG | Time window for average measurement (seconds) |
0x0007 |
Uncertainty | float | MEA | Measurement uncertainty (± range) |
0x0008 |
MeasurementUnit | enum8 | MEA | Measurement unit (PPM / PPB / ...) |
0x0009 |
MeasurementMedium | enum8 | — | Measurement medium (Air / Water / Soil) |
0x000A |
LevelValue | enum8 | LEV | Current concentration level (Low / Medium / High / Critical) |
Key Enums
The following enums are shared across all concentration measurement Clusters. Only the two most commonly used in CO scenarios are listed here.
LevelValueEnum (Concentration Level)
MeasurementUnitEnum (Measurement Unit)
CO Safety Threshold Reference
The following thresholds are derived from WHO and UL 2034 standards, provided as a reference for App alarm strategy design. The actual LevelValue classification on a device is set by the manufacturer and may not align exactly with this table.
| Concentration Range | Level | Description | Recommended Action |
|---|---|---|---|
< 9 ppm |
Normal | Good indoor air quality | No action needed |
9 ~ 35 ppm |
Attention Needed | Mildly elevated; possible gas leak or poor ventilation | Open windows for ventilation; check gas appliances |
36 ~ 70 ppm |
Warning | Prolonged exposure may cause headache and dizziness | Ventilate immediately; shut off potential CO sources |
71 ~ 150 ppm |
Dangerous | Poisoning symptoms can appear within a short time | Evacuate the room; call emergency services |
> 150 ppm |
Lethal | Can cause loss of consciousness or death within minutes | Evacuate the building immediately; call emergency services |
Sensitivity to CO varies significantly across populations (elderly, children, pregnant women, patients with cardiopulmonary conditions).
Apps should not rely solely on MeasuredValue for safety decisions — use the device-reported LevelValue as the authority,
and prioritize the alarm state from the SmokeCOAlarm Cluster.
Integration with SmokeCOAlarm
In real products, CO sensor devices typically implement two Clusters simultaneously:
- SmokeCOAlarm (0x005C) — handles local audible/visual alarms and device interlock, providing boolean-style states such as
COState(Normal / Warning / Critical) - CarbonMonoxideConcentrationMeasurement (0x040C) — provides precise ppm values, supporting trend analysis and remote monitoring
The division of responsibility: SmokeCOAlarm determines "whether to alarm," while this Cluster reports "the exact ppm reading." App alarm logic should primarily follow SmokeCOAlarm's state, with this Cluster's values displayed as supplementary information.
Example Data
Reading all attributes from a CO sensor device (FeatureMap = MEA + LEV + AVG):
{
// --- Concentration Measurements ---
"0x0000": 3.2, // MeasuredValue = 3.2 ppm (current CO concentration)
"0x0001": 0.0, // MinMeasuredValue = 0 ppm
"0x0002": 1000.0, // MaxMeasuredValue = 1000 ppm (sensor full-scale range)
"0x0003": null, // PeakMeasuredValue = null (PEA Feature not enabled)
"0x0004": null, // PeakMeasuredValueWindow (not enabled)
"0x0005": 2.8, // AverageMeasuredValue = 2.8 ppm
"0x0006": 3600, // AverageMeasuredValueWindow = 3600 seconds (1-hour average)
// --- Uncertainty ---
"0x0007": 1.5, // Uncertainty = ±1.5 ppm
// --- Unit and Medium ---
"0x0008": 0, // MeasurementUnit = PPM
"0x0009": 0, // MeasurementMedium = Air
// --- Level Indication ---
"0x000A": 0 // LevelValue = Low (Normal)
}
Subscribing to CO concentration and level changes (recommended min interval 10 seconds, max interval 60 seconds):
{
"subscribeRequests": [{
"attributePath": {
"endpointId": 1,
"clusterId": "0x040C",
"attributeId": "0x0000" // MeasuredValue
},
"minInterval": 10,
"maxInterval": 60
}, {
"attributePath": {
"endpointId": 1,
"clusterId": "0x040C",
"attributeId": "0x000A" // LevelValue
},
"minInterval": 10,
"maxInterval": 60
}]
}
Usage Scenarios
Scenario 1: Garage Ventilation Interlock
Garages are high-risk areas for CO buildup (idling vehicles, fuel-burning equipment). A typical approach:
- Subscribe to
MeasuredValue (0x0000)at 10–30 second intervals - When concentration exceeds 9 ppm, trigger an automation rule to start the exhaust fan (OnOff Cluster)
- When concentration exceeds 35 ppm, push a mobile notification reminding the user to check if a vehicle is running
- When concentration drops below 5 ppm and stays there for 5 minutes, turn off the exhaust fan
The drop-off threshold (5 ppm) being lower than the activation threshold (9 ppm) prevents frequent fan cycling — this is a classic hysteresis control strategy.
Scenario 2: Kitchen Gas Safety
Incomplete combustion from gas stoves produces CO. In a kitchen scenario:
- Subscribe to
LevelValue (0x000A)and watch for level transitions - When LevelValue jumps to
Medium (2): push a notification "Kitchen CO elevated — check gas stove" - When LevelValue jumps to
High (3): trigger emergency automation — shut off the smart gas valve, turn on range hood/exhaust fan, activate whole-home alarm - Simultaneously check SmokeCOAlarm's
COStateto confirm whether the local alarm has been triggered
Note: Brief CO spikes during cooking are normal (especially stir-frying and grilling).
Use AverageMeasuredValue to distinguish between sustained leaks and transient fluctuations to avoid false alarms.
Developer Tips
- Read FeatureMap first — not all CO sensors support ppm values; budget devices may only have LEV (level) without MEA (numeric value)
- Subscribe over polling — CO concentration changes require timely response; use Subscribe instead of periodic Read
- Handle null — a null MeasuredValue means the sensor reading is invalid (warming up, fault, etc.); the UI should display "Sensor initializing" rather than 0
- Check the unit — although the vast majority of CO sensors use PPM, always check MeasurementUnit to avoid displaying PPB values as PPM
- This Cluster has no commands — it is a purely read-only sensor data report with no Client-to-Server commands