Skip to content

L1Blom/brel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Brel Blind Control via RFXtrx433XL

Control Brel (Dooya DDxxxx) motorized blinds locally from a Raspberry Pi using an RFXtrx433XL USB stick — no cloud, no hub required.

Background

The Brel DD-7002B hub is cloud-only and has no local API (especially after recent firmware updates). This solution bypasses the hub entirely by using an RFXtrx433XL USB stick to communicate directly with the blind motors over 433MHz FSK.

Note: Standard 433MHz devices (RFLink, cheap GPIO transceivers) will NOT work. Brel/Dooya motors use FSK modulation which requires the RFXtrx433XL specifically.


Hardware Requirements

  • Raspberry Pi (any model)
  • RFXtrx433XL USB stick (with firmware version 2025 or higher)
    • Available at rfxcom.com (~€110)
    • Also sold as RFXusb-RFX433 (newer model)
  • Brel motorized blinds with a DDxxxx-compatible remote (e.g. DD2700, DD2702)
  • The original Brel remote (needed once for pairing)

Firmware Setup

The RFXtrx433XL may ship without firmware. Flash it once using RFXmngr on Windows:

  1. Download RFXmngr from rfxcom.com/downloads
  2. Download the latest RFXtrx433XL_ProXL1 firmware from the same page
  3. Plug the RFXtrx433XL into a Windows PC
  4. Open RFXmngr → Firmware tab → select the .hex file → click Upload
  5. After flashing, plug into your Raspberry Pi

Linux alternative: You can flash using Mono with sudo mono RFXflash.exe /dev/ttyUSB0 RFXtrx433XL_ProXL1_XXXX.hex — however this may fail on newer Debian/Raspberry Pi OS due to missing Visual Basic assemblies in Mono 6.8.


Software Setup

Install dependency

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

requirements.txt currently includes:

  • flask (API service)
  • pyserial (RFXtrx433XL serial communication)

Verify the device is detected

ls /dev/ttyUSB0

If not present, check dmesg | tail -20 after plugging in the USB stick.


Pairing Your Blinds

Recommended (single script)

Use the unified pairing script:

# up/down channel only
python3 pair.py rolluik1 updown

# percentage channel only
python3 pair.py rolluik1 position

# both channels
python3 pair.py rolluik1 both

Valid devices: screen, rolluik1, rolluik2.

Before pairing:

  • Stop the API/service so /dev/ttyUSB0 is free.
  • Put the target motor in pairing mode (P2 workflow on remote).

Legacy scripts are kept for troubleshooting and renamed with a legacy- prefix:

  • legacy-pair-rolluik1.py
  • legacy-pair-rolluik2.py
  • legacy-pair-screen.py
  • legacy-pair-rolluik1-updown.py
  • legacy-pair-rolluik1-position.py
  • legacy-pair-rolluik2-updown.py
  • legacy-pair-rolluik2-position.py

Use pair.py as the default path for pairing.

You need to pair the RFXtrx433XL with each blind motor once. This uses the motor's built-in "learn extra remote" function — no physical access to the motor is needed, only the original remote.

You choose the ID yourself — any arbitrary ID works. The motor learns and remembers it. You do not need MAC addresses or any IDs from the Brel app.

Pairing procedure (per blind)

  1. Select the channel for the blind you want to pair on your original remote
  2. Press the P2 button twice on the back of the remote
  3. The blind motor will jog (move slightly) to confirm it entered pairing mode
  4. Within 3 seconds, run the relevant python3 pair.py <device> <mode> command
  5. The motor will jog again to confirm successful pairing

Pairing script

import serial

# Choose any ID you like — use the same ID for all blinds,
# differentiate them by unit code (1, 2, 3 etc.)
ID = [0x10, 0x20, 0x30, 0x40]
UNIT_CODE = 0x01  # change to 0x02, 0x03 etc. for each blind

with serial.Serial('/dev/ttyUSB0', 38400, timeout=2) as ser:
    ser.flushInput()

    # Step 1: Pair for up/down/stop (BlindsT21)
    packet = bytes([
        0x09, 0x19, 0x15, 0x00,
        ID[0], ID[1], ID[2],
        (ID[3] & 0xF0) | (UNIT_CODE & 0x0F),
        0x03,  # P2 pair command
        0x00,
    ])
    ser.write(packet)
    print(f"BlindsT21 pair sent: {' '.join(f'{b:02X}' for b in packet)}")

import time
time.sleep(1)

with serial.Serial('/dev/ttyUSB0', 38400, timeout=2) as ser:
    ser.flushInput()

    # Step 2: Pair for position/percent (DDxxxx 0x31)
    packet = bytes([
        0x0C, 0x31, 0x00, 0x00,
        ID[0], ID[1], ID[2], ID[3],
        UNIT_CODE,
        0x03,  # P2 pair command
        0x00, 0x00, 0x00,
    ])
    ser.write(packet)
    print(f"DDxxxx pair sent:    {' '.join(f'{b:02X}' for b in packet)}")

Run the pairing script immediately after the motor jogs (within ~3 seconds). The motor will jog again to confirm pairing.

Tip: Run the pairing script in advance and have it ready to execute. The timing window is short.


Controlling Your Blinds

brel.py — main control script

Edit the DEVICES dictionary at the top of brel.py to match your setup:

DEVICES = {
    'screen':   (0x41, 0x01),  # (BlindsT21 unit byte, DDxxxx unit code)
    'rolluik1': (0x42, 0x02),
    'rolluik2': (0x43, 0x03),
}

The unit byte format for BlindsT21 is (ID[3] & 0xF0) | unit_code. With ID 10 20 30 40 and unit codes 1/2/3 this gives 0x41, 0x42, 0x43.

Usage

# Up / Down / Stop
python3 brel.py screen up
python3 brel.py rolluik1 down
python3 brel.py rolluik2 stop
python3 brel.py all up

# Set position (0 = fully open, 100 = fully closed)
python3 brel.py screen position 50
python3 brel.py rolluik1 position 0
python3 brel.py all position 75

Packet Reference

BlindsT21 — up/down/stop

09 19 15 00 [ID1] [ID2] [ID3] [ID4|unit] [cmd] 00

Commands:
  0x00 = Up
  0x01 = Down
  0x02 = Stop
  0x03 = P2 pair

DDxxxx (0x31) — position/percent

0C 31 00 00 [ID1] [ID2] [ID3] [ID4] [unit] [cmd] [percent] 00 00

Commands:
  0x03 = P2 pair
  0x04 = Set percent (0–100)

Troubleshooting

Problem Likely cause Fix
/dev/ttyUSB0 not found Driver not loaded Check dmesg after plugging in
ACK received but blind doesn't move Not paired with this ID Re-run pairing procedure
Motor doesn't enter pairing mode P2 not pressed correctly Press P2 twice, wait for jog each time
Position command ignored Only paired for BlindsT21 Also pair using the DDxxxx (0x31) packet
Works for one blind, not others Wrong channel selected on remote Switch channel on remote before pairing

Tested With

  • Raspberry Pi 4 / Pi 5
  • RFXtrx433XL with firmware 2026
  • Brel motorized roller blinds and sun screens with DD2700 remote
  • Raspberry Pi OS (Debian 12 Bookworm)

Credits

Packet format documented by the RFXCOM community at rfxcom.com and the Home Assistant community.

About

Connect to your Brel motors with RFX433XL-USB

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages