Open 0neday opened 2 years ago
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.
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 ...
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?
Are you able to control different speed levels of the ceiling fan using the app?
using Mijia app, I can control fan speed.
How many levels?
3 level speed, it use uart communicate between esp32 and bp8601
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?
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?
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:
I don't have any circuit diagrams. How to identify the PWM GPIOs:
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.
Another wish/suggestion:
TP1
, TP5
) and the GPIOs of the ESP. I bet GPIO0
is exposed as test point.CON2
(connector 2) of the fan driver board (EN
, WIFI
, TXD
, RXD
, (GND
)) and the GPIOs of the ESP.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.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?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
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.
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.
Did you backup the stock firmware?
Did you backup the stock firmware?
yes, I have
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/
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.
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
the buzzer beep is for fan mcu BP6601, check here https://bbs.elecfans.com/jishu_1868688_1_1.html
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 .
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.
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.
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.
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?
maybe, we could use decompile engineering to check how control fan https://github.com/jsandin/esp-bin2elf
I've no experience with reverse engineering of ELF executables. This is the way I would choose:
con2
the pin header between the mainboard and the fan driver board.con2
GPIOs. Use the android app to start/stop/control the fan. Try different baudrates. Do you see some messages/control instructions?con2
again without having the fan driver board attached.Some more ideas:
con2
. Alternatively you could use another ESP (f.e. ESP8266) plus a configuration yaml like thishttps://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.
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
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
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
bewteen rx, tx of con2 and gpio, there is some divider resistor, the voltage rx and tx is 2V
I assume the fan driver board runs at 5V and the logic level of the serial interface of the BP6601 is 5V too. To shift the logic level to 3.3V (because the ESP isn't 5V tolerant) the voltage divider is used. You could measure the voltage between TX and GND at the BP6601 to prove this assumption.
when I tap one time, but on_ble_service_data_advertise advertise 2 times data, so when I use light.toggle, that work poorly
There is a counter at the frame which is increased per button press:
The external component tracks the counter value and discards duplicates. I'm busy today and will provide some more input how to improve and use the external component tomorrow.
How to use / extend the external component:
This instructions clones the remote repository every time you compile your configuration:
external_components:
- source: github://syssi/esphome-yeelight-ceiling-light@main
refresh: 0s
To be able to make local changes you have to clone the repository manually:
git clone git@github.com:syssi/esphome-yeelight-ceiling-light.git
And let the external component configuration point to the local checkout / directory:
external_components:
- source: components
refresh: 0s
Now you can make changes here:
components/xiaomi_ble/xiaomi_ble.cpp
We need a new block for your device like this:
} else if ((raw[2] == 0x53) && (raw[3] == 0x01)) { // Yeelight Remote Control YLYK01YL
result.type = XiaomiParseResult::TYPE_YLYK01YL;
result.name = "YLYK01YL";
Your device type idenfier is 0x068E
. As next step (I assume) we need a new directory for the device implementation. May be your remote control is pretty similar to the YLYK01YL. In this case we could just extend the existing implementation. This diff should help to get a better understanding how a full device implementation looks like:
Could you provide the bluetooth name of your remote control? I assume it's advertised and part of your ESPHome log at the very beginning.
I assume this GPIO must be enable/pulled to start/enable the fan driver board:
EN( pin3 ) ----> con2( wifi_en )
Could you provide the bluetooth name of your remote control? I assume it's advertised and part of your ESPHome log at the very beginning.
yee-rc
The external component tracks the counter value and discards duplicates. I'm busy today and will provide some more input how to improve and use the external component tomorrow.
have a good day, thank you very much
yee-rc
Is there a model identifier on the back (under the sticker?) or somewhere?
when I tap one time, but on_ble_service_data_advertise advertise 2 times data, so when I use light.toggle, that work poorly
There is a counter at the frame which is increased per button press:
The external component tracks the counter value and discards duplicates. I'm busy today and will provide some more input how to improve and use the external component tomorrow.
thank you, I have fixed by defined global variable frame_counter
and use if condition and
globals:
- id: frame_counter
type: int
initial_value: '0'
# 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 && id(frame_counter) != x[4]);"
then:
- lambda: |-
id(frame_counter) = x[4];
id(yeelight_remote_controller).publish_state(x[14]);
- switch.turn_on: buzzer_beep
- light.toggle: ceiling_light
- if:
condition:
lambda: "return(x[14] == 4 && id(frame_counter) != x[4]);"
then:
- lambda: |-
id(frame_counter) = x[4];
id(yeelight_remote_controller).publish_state(x[14]);
- switch.turn_on: buzzer_beep
- light.toggle: night_light
yee-rc
Is there a model identifier on the back (under the sticker?) or somewhere?
no any identifier, maybe is a DIY product, just know the chip of ble is TLSR8267
sniff uart communication data fromat is
[D][uart_debug:114]: <<< 01:01:01:13:11:03 # off
[D][uart_debug:114]: <<< 01:03:01:68:64:03 # on
# Natural wind third gear
[D][uart_debug:114]: <<< 01:03:01:05:01:03
[D][uart_debug:114]: <<< 01:03:01:36:32:03
[D][uart_debug:114]: <<< 01:03:01:68:64:03
You can send these frames using uart.write
: See https://github.com/syssi/esphome-jbd-bms/blob/main/tests/esp8266-query-data.yaml
thank you! fan is work.
Could you try to provide a much details about the frames as possible?
Byte Value Description
0 0x01 Start of frame (always 0x01)
1 0x03 0x01=Off, 0x03=On (is 0x02 also a possible value?)
2 0x01 ??
3 0x68 Fan speed?
4 0x64 Checksum (n - byte1 - byte2 - byte3)
5 0x03 End of frame (always 0x03)
Does the uC of the fan driver board respond? The dummy_receiver
should write the answers to the log.
It's possible byte3 is the checksum: sum of byte1+byte2+byte4.
Could you try to provide a much details about the frames as possible?
Byte Value Description 0 0x01 Start of frame (always 0x01) 1 0x03 0x01=Off, 0x03=On (is 0x02 also a possible value?) 2 0x01 ?? 3 0x68 Fan speed? 4 0x64 Checksum (n - byte1 - byte2 - byte3) 5 0x03 End of frame (always 0x03)
Does the uC of the fan driver board respond? The
dummy_receiver
should write the answers to the log.
new data is here, https://github.com/0neday/yeelight-c900#sniff-communication-esp32-with-bp6601
0x04 is on, 0x03 reverse
this need more data to recompile frame format. because I flash stock firmware into a new esp32, that cannot connect Mijia server( maybe server use mac address check ) , so Mijia App show my device is offline. so that I can not test 0-100% speed.
# open
[D][uart_debug:114]: >>> 01:04:01:18:13:03
[D][uart_debug:114]: <<< 01:F3:01:07:13:03
# close
[D][uart_debug:114]: >>> 01:01:01:13:11:03
[D][uart_debug:114]: <<< 01:F3:01:05:11:03
# 1 level
[D][uart_debug:114]: >>> 01:03:01:05:01:03
[D][uart_debug:114]: <<< 01:F3:01:F5:01:03
# 2 level
[D][uart_debug:114]: >>> 01:03:01:36:32:03
[D][uart_debug:114]: <<< 01:F3:01:26:32:03
# 3 level
[D][uart_debug:114]: >>> 01:03:01:68:64:03
[D][uart_debug:114]: <<< 01:F3:01:58:64:03
I still assume there is an eeprom next to the ESP32 containing some secrets required to talk to the Mijia cloud.
# on
[D][uart_debug:114]: >>> 01:04:01:18:13:03 -> 0x04 + 0x01 + 0x13 = 0x18
[D][uart_debug:114]: <<< 01:F3:01:07:13:03 -> 0xF3 + 0x01 + 0x13 = 0x07
# off
[D][uart_debug:114]: >>> 01:01:01:13:11:03 -> 0x01 + 0x01 + 0x11 = 0x13
[D][uart_debug:114]: <<< 01:F3:01:05:11:03 -> 0xF3 + 0x01 + 0x11 = 0x05
# 1 level
[D][uart_debug:114]: >>> 01:03:01:05:01:03 -> 0x03 + 0x01 + 0x01 = 0x05
[D][uart_debug:114]: <<< 01:F3:01:F5:01:03 -> 0xF3 + 0x01 + 0x01 = 0xF5
# 2 level
[D][uart_debug:114]: >>> 01:03:01:36:32:03 -> 0x03 + 0x01 + 0x32 = 0x36
[D][uart_debug:114]: <<< 01:F3:01:26:32:03 -> 0xF3 + 0x01 + 0x32 = 0x26
# 3 level
[D][uart_debug:114]: >>> 01:03:01:68:64:03 -> 0x03 + 0x01 + 0x64 = 0x68
[D][uart_debug:114]: <<< 01:F3:01:58:64:03 -> 0xF3 + 0x01 + 0x64 = 0x58
Byte Value Description
0 0x01 Start of frame (always 0x01)
1 0x03 0x01=Off, 0x03=On, 0x04=OnReverse
2 0x01 ??
3 0x68 Checksum (byte1 + byte2 + byte4)
4 0x64 Fan speed 0x01...0x64 = 1...100%
5 0x03 End of frame (always 0x03)
Could you try to send an command with an invalid checksum and/or invalid speed (0x65)? I assume the first nibble of 0xF3 indicates success. May be byte 2 of the frame is static and always 0x01
.
# 0x04, with error chechsum, fan not work
[D][uart_debug:114]: >>> 01:04:01:17:13:03
[D][uart_debug:114]: <<< 01:F3:01:94:A0:03
# 0x04, change speed to 0x01 , no return
[D][uart_debug:114]: >>> 01:04:01:06:01:03
# 0x03, speed = 0x65 is work
[D][uart_debug:114]: >>> 01:03:01:69:65:03
[D][uart_debug:114]: <<< 01:F3:01:59:65:03
# 0x03, speed = 0x20 , work
[D][uart_debug:114]: >>> 01:03:01:24:20:03
[D][uart_debug:114]: <<< 01:F3:01:14:20:03
# 0x03 , with error checksum, fan not change state
[D][uart_debug:114]: >>> 01:03:01:15:10:03
[D][uart_debug:114]: <<< 01:F3:01:94:A0:03
I guess speed change is just for `0x03`,
so byte 1 is identify of 自然风 or 循环风 ?
`0x04` is for `on`
the `A0` of retrun code say, not correct, or chechsum error.
I have another question is how to use uart read to get return code for comfirming the write is correct.
like use uart.read
get return, if get byte 4 is A0
, that show write is error.
RT,
thank you