#Bluetooth dev in macOs

1 messages · Page 1 of 1 (latest)

tribal siren
#

I should have done a thread long ago

#

made

peak ridge
#

I don’t think this is macOS tbh

#

The api you tried to use.. I guess it’s sort of an internal api for retry connector

tribal siren
#

BTW, I can't get it to work in mac either using the bluetooth.async_... either. Discovery works, connection doesn't.

#

Yes, it seems like that is the case, but somebody friendlily pointed me to it, and I found it used by the led_ble, so I had hopes.
I don't quite get why the docs mention it though.

Maybe work in progress

fossil meadow
#

bluetooth does work in mac at least. I run it, thou i don't use any of the retry connectors

tribal siren
#

maybe only non connectables?

peak ridge
#

What’s up?

tribal siren
peak ridge
#

That was a child flailing in my direction anyway 🤣

#

bleak-retry-connector should work for you, but i think you are using it wrong. and even if it's get_device works, it would bypass a lot of hard work HA is doing for you, so you should forget about it

#

if you have an advertisement, you already have a BLEDevice

#

e.g. if you have a service_info: BluetoothServiceInfoBleak you can just use service_info.device

#

you need to check service_info.connectable if you can't be sure that its connectable - e.g. if you asked the backend for connectable service_infos, you can skip that check (i think)

#

if you dont have an advertisement, you should use async_ble_device_from_address

#

If that returns none, then you should probably just skip the poll or whatever you are doing - that device is not available right now. it could be out of range, switched off, etc. the bluetooth stack just doesn't see it.

#

the only API i use from retry connector is:

#

from bleak_retry_connector import establish_connection

#

i take the BLEDevice i got above ^ and do something like

#
            client = await establish_connection(
                BleakClient, ble_device, ble_device.address
            )
            try:
                battery_char = client.services.get_characteristic(
                    CHARACTERISTIC_BATTERY
                )
                payload = await client.read_gatt_char(battery_char)
            finally:
                await client.disconnect()
#

you should not fall back to using the mac if you can't get a BLEDevice

#

if any of that fails, i try again on the next poll

#

if you do it like this, it should all work the same on macOS, Linux and with esphome proxies

tribal siren
#

got it, thanks a lot!

#

btw, I have the ble_device when discovered, but not when started after a boot (or on the next pull). I searched the code around and found a couple of other components doing the same with the address.
Also the docs say Fetch a new BLEDevice from the bluetooth.async_ble_device_from_address API each time a connection is made
Can you confirm I understood it right, and it is ok/efficient to use the mac address in these cases?

peak ridge
#

yes - its essentially as expensive as looking up a key in a dict

#

don't store the BLEDevice because in multi-adaptor multi-proxy scenarios it breaks roaming

#

think of the BLEDevice as something that ties a MAC address to a particular dongle or esp proxy. if we have the BLEDevice, which know to talk to X mac address via Y bluetooth device

#

that is a simplification, but its a useful mental model

tribal siren
#

Got it.

peak ridge
#

I am probably going to be radio silent for a few hours - kid stuff

tribal siren
#

Code is a bit of a mess for now

#

I put a retry loop around the while communication (including connection)

#

I didn't manage to make it work on the MacBook, even through the bt proxy

tribal siren
#

Each time there is the need to send something, the whole "get connection, send question and receive answer" is inside a retry loop.

#

@peak ridge 🙂

tribal siren
#

Ok, removed my stuff and used the fn you recommended to connect. Way more reliable now