GOSUND LB3
Describe the problem you have/What new integration you would like
Hi. Tommorow i recive my new light table led GOSUND LB3. Maybe is any person who implement to this lamp EDPHome and can tell me and send me config for this lamp ? Or maybe who can help me please.
https://rcpro.pl/product-pol-19418-Inteligentna-lampka-nocna-Gosund-LB3.html Please describe your use case for this integration and alternatives you've tried:
Additional context
Any news ?
Hi I just received this device today and did some tests and I have good news for you (and probably others).
Status so far:
- It's ESP8266EX
- It's not convertible by tuya-convert
- PCB has serial pinouts on hidden side (need to remove pcb from device for first flashing)
- Flashed with esphome using serial sucessfully (sample config below)
- GPIO: GPIO13 = WLED PWM GPIO12 = G_LED PWM GPIO5 = B_LED PWM GPIO15 = R_LED PWM
TODO: There is i2c touch sensor for side touch "buttons", it's On-Chip IC. Haven't found any info about it yet.
substitutions:
devname: mynitebird
output:
- id: "${devname}_output_wled"
platform: esp8266_pwm
pin: GPIO13
frequency: 1000 Hz
- id: "${devname}_output_gled"
platform: esp8266_pwm
pin: GPIO12
frequency: 1000 Hz
- id: "${devname}_output_bled"
platform: esp8266_pwm
pin: GPIO5
frequency: 1000 Hz
- id: "${devname}_output_rled"
platform: esp8266_pwm
pin: GPIO15
frequency: 1000 Hz
light:
- platform: monochromatic
name: "${devname}_wled"
id: "${devname}_wled"
output: "${devname}_output_wled"
- platform: monochromatic
name: "${devname}_gled"
id: "${devname}_gled"
output: "${devname}_output_gled"
- platform: monochromatic
name: "${devname}_bled"
id: "${devname}_bled"
output: "${devname}_output_bled"
- platform: monochromatic
name: "${devname}_rled"
id: "${devname}_rled"
output: "${devname}_output_rled"
@jkolczasty
Thanks for what you posted above, I appreciate your work. I wanted to share back what added progress I've been able to make (though I'm a Tasmota user). The I2C bus is on the following GPIOs:
GPIO2 - I2C SDA GPIO14 - I2C SCL
I was able to query what is (I think) both bus 1 and bus 2 and found devices at address 0x39 and 0x45. This does not explicitly apply to a specific driver that I've found yet, I guess I need to pop the bottom off the light again and try to read the super tiny chip again (arg!).
If I figure out the chip or manage to talk to it, I'll post some more.
If it is of use to you, in trying to tune the color gamma, I found it was very weak on the red, a little weak on green, and that the white LED was very bright (when transitioning between color and white light. I can share that if it helps you, though not sure if how to translate between Tasmota and EspHome.
All the best.
It's KF8TS2716 chip. It's very same what is used in xiaomi lamps and someone already did some research on that:
https://github.com/mmakaay/esphome-xiaomi_bslamp2/blob/d97c3361b09dacbab0dc9452bdd3c3e1e1235967/doc/technical_details.md
Currently have no time to write some test code for esphome, but it's still on top of my to-do.txt file ;-)
I just found that same/slightly link! (https://github.com/mmakaay/esphome-xiaomi_bslamp2/blob/dev/doc/technical_details.md) You are totally on top of this. I've never written an i2c driver, though thinking of writing one also. I'll put a link to code here as I play with it (hopefully it's only somewhat awful!)
Are there any news on this? Has anyone gotten the touch function to work?
Had not time to look at it so far. Maybe next week will find some time ;-)
It's unclear what the alternative offered is here so I'm not sure why this was closed. Reports are that the KF8TS2716 is a generic MCU and if so the code used in the Xiaomi lamp may be different and thus the i2c commands different.
I'm using mine, remote only via MQTT (with Tasmota). Getting the touch to work would be nice, however its definitely beyond my skill level. @jkolczasty is the real pro! anyhow best to all.
Aby new about touch ?
Any news ?
So, I did reverse engineer those lamps, and got both the touch and the tap-to-turn-on features to work! The "tap-to-turn-on" is handled by a cheap MEMS accelerometer, whose support I submitted in esphome/esphome#6187. The great news is that the behavior can be heavily customized (single tap, double tap, length, intensity), and you get your lamp's acceleration as a bonus (extremely useful ofc 🤣).
The touch part (at least on my model), is (poorly) handled by a cbm7320 IC chip that talks over I2C to the ESP8266. This cbm chip is not very well put together : if the lamp is above 60% brightness the chip's touch sensing mechanism gets confused and the chip start spitting out nonsense on I2C… Also that chip is in fact a general purpose MCU with a specific firmware made to transmit touch sensing events over I2C, so I don't know if a driver makes sense for esphome.
Anyway, here's my custom config (just ignore the cbm7320 part for now). But with #6187 the da270 part works well 😄
esphome:
friendly_name: "Bedside Lamp"
esp8266:
board: esp01_1m
output:
- platform: esp8266_pwm
id: blue_led
pin: GPIO5
- platform: esp8266_pwm
id: green_led
pin: GPIO12
- platform: esp8266_pwm
id: warm_white_led
pin: GPIO13
- platform: esp8266_pwm
id: red_led
pin: GPIO15
light:
- platform: rgbw
id: main_light
name: "Light"
red: red_led
green: green_led
blue: blue_led
white: warm_white_led
i2c:
sda: GPIO2
scl: GPIO14
scan: false
frequency: 32 kHz # Matches the default firmware
external_components:
- source: components
cbm7320:
binary_sensor:
- platform: gpio
icon: 'mdi:gesture-tap-box'
pin:
number: GPIO4
mode:
input: true
pullup: false
name: "Tap Detector"
on_press:
- light.toggle: main_light
- platform: cbm7320
name: Power Button
channel: 14
on_press:
- light.toggle: main_light
- platform: cbm7320
name: Left Slider A
channel: 7
- platform: cbm7320
name: Left Slider B
channel: 8
- platform: cbm7320
name: Left Slider C
channel: 9
- platform: cbm7320
name: Left Slider D
channel: 10
- platform: cbm7320
name: Left Slider E
channel: 11
- platform: cbm7320
name: Left Slider F
channel: 12
- platform: cbm7320
name: Left Slider G
channel: 13
- platform: cbm7320
name: Right Slider A
channel: 0
- platform: cbm7320
name: Right Slider B
channel: 1
- platform: cbm7320
name: Right Slider C
channel: 2
- platform: cbm7320
name: Right Slider D
channel: 3
- platform: cbm7320
name: Right Slider E
channel: 4
- platform: cbm7320
name: Right Slider F
channel: 5
- platform: cbm7320
name: Right Slider G
channel: 6
sensor:
- platform: da217
address: 0x27
resolution: 14bits
full_scale: 4g
tap_quiet_duration: 30ms
tap_shock_duration: 70ms
double_tap_duration: 500ms
interrupt_source: unfiltered
enable_double_tap_interrupt: true
map_double_tap_interrupt_to_int1: true
tap_acceleration_threshold: 0.0625
output_data_rate: 125Hz
accel_x:
name: "Acceleration X"
accel_y:
name: "Acceleration Y"
accel_z:
name: "Acceleration z"
@Ecco Thank you so much!
FYI there's a key mismatch in your 6187 between OUTPUT_DATA_RATES in sensor.py and OutputDataRate in da217.h; one uses underscores before HZ but not the other.
Sorry to hijack this issue for a slightly off-topic question, but: Could anyone provide a link to a guide on how to flash this light via the serial port? I have connected Vcc, GND, RX and TX to a serial ftdi adapter, but esptool is unable to read/write anything - so any help would be appreciated!
I finally got around to playing with one of mine, and think I have it working "good enough".
As mentioned by others, there are signal issues when LEDs are going at high brightness which effect the touch inputs. I've done the best I can to mitigate them, but there are still quirks, where inputs will be ignored or jump unexpectedly, and there isn't a lot that can be done about it, so what you get here is about as good as it gets unless someone wants to spend a much greater amount of time trying to mitigate the oddities.
Here is the config I came up with. I will not be creating an external component for this, as I don't think it's polished well enough, and I don't desire to spend much more time on it.
esphome:
on_boot:
- priority: 600
then:
- lambda: !lambda |-
// Set up accelerometer to detect taps and signal int
id(i2c_tap_setup).write_byte(0x00, 0xA5);
id(i2c_tap_setup).write_byte(0x0F, 0x41);
id(i2c_tap_setup).write_byte(0x10, 0x07);
id(i2c_tap_setup).write_byte(0x11, 0x00);
id(i2c_tap_setup).write_byte(0x16, 0x50);
id(i2c_tap_setup).write_byte(0x19, 0x10);
id(i2c_tap_setup).write_byte(0x2A, 0x85);
id(i2c_tap_setup).write_byte(0x2B, 0x02);
i2c:
sda: GPIO2
scl: GPIO14
scan: false
frequency: 32 kHz # Matches the default firmware
i2c_device:
- id: i2c_touch_input
address: 0x2D
- id: i2c_tap_setup
address: 0x27
output:
- platform: esp8266_pwm
id: output_red
pin: GPIO15
max_power: 0.9
frequency: 500 Hz
- platform: esp8266_pwm
id: output_green
pin: GPIO12
max_power: 0.85
frequency: 500 Hz
- platform: esp8266_pwm
id: output_blue
pin: GPIO5
max_power: 0.85
frequency: 500 Hz
- platform: esp8266_pwm
id: output_warm_white
pin: GPIO13
max_power: 0.9
frequency: 500 Hz
light:
- platform: rgbw
id: light_primary
name: None
red: output_red
green: output_green
blue: output_blue
white: output_warm_white
color_interlock: true
binary_sensor:
- platform: gpio
id: sensor_tap
pin:
number: GPIO4
mode:
input: true
pullup: false
on_press:
- light.toggle: light_primary
number:
- platform: template
id: touch_input_last_value
optimistic: true
min_value: 0
max_value: 4294967295
step: 1
on_value:
then:
- lambda: !lambda |-
uint32_t dec = (int)x;
if (dec > 0 && (dec & 0xFF00FF) == dec) {
if ((dec & 0xFF) <= 0x60) {
//ESP_LOGD("TOUCH RIGHT", "0x%02X", dec & 0xFF);
id(touch_right_slider)->execute(dec & 0xFF);
} else {
//ESP_LOGD("TOUCH LEFT", "0x%02X", dec & 0xFF);
id(touch_left_slider)->execute(dec & 0xFF);
}
} else if (dec > 0 && (dec & 0x00FFFF) == dec) {
if ((dec & 0xFF) == 0x40) {
id(touch_button)->execute();
} else {
//ESP_LOGD("TOUCH LEFT", "0x%02X", dec & 0xFF);
id(touch_left_slider)->execute(dec & 0xFF);
}
} else if (dec > 0 && dec == 0x800181) {
//ESP_LOGD("TOUCH LEFT", "0x%02X", dec & 0xFF);
id(touch_left_slider)->execute(dec & 0xFF);
}
interval:
- interval: 200ms
then:
- lambda: !lambda |-
uint8_t read_data[4];
// Read data
if (id(i2c_touch_input).read(read_data, sizeof(read_data)) == 0) {
uint32_t dec = read_data[0] << 16 | read_data[1] << 8 | read_data[2];
if (id(touch_input_last_value).state != dec) {
auto call = id(touch_input_last_value).make_call();
call.set_value(dec);
call.perform();
}
//ESP_LOGI("i2c", "Received: 0x%02X 0x%02X 0x%02X 0x%02X (%i)", read_data[0], read_data[1], read_data[2], read_data[3], dec);
}
script:
- id: touch_button
then:
- light.toggle: light_primary
- id: touch_left_slider
parameters:
value: int
then:
- lambda: !lambda |-
auto call = id(light_primary).make_call();
call.set_transition_length(250); // 0.25s
switch (value) {
case 0x20: // #1
call.set_brightness(0.1);
break;
case 0x30: // #2
call.set_brightness(0.15);
break;
case 0x10: // #3
call.set_brightness(0.19);
break;
case 0x18: // #4
call.set_brightness(0.27);
break;
case 0x08: // #5
call.set_brightness(0.35);
break;
case 0x0C: // #6
call.set_brightness(0.43);
break;
case 0x04: // #7
call.set_brightness(0.51);
break;
case 0x06: // #8
call.set_brightness(0.59);
break;
case 0x02: // #9
call.set_brightness(0.67);
break;
case 0x03: // #10
call.set_brightness(0.75);
break;
case 0x01: // #11
call.set_brightness(0.83);
break;
case 0x81: // #12
call.set_brightness(0.91);
break;
case 0x80: // #13
call.set_brightness(1.0);
break;
default:
//ESP_LOGE("LEFT SLIDER", "Invalid Value: 0x%02X", value);
return;
}
call.perform();
//ESP_LOGD("LEFT SLIDER", "Value: 0x%02X", value);
- id: touch_right_slider
parameters:
value: int
then:
- lambda: !lambda |-
auto call = id(light_primary).make_call();
call.set_transition_length(0); // 0s
call.set_color_mode(ColorMode::RGB);
call.set_white(0);
// evens are "between" states where it thinks both odds are selected
// but upon release, it will almost always shift to an odd, so latch
// evens to the nearest odd to lessen release jumping
switch (value) {
case 0x01: // #1
call.set_color_mode(ColorMode::WHITE);
call.set_rgb(0, 0, 0);
call.set_white(1);
break;
case 0x03: // #2
case 0x02: // #3
call.set_rgb(1.0, 0.8, 0); // yellow
break;
case 0x06: // #4
case 0x04: // #5
call.set_rgb(1.0, 0, 0.65); // purple
break;
case 0x0C: // #6
case 0x08: // #7
call.set_rgb(1.0, 0.45, 0); // orange
break;
case 0x18: // #8
case 0x10: // #9
call.set_rgb(0, 0, 1.0); // blue
break;
case 0x30: // #10
case 0x20: // #11
call.set_rgb(0, 1.0, 0); // green
break;
case 0x60: // #12
case 0x40: // #13
call.set_rgb(1.0, 0, 0); // red
break;
default:
//ESP_LOGE("RIGHT SLIDER", "Invalid Value: 0x%02X", value);
return;
}
call.perform();
//ESP_LOGD("RIGHT SLIDER", "Value: 0x%02X", value);
A couple notes:
- this config is for control only, make sure to properly fill out your device name, wifi, ota, etc as needed
- The touch sensor detects 7 unique positions, but has "in-between" states where it thinks two values are both active. For brightness it doesn't make much of a difference, so I just let it do whatever is active at the time, but it will slightly jump upon release. For the color selector side, it is too jarring, so I locked to one direction. There can still be jumping on release, but it should be somewhat tolerable.
- At high brightness, touch inputs can get stuck beyond our control. I've mitigated as best I can by adjusting output
frequencyandmax_power, you may need to tweak them further.- I would not recommend using the color cyan (green+blue) or full RGB white (red+green+blue) as those colors cause the most noise for touch input
- You can set whatever colors on the color slider you wish (minding the warning above), I just chose some at random.
- The touch interval is set to 200ms. It can go every loop (0ms), however, it seems to register more double-touches, 200ms was my happy medium, adjust to taste
- debugging lines are all commented out, uncomment if you want to try to get a better idea of where things might be failing.
Feel free to post if there are any obvious improvements found.