Generic Bluetooth Integration

I just created a generic BT custom integration here:

I am sure, this is the worst idea out there :slight_smile: so skip this integration at all :slight_smile:

If you know the characteristics id you need to write and respective value to send, this integration is for you :slight_smile: I am planning to add some learning mechanism here similar to broadlink IR remotes (so you can save commands, no need to keep UUID and data all around)

After adding related BT device, you can send write commands to the device.

It will create one binary sensor to track the connection status (it will connect on first request to device).

image

and example service call to turn off my Christmas Led Light (required IDEAL LED apk) - thanks @koying for doing the hard work and extracting these (Christmas tree bluetooth light - #2 by koying)

service: generic_bt.write_gatt
data:
  target_uuid: d44bc439-abfd-45a2-b575-925416129600
  data: 79d1dba40919c246a8580ae7d11b7884
target:
  entity_id: binary_sensor.e5_a4_89_64_e4_f8

to turn it on;

service: generic_bt.write_gatt
data:
  target_uuid: d44bc439-abfd-45a2-b575-925416129600
  data: 84dd5042374150897ac82f39110968a8
target:
  entity_id: binary_sensor.e5_a4_89_64_e4_f8

After the initial service call, it will stay connected to the device.

image

5 Likes

This looks great, thanks!

So the ‘data’ is just a base16 encoded string? So if I wanted to send just a single byte with ‘1’ in it, I’d write data: 01?

I think a nice addition might be a connection timeout - at least on the ESPHome site (Bluetooth Proxy — ESPHome) it mentions you can have max of 3 concurrent connections, so for things like turning a light on and off it’d be nice to have to automatically disconnect after a few seconds of inactivity.

1 Like

I agree with Gordon, but aside from that looks like a great start. I will have to go sniff out the other commands for that Bluetooth light myself (the one you posted there work, but I want more control than just on/off). If I find more I’ll post it here. Hope to see updates to this one :slight_smile:

1 Like

Thanks, i can change the integration to reconnect each time rather than being connected, makes sense.

@fuatakgun Hello, many thanks for creating this integration as this is something I have been searching for for awhile. I am looking to use this to write temperature values to an electric radiator which has bluetooth, so I can control it with home assistant :slight_smile:

I am becoming stuck on a couple of things because I am very unfamiliar with how Bluetooth works and I am not that great at coding but have been trying all day to figure this out and I think I am so close to getting this working and hopefully with a small bit of your help I can get this to finally work!

So FYI I have used an iOS app called LightBlue to interrogate the BLE device and I have managed to determine which characteristics specify the temperature of the device. I was then able to use this app to write to this characteristic to change its temperature!

At this moment I became very excited thinking I might be able to make this work using your integration! but I am struggling to decipher the correct information (UUID and Data values) for the integration you have made This is what I need help on.

Here’s what I know so far:

I have attached the screenshots from the Bluetooth sniffer app (LightBlue) you can see there are alot of what I think are called “characteristics” (in Screenshot 3) for this device and I know that if I write to the one called “0x1003” which the app tells me is UUID 1003 (in Screenshot 4) then it changes the temp on the radiator. From the screen shots you can see that the value for this characteristic is “0x0015” for 21 degrees Celsius and “0x0017” for 23. I know those values “0x0017” are Hex values and in the app I can display different formats for the characteristics and the format that displays the value in Celsius is called “2 byte Unsigned Int Little Endian”(in Screenshot 5) I am abit confused as to what to put in the “data” field in your integration and any help on this part would be appreciated.

I am unsure which UUID to use as there are multiple ones shown under this device on the LightBlue app screens, there’s one at the top of the device page starting “AFA1047A-…” , (in Screenshot 1). One further down above all the characteristics ending “…34FB” (in Screenshot 2). and one inside the characteristics page which is just “1003” (in Screenshot 4)- as you can tell I am very confused on this part as well, do you know which UUID I should be using for your integration to work :frowning:

Update: I have obtained a full log below. However I think I know what might be wrong. It says towards the end of the log BleakError: Characteristic {char_specifier} was not found
The UUID I have used is 00000000-0000-1000-8000-00805F9B34FB and I think the characteristic value I need to use is “1003” from before. How do I input the characteristic value in the the YAML service call? is there a way to do this?

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 26, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 782, in handle_execute_script
    script_result = await script_obj.async_run(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1578, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2067, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2104, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 833, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 878, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/generic_bt/binary_sensor.py", line 50, in write_gatt
    await self._device.write_gatt(target_uuid, data)
  File "/config/custom_components/generic_bt/generic_bt_api/device.py", line 54, in write_gatt
    await self._client.write_gatt_char(uuid, data_as_bytes, True)
  File "/usr/local/lib/python3.11/site-packages/bleak/__init__.py", line 769, in write_gatt_char
    raise BleakError("Characteristic {char_specifier} was not found!")
bleak.exc.BleakError: Characteristic {char_specifier} was not found!

is it possible to “subscribe” to a service and get notifications when it changes, like lets say an itag with a button?

the problem is the service will only return 0x00 before i press the button and after i press the button it will always return a 0x01 untill i power cycle it.

1 Like

That’s exactly what I was thinking too. I got it to send commands to some devices already, which is awesome, but having device polling would be 10/10

Just submitted an issue on Github, but when I install this custom integration and restart HA, I received an error message about not having Switchbot available. After installing python-switchbot, I now receive the following:

2024-05-15 17:27:47.564 ERROR (MainThread) [homeassistant.setup] Unable to prepare setup for platform 'generic_bt.binary_sensor': Platform not found (cannot import name 'Switchbot' from 'switchbot' (/srv/homeassistant/venv/lib/python3.12/site-packages/switchbot/__init__.py)).

How did everyone else set this up? As far as I can tell, the Switchbot python library requires a token, etc. Does this use an older version?

How does one even add this to HA? The readme just keeps pointing back to this post, it’s not in HACS, and I have no clue how to get it added. I would love to be able to automate my adjustable bed just for fun, and I’ve already managed to sniff the BLE info I need and confirmed it works well with gatttool in my linux console. I just can’t get the Generic Bluetooth integration added.

To answer my own question (wasn’t too familiar with HACS) when you have HACS installed already, go to integrations, hit the 3 dots in the top right, hit “Custom Repository” set type as integration, and then hit add. You can then install it as an integration in HA as normal in settings.
image
That being said, when trying to install it through HACS I kept getting this error:
image
So I figured out how to do it manually. Simply do a git clone of the repo to the /config dir and it will copy the repo to a folder in /config/custom_repositories/generic_bt folder. Then restart HA and you’ll be able to add it. Not sure why it’s not compatible with HACS, but whatever I learned something, or more likely relearned something I had only done once to install HACS a few years ago. XD

Any idea if the function to disconnect after doing a write was implemented? I have a device that seems to get “stuck.” I can send it a command it works, but after being idle for about 5 minutes I no longer see the device broadcasting anymore. It’s almost like it think it’s still connected to the HA proxy that sent the command, even though it’s not. After a long time it will come back, or if I reboot the device.

I need to use ASCII text as the data for my BLE devices which your integration doesn’t support. Is it possible to add this support? Does Python actually support this?