Controlling BLE ceiling light with HA

Hi,

I recently purchased Chinese Marpou ceiling lights. They work with the app “LampSmart Pro” and are controlled over BLE.
Does anyone know if they could work with HA and how to do it?

2 Likes

Searching for Home Assistant and LampSmart Pro sent me this way :smiley:

I also just bought a Brillant LED Spot Modular light. Uses LampSmart Pro app to control it via BLE. Really love the lights and would want to buy more and hoping there is a way to get it into HA.

Hopefully someone have some answers :wink:

1 Like

Hi :slight_smile: I have two of these lamps and I’m looking a way to integrate with my HA system… does anybody have some suggestion?

1 Like

Same problem.

Over BLE Led no way.

Thanks in advance!!

Has anyone figured this out? I just bought a ceiling light using LampSmart Pro and a BLE remote and I can’t figure out how to sniff the commands.

1 Like

Hi guys,
I’m the next in line who wants the lampsmart pro product to work with HA.
I found this in a reddit forum:

I just find a project which seems to work with LampSmartPro. There may be a way to migrate the logic to python/HA.

2 Likes

I managed to hook my Marpou ceiling lamp (works with LampSmart Pro app) to an ESP32 via a custom component I developed. Lampify was a good start, but I ended up reversing the app and building the component from scratch based on that. The code is quite unfinished, but here it is, nonetheless: GitHub - aronsky/esphome-components: Custom components for ESPHome

Known issues:

  • Only tested with Marpou Ceiling CCT light (definitely doesn’t support RGB lights currently, but that could be added in the future).
  • All lights are controlled at the same time (does not support controlling different lamps individually - need help with ESPHome internals to figure this one out).

How to try it:

  1. Create an ESPHome configuration that references the repo (using external_components)
  2. Add a light entity to the configuration with the lampsmart_pro_light platform
  3. Build the configuration and flash it to an ESP32 device (since BLE is used, ESP8266-based devices are a no-go)
  4. Add the new ESPHome node to your Home Assistant instance
  5. Use the newly exposed service (esphome.<esphome-node-name>_pair) to pair with your light (call the service withing 5 seconds of powering it with a switch.
  6. Enjoy controlling your Marpou light with Home Assistant!
3 Likes

Dear aronsky,

I’m delighted that someone has finally come up with an integration solution for Lampsmart Pro. I followed your steps to set up the ESP32 and called the service within 5 seconds of powering it on with a switch. However, it seems unable to pair successfully. I noticed a variable in the source code that stores an identifier for pairing purposes, and I suspect that different brands may require different identifiers. Could you provide me with some clues so that I can conduct some tests?

Thank you,

Xenos

Hi. What kind of light do you have? Does it work correctly with LampSmart Pro? In the code, there are 3 variables the values of which aren’t 100% clear to me (in the adv_data_t struct): type, var1, and var2. Here are my assumptions about the values that should go there:

  • type: I think it might differ between lights, fans, etc. I recorded the packets coming out of my phone with one lamp defined, and the value seemed to always be 0x100. Note that I never paired the app with the lamp, actually - and the app doesn’t let me choose the type of the lamp (or set it as a fan). Maybe it does that after successful pairing?
  • var1: These 32 bits seem to be pretty arbitrary. The value in code, 0xcafebabe, is obviously bogus (the phone app sent something different), but it works for me. I assume this is a randomly generated ID that the lamp accepts during the pairing period, and is used to differentiate between different lamps.
  • var2: Seems to be 0 in the packets I recorded, not sure of its purpose.

I think there are multiple protocols that LampSmart Pro supports, and it’s possible that I only implemented one of them, that might not be compatible with all the lamps… Though from reading the code of the app, I don’t see any evidence of anything like that.

Edit: not sure I’m getting notifications on this thread. Feel free to raise an issue on the GitHub repo, if I’m not replying here.

Where can I get the codebase you are mentioning?

It’s right there, 2 messages above (my first message in this thread). GitHub - aronsky/esphome-components: Custom components for ESPHome

Works good right here with a LampSmart Ceiling Light.
Connecting was really easy! To bad i can just control one light… i have four, so i’ll see if i can hook up some presence sensors to them to give them an extra job.

Sadly the colours and brightness levels are messed up with my device…
In Home assistant, the Cool temperature is Warm on my light. The Warm temperature is Cool.
If the temperature is Fully cool (so my light is yellowish) and i dimm the light, the light starts getting whiter and not just dimmer.
Also the 1% brightness in Home Assistant isn’t as dim as 1% in the LampSmart App or the remote.

Is it because of my light? and can i edit this myself?
Thanks for the good work! did not understand why it wasn’t working with any of the wifi sniffers, but turns out it’s ble based :wink:

I’ve tried to make it local (using my_components) but sadly it doesn’t get detected (can’t even install it on my esp32). // EDIT: I did get it to install, will try the lights tomorrow to see if the changes worked

Made some changes to the code

static uint8_t BRIGHTNESS_LEVELS[15] = {
  0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
  0xB0, 0xC0, 0xD0, 0xE0, 0xF0
};

and

  uint8_t cwi = 0xFF - (uint8_t)(0xE5 * cwf);
  uint8_t wwi = 0xFF - (uint8_t)(0xE5 * wwf);

but i’ve not been able to test it yet…

Sorry - I meant the mobile app codebase.

Oh… I’ve used a decompiler for the Java part, and Ghidra for the native library.

Sounds like our lights have reversed positions for warm white and vppd white output, as well as different minimum brightness. That means we’ll need to introduce some additional properties to the YAML config to support that - something like reverse-cw-ww and min-brightness-value.

Let me know how your tests go.

EDIT:
Regarding your code changes:

  • BRIGHTNESS_LEVELS is unused (I forgot to remove it), so changing it won’t do a thing.
  • I suggest that instead of negating the values of cwf and wwf, just replace the order of the arguments on line 125 like so send_packet(0x21, wwi, cwi);
  • As for minimum brightness, it’s set to 0x1a based on the code of Lampify. I tried sending 0x01 to my light, and it turned it off, so I went back to the 0x1a value. Definitely possible that it can go lower than that, and also possible that the minimum value differs between brands… So experiment (replace the 0x1a on lines 116-117)

EDIT #2: I updated the code with the required changes to support the above. Please check it out and let me know if it works. Notice that it requires the latest version of ESPHome (2023.5+) to build, otherwise it will complain about the CONF_MIN_BRIGHTNESS import in the Python file.

Thanks for the quick update!

I’ve tested the code this morning:
Colour change worked, but i’ll try you version to see if that’s better

The Brightness level change made it not dimm at all… so it did do something :wink:

I’ll test your code and get back to you!

(i’m not able to change the 0x1a on lines 116-117 as there is no 0x1a value never mind, changed the lines to something else :wink: )
And how are you able to send the specific 0x01 value?

Ok, the results of your last code change:

Color Temperatures: Correct (ish), my light can get a lot Yellower / whiter with the remote
Brightness: If the value is above 50% or so, the temperature can still change, below the 50% value, the color temperature stays the same, so i’m not able to dim to a warmer color.

Question: Is it possible to retrieve/see the state the light is in when controlling it with the app or the remote? This way i might be able to see what my maximum and minimum values are.

Color Temperatures: Correct (ish), my light can get a lot Yellower / whiter with the remote

Can you try setting the cold_white_color_temperature and warm_white_color_temperature configuration options for the light? I haven’t documented it (will do), and it defaults to the values supported by my light - but the values are configurable. See here for an example: Cold White + Warm White Light — ESPHome

Brightness: If the value is above 50% or so, the temperature can still change, below the 50% value, the color temperature stays the same, so i’m not able to dim to a warmer color.

Interesting. Not sure what the issue might be… I suggest we resolve the temperatures correctly (see above), before we tackle this issue.

Question: Is it possible to retrieve/see the state the light is in when controlling it with the app or the remote? This way i might be able to see what my maximum and minimum values are.

Not currently, and I haven’t explored the possibility. I’ll have to see whether the lamp broadcasts any packets that I can catch. You could try recording the packets from the remote - though my code is not using packets compatible with the remote, so not sure I’ll be able to understand that data. How about controlling the light with the LampSmart Pro app - does that work correctly? Do you get the same range of temperature/brightness as with the remote?

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

After setting the white values, things changed!
with the current settings:

light:
  - platform: lampsmart_pro_light
    name: Slaapkamer Lamp
    duration: 1000
    default_transition_length: 0s
    cold_white_color_temperature: 7000 K
    warm_white_color_temperature: 1800 K

and the following brightness levels:

  uint8_t cwi = 0x01 + (uint8_t)((0xff - 0x01) * cwf);
  uint8_t wwi = 0x01 + (uint8_t)((0xff - 0x01) * wwf);

The device dimms nicely yellowish like i’d like to.
However, like you stated, the values are to low.
When setting the values (in the brightness) to 0x01, Home Assistant is sending these values:

11:29:46	[D]	[lampsmartpro:119]	
LampSmartProLight::write_state called! Requested cw: 1, ww: 7
11:29:48	[D]	[light:035]	
'Slaapkamer Lamp' Setting:
11:29:48	[D]	[light:050]	
  Brightness: 22%
11:29:48	[D]	[light:050]	
  Brightness: 22%

So at 22% (warm white) the WW value is only 7, which results in 19% being just 3 and turning the light off.

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

I’ll try changing the min_brightness Value and seeing what’ll happen.

EDIT:
changing the min_brightness value to 0xa kept the light on when dimming below 20%, however, when setting the light to warm white, the cold white value should be just off (not staying at around 10). If it stays at 10, when dimming the light, the cold white stays visible and thus making the light not as yellow as it should be.