Service to write on BLE characteristics

Since Home Assistant has built in Bluetooth support, a service to write data on a BLE characteristic would be useful. Ideally this shouldn’t be needed as support for specific Bluetooth devices should be added as integrations in HA’s main trunk, but this requires a good understanding of the HA’s code (how to implement a config flow, etc) and sometimes you just need something simple like triggering an action by writing on a ESP32 exposed characteristic, for example.

Currently I made a pyscript script for personal use which implements a ble_write service, but I would love a built-in service for that.

That’s a great script. Thank you for making it. I have a smart fan for cycling indoors called Wahoo Headwind. It goes into a stupid ‘no-mode-selected’ state after powering up. I always forget to choose a mode (Heart Rate, Speed Sensor or Manual) for the fan and have to use my phone to choose it or get off the bike. I figured that it’s possible to write some values to a BLE characteristic to select its mode. Your script worked like a charm!

Leaving the details here for someone else:
Characteristic: a026e038-0a7d-4ab3-97fa-f1500f9fEb8b
Hex Values to write:
0402 - Heart Rate
0403 - Speed
0404 - Manual

I had to add a timeout to the bleak client to make it work better.

I would like to write data on a BLE characteristic for my Easywallbox EV charger. As there is no integration for this device yet, I think your script would do the trick, however I’m not able to get it to work.
In my home assistant I have set the BLE tracker and my EV charger is detected, but when I run your script, I get the following errors:

* Device with address 84:2e:14:9f:8d:ab is not present
* BLE client with address 84:2e:14:9f:8d:ab not found

Any idea where the issue could come from ?

Well,

Device with address 84:2e:14:9f:8d:ab is not present

is the result of HA’s async_address_present returning False, which is an API to determine if the device is still present. I’d try to comment the lines 29 - 32 from my script and see if async_ble_device_from_address alone can resolve the device. If I correctly understand the documentation, this should actually try to reach the device, otherwise returning None if not possible.

How do I use this script? I’m getting an error like:

ImportError: __import__ not found

You should use the script via Pyscript integration with allow_all_imports set to true (docs).

But nowadays I’d recommend using the Generic BT integration, which looks really promising.

I send this request 100% I just started sending BLE writes with ESP32s and most of my Bluetooth devices are close to my Home Assistant Pi anyway