Could you describe the steps how you came there, please? I tryed the same but I stucked already on the step “activate”. The ledvance App show “no Network found”
I think these “Ledvance Smart+” are the same as the “Osram Smart+” and “Sylvania Smart+” bulbs
My Sylvania Smart+ is recognized by my pixel phone as
[Destination BD_ADDR: Ledvance_22:c6:ac (f0:d1:b8:22:c6:ac)]
[Destination Device Name: SYLVANIA A19 T-C-MC6AC]
From my explorations using bluez gatttool:
Attempting to connect to F0:D1:B8:22:C6:AC
Connection successful
Indication handle = 0x0029 value: 01 00 ff 00
[F0:D1:B8:22:C6:AC][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000c uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x000d, end grp handle: 0x0010 uuid: 00010203-0405-0607-0809-0a0b0c0d1912
attr handle: 0x0011, end grp handle: 0x0019 uuid: 00001827-0000-1000-8000-00805f9b34fb
attr handle: 0x001a, end grp handle: 0x0022 uuid: 00007fdd-0000-1000-8000-00805f9b34fb
attr handle: 0x0023, end grp handle: 0x0026 uuid: 00010203-0405-0607-0809-0a0b0c0d7fde
attr handle: 0x0027, end grp handle: 0x002b uuid: 00001801-0000-1000-8000-00805f9b34fb
[F0:D1:B8:22:C6:AC][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002a50-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002a26-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00010203-0405-0607-0809-0a0b0c0d2b12
handle: 0x0010, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002adc-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0015, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0016, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0017, uuid: 00002adb-0000-1000-8000-00805f9b34fb
handle: 0x0018, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0019, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001a, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x001b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001c, uuid: 00002ade-0000-1000-8000-00805f9b34fb
handle: 0x001d, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x001e, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001f, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0020, uuid: 00002add-0000-1000-8000-00805f9b34fb
handle: 0x0021, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0022, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0023, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0024, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0025, uuid: 00010203-0405-0607-0809-0a0b0c0d7fdf
handle: 0x0026, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0027, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0028, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0029, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x002a, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x002b, uuid: 00002902-0000-1000-8000-00805f9b34fb
I used this sylvania app to control it:
com.ledvance.smartplus
I enabled bluetooth debugging on my phone and them imported the log into wireshark
It uses bluetooth mesh which is not simple to reverse-engineer
Looks like all commands are sent over handle 0x0020
But the commands are variable length, I can’t spot any pattern, and replaying the commands using gatttool doesn’t work
I don’t know enough about bluetooth mesh to take this much further
From the nRF connect app, nothing too interesting, I can see the firmware version, and maybe some references to things like SigMesh and Telink, which seems to be an obscure proprietary BLE mesh protocol. There’s some information about it on Google but it seems to be mostly in Japanese
http://wiki.telink-semi.cn/wiki/protocols/Telink-Mesh/
A bit more research on this bulb
It looks like it operates differently depending on whether it has the HomeBridge firmware (uses BLE) or the Google/Amazon firmware (uses Bluetooth Mesh)
From:
a) SMART+ Bluetooth lights in connection with the LEDVANCE SMART+ Bluetooth app, Amazon Alexa app or Google Assistant:
If SMART+ Bluetooth lights are operated with the LEDVANCE SMART+ Bluetooth app, the Amazon Alexa app or Google Assistant, they communicate with Bluetooth mesh. This means that any SMART+ Bluetooth product on the same network acts as a repeater and can therefore relay the signal to other SMART+ Bluetooth devices. This means that the range between the smartphone and the SMART+ light to be controlled can be significantly higher if there are other SMART+ Bluetooth products in between.
b) SMART+ Bluetooth lights in connection with Apple HomeKit:
If SMART+ Bluetooth lights are operated with the Apple Home App, they communicate with Bluetooth Low Energy. Here there is only direct communication between the smartphone and the SMART+ Bluetooth light. This means that only lights that are within direct range of the Bluetooth signal can be controlled.```
I played a bit with one of these bulbs and here’s what I found so far:
On the Telink wiki page that @SomeGuyNamedBob mentioned, I found the TelinkBleMesh example app together with its source code in the Bluetooth SDK: http://wiki.telink-semi.cn/tools_and_sdk/BLE_Mesh/SIG_Mesh/sig_mesh_sdk.zip
With this app, I could successfully pair and control these bulbs. Apparently, the bulb follows the Bluetooth Mesh standard and can be provisioned with (almost) any Bluetooth Mesh stack.
From there I tried to provision it from the Linux Bluez stack. I used the latest 5.66 version and built it with --enable-mesh
and --enable-deprecated
.
Using meshctl
, I could discover the device. Provisioning also worked when setting security 0
first. I could not control the light, however.
Using the (newer and non-deprecated) mesh-cfgclient
, I had no luck provisioning. I believe the device supports only the PB-GATT bearer that meshctl
is using for provisioning, but not PB-ADV, which seems to be the only one that mesh-cfgclient
supports.
That’s all I found out so far. I tried to somehow copy the device information from meshctl
to the mesh-cfgclient
configuration, but so far without success. Maybe someone else has more luck or a better idea.
Good news! I got the Ledvance Bluetooth bulbs integrated into Homeassistant on a Raspberry Pi with a modified version of GitHub - dominikberse/homeassistant-bluetooth-mesh: Allows to use bluetooth mesh devices directly from homeassistant.
Long story short, I had to switch back to the older BlueZ Version 5.55 from the Debian Bullseye package repository. I also had to make a few other small changes to make it work more reliably (e.g. lights did not work after restarting the Docker container). The working version with my changes is also on GitHub: GitHub - olipink/homeassistant-bluetooth-mesh: Allows to use bluetooth mesh devices directly from homeassistant
From there on, it was basically just following the steps in the setup instructions. I.e. clone repository, build and run the Docker container, docker compose exec <container_name> /bin/bash
into the docker container, and then provision the devices:
python3 gateway.py scan
- Create entry in the
config.yaml
. python3 gateway.py prov --uuid <uuid> add
python3 gateway.py prov --uuid <uuid> config
-
python3 gateway.py
or restart the container
Further notes:
- To make sure that the bulb runs the right firmware, I’d recommend to first pair it in the Ledvance Bluetooth app, then remove/reset it
- Make sure you are using a recent Linux kernel version (check with
uname -a
). I am using the 6.10 kernel from the latest Raspberry Pi OS release. I did not get it to work with Kernel 5.10. - In some cases, provisioning failed with a
bad-pdu
message. This is returned for all sorts of different errors. In some cases, it helps to add--reload
to the provision commands, e.g.python3 gateway.py --reload prov --uuid <uuid> add
- Apart from BlueZ 5.55 from the package sources, I also tested versions 5.58 and 5.62 and got it to work. For 5.62, I had to add
--reload
to the provision commands. - If you are having trouble and want to rule out hardware or configuration issues, you might want to try provisioning with
meshctl
and/ormesh-cfgclient
first. In case of the latter, you will have to build it from source. The version from the package repository will get you stuck with a “Failed to generate UUID array” error when trying to provision: BlueZ seems to be very picky about the device UUIDs, and the UUIDs of the Ledvance SMART+ bulbs are apparently not considered valid. Remove all occurrences of|| !l_uuid_is_valid(uuid)
frommesh-cfgclient.c
and it will work.
you are a genius!!! I can confirm that your steps worked for me with the Sylvania Smart+ bulbs. Going to let it run for a few days to see how stable it is.
Only thing that’s not working is the color picker only allows to select the color temperature (cool to warm), not the full RGB spectrum
Hi @Homeowner
thank you for this solution. I bought two color light strips for my kids and would like to get them to work with home assistant and thus home kit too.
However, can you elaborate a little more on what to do? What uuid and password do I have to put in the docker config? How do I actually do this?
And one further question aside from installation how-to: Is the RGB going to work? I read that you are not intending to support this but it would be great if this is the key use case I am looking for (“hey Siri, turn my lights red”)
Thanks
Philip
You’ll get a list of UUIDs after running “python3 gateway.py scan
”
The lack of reliable RGB was also a dealbreaker for me. For now, I picked up a 3rd gen Amazon Echo for around $15 on marketplace, it has flawless support for these Ledvance/Sylvania Bluetooth Smart+ bulbs, including RGB, and it integrates with HomeAssistant:
- You’ll need an amazon account with 2FA (either use an existing one or create a new dummy one)
- Pair the bulbs to Echo (make sure the Echo is updated to the latest firmware otherwise the pairing process will keep failing)
- in HomeAssistant install HACS
- in HACS install “Alexa Media Player” and in the config ensure “Include devices connected via Echo” is checked
Could this also be done on HaOS and would this also work with (esphome) bluetooth proxy’s at all (without bluetooth on the HA server)?
I have a load of these lights at home and they are terrible the app can only control one at a time. Maybe this is what I am looking for however I need some help with this please.
The config yaml is confusing because how do you create the data for the config file. I presume it comes from running python3 gateway.py scan but the guide runs that after the build.
If I try to run it I get this error…
opt/hass-ble-mesh/gateway# python3 gateway.py scan
DEBUG:asyncio:Using selector: EpollSelector
Traceback (most recent call last):
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 53, in _load
return StoredNodeSchema().loads(r)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 756, in loads
return self.load(data, many=many, partial=partial, unknown=unknown)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 722, in load
return self._do_load(
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 909, in _do_load
raise exc
marshmallow.exceptions.ValidationError: {‘token’: [‘Field may not be null.’]}
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 271, in
main()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 267, in main
loop.run_until_complete(app.run(args))
File “/usr/local/lib/python3.10/asyncio/base_events.py”, line 649, in run_until_complete
return future.result()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 198, in run
self.token_ring.token = self._store.get(“token”)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/application.py”, line 187, in token_ring
return self.TOKEN_RING(uuid=self.uuid)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 44, in init
self.data = self._load()
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 55, in _load
return dict(token=int(r, 16), acl={}, network={})
ValueError: invalid literal for int() with base 16: ‘{“network”: {}, “acl”: {}, “token”: null}’
root@nas:/opt/hass-ble-mesh/gateway# python3 gateway.py --reload
DEBUG:asyncio:Using selector: EpollSelector
Traceback (most recent call last):
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 53, in _load
return StoredNodeSchema().loads(r)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 756, in loads
return self.load(data, many=many, partial=partial, unknown=unknown)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 722, in load
return self._do_load(
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 909, in _do_load
raise exc
marshmallow.exceptions.ValidationError: {‘token’: [‘Field may not be null.’]}
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 271, in
main()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 267, in main
loop.run_until_complete(app.run(args))
File “/usr/local/lib/python3.10/asyncio/base_events.py”, line 649, in run_until_complete
return future.result()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 198, in run
self.token_ring.token = self._store.get(“token”)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/application.py”, line 187, in token_ring
return self.TOKEN_RING(uuid=self.uuid)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 44, in init
self.data = self._load()
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 55, in _load
return dict(token=int(r, 16), acl={}, network={})
ValueError: invalid literal for int() with base 16: ‘{“network”: {}, “acl”: {}, “token”: null}’
root@nas:/opt/hass-ble-mesh/gateway# python3 gateway.py scan
DEBUG:asyncio:Using selector: EpollSelector
Traceback (most recent call last):
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 53, in _load
return StoredNodeSchema().loads(r)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 756, in loads
return self.load(data, many=many, partial=partial, unknown=unknown)
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 722, in load
return self._do_load(
File “/usr/local/lib/python3.10/site-packages/marshmallow/schema.py”, line 909, in _do_load
raise exc
marshmallow.exceptions.ValidationError: {‘token’: [‘Field may not be null.’]}
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 271, in
main()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 267, in main
loop.run_until_complete(app.run(args))
File “/usr/local/lib/python3.10/asyncio/base_events.py”, line 649, in run_until_complete
return future.result()
File “/opt/hass-ble-mesh/gateway/gateway.py”, line 198, in run
self.token_ring.token = self._store.get(“token”)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/application.py”, line 187, in token_ring
return self.TOKEN_RING(uuid=self.uuid)
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 44, in init
self.data = self._load()
File “/usr/local/lib/python3.10/site-packages/bluetooth_mesh/tokenring.py”, line 55, in _load
return dict(token=int(r, 16), acl={}, network={})
ValueError: invalid literal for int() with base 16: ‘{“network”: {}, “acl”: {}, “token”: null}’
I set this up from scratch on a Raspi 4 with 64bit Bookworm (Homeassistant, Docker, Mosquitto already installed). Here’s a summary of the steps:
sudo systemctl stop bluetooth
sudo systemctl disable bluetooth
sudo systemctl mask bluetooth
cd ~
git clone https://github.com/olipink/homeassistant-bluetooth-mesh
cd homeassistant-bluetooth-mesh
→ create/modify docker/config.yaml
with following content:
mqtt:
broker: 192.168.1.123 # replace with your address
# username: <username>
# password: <password>
node_id: mqtt_mesh
Then
docker compose build
docker compose up -d
docker compose exec app /bin/bash
python3 gateway.py scan
Now you should get something like
INFO:root:Scanning for unprovisioned devices...
Found 1 node:
...
Now add one entry for each device to the config.yaml
, e.g.:
mesh:
living_room_light:
uuid: <bluetooth_mesh_device_uuid>
name: "Living Room Light"
type: light
relay: false # or true, if you prefer
@domrnet curiously, I got the same error message as you did at my first try. But after a reboot, it was gone and I could not reproduce it since. My guess is it had something to do with the bluetooth device still being locked.
@PhilSnider No, RGB is not supported, and since I do not own any Ledvance RGB device, I am not able to add support either. I also do not plan to put more effort into these lights: Link quality has been an issue for me all the time, and a couple days ago, the first out of 4 lights went out. So I give them a few more months until all of them have to be replaced.
Since I also own some of these bluetooth bulbs and the solution from Homeowner has not worked for me, I digged into the ESP BLE MESH framework and finally managed to get a working version running on my ESP32.
The ESP32 is acting.as a BLE MESH client and communicates to Home Assistant via MQTT.
It is by no means perfect but so far it works fine enough for me.
If anybody is interested, I put my code with some instructions on GitHub.
That’s phenomenal! Any chance you’ve tested whether it keeps working across power loss/reboots?
Any possibility of adding the function to change color?
Awesome
Thank’s for sharing your work
Did you also try to get this working with(in) esphome or are there technical difficulties not allowing this (easily)?
It looks like esphome does not really have an implementation for BLE Mesh yet
https://github.com/esphome/feature-requests/issues/1671
If you mean restart of the ESP, that works fine. The state is stored in the flash of the ESP so it reconnects to the BLE Mesh network after a restart.
What is still not perfect is that if HA restarts, you have to manually send again the config mqtt message so that the entities appear in HA. I did not have time to code that part but it should be relatively easy as HA sends a message when the mqtt service is started
Hey. Could you explain how you did that?
I accidentally upgraded the firmware on my ledvance G50 globe, and after that it is no longer recognizable by apple homekit. Apparently it has upgraded from BLE to Sig Mesh. Now, I desperately wanna go back to the previous firmware. Looks like you have done this before and would appreciate it if you teach me how.
Did anyone get the colors working? Nordic devzone says the nrfmesh app doesn’t support all mesh models like HSL.
Wondering what the best approach is - the Sylvania app is OK but I don’t know if I can export keys and have it working in multiple devices + homeassistant.
I can export the nrfmesh setup and import it into another device but the new device doesn’t work until I plug/unplug the lamp. I don’t know if BLE mesh can work with multiple phones/servers controlling the same lamp or group.
Docker/Bluetooth mesh would be good but my server may be too far to work reliably.
@Ultraworg any idea if your code would be easy to port/add to esphome/Tasmota/OMG?
Hi guys,
I have two of the W27 filament bluetoth bulbs(https://www.ledvance.com/consumer/products/smart-home/smart-lamps/smart-bluetooth/smart-classic-filament-lamps-with-bluetooth-technology/classic-bulb-shape-with-filament-style-with-bluetooth-technology-c6328), but i guess the boxes went to trash, I didn’t realise i would need the qr code to add them to homekit. Does anyone have the qr code they can share to add them to homekit?
Thanks