LevelControl Cluster
Cluster ID: 0x0008 |
Endpoint: Typically on Endpoint 1 (application endpoint)
LevelControl provides full control over a device's adjustable level -- the most typical use case is light dimming, but it also applies to fan speed, curtain position, or any device whose "degree" can be represented numerically. It defines two groups of commands: one group does not affect the OnOff state, while the other group coordinates with the OnOff Cluster's on/off state.
LevelControl is typically used together with the OnOff Cluster (0x0006).
Commands with the WithOnOff suffix (e.g. MoveToLevelWithOnOff) automatically turn off the light when level reaches 0 and turn it on when level is above 0.
Commands without the suffix only adjust the level without affecting the on/off state.
Commands
LevelControl provides two groups of commands: the basic group (0x00~0x03) and the WithOnOff group (0x04~0x07). Both groups share the same parameters; the difference is that the WithOnOff group coordinates with the OnOff Cluster's on/off state. There is also a frequency control command (0x08), available only when the device supports the Frequency feature.
| ID | Name | Description | OnOff Sync |
|---|---|---|---|
0x00 |
MoveToLevel | Move to a specified level | No |
0x01 |
Move | Continuously move level up/down | No |
0x02 |
Step | Adjust level by a step value | No |
0x03 |
Stop | Stop an ongoing level transition | No |
0x04 |
MoveToLevelWithOnOff | Move to a specified level (syncs on/off) | Yes |
0x05 |
MoveWithOnOff | Continuously move level (syncs on/off) | Yes |
0x06 |
StepWithOnOff | Adjust level by step (syncs on/off) | Yes |
0x07 |
StopWithOnOff | Stop transition (syncs on/off) | Yes |
0x08 |
MoveToClosestFrequency | Move to the closest supported frequency | No |
The TransitionTime parameter in all commands is in units of 1/10 second (0.1s).
For example, 10 means 1 second, and 50 means 5 seconds.
If 0xFFFF (65535) is passed, the device uses the value of the OnOffTransitionTime attribute as the default transition time.
MoveToLevel (0x00)
Smoothly transitions CurrentLevel from its current value to a specified target level. This is the most commonly used command -- it is what gets sent when the user releases the brightness slider in the app.
Does not affect the OnOff state; even if the target level is 0, it will not turn off the light.
| Parameter | Type | Description |
|---|---|---|
| Level | uint8 | Target level, range 0~254 |
| TransitionTime | uint16 / null | Transition time in 1/10 seconds. null uses OnOffTransitionTime |
| OptionsMask | bitmap8 | Options mask (see OptionsBitmap) |
| OptionsOverride | bitmap8 | Options override value |
Usage Scenarios & Parameters
Called when the user drags the brightness slider in the app. Before sending, read MinLevel (0x02) and MaxLevel (0x03) to determine the valid range and map the UI slider percentage to that range.
Move (0x01)
Continuously changes CurrentLevel up or down at a specified rate until it reaches MinLevel/MaxLevel or a Stop command is received.
Ideal for long-press dimming scenarios.
| Parameter | Type | Description |
|---|---|---|
| MoveMode | enum8 | Move direction: 0 = Up, 1 = Down (see MoveModeEnum) |
| Rate | uint8 / null | Units of change per second. null uses DefaultMoveRate |
| OptionsMask | bitmap8 | Options mask |
| OptionsOverride | bitmap8 | Options override value |
Usage Scenarios & Parameters
Triggered when the user long-presses a physical dimmer button. On press, send Move (specifying direction); on release, send Stop to halt the transition. Suited for continuous dimming via physical switches or remotes.
Step (0x02)
Adjusts CurrentLevel up or down by a specified step value. Ideal for short-press "one step brighter" or "one step dimmer" interactions.
| Parameter | Type | Description |
|---|---|---|
| StepMode | enum8 | Step direction: 0 = Up, 1 = Down (see StepModeEnum) |
| StepSize | uint8 | Step size (absolute value of change) |
| TransitionTime | uint16 / null | Transition time in 1/10 seconds. null uses OnOffTransitionTime |
| OptionsMask | bitmap8 | Options mask |
| OptionsOverride | bitmap8 | Options override value |
Usage Scenarios & Parameters
Used when the user short-presses a physical button or the +/- button in the app. Each press sends one Step command for incremental dimming. Typical step values are 25~50 (roughly 10%~20% brightness change).
Stop (0x03)
Stops an ongoing Move or Step transition. CurrentLevel remains at the value it held when the Stop command was received.
| Parameter | Type | Description |
|---|---|---|
| OptionsMask | bitmap8 | Options mask |
| OptionsOverride | bitmap8 | Options override value |
MoveToLevelWithOnOff (0x04)
Functions identically to MoveToLevel, except it also coordinates with the OnOff Cluster: the light automatically turns off (OnOff becomes Off) when the target level is 0, and turns on (OnOff becomes On) when the target level is above 0.
This is the preferred command for app dimming, ensuring brightness and on/off state are always consistent.
| Parameter | Type | Description |
|---|---|---|
| Level | uint8 | Target level, range 0~254 |
| TransitionTime | uint16 / null | Transition time in 1/10 seconds |
| OptionsMask | bitmap8 | Options mask |
| OptionsOverride | bitmap8 | Options override value |
Usage Scenarios & Parameters
The preferred command for app dimming. When the brightness slider is dragged to 0, the light turns off automatically; when dragged to any positive value, it turns on, keeping the UI state consistent with the actual device state.
MoveWithOnOff (0x05)
Same as Move, but coordinates with the OnOff state during the transition. Parameters are identical to Move.
StepWithOnOff (0x06)
Same as Step, but coordinates with the OnOff state during the step. Parameters are identical to Step.
StopWithOnOff (0x07)
Same as Stop, but coordinates with the OnOff state. Parameters are identical to Stop.
MoveToClosestFrequency (0x08)
Moves CurrentFrequency to the closest value supported by the device. Only available when the device supports the Frequency feature; rarely used in everyday lighting control development.
| Parameter | Type | Description |
|---|---|---|
| Frequency | uint16 | Target frequency value |
Attributes
LevelControl attributes are organized into four groups by function. Click an attribute ID in the summary table below to jump to its detailed description.
| ID | Name | Type | Group | Description |
|---|---|---|---|---|
0x00 |
CurrentLevel | uint8 / null | Current State | Current level value |
0x01 |
RemainingTime | uint16 | Current State | Transition remaining time |
0x02 |
MinLevel | uint8 | Current State | Minimum available level |
0x03 |
MaxLevel | uint8 | Current State | Maximum available level |
0x04 |
CurrentFrequency | uint16 | Frequency Control | Current frequency |
0x05 |
MinFrequency | uint16 | Frequency Control | Minimum frequency |
0x06 |
MaxFrequency | uint16 | Frequency Control | Maximum frequency |
0x0F |
Options | bitmap8 | Transition & OnOff Coordination | Command execution options |
0x10 |
OnOffTransitionTime | uint16 | Transition & OnOff Coordination | On/off transition time |
0x11 |
OnLevel | uint8 / null | Transition & OnOff Coordination | Target level when turning on |
0x12 |
OnTransitionTime | uint16 / null | Transition & OnOff Coordination | Turn-on transition time |
0x13 |
OffTransitionTime | uint16 / null | Transition & OnOff Coordination | Turn-off transition time |
0x14 |
DefaultMoveRate | uint8 / null | Transition & OnOff Coordination | Default move rate |
0x4000 |
StartUpCurrentLevel | uint8 / null | Startup Behavior | Power-on initial level |
Current State (0x00 – 0x03)
Describes the device's current level and allowed range. This is the most direct data source for displaying brightness status in the app.
| ID | Name | Type | Description |
|---|---|---|---|
0x00 |
CurrentLevel Current Level |
uint8 / null | The device's current level. Valid range is MinLevel~MaxLevel (typically 1~254). Nullable -- the device returns null when the current level is unknown |
0x01 |
RemainingTime Remaining Time |
uint16 | Remaining time of the current transition, in units of 0.1 second. 0 when no transition is in progress |
0x02 |
MinLevel Minimum Level |
uint8 | The minimum level supported by the device. Defaults to 1 with Lighting feature, 0 without |
0x03 |
MaxLevel Maximum Level |
uint8 | The maximum level supported by the device. Defaults to 254 (0xFE) |
Like DoorLock's LockState, CurrentLevel can be null.
This may occur when the device has just powered on, after a firmware upgrade, or during hardware anomalies.
Always handle null values when displaying brightness in the app -- show "Unknown" or use MinLevel as the default.
CurrentLevel ranges from MinLevel~MaxLevel (typically 1~254), not 0~100.
Conversion formula: percentage = (CurrentLevel - MinLevel) / (MaxLevel - MinLevel) * 100.
For example, with MinLevel=1, MaxLevel=254, CurrentLevel=127 is approximately 50% brightness.
Frequency Control (0x04 – 0x06)
Describes the device's frequency control capabilities. These attributes are only present when the device supports the Frequency feature (Feature Map Bit 2).
Frequency control attributes are rarely used in typical lighting development. They are mainly for special devices that require precise output frequency control (such as certain industrial lighting or signaling devices). The vast majority of smart lights only use the current state and transition-related attributes.
| ID | Name | Type | Description |
|---|---|---|---|
0x04 |
CurrentFrequency Current Frequency |
uint16 | The device's current output frequency |
0x05 |
MinFrequency Minimum Frequency |
uint16 | The minimum frequency supported by the device |
0x06 |
MaxFrequency Maximum Frequency |
uint16 | The maximum frequency supported by the device |
Transition & OnOff Coordination (0x0F – 0x14)
Controls the transition behavior of level changes and how the OnOff Cluster affects brightness when turning on/off. These attributes directly impact user experience -- whether the light snaps on/off or transitions smoothly.
| ID | Name | Type | Description |
|---|---|---|---|
0x0F |
Options Options |
bitmap8 | Global options for command execution. Read/Write (see OptionsBitmap below) |
0x10 |
OnOffTransitionTime On/Off Transition Time |
uint16 | Transition time for level change from MinLevel to MaxLevel (or reverse) when turning on/off, in units of 0.1 second. Defaults to 0 (instant switch). Read/Write |
0x11 |
OnLevel On Level |
uint8 / null | When the OnOff Cluster's On command is executed, the level is set to this value. null means restore the brightness from before the last turn-off. Range 1~254, Read/Write |
0x12 |
OnTransitionTime On Transition Time |
uint16 / null | Transition time when turning on via OnOff, in units of 0.1 second. null falls back to OnOffTransitionTime. Read/Write |
0x13 |
OffTransitionTime Off Transition Time |
uint16 / null | Transition time when turning off via OnOff, in units of 0.1 second. null falls back to OnOffTransitionTime. Read/Write |
0x14 |
DefaultMoveRate Default Move Rate |
uint8 / null | Default rate used when the Move command does not specify a Rate (units of change per second). null means the device decides. Read/Write |
OnLevel determines what brightness the light reaches when the user turns it on:
null(recommended default) -- remembers the brightness before the last turn-off, restoring it when turning back on. Most natural user experience- Specific value (e.g.
254) -- always turns on to this fixed level, ignoring the brightness from the last turn-off
Startup Behavior (0x4000)
Controls the initial brightness after the device powers on.
| ID | Name | Type | Description |
|---|---|---|---|
0x4000 |
StartUpCurrentLevel Startup Level |
uint8 / null | Initial value of CurrentLevel when the device powers on. Read/Write |
StartUpCurrentLevel Special Values
StartUpCurrentLevel only controls CurrentLevel, not the OnOff state.
If the user wants the light to turn on automatically after a power outage, the StartUpOnOff attribute in the OnOff Cluster must also be configured.
Setting only StartUpCurrentLevel without StartUpOnOff may result in the brightness being restored but the light remaining off.
Enums & Bitmaps
MoveModeEnum
The MoveMode parameter in the Move and MoveWithOnOff commands uses this enum to specify the direction of level change.
StepModeEnum
The StepMode parameter in the Step and StepWithOnOff commands uses this enum to specify the step direction.
OptionsBitmap
This bitmap is used by the Options attribute and the OptionsMask / OptionsOverride parameters in all commands.
It controls whether commands execute under specific conditions.
These two parameters are used to temporarily override the device's Options attribute. The calculation logic:
effectiveOptions = (Options AND NOT OptionsMask) OR (OptionsOverride AND OptionsMask)。
In simple terms: OptionsMask marks which bits to override, and OptionsOverride provides the override values.
Passing 0 for both uses the device's Options attribute directly.
Feature Map
LevelControl uses the Feature Map to declare the device's supported optional capabilities.
Most smart lights have a Feature Map of 0x03 (OnOff + Lighting), indicating support for both on/off coordination and lighting behavior.
After reading the Feature Map, you can determine which attributes and commands are available, avoiding errors from reading non-existent attributes.
Example Data
Read result of a typical dimmable light fixture's LevelControl Cluster:
{
// --- Current State ---
"0x0": 127, // CurrentLevel = 127 (approximately 50% brightness)
"0x1": 0, // RemainingTime = 0 (no transition in progress)
"0x2": 1, // MinLevel = 1 (minimum available level)
"0x3": 254, // MaxLevel = 254 (maximum available level)
// --- Transition & OnOff Coordination ---
"0xF": 0, // Options = 0 (no special options)
"0x10": 10, // OnOffTransitionTime = 10 (1-second transition)
"0x11": null, // OnLevel = null (restore previous brightness on turn-on)
"0x12": null, // OnTransitionTime = null (uses OnOffTransitionTime)
"0x13": null, // OffTransitionTime = null (uses OnOffTransitionTime)
"0x14": 50, // DefaultMoveRate = 50 (50 units of change per second)
// --- Startup Behavior ---
"0x4000": null // StartUpCurrentLevel = null (restore level before power loss)
}
Typical processing flow when displaying brightness in the app:
- Read
CurrentLevel (0x00), handle thenullcase - Read
MinLevel (0x02)andMaxLevel (0x03)to determine the slider range - Convert
CurrentLevelto a percentage:(CurrentLevel - MinLevel) / (MaxLevel - MinLevel) * 100 - If
RemainingTime (0x01)is greater than 0, a transition is in progress and the UI can show a transition animation
Common Scenarios
Scenario 1: App Dimming
- Read
MinLevel (0x02)andMaxLevel (0x03), map to slider 0%~100% - When the user drags the slider, convert the percentage to a target level value
- Send
MoveToLevelWithOnOff (0x04)(the WithOnOff variant is recommended to keep the on/off state consistent) - Subscribe to changes of
CurrentLevel (0x00)to update the UI in real time
Scenario 2: Memory Brightness On/Off
- Set
OnLevel (0x11)tonull-- lets the device remember the brightness before the last turn-off - User taps "Turn On" → OnOff Cluster sends On command → light automatically restores to the previous brightness
- User taps "Turn Off" → OnOff Cluster sends Off command → brightness gradually fades to 0
- Optional: set
OnTransitionTime (0x12)andOffTransitionTime (0x13)to control transition speed
Scenario 3: Power Restore Configuration
- Set
StartUpCurrentLevel (0x4000):null= restore level before power loss,0x00= minimum brightness, specific value = fixed brightness - Also set
StartUpOnOffin the OnOff Cluster to ensure the on/off state and brightness are correctly coordinated - Typical configuration:
StartUpCurrentLevel=null+StartUpOnOff=RestorePrevious→ fully restores the state before power loss
Scenario 4: Physical Button Dimming (Long Press + Short Press)
- Short press → send
StepWithOnOff (0x06), each press changes by a fixed step value (e.g. 25) - Long press down → send
MoveWithOnOff (0x05), continuously changes - Long press release → send
StopWithOnOff (0x07), stops at the current brightness