[BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration

4halbe 204 8
  • Helpful post
    Level 1  
    The controller is a NoName SCS86-03AJAI Smart Curtain Switch (as labelled on the back) and fits into a standard single wall box.

    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration

    It is one of the few curtain/shade controllers with mechanical keys. It's rather cheap while mechanical build looks quite okay with reasonable electrical separation and proper capacitors. However, the original Tuya firmware has a severe flaw, causing this device to crash at random intervals between a few hours and multiple weeks. It then disconnects from the network; the green WLAN LED is lit permanently, and it can only be restored by a full power cycle. So, flashing it with a proper firmware is mandatory.

    It originally was sold with an ESP32 inside that could be flashed with Tasmota (described here https://templates.blakadder.com/SCS86-03AJAI.html) but since 2021 there's a different version using a WB3S module that's hard to distinguish from the outside. The only obvious difference is the load specification (800W on the old device with ESP32, 600W on the current one with WB3S), but this may not be a safe distinction.

    The board now has a WB3S with the BK7231T processor, three mechanical buttons for Open, Stop and Close. Blue backlighting can be enabled for the three button LEDs. On activation, each button lights up red. A green LED behind the right button shows WLAN state (off when connected). The terminal block has live and neutral in and live/open and live/close outputs.


    Opening the case is straightforward: Just carefully pry the 4 clips holding the back cover to the metal frame and detach it with the boards from the front plate. A single Philips screw then needs to be removed from the power board through an opening in the processor board. Make sure the screws on the terminals are either removed or fully screwed in so the boards can be removed from the cover. Here's a view of both sides of the two boards:
    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration
    As can be seen, the power board offers space for a third relay and terminal, so there might be a version around that operates as a simple 3-gang power switch, but I haven't come across such a variant anywhere.


    I soldered wires onto the TXD1, RXD1, GND and VCC pads of the WB3S and connected it up my USB/UART converter set to 3V3, downloaded BK7231Flasher.exe and got the appropriate file to flash it with by this method (OpenBK7231T_UA_1.17.243.bin). The TXD/RXD pins do not interfere with the circuitry, but the trick was to put the device into flash mode: Powering it down did not work as the module draws too much power from the USB converter during powerup, causing an USB disconnect. Momentarily connecting the reset pin to ground however worked fine. Depending on your USB to serial converter, you might have to use a separate 3.3V power source for the WB3S module. Here's my flashing set-up:
    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration
    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration
    Instead of soldering power to the WB3S module, pin 4 (VCC) and pin 6 (GND) on J5 could have been used as well.


    Ater removing the temporary wires and reassembling, power up the device, but do not connect the controlled curtain or shutter motor yet. Use e.g., your phone to find and connect to its WiFi - the SSID is pretty obvious. Having done that, open a browser and go to, this should get you into the GUI where you should now enter your own WiFi's credentials. Reboot the device and try and find it through your own router. On my router when I looked at WiFi devices it was actually named including the MAC, so it was pretty obvious and unique. You will want to set a reserved IP in many cases.


    The Tuya controller has 3 buttons, 3 LEDs which illuminate the buttons and 2 relays plus the backlight (I kept the backlight function on channel 4). I set it up like this:
      "vendor": "NoName",
      "bDetailed": "1",
      "name": "SCS86-03AJAI Smart Curtain Switch",
      "model": "SCS86-03AJAI",
      "chip": "BK7231T",
      "board": "WB3S",
      "flags": "1024",
      "keywords": [
      "pins": {
        "0": "Rel;3",
        "1": "WifiLED_n;0",
        "6": "Rel;1",
        "7": "Rel;3",
        "8": "Btn;3",
        "10": "Btn;2",
        "11": "LED;4",
        "14": "LED;1",
        "24": "Btn;1",
        "26": "LED;2"
      "command": "",
      "image": "https://obrazki.elektroda.pl/7035845600_1694622383.jpg",
      "wiki": "TBA"

    This sets up the correct pinout, but the device will not work as a shutter/curtain controller yet, so don't connect the actuator at this point!
    Referring to the great post from richardsg307 on another controller (https://www.elektroda.com/rtvforum/topic3972935.html - also giving nice instructions for integration with MQTT and HA), I adapted his autoexec.bat file to make the device operate properly (e.g., pressing the open button would turn everything off then turn on the open relay and LED for 30 seconds. It would then turn all off before turning the stop LED on for just 1 second. Different from the original fimware, the backlight can now be toggled by a double click of the middle butten (instead of holding it for 10 seconds) if you add channel 4 behind button 2 for P10 on the cfg_pins page, which is not part of below config. Here's my autoexec.bat file which can be uploaded via the "Filesystem" Web Application menu.

    // Set up Aliases
    alias Set_Stop backlog setChannel 3 0; setChannel 2 0; setChannel 1 0; setButtonColor 3 blue; setButtonColor 2 blue; setButtonColor 1 blue
    alias Set_Open backlog setChannel 1 1; setButtonColor 1 green
    alias Set_Close backlog setChannel 3 1; setButtonColor 3 green
    alias Set_Finish backlog setChannel 2 1; setButtonColor 2 red
    alias Start_Opening backlog stopAllScripts; startScript autoexec.bat openShutter
    alias Start_Closing backlog stopAllScripts; startScript autoexec.bat closeShutter
    alias Stop_All backlog stopAllScripts; startScript autoexec.bat stopShutter
    // Channel 60 is seconds for power to be applied
    setChannel 60 30
    // create GUI buttons for HTTP panel
    startDriver httpButtons
    startDriver NTP
    setButtonEnabled 1 1
    setButtonLabel 1 "Open"
    setButtonCommand 1 Start_Opening
    setButtonColor 1 blue
    setButtonEnabled 3 1
    setButtonLabel 3 "Close"
    setButtonCommand 3 Start_Closing
    setButtonColor 3 blue
    setButtonEnabled 2 1
    setButtonLabel 2 "Stop"
    setButtonCommand 2 Stop_All
    setButtonColor 2 blue
    // Hide the default GUI buttons
    setChannelVisible 1 0
    setChannelVisible 2 0
    setChannelVisible 3 0
    // Loading Event Handlers
    addEventHandler OnClick 8 Start_Closing
    addEventHandler OnClick 24 Start_Opening
    addEventHandler OnClick 10 Stop_All
    // Setting Timed Handlers
    ntp_timeZoneOfs 02:00
    addClockEvent 20:30 0xff 0 Start_Closing
    addClockEvent 8:00 0x3f 1 Start_Opening
    addClockEvent 9:00 0x41 2 Start_Opening
    // do not proceed
    delay_s 0.1
    delay_s $CH60
    delay_s 1
    delay_s 0.1
    delay_s $CH60
    delay_s 1
    delay_s 1

    Note that this also includes NTP and ClockEvent settings to close shutters at dawn (I'm yet still thinking about an autonomous dynamic setting) and to open them an 8:00 a.m. on weekdays and 9:00 a.m. on the weekend. Note that currently there's a bug in the firmware not allowing leading zeroes in a time setting. Also, events can only be numbered with integer flags to individually delete them later.

    The code is not perfect, especially upon manual activation, there's a bit of delay and short key presses won't be recognised. Would be happy to hear about any suggestions for improvement!
  • #2
    Moderator Smart Home
    Very nice and detailed description. Regarding the shutter control: I think we should think about writing a driver for that in C. Is there anyone with shutters who knows the basics of programming? We could try to work together on that, however, the issue is that I don't have any shutters.

    So you've managed to flash without external 3.3V power supply? Nice.
  • #3
    Level 11  
    Hi Guys.

    Big thanks for your effort into OpenBK project - Love it!

    Think I may help.

    Got facade shutters (supporting angle),
    cheap 2ch curtain switch tuya alike (similar to this),
    flashed version OpenBK7231N 1.17.231,
    configured buttons and relays,
    all tested and looking good.
    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration

    My 2ch wall mounted curtain switch has 3 (up, off, down) and holds states, once pressed it mechanically stays pressed. OpenBK buttons does't work like that (or I'm using wrong driver for them atm). Shutter motor itself has (adjustable) max top/bottom limit switches, so once curtain switch pressed in desired direction you can leave it pressed, limit switch will turn the motor off once activated.
    [BK7231T] SCS86-03AJAI Smart Curtain Switch - Teardown - Flashing - Configuration

    - There no such thing like position feedback from Shutter or its motor, so most likely we'll have to relay on time.
    - When they travel down they do that always in fully blinded state (lamells are closed).
    - When they travel up they do that always in fully open state (lamells are open).
    - In order to adjust their angle a short impulse in reverse direction of travel is required.
    Eg. If you cycle them from very top to bottom they will be fully closed, then if you want to adjust the angle of lamells a short impulse in direction of opening will do the trick. Angle can be adjusted at any height of the shutter. I can do a video to make this process slightly more organoleptic.

    LMK what I cad do in order to help with driver development.
    Got some programming skills and tools.
  • #4
    Moderator Smart Home
    Hello, thank you for your interest in OpenBeken.

    If you have shutters and some programming skills, then we could write a shutter driver together.

    Something like that driver for bridge relay by @valeklubomir :
    The driver implementation should be very easy, it's just that I don't have any shutters.

    We can create a very advanced driver that way, with a better options for calibration.
  • #5
    Level 11  

    Don't know much about how OpenWRT/Tasmota handles those drivers.
    Will do some reading, fork it down and report back for your feedback.
    Perhaps some day it'll give birth to a pull request.
  • #6
    Moderator Smart Home
    This is very simple.

    - in init function, you register console commands that can be executed from MQTT or anywhere else
    - you have also a quick tick function and a every second function
    - you can also add channel change callback if required
    - you also get a HTTP page refresh callback
    Those few simple mechanism should be enough to implement shutter driver.
  • #7
    Level 11  
    Thanks p.kaczmarek2. Will PM after dev stack and deploy paths sorted. For the time being (missis demands) needed a quick workaround. Slightly upgraded autoexec.bat so its usable with HASS (w/o sending 2 directions simultaneously). It's also pretty quick in response to wall switches.

    // drivers
    startDriver httpButtons
    startDriver NTP
    ntp_timeZoneOfs 02:00
    // config
    powerSave 1
    setFlag 2 1 // MQTT Broadcast self state
    setFlag 6 1 // BTN Instant touch
    setFlag 27 1 // HASS discovery on IP change
    //setButtonHoldRepeat 20
    setButtonTimes 1 1 1
    // shutter cycle
    setChannel 40 42 // seconds
    // position (open 0 - N closed in seconds)
    setChannelType 41 ReadOnly
    setChannelLabel 41 "Ch1 Position"
    setChannel 41 $CH40 // closed
    setChannelType 42 ReadOnly
    setChannelLabel 42 "Ch2 Position"
    setChannel 42 $CH40 // closed
    // relays
    setChannelType 1 toggle
    setChannelLabel 1 "Ch1 Open"
    setChannel 1 0
    addChangeHandler Channel1 == 1 backlog cancelRepeatingEvent 1; cancelRepeatingEvent 2; setChannel 2 0; addRepeatingEventID $CH40 1 1 setChannel 1 0; setChannel 41 $CH41-1; addRepeatingEventID 1 -1 11 setChannel 41 $CH41-1
    addChangeHandler Channel1 == 0 cancelRepeatingEvent 11
    setChannelType 2 toggle
    setChannelLabel 2 "Ch1 Close"
    setChannel 2 0
    addChangeHandler Channel2 == 1 backlog cancelRepeatingEvent 1; cancelRepeatingEvent 2; setChannel 1 0; addRepeatingEventID $CH40 1 2 setChannel 2 0; setChannel 41 $CH41+1; addRepeatingEventID 1 -1 22 setChannel 41 $CH41+1
    addChangeHandler Channel2 == 0 cancelRepeatingEvent 22
    setChannelType 3 toggle
    setChannelLabel 3 "Ch2 Open"
    setChannel 3 0
    addChangeHandler Channel3 == 1 backlog cancelRepeatingEvent 3; cancelRepeatingEvent 4; setChannel 4 0; addRepeatingEventID $CH40 1 3 setChannel 3 0; setChannel 42 $CH42-1; addRepeatingEventID 1 -1 33 setChannel 42 $CH42-1
    addChangeHandler Channel3 == 0 cancelRepeatingEvent 33
    setChannelType 4 toggle
    setChannelLabel 4 "Ch2 Close"
    setChannel 4 0
    addChangeHandler Channel4 == 1 backlog cancelRepeatingEvent 3; cancelRepeatingEvent 4; setChannel 3 0; addRepeatingEventID $CH40 1 4 setChannel 4 0; setChannel 42 $CH42+1; addRepeatingEventID 1 -1 44 setChannel 42 $CH42+1
    addChangeHandler Channel4 == 0 cancelRepeatingEvent 44
    // bind physical switches
    addEventHandler OnHold 6 setChannel 1 1
    addEventHandler OnRelease 6 setChannel 1 0
    addEventHandler OnHold 26 setChannel 2 1
    addEventHandler OnRelease 26 setChannel 2 0
    addEventHandler OnHold 7 setChannel 3 1
    addEventHandler OnRelease 7 setChannel 3 0
    addEventHandler OnHold 8 setChannel 4 1
    addEventHandler OnRelease 8 setChannel 4 0

    Edit: Updated above with simple position indication, but it goes sideways. Measured tavel time is 42 seconds. Am i doing something wrong with below ?
    addRepeatingEventID 1 -1 22 setChannel 41 $CH41+1
  • #8
    Moderator Smart Home
    If you want to have online builds, just fork our repository, online builds also work in pull requests, you don't need to have compiler.

    I think that once we have a C driver for shutters, the scripts will not be needed at all, but still, it's a good progress.

    The following script:
    addRepeatingEventID 1 -1 22 setChannel 41 $CH41+1

    looks okay, what kind of wrong behaviour do you observe?
  • #9
    Level 11  

    Already forked, will look into online builds. Thanks for the tip.

    The above script sets the physical shutter travel time into Channel 40 as 42 seconds. It then copies that into channel 41. The device is reset with the shutters fully closed. When the shutter is opening, the "addRepeatingEventID 1 -1 11 setChannel 41 $CH41-1" should subtract 1 for each second of travel before "addRepeatingEventID $CH40 1 1 setChannel 1 0;" stops the process. Unfortunately, that's not the case. I'm getting way more seconds (added or subtracted) than I should.

    EDIT: Just tested it again, and suddenly they match. Must have been tired or something wasn't reset properly.