Light control
Controls one light: a Material switch, a brightness slider, and a color picker, any of which can be hidden. Reads the light’s level, state, and color from its attributes and writes changes back to those same attributes, or sends them as one-way RPC commands. Dragging the slider sends one command, not one per step. Range, units, color format, presets, and the accent color are settings. Point one card at each light.
Who it’s for
Dashboard authors who need one light on one card ask “how do I give someone a switch, a brightness slider and a color picker for a single light, without wiring three separate widgets together?” This card answers that directly: one card, one device, and any of the three controls can be turned off if the light doesn’t have that capability.
What it does
Out of the box the card is a full light control: a switch, a 0–100%
brightness slider and a color picker, sending RPC commands
setBrightness, setState and setColor. Hide any of the three for a
plain dimmer, a plain switch, or a switch-and-color card with no slider.
- Switch, slider and color, each independently hideable — a card can be as simple or as complete as the light needs
- One command per gesture — dragging the slider across many levels sends the level you settle on, not every level crossed on the way
- Always reads the light’s actual state, even when writes go out as RPC commands — level, on/off state and color come from the device’s attributes on load and on every poll, regardless of how changes are sent
- The slider locks while the light is off, so a level can’t be set on a dark lamp
- Optional queueing for an offline device, with retries, when writes go out as RPC
- Accent color follows the ThingsBoard theme unless you override it
- Writes either one-way RPC commands or device attributes; it does not wait for a device reply, so what actually happened is best confirmed with a feedback key elsewhere or a separate alarm
How to set up
Data keys
This is a control widget: it takes no data keys. Choose a Target device in the widget configuration — everything the card reads and writes goes to that one device, so add one card per light.
| Attribute | Scope | Operation | Description |
|---|---|---|---|
Level attribute name (brightness by default) | Shared or Server | Read + Write | Always read on load and on every poll, regardless of What a change does — also written here when that setting is Write an attribute |
’On/off’ state attribute name (state by default) | Same scope as above | Read + Write | Always read, the same as the level. Accepts true/false, 1/0, or the strings "true", "on", "1" when reading |
Color attribute name (color by default) | Same scope as above | Read + Write | Read and written only while Show the color row is on; understood as #RRGGBB, #RGB, "r,g,b", "rgb(r,g,b)" or an {r,g,b} object |
| Method | Direction | Parameters | Sent when |
|---|---|---|---|
RPC method for the brigtness (setBrightness by default) | One-way | An object (default parameter name value), the bare number, or whatever a payload function of yours returns | The slider settles — once per gesture, after the drag-settle delay below |
RPC method for the light switch (setState by default) | One-way | true / false | The switch is used — sent immediately, with no delay |
RPC method for color change (setColor by default) | One-way | The color in the chosen format | A color is picked — sent immediately, with no delay |
Reading always goes through the three attributes above, no matter what What a change does is set to — so even in RPC mode, keep those attributes updated on the device for the card to show the light’s real state on load and on every poll. Writing follows What a change does: RPC commands, or the same attributes.
What the device receives picks the parameter shape for all three RPC
commands: an object like {"value": 60} with a parameter name you set,
the number alone, or a custom Payload function(value). The function
receives one argument, value — the level as a number, the switch as a
boolean, the color as a string or object; its type tells you which
command is being built:
if (typeof value === 'boolean') { return { on: value }; }if (typeof value === 'string') { return { rgb: value }; }return { level: value, fade: 500 };If the function returns nothing or throws, the change counts as failed: nothing is sent, and the device name turns red until a later change succeeds. A function that will not compile is caught when the card loads rather than on first use.
A one-way command nobody answers is not an error, so a device with no matching RPC handler will appear to accept changes and do nothing. If your lights work through shared attributes, switch What a change does over.
Delivery
| Setting | Default | Effect |
|---|---|---|
| What a change does | Send a one-way RPC command | RPC command, or attribute write, for the level, switch and color |
| Request timeout (ms) | 5000 | How long an RPC command waits for the platform to accept it. Between 100 ms and two minutes. RPC mode only |
| Queue the command for an offline device | Off | Uses the platform’s persistent RPC, so a sleeping device gets the change once it wakes. RPC mode only |
| Retries | 0 | Up to ten. Shown only when the command is queued |
| Timeout (ms) | 350 | Despite the label, this isn’t the request timeout above — it’s the delay after the slider stops moving before the level is sent. Applies to the slider only; the switch and the color picker always send immediately. Set it to 0 to send every step |
| Attribute scope | Shared | The one scope read and written in both directions. Shared is what a device subscribes to; Server keeps the value on the platform for a rule chain to act on. Client scope isn’t offered — only the device itself can write there |
| Re-read the device every (s) | 0 | 0 reads once on load. Raise it if a scene, a rule chain or a wall switch can move the same light. Polling pauses while the slider is being dragged |
| Read only | Off | Shows the light’s state, level and color but refuses all input. Nothing is ever sent |
Range
| Setting | Default | Effect |
|---|---|---|
| Lowest level | 0 | Start of the slider |
| Highest level | 100 | End of the slider |
| Step between levels | 1 | Spacing the slider snaps to — also how far one arrow key moves |
| Lock the slider while the light is off | On | Stops the slider accepting drags while the switch reads off, so a level can’t be set on a dark lamp. Ignored when the switch is hidden, since nothing on the card could turn the light back on |
Color
| Setting | Default | Effect |
|---|---|---|
| Show the color row | On | Off, the color attribute stops being read or written entirely, and the RPC color command is never sent |
| Color format | Hex string | The shape written for the color attribute and sent as the RPC parameter — hex, an {r,g,b} object, or a comma-separated string. All four read formats are still accepted regardless |
How to customize
Visibility & layout
- To hide the switch — turn off Show the ‘On/off’ switch; the state attribute is still read, just not shown or switchable here.
- To hide the slider for a switch-and-color card — turn off Show the level slider.
- To move the color control below the slider instead of the top row — set Color control position; worth it once the presets are shown and there are several.
- To show the value in a floating bubble while dragging — turn on Show the value in a bubble while dragging; it needs room beside the slider and is drawn outside the widget on a small card, which is why it’s off by default.
- To show the level as text next to the slider — turn on Display
current value; edit Brigtness unit to change or remove the
%.
Color picker
- To offer only a fixed list of colors instead of the full picker — turn off Allow any color.
- To change that fixed list — edit Preset colors; comma-separated,
hex,
#RGB,"r,g,b"andrgb(r,g,b)are all accepted. - To change the color shown before the device has reported one — set Default color.
Labels & fonts
- To change the name shown on the card — edit Name shown on the card; empty uses the device’s label, then its name.
- To match your dashboard’s fonts — set Label font and, when Display current value is on, Current value font.
- To recolor the name, the accent, or a failed-change indicator — set Label color, Accent — switch and slider, and Error color (the name stays this color until a change succeeds).
The card draws no title of its own — only the device name. The widget’s own Appearance tab still controls the title, background, padding and drop shadow; the title and the shadow ship off by default for this widget.
What the card shows while a change is in flight
The switch, slider and swatch move to the value you chose as soon as the gesture settles, not once the device confirms — so the card can be ahead of the light for as long as the request takes. A failed change is reported and turns the device name red rather than being dropped silently.
If the device has never reported its on/off state, the switch starts on and the slider stays usable. Treating an unknown state as off would lock a card that may be perfectly healthy.
Tips
- Keep every attribute the light actually reports up to date, even in RPC mode — reading always goes through the three attributes, so a light that only answers RPC and never updates its attributes shows a card that’s permanently out of sync.
- A device that’s often offline is a better fit for Write an attribute than RPC — the attribute waits for it, and nothing has to be queued.
- The Timeout (ms) field under Command is the drag-settle delay, not a request timeout — that’s the separate Request timeout (ms) setting above it.
- Two color swatches and no slider makes a simple two-color night-light control: hide the slider and turn off Allow any color.
Share Your Widget with the Community
Built a custom widget? Export it as a JSON from ThingsBoard and publish it to the IoT Hub through a simple 4-step wizard (Upload, Listing, Readme, Review & Submit). Share it with thousands of ThingsBoard developers worldwide and get featured in the catalog.