syssi / esphome-yeelight-ceiling-light

ESPHome custom firmware for some Yeelight Ceiling Lights
Apache License 2.0
134 stars 20 forks source link

Add YLXD05YL and YLXD01YL support (Mediatek devices) #10

Open splitatom44 opened 3 years ago

splitatom44 commented 3 years ago

Is it possible to assist with flashing the YLXD05YL and YLXD01YL models of the Yeelights? Photos attached of mainboards. Thankyou

20210403_074056 20210403_074107 20210403_074251 20210403_075015 20210403_075017 20210403_075709 20210403_075716

syssi commented 3 years ago

Bad news: The heart of the white daughterboard is a Mediatek microcontroller. Esphome has ESP8266 and ESP32 support only. Your device aren't Esphome compatible. :-(

splitatom44 commented 3 years ago

Ah ok, thought that might be the case when I pulled it apart. Thanks anyways

syssi commented 3 years ago

Do you like to replace the white daughterboard with an esp32? The task isn't easy but possible.

splitatom44 commented 3 years ago

Interesting, I'd assume a fairly good understanding of the schematics of the board would be needed no?

syssi commented 3 years ago

Yes. I try to outline the steps to get a better undestanding what needs to be done:

  1. Use the pads at J2 to power the daughter board. Attach 3.3V + GND to a power supply providing 3.3V. Don't attach the LEDs! Don't power the device with 230V AC. Attach RXD, TXD and GND to a USB-to-TTL serial adapter.
  2. Open a serial console. You should see some output of the stock firmware.
  3. Try to control the device by the android app. Do you see any output at the serial console?
  4. Remove the power. Try to understand / identify which pads of the white daugther board are connected to the led driver. Trace the lines / use a continuity tester.

We are ready if you've identified the following pins:

  1. As soon we know the location of the pads of the different functions we will try to compare the pin layout with the esp32 wroom. I hope the esp32 can be attached/soldered 1:1 to the board. If not: The relevant pins needs to be wired to the corresponding pin (gnd, 3.3v, txd, rxd) of the esp32.

  2. As soon we know/assume the location/pads of C, W, N and Standby we can verify our assumption by driving the stock firmware via the app. F.e. turn on the light and drive cold white to 100%. You should measure between C and GND a voltage of max. 3.3V (if it's less than 3.3V the max voltage of C is limited. Note down the limits!). Do the same for the warm white PWM pin. Turn on the night light and measure the min/max voltage/setting of the night light. Turn the light on/off. Measure the voltage at the standby pin.

  3. As soon you know your device very well, we can replace the white daughter board. I assume a lot of pads aren't connected. If we find pads/connections without knowing the purpose we are doomed. ;-)

splitatom44 commented 3 years ago

Excellent guide, next weekend when I have time I'll start poking around

lazzzrus commented 3 years ago

Hello Syssi!

Thank you for your wonderful work!

I have similar light. So i can see output on UART. Miio net, miio monitor etc. It reacts when i change settings in yeelight app i.e. "new britght 67". Should i look for particular messages?

I've found g, rx, tx, 3v3 and start pins. But i don't know how to find pwm pins. There are some pins with 3.2V, some with 0V. Current is 10, 20 and 40 mA, but it doesn't change when i change brightness. Also i can't discover pwm signal even by oscilloscope (hantek d72). I totally new with these measurements. Could you advice how to find pwm pins please?

syssi commented 3 years ago

You can identify a PWM signal if you measure the voltage at a GPIO. If you change the brightness the voltage should change.

Examples: Warm white brightness 100%: 3.2V Warm white brightness 50%: 1,5V Warm white brightness 1%: 0,2V

lazzzrus commented 3 years ago

Thank you! So the reason was mediatek doesn't output pwm signal when is not connected to the mains. Now i've managed to find cold and warm leds.

Is there way to disable mediatek without displacing it? i'd want to connect esp32 to test everything. And only displace old MCU after everethyng is working. Tried to connect start with the ground but no effect.

lazzzrus commented 3 years ago

So these pins i discovered so far: image

lazzzrus commented 3 years ago

nightlight is very low warm leds. What the nightlight pin does and how to find it?

Same with RGB backlight. I'm not familiar with how it works yet. Should it be 3 different pins?

syssi commented 3 years ago

The nightlight pin is a PWM pin too. It drives the warm white LEDs in a very low brightness range.

The RGB backlight are 3 PWM pins one per color.

syssi commented 3 years ago

I prefer to remove the Mediathek MCU before assembling the ESP32 because it will be hard to remove the power supply from the Mediathek MCU only.

lazzzrus commented 3 years ago

Hi Sebastian! Thanks! So the pinout now looks like this: image

What else should be considered before desoldering Mediatek?

Your yaml contains "power_supply" pin. Is it necessary or it could be not present in my device?

syssi commented 3 years ago

At some devices a GPIO ist used (Low vs. High) to turn the LED driver on and off. Please check all remaining pins while turning the lamp on and off. Do you see a GPIO flipping between 0 and 3,3V?

lazzzrus commented 3 years ago

Well, now it looks this way: image

5 pins are always high but they are not connected to 3.3pin 4 pins are always low

1 pin between warm and nightlight is low when turned off and 1.55V when turned on 1 pin between night and red is 0,87V when turned off an 1,55V when turned on. 1 pin at the bottom right is 1.55V when off and 1.4V when on What these three pins could be meant for? Some sensors?

Also i provided 3,3V to cold and warm LED pins when the light was turned off and the LEDs worked. Does it mean that the driver is always on and all we need is just to provide PWM output?

syssi commented 3 years ago

5 pins are always high but they are not connected to 3.3pin 4 pins are always low

Just keep this in mind. May be the behaviour/state needs to replicated at the esphome firmware.

1 pin between warm and nightlight is low when turned off and 1.55V when turned on 1 pin between night and red is 0,87V when turned off an 1,55V when turned on. What these two pins could be meant for?

I don't know.

Also i provided 3,3V to cold and warm LED pins when the light was turned off and the LEDs worked. Does it mean that the driver is always on and all we need is just to provide PWM output?

Good idea. I think you are safe now. :-)

lazzzrus commented 3 years ago

Finally got it working! Sebastian, thank you for the help!

Issues and questions so far:

  1. Noise in night mode. May be i use not correct frequency for the LEDC component. It's 1220Hz now.
  2. Need to make least voltage about 0,67V for main light. Don't know how to do it yet. So the light can disappear when i'm changing color temperature or move lovelace scale to thee left.
  3. Bluetooth dimmer probably won't work ever. There is open issue but nothing happens so far: https://github.com/esphome/feature-requests/issues/293
  4. May be you can advice lovelace card for such ceiling lights? All-in-one card

So Mediatek controller of YLXD02YL can be replaced by ESP32.

syssi commented 3 years ago

Could you provide a photo and your yaml as contribution?

10bn commented 3 years ago

2. make least voltage about 0,67V for main light. Don't know how to do it yet. So the light can disappear when i'm changing color temperature or move lovelace scale to thee left.

try these frequency settings to get ride of the noise.

`output:

10bn commented 3 years ago

I have the same light an was already thinking for a while to try this too. My soldering skills or the tools I where using have been simply not enough for the job. However I manged to restore full functionality except the Bluetooth remote.

There you go. @syssi use any of the files for contribution if you want.

https://github.com/jaddel/ESPHome-Configurations/tree/master/Devices/Ceiling%20Yeelight%20YLXD05YL

https://github.com/jaddel/ESPHome-Configurations/blob/master/Devices/Ceiling%20Yeelight%20YLXD05YL/Ceiling%20Yeelight%20YLXD05YL.jpg

syssi commented 3 years ago

@jaddel I've updated my ceiling lamps to esphome 1.18.0b3. In the past there where connection dropouts at the history. With 1.18.0 the connection is rock solidsolid.

lazzzrus commented 3 years ago

IMG_20210429_212349 Can't say that my soldering skills are good as well. But it works.

lazzzrus commented 3 years ago
  1. make least voltage about 0,67V for main light. Don't know how to do it yet. So the light can disappear when i'm changing color temperature or move lovelace scale to thee left.

try these frequency settings to get ride of the noise.

`output:

  • platform: ledc pin: GPIO19 id: output_warm frequency: 4882Hz
  • platform: ledc pin: GPIO21 id: output_cold frequency: 4882Hz
  • platform: ledc pin: GPIO23 id: output_nightlight frequency: 9765Hz`

Thank you, i will try!

lazzzrus commented 3 years ago

BLE-monitor custom integration now supports Yeelight dimmer and remote! https://github.com/custom-components/ble_monitor#supported-sensors

Could you please advice how to set the mediatek controller into pairing mode? power off/on for 5 times doesn't work. I need to add old controller to mihome app in order to get BLE encryption key.

syssi commented 3 years ago

@lazzzrus The remote control can be used without any encryption key. The encryption key of the dimmer can be retrieved by a modded mihome app version. Do you want to give it a try? (No OEM firmware / Mediatek required)

lazzzrus commented 3 years ago

i do for sure. Actually i have both remote and dimmer. The dimmer is not visible by miihome mod. Remote is visible but returns error when try to pair with mihome mod.

Now i've managed to get mediatek back into mihome mod, but no pairing .txt is available yet... Installyng python_miio to get key from dimmer.

lazzzrus commented 3 years ago

Well, miio returns another error: C:\Users\user>miiocli device --ip --token raw_command ble_dbg_tbl_dump '{"table":"evtRuleTbl"}' Running command raw_command Error: {'code': -9999, 'message': 'user ack timeout'}

syssi commented 3 years ago

I assume at the daughterboard of your ceiling lamp is a small eeprom connected via i2c which is used to store the key. As long as your mediatek uC isn't back in place it's unable to retrieve the key from the eeprom.

I've used this modded mihome app: https://github.com/custom-components/ble_monitor/issues/289#issuecomment-844014615

Steps to pair the dimmer and retrieve the token without using a ceiling lamp:

  1. Uninstall the original MiHome app
  2. Install the modded APK (unknown sources must be enabled)
  3. Login (use the region india as location/cloud/storage bucket)
  4. Go to the settings of your android device (settings -> app -> mihome app) and make sure the app has permissions to write to the internal storage and to use the "phone permission". The first permission is required to write files to yor smartphone. The second permission is required for BLE (I hope I didn't miss a permission here).
  5. Use a file manager to take a look at your internal storage. Do you see a vevs/ directory here?
    • If not: Close / kill the app and start it again. If the app has the permission the folder should be created now.
    • If yes: Goto the directory vevs/ and create a subdirectory called logs: vevs/logs/.
  6. Close / kill the app.
  7. Open the app. Goto the scanner/radar symbol at the top right corner and "scan" your environment for BLE advertisements.
  8. Press and rotate the dimmer to provide some traffic
  9. The dimmer should show up at the list of discovered devices.
  10. Select the discovered dimmer to start the pairing.
  11. If step 9 (pairing) doesn't complete start again at step 5. I had to disable bluetooth at my smartphone once and restart the app. If the pairing is successful it's super fast (3-6 seconds).
  12. Take a look at the internal storage. You should find a file called pairings.txt now. Alternatively use the https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor to login into the cloud and retrieve all devices from region i2 (india).

It should look like this:

$ python3 token_extractor.py 
Username (email or user ID):
***********************
Password:
***********************
Server (one of: cn, de, us, ru, tw, sg, in, i2) Leave empty to check all available:
i2

Logging in...
Logged in.

Devices found for server "i2":
   ---------
   NAME:     小米无线开关2
   ID:       blt.7.16mdp9hbd0g00
   BLE KEY:  ababababababababababababFFFFFFFF
   TOKEN:    efefefefefefefefefefefef
   MODEL:    yeelink.remote.ctrl
   ---------

Press ENTER to finish

The key abababababababababababab is the key you are looking for.

lazzzrus commented 3 years ago

Dear Sebastian! Thank you for so comprehensive guide!

I've tried two different smartphones, but both still can't pair with remote. Reinstalled several times. Rebooted phones, turned bluetooth on/off, tried different regions... Dimmer is not visible at all. I'll keep trying with different phones. But it doesn't look good so far(

Now i even think about resoldering mediatek back. To get control over bluetooth devices.

Another guess: i've unpaired remote in mihome app. But not sure the remote "knows" about that. Pressed "M" and OFF buttons together as well...

syssi commented 3 years ago

If I remember correctly the modded mihome app can be used to pair the dimmer only. @rezmus Do you agree?

Do you know the instructions of the ble monitor? May be I missed an important step to press the pairing button of the dimmer:

https://github.com/custom-components/ble_monitor/blob/master/faq.md#how-to-get-the-mibeacon-v2v3-encryption-key

In my case I had to start, stop and re-install the app multiple times. At the end everything went well. The BLE keys of the devices doesn't change over time. I printed the key to the back of my dimmers now ;-)

rezmus commented 3 years ago

app can pair both dimmer and remote, for sure the one bought separately pid 339. not sure if light bundle remotes can be paired, depends on pid. do you have proper version of the app? click + and go to household security. scroll down to remote control, view more. you should see remote/dimmer icons there. i paired both with the app recently without issues.

bt device does not know if it's paired or not. it just keep sending adv encrypted with constant key. any device arround which knows algo and key can decrypt.

https://ibb.co/M6x38KM https://ibb.co/3mcbttj https://ibb.co/z80S9WV

rezmus commented 3 years ago

@lazzzrus if you still have no luck with the app here's python script to auth device and read beaconkey directly (use pid 950 for dimmer and 339 for remote).

https://github.com/rexbut/mikettle/blob/master/get_beacon_key.py

syssi commented 3 years ago

@lazzzrus @rezmus It looks like there is another solution to retrieve the BLE key now: https://github.com/rexbut/mikettle/blob/master/get_beacon_key.py

rezmus commented 3 years ago

@syssi look at previous comment ;)

syssi commented 3 years ago

You are fast as hell! :-)

lazzzrus commented 3 years ago

Still no luck with Android. The only difference it now sees the dimmer. But can't pair as well. Thank you guys! Will try a python!

lazzzrus commented 3 years ago

This thing looks cursed. I've installed two instances of debian in virtualbox on two different hosts, also raspbian on raspberry pi. Always get the same result:

# python3 get_beacon_key.py F8:24:41:C3:37:36 950      Activate pairing on your 'F8:24:41:C3:37:36' device, then press Enter:
Connection in progress...
Traceback (most recent call last):
  File "get_beacon_key.py", line 144, in <module>
    main(sys.argv)
  File "get_beacon_key.py", line 141, in main
    get_beacon_key(mac, product_id)
  File "get_beacon_key.py", line 96, in get_beacon_key
    peripheral = Peripheral(deviceAddr=mac)
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 391, in __init__
    self._connect(deviceAddr, addrType, iface)
  File "/usr/local/lib/python3.7/dist-packages/bluepy/btle.py", line 439, in _connect
    raise BTLEDisconnectError("Failed to connect to peripheral %s, addr type: %s" % (addr, addrType), rsp)
bluepy.btle.BTLEDisconnectError: Failed to connect to peripheral F8:24:41:C3:37:36, addr type: public
jinhong- commented 2 years ago

@lazzzrus I also have a mediatek board on my yeelights and the board layout looks the same. So far i managed to desolder the mediatek board. It is not clear to me what is the pinout i should be using. Is this the correct pinout? https://github.com/syssi/esphome-yeelight-ceiling-light/issues/10#issuecomment-827154861

syssi commented 2 years ago

ylxd05yl-mediatek-pinout

I hope this helps a bit.

jinhong- commented 2 years ago

Amazing. Thanks @syssi!

jinhong- commented 2 years ago

I just received my ESP32 board I have more questions. In the initial discussions it was mentioned that the following pins need to be identified:

The following I understand how I should be mapping/connecting

The following I understand what they are, but do not understand how and why we need to connect them. Do we connect them to the TX and RX of the ESP32 or use other gpio pins

The following I don't know what they are for, or which pins on the ESP32 I should connect them to

I am also assuming R, G, B pins are more for lights that have RGB support, which mind doesn't so thus I don't have to connect them

any thoughts @syssi? Thanks in advanced :D

syssi commented 2 years ago

You are right: RXD and TXD isn't important. Both pins are required the flash esphome once. You don't need to solder these pins to the daughter board. START is also not important because it's the RESET pin of the Mediatek micro controller. At the beginnen I was unsure about the purpose of the pin. STANDBY is important if your ceiling lamp doesn't turn on if you apply a PWM to CW or WW. The STANDBY pin turns the power supply of LED driver board on/off (at some devices).

jinhong- commented 2 years ago

Gotcha. I'll give it a try and see what i get

jinhong- commented 2 years ago

@syssi It works great. Just got everything wired in. One thing - the light seems to turn off before hitting 1% brightness. How do I adjust it so that it will stay on at 1%?

syssi commented 2 years ago

This is a well known issue: https://github.com/syssi/esphome-yeelight-ceiling-light/issues/15#issuecomment-850946633

If you are able to solve/improve it please share your configuration!

jinhong- commented 2 years ago

For others to reference this post in the future, this is the configuration I used that worked for me. Light Model YLXD04YL

#Variables
substitutions:
  device_name: main-bedroom-light
  friendly_name: Main Bedroom Light

esphome:
  name: ${device_name}
  platform: ESP32
  board: nodemcu-32s
  platformio_options:
    platform: espressif32@3.0.0
    platform_packages: tasmota/framework-arduinoespressif32 @ 3.10006.210420

web_server:
  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# logger:
api:
ota:
  password: !secret ota_password

output:
  - platform: ledc
    pin: GPIO19
    id: output_warm
    frequency: 4882Hz
    min_power: 0.07
    zero_means_zero: true

  - platform: ledc
    pin: GPIO21
    id: output_cold
    frequency: 4882Hz
    min_power: 0.07
    zero_means_zero: true

  - platform: ledc
    pin: GPIO23
    id: output_nightlight
    frequency: 9765Hz

light:
  - platform: monochromatic
    name: "${friendly_name} Nightlight"
    id: night_light
    output: output_nightlight
    gamma_correct: 0
    on_turn_on:
      - light.turn_off: ceiling_light
  - platform: cwww
    name: "${friendly_name}"
    id: ceiling_light
    cold_white: output_cold
    warm_white: output_warm
    cold_white_color_temperature: 6000 K
    warm_white_color_temperature: 2700 K
    gamma_correct: 0
    constant_brightness: true
    on_turn_on:
      - light.turn_off: night_light
syssi commented 2 years ago

Cool! I didn't know zero_means_zero.

wf1nder commented 2 years ago

Successfully transformed mediatek-based Xiaomi Mijia LED Ceiling Light (450 mm) (MJXDD01YL) into esphome device. Used Wemos D1 mini (esp8266) board. It needed to connect only these five pins:

Standby pin turned out to be unnecessary. And here my config:

#Variables
substitutions:
  device_name: kitchen-light
  friendly_name: Kitchen Light

esphome:
  name: ${device_name}
  platform: ESP8266
  board: d1_mini

web_server:
  port: 80

prometheus:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "ESPHome $friendly_name"
    password: !secret ap_wifi_password

captive_portal:

# logger:
api:
ota:
  password: !secret ota_password

logger:
    level: WARN

output:
  - platform: esp8266_pwm
    pin: D5
    id: output_warm
    frequency: 4882Hz
    min_power: 0.07
    zero_means_zero: true

  - platform: esp8266_pwm
    pin: D6
    id: output_cold
    frequency: 4882Hz
    min_power: 0.07
    zero_means_zero: true

  - platform: esp8266_pwm
    pin: D8
    id: output_nightlight
    frequency: 9765Hz

light:
  - platform: monochromatic
    name: "${friendly_name} Nightlight"
    id: night_light
    output: output_nightlight
    gamma_correct: 0
    on_turn_on:
      - light.turn_off: ceiling_light
  - platform: cwww
    name: "${friendly_name}"
    id: ceiling_light
    cold_white: output_cold
    warm_white: output_warm
    cold_white_color_temperature: 6000 K
    warm_white_color_temperature: 2700 K
    gamma_correct: 0
    constant_brightness: true
    on_turn_on:
      - light.turn_off: night_light
    restore_mode: ALWAYS_ON
    default_transition_length: 500ms

IMG_1973

IMG_1978

syssi commented 2 years ago

Good job! Congratulations!