Controlling BLE ceiling light with HA

I can’t set the brightness or the color as low as the remote with the app.

That means this might be a limiting factor - i.e., we might not reach the values possible with a remote, since we’re using the protocol used by the app… But maybe if we adjust the values correctly, it’ll work.

If it’s 0x1A however, the CW value stays 26 the whole time, making the warm white a little to cold.

I see now the problem with my code… There’s no reason for the minimum brightness to be applied to both the cold and warm values. I will push a fix soon (and edit this post when it’s done).

Also note that you don’t have to change the minimum brightness at the cwi and wwi values manually in code - you can just use the min_brightness configuration in YAML, and it should sort it out.

thanks! i tought the same, just didn’t know how to fix it fast :wink:

Could you give an example of the Yaml Code? (with the Min_brightness added)

Done, please check the latest version of the code :slight_smile:

Fixed the minimum brightness logic, now the temperature will be correct at lowest brightness settings (though, of course, at minimum brightness, the temperature resolution is rather abysmal - it’s either warm, cold, or both - nothing in-between).

Regarding a sample YAML - here you go:

# Enable LightSmart Pro Light
light:
  - platform: lampsmart_pro_light
    name: Kitchen Light
    duration: 1000
    default_transition_length: 0s
    min_brightness: 0x7

But you don’t need that any longer - I’ve updated the default value for minimum brightness to 7, it seems to work well. 0x1a (and 0x10) were definitely too high.

1 Like

Worked like a charm.
didn’t add the brightness part,
changed the wwi - cwi part in the code, but i guess this can be changed by adding:

light:
  - platform: lampsmart_pro_light
    name: Kitchen Light
    duration: 1000
    default_transition_length: 0s
    reversed: true

Thanks for the quick updates and the awesome work!!

No problem - glad to hear it worked! And yeah, reversed: true should take care of it and allow you to use the code as-is, without changes.

@aronsky I am so happy you got something going. :+1: I have 3 lights…are we saying I can only add 1 light or I can add 3 but will control them all with the same values? I tried putting the code into a DualR3 yesterday but getting some errors while compiling. Will setup another ESP32 only for this later to test.

Not sure what’s a DualR3… I’ve only tested this on a regular ESP32. Is the DualR3 based on ESP32? Dose it have BLE?

Regarding multiple lights - yeah, if you have multiple lights - they will all appear as a single light, as far as ESPHome and Home Assistant are concerned. It should be possible to differentiate in the future, but I need help with that in terms of implementing it correctly on the ESPHome side (I think I have a pretty good idea regarding how it should work on the lights side, but it requires some testing).

  [reversed] is an invalid option for [light.lampsmart_pro_light]. Please check the indentation.
  reversed: True

Sadly no luck. → got it working after a few tries
Will keep my local version running

Multiple lights would be awesome, if I can help out with testing let me know!
Would help to know the BLE Mac address of the device it’s connected to, is it possible to add this as a sensor? (or see it in the logs)

Sadly no luck.
Will keep my local version running

Strange, it works for me… Any chance the light.py file wasn’t updated with my latest changes? It’s complaining about indentation - any chance you mixed spaces and tabs, maybe that’s the issue?

Multiple lights would be awesome, if I can help out with testing let me know!
Would help to know the BLE Mac address of the device it’s connected to, is it possible to add this as a sensor? (or see it in the logs)

Currently, the component is strictly one-way (the ESP32 controls the light, and doesn’t receive any information back), and the MAC address isn’t used for that control. The light simply listens to broadcast BLE traffic, and whatever packet matches the predefined structure (and, I think, includes an identifier that is broadcast during the 5-second pairing period) is processed and its command is executed. So as of now, knowing the MAC address of the light is irrelevant.

If you take a look at my code, specifically at the packet structure that’s being used in the send_packet method, one of the fields (called identifier) is set to a predefined value 0xcafebabe. I think that by using different values for different lights, control over separate lights is possible. But I’m not sure how to do it correctly on the ESPHome side.

I’d like to register a service per each instance of the light component (well, ideally - I’d like to register a single service, and receive the component instance as an argument to the service). But for some reason, I can’t seem to debug the LampSmartProLight::setup method properly - it’s definitely getting called (the service is registered), but I’m not sure at which point - and logging doesn’t work that early (maybe it would work over USB, I don’t know).

We’d need to generate a unique, 32-bit ID during construction of LampSmartProLight (and base it on the entity ID - another problem I faced, as I don’t seem to be able to get that info using ESPHome API). And then this ID would be used instead of 0xcafebabe, making each instance unique.

You’re welcome to give it a go and create a PR, if successful.

It is the Sonoff DualR3 and it is an ESP32 based with BLE. I am already using one as the Bluetooth Proxy.

I see. If you have any logs, I can try and help. Also, I think that using the BT proxy and the LampSmart Pro component on the same unit might not work - maybe that’s the issue?

Removed all of Bluetooth Proxy and still get error. Not sure where I went wrong? Log as below.

INFO Reading configuration /config/esphome/esp32-bluetooth-proxy-1856c8.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing esp32-bluetooth-proxy-1856c8 (board: esp32dev; framework: espidf; platform: platformio/[email protected])
--------------------------------------------------------------------------------
Removing unused dependencies...
Library Manager: Removing Improv @ 1.2.3
INFO Removing Improv @ 1.2.3
Library Manager: [email protected] has been removed!
INFO [email protected] has been removed!
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - framework-espidf @ 3.40404.0 (4.4.4) 
 - tool-cmake @ 3.16.4 
 - tool-ninja @ 1.7.1 
 - toolchain-esp32ulp @ 2.35.0-20220830 
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Reading CMake configuration...
Generating assembly for certificate bundle...
Dependency Graph
|-- noise-c @ 0.1.4
|   |-- libsodium @ 1.10018.1
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/api_connection.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/api_frame_helper.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/api_pb2.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/api_pb2_service.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/api_server.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/list_entities.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/proto.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/subscribe_state.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/api/user_services.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/binary_sensor/automation.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/binary_sensor/binary_sensor.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/binary_sensor/filter.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32/core.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32/gpio.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32/preferences.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32_ble/ble.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32_ble/ble_advertising.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/esp32_ble/ble_uuid.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.o
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/light/addressable_light.o
src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.cpp: In function 'void esphome::lampsmartpro::ble_whiten(uint8_t*, uint8_t, uint8_t, uint8_t)':
src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.cpp:73:44: error: suggest parentheses around '+' in operand of '&' [-Werror=parentheses]
     buf[i] ^= XBOXES[(seed + i + 9) & 0x1f + (salt & 0x3) * 0x20];
                                       ~~~~~^~~~~~~~~~~~~~~~~~~~~
src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.cpp: In member function 'void esphome::lampsmartpro::LampSmartProLight::send_packet(uint16_t, uint8_t, uint8_t)':
src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.cpp:163:4: warning: missing initializer for member 'esphome::lampsmartpro::adv_data_t::<unnamed struct>::crc16' [-Wmissing-field-initializers]
   }};
    ^
Compiling /data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/light/automation.o
cc1plus: some warnings being treated as errors
*** [/data/esp32-bluetooth-proxy-1856c8/.pioenvs/esp32-bluetooth-proxy-1856c8/src/esphome/components/lampsmart_pro_light/lampsmart_pro_light.o] Error 1
========================= [FAILED] Took 20.11 seconds =========================

My yaml config…

substitutions:

  devicename: esp32-bluetooth-proxy-1856c8

  friendly_name: Living BT-Proxy

esphome:

  name: $devicename

  name_add_mac_suffix: false

  friendly_name: $friendly_name

esp32:

  board: esp32dev

  framework:

    type: esp-idf

# Enable logging

logger:

  baud_rate: 0

  level: VERBOSE

# Enable Home Assistant API

api:

  encryption:

    key: !secret esphome_api_key

ota:

  password: !secret esphome_ota_password

wifi:

  ssid: !secret esphome_wifi_ssid

  password: !secret esphome_wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails

  ap:

    ssid: "$friendly_name Fallback Hotspot"

    password: !secret esphome_wifi_ap_password

#LampSmart Pro

external_components:

  # shorthand

  source: github://aronsky/esphome-components

sensor:

  - platform: uptime

    name: Uptime Sensor

  - platform: wifi_signal

    name: WiFi Signal

    update_interval: 60s

  - platform: template

    name: Free Memory

    lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024;

    unit_of_measurement: 'kB'

    state_class: measurement

binary_sensor:

  - platform: status

    name: Status

#LampSmart Pro

light:

  - platform: lampsmart_pro_light

    name: Main Hallway

    duration: 1000

    default_transition_length: 0s

I’m not in front of my computer, so can’t verify versions. Can you try and remove the framework specification from your YAML? Might help… That definitely seems like some issue with a compiler version, since it’s complaining about syntax that’s treated correctly on my side…

Indeed that was the problem.:man_facepalming: Forgot to change that as Bluetooth Proxy needs the framework type as esp-idf.

It is now working but I do notice some issues (hopefully this component will only get better)…

  1. Does not dim down to as low as when control from app.
  2. Lights flicker when controlling the color temp as I guessed it is trying to get all 3 lights to be in sync.
  3. The temp color slider in HA also jumping around a little as the 3 lights get in sync.
  4. As you mentioned now it is only one way traffic thus HA not really showing the real settings of the lights. I have the lights connected to a main switch and it is still showing it as on even though main switch is already off.

Forgot to thank @aronsky for at least getting us ability to control the lights.

Indeed that was the problem.:man_facepalming: Forgot to change that as Bluetooth Proxy needs the framework type as esp-idf.

Great!

  1. Does not dim down to as low as when control from app.

Please see the latest changes (the progress was documented in this thread). Make sure that the latest version of the component is pulled from GitHub. Theoretically, you can go even lower than the now default minimum brightness of 7 using the configuration option - but I think that just updating to use the new minimum will fix it for you.

  1. Lights flicker when controlling the color temp as I guessed it is trying to get all 3 lights to be in sync.

Do you mean that you have 3 separate lights, and their color/brightness changes are slightly out of sync? It sort of makes sense. Basically, what this component does is broadcasting the newly requested brightness/color for the requested duration (set by the duration parameter). Due to the nature of BLE, the lights won’t necessarily pick up the message at exactly the same time (that’s also the reason the duration is that long, a whole second - to verify that the message is actually received and not lost).

  1. The temp color slider in HA also jumping around a little as the 3 lights get in sync.

Not sure whether it’s an actual issue with the code, or maybe the way Home Assistant works. The temp slider is not aware neither of the multiple lights, nor of their state. All it knows is the temperature actually set by ESPHome - and that should not fluctuate since you set the default transition to 0 (otherwise, it would fade from the previous temperature to the newly requested one, stepping through multiple values in the middle). I’d have to see it in action, but FWIW, that’s what other lights (unrelated to this component) work for me, as well. Do you have other lights with temperature/color control, that work differently?

  1. As you mentioned now it is only one way traffic thus HA not really showing the real settings of the lights. I have the lights connected to a main switch and it is still showing it as on even though main switch is already off.

Yep, I can imagine it’s frustrating, but no immediate solution to this. It’s worth emphasizing that 2-way communication might not even be possible - I know it didn’t working for me with the app (admittedly, I didn’t try for long). So just to set the expectations straight - don’t keep your hopes up for this specific feature :frowning:

Forgot to thank @aronsky for at least getting us ability to control the lights.

You’re welcome! :slightly_smiling_face:

I have a few questions besides the reply I gave below…

  1. How do I unpair the lights? I was thinking of pairing 1 of them to the app and the other 2 with your solutions to compare the lights in terms of brightness and color temp.
  2. How do I set the upper and lower limit of the color temp? Currently I see the max is 5988 and min is 3003. I wanted like 6500 and 2700.

Yes…it is exactly as how you have described the 3 lights and what you explained makes sense.

It only happens with the LampSmart Pro lights. I have other Tuya lights that are also group together and the control is very smooth and both lights change color and brightness in sync. I have attached 2 videos for comparison in your Github issues section as I am not able to attached video here.

I understand and even with the current control is already better than not able to control. :smiley: I did also notice the same behavior with the app as it is showing me as “ON” even though the main switch to the light is not on.

How do I unpair the lights? I was thinking of pairing 1 of them to the app and the other 2 with your solutions to compare the lights in terms of brightness and color temp.

There’s no proper “unpair” procedure. However, if you change the code to use a different identifier (currently, the hard-coded identifier is 0xcafebabe), I believe the lights will stop responding to it. Then you can use the pairing procedure with just one of the lights, and end up with only one light controlled by the ESP32 device.

How do I set the upper and lower limit of the color temp? Currently I see the max is 5988 and min is 3003. I wanted like 6500 and 2700

That’s achieved via the cold_white_color_temperature and warm_white_color_temperature configuration options, they are discussed earlier in this thread.

It only happens with the LampSmart Pro lights. I have other Tuya lights that are also group together and the control is very smooth and both lights change color and brightness in sync. I have attached 2 videos for comparison in your Github issues section as I am not able to attached video here.

This might be an issue between Home Assistant and ESPHome. There’s nothing in the code that should add such jumping. It’s also not happening on my end. Did you use the duration time of 0 and default transition length of 0 seconds, as per the sample configuration? If not, it might be possible that the transition is throwing it off.

Let me test it out first. In the app, there is an “Unpair” button that after you press it, the lights will blink indicating it is no longer controlled by the app. Not sure if just changing the code will do anything besides no longer able to control the lights.

I believed you meant to say duration time of 1000? My settings is as below same as per sample config.

#LampSmart Pro

light:

  - platform: lampsmart_pro_light

    name: Main Hallway

    duration: 1000

    default_transition_length: 0s

I have just tested it. I off the switch to the lights and on back and I am able to pair the 3 lights in the app without having to do anything to the code. I then played around a little and then I unpaired it from the app. I then off and on back the switch and tried to use HA to control the lights but not able to. I need to off and on and then go to “Services” and pair it again in order to control from HA.

Hm, I’ll take a look at it and add the functionality, if possible. Can you open an issue on the GitHub repo?

Strange. In that case, I’m not sure what the problem might be… The temperature isn’t jumping around for me, and since it’s a one-way control over the lights, the light type shouldn’t matter, and it should behave exactly the same.