I managed to use the ltchiptool to backup then flash libretiny over serial onto a couple of generic tuya wifi touch switches that I bought from eBay (no cloudcutter profile worked). They have a tiny surface-mount BK7321N chip soldered directly onto the PCB.
The YAML generated by ltchiptool got the touch switches and relays working, but the backlight for the touch switches was all wonky.
I worked out that P28 had to be on to enable the blue “off state” backlight for buttons 1 and 3, but nothing happened for button 2. It just stays off.
With P28 enabled, buttons 1 and 3 change from blue to red when on. This is the proper behaviour.
Button 2 has no backlight whether off or on.
Can one of you experts please help me out? Either:
- Maybe there is a clue in the JSON from the original that just wasn’t converted to yaml properly?
Please help me to work out what’s missing and how to add it. - If I can find this information somewhere, please give me some directions. I can’t work it out.
Here is the JSON from the backup:
Expand
{
"gw_bi": {
"uuid": "dd77e010871e2d84",
"psk_key": "kHI2JHHYjCtEj4ju3EvcKcG1cNfJpgURDaUjg",
"auth_key": "9TeTkBgIRE9okiiu8pbWWeAo4u9jZipB",
"ap_ssid": "SmartLife",
"ap_passwd": null,
"country_code": "CN",
"bt_mac": null,
"bt_hid": null,
"prod_test": false,
"fac_pin": "qpalfe6ashfu7bbx"
},
"user_param_key": {
"backlit_dp": 16,
"backlit_io_lv": 1,
"backlit_io_pin": 28,
"backlit_select": 1,
"bt1_lv": 0,
"bt1_pin": 6,
"bt2_lv": 0,
"bt2_pin": 9,
"bt3_lv": 0,
"bt3_pin": 16,
"bt_type": 1,
"cd_flag2": 1,
"ch_cddpid1": 7,
"ch_cddpid2": 8,
"ch_cddpid3": 9,
"ch_dpid1": 1,
"ch_dpid2": 2,
"ch_dpid3": 3,
"ch_flag1": 1,
"ch_flag3": 1,
"ch_num": 3,
"crc": 123,
"cyc_dpid": 17,
"inch_dp": 19,
"init_conf": 14,
"jv": "1.0.0",
"led1_lv": 1,
"led1_pin": 8,
"led2_lv": 1,
"led2_pin": 15,
"led3_lv": 1,
"led3_pin": 26,
"led_dp": 15,
"light_status_select": 1,
"module": "CBU",
"net_trig": 4,
"rand_dpid": 18,
"reset_t": 6,
"rl1_lv": 1,
"rl1_pin": 7,
"rl2_lv": 1,
"rl2_pin": 14,
"rl3_lv": 1,
"rl3_pin": 17,
"total_stat": 2
},
"light_mode_en": 1,
"save_off_stat": {
"power": [
false,
false,
false,
false,
false
]
},
"tls_ca_cnt": 0,
"gw_wsm": {
"nc_tp": 4,
"ssid": "Sy1Xb2lGb2lfMi40",
"passwd": "MUNvcjEzOjhsbmY=",
"md": 0,
"random": 0,
"wfb64": 1,
"stat": 2,
"token": "t1Tn4gsA",
"region": "EU",
"reg_key": "4PUn",
"dns_prio": 2
},
"init_stat_save": {
"def_mode": 2
},
"wf_start_md": 3,
"is_stride": 0,
"backlit_en": "\u0001",
"000004cnb1": [
{
"type": "obj",
"mode": "rw",
"property": {
"type": "bool"
},
"id": 1
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "bool"
},
"id": 2
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "bool"
},
"id": 3
},
{
"type": "obj",
"mode": "rw",
"property": {
"min": 0,
"max": 86400,
"scale": 0,
"step": 1,
"type": "value"
},
"id": 7
},
{
"type": "obj",
"mode": "rw",
"property": {
"min": 0,
"max": 86400,
"scale": 0,
"step": 1,
"type": "value"
},
"id": 8
},
{
"type": "obj",
"mode": "rw",
"property": {
"min": 0,
"max": 86400,
"scale": 0,
"step": 1,
"type": "value"
},
"id": 9
},
{
"type": "obj",
"mode": "rw",
"property": {
"range": [
"off",
"on",
"memory"
],
"type": "enum"
},
"id": 14
},
{
"type": "obj",
"mode": "rw",
"property": {
"range": [
"none",
"relay",
"pos"
],
"type": "enum"
},
"id": 15
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "bool"
},
"id": 16
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "string",
"maxlen": 255
},
"id": 17
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "string",
"maxlen": 255
},
"id": 18
},
{
"type": "obj",
"mode": "rw",
"property": {
"type": "string",
"maxlen": 255
},
"id": 19
},
{
"type": "obj",
"mode": "rw",
"property": {
"range": [
"switch",
"linkage_control"
],
"type": "enum"
},
"id": 35
},
{
"type": "obj",
"mode": "rw",
"property": {
"range": [
"switch",
"linkage_control"
],
"type": "enum"
},
"id": 36
},
{
"type": "obj",
"mode": "rw",
"property": {
"range": [
"switch",
"linkage_control"
],
"type": "enum"
},
"id": 37
},
{
"trigger": "direct",
"type": "obj",
"mode": "rw",
"property": {
"range": [
"single_click",
"double_click",
"long_press"
],
"type": "enum"
},
"id": 41
},
{
"trigger": "direct",
"type": "obj",
"mode": "rw",
"property": {
"range": [
"single_click",
"double_click",
"long_press"
],
"type": "enum"
},
"id": 42
},
{
"trigger": "direct",
"type": "obj",
"mode": "rw",
"property": {
"range": [
"single_click",
"double_click",
"long_press"
],
"type": "enum"
},
"id": 43
}
],
"timer_arr": {
"lastFetchTime": 0,
"cnt": 0
},
"gw_di": {
"abi": 0,
"id": "bf7943fa3ec86c8692jah7",
"swv": "1.0.1",
"bv": "40.00",
"pv": "2.2",
"lpv": "3.3",
"pk": "keyfk4gt95hqky4p",
"firmk": "keyfk4gt95hqky4p",
"cadv": "1.0.3",
"cdv": "1.0.0",
"dev_swv": "1.0.1",
"s_id": "000004cnb1",
"dtp": 0,
"sync": 0,
"attr_num": 0,
"mst_tp_0": 0,
"mst_ver_0": null,
"mst_tp_1": 0,
"mst_ver_1": null,
"mst_tp_2": 0,
"mst_ver_2": null,
"mst_tp_3": 0,
"mst_ver_3": null
},
"em_sys_env": "bk7231n",
"gw_ai": {
"key": "N/d1SdV!9=E'/9N-",
"lckey": "BK?vMKuV^(?@O2MS",
"h_url": "http://a.tuyaeu.com/d.json",
"h_ip": "3.67.217.150",
"hs_url": null,
"hs_ip": null,
"hs_psk": "https://a3.tuyaeu.com/d.json",
"hs_psk_ip": "18.195.249.137",
"mqs_url": null,
"mqs_ip": null,
"mq_url": "m2.tuyaeu.com:1883",
"mq_ip": "3.67.242.33",
"ai_sp": null,
"ai_sp_ip": null,
"mq_psk": "m2.tuyaeu.com:8886",
"mq_psk_ip": "3.67.242.33",
"time_z": "+10:00",
"s_time_z": "[[1696089600,1712419200],[1728144000,1743868800]]",
"wx_app_id": null,
"wx_uuid": null,
"dy_tls_m": 2,
"cloud_cap": 1025,
"psk21_key": null
},
"mf_test_close": true
}```
Here is the YAML from ESPhome that I am using:
Expand
esphome:
name: sw-wifi-laundry-top
friendly_name: sw_wifi_laundry_top
bk72xx:
board: generic-bk7231n-qfn32-tuya
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret api_encryption_key
ota:
password: !secret ota_password
wifi:
ssid: !secret my_wifi_ssid
password: !secret my_wifi_pwd
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Sw-Wifi-Laundry-Top"
password: !secret ap_password
captive_portal:
web_server:
mdns:
text_sensor:
- platform: libretiny
version:
name: LibreTiny Version
output:
- platform: libretiny_pwm
id: output_led_1
pin: P8
- platform: libretiny_pwm
id: output_led_2
pin: P15
- platform: libretiny_pwm
id: output_led_3
pin: P26
light:
- platform: binary
id: light_switch_1
output: output_led_1
- platform: binary
id: light_switch_2
output: output_led_2
- platform: binary
id: light_switch_3
output: output_led_3
binary_sensor:
- platform: gpio
id: binary_switch_1
pin:
number: P6
inverted: true
mode: INPUT_PULLUP
on_press:
then:
- switch.toggle: switch_1
- platform: gpio
id: binary_switch_2
pin:
number: P9
inverted: false
mode: INPUT_PULLUP
on_press:
then:
- switch.toggle: switch_2
- platform: gpio
id: binary_switch_3
pin:
number: P16
inverted: true
mode: INPUT_PULLUP
on_press:
then:
- switch.toggle: switch_3
switch:
- platform: gpio
id: switch_1
name: Relay 1
pin: P7
on_turn_on:
- light.turn_on: light_switch_1
on_turn_off:
- light.turn_off: light_switch_1
- platform: gpio
id: switch_2
name: Relay 2
pin: P14
on_turn_on:
- light.turn_on: light_switch_2
on_turn_off:
- light.turn_off: light_switch_2
- platform: gpio
id: switch_3
name: Relay 3
pin: P17
on_turn_on:
- light.turn_on: light_switch_3
on_turn_off:
- light.turn_off: light_switch_3
status_led:
pin:
number: P28
inverted: yes
I’ve been messing around changing states etc with the unused GPIO pins all day and still nothing works. (The status led definition at the bottom of the yaml makes the backlight on buttons 1 and 3 flash while initialising then stays on once it is connected, but I think that is supposed to happen on a different button backlight.)
Is there anything else I need to include?
This is what it should look like with one switch on (this switch-plate has 2x 3 gang modules side-by-side.)