BLE Sig Mesh Gateway

Hello,

I have a BLE Sig Mesh Light that I can control via Smart Life with my Phone.
I’m looking for a DIY BLE Gateway for this kind of device. I would prefer via a PI 4 or an ESP32 if possible.

I saw this kind of device but I would like a Gateway 2 MQTT or via ESPHOME.
It seems all current BLE GW are for sensors/beacons, not for lights.

Thanks for the help.

You might explore the localtuya integration to see if it is possible to control your Moes device. I have looked around github and not found much current work on any BLE mesh projects. I think folks are waiting for the whole Matter thing to solidify. Espressif ESP32-H2 is a new chip that is coming soon that may spur development with both BLE and Zigbee (dot or whatever it is named now) mesh to wifi. BLE mesh is more complex to implement that the current projects that simply listen for BLE advertising packets, this is what most of the BLE integrations do currently.

Good hunting!

1 Like

I know for a fact the ESP32-C3 and S3 support BLE-MESH and for the pi4 it’s just a matter of software.
Speaking of, this is all I could really find, BLE-MESH and Mesh2MQTT so it looks like just the one guy is working on this, at least until Thread Matter is sorted out.

I have just been looking GitHub - lucamoroz/Bluetooth-Mesh-Sensor-Network: Bluetooth Mesh sensor network the rest apart from previously posted seems to be firmware based.

I just ordered x2 https://www.moeshouse.com/en-gb/products/bluetooth-smart-switch-relay-module-single-point-control-and-pairing-without-wifi-network-bluetooth-sigmesh-functional-wireless-remote-control-with-bluetooth-gateway as both Moes and bluetooth mesh sig is new to me and was curious hwo compatible it is as a bluetooth mesh rather than a lesser common radio such as Zigbee seems it could be a great product platform.

I haven’t a clue to tell you the truth :slight_smile:

I just wanted to share, that it is in fact possible to control Bluetooth Mesh lights via MQTT and Home Assistant. I use a python library on top of the Bluez bluetooth-mesh service to retrieve device information, turn devices on/off, set the brightness and light color.

My current state is available here GitHub - dominikberse/homeassistant-bluetooth-mesh: Allows to use bluetooth mesh devices directly from homeassistant, but it is still very much under development and might be a little tricky to configure and set up.

5 Likes

can you help to configure meshctl ? I have installed the binary and the python requirements, but don’t know what to do with meshctl.
thx

I think meshctl is ok now, I try to run the gateway, but I …/store.yaml is missing, is there any data to put in that file ?

root@pizero2w:~/homeassistant-bluetooth-mesh/gateway# python3 gateway.py scan

Traceback (most recent call last):
  File "/root/homeassistant-bluetooth-mesh/gateway/gateway.py", line 259, in <module>
    main()
  File "/root/homeassistant-bluetooth-mesh/gateway/gateway.py", line 240, in main
    app = MqttGateway(loop)
  File "/root/homeassistant-bluetooth-mesh/gateway/gateway.py", line 69, in __init__
    self._store = Store(location='../store.yaml')
  File "/root/homeassistant-bluetooth-mesh/gateway/tools/store.py", line 23, in __init__
    raise Exception('Store data not available')
Exception: Store data not available

Ah right, I think you can simply create that file with the following content

local:
  address: 1

The rest of the file should be created automatically, it just does not handle the case where the file does not exist or is empty properly by now. Testing the initial setup process is a little annoying, that’s why I have not had time to do that yet. The file stores information about the provisioned devices.

I also noticed that it crashed on the very first startup (after I created that file). I just had to re-run the application.

By the way, please double check that you know how to reset a provisioned device. If something goes wrong, you might end up with a provisioned device that cannot be accessed over a network. For my light bulbs, this is simply turning them on and off with 3 seconds delay for 5 times (costed me a lot of 30 seconds so far :smiley:).

Sorry for the headache, this is my bleeding edge development state :smiley: I just wanted to share it, so that people can play around with it and maybe even improve it.

I make some progress, but still need some help :

The script does nothing, just stale on Connecting to org.bluez.mesh

pi@pizero2w:~/homeassistant-bluetooth-mesh/gateway $ sudo python3 gateway.py scan

DEBUG:asyncio:Using selector: EpollSelector
DEBUG:MqttGateway:Connecting to D-Bus
INFO:MqttGateway:Connecting to org.bluez.mesh

Trying with meshclt
I found my device, by I’m block at this step :

Request hexadecimal key (hex 16 octets)
[[mesh-agent]# ] Enter key (hex number): 0000
Incorrect input: expecting 16 hex octets
		OOB: 0000

any idea ?

I’m not quite sure on how to work with meshctl directly. The script uses the bluetooth-mesh service, which should come with Bluez with meshctl and the message indicates that it is not running. Depending on your setup you can either run it from command line or using systemctl. I would recommend command line with debug info first:

sudo ./bluetooth-meshd --nodetach --debug --dbus-debug

If you build Bluez yourself it should be inside the build folder under ./mesh/, otherwise it might be under /usr/lib/bluetooth/.

As the service wants exclusive access to the hci device, you might run into a message that indicates that the hci device is not available. In that case you will need to release the device using:

sudo hciconfig hci0 down

From what I understand, as long as the default bluetooth service is running, it will try to regain access to the bluetooth controller after a while. However I read in some places, that stopping the bluetooth service gracefully might power down the bluetooth controller making it inaccessible. Maybe it’s best to disable both the bluetooth and the bluetooth-mesh service while setting everything up and once the setup works, enable the bluetooth-mesh service.

It seems it quite better now.

Scan is working, I found my uuid.
But I can’t prov it :

INFO:root:Provisioning node a8017*****...


INFO:root:Provisioning 1 new address(es)

ERROR:root:Failed to provision a8017*****:
bad-pdu

Mesh contains 0 node(s):
INFO:MqttGateway:Unregistering application
pi@pizero2w:~/homeassistant-bluetooth-mesh/gateway $ cat ../config.yaml
mqtt:
  broker: 192.168.1.10
  node_id: mqtt_mesh
mesh:
  a8017*****:
    uuid: a8017*****
    name: name
    type: light             # thats it for now
    relay: false

What is this error BAD PDU

@dberse I have finally understood why I have this issue.
There is no OOB on my device.
Is it possible to allow provisioning without OOB in your module ?

Hey, sorry for the late reply. I am not sure about OOB, but my light bulbs do not have OOB as well, as far as I know. For me this BAD PDU error occured when the device did not respond in time or the response was not handled properly. But I will not have time to do further development until november.

Maybe if you could set the application log level to debug (has to be done in the python file manually) and also start the bluetooth-meshd with --nodetach --debug and post the logs here, I could have a look. Not sure I can help though, setting up this bluetooth mesh stuff until it finally responded properly was troublesome for me as well.

I am getting the same bad-pdu results when trying to provision. I attempted to look at the underlying project and found an old bug MessageReceived doesn't reach Python code · Issue #62 · SilvairGit/python-bluetooth-mesh · GitHub I was able to run the code in the last post the bug but getting dbus output that is different so may not be related:

Script output:

INFO     Request prov data called with count 1
ERROR    got unexpected error processing a message: Expected signal to return a list of a
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/dbus_next/message_bus.py", line 621, in _o
    self._process_message(msg)
  File "/usr/local/lib/python3.9/dist-packages/dbus_next/message_bus.py", line 712, in _p
    handler(msg, send_reply)
  File "/usr/local/lib/python3.9/dist-packages/dbus_next/message_bus.py", line 732, in ha
    body, fds = ServiceInterface._fn_result_to_body(
  File "/usr/local/lib/python3.9/dist-packages/dbus_next/service.py", line 453, in _fn_re
    raise SignatureBodyMismatchError(
dbus_next.errors.SignatureBodyMismatchError: Expected signal to return a list of argument

DBUS output:

error time=1665781402.660207 sender=:1.462 -> destination=:1.69 error_name=com.dubstepdish.dbus.next.ServiceError reply_serial=541
   string "The service interface raised an error: Expected signal to return a list of arguments.
['  File "/usr/local/lib/python3.9/dist-packages/dbus_next/message_bus.py", line 712, in _process_message\n    handler(msg, send_reply)\n', '  File "/usr/local/lib/python3.9/dist-packages/dbus_next/message_bus.py", line 732, in handler\n    body, fds = ServiceInterface._fn_result_to_body(\n', '  File "/usr/local/lib/python3.9/dist-packages/dbus_next/service.py", line 453, in _fn_result_to_body\n    raise SignatureBodyMismatchError(\n']"

So the output you posted is from the code that from that issue? If I remember correctly, that is because in that code snippet the request_prov_data(self, count: int) function should return a list, not a tuple (return [0, count + 1] instead of return (0, count + 1)).

Could you run the bluetooth-meshd service with the debug flag like I posted above? Then I can see whether the device actually responds. For my lightbulbs I had to increase the timeout during provisioning, which in turn required forking the underlying ble-mesh library, but maybe the timeout is still not sufficient.

But this bad-pdu stuff is really annoying, it took me a while to get around it myself. Maybe I missed something.

It would be interesting to see this implemented as a HACS integration or an AddOn

Where did you change that in the code ? @dberse
Edit: i Have increase timeout in your python bluetooth mesh fork, but same issue.

I think I need to increase it too

mesh/prov-initiator.c:initiator_prov_data() Failing... 7
mesh/pb-adv.c:send_adv_segs() Sending 1 fragments for 2 octets
mesh/pb-adv.c:send_adv_segs() max_seg: 00
mesh/pb-adv.c:send_adv_segs() size: 02, CRC: e6
mesh/net-keys.c:snb_timeout() beacon 1 for 1 nodes, period 20, obs 2, exp 2

mesh/pb-adv.c:tx_timeout() TX timeout
[DBUS] > 6c 01 01 01 20 00 00 00 15 00 00 00 71 00 00 00  l... .......q...
[DBUS]   01 01 6f 00 0e 00 00 00 2f 6f 72 67 2f 68 61 73  ..o...../org/has
[DBUS]   73 2f 6d 65 73 68 00 00 03 01 73 00 0d 00 00 00  s/mesh....s.....
[DBUS]   41 64 64 4e 6f 64 65 46 61 69 6c 65 64 00 00 00  AddNodeFailed...
[DBUS]   02 01 73 00 1b 00 00 00 6f 72 67 2e 62 6c 75 65  ..s.....org.blue
[DBUS]   7a 2e 6d 65 73 68 2e 50 72 6f 76 69 73 69 6f 6e  z.mesh.Provision
[DBUS]   65 72 31 00 00 00 00 00 06 01 73 00 05 00 00 00  er1.......s.....
[DBUS]   3a 31 2e 33 30 00 00 00 08 01 67 00 03 61 79 73  :1.30.....g..ays
[DBUS]   00 00 00 00 00 00 00 00                          ........
[DBUS]   10 00 00 00 a8 01 71 ad 10 00 00 63 0a 44 63 a7  ......q....c.Dc.
[DBUS]   f8 02 00 00 07 00 00 00 62 61 64 2d 70 64 75 00  ........bad-pdu.
[DBUS] < 6c 04 01 01 1d 00 00 00 06 00 00 00 89 00 00 00  l...............
[DBUS]   01 01 6f 00 15 00 00 00 2f 6f 72 67 2f 66 72 65  ..o...../org/fre
[DBUS]   65 64 65 73 6b 74 6f 70 2f 44 42 75 73 00 00 00  edesktop/DBus...
[DBUS]   02 01 73 00 14 00 00 00 6f 72 67 2e 66 72 65 65  ..s.....org.free
[DBUS]   64 65 73 6b 74 6f 70 2e 44 42 75 73 00 00 00 00  desktop.DBus....
[DBUS]   03 01 73 00 10 00 00 00 4e 61 6d 65 4f 77 6e 65  ..s.....NameOwne
[DBUS]   72 43 68 61 6e 67 65 64 00 00 00 00 00 00 00 00  rChanged........
[DBUS]   07 01 73 00 14 00 00 00 6f 72 67 2e 66 72 65 65  ..s.....org.free
[DBUS]   64 65 73 6b 74 6f 70 2e 44 42 75 73 00 00 00 00  desktop.DBus....
[DBUS]   08 01 67 00 03 73 73 73 00 00 00 00 00 00 00 00  ..g..sss........
[DBUS]   05 00 00 00 3a 31 2e 33 30 00 00 00 05 00 00 00  ....:1.30.......
[DBUS]   3a 31 2e 33 30 00 00 00 00 00 00 00 00           :1.30........
App :1.30 disconnected (1)
[DBUS] > 6c 04 01 01 a0 00 00 00 16 00 00 00 69 00 00 00  l...........i...
[DBUS]   01 01 6f 00 01 00 00 00 2f 00 00 00 00 00 00 00  ..o...../.......
[DBUS]   03 01 73 00 11 00 00 00 49 6e 74 65 72 66 61 63  ..s.....Interfac
[DBUS]   65 73 52 65 6d 6f 76 65 64 00 00 00 00 00 00 00  esRemoved.......
[DBUS]   02 01 73 00 22 00 00 00 6f 72 67 2e 66 72 65 65  ..s."...org.free
[DBUS]   64 65 73 6b 74 6f 70 2e 44 42 75 73 2e 4f 62 6a  desktop.DBus.Obj
[DBUS]   65 63 74 4d 61 6e 61 67 65 72 00 00 00 00 00 00  ectManager......
[DBUS]   08 01 67 00 03 6f 61 73 00 00 00 00 00 00 00 00  ..g..oas........
[DBUS]   34 00 00 00 2f 6f 72 67 2f 62 6c 75 65 7a 2f 6d  4.../org/bluez/m
[DBUS]   65 73 68 2f 6e 6f 64 65 64 33 61 61 64 31 39 30  esh/noded3aad190
[DBUS]   62 34 34 38 35 36 30 33 38 34 62 61 64 39 66 37  b448560384bad9f7
[DBUS]   66 34 32 32 66 63 64 66 00 00 00 00 60 00 00 00  f422fcdf....`...
[DBUS]   14 00 00 00 6f 72 67 2e 62 6c 75 65 7a 2e 6d 65  ....org.bluez.me
[DBUS]   73 68 2e 4e 6f 64 65 31 00 00 00 00 1a 00 00 00  sh.Node1........
[DBUS]   6f 72 67 2e 62 6c 75 65 7a 2e 6d 65 73 68 2e 4d  org.bluez.mesh.M
[DBUS]   61 6e 61 67 65 6d 65 6e 74 31 00 00 1f 00 00 00  anagement1......
[DBUS]   6f 72 67 2e 66 72 65 65 64 65 73 6b 74 6f 70 2e  org.freedesktop.
[DBUS]   44 42 75 73 2e 50 72 6f 70 65 72 74 69 65 73 00  DBus.Properties.
pi@raspberrypi:~/homeassistant-bluetooth-mesh/gateway $ python3 gateway.py prov add --uuid a80171ad-1000-0063-0a44-63a7f8020000
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:MqttGateway:Connecting to D-Bus
INFO:MqttGateway:Connecting to org.bluez.mesh
INFO:MqttGateway:Registering application
INFO:MqttGateway:Attach 923068faecc0540 (socket_pair=False, socket_path=None)
INFO:MqttGateway.Element0.GenericOnOffClient:Update config of (None, 4097): <ModelConfig bindings=[0], subs=[]>
INFO:MqttGateway.Element0.LightLightnessClient:Update config of (None, 4866): <ModelConfig bindings=[0], subs=[]>
INFO:MqttGateway.Element0.LightCTLClient:Update config of (None, 4869): <ModelConfig bindings=[0], subs=[]>
INFO:MqttGateway:Attached to node /org/bluez/mesh/noded3aad190b448560384bad9f7f422fcdf, address: 0001, configuration: defaultdict(<class 'dict'>, {0: {(None, 4097): {'bindings': [0]}, (None, 4866): {'bindings': [0]}, (None, 4869): {'bindings': [0]}}})
DEBUG:MqttGateway.Element0.ConfigClient:Building message with parameters: {'net_key_index': 0, 'app_key_index': 0, 'app_key': b'b}k\xccN\xb36\xa8\xf7\x14\x1d\x1frN\xd4i'}
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_APPKEY_ADD: 0>, config_appkey_add=Container(app_key_index=0, net_key_index=0, app_key=b'b}k\xccN\xb36\xa8\xf7\x14\x1d\x1frN\xd4i'))
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] 00000000627d6bcc4eb336a8f7141d1f724ed469
DEBUG:MqttGateway.Element0.ConfigClient:Dev message received: 0001 [remote False, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_APPKEY_STATUS: 32771>, config_appkey_status=Container(status=<StatusCode.SUCCESS: 0>, app_key_index=0, net_key_index=0))
DEBUG:MqttGateway.Element0.ConfigClient:Building message with parameters: {'element_address': 1, 'app_key_index': 0, 'model': {'model_id': 4097}}
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_BIND: 32829>, config_model_app_bind=Container(element_address=1, app_key_index=0, model=Container(model_id=4097)))
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] 803d010000000110
DEBUG:MqttGateway.Element0.ConfigClient:Dev message received: 0001 [remote False, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_STATUS: 32830>, config_model_app_status=Container(status=<StatusCode.SUCCESS: 0>, element_address=1, app_key_index=0, model=Container(model_id=4097)))
DEBUG:MqttGateway.Element0.ConfigClient:Building message with parameters: {'element_address': 1, 'app_key_index': 0, 'model': {'model_id': 4866}}
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_BIND: 32829>, config_model_app_bind=Container(element_address=1, app_key_index=0, model=Container(model_id=4866)))
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] 803d010000000213
DEBUG:MqttGateway.Element0.ConfigClient:Dev message received: 0001 [remote False, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_STATUS: 32830>, config_model_app_status=Container(status=<StatusCode.SUCCESS: 0>, element_address=1, app_key_index=0, model=Container(model_id=4866)))
DEBUG:MqttGateway.Element0.ConfigClient:Building message with parameters: {'element_address': 1, 'app_key_index': 0, 'model': {'model_id': 4869}}
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_BIND: 32829>, config_model_app_bind=Container(element_address=1, app_key_index=0, model=Container(model_id=4869)))
DEBUG:MqttGateway.Element0.ConfigClient:Sending: /org/hass/mesh/element0 -> 0001 [remote True, net_index 0] 803d010000000513
DEBUG:MqttGateway.Element0.ConfigClient:Dev message received: 0001 [remote False, net_index 0] Container(opcode=<ConfigOpcode.CONFIG_MODEL_APP_STATUS: 32830>, config_model_app_status=Container(status=<StatusCode.SUCCESS: 0>, element_address=1, app_key_index=0, model=Container(model_id=4869)))
INFO:root:Provisioning node a80171ad-1000-0063-0a44-63a7f8020000...
INFO:root:Provisioning 1 new address(es)
WARNING:root: plop [0, 16]
INFO:root:Provisioning 1 new address(es)

ERROR:root:Failed to provision a80171ad-1000-0063-0a44-63a7f8020000:
bad-pdu

Mesh contains 0 node(s):
INFO:MqttGateway:Unregistering application

BLE Mesh Gateway diy

@dberse this is great, exactly what I was meaning to do but then better! :grinning_face_with_smiling_eyes:

I’m now controlling my front door light made by Tuya, on/off works but RGB, dimming and tone need work. Next is my christmas tree.

Some tips: make sure to turn off all bluetooth integrations in hassio and also to stop the bluetooth daemon.

Hi, does this also work with esphome bt proxy?