Based on the original work by Scott Downing (GimpArm), with calibration persistence introduced by ohlmannmichael-ai.
Home Assistant component that interfaces with the Schellenberg Usb Funk-Stick.
Warning
This integration is not affiliated with Schellenberg, the developers take no responsibility for anything that happens to your devices because of this library.
- Supports blind movement Up, Down, and Stop
- After calibation, position tracking is possible.
Make sure you have HACS installed. If you don't, run wget -O - https://get.hacs.xyz | bash - in HA.
Choose Integrations under HACS. Click the '+' button on the bottom of the page, search for "Schellenberg USB+", choose it, and click install in HACS.
Clone this repository or download the source code as a zip file and add/merge the custom_components/ folder with its contents in your configuration directory.
In order for the newly added integration to be loaded, HA needs to be restarted.
In HA, go to Configuration > Integrations. In the bottom right corner, click on the big button with a '+'.
If the component is properly installed, you should be able to find 'Schellenberg USB+' in the list. You might need to clear you browser cache for the integration to show up.
Select it, and the Schellenberg USB+ integration is ready for use.
- In Home Assistant, go to Settings > Devices & Services
- Find the Schellenberg USB+ integration and click on it
- Click the + button or select Pair device from the menu
- Put your blind motor into pairing mode (see Device Pairing Instructions)
- Once pairing is successful, provide a friendly name for your blind
Calibration is essential for accurate position tracking. The integration measures how long it takes your blind to fully open and close, allowing it to calculate the current position during operation.
Important
This calibration is not the same as setting the end positions (fully open/closed limits) on your blind motor. End positions must be configured directly on the device itself using the motor's built-in adjustment features or a Schellenberg remote control before using this integration.
You can calibrate a blind:
- During initial pairing: After naming your device, you'll be prompted to calibrate
- After pairing from the device page: Go to the device and click the Calibrate gear icon (⚙️) as shown below
Click the gear icon labeled "Calibrate" in the top right corner of your blind device to start calibration.
-
Step 1 - Close the blind: Ensure your blind is fully closed (all the way down). Press Next when ready.
-
Step 2 - Measure open time:
- Press Start in the dialog
- Then press the open button on your physical remote/control
- The integration will automatically detect when the blind starts moving and begin timing
- Wait for the blind to fully open - the timer stops automatically when movement stops
-
Step 3 - Measure close time:
- Press Start in the dialog
- Then press the close button on your physical remote/control
- The integration will automatically detect when the blind starts moving and begin timing
- Wait for the blind to fully close - the timer stops automatically when movement stops
-
Complete: The integration will display the measured open and close times and save them for position tracking
Tip
There's no need to rush when pressing the buttons - the timer doesn't start until the integration receives a "moving" signal from the blind motor.
Note
If calibration times seem incorrect, you can recalibrate at any time from the device options.
Each Schellenberg device has a specific button combination to enter pairing mode. You must put your device into pairing mode within 2 minutes of starting the pairing process in Home Assistant.
Art.Nr.: 22567, 22576, 22578, 22726, 22727, 22728, 22767
To enter pairing mode:
- Press and hold the Sun (☀) button and the Up (▲) button simultaneously
- Hold for 5 seconds until the LED flashes
- The device is now in pairing mode
Art.Nr.: 20106, 20110, 20406, 20410, 20610, 20615, 20620, 20640, 20710, 20720, 20740
These motors are controlled via external switches or remote controls. Pairing is typically done through the connected Schellenberg remote control or timer switch.
Art.Nr.: 21106, 21110, 21210, 21220, 21240
To enter pairing mode, refer to your specific remote control or timer switch manual. The pairing button combination varies by the control device used.
- Keep the USB Funk-Stick within range (approx. 20m indoors, 100m outdoors)
- Avoid metal obstructions between the stick and the motor
- If pairing fails, try moving the USB stick closer to the device
- Consult your device's manual for the exact pairing procedure if the above doesn't work
Note
The pairing instructions above are based on common Schellenberg products. Your specific device may have different procedures - always refer to the device's original manual if unsure.
As of v1.3.0, the integration distinguishes between two motor types:
| Type | Description |
|---|---|
| Bidirectional | Motor sends movement events back to the stick. The integration detects when motion starts and stops — this is the classic mode. All previously paired motors are treated as bidirectional by default. |
| Timed (non-bidirectional) | Motor gives no movement feedback. The integration cannot detect when the motor starts or stops moving, so it times runs by measuring the wall-clock duration between button presses instead of waiting for events. |
You select the motor type once, when adding the device. A timed motor requires a separate calibration flow (described below); a bidirectional motor uses the event-based flow documented in Step 5: Calibrate your blinds.
Note
Legacy subentries created before v1.3.0 have no mode flag and are treated as bidirectional — existing paired motors are unaffected.
If a motor is already paired (for example it responds to an existing Schellenberg remote) you can add it to Home Assistant without triggering the radio-pairing procedure:
- In Home Assistant, go to Settings > Devices & Services.
- Find the Schellenberg USB+ integration and click on it.
- Click the + button to add a device.
- When the menu appears, choose Add manually.
- Enter the motor's device enum — a two-character hex value (e.g.
10,11,1A) that identifies the device on the radio bus. - Choose the motor mode: toggle on for bidirectional, toggle off for timed/non-bidirectional.
- Optionally provide a friendly name (defaults to
Blind <enum>if left blank). - For timed motors only: a second screen asks for the initial position (0–100 %). Set this to the motor's current physical position so the integration starts tracking from the right point. Use 100 % if the shutter is currently fully open.
- Click Submit — the device is created immediately with no radio-pairing step.
Tip
The device enum is the two-hex-character address the stick uses to address the motor. If you are unsure of the value, check your previous pairing records or consult the integration logs — each enrolled device is logged with its enum at startup.
Important
This section describes the timed calibration flow for non-bidirectional (timed) motors. It is separate from and additional to the event-based "Calibration Steps" in Step 5, which applies only to bidirectional motors. Do not use the event-based flow for a timed motor — it will wait indefinitely for movement events that never arrive.
Because timed motors send no movement feedback, calibration is driven entirely by button presses: the integration sends a command, you watch the shutter move, and you press a button when it stops.
- The shutter must be fully open (all the way up) before you start. If it is not, drive it to the top using your physical remote first.
Access timed calibration the same way as regular calibration:
- After adding a timed motor: the timed calibration flow launches automatically once the device is created.
- Later, from the device page: click the Calibrate gear icon (⚙️) on the device page.
-
Precondition check: Confirm the shutter is fully open. Press Next when ready — no command is sent at this point.
-
Close run:
- The integration sends a close command to the motor.
- Watch the shutter travel all the way down to its physical endstop. Wait until it has fully stopped.
- Press Next to record the elapsed time.
- The integration does not send a stop command — the motor coasts to its physical endstop naturally.
-
Open run:
- The integration sends an open command to the motor.
- Watch the shutter travel all the way up. Wait until it has fully stopped at the top endstop.
- Press Next to record the elapsed time.
- Again, no stop command is sent — the motor stops at its physical endstop.
-
Confirm: The integration shows the measured close time and open time. Press Done to save, or check Redo to discard the measurements and start again from the precondition step.
The integration validates each run before accepting it:
| Condition | Guard | What to do |
|---|---|---|
| You pressed Next in under 2 seconds | Rejected (likely a double-press or misfire) | The form re-shows; drive the shutter back to fully open manually and retry |
| You waited more than 120 seconds | Rejected ("walked away" run) | The form re-shows; drive the shutter back to fully open manually and retry |
Important
After a guard error, the shutter position is unknown — it may have stopped mid-travel. Return the shutter to the fully open position using your physical remote before pressing Next again.
Once a timed motor has been calibrated, the position slider in the Home Assistant UI becomes active. Requesting a percentage (e.g., 50 %) causes the integration to:
- Determine the direction of travel (open or close) from the current tracked position.
- Send the appropriate command to the motor.
- Schedule a stop command after the computed fraction of the full-travel time has elapsed.
The integration tracks position by dead-reckoning — it uses the calibrated open and close times to estimate where the shutter is. If the motor is ever moved outside of Home Assistant (e.g., by a physical remote), the tracked position will drift until the next full-travel recalibration.
Contributions are welcome. See CONTRIBUTING.md for the development setup and the local quality gate (tests, lint, type-check, and spell-check) every change must pass.

