Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add yeelink.light.fancl5 support #42

Open
0neday opened this issue Jul 18, 2022 · 144 comments
Open

Add yeelink.light.fancl5 support #42

0neday opened this issue Jul 18, 2022 · 144 comments
Labels
enhancement New feature or request esp32

Comments

@0neday
Copy link
Contributor

0neday commented Jul 18, 2022

RT,

thank you

@syssi
Copy link
Owner

syssi commented Jul 18, 2022

You could open the device and provide some photos. If you own a multimeter I could provide some instructions how to collect all required infos.

@0neday
Copy link
Contributor Author

0neday commented Jul 18, 2022

You could open the device and provide some photos. If you own a multimeter I could provide some instructions how to collect all required infos.

thank you, I have multimeter, I will give you some postion of gpio, such as gpio0, rx, tx ...

@syssi
Copy link
Owner

syssi commented Jul 19, 2022

Some high-res photos of the mainboard especially the WiFi daughter board are important. In best case the pin header between the mainboard and the daughter board is labeled.

Are you able to control different speed levels of the ceiling fan using the app?

@0neday
Copy link
Contributor Author

0neday commented Jul 19, 2022

Are you able to control different speed levels of the ceiling fan using the app?

using Mijia app, I can control fan speed.

@syssi
Copy link
Owner

syssi commented Jul 19, 2022

How many levels?

@0neday
Copy link
Contributor Author

0neday commented Jul 19, 2022

3 level speed, it use uart communicate between esp32 and bp8601

@syssi
Copy link
Owner

syssi commented Jul 19, 2022

You could use a logic analyzer (something like this https://de.aliexpress.com/item/1005002511491492.html or https://de.aliexpress.com/item/1005003812410259.html) plus a open-source software called sigrok/pulseview to capture the serial traffic between the ESP and the driver board of the fan. As soon as we know the messages here we can try to replicate the communication. The ceiling lamp is working already? What's working and what's not if you flash your yaml? Did you make a backup of the stock firmware?

@0neday
Copy link
Contributor Author

0neday commented Jul 19, 2022

no, I have not flash esphome, I just test UART using a usb-ttl tools, and get

brownout detector 

when I set gpio0 = low level, it could enter into flash mode.

I can not get gpio for light., the gpio of my yaml is copy from your's, do not test.

Do you any decompiled circuit diagram of yeelight ceiling?

@syssi
Copy link
Owner

syssi commented Jul 19, 2022

The brownout detector is triggered if the power supply is not strong enough. I assume you did power the ESP using the USB-TTL converter. Cheap converters (f.e. PL2303) doesn't provide enough current to power an ESP. You should/could use an external power supply.

If you are able to enter the flash mode please make a backup of the firmware. Please follow this guide:

https://github.com/mmakaay/esphome-xiaomi_bslamp2/blob/dev/doc/flashing.md#make-a-backup-of-the-current-firmware

I don't have any circuit diagrams. How to identify the PWM GPIOs:

  1. Power the ESP32 properly. You must be able to control the device using your Android app. It's fine if you power the ESP only.
  2. Connect the USB-to-TTL module to RX, TX and GND. You should see debug messages of the stock firmware
  3. Turn the light on and change the color temperature to 100% warm-white
  4. Measure the voltage between GND and every GPIO. You should find a GPIO providing 3.3V (PWM=100%).
  5. Set the warm white brightness to 50%. Measure again. You should find a GPIO providing 1.5-2V now (PWM=50%).
  6. Set the warm white brightness to the lowest value (1%?). Measure again.

Follow the same steps to identify the cold-white PWM GPIO and the Night Light PWM GPIO. It's possibe there is a feature called "power supply standby" (STB). This is a GPIO which drives/turns on the power supply if you turn on the light (Voltage between GND and STB should be 3.3V). If you turn off the light the voltage should drop to 0V.

Please try to identify these GPIOs so you are able to control the ceiling light. The next step will be the reverse engineering of the fan. I'm afraid a logic analyzer is required here. I could provide some guidance how to use sigrok to decode the serial traffic between the ESP and the driver board of the fan.

@syssi
Copy link
Owner

syssi commented Jul 19, 2022

Another wish/suggestion:

  1. Please use a continuity tester or a ohm meter to measure the continuity between the test points (TP1, TP5) and the GPIOs of the ESP. I bet GPIO0 is exposed as test point.
  2. Use a continuity tester or a ohm meter to measure the continuity between CON2 (connector 2) of the fan driver board (EN, WIFI, TXD, RXD, (GND)) and the GPIOs of the ESP.
  3. Could you provide the label / model identifier of IC2? I assume it's an EEPROM and connected via I2C (2 GPIOs, VCC, GND). If we know the type we can lookup the pinout and identify the SDA and SCL pins connected to the ESP.
  4. There is a piezo buzzer labeled with BP1. I assume the buzzer is somehow connected to the ESP. Usually a piezo isn't connected directly to the ESP. I assume there is an NPN transistor in between. Do you know how to let the device beep?
  5. Please provide the type / model identifier of the 24 pin IC located at the fan driver board. I've trouble to identify the label.

@syssi syssi changed the title please support yeelink.light.fancl5 Add yeelink.light.fancl5 support Jul 19, 2022
@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

Measure the voltage between GND and every GPIO. You should find a GPIO providing 3.3V (PWM=100%).

you are genius!

Do you know how to let the device beep

when use remote controller and tap any key, the buzzer beep a time.

label / model identifier of IC2
provide the type / model identifier of the 24 pin IC located at the fan driver board

I will provide the label of IC, wait some time

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

test result is :

cold --> gpio21
warn --> gpio19
night mode ---> gpio23

so, the light gpio is same as yeelink.light.ceiling15

ps:
I have question is except for fan, there is a remote controller, that is connected by bluetooth.

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

Could you provide a photo of your remote control? I assume it's the standard BLE remote talking to the ESP. It's known how to receive commands from these kind of remotes but we shouldn't try to support the remote control at the first iteration. I would be happy if we focus on the ceiling light and fan feature.

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

Did you backup the stock firmware?

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

Did you backup the stock firmware?

yes, I have

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

The remote control is the standard bluetooth remote control of yeelight fans. I assume it's the 0x068E: "YLYK01YL-FANCL". If you want to receive commands using Home Assistant you could use this custom component: https://github.com/custom-components/ble_monitor/

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

It looks like you managed to flash the ESP32. If you don't want to buy a logic analyzer I could provide some instruction how to piggy back another ESP (running esphome to dump some traffic) to the serial line between the ESP and the fan driver board. The idea is to sniff the traffic between these two components to get a better understanding how to replicate the communication.

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

back another ESP (running esphome to dump some traffic) to the serial line between the ESP

that is a good idea! I have a nodemcu esp32 , I will to flash stock firmware into it , and check what happed

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

the buzzer beep is for fan mcu BP6601, check here https://bbs.elecfans.com/jishu_1868688_1_1.html

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

you want to receive commands using Home Assistant you could use this custom component

nop, I want to use esphome to execute animation.

I use ble tracker to get remote controller adversie data, like

# for fan
[21:53:04][D][ble_adv:107]:     - 0xFE95: (length 17)  - 50.30.8E.06.8B.0B.85.6E.38.C1.A4.01.10.03.00.00.00 (17)
# for light
[21:52:09][D][ble_adv:107]:     - 0xFE95: (length 17)  - 50.30.8E.06.89.0B.85.6E.38.C1.A4.01.10.03.01.00.00 (17)
# for recirculating air
[21:54:25][D][ble_adv:107]:     - 0xFE95: (length 17)  - 50.30.8E.06.8E.0B.85.6E.38.C1.A4.01.10.03.02.00.00 (17)
....

so, just use esphome to get adversie data and using xor get third-to-last byte and compare, and using on_... to execute .

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

In the past the single core ESP32 of the yeelight devices did crash if you try to use the BLE tracker at your configuration yaml. Some remote controls are encrypted and the bind_key is required to decrypt the data. Do you know my implementation of the ceiling lamp remote control?

https://github.com/syssi/esphome-yeelight-ceiling-light/blob/main/yeerc_ylyk01yl.yaml

This implementation can be easily extended to support the yeerc_fancl remote control. Please keep in mind: A dual core ESP32 is required to avoid the boot loop.

I've replaced the single core ESP32 of some of my lights to be able to use bluetooth without trouble.

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

single core ESP32 of the yeelight devices did crash

I know this issue, but it could be fixed by add delay vTaskDelay(10/portTICK_PERIOD_MS); on_loop to avoid loop reboot

esphome:
  name: yeelight-c900
  platformio_options:
    platform_packages:
     - framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.6
 
  on_loop:
   - lambda: |
        vTaskDelay(10/portTICK_PERIOD_MS);

I use framework is - framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.6 that support OTA web.

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

I know this issue, but it could be fixed by add delay vTaskDelay(10/portTICK_PERIOD_MS); on_loop to avoid loop reboot

Wow. Good job! I didn't know about this solution.

I use framework is - framework-arduinoespressif32 @ https://github.com/pauln/arduino-esp32.git#solo-no-mac-crc/1.0.6 that support ota web.

I prefer ESP-IDF over the Arduino framework. I flash my esphome nodes using esphome run config.yaml + ota: component.

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

the buzzer beep is for fan mcu BP6601, check here https://bbs.elecfans.com/jishu_1868688_1_1.html

Could you help me to download provide the two attachments?

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

maybe, we could use decompile engineering to check how control fan
https://github.com/jsandin/esp-bin2elf

@syssi
Copy link
Owner

syssi commented Jul 20, 2022

I've no experience with reverse engineering of ELF executables. This is the way I would choose:

  1. Identify the GPIOs attached to con2 the pin header between the mainboard and the fan driver board.
  2. Flash the backup of the stock firmware to another ESP32. Try to boot. It's likely the ESP doesn't boot/crashs because peripherals (EEPROM?) isn't available or the MAC address doesn't match. If the ESP boots connect the USB-TTL converter to the RX/TX pins of the con2 GPIOs. Use the android app to start/stop/control the fan. Try different baudrates. Do you see some messages/control instructions?
  3. If step 2 isn't successful flash the stock firmware back to the yeelight single core ESP32. Let the ESP boot and sniff the traffic at con2 again without having the fan driver board attached.

Some more ideas:

  1. Attach dhe fan driver board using con2 to the ESP32 again and power the board with 5V. Don't apply the 24V. I hope this doesn't harm the device but I don't know for sure. You could attach the USB-TTL converter to the RX/TX lines of con2. Alternatively you could use another ESP (f.e. ESP8266) plus a configuration yaml like this

https://github.com/syssi/esphome-jbd-bms/blob/main/tests/esp8266-dummy-receiver.yaml

to sniff the traffic of one direction. Try to identify the baudrate. Capture the traffic/commands from the ESP. Swap the RX/TX lines and capture the responses from the fan driver board (hopefully the board responds). If this doesn't work I would attach a 24V power source too to make the fan driver board happy.

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

Identify the GPIOs attached to con2 the pin header

I try to identify, but failed! the board have a layer of insulating glue.

You could attach the USB-TTL converter to the RX/TX lines of con2.

bewteen rx, tx of con2 and gpio, there is some divider resistor, the voltage rx and tx is 2V

@0neday
Copy link
Contributor Author

0neday commented Jul 20, 2022

Do you know my implementation of the ceiling lamp remote control?

I have check your external_components, but I have no idea how to get it work.

I use

# BLE    
esp32_ble_tracker:
  on_ble_advertise:
    - mac_address: A4:C1:38:6E:85:0B
      then:
        - lambda: |-
            for (auto data : x.get_service_datas()) {
                ESP_LOGD("ble_adv", "    - %s: (length %i)  - %s", data.uuid.to_string().c_str(), data.data.size(),hexencode(data.data).c_str());
            }

to print adv data. I confirm there is no bind_key and no encryption data.

and then, use x[14] to get key code, and use if condition select

# BLE    
esp32_ble_tracker:
  on_ble_service_data_advertise:
    - mac_address: A4:C1:38:6E:85:0B
      service_uuid: FE95
      then:
         - if:
            condition: 
              lambda: "return(x[14] == 1);"
            then:
             - light.turn_on:
                id: ceiling_light
              
         - if:
            condition: 
              lambda: "return(x[14] == 4);"
            then:
             - light.turn_on:
                id: night_light

and now, I have a question is
when I tap one time, but on_ble_service_data_advertise advertise 2 times data, so when I use light.toggle, that work poorly

@0neday
Copy link
Contributor Author

0neday commented Jul 21, 2022

Identify the GPIOs attached to con2 the pin header between the mainboard and the fan driver board.

comfirm

gpio16( RX )  ---> con2 ( TX )
gpio17( TX ) ----> con2 ( RX )
EN( pin3 )  ----> con2( wifi_en )
gpio33  --->  fan_buzzer_beep

@0neday
Copy link
Contributor Author

0neday commented Jul 24, 2022

It's possible the delay is causing all this. :-(

I check your code carefully, and check esphome offical api document, and notice that

  if (now - this->last_byte_ > 50) {
    this->rx_buffer_.clear();
    this->last_byte_ = now;
  }

It will clear read buffer when period > 50 ms

@syssi
Copy link
Owner

syssi commented Jul 24, 2022

Yes. The RX buffer is cleared of the is a period of 50ms silence on the serial line. If the value is too low some received bytes can get dropped. I don't care much about the feedback of the BP6601 right now. This shouldn't cause crashes.

If you want to debug the crashes / BLE commands you could flash the configuration yaml (with another ESPHome node name) to a second ESP32.

@0neday
Copy link
Contributor Author

0neday commented Jul 24, 2022

If the value is too low some received bytes can get dropped.

yes, drop but do not cause crash.

with another ESPHome node name) to a second ESP32.

I see, I will test.

@syssi
Copy link
Owner

syssi commented Jul 24, 2022

Just pick the config yaml f.e. yeelight_light_fancl5.yaml.

Change to node name:

substitutions:
  name: yeelight-test-dummy
  external_components_source: github://syssi/esphome-yeelight-ceiling-light@main

Flash the yaml to another ESP32: esphome run test-dummy.yaml. It's no problem to have no LED driver or fan driver attached. The ESP32 should be able to receive the bluetooth frame from the remote control and will just write to the UART. The implementation doesn't care about missing response from the BP6601. If you are able to trigger the crash now you should see the exception/crash dump on the serial console (USB-to-TTL).

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

hi, when I close light (both ceiling and night light) using HA or homekit or something else, I found that the light are dim.

like this
dim.PNG

maybe there is power standby ?

when I close mechanical switch, the dim disapper.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

Do you remember the STB pin I mentioned at the beginning? It's possible there is a GPIO which should be disabled to shutdown the led driver completely.

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

there is a GPIO which should be disabled to shutdown the led driver completely.

how find this gpio

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

  1. Flash the stock firmware
  2. Use the remote control or MiHome App to turn the ceiling lamp on and off.
  3. Check all GPIOs (measure the voltage between GPIO and GND) and turn the lamp on/off. You should find a GPIO which is flipped on every state change.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

If you are able to control the stock firmware using a second ESP32 you could avoid to flash the stock firmware to your lamp again. But I assume the remote control cannot be paired with the second ESP32 easily.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

There is a brute-force and a bit risky brute-force solution if you don't want to flash the stock firmware again:

  1. Extend your config yaml by a switch entity per available GPIO please exclude the already known PWM und UART GPIOs
  2. Boot the lamp. Turn the lamp on and flip every new switch once. The lamp should turn of/off at one of the switches.

A bet GPIO3 is the one we are looking for.

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

I use switch component

switch:
  - platform: gpio
    pin: GPIO32
    name: gpio32

for every gpio not used before. turn on or off, no lucky happed!
the high level have

gpio 35 32 25 14 15 5

the low level have

gpio 34 26 27 12 13 2 4 18 22

turn on/off all of these, not find what change.

except gpio 34 - 39 , because it is not for output.

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

cannot be paired with the second ESP32 easily.

no, paired easy

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

Turn the lamp on and flip every new switch once. The lamp should turn of/off at

need turn on ceiling or night light?

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

A bet GPIO3 is the one we are looking for.

gpio3 is for uart rx0, so are you sure?

I measure uart voltage, the rx is 3.1v
tx is 3.6v

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

need turn on ceiling or night light

I would turn on/off the ceiling light but it doesn't matter. Both lamps cannot work if the power supply is turned off.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

EN( pin3 )  ----> con2( wifi_en )

You did discover the enable pin of the fan driver. My hope was this is a shared pin and is used to enable/disable the fan and lamp power supply. It's possible we are on the wrong track here.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

The logic level of the GPIO must change if you toggle the light. If the level doesn't change it's not the GPIO we are looking for.

If there is no STB GPIO to control the power supply I assume the power supply is always on and we have to improve the PWM settings to turn off the LEDs properly.

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

I would turn on/off the ceiling light but it doesn't matter. Both lamps cannot work if the power supply is turned off.

test all possible gpio, have not lucky, maybe It does not support STB

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

You did discover the enable pin of the fan driver. My hope was this is a shared pin and is used to enable/disable the fan and lamp power supply. It's possible we are on the wrong track here.

pin3 is for INPUT, and it always have high level. so it maybe do not control by software

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

In case of a serial connection GPIO3 is used as input. IMO you can use the pin as standard GPIO. If you did configure the GPIO to pull-down and it doesn't affect the level/voltage I agree: It looks like the pin is used as INPUT pin.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

Could you explain how to pair a remote to the ESP32? I would like to give it a try.

@0neday
Copy link
Contributor Author

0neday commented Jul 26, 2022

Could you explain how to pair a remote to the ESP32? I would like to give it a try.

because this remote controller communication without encrytion, so what it submit data could be recieved by any BLE device. so, there is no pair produce, they communiction just use broadcast.

@syssi
Copy link
Owner

syssi commented Jul 26, 2022

And if you own two ceiling lamps you are in trouble? How do I teach the ESP32 (stock firmware) the MAC address of the remote control?

@0neday
Copy link
Contributor Author

0neday commented Jul 29, 2022

And if you own two ceiling lamps you are in trouble?

no trouble is here. because you need write MAC address of remote controller

xiaomi_ylyk01yl:
  # change mac_address here
  mac_address: "A4:C1:38:6E:85:0B"

How do I teach the ESP32 (stock firmware) the MAC address of the remote control

press light and M key simultaneously and release immediately,and then the indicator light of remote controller will flicker

@0neday
Copy link
Contributor Author

0neday commented Jul 31, 2022

I check LED ceiling light and night light connection on board

微信图片_20220731094438.png

show ceiling light and night light positive electrode connection together
IMG_0124.JPG

so, maybe control light using negative electrode

so, maybe there is a power supply gpio to control light positive electrode

there is a any another method to find this gpio

@syssi
Copy link
Owner

syssi commented Jul 31, 2022

I would try to compare the PWM signal and voltages between the stock firmware and the new one. If you are able to make the PWM visible we can get a better understanding what's the difference between both implementations.

@0neday
Copy link
Contributor Author

0neday commented Aug 4, 2022

I have decompile circuit diagram.

IMG_0140.JPG

after close ceiling light and night light, measure voltage

w+/c+ and gnd = 300v
c- and gnd = 300v
w+/c+ and c- = 0v

but

w+/c+ and w- = 3v
w- and gnd = 3v 

because w+/c+ and gnd = 300v

so the voltage should be
w+/c+ and w- = 297v

all chip datasheet is here
https://github.com/0neday/yeelight-c900/blob/main/bp2887_bp5711.pdf

@syssi
Copy link
Owner

syssi commented Aug 15, 2022

@avion23 Any ideas how to solve this issue? I am out of ideas.

@avion23
Copy link

avion23 commented Aug 15, 2022

I'm not sure what the problem is and I don't fully understand what the circuit does :)

  • the circuit will be 'hot'. You shouldn't do this, unless you are an electrician, and then you wouldn't do it ;)
  • you might be able to get lower voltages if you plug it in the other way around
  • the voltages need to be sinked, so if you measure, you should measure with a load. Easiest is the LED
  • Big guess: BP5711 is for the common power, BP2887 distributes the power between the two channels
  • so you need to always turn on BP5711 if you want to have light
  • And then the power is split up in the ratio of the two BP2887
  • You could start with a linear distribution between the two PWMs, i.e. PWM_CW + PWM_WW = 100%
  • It's common anode, that's why I'm guessing this

@0neday
Copy link
Contributor Author

0neday commented Aug 16, 2022

@avion23 thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request esp32
Projects
None yet
Development

No branches or pull requests

3 participants