Add yeelink.light.fancl5 support

RT,
thank you

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?

循环风三档，标准风 0-100%调速。
拆了看了下，esp32通过 软 串口给风扇驱动模块。目前只分析出，白线是接到 IC2 的8号引脚，其他分析太难了，没搞过。
图片已经上传。
https://github.com/0neday/yeelight-c900

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, and it  could enter into flash mode.
I can not get gpio is for light.  the gpio of my yaml is copy from your's, do not test.
Do you any decompiled circuit diagram of yeelight ceiling?

Another wish/suggestion:
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.

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

you are genius！

[16:05:37]ets 016 :22:MS
[16:05:37]. (POWQ}IMET),0L&BA%_FASTe1M!}BOOT)C˥sip:, SPR
[16:05:37]clE0,qߖ0,d_d.0,cs0_0x,hd_0x,wp_0xj
[16:05:37]moY'T	div:2C!+0x3ffbbn:4!+0x3fffc,lKj
[16:05:37]ho 12 roo[j
[16:05:37]l+0x,lenj
[16:05:37]load:008bb:587C 0x4006d4Cfast_reboot_count in psm is now 1
[16:05:37]08:00:00.100 [I] miio_ot: httpdns enabled
[16:05:37]08:00:00.100 [I] miio_ot: dlg enabled
[16:05:37]
[16:05:37]
[16:05:37]_|      _|  _|_|_|  _|_|_|    _|_|
[16:05:37]_|_|  _|_|    _|      _|    _|    _|
[16:05:37]_|  _|  _|    _|      _|    _|    _|
[16:05:37]_|      _|    _|      _|    _|    _|
[16:05:37]_|      _|  _|_|_|  _|_|_|    _|_|
[16:05:37]JENKINS BUILD NUMBER: N/A
[16:05:37]BUILD TIME: Sep 24 2020,16:03:38
[16:05:37]BUILT BY: N/A
[16:05:37]MIIO APP VER: 2.0.6_0006
[16:05:37]MIIO MCU VER:
[16:05:37]MIIO DID: 474769981
[16:05:37]MIIO WIFI MAC: ec4d3e7e1033
[16:05:37]MIIO MODEL: yeelink.light.fancl5
[16:05:37]ARCH TYPE: esp32,0x0000a601
[16:05:37]ARCH VER: 401ef84
[16:05:37]W (637) phy_init: saving new calibration data because of checksum failure, mode(0)
[16:05:38]W (957) wifi: ap start fail
[16:05:38]
[16:05:38]W (957) wifi: ap start fail
[16:05:38]
[16:05:38]08:00:00.650 [I] otu: Opened.
[16:05:42]08:00:05.040 [W] arch_flash: data from DROM. (arch_flash_write,74)

read from usb-ttl

test rulst is :
cold --> gpio21
warn --> gpio19
night mode ---> gpio23

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

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?

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
no, 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.A<IP_ADDRESS>.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.A<IP_ADDRESS>.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.A<IP_ADDRESS>.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?

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.

can not downlod, but you could look this online https://www.docin.com/p-2267808805.html

maybe, we cloud us 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:

Identify the GPIOs attached to con2 the pin header between the mainboard and the fan driver board.
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?
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:

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.

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.

bwteen 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.
for 50.30.8E.06.89.0B.85.6E.38.C1.A<IP_ADDRESS>.01.00.00 of fan key data,  how to use this->keycode_->publish_state(*res->keycode) to get keycode, and how create on_... events? how to modify your code, thank you!

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?

https://github.com/0neday/yeelight-c900/commit/d381f730cc247fe4ff168e5fe835aaec6f1c73ce

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 frame counter which increases permanently:
https://github.com/syssi/esphome-yeelight-ceiling-light/blob/main/components/xiaomi_ble/xiaomi_ble.cpp#L154
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 likes 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 understand what a full device implementation looks like:
https://github.com/esphome/esphome/pull/1783/files#diff-a1fc96aecdd718ce2fd8d4892c7d9ecef75683f467cc58282fd4c0b13cd24934

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:
https://github.com/syssi/esphome-yeelight-ceiling-light/blob/main/components/xiaomi_ble/xiaomi_ble.cpp#L154
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:
              and:
                - lambda: "return(id(frame_counter) != x[4]);"
                - lambda: "return(x[14] == 1);"
            then:
             - lambda: "id(frame_counter) = x[4];"
             - switch.turn_on: buzzer_beep
             - lambda: 'id(yeelight_remote_controller).publish_state(x[14]);'
             - light.toggle: ceiling_light

         - if:
            condition:
              and:
                - lambda: "return(id(frame_counter) != x[4]);"
                - lambda: "return(x[14] == 4);"
            then:
             - lambda: "id(frame_counter) = x[4];"
             - switch.turn_on: buzzer_beep
             - lambda: 'id(yeelight_remote_controller).publish_state(x[14]);'
             - 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

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

maybe not work on nodemcu esp32
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
 - Flash Size: 4MB
Unexpected error: The firmware binary is invalid (magic byte=FF, should be E9)

I found this issue, that show uart communication is 4 bytes .https://github.com/arendst/Tasmota/discussions/13664#discussioncomment-2929489
do you know how to install stock firmware, thank you

sniff  uart communication data fromat is
[D][uart_debug:114]: <<< 01:01:01:13:11:03 关
[D][uart_debug:114]: <<< 01:03:01:68:64:03 开

自然风 三档
[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   ??
4     0x64   Fan speed in percent 0x01 ...0x64 = 1...100%
5     0x03   End of frame (always 0x03)

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.

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 adress check ) , so Mijia App show my device is downline. 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

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 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.

The next step is the implementation of a custom UART component:
https://esphome.io/custom/uart.html
or a full blown external component to control/monitor the fan. I prefer the external component.

If the fan is off and you send the set speed to 100% (01:03:01:68:64:03) command. Does the fan turn on or is the turn on (01:04:...) command required first?

If you don't want to do the deep dive into the external components of ESPHome I can prepare a first draft of the fan component.

# miot specs of the device / stock firmware features

https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:light:0000A001:yeelink-fancl5:1

Device 'urn:miot-spec-v2:device:light:0000A001:yeelink-fancl5:1': Light with 5 services

* Service siid 1: (Device Information): 4 props, 0 actions

        ## Properties ##
                siid 1: piid: 1 (Device Manufacturer): (string, unit: None) (acc: ['read'])
                siid 1: piid: 2 (Device Model): (string, unit: None) (acc: ['read'])
                siid 1: piid: 3 (Device Serial Number): (string, unit: None) (acc: ['read'])
                siid 1: piid: 4 (Current Firmware Version): (string, unit: None) (acc: ['read'])

* Service siid 2: (Light): 4 props, 0 actions

        ## Properties ##
                siid 2: piid: 1 (Switch Status): (bool, unit: None) (acc: ['read', 'write', 'notify'])
                siid 2: piid: 3 (Brightness): (uint8, unit: percentage) (acc: ['read', 'write', 'notify'])
                        Range: [1, 100, 1]
                siid 2: piid: 5 (Color Temperature): (uint32, unit: kelvin) (acc: ['read', 'write', 'notify'])
                        Range: [2700, 6500, 1]
                siid 2: piid: 7 (Mode): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 0, 'description': 'Day'}
                        {'value': 1, 'description': 'Night'}

* Service siid 3: (Ceiling Fan): 5 props, 0 actions

        ## Properties ##
                siid 3: piid: 1 (Switch Status): (bool, unit: none) (acc: ['read', 'write', 'notify'])
                siid 3: piid: 2 (Fan Level): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 0, 'description': 'Auto'}
                        {'value': 1, 'description': 'Level1'}
                        {'value': 2, 'description': 'Level2'}
                        {'value': 3, 'description': 'Level3'}
                siid 3: piid: 3 (Status): (uint8, unit: None) (acc: ['read', 'notify'])
                        {'value': 1, 'description': 'Idle'}
                        {'value': 2, 'description': 'Busy'}
                siid 3: piid: 4 (Mode): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 0, 'description': 'Auto'}
                        {'value': 1, 'description': 'Auto'}
                siid 3: piid: 10 (Power Off Delay Time): (uint32, unit: minutes) (acc: ['read', 'write', 'notify'])
                        Range: [0, 720, 1]

* Service siid 4: (yl-light): 7 props, 9 actions

        ## Properties ##
                siid 4: piid: 1 (): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                        {'value': 1, 'description': '上电开灯'}
                        {'value': 2, 'description': '上电关灯'}
                siid 4: piid: 3 (): (bool, unit: none) (acc: ['read', 'notify', 'write'])
                siid 4: piid: 4 (): (uint32, unit: minutes) (acc: ['read', 'notify', 'write'])
                        Range: [0, 180, 1]
                siid 4: piid: 5 (): (uint32, unit: minutes) (acc: ['read', 'notify'])
                        Range: [0, 180, 1]
                siid 4: piid: 6 (night-time-str): (string, unit: none) (acc: ['read', 'notify', 'write'])
                siid 4: piid: 7 (dl-brightness): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]
                siid 4: piid: 8 (nl-brightness): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]

        ## Actions ##
                siid 4: aiid 1 toggle: in: [] -> out: []
                siid 4: aiid 2 brightness-up: in: [] -> out: []
                siid 4: aiid 3 brightness-down: in: [] -> out: []
                siid 4: aiid 4 brightness-cycle: in: [] -> out: []
                siid 4: aiid 5 ct-cycle: in: [] -> out: []
                siid 4: aiid 7 ct-increase: in: [] -> out: []
                siid 4: aiid 8 ct-decrease: in: [] -> out: []
                siid 4: aiid 9 on-or-bright-cycle: in: [] -> out: []
                siid 4: aiid 10 on-or-ct-cycle: in: [] -> out: []

* Service siid 5: (yl-fan): 5 props, 1 actions

        ## Properties ##
                siid 5: piid: 4 (left-time): (uint32, unit: minutes) (acc: ['read', 'notify'])
                        Range: [0, 720, 1]
                siid 5: piid: 5 (fan-init-power-opt): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                        {'value': 0, 'description': '上电风扇不开'}
                        {'value': 1, 'description': '上电开风扇'}
                siid 5: piid: 6 (smart-switch-en): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                        {'value': 0, 'description': '闪断不控制风扇'}
                        {'value': 1, 'description': '闪断控制风扇开关'}
                siid 5: piid: 7 (fan-speed-std): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]
                siid 5: piid: 8 (fan-speed-rec): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]

        ## Actions ##
                siid 5: aiid 1 toggle: in: [] -> out: []

If the fan is off and you send the set speed to 100% (01:03:01:68:64:03) command. Does the fan turn on or is the turn on (01:04:...) command required first?

need first send 01:04:..., and then send 01:03:..., otherwise the fan will reverse

Could you try to find out how to control the speed if the fan runs in reverse mode? May be byte3 indicates the reverse speeed?
Byte  Value  Description
0     0x01   Start of frame (always 0x01)
1     0x03   0x01=Off, 0x03=On, 0x04=OnReverse
2     0x64   Reverse speed 100%
3     0x68   Checksum (byte1 + byte2 + byte4)
4     0x01    Forward speed
5     0x03   End of frame (always 0x03)

The miot specs indicates something like: "The fan speed can be controlled in reverse speed too":
                siid 5: piid: 7 (fan-speed-std): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]
                siid 5: piid: 8 (fan-speed-rec): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]

external components of ESPHome

how to write a simple  external components of ESPHome

This is a external component: https://github.com/syssi/esphome-jbd-bms
It can be loaded using:
external_components:
  - source: github://syssi/esphome-jbd-bms@main

It consumes data from a selected uart:
uart:
  id: uart0
  baud_rate: 9600
  tx_pin: ${tx_pin}
  rx_pin: ${rx_pin}

jbd_bms:
  uart_id: uart0

The folder structure is important: components//
This must be adapted to support the fancl5 bp6601 frames: https://github.com/syssi/esphome-jbd-bms/blob/main/components/jbd_bms/jbd_bms.cpp#L88-L159
This must be adapted to send the fancl frames: https://github.com/syssi/esphome-jbd-bms/blob/main/components/jbd_bms/jbd_bms.cpp#L399-L414

Could you explain the difference between:
                siid 3: piid: 2 (Fan Level): (uint8, unit: none) (acc: ['read', 'write', 'notify'])
                        {'value': 0, 'description': 'Auto'}
                        {'value': 1, 'description': 'Level1'}
                        {'value': 2, 'description': 'Level2'}
                        {'value': 3, 'description': 'Level3'}

and
                siid 5: piid: 7 (fan-speed-std): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]
                siid 5: piid: 8 (fan-speed-rec): (uint8, unit: percentage) (acc: ['read', 'notify', 'write'])
                        Range: [1, 100, 1]

It looks like the fan has 3 different fan speeds vs. the fan speed can be controlled stepless between 1 and 100%. Do we support all features if we implement the fan speed 1...100% only?

It looks like the fan has 3 different fan speeds
this function is just for BLE remote controller

1-level = 1% speed
2-leve = 50% speed
3-level = 100% speed

that is part of stepless  between 1 and 100%, because remote controller can not do stepless speed control.

the fan speed can be controlled stepless between 1 and 100%

this function is for Mijia App, in Mijia App you can control fan stepless between 1 and 100% like light brightness controller in HA.

Please don't risk to brick your device by soldering. We can ignore this missing feature or we could make two attempts to guess the reverse frame. My next bet is passing a inverted value byte4 plus byte2=0x04. Something like this:
01:04:01:CRC:F0:03

I don't think so. I assume the timer is part of the ESP firmware and the BP6601 features are pretty limited.

I've prepared a external component to expose the device as fan entitiy:
external_components:
  - source: github://syssi/esphome-yeelight-ceiling-light@add-fancl5-support
    refresh: 0s

uart:
  baud_rate: 9600
  rx_pin: GPIO16
  tx_pin: GPIO17
  debug:
    direction: BOTH

fan:
  - platform: yeelight_fan_controller
    name: "${name} ceiling fan"

Please give it a try!

not work
[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 100
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 100
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:04:01:69:64:03:01:03:01:68:64:03

and , when fan is off , first tap speed bar not work，but tap again is work
[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 72
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 72
[D][fan:115]:   Direction: REVERSE
[D][uart_debug:114]: >>> 01:04:01:4D:48:03:01:03:01:4C:48:03
[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 55
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 55
[D][fan:111]:   Speed: 55
[D][fan:115]:   Direction: REVERSE
[D][uart_debug:114]: >>> 01:03:01:3B:37:03
[I][yeelight_fan_controller:109]: Command successful
[I][yeelight_fan_controller:109]: Command successful
[D][uart_debug:114]: <<< 01:F3:01:2B:37:03

[D][uart_debug:114]: >>> 01:04:01:4D:48:03:01:03:01:4C:48:03

I think need send `01:04...` , then delay 1s, and then send `01:03...`

and every tap, the state `ON` is  triggered, it is not pretty good.

[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 55
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 55
[D][fan:111]:   Speed: 55

and I notice that when I tap fan off, the command is different. that is related with the speed bar .
# speed 46
[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: OFF
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: OFF
[D][fan:111]:   Speed: 46
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:01:01:30:2E:03

# speed 73
[D][fan:022]: 'test yeelight ceiling fan' - Setting:
[D][fan:025]:   State: OFF
[D][fan:108]: 'test yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: OFF
[D][fan:111]:   Speed: 73
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:01:01:4B:49:03

maybe only 01:01:01:13:11:03 could be triggered ?

hey, I change your code in yeelight_fan.cpp, that work fine now!!! thank you very much!
void YeelightFan::write_state_() {
  if (this->state != this->last_state_) {
    if (this->state) {
      this->parent_->send_command(FUNCTION_TURN_ON, 0x13);
    } else {
      this->parent_->send_command(FUNCTION_TURN_OFF, 0x11);
    }
  }

  else if (this->state) {
    // if (this->direction == fan::FanDirection::REVERSE) {
    this->parent_->send_command(FUNCTION_SET_SPEED, this->speed);

Thanks for testing. I will fix the turn_on/turn_off payload ASAP. I would be happy about more protocol details / example frames if possible.

when first tap speed bar, just send on , not effect speed, the speed was ignored

You are right. This is bug. We don't know the frame (maybe it doesn't exist) to ask the fan about the current state without changing something. I've added the state restore because of this limitation. If the ESP crashs and the fan is running, the ESP should he able to restore the running state. At the moment the last_state isn't restored. It's initialized with false always. I assume this is the root cause for the misbehavior.

I don't know enough about the reverse mode + speeds. At the moment the UI feature is enabled but it's not implemented yet:
https://github.com/syssi/esphome-yeelight-ceiling-light/pull/43/files#diff-92d52ad3a4d9b8f1a8c74c856b9123751849020abd388134be5f97f28ace6d2eR48-R54

I don't know enough about the reverse mode + speeds. At the moment the UI feature is enabled but it's not implemented yet:

wait me some times, I will give you more information of uart communication

Finished!
# on ( 0x04 ),  fan mode select , 0x18 for standard wind, 0x17 for circulating wind
[D][uart_debug:114]: <<< 01:04:01:18:13:03
[D][uart_debug:114]: <<< 01:04:01:17:12:03

# off,  0x01
[D][uart_debug:114]: <<< 01:01:01:13:11:03

# circulating wind only have three levels  1% 50% 100%
[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

# standard wind have stepless control,  1%-100%
[D][uart_debug:114]: <<< 01:03:01:05:01:03 (1%)
[D][uart_debug:114]: <<< 01:03:01:36:32:03 (50%)
[D][uart_debug:114]: <<< 01:03:01:4A:46:03 (70%)
[D][uart_debug:114]: <<< 01:03:01:5E:5A:03 (90%)
[D][uart_debug:114]: <<< 01:03:01:68:64:03 (100%)

# timer, controlled by esp32 , do not send command

# mode toggle
### from standard wind with speed 70% , toggle into circulating wind，need restore last speed level of  circulating wind
[D][uart_debug:114]: <<< 01:03:01:4B:47:03
[D][uart_debug:114]: <<< 01:04:01:17:12:03
[D][uart_debug:114]: <<< 01:03:01:68:64:03 （last setting circulating wind level）

### from circulating wind mode , toggle into standard wind mode，need restore last speed value of  standard wind ）
[D][uart_debug:114]: <<< 01:03:01:68:64:03
[D][uart_debug:114]: <<< 01:04:01:18:13:03
[D][uart_debug:114]: <<< 01:03:01:4B:47:03 （ast speed value of  standard wind）

ps:
when toggle fan mode ，need to send 2  command ，the first is mode select command ，and delay 1s  , then send second restored speed command.

Good job! I will try to implement the new findings. Is the delay of 1s between two commands required?

Is the delay of 1s between two commands required?

I have update, maybe , but should be delay 1s , avoid to this happened
[D][uart_debug:114]: >>> 01:04:01:4D:48:03:01:03:01:4C:48:03
this show that 2 command be sent together.

The circulating wind  (reverse mode ) is also could be controlled stepless, 1% - 100%. so just need restore last speed value regardless speed level when toggle fan mode.

this show that 2 command be sent together.

It looks like one message but good software should be able to see two frames here.

I will be test command 01:04:01:17:12:03:01:03:01:68:64:03  , and check whether correct

Thanks!

I'm a bit confused. Could acknowledge this: Your ceiling fan supports 4 different modes:

Straight wind + forward (1...100%)
Straight wind + reverse (1...100%)
Natural wind + forward (1...100%)
Natural wind + reverse (1...100%)

If we change the mode we will send two commands in future:

Turn on the fan in XXX mode (funtion 0x04)
Set speed level to YY % (function 0x03)

only accept  01:04:01:17:12:03 , should check frame length first , then execute
[D][switch:021]: 'yeelight fan' Toggling ON.
[D][switch:037]: 'yeelight fan': Sending state ON
[D][uart_debug:114]: >>> 01:04:01:17:12:03:01:03:01:68:64:03
[I][yeelight_fan_controller:094]: RX <- 01.F<IP_ADDRESS>.03 (6)
[I][yeelight_fan_controller:114]: Command successful
[D][uart_debug:114]: <<< 01:F3:01:06:12:03

I'm a bit confused. Could acknowledge this: Your ceiling fan supports 4 different modes:

Straight wind + forward (1...100%)
Straight wind + reverse (1...100%)
Natural wind + forward (1...100%)
Natural wind + reverse (1...100%)

If we change the mode we will send two commands in future:

Turn on the fan in XXX mode (funtion 0x04)
Set speed level to YY % (function 0x03)

no,   only have 2 mode
Straight wind = forward ( standard mode  )
Natural wind  = reverse ( circulating wind )
they both  have speed stepless control

Could you add a delay(55) to the send_command method and try again? If it doesn't work out of the box please increase the delay slowly. We are not allowed to block the loop for too long.
https://github.com/syssi/esphome-yeelight-ceiling-light/pull/43/files#diff-03fdb16a6d0644a03a1ec2905b5d7a8faee9133e163b28e33b18b9cb55189b82R142

I've added the delay: https://github.com/syssi/esphome-yeelight-ceiling-light/pull/43/commits/a43438528aaa9b369e82a3c005a0a8645ada4a93
Please give it a try.

maybe worked
https://github.com/0neday/yeelight-c900/commit/6acfa660a40c403d4b5df2ba6f26b6f179f1f1ed
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[I][yeelight_fan_controller:155]: send frame[0]: 0x01
[I][yeelight_fan_controller:155]: send frame[1]: 0x04
[I][yeelight_fan_controller:155]: send frame[2]: 0x01
[I][yeelight_fan_controller:155]: send frame[3]: 0x18
[I][yeelight_fan_controller:155]: send frame[4]: 0x13
[I][yeelight_fan_controller:155]: send frame[5]: 0x03
[I][yeelight_fan_controller:155]: send frame[0]: 0x01
[I][yeelight_fan_controller:155]: send frame[1]: 0x03
[I][yeelight_fan_controller:155]: send frame[2]: 0x01
[I][yeelight_fan_controller:155]: send frame[3]: 0x53
[I][yeelight_fan_controller:155]: send frame[4]: 0x4F
[I][yeelight_fan_controller:155]: send frame[5]: 0x03
[D][fan:108]: 'yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 79
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:04:01:18:13:03:01:03:01:53:4F:03
[I][yeelight_fan_controller:096]: RX <- 01.F<IP_ADDRESS>.03 (6)
[I][yeelight_fan_controller:116]: Command successful
[I][yeelight_fan_controller:096]: RX <- 01.F<IP_ADDRESS>F.03 (6)
[I][yeelight_fan_controller:116]: Command successful
[D][binary_sensor:036]: 'fan running': Sending state ON
[D][uart_debug:114]: <<< 01:F3:01:07:13:03:01:F3:01:43:4F:03

I've added the delay: a434385
Please give it a try.

comfimed again , remove delay, that work fine also , maybe do not need delay. thank you

Alright. I will revert the commit. If no delay is required the delay should be avoided.

get weird bug. when I use homeassisstant app on iPhone with latest version, sometimes it will crash, and crash web ota page, and close light.
when I tap speed bar one time, but send 2 command
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 91
[I][yeelight_fan_controller:155]: send frame[0]: 0x01
[I][yeelight_fan_controller:155]: send frame[1]: 0x03
[I][yeelight_fan_controller:155]: send frame[2]: 0x01
[I][yeelight_fan_controller:155]: send frame[3]: 0x5F
[I][yeelight_fan_controller:155]: send frame[4]: 0x5B
[I][yeelight_fan_controller:155]: send frame[5]: 0x03
[D][fan:108]: 'yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 91
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:03:01:5F:5B:03
[I][yeelight_fan_controller:096]: RX <- 01.F3.01.4F.5B.03 (6)
[I][yeelight_fan_controller:116]: Command successful
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 91
[D][uart_debug:114]: <<< 01:F3:01:4F:5B:03
[I][yeelight_fan_controller:155]: send frame[0]: 0x01
[I][yeelight_fan_controller:155]: send frame[1]: 0x03
[I][yeelight_fan_controller:155]: send frame[2]: 0x01
[I][yeelight_fan_controller:155]: send frame[3]: 0x5F
[I][yeelight_fan_controller:155]: send frame[4]: 0x5B
[I][yeelight_fan_controller:155]: send frame[5]: 0x03
[D][fan:108]: 'yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 91
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:03:01:5F:5B:03
[I][yeelight_fan_controller:096]: RX <- 01.F3.01.4F.5B.03 (6)
[I][yeelight_fan_controller:116]: Command successful
[D][uart_debug:114]: <<< 01:F3:01:4F:5B:03

However, when I use chrome to access Homeassisstant, that work fine.

I cannot recommend the web interface. It's super heavy. The api communication with HA core is pretty lightweight in comparison.

I've pushed an updated version of the fan controller. The reverse mode is supported now. I've removed the last_state property. All commands now consists of two frames (set_mode + set_speed) for simplicity.

I've pushed an updated version of the fan controller. The reverse mode is supported now. I've removed the last_state property. All commands now consists of two frames (set_mode + set_speed) for simplicity.

test many times, I think need add delay before send speed command
void YeelightFan::write_state_() {
  if (this->state) {
    if (this->direction == fan::FanDirection::REVERSE) {
      this->parent_->send_command(FUNCTION_SET_MODE, MODE_REVERSE);
    }
	else {
      this->parent_->send_command(FUNCTION_SET_MODE, MODE_FORWARD);
    }
    delay(500);
    this->parent_->send_command(FUNCTION_SET_SPEED, this->speed);
  }

Okay. I will think about it how to schedule/delay the second command without using a blocking delay().

I've added the fancl remote control support to the external component. Please give it a try: https://github.com/syssi/esphome-yeelight-ceiling-light/blob/main/yeelight_light_fancl5.yaml#L87-L118

keycode = 0 work, keycode=1 work.
keycode = 2 is not work
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 2.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][main:349]: Button wind speed pressed
[D][main:379]: Button with keycode 2 pressed
[D][esp32_ble_tracker:723]: Found device A4:C1:38:6E:85:0B RSSI=-50
[D][esp32_ble_tracker:744]:   Address Type: PUBLIC
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
```

test,
sometimes get length is 16 package
[D][ble_adv:169]:     - 0xFE95:  51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16)
[D][esp32_ble_tracker:723]: Found device A4:C1:38:63:BB:0A RSSI=-71
[D][esp32_ble_tracker:744]:   Address Type: PUBLIC
[D][ble_adv:169]:     - 0xFE95:  50.30.8E.06.C6.0B.85.6E.38.C1.A<IP_ADDRESS>.00.00.00 (17)

so, shoud be check length == 17

Okay. I will think about it how to schedule/delay the second command without using a blocking delay().

without delay(500)
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 40
[I][yeelight_fan_controller:141]: TX -> <IP_ADDRESS>.13.03 (6)
[I][yeelight_fan_controller:141]: TX -> <IP_ADDRESS>C.28.03 (6)
[D][fan:108]: 'yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 40
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:04:01:18:13:03:01:03:01:2C:28:03
[I][yeelight_fan_controller:036]: rx_buffer_size: 0
[I][yeelight_fan_controller:036]: rx_buffer_size: 1
[I][yeelight_fan_controller:036]: rx_buffer_size: 2
[I][yeelight_fan_controller:036]: rx_buffer_size: 3
[I][yeelight_fan_controller:036]: rx_buffer_size: 4
[I][yeelight_fan_controller:036]: rx_buffer_size: 5
[I][yeelight_fan_controller:089]: RX <- 01.F<IP_ADDRESS>.03 (6)
[I][yeelight_fan_controller:106]: Command successful
[D][uart_debug:114]: <<< 01:F3:01:07:13:03
```

with ` delay(500) ` between 2 command
```
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: ON
[D][fan:029]:   Speed: 40
[I][yeelight_fan_controller:141]: TX -> <IP_ADDRESS>.13.03 (6)
[I][yeelight_fan_controller:141]: TX -> <IP_ADDRESS>C.28.03 (6)
[D][fan:108]: 'yeelight ceiling fan' - Sending state:
[D][fan:109]:   State: ON
[D][fan:111]:   Speed: 40
[D][fan:115]:   Direction: FORWARD
[D][uart_debug:114]: >>> 01:04:01:18:13:03:01:03:01:2C:28:03
[I][yeelight_fan_controller:036]: rx_buffer_size: 0
[I][yeelight_fan_controller:036]: rx_buffer_size: 1
[I][yeelight_fan_controller:036]: rx_buffer_size: 2
[I][yeelight_fan_controller:036]: rx_buffer_size: 3
[I][yeelight_fan_controller:036]: rx_buffer_size: 4
[I][yeelight_fan_controller:036]: rx_buffer_size: 5
[I][yeelight_fan_controller:089]: RX <- 01.F<IP_ADDRESS>.03 (6)
[I][yeelight_fan_controller:106]: Command successful
[I][yeelight_fan_controller:036]: rx_buffer_size: 0
[I][yeelight_fan_controller:036]: rx_buffer_size: 1
[I][yeelight_fan_controller:036]: rx_buffer_size: 2
[I][yeelight_fan_controller:036]: rx_buffer_size: 3
[I][yeelight_fan_controller:036]: rx_buffer_size: 4
[I][yeelight_fan_controller:036]: rx_buffer_size: 5
[I][yeelight_fan_controller:089]: RX <- 01.F3.01.1C.28.03 (6)
[I][yeelight_fan_controller:106]: Command successful
[D][uart_debug:114]: <<< 01:F3:01:07:13:03:01:F3:01:1C:28:03
```

I've added the delay as workaround as long there is no better solution: https://github.com/syssi/esphome-yeelight-ceiling-light/pull/47

I've pushed a fix to handle short remote control frames: https://github.com/syssi/esphome-yeelight-ceiling-light/pull/48/files
It's already merged to main. Please give it a try. If it doesn't work out of the box please increase the log level to VERY_VERBOSE because I would like to see these log messages
ESP_LOGVV(TAG, "parse_xiaomi_message(): fixed byte not found, stop parsing residual data.");
ESP_LOGVV(TAG, "parse_xiaomi_message(): value has wrong size (%d)!", value_length);

to get a better idea what's going on.

e the log level to VERY_VERBOSE because I would like to see these log messages

make a mistake, can not set very_verbose, it will exhaust memory and can not update firmware on OTA.

The ESP should go into the safe mode after 10 failed restarts. You should be able to reflash the device without disassembly.

[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.
[I][xiaomi_ylyk01yl:018]: parse_device(): unknown MAC address.

The ESP should go into the safe mode after 10 failed restarts. You should be able to reflash the device without disassembly.

start normal, but using ota update will be crashed when update to 50%

Uh. That's bad. Sorry for the mess.

Please ignore this error:
parse_device(): unknown MAC address.

This is normal and happens for every discovered MAC address / BLE message if I remember correctly.

Please ignore this error:
parse_device(): unknown MAC address.
This is normal and happens for every discovered MAC address / BLE message if I remember correctly.
all key do not work

I've reverted my commit because manipulating the raw_offset was the wrong approach. The data / payload starts in both cases at the same position:
50.30.8E.06.1C.0B.85.6E.38.C1.A<IP_ADDRESS>.01.00.00 (17)
51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16)

0x50 0x30 0x8E 0x06 0x1C 0x0B 0x85 0x6E 0x38 0xC1 0xA4 0x01 0x10 0x03 0x01 0x00 0x00 (17)
0x51 0x32 0x8E 0x06 0x01 0x0B 0x85 0x6E 0x38 0xC1 0xA4 0x02 0x00 0x02 0x01 0x10 (16)
  0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16
     ^^^^^^^^^
    device_type          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                  mac_address
                                                        ^^ raw_offset=11, 3 bytes data
                                                         0    1    2
                                                         |    |    is_long_press if 0x02, else is_press
                                                         |    unused
                                                         keycode

0x51 0x32 0x8E 0x06 0x01 0x0B 0x85 0x6E 0x38 0xC1 0xA4 0x02 0x00 0x02 0x01 0x10 (16)

This 16 length package is for client register,  just ommit it!

Could you explain your feedback

keycode = 0 work, keycode=1 work.
keycode = 2 is not work

Are you able to receive keycode 2? There is no action attached at the moment.

D][binary_sensor:036]: 'fan running': Sending state ON
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.A2.0B.85.6E.38.C1.A<IP_ADDRESS>.01.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 1.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][light:035]: 'yeelight c900 ceiling' Setting:
[D][light:046]:   State: OFF
[D][light:084]:   Transition length: 0.5s
[D][main:370]: Button with keycode 1 pressed
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
[I][ble_adv:167]:  (length 16) - 51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16)
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.A4.0B.85.6E.38.C1.A<IP_ADDRESS>.01.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):

[I][ble_adv:167]:  (length 16) - 51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16)

[D][esp32_ble_tracker:723]: Found device A4:C1:38:53:B8:C8 RSSI=-72
[D][esp32_ble_tracker:744]:   Address Type: PUBLIC
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.04.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 4.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][main:356]: Button wind mode pressed
[D][main:370]: Button with keycode 4 pressed
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.02.0B.85.6E.38.C1.A<IP_ADDRESS>.05.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 5.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][main:364]: Button brightness pressed
[D][main:370]: Button with keycode 5 pressed
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.04.0B.85.6E.38.C1.A<IP_ADDRESS>.03.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 3.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][main:348]: Button color temperature pressed
[D][main:370]: Button with keycode 3 pressed
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.05.0B.85.6E.38.C1.A<IP_ADDRESS>.02.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 2.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][main:340]: Button wind speed pressed
[D][main:370]: Button with keycode 2 pressed
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF
[D][esp32_ble_tracker:723]: Found device 7C:FD:82:A2:C5:FD RSSI=-94
[D][esp32_ble_tracker:744]:   Address Type: PUBLIC
[D][esp32_ble_tracker:746]:   Name: 'XTC_WATCH'
[D][esp32.preferences:114]: Saving preferences to flash...

keycode 1
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.2C.0B.85.6E.38.C1.A<IP_ADDRESS>.01.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 1.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][light:035]: 'yeelight c900 ceiling' Setting:
[D][light:046]:   State: ON
[D][light:084]:   Transition length: 0.5s
[D][light:035]: 'yeelight c900 night' Setting:
[D][light:084]:   Transition length: 0.5s
[D][switch:017]: 'buzzer_beep' Turning OFF.
[D][switch:037]: 'buzzer_beep': Sending state OFF

keycode 0
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.2D.0B.85.6E.38.C1.A<IP_ADDRESS>.00.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 0.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON
[D][fan:022]: 'yeelight ceiling fan' - Setting:
[D][fan:025]:   State: OFF
[D][main:370]: Button with keycode 0 pressed
[I][yeelight_fan_controller:089]: RX <- 01.F<IP_ADDRESS>.03 (6)
[I][yeelight_fan_controller:106]: Command successful
[D][binary_sensor:036]: 'fan running': Sending state OFF

and tap M key, sometimes trigger keycode 1

Please keep in mind the example configuration is incomplete:
  on_press:
    - keycode: 0
      then:
        - switch.turn_on: buzzer_beep
        - fan.toggle: yeelight_ceiling_fan  # Toggles the fan
    - keycode: 1
      then:
        - switch.turn_on: buzzer_beep
        - light.toggle: ceiling_light  # Toggles the light
    - keycode: 2
      then:
        - switch.turn_on: buzzer_beep
        - logger.log: "Button wind speed pressed"
        # Please add additional actions here
    - keycode: 3
      then:
        - switch.turn_on: buzzer_beep
        - logger.log: "Button color temperature pressed"
        # Please add additional actions here
    - keycode: 4
      then:
        - switch.turn_on: buzzer_beep
        - logger.log: "Button wind mode pressed"
        # Please add additional actions here
    - keycode: 5
      then:
        - switch.turn_on: buzzer_beep
        - logger.log: "Button brightness pressed"
        # Please add additional actions here

In other words: You are able to receive the log messages of all keycodes / buttons. We have to connect the keycode with some additional actions?
What happens if you receive a 16 byte message? Is some action triggered here too?

What happens if you receive a 16 byte message? Is some action triggered here too?

wait, need more test. 16 byte message not always happen
I guess that,
[I][ble_adv:167]:  (length 16) - 51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16) , the x[14] = 01 , that will trigger keycode 1

Frame control bits of the 16 vs 17 byte frame.
>>> data = [0x51,0x32]
>>> frctrl = data[0] + (data[1] << 8)
>>> frctrl_mesh = (frctrl >> 7) & 1  # mesh device
>>> frctrl_version = frctrl >> 12  # version
>>> frctrl_auth_mode = (frctrl >> 10) & 3
>>> frctrl_solicited = (frctrl >> 9) & 1
>>> frctrl_registered = (frctrl >> 8) & 1
>>> frctrl_object_include = (frctrl >> 6) & 1
>>> frctrl_capability_include = (frctrl >> 5) & 1
>>> frctrl_mac_include = (frctrl >> 4) & 1  # check for MAC address in data
>>> frctrl_is_encrypted = (frctrl >> 3) & 1  # check for encryption being used
>>> frctrl_request_timing = frctrl & 1  # old version
>>>
>>> frctrl_mesh
0
>>> frctrl_version
3
>>> frctrl_auth_mode
0
>>> frctrl_solicited
1
>>> frctrl_registered
0
>>> frctrl_object_include
1
>>> frctrl_capability_include
0
>>> frctrl_mac_include
1
>>> frctrl_is_encrypted
0
>>> frctrl_request_timing
1
>>>
>>>
>>>
>>> data = [0x50,0x30]
>>> frctrl = data[0] + (data[1] << 8)
>>> frctrl_mesh = (frctrl >> 7) & 1  # mesh device
>>> frctrl_version = frctrl >> 12  # version
>>> frctrl_auth_mode = (frctrl >> 10) & 3
>>> frctrl_solicited = (frctrl >> 9) & 1
>>> frctrl_registered = (frctrl >> 8) & 1
>>> frctrl_object_include = (frctrl >> 6) & 1
>>> frctrl_capability_include = (frctrl >> 5) & 1
>>> frctrl_mac_include = (frctrl >> 4) & 1  # check for MAC address in data
>>> frctrl_is_encrypted = (frctrl >> 3) & 1  # check for encryption being used
>>> frctrl_request_timing = frctrl & 1  # old version
>>>
>>> frctrl_mesh
0
>>> frctrl_version
3
>>> frctrl_auth_mode
0
>>> frctrl_solicited
0
>>> frctrl_registered
0
>>> frctrl_object_include
1
>>> frctrl_capability_include
0
>>> frctrl_mac_include
1
>>> frctrl_is_encrypted
0
>>> frctrl_request_timing
0
>>>

maybe work
[I][ble_adv:167]:  (length 16) - 51.32.8E.06.01.0B.85.6E.38.C1.A<IP_ADDRESS>.01.10 (16)
[I][ble_adv:167]:  (length 17) - 50.30.8E.06.AF.0B.85.6E.38.C1.A<IP_ADDRESS>.02.00.00 (17)
[D][xiaomi_ble:322]: Got Xiaomi YLYK01YL-FANCL (A4:C1:38:6E:85:0B):
[D][sensor:125]: 'last button pressed': Sending state 2.00000  with 0 decimals of accuracy
[D][switch:013]: 'buzzer_beep' Turning ON.
[D][switch:037]: 'buzzer_beep': Sending state ON

when get 16 byte message, no output.

because fan control using mode + speed frame, command, so the buzzer_beep beep 2 times except for fan off (it using one command)

because fan control using mode + speed frame command, so the buzzer_beep beep 2 times except for fan OFF (it using one command)

Are you talking about the stock firmware or our setup/implementation? Our implementation should beep once per button press because of
    - keycode: 0
      then:
        - switch.turn_on: buzzer_beep    # <-------- beep once
        - fan.toggle: yeelight_ceiling_fan

I will give you a radio record

because there is delay 500ms between  2 command, so the beep sound wierd, change sequence will fix it.
when fan toggle execute complete, and then beep
    - keycode: 0
      then:
        - fan.toggle: yeelight_ceiling_fan
        - switch.turn_on: buzzer_beep    # <-------- beep once

when use remote controller, sometimes crash esp32. because use web ota debug windows, so can not see what happed when crash.

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

I've pushed another change to ignore the frctrl_solicited requests: https://github.com/syssi/esphome-yeelight-ceiling-light/commit/1c1f1dd322f343142d4a68740e3ac90c46ee4b80

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 buffer when period > 50 ms

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.

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.

how to do that

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).

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

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.

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

how find this gpio

Flash the stock firmware
Use the remote control or MiHome App to turn the ceiling lamp on and off.
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.

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.

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

Extend your config yaml by a switch entity per available GPIO please exclude the already known PWM und UART GPIOs
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.

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 - 36 , because it is not for output.

cannot be paired with the second ESP32 easily.

no, paired easy

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

need turn on ceiling or night light?

A bet GPIO3 is the one we are looking for.

gpio3 is for uart rx0, so are you sure?

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.

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.

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.

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

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.

how to set en(pin3) = 0 level, it always have high level

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.

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

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.

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?

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

not 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

I check LED ceiling light and night light connection on board

show ceiling light and night light positive electrode connection together

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

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.

I have decompile circuit diagram.

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

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

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

@avion23 thank you


Doc keras/Model for "predict" function the list of argument is not display properly (fullblock instead of list)

System information

TensorFlow version: 2.0
Doc Link:
https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/Model

Describe the documentation issue
In the documentation keras/Model for "predict" function the list of argument is not display properly (fullblock instead of list) on both Chrome and Firefox

I think the issue is that the first line x: Input samples. should be prefixed with 4 spaces (not 5). Created a PR #27596 for the fix.

@dynamicwebpaige  @margaretmz  Since you are experts, any idea why this PR didn't pass test ? It was just to fix some display issue of the Keras doc. I didn't do the PR but I see it didn't pass the test and it is not clear why. Thanks

I don't know if it normally take 2 days to deploy the new version of the doc, but I still see the same issue in the doc:

Thanks

The issue was not fixed with the PR, please reopen the ticket. Thanks

@tarrade The page is pointing to 2.0.0alpha so it still use the docstring in 2.0.0 python. The PR #27596 fixes the issue in the master branch, it will show up in the next release of 2.0.0 (alpha or beta), then the web page will be re-rendered to capture the change.
I will re-open the issue for now, though I think once the next release of 2.0.0 (alpha or beta) is out the page will be updated and corrected automatically.

@yongtang ah ok got it. Since this was independend of a Tensorflow version (the format), I was think it will be probagated to the main branch and I could see the update on the main page. I am fine to have the ticket closed since the issue is really fixed.

I am closing the issue as it was resolved. I have checked that the PR was merged already. It will reflect on the website soon. Thanks!


[BUG]: Trigger atomicity is broken

Atm we don't have trigger atomicity, tirgger can fail and still change state in some way.

@Mingela i moved this to verify column in zenhub, so our QA team could verify ticket.


IDE can support multiple canisters

Reported by @kritzcreek
Resolving canister aliases in the IDE
Problems:
At this point in time the Language Server (called LS going forwards)  uses the same set of arguments as moc, meaning all canister aliases  have to be given statically on startup, and all .did files have to  be put into the same directory for the LS to find them
When the LS starts up .did files might not have been generated and  the canister ids for canisters in the project might not be known yet.
DFX generates temporary files during the build process that the  long-running LS can't read.
This means currently the LS doesn't work well in multi-canister  projects (It doesn't work for any canister that imports another one)
Solution 1:
DFX outputs the required information for the LS to a known location  in a persistent fashion. This would include:
canister alias - entry point mapping
canister alias - id mapping
a single path where all IDL files get generated (and garbage collected!)The two canister alias mappings can be used to invalidate out of dateIDL files from the LS, which can then produce more up-to-dateversions on the file system, or update them in-memory.The garbage collected bit is important because the LS can't tell whichidl files are for external services and which are for canisters thatused to exist in the local project but have been removed by the usersince.
Solution 2:
The LS reproduces enough of DFX's understanding of a project to be  able to handle the dynamic IDL generation on its own
This means moving more knowledge about what a Motoko project is  into the compiler, so would need design work

Closing all issues created by me that are older than 2 years as cleanup.


fix: add run first determines whether a package.json exists (#138)

Prompt the user if it is not currently a valid node project

Linked Issues
#138

I am not really convinced by this. I'd expect ni to work in all cases, when package.json is not presented it should show a prompt to choose the agent. I'd love to see a minimal reproduction of the original issue as I didn't saw that error.

I am not really convinced by this. I'd expect ni to work in all cases, when package.json is not presented it should show a prompt to choose the agent. I'd love to see a minimal reproduction of the original issue as I didn't saw that error.

nris ok,niis wrong, you can create an empty folder at random, go to the end point and executeni.  Including nu is also unreasonable

https://github.com/antfu/ni/issues/138#issuecomment-1594894106


Add an explicit base class pointer to avoid potential breakage.

Should fix #5499.

Green enough?

Ping.

LGTM


Add support for command line arguments to the iPython notebook

Feature request
I'm looking to run a notebook server, and this command gives an error:
shell_plus --notebook profile create nbserver
Error: Command doesn't accept any arguments
Would really appreciate this, or an interim workaround to let me run a server.

I think the IPYTHON_ARGUMENTS in settings file solution works for most people / use cases.
If you still need additional support for ipython arguments please open a new ticket.


Can't install PHP extension using manual

Is there an existing issue for this?

[X] I have searched the existing issues

Output of ddev debug test
Expand `ddev debug test` diagnostic information
Running bash [-c /var/folders/3x/jhynh62d10l0l1lt2rwrlcv80000gn/T/test_ddev.sh]
======= Existing project config =========
These config files were loaded for project project.com: [/Users/nnevill/projects/project.com/.ddev/config.yaml /Users/nnevill/projects/project.com/.ddev/config.sqlsrv.yaml]
name: project.com
type: drupal10
docroot: web
php_version: 8.2
webserver_type: nginx-fpm
webimage: ddev/ddev-webserver:20230803_php_serialize_precision
router_http_port: 80
router_https_port: 443
database: {mariadb 10.4}
hooks: map[post-start:[map[exec:echo export PATH="$PATH:/opt/mssql-tools/bin" >> ~/.bashrc] map[exec:source ~/.bashrc]]]
mailhog_port: 8025
mailhog_https_port: 8026
project_tld: ddev.site
use_dns_when_possible: true
composer_version: 2
disable_settings_management: true
nodejs_version: 18
default_container_timeout: 120
======= Creating dummy project named  tryddevproject-2606 in ../tryddevproject-2606 =========
OS Information: Darwin Andriis-MacBook-Pro-3.local 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000 arm64
ProductName:		macOS
ProductVersion:		13.0.1
BuildVersion:		22A400
User information: uid=501(nnevill) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae),702(com.apple.sharepoint.group.2)
DDEV version:  ITEM             VALUE
 DDEV version     v1.22.1
 architecture     arm64
 db               ddev/ddev-dbserver-mariadb-10.4:v1.22.0
 ddev-ssh-agent   ddev/ddev-ssh-agent:v1.22.0
 docker           24.0.6
 docker-compose   v2.20.0
 docker-platform  docker-desktop
 mutagen          0.17.2
 os               darwin
 router           traefik:v2.10
 web              ddev/ddev-webserver:20230803_php_serialize_precision
PROXY settings: HTTP_PROXY='' HTTPS_PROXY='' http_proxy='' NO_PROXY=''
======= DDEV global info =========
Global configuration:
instrumentation-opt-in=true
omit-containers=[]
performance-mode=mutagen
router-bind-all-interfaces=false
internet-detection-timeout-ms=3000
disable-http2=false
use-letsencrypt=false
letsencrypt-email=
table-style=default
simple-formatting=false
auto-restart-containers=false
use-hardened-images=false
fail-on-hook-fail=false
required-docker-compose-version=v2.20.0
use-docker-compose-from-path=false
project-tld=
xdebug-ide-location=
no-bind-mounts=false
router=traefik
wsl2-no-windows-hosts-mgt=false
router-http-port=80
router-https-port=443
traefik-monitor-port=10999

======= DOCKER info =========
docker location: lrwxr-xr-x  1 root  wheel  54 Nov 21  2022 /usr/local/bin/docker -> /Applications/Docker.app/Contents/Resources/bin/docker
Docker Desktop Version: Docker Desktop for Mac 4.25.1 build 128006
docker version:
Client:
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:28:49 2023
 OS/Arch:           darwin/arm64
 Context:           default

Server: Docker Desktop 4.25.1 (128006)
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:31:36 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
DOCKER_DEFAULT_PLATFORM=notset

Expected Behavior
PHP extension added smoothly as in manual.
Actual Behavior
I need to add several PHP extensions (sqlsrv and pdo_sqlsrv). First thing I did is read the manual here
Then I've created .ddev/web-build/Dockerfile with exact the same content as in manual:
ENV extension=mcrypt
SHELL ["/bin/bash", "-c"]
# Install the needed development packages
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::="--force-confnew" --no-install-recommends --no-install-suggests build-essential php-pear php${DDEV_PHP_VERSION}-dev
# mcrypt happens to require libmcrypt-dev
RUN apt install -y libmcrypt-dev
RUN pecl install ${extension}
RUN echo "extension=${extension}.so" > /etc/php/${DDEV_PHP_VERSION}/mods-available/${extension}.ini && chmod 666 /etc/php/${DDEV_PHP_VERSION}/mods-available/${extension}.ini
RUN phpenmod ${extension}```

But as a result I've got the following:
```console
failed to solve: process "/bin/bash -c apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=\"--force-confnew\" --no-install-recommends --no-install-suggests build-essential php-pear php${DDEV_PHP_VERSION}-dev" did not complete successfully: exit code: 100
Failed to restart project.com: docker-compose build failed: ComposeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-project docker-compose -f /Users/nnevill/projects/project.com/.ddev/.ddev-docker-compose-full.yaml --progress=quiet build', action='[--progress=quiet build]', err='exit status 17', stdout='', stderr='failed to solve: process "/bin/bash -c apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=\"--force-confnew\" --no-install-recommends --no-install-suggests build-essential php-pear php${DDEV_PHP_VERSION}-dev" did not complete successfully: exit code: 100', output='', stderr='failed to solve: process "/bin/bash -c apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=\"--force-confnew\" --no-install-recommends --no-install-suggests build-essential php-pear php${DDEV_PHP_VERSION}-dev" did not complete successfully: exit code: 100'

I've also tried a super simple Dockefile with the following content:
RUN apt-get update

But still got an error:
failed to solve: process "/bin/sh -c apt-get update" did not complete successfully: exit code: 100
Failed to restart project.com: docker-compose build failed: ComposeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-project docker-compose -f /Users/nnevill/projects/project.com/.ddev/.ddev-docker-compose-full.yaml --progress=quiet build', action='[--progress=quiet build]', err='exit status 17', stdout='', stderr='failed to solve: process "/bin/sh -c apt-get update" did not complete successfully: exit code: 100', output='', stderr='failed to solve: process "/bin/sh -c apt-get update" did not complete successfully: exit code: 100'

What could be wrong here?
Steps To Reproduce
I've tried just a clean environment with Drupal and got the same problem.
Anything else?
No response

Could you please try it with the current version of DDEV, v1.22.7?
https://ddev.readthedocs.io/en/stable/users/install/ddev-upgrade/

Hi Randy.
It works now.
I've updated ddev with a brew before posting this bug report. But for some reason, I had some another old binary ddev executable that was used so I removed it and reinstalled it with brew and things are now working like a charm.
Thanks!


disable system printf

is it possible to get rid of all system messages (boot, wifi, etc...) in UART but leave the option to use printf?
esp8266 trick with
int ets_printf(const char *format, ...)
{
	return 0;
}

doesn't work

https://esp-idf.readthedocs.io/en/latest/api-reference/system/log.html#_CPPv219esp_log_set_vprintf14vprintf_like_t

that works for wifi messages, but bootloader still prints its stuff

https://github.com/espressif/esp-idf/blob/master/components/bootloader/Kconfig.projbuild#L2

nope. still prints:
ets Jun  8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
....

That's ROM bootloader, you have to pull MTDO low

Wow! that helped, thanks!


[Bug]: Monkey365 is not handling duplicate entries in Analysis parameter

What happened?
Duplicate values in Analysis should raise some kind of warning. This would help prevent mistakes when working with larger tenants and complex configs.
How to reproduce it
Steps to reproduce the behavior:

$param = @{
    Instance = 'Microsoft365';
    Analysis = @("SharePointOnline","Microsoft365","ExchangeOnline","SharePointOnline","Purview","MicrosoftTeams");
    PromptBehavior = 'SelectAccount';
    IncludeEntraID = $true;
    ExportTo = @("CSV","JSON","HTML");
}
Invoke-Monkey365 @param

The above command will be executed without throwing any error (or warning).
Expected behavior
Duplicate values in Analysis should raise some kind of warning or throw an error.
From where are you running Monkey365?
Please, complete the following information:

Resource: [Docker container, workstation)  all
OS: [e.g. Windows, Linux, etc. ] all
PowerShell Version [$PsVersionTable]: all versions
Monkey365 Version: Monkey365 v0.91.2-beta (dev)

Fix on dev branch.
Cheers,

This is now updated in main release.
Cheers,


KPConv

❓ Questions & Help

Hey @rusty1s, what is your intuition for implementing KPconv in the best manner within pytorch geometric.

I was thinking to perform two radius search. One to create the balls of the same size of the kernels, a second one to perform kernel search from the neighbooring points of the center to the kernels based on sigma we defined within those balls. Calculte ratio between distance / sigma * torch. Index select weights. Perform a first scatter add to create the weights and then a mat prod between weights and features at those neighboors and a scatter max/mean on the center of the sphere and so on.

But I am afraid it will be slow.

Using a first radius + a custom cuda kernel between 2 spheres. But it will make it hard for people to change things into it.

What do you think ?

I am not sure why you need to perform two radius searchs. Actually, the radius search is IMO not part of the KPConv and should be viewed as given input edge_index.
I believe the basic idea of KPConv can be easily implemented with the MessagePassing interface. Simply compute the linear correlation between all kernel weights and pos_j - pos_i in the message function. You should apply the kernel deformation here too. Initializing the kernel positions is a bit tricky, since it needs to solve an optimization problem in reset_parameters.

Hey @rusty1s,
I have almost finished to implement KPConv, but I have a wierd bug from cublas you might know about.
Can you have a look at the code and help me to debug it ?
It is on the branch: Implement_Point_Kernel
https://github.com/tchaton/KP_Conv/invitations
Best,
Thomas Chaton.

Thanks for your implementation! I will have a closer look as soon as possible. Currently on a paper deadline, so I do not think I will have time to look at it in detail this week. Do you have any error messages for me? In which line does the error occur?

Hey @rusty1s,
I am getting: RuntimeError: cublas runtime error : the GPU program failed to execute at /pytorch/aten/src/THC/THCBlas.cu:331
But I think it is liked to my cuda installation, as it is working fine on cpu.

Hey! I am also trying to make a KPConv implementation using torch_geometric. However, i am running into some unexpected memory issues (i think i am allocating more memory than necessary)
@tchaton did you manage to finish your implementation and if so, could i have a peak at your code to figure out what i am doing wrong ?

Hey! I am also trying to implement KPConv using torch_geometric. However, i am running into some memory issues ( i think i am allocating more memory than necessary)
@tchaton did you manage to finish your implementation and if so, could i have a peak at your code to figure out what i am doing wrong (the link you posted above doesn't seem to work and i couldn't find it your repositories)?
Also, my implementation is here :  https://github.com/JohnRomanelis/KPConv_torch_geometric/
Thank you in advance!

Hey @JohnRomanelis, yes, it is implemented in torchpoints3d repo

Hey @rusty1s,
Thanks you very much :) We will also share Relation Shape which is almost PointNet++.
bug #1.
Here are the shapes: torch.Size([793, 16, 16]) torch.Size([793, 16, 3])
Should be fine on gpu and works fine on cpu.
Traceback (most recent call last):
File "kp_train.py", line 162, in
train()
File "kp_train.py", line 112, in train
out = model(data)
File "/home/thomas/.cache/pypoetry/virtualenvs/superpoint-graph-job-py3.6/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in call
result = self.forward(*input, **kwargs)
File "kp_train.py", line 91, in forward
kp1_out = self.kp1_module(*input)
File "/home/thomas/.cache/pypoetry/virtualenvs/superpoint-graph-job-py3.6/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in call
result = self.forward(*input, **kwargs)
File "/home/thomas/HELIX/research/KPConv/modules.py", line 166, in forward
x = self.conv(x, (pos, pos[idx]), edge_index)
File "/home/thomas/.cache/pypoetry/virtualenvs/superpoint-graph-job-py3.6/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in call
result = self.forward(*input, **kwargs)
File "/home/thomas/HELIX/research/KPConv/modules.py", line 80, in forward
return self.propagate(edge_index, pos=pos)
File "/home/thomas/.cache/pypoetry/virtualenvs/superpoint-graph-job-py3.6/lib/python3.6/site-packages/torch_geometric/nn/conv/message_passing.py", line 126, in propagate
out = self.message(*message_args)
File "/home/thomas/HELIX/research/KPConv/modules.py", line 85, in message_pos
return self.message_forward(pos_i=pos_i, pos_j=pos_j)
File "/home/thomas/HELIX/research/KPConv/modules.py", line 139, in message_forward
weighted_features = torch.matmul(all_weights, features)
RuntimeError: cublas runtime error : the GPU program failed to execute at /pytorch/aten/src/THC/THCBlas.cu:450
(superpoint-graph-job-py3.6) ➜ KPConv git:(Implement_Point_Kernel) python
Python 3.6.8 (default, Oct 1 2019, 16:49:07)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

import torch
x = torch.randn((1000,))
x = torch.randn((793, 16, 16)).cuda()
y = torch.randn((793, 16, 3)).cuda()
torch.matmul(x, y)
Traceback (most recent call last):
File "", line 1, in
RuntimeError: cublas runtime error : the GPU program failed to execute at /pytorch/aten/src/THC/THCBlas.cu:450

bug #2, the loss gets to nan after one element.

Hi, any updates on KPConv?

Hey! I am also trying to implement KPConv using torch_geometric. However, i am running into some memory issues ( i think i am allocating more memory than necessary)
@tchaton did you manage to finish your implementation and if so, could i have a peak at your code to figure out what i am doing wrong (the link you posted above doesn't seem to work and i couldn't find it in your repositories)?
Also, my implementation is here : https://github.com/JohnRomanelis/KPConv_torch_geometric/
Thank you in advance!

Hi @JohnRomanelis , did you manage to add KPConv in Pytorch Geometric?

Hey @caizhongang , if i get it right the torch-points3d isn't using the torch-geometric message passing scheme to implement the KPConv. Unfortunately, i haven't made an implementation of my own yet.


Simulator: display additional info in logs

Independent changes to declutter diff in cook-executor PR

Passing build: https://travis-ci.org/twosigma/Cook/builds/228533097

addressed feedback from @dposada  and @pschorf

Passing build: https://travis-ci.org/twosigma/Cook/builds/228758848


Stale connection occurred during failover and READONLY commands could not be executed as Redis was in warm-up state

Bug Report
In this scenario, Lettuce version 5.3 is being used with a Redis cluster consisting of 3 master nodes and corresponding replica nodes. The client is configured to use readFrom NEAREST to connect to the Redis cluster and readFrom MASTER to the master nodes.
The previous status was as follows: master_1 had a corresponding slave_1. However, when master_1 was restarted, it got changed to slave, and the slave_1 was promoted to master due to failover.
From the client's perspective, before the failover, it had a readwrite connection to master_1 and a readonly connection to replica_1. After the failover, the connection to the previous master_1 remained active and successfully reconnected. Additionally, after the topology refresh (every 60 seconds), a new connection was established between the client and the previous master_1 (current slave), resulting in two connections instead of the expected one.
Consequently, we encountered a "MOVED" error caused by the connection issue.
RedisStateMachine: Decoded ClusterCommand [command=AsyncCommand [type=MGET, output=KeyValueListOutput [output=[], error='MOVED 5123 xxx:6379'], commandType=io.lettuce.core.protocol.Command], redirections=0, maxRedirections=5], empty stack: true

And another mget call to the routed node was triggered.
write(ctx, ClusterCommand [command=AsyncCommand [type=MGET, output=KeyValueListOutput [output=[], error='null'], commandType=io.lettuce.core.protocol.Command], redirections=1, maxRedirections=5], promise)

The question is whether it is expected to have two connections in this case, considering that topology period refresh is enabled. And if there is any solution to prevent this issue without restarting the application (client).

[INFO]  (lettuce-epollEventLoop-5-13) ReconnectionHandler: Reconnected to <IP_ADDRESS>:6379, Channel channel=0xe6c8cf11, /<IP_ADDRESS>:48924 -> <IP_ADDRESS>/<IP_ADDRESS>:6379

After setting up the new channel, an attempt was made to register in READONLY mode. However, an error occurred during the process.
28 Nov 2023 19:36:36,188 [DEBUG]  (lettuce-epollEventLoop-5-13) RedisStateMachine: Decoded ActivationCommand [type=READONLY, output=StatusOutput [output=null, error='LOADING Redis is loading the dataset in memory'], commandType=io.lettuce.core.protocol.AsyncCommand], empty stack: true
28 Nov 2023 19:36:36,188 [WARN]  (lettuce-epollEventLoop-5-13) StatefulRedisConnectionImpl: READONLY failed: LOADING Redis is loading the dataset in memory

If the READONLY command fails to execute, the replica node will not be able to handle the subsequent read commands.
The workflow involves reconnecting to the replica node, attempting to set up READONLY mode, and encountering a failure due to the "Redis is loading the dataset" error. As a result, the connection does not enable READONLY mode, leading to the failure of executing the MGET commands on the replica node (resulting in a "MOVED" exception in this scenario).
Is there a way to prevent this issue from occurring in this scenario? For example, could we prevent the client from attempting to connect to the replica node (which is hidden from the client's perspective) during the dataset loading process? We hold on the readonly command and once the loading dataset is ready, then we try to reconnect and enable READONLY mode.

There are a couple questions here, let's try to go about it in sequence:

The question is whether it is expected to have two connections in this case,

Lettuce creates up to two connections per host, one read-only, one read-write and if the node goes down, Lettuce tries to reconnect to that node.
You've experienced the LOADING error and that is one of these cases where reconnect can fail.
In Lettuce 6.0 we improved the handshake process to disconnect the connection and attempt a reconnect later on when LOADING is gone.

Thank you for your response! It was very helpful!
Connection issue
I have a few follow-up questions regarding the connection. To simplify the issue:

T1: The client has a readonly connection to Redis replica node A.

T2: A failover occurs, promoting the Redis replica node to master, making Redis node A the new master node.

T2: The client detects that it now has two connections to Redis node A.

The questions here are:

Why does the connection become two at T2? One is the original connection held by the client, and the other is the ReadWrite connection that needs to be set up due to the role change of Redis node A.

At T2, when the client executes a command, how does it choose which connection to use?

Currently, is it true that only restarting the client can restore the connection data for Redis node A to normal (i.e., one connection)?

READONLY connection not setup successfully issue
I'm glad to hear that the LOADING error has been resolved in higher versions. We will upgrade to that version to confirm. Wondering how does Lettuce know when the LOADING state is gone? Since LOADING should be operation on the Redis server side, is there any event notification that Lettuce can receive?


Getting recipient signed or not and get the recipient inputs in web hook

Hi,
We have added the custom field check box in the template in docusign admin panel and on user end if the user is checked the check box we are not able to find the value,kindly tell me how to achieve it
in api php we are using below  code
$envelopeEvents = ['customFields','recipients','tabs','form_data'];
$event_data1 = new \DocuSign\eSign\Model\ConnectEventData([
'include_data' =>$envelopeEvents
]);
$recipient_event1 = new \DocuSign\eSign\Model\RecipientEvent([
'recipient_event_status_code' => "Sent"
]);
$recipient_events1 = [$recipient_event1];
$envelope_event1 = new \DocuSign\eSign\Model\EnvelopeEvent([
'envelope_event_status_code' => "Completed"
]);
$envelope_events1 = [$envelope_event1];
$event_notification1 = new \DocuSign\eSign\Model\EventNotification([
'envelope_events' => $envelope_events1,
'event_data' => $event_data1,
'include_envelope_void_reason' => "true",
'logging_enabled' => "true",
'recipient_events' => $recipient_events1,
'require_acknowledgment' => "true",
'url' => "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
]);
$envelope_definition->setEventNotification($event_notification1);
kindly help me to get the envelope form field values in webhook using php

Checkbox values can be obtained using this code example that is part of this repo - https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/EnvelopeTabDataService.php


Deleted CIS scans aren't removed from the Scans list

Delete works fine, just the entries aren't removed from the list whilst on the scans page

You need to install the 'CIS Benchmark' cluster tools to see this.

@richard-cox I could not reproduce this.


Hotkey to quit the app

...wold be great.
And make Alt+F4 do it as well, like any other app.
And setting to close the app when last tab is closed.

This! It's hard to believe there isn't a hotkey for this.

This! It's hard to believe there isn't a hotkey for this.


DocsArchive-<IP_ADDRESS>Auto archive content

Auto archive content from https://github.com/VSC-Service-Account/docs-archive-test-source.git

Docs Build status updates of commit 96ed8db:
:x: Validation status: errors
Please follow instructions here which may help to resolve issue.

File
Status
Preview URL
Details

:x:Error

Details

[Error-RepositoryUnauthorizedWithSourceCommit] Git data access to 'https://github.com/VSC-Service-Account/docs-archive-test-target' (branch: Release_Archive_master_2020-05-25-13-53-28) is not authorized.. It looks like this might be the first time you’ve submitted a pull request to this repo. Before you can run builds in a pull request, you have to enable your GitHub account in Docs by visiting https://opportal-sandbox.azurewebsites.net. After you enable your account, close and then reopen this pull request to start another build.

For more details, please refer to the build report.
Note: Broken links written as relative paths are included in the above build report. For broken links written as absolute paths or external URLs, see the broken link report.
Note: Your PR may contain errors or warnings unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.
For any questions, please:Try searching in the Docs contributor and Admin GuideSee the frequently asked questionsPost your question in the Docs support channel


Add support for PostgreSQL operators in drogon::orm::CompareOperator

Notice
If you need support or clarification regarding the usage of Drogon in your project, visit the official Drogon support channel at gitter
Please create a new issue only if you think you have found a bug or if have a feature request/enhancement.
Is your feature request related to a problem? Please describe.
When fiddle around with PostgreSQL's unique types Array, Json, etc., it is hard to use ORM feature along with operators like <@, @> and &&.
Describe the solution you'd like
Add a custom constructor in drogon::orm::Criteria which accepts any operand(std::string) and custom leftValue(std::string) instead of colName.
Describe alternatives you've considered
Add enums into enum class drogon::orm::CompareOperator, then process them in drogon::orm::Criteria's constructor.
This is an alternative... But why not just implement both?
Additional context
Add ORM support for PostgreSQL's  Array, Json, etc. later with better efficiency.

See progress in #1241

This issue should be closed due to the mergence of the related PR


WindowDialog can't be resized diagonally

Godot version:
master:  03823f1
Issue description:
The WindowDialog and anything that inherits from it don't seem to be able to be resized diagonally, only horizontally and vertically.

 It can be resized, but I wasn't able to click in the correct spot because the cursor doesn't change to reflect that. Likely related to https://github.com/godotengine/godot/issues/14878.
Closing it.

I still wonder why the cursor itself affects the hit test which doesn't care about the actual cursor, just the coordinates.

No, no. It detected it just fine, I just have the precision of a mole. :v