[RELEASE] Zigbee Window Shade/Blind (Timed) — Sonoff MINI-ZBRBS, Tuya, ZCL
A Hubitat driver for Zigbee shade/curtain/blind modules that estimates position based on movement time, motor and Zigbee delays.
Designed for devices that don't reliably report their position, or don't report the position at all.
This was the first driver I've developed for Hubitat back in 2021 when I got my first hub.
It's been improved over the years, but the main calculations didn't change since then, so it is very stable and well tested.
Supported Devices
| Device | Protocol | Recommendation |
|---|---|---|
| Sonoff MINI-ZBRBS | ZCL | |
| LoraTap SC500ZB | Tuya | |
| Zemismart ZW-EC-01 | Tuya | |
| Other ZCL devices | ZCL | Should work with any device that follows ZCL Window Covering cluster standards. |
| Other Tuya devices | Tuya | May work with similar Tuya devices, but not tested. |
Features
-
Time-based position estimation — Configurable open/close durations and motor start delays for precise positioning.
-
Semi-blind position — Special support for cellular/honeycomb shades: setting position to 3% uses a dedicated timing for precise cell positioning (e.g., cells closed with shade slightly raised for privacy + light).
-
Inverted movement near lower limit — When targeting a low position (≤5%), the shade first closes fully and then opens to the target, improving accuracy near the bottom.
-
Turbo Mode (Sonoff only) — Increases Zigbee radio power for better range.
-
Safety timeout — Automatically recovers state if a pause command is missed.
-
Invert open/close — For installations where the motor direction is reversed.
-
Configurable logging levels — Error, Warning, Info, Debug, Trace.
Installation
-
Go to Drivers Code in your Hubitat hub and click New Driver.
-
Paste the driver code and click Save.
-
Assign the driver to your device under Devices → (your device) → Type.
Setup
-
Calibration — It is important not to set or clear any existing calibration on the device.
-
Reset Position — When first using the driver, use the
Reset Positioncommand to set the shade's current actual position. This initializes the driver's internal state to match reality. No commands are sent to the device. -
Set open/close durations — Open and close the shade fully, measure the times (in milliseconds), and enter them in the preferences. Click Save Preferences.
-
That's it for most users. The default motor delay values work well for typical setups. You can now use
open/close/setPosition/stopPositionChangeas usual, and the driver will estimate position based on your configured timings.
Advanced: Precise Timing Calibration
For very precise positioning (e.g., the semi-blind cell position):
-
Record a video of the shade opening and closing.
-
Use a subtitle tool or video analysis tool that shows precise frame timestamps (milliseconds).
-
Motor start delay = time from when you hear the controller relay click until you see the shade actually start moving.
-
Open/close time = time from when the shade starts moving until it reaches the fully open/closed position.
Preferences
| Preference | Default | Description |
|---|---|---|
| Invert open/close | false |
Swap open/close direction for reversed motor installations |
| Time to open | 10000 ms |
Total time for the shade to go from fully closed to fully open |
| Time to close | 10000 ms |
Total time for the shade to go from fully open to fully closed |
| Semi-blind position time | 0 ms |
Time from closed to semi-blind position (triggered at 3%). Set to 0 to disable. |
| Motor start delay (open) | -108 ms |
Delay compensation after the open command is sent |
| Motor start delay (close) | 186 ms |
Delay compensation after the close command is sent |
| Open/Close safety margin | 1000 ms |
Extra time added when targeting fully open or fully closed |
| Turbo Mode (Sonoff only) | Disabled |
Increases Zigbee radio power for better range |
| Logging level | Info |
Error / Warning / Info / Debug / Trace |
Commands
| Command | Description |
|---|---|
open() |
Opens the shade to 100% |
close() |
Closes the shade to 0% |
setPosition(pos) |
Moves the shade to the specified position (0–100%) |
startPositionChange(direction) |
Starts moving up or down |
stopPositionChange() |
Stops the shade |
resetPosition(pos) |
Sets the driver's internal position state without sending any command to the device |
How It Works
The driver sends standard Zigbee Window Covering cluster commands (open/close/stop) and estimates position by measuring elapsed movement time against the configured durations. When a stop command is needed (e.g., to reach 50%), the driver schedules a precisely-timed pause command.
Key implementation details:
-
Zigbee command delay compensation — The round-trip delay is measured and factored into pause timing.
-
Pre-pause scheduling — A two-stage scheduling approach (pre-pause → pause) minimizes timing jitter.
-
Inverted movement — For positions ≤5%, the shade closes fully first, then opens to the target position, avoiding the inaccuracy of stopping very close to the limit.