Skip to content
Stand with Ukraine flag

Step control

  • Widget
  • 57 installs
  • v1.1.0
  • Aug 5, 2026
  • MIT license
  • v4.2+
Step control

A control for a value that moves in steps: a column of dots filling from a button, one dot per step. Wheel over it or click a step, and the change goes out as a one-way RPC command or an attribute write — with the payload shaped by you if the device wants something of its own. A wide range is grouped, so 0 to 50 becomes ten dots of five, and a rejected change returns the control to the value the device reports.

Widget Type
  • Control
Category
  • Controls

Who it’s for

Dashboard authors building a control for a value that moves in steps ask “how do I let someone set a speed, a level, or a position without typing a number?” A slider works for a continuous value, but a fan with four speeds or a damper with five positions has a fixed set of stops — this control turns that set into a column of dots a person can click, wheel through, or read at a glance.

What it does

Out of the box the control is a four-speed fan: four dots, a fan icon, and RPC method setFanSpeed. Change the range, the icon, and the caption, and the same control becomes a heater level, a damper position, a pump rate, or a dimmer — nothing about it is specific to fans.

  • Wheel or click to change it — turn the mouse wheel to step one at a time, or click any dot to jump straight to it
  • One gesture, one change — crossing four steps on the way to the fifth sends the fifth, not all four, so the device isn’t flooded with intermediate values
  • Opens on the value the device already holds, read back from telemetry or, for an attribute write, from the attribute itself — so a change made anywhere else shows up here too
  • A wide range is grouped automatically — 0 to 50 becomes ten dots of five, so the control never turns into fifty unclickable slivers
  • A rejected change is not pretended away — the control returns to the value the device reports and prints why, instead of sitting on a value that never actually took effect
  • Sends a one-way command or writes an attribute; it does not wait for a device reply, so what actually happened is best confirmed with a bound feedback key or a separate alarm

How to set up

Data keys

KeyRoleTypeDescription
Feedback key (optional, user-configured)Current valueTimeseriesOptional. Read back so the control opens on the value the device already holds and updates if the value changes anywhere else. Without it, the control opens at its lowest value in RPC mode, or reads the attribute directly once in attribute mode
AttributeScopeOperationDescription
Attribute key (fanSpeed by default)Shared (the device reads it) or Server (platform only)Write, plus one initial Read when no feedback key is boundUsed only when What a change does is set to Write an attribute
MethodDirectionParametersSent when
RPC method (setFanSpeed by default)One-wayAn object (default parameter name value), the bare number, or whatever a payload function of yours returnsA step is picked and the pointer settles — once per gesture, after Wait before sending

What the device receives picks the RPC parameter shape: an object like { "value": 30 } with a parameter name you set, the number alone, or a custom Payload function(value). The function receives value — the number being sent — and ctx, the widget context, and returns the object to send:

return { fan: { speed: value }, source: 'dashboard' };

It can scale, wrap, nest, or turn the value into a list. If it throws or returns nothing, nothing is sent — the change is treated as failed, the reason appears on the card, and the control returns to the value the device reports.

Delivery

SettingDefaultEffect
Request timeout (ms)5000How 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 deviceOffUses the platform’s persistent RPC, so a sleeping device gets the change once it wakes. RPC mode only
Retries0Up to ten. Shown only when the command is queued
Wait before sending (ms)350A wheel gesture crosses several steps; the change is sent once the pointer settles. Set it to 0 to send every step instead

Range

SettingDefaultEffect
Lowest value0The value the control sits on when it is off
Highest value4The top of the range
Step between values1The spacing between dots, before any grouping
Most dots to draw10A cap, not a target — the step widens to a round number so the dot count stays under this. 50 values with a cap of 10 become ten dots of five
Allow switching offOnThe button toggles between the lowest value and the last value used, instead of only stepping forward

How to customize

Layout & sizing

  • To lay the steps horizontally instead of above the button — set Layout to Horizontal.
  • To make the control bigger or smaller within the widget — set Size; 100 fills the widget edge to edge, the default 70 leaves a margin. It’s measured against the widget itself, so a narrow card gets a control sized for it rather than a shrunken one.
  • To change the caption under the control — edit Caption under the control; empty falls back to the data key’s own label.

Button & steps

  • To change the button’s icon — set Icon on the button to anything from the picker, including the mdi: set; clearing it brings back the fan.
  • To recolor the button — set Button above the lowest value and Button at the lowest value; the icon picks a light or dark ink on its own to stay readable against either.
  • To override the icon’s color directly — set Icon colour instead of letting it follow the button.
  • To recolor the steps — set Step dots and Steps not reached.
  • To make unreached steps fainter or more visible — set How visible an unreached step is.

Value & captions

  • To show the number under the control — turn on Show the value; worth it once a dot stands for more than one value. Add Units to append them.
  • To recolor the caption, the value, or an error message — set Caption and value, Value (shown only when Show the value is on), and Failed change.

Fonts

  • To match your dashboard’s fonts — set Caption font, and, when Show the value is on, Value font.

How a change is sent and confirmed

A wheel gesture crosses several steps on the way to the one you want. The dots follow your hand immediately, and the change goes out once you stop — that pause is Wait before sending. One mouse wheel notch is one step, and a trackpad’s smaller movements accumulate to the same, so a gesture sends one command, not one per step it crossed.

While a change is in flight, the control shows the value you picked. If the platform accepts it, that value becomes the new baseline. If it’s rejected — no permission, the target device isn’t set, the device is unreachable for a queued command — the control falls back to the value the device last reported, or to the lowest value if it has never reported anything, and the reason is printed under the control. It’s a control, not an indicator: showing a value the device isn’t actually holding would be worse than showing nothing.

Tips

  • Two steps with Allow switching off on gives an off / low / high control in three dots.
  • Bind the feedback key even when you don’t plan to show its value on screen — a control that disagrees with the device is worse than no control at all.
  • A device that’s often offline is a better fit for an attribute write than a command — the attribute waits for it, and nothing has to be queued.
  • Set Wait before sending to 0 only if the device is happy to receive every step of a wheel gesture; the default groups a fast gesture into one change instead.

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.