BK7231N-based LoraTap SC400W-EU curtain/blinds switch board was opened, identified, and prepared for flashing through the CB3S module.
Instead of desoldering the soldered board pins, the board was lifted, RX/TX were connected, power went to the outer pins, and flashing started by shorting GND to CEN.
Pin mapping used P6 WifiLED_n;0, P7 Btn;2, P8 LED_n;2, P9 Btn;1, P14 Rel;3, P23 Btn;3, P24 LED;3, and P26 Rel;1.
The flashing application could not read settings automatically, so all pins had to be found manually and entered into the configuration JSON.
A custom /autoexec.bat restored OPEN/CLOSE/STOP logic, with buttons auto-disabling after 60 seconds, reset lit for 1 second, and RESET toggling the buttons off.
Good job, I will post that information in a form of miniguide for compiling on WSL soon. I didn't know that.
Regarding rebuild, I think that @btsimonh added the recursive "delete generated files" in the build script somewhere because there was some kind of issue. I am not sure.
Do you need help with compiling OBK to run on Windows (as a simulator with self tests)?
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is called once when a driver starts. You can create custom commands there via CMD_RegisterCommand. The registered commands can be later called via MQTT, etc.
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is called on every second. I am not sure if you need it.
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is used to add custom information to HTTP page. Maybe you can use it to display the percentages, etc, how much shutters are open.
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is called on quick tick, every 25ms. See QUICK_TMR_DURATION . Use this to update your timer counters and when they overflow, stop the shutter operations.
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is called when a driver is stopped. This is often ignored, as we just assume user will restart the device.
hezipereg wrote:
Code: C / C++
Log in, to see the code
This is a channel change callback in case that you might need that. If you decide that you want to use some channel as as shutter percentage level, you may watch for it to change.
Keep in mind that there are many possible approaches to implementing the shutters driver and even I don't know which is the best. You can use our SDK in many ways, just find the one that suits your needs best.
Till today I had a controller working about 2 years and suddenly disconnected from the Wifi network. I can not normally add to Tuya so I decided if it is possible to do an Open Beken?
There is a problem because the device reports as New Device when it should be a Curtain Switch.
I have checked the capacitors and replaced them without any change.
I still need to change the software .
Can I ask for help?
>>21109623 .
I do not know TuyaMCU... it worked normally with tuya app.
I have something to upload the soft so maybe check.
Where can I generate the soft? You have already helped me in the past with the light switch flies nicely
Our flasher downloads the soft from the internet:
https://github.com/openshwprojects/BK7231GUIFlashTool But first check with a multimeter if the RX and TX from the WiFi module is not connected to this microcontroller by any chance?
Hello, very good, just thank @rodionzhitomirsky and @gliga69 for your code. I modified it and it works very well. Both the physical and web buttons work correctly, and the blind percentage seems great. I have it on a Loratap SC400W-EU, but don't trust the PINs; each Loratap is unique.
I'm leaving the code here, with a comment on where to put your PINs, in case anyone is interested.
clearIO
// ====== CONFIG ======
// Used to hold the delay value in millis for sleeping during closing or opening loop
// Play with your curtain and find the right value for this delay
SetChannel 8 100
// Delay to wait (millis) before starting to move the curtain after we close both relays
// maybe it is not necessary, but I prefer it to be to ensure we do not have
// both open and close relays powered simultaneously:
SetChannel 7 500
// MQTT stuff
MqttClient lr_curtain_2
MqttHost <YOUR_HA_MQTT_HOST>
MqttUser <YOUR_HA_MQTT_USER>
MqttPassword <YOUR_HA_MQTT_PASSWORD>
// ====== END OF CONFIG ======
// set channels 7, 8 and 9 to be private, so that we do not spend resources to publish their values:
SetChannelPrivate 7 1
SetChannelPrivate 8 1
SetChannelPrivate 9 1
// HIde relays from GUI
setChannelVisible 1 0
setChannelVisible 3 0
// We start the main opening/closing loop with a delay
// and than immediately have a calibration delay
// so, let's decrement the calibration delay to not have them both
// at the beginning of the loop:
addChannel 7 -$CH8 0 5000
PowerSave 1
//startDriver ntp
// set pins and channels
// Pin 7 is connected to opening relay
SetPinRole 7 Rel
// we also connect it to channel 1
SetPinChannel 7 1
SetChannelLabel 1 "Up"
// Pin 6 is connected to closing relay
SetPinRole 6 Rel
// we also connect it to channel 3
SetPinChannel 6 3
SetChannelLabel 3 "Down"
// crea los botones
setChannelType 20 Toggle
SetChannelLabel 20 "Down"
setChannelType 21 Toggle
SetChannelLabel 21 "Stop"
SetChannel 21 1
setChannelType 22 Toggle
SetChannelLabel 22 "Up"
// 23 - stop button
SetPinRole 26 Btn
// 24 - opening button
SetPinRole 9 Btn
// 26 - closing button
SetPinRole 24 Btn
// CH9 - saved position for reboot
// CH10 - current position
// CH11 - target position
SetChannelLabel 9 "Saved Position"
setChannelType 9 Dimmer
SetChannelLabel 10 "Current Position"
setChannelType 10 Dimmer
SetChannelLabel 11 "Target Position"
setChannelType 11 Dimmer
SetStartValue 9 -1
// read position saved before reboot:
SetChannel 10 $CH9
SetChannel 11 $CH9
// Setup LED:
//SetPinRole 10 LED
//SetPinChannel 10 4
// ============= MQTT ============
// Let it shine when MQTT connection is established:
addEventHandler MQTTState 1 SetChannel 4 1
addEventHandler MQTTState 0 SetChannel 4 0
// [2] Always set MQTT Retain flag to all published values;
// [7] Broadcast self state every N seconds:
// [10] Broadcast self state on MQTT connect
flags 1156
// Inform HA about our values every 30 seconds, publish 2 values per second
mqtt_broadcastInterval 30
mqtt_broadcastItemsPerSec 2
alias Set_Stop backlog setChannel 3 0; setChannel 1 0
alias Start_Opening backlog SetChannel 22 1; stopAllScripts; startScript autoexec.bat openSkylight
alias Start_Closing backlog SetChannel 20 1; stopAllScripts; startScript autoexec.bat closeSkylight
alias Stop_All backlog stopAllScripts; startScript autoexec.bat stopSkylight
alias Open_To_Target backlog stopAllScripts; startScript autoexec.bat openSkylightToTarget
alias Stop_Clicked backlog Set_Stop; Stop_All; SetChannel 21 1
// Click and fast release will effect in fully closing or opening.
// If during this process we click on the same button again, it stops
// EDIT PINS..............................................................................................................................................
addEventHandler OnClick 24 if $CH03==1 then Stop_Clicked else Start_Closing
addChangeHandler Channel20 == 1 if $CH03==1 then Stop_Clicked else Start_Closing
addEventHandler OnClick 9 if $CH01==1 then Stop_Clicked else Start_Opening
addChangeHandler Channel22 == 1 if $CH01==1 then Stop_Clicked else Start_Opening
addEventHandler OnClick 26 Stop_Clicked
addChangeHandler Channel21 == 1 if $CH02==1 then Stop_Clicked else Stop_Clicked
//..............................................................................................................................................................................
addChangeHandler Channel20 == 1 backlog SetChannel 21 0; SetChannel 22 0
addChangeHandler Channel21 == 1 backlog SetChannel 20 0; SetChannel 22 0
addChangeHandler Channel22 == 1 backlog SetChannel 20 0; SetChannel 21 0
return
// === OPEN TO GIVEN PERCENTAGE ===
openSkylightToTarget:
Set_Stop
delay_ms $CH7
openSkylightToTarget_again:
delay_ms $CH8
if $CH10<$CH11 then goto continue_opening
if $CH10>$CH11 then goto continue_closing
// we are done, we reached our target
// If we were opening or closing fully, we let the motor
// run for 3 seconds for the case we are uncalibrated:
if $CH10==0 then goto calibrate
if $CH10==100 then goto calibrate
goto openSkylightFinished
continue_opening:
// Unset_Close
setChannel 3 0
// Set_Open
setChannel 1 1
// increment:
addChannel 10 1 0 100
goto openSkylightToTarget_again
continue_closing:
// Unset_Open
setChannel 1 0
// Set_Close
setChannel 3 1
// decrement:
addChannel 10 -1 0 100
goto openSkylightToTarget_again
calibrate:
delay_ms 3000
Set_Stop
SetChannel 9 $CH10
return
openSkylightFinished:
Set_Stop
SetChannel 9 $CH10
return
// === CLOSE ===
closeSkylight:
SetChannel 11 0
goto openSkylightToTarget
return
// === OPEN ===
openSkylight:
SetChannel 11 100
goto openSkylightToTarget
return
// === STOP ===
stopSkylight:
Set_Stop
SetChannel 11 $CH10
SetChannel 9 $CH10
return
Hello!
I am trying to adapt the autoexec for a SC420W-EU (Loratap 2 shutters switch like this one: https://fr.aliexpress.com/item/1005005454300272.html).
It doesn't work 100% yet, but I think that the best way to make shutters switches work as expected without a bunch of tricks would be to have a shutter driver...
Is that a work in progess?
Thanks.
JY
✨ The discussion centers on the BK7231N-based LoraTap SC400W-EU switch board, focusing on desoldering challenges, flashing procedures, and firmware customization using OpenBeken. Initial difficulties in desoldering the switch pins led to partial soldering of RX, TX, VCC, and GND for flashing via shorting GND to CEN. Users shared detailed GPIO pin mappings for LEDs, buttons, and relays, clarifying LED roles such as LED, LED_n (inverted), and WifiLED_n, with hardware limitations restricting color control to on/off states. Configuration adjustments via the autoexec.bat script enabled control of LED states and introduced a runtime parameter for shutter open/close duration, which was integrated with Home Assistant through MQTT and input_number entities. Advanced users discussed developing a dedicated shutter driver in C within the OpenBK7231T_App framework, including driver structure, function callbacks, and build environment setup using Cygwin or WSL. Troubleshooting build issues and GitHub workflow for pull requests were addressed. The conversation also covered TuyaMCU device considerations, flashing tools, and extracting Tuya configurations. Finally, a user shared a custom blind driver script for the LoraTap SC400W-EU, emphasizing unique pin assignments and MQTT integration for Home Assistant control, highlighting the variability of hardware revisions. Generated by the language model.
TL;DR: With 8 mapped GPIOs and one simple script, you can flash a BK7231N/CB3S-based LoraTap SC400W-EU without fully desoldering the board; as one expert reply put it, "We have a new working native driver for shutters" if you want a cleaner alternative later. This FAQ helps OpenBeken users wire, flash, script, and tune shutter control. [#21856035]
Why it matters: This thread turns a hard-to-open Tuya curtain switch into a documented OpenBeken workflow, including pin mapping, LED behavior, MQTT control, and the path from script hacks to native shutter support.
Approach
What it does
Main advantage
Main limit
autoexec.bat script
Recreates Open/Stop/Close logic and timers
Works now on SC400W-EU
Percentage control is manual to design
GPIO remapping
Changes LED behavior and adds LED toggle control
Fast hardware-aware customization
Cannot create colors the PCB cannot drive
Native shutter driver
Adds dedicated shutter logic
Better fit for 0–100% control
Arrived later and needs testing per device
Key insight: Start with the proven SC400W-EU pin template and autoexec.bat, then move to the native shutter driver only if you need cleaner percentage-based control. The hardware wiring, especially LED and UART layout, decides what is possible. [#20795168]
Quick Facts
The working SC400W-EU OpenBeken template maps 8 pins: P6, P7, P8, P9, P14, P23, P24, and P26 for WiFi LED, buttons, LEDs, and relays. [#20795168]
The original script improved factory-like timing by changing auto-off from 120 s to 60 s and the reset indicator from 2 s to 1 s. [#20795168]
A later Home Assistant-friendly version exposes channel 4 as "Open/Close Duration" with a default of 30 s instead of the earlier 60 s example. [#20988845]
One user reported the LoraTap unit cost about $17 from the brand store on AliExpress, showing this is a low-cost shutter platform. [#20796938]
WSL builds succeeded after installing lib32z1 and python-is-python3; Cygwin also worked, while WSL initially failed for another participant. [#20994640]
How do I open and flash a LoraTap SC400W-EU with a BK7231N/CB3S module when the board pins are soldered and hard to desolder?
Open it by lifting the board instead of fully removing the soldered pin header. Then solder only RX and TX directly to the CB3S pads, and feed power to the two extreme board pins where GND is on the left, the same side as the OPEN button. To enter flashing mode, short GND to CEN. This avoids desoldering the whole switch assembly and was reported to work on the SC400W-EU with a BK7231N-based CB3S module. [#20795168]
Which RX, TX, VCC, GND, and CEN connections are needed to put the CB3S module on a LoraTap SC400W-EU into flashing mode?
You need RX and TX on the CB3S module pads, VCC and GND on the two extreme board pins, and a temporary short from GND to CEN to enter flashing mode. The thread states GND is on the left side, matching the OPEN button side. The author powered the board from those outer pins and did not rely on automatic pin detection in the flashing app. That manual wiring was enough to flash the device successfully. [#20795168]
What is the correct OpenBeken pin template for the LoraTap SC400W-EU, including the button, relay, and LED mappings?
The working template is: P6 WifiLED_n;0, P7 Btn;2, P8 LED_n;2, P9 Btn;1, P14 Rel;3, P23 Btn;3, P24 LED;3, and P26 Rel;1. That maps three buttons, two relay outputs, and indicator LEDs for the SC400W-EU. A later LED-focused variant changed P6 to Rel_n;0 and P24 to LED_n;3, but the first published template is the baseline mapping for flashing and initial setup. [#20795168]
How can I use autoexec.bat in OpenBeken to recreate the original LoraTap shutter logic with Open, Close, Stop, and auto-reset timers?
Use autoexec.bat to label channels 1, 2, and 3 as Close, Stop, and Open, then add change handlers that cancel opposite actions and start timed reset scripts. 1. Create aliases such as Reset_Stop_Open and Reset_Close_Open. 2. Attach addChangeHandler rules so Channel1 and Channel3 auto-start timer scripts. 3. Use delay_s 60 for open and close, and delay_s 1 for stop reset. This reproduces the switch logic and prevents both directions staying active together. [#20795168]
What is the difference between LED, LED_n, WifiLED, and WifiLED_n in OpenBeken IO roles?
LED follows a linked channel, while LED_n follows the same channel with inverted logic. WifiLED shows Wi-Fi state, and WifiLED_n shows the same status with inverted polarity. "IO role" is a per-GPIO function assignment that tells OpenBeken what a pin should do and whether its logic is normal or inverted. The thread also notes these roles only drive high or low states, so they do not create arbitrary colors unless the PCB already supports multiple LED paths. [#20977537]
How can I change the touch button LED behavior or color indication on a LoraTap SC400W-EU by remapping GPIO roles in OpenBeken?
Change the LED-related pin roles and linked channels, then test in GPIO Doctor. One user switched to this working LED setup: P6 Rel_n;0, P8 LED_n;2, and P24 LED_n;3. That reversed the visible color behavior on the touch buttons and made the front-panel indication match the desired state better. The key limit is hardware: if the PCB exposes only one LED path per button, remapping can invert or swap behavior, but not invent a new color. [#20978313]
Why does changing P6 from WifiLED_n to Rel_n on the SC400W-EU let me add a separate button to turn the switch LEDs on and off?
Because Rel_n binds P6 to a normal user channel instead of automatic Wi-Fi status logic. With WifiLED_n, OpenBeken controls that pin from connection state and you cannot toggle it manually. After changing P6 to Rel_n;0, one user added a dedicated channel and exposed it in Home Assistant as a separate LED on/off control. That turned the front LEDs into a scriptable output instead of a fixed network indicator. [#20978313]
How do I expose the shutter open/close duration as a configurable field in OpenBeken and control it from Home Assistant over MQTT?
Move the fixed delay into channel 4 and use delay_s $CH4 instead of delay_s 60. Then set SetChannelLabel 4 "Open/Close Duration", SetChannelType 4 TextField, setStartValue 4 -1, and a default like if $CH4==0 then setChannel 4 30. A user confirmed this worked and then pushed new values from a Home Assistant input_number through MQTT publish automation. That made the duration adjustable without editing the script again. [#20988845]
Where can I read about OpenBeken scripting, GPIO roles, and example autoexec.bat files for shutters and similar devices?
Read the links shared in the thread to the OpenBK7231T_App documentation. The GPIO role reference was linked under docs/ioRoles.md, and script examples were linked under docs/autoexecExamples.md. The discussion explicitly points new users to those two files when explaining LED, LED_n, WifiLED_n, channel logic, and timed scripts. Those references are the thread’s main documentation path for OpenBeken scripting and pin-role behavior. [#20988420]
What is TuyaMCU, and how does it affect flashing and configuring a curtain switch that has a separate MCU connected over UART?
TuyaMCU is a secondary microcontroller that handles device features and talks to the Wi-Fi module over UART using dpIDs and commands. If RX and TX from the Wi-Fi module are wired to that MCU, the switch is a TuyaMCU design and configuration changes differ from a simple GPIO-only device. In that case, flashing OpenBeken is still possible, but you must also identify the UART relationship and often configure TuyaMCU-specific behavior instead of only mapping pins. [#21109644]
How do I find the correct Tuya dpId for a curtain switch parameter like running time if I want to preserve Tuya-style control instead of replacing it with autoexec.bat logic?
First confirm the switch actually uses TuyaMCU, then inspect TuyaMCU traffic or use the dedicated TuyaMCU guide linked in the thread. The discussion never identifies a confirmed dpId for the running-time field on this SC400W-EU, so the practical answer in-thread was to replace that feature with channel-based autoexec.bat logic. This is an important edge case: if you cannot see or decode the UART parameter, you cannot preserve the Tuya control field reliably. [#21109644]
What is GPIO Doctor in the OpenBeken web app, and how can it help identify LEDs, buttons, and relays on a LoraTap switch?
GPIO Doctor is an OpenBeken web-app tool for probing GPIO behavior and testing pin roles interactively. The thread recommends it to discover whether more LEDs exist than the template shows and to experiment safely with LED inversions and channel links. One user used the GPIO finder workflow to reach a working LED configuration for P6, P8, and P24. It is especially useful when the PCB differs from the published SC400W-EU mapping. [#20978313]
OpenBeken autoexec script vs a native shutter driver — which approach is better for percentage-based blind control on LoraTap switches?
Use autoexec.bat for immediate results, but prefer the native shutter driver for cleaner 0–100% control. The thread shows scripts work well for Open, Close, Stop, timers, and MQTT-exposed duration fields, but percentage logic quickly becomes complex. Later, the maintainer stated, “We have a new working native driver for shutters,” which makes the driver path the better long-term choice when your firmware supports it. For quick deployment, script first; for maintainability, move to the driver. [#21856035]
How can I implement or test percentage slider control for shutters in OpenBeken so Home Assistant can set the blind position from 0 to 100%?
Implement it by separating full-travel time from current position. The thread’s proposed logic uses one channel for full open/close duration, another for current or saved position, and a Slider-type channel with a 0–100 range as the target. Then the script normalizes the requested change and runs open or close long enough to move that percentage. A later shared script used channels 9, 10, and 11 for saved, current, and target position, plus channels 20–22 for Down, Stop, and Up controls. [#21484624]
What causes OpenBK7231T_App builds to fail under WSL, and how do lib32z1, python-is-python3, line endings, Cygwin, and Docker compare as build options?
WSL failed for two concrete reasons in the thread: missing lib32z1 and missing python-is-python3. One user also hit /bin/sh^M: no such file or directory, which points to Windows CRLF line endings. After installing both packages, the WSL build succeeded. Another participant reported WSL still failed on their side and recommended Cygwin as the proven option, while also noting an alternative Docker build system existed in the repository. This makes Cygwin the known-good path and WSL workable after fixes. [#20994640]