Controlling BLE ceiling light with HA

Hi Dave,

Well in fact ESPHome is a very good base to build components that easily interact with HA, abstracting a lot of the process. Extracting a full standalone software would need a lot of work.

Still you can use Any ESPHome based device without HA by configuring the webserver or using the REST API. I never used those so I cannot help more, but it may help.

Rgds

Hi NicolIT,
that seems doable, but do you ( or anyone else) know if the BLE registration is following some sort of hardware “fingerprint” or it’s following hardware/software combination?
No point to “reinvent the wheel”: if it’s hardware connected I can setup a temporary HA, register the BLE on the ESP32 and then embed the result into the ESP .
Just to clarify : I am not planning to control speed, light colour or intensity through the ESP, simply send command like ON and OFF at a predefined combination.
I will leave the “finesse” to mobile phone or remote control.
Ideally once embedded I will add the Hue emulator to allow a local discovery of the service and drive the operations using a voice command.

Regards

Hello Dave,

do you ( or anyone else) know if the BLE registration is following some sort of hardware “fingerprint” or it’s following hardware/software combination?

There is no need to perform ‘BLE registration’ (aka ‘Pairing’): in order to control a device, one ‘just’ need to listen to a BLE ADV command emitted by another controller (such as a Phone or a physical remote), extract the info and re emit (nearly) the same. If you are lucky (but this is not often the case) you can re emit exactly the same command to have the same result. If not, and this is all the point of our component, you have to decode the message, extract the key info and use it to encode new messages, you can find details on how those devices are controlled here.

No point to “reinvent the wheel”: if it’s hardware connected I can setup a temporary HA, register the BLE on the ESP32 and then embed the result into the ESP .

No need to setup a HA at any point to do so: the ESP32 software is able to listen to commands emitted by another controller, decode them and log all the needed info for itself to be able to build any command.

Just to clarify : I am not planning to control speed, light colour or intensity through the ESP, simply send command like ON and OFF at a predefined combination.

It is as ‘simple’ to control speed or anything else than to send ON / OFF command: the complexity is the encoding / decoding of the commands, not the command itself.

Ideally once embedded I will add the Hue emulator to allow a local discovery of the service and drive the operations using a voice command.

As would do HA and ESPHome natively, one day you will come to it :slight_smile:

Rgds

Hello everyone, I tried to use the component github://NicoIIT/esphome-components
the guide is really well structured and I think I did everything correctly but the lamp doens’t respond so I guess I didn’t and I would appreciate some advice.
this is my yaml

esphome:
  name: lampsmart-pro
  friendly_name: ESP32-light

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
  - platform: esphome

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

captive_portal:

external_components:
  - source: github://NicoIIT/esphome-components

ble_adv_handler:
  log_raw: true
  log_command: true
  log_config: true

ble_adv_controller:
  - id: my_controller
    encoding: lampsmart_pro
    variant: v1  
    forced_id: 0x9350E1
    index: 0
    
light:
  - platform: ble_adv_controller
    ble_adv_controller_id: my_controller
    name: Living Wall Lamp
    type: cww

button:       
  - platform: template
    name: Pair
    entity_category: config
    on_press:
      ble_adv_controller.pair: my_controller

When I use the handler I record 3 inputs every time I press a button on the phone. apparently it uses 3 different encoding for some reasons. if I turn on the light I get:

[20:24:45][D][lampsmart_pro - v1:378]: Decoded OK - tx: 2, gen: LIGHT/0 - ON, enc: 0x10 - param1 0x00 - args[0,0,0]
[20:24:45][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: lampsmart_pro
  variant: v1
  forced_id: 0x9350E1
  index: 0
[20:24:45][D][lampsmart_ios - v1:378]: Decoded OK - tx: 2, gen: LIGHT/0 - ON, enc: 0x10 - param1 0x00 - args[0,0,0]
[20:24:45][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: lampsmart_ios
  variant: v1
  forced_id: 0x9350E1
  index: 0
[20:24:45][D][ble_adv_handler:362]: raw - 02.01.01.1B.03.F0.08.30.80.B8.65.E1.27.05.F7.EF.F0.65.7C.A4.9F.67.F6.B6.4D.68.8B.53.2B.D6.F4 (31)
[20:24:45][D][lampsmart_pro - v3:378]: Decoded OK - tx: 17, gen: LIGHT/0 - ON, enc: 0x10 - param1 0x00 - args[0,0]
[20:24:45][D][light:036]: 'Living Wall Lamp' Setting:
[20:24:45][D][light:047]:   State: ON
[20:24:45][D][ble_adv_light:046]: Switch ON
[20:24:45][D][ble_adv_controller:140]: Publishing mode - No Command sent to controlled Device.
[20:24:45][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: lampsmart_pro
  variant: v3
  forced_id: 0x852F59E1

Based on my config above I get instead:

[20:32:42][D][light:047]:   State: ON
[20:32:42][D][ble_adv_light:046]: Switch ON
[20:32:42][D][lampsmart_pro - v1:234]: UUID: '0x9350E1', index: 0, tx: 7, enc: 0x10 - param1 0x00 - args[0,0,0]
[20:32:42][D][ble_adv_handler:343]: request start advertising - 6: 02.01.19.1B.03.77.F8.B6.5F.2B.5E.00.FC.31.51.D0.3D.92.08.24.CB.DB.FC.95.8E.4E.78.EC.11.8E.3F (31)
[20:32:43][D][ble_adv_handler:351]: request stop advertising - 6

to me the main different is that “tx” is different but I don’t know how to force it because it of course change command by command. I tried to change encoding to zhijia, index to 1 and all the lampsmart_pro variants but nothing solves it.

any educated guess please?

Hello @Bonfo10 ,

You are really near the solution :slight_smile: I think.

Concerning the ‘tx’ in the logs, it is the transaction number, it increases on each command so it differs and it is perfectly normal!

You discovered 3 different configs by listening on the LampSmart Pro App (just to be sure, this will work only if this phone app is already paired to your device and controlling it), it is also normal as Android Apps are sending multiple commands to cope with various different device types, but only one is effectively controlling your device while the others have no effect. Just retry them one by one in the yaml directly.

Still as it seems you tried all the configs already, your ESP is maybe too far from your device so you may need to increase the transmitted power of your esp with option use_max_tx_power (by default this transmitted power is limited on some boards such as the ESP32-C3/6):

ble_adv_handler:
  use_max_tx_power: true

No guarantee here, Hope it will help.

+1 for checking distance/power - My outside light is the other side of a brick wall and I need to have the ESP less than 1m from it to penetrate, whereas my phone seemed to cope much better.

Hi @NicoIIT,
thanks for your quick reply! I tried again the first encoding lampsmart_pro v3 and turning off the log from the handler it magically worked!
It seems all good now! thanks a lot for the tips.
I activated “use_max_tx_power: true” even if the ESP is in the same room with nothing covering the lamp so that shouldn’t be the issue but I won’t touch anything now that works!

thanks again!

Hello again @NicoIIT
I need another advice if possible. I’m controlling 2 lights of the exact same time mount on the wall a couple of meters apart.
I’m noticing that most of the time the command act on only 1 of them. I extended “my_controller - Duration” to 1000; it’s slightly better but still not great. 3 out of 5 times only 1 light receive the command.

I was thinking to create 2 lights and join them in a group but their config will be the same (except for the name). Would it be a problem? Any further advice?
Thanks in advance

Well I think your problem is still the same: your ESP has not enough power to advertise messages to (one of) your device. Increasing the duration can indeed help because it gives more chance to have one message reaching your device, but it does not solve the root cause: you can do whatever configuration change it will not solve this issue, only decreasing the distance between the ESP and the lamps will help.

@ ALL, I mostly finalized a HA Custom Integration using directly the Bluetooth stack of your Home Assistant host, the topic for this is here, waiting for BETA testers!

2 Likes

This is some incredible work @NicoIIT ! I’ve just installed a fan light that uses yet another app called “Zhi Kong” or “HF Smart” if you want to add those to the compatibility list. I found that the zhimei vf0 encoder worked right out of the gate and paired successfully. I’ll try the HA custom integration too as it would be nice to free up an esp32 for other things

2 Likes

Hey @NicoIIT , the control part is working great but now I’m trying to use the ble_adv_remote feature to sync the state to HA and I found out that my remote is failing to be decoded correctly. To be completely honest, I just got lucky that the first encoding I tried (zhimei vf0) worked for directly pairing to the light.

Here’s the capture from the remote with the malformed raw message:

[20:46:13][D][ble_adv_handler:362]: raw - 1E.FF.1F.61.3E.48.46.4B.4A.16.77.19.1F.72.BD.E7.D5.77.36.70.52.67.23.79.0C.10.11.12.13.14.15 (31)
[20:46:14][D][ble_adv_handler:362]: raw - 55.FF.20.61.3E.06.00.00.00.19 (10)
[20:46:14][D][ble_adv_handler:366]: Malformed raw message - ignored.

And here’s a capture and successful decode from the phone app:

[20:54:09][D][ble_adv_handler:362]: raw - 02.01.01.0B.03.55.01.18.CB.D0.B4.AA.66.55.22 (15)
[20:54:09][D][zhimei - vf0:379]: Decoded OK - tx: 24, gen: CONTROLLER - PAIR, enc: 0xB4 - args[170,102,85]
[20:54:09][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: zhimei
  variant: vf0
  forced_id: 0xD0CB
  index: 1
[20:54:09][D][ble_adv_handler:362]: raw - 02.01.01.1B.03.48.46.4B.4A.16.8C.14.89.04.BD.E7.63.99.7C.26.BF.88.64.68.3C.10.11.12.13.14.15 (31)
[20:54:09][D][zhimei - vf1:379]: Decoded OK - tx: 24, gen: CONTROLLER - PAIR, enc: 0xB4 - args[170,102,85]
[20:54:09][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: zhimei
  variant: vf1
  forced_id: 0xD0CB
  index: 1
[20:54:09][D][zhimei - v1:379]: Decoded OK - tx: 24, gen: CONTROLLER - PAIR, enc: 0xB4 - args[170,102,85]
[20:54:09][D][ble_adv_handler:391]: Configuration Parameters:
  encoding: zhimei
  variant: v1
  forced_id: 0xD0CB
  index: 1

Hello @zedfs, I just pushed a new version:

  • Add new zhimei vfr1 codec supporting your remote
  • Removal of conflict with esp32_ble_tracker: the component can now be used at the same time than bluetooth_proxy and esp32_ble_tracker
4 Likes

Thanks !!! I was stuck finding a way to control my BLE led’s
I have a Led driver made by Finemei with a remote, I began to try to sniff the RF, BT, found that it was BT, but no idea for the App, Finally found the phone app named Lamp smart pro that worked with this Led driver !
and finally found your super great work ! Thanks!

Wow, you have no idea what joy you brought me by creating this repo!

I was about to make a deep dive into reverse engineering the remote myself, which would have been a first for me, and very challenging… And then I found this thread, and your repositories that are simply amazing :exploding_head: I still can’t wrap my head around the feature set, including using an ESPHome device as a BLE Advertise proxy, auto discovery of the remote and a full fledged Home Assistant config flow… I am speechless.

As a developer myself (Android) I can only guess how many days and nights of commitment this required, and I want to thank you for every second of it :love_letter: You just upgraded the living room in our new home, for free. Thank you!!

Thank you as well to aronsky, which got the ball rolling and also did a lot of very important work. People like you are what gives me hope in humanity :heart:

4 Likes

I need to check if my fan lamp is BLE compatible. The included remote is shown in the photo. I have the integration installed and esp32-ble-proxy and one fan lamp works perfectly with the remote_v3 protocol, but other four lamps use different remotes (identical as the one pictured) that don’t work with any app - only their physical remotes. Duplicating remotes doesn’t work either. Are these BLE compatible remotes and lamps? Am I doing something wrong or are these devices incompatible?

external_components:
  - source: github://NicoIIT/esphome-components@main
    components: [ble_adv_controller, ble_adv_handler]

This doesn’t wompile anymore in recent ESPHome version.
I saw on other external componens pages that a recent version (2025.7 ?)broke something, but i didn’t understand what exactly.

I get an error:

cannot import name 'setup_entity' from 'esphome.cpp_helpers'

Hello @laurentgedm,

My Fork is archived and no more maintained, please check the doc to migrate to the new solution.