jlusiardi / homekit_python

A python implementation to work as both HomeKit controller and accessory.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing Documentation for BlePairing

kvaellning opened this issue · comments

commented

I hope that this is the right title...

So currently, I am trying to wrap my head around the BlePairing.get_characteristics function, which expects the aid and iid passed as tuple. Whereas aid makes sense to me, I have no idea on how to get the iid, which is device specific (the models also use unique but arbitrary values). What would makes more sense for me would be a get_characteristics with (aid, char_uuid), which can be extracted from e.g. Characteristic types.

So, is there any helper function which does that for me, or is there just some documentation missing?

commented

Again this is probably driven by IP which takes the aid/iid in the JSON you pass to the device.

For BLE, aid is always 1. The iid should be on a descriptor of the characteristic, the descriptor UUID is DC46F0FE-81D2-4616-B5D9-6ABDD796939A. Every characteristic should have a descriptor with that UUID.

The reason for the characteristic cache in https://github.com/jlusiardi/homekit_python/pull/224/files is so that we have the iid's that are available to us, so that we can map from char iid to char uuid and back, without needing to hit the device itself.

It's kind of an annoying interface provided by the device too. You have to have the correct characteristic UUID, but you also have to know its IID to put in the PDU, otherwise your PDU is rejected. You can't write to a characteristic UUID if you don't know the IID. There is even a dedicated PDU error code for getting the IID wrong.

find_characteristic_by_uuid will get you a GATT characteristic object AND the iid for the characteristic. But it does lots of I/O against the device and is slow.

BleSession has an iid_map and a short_map. short_map takes the short form of UUID of a ServicesTypes and a CharacteristicsType so you can do: session.short_map[(ServicesTypes.ACCESSORY_INFORMATION, CharacteristicsTypes.NAME)] and get the iid. iid_maptakes aniid` and gives you the characteristic and some metadata about it.

You can't do (aid, char_uuid) because a characteristic can repeat within an accessory. E.g. for a water valve i've seen there were 4 valve services (so same Service UUID) and each valve has a name. So that device has like 5 CharacteristicTypes.NAME characteristics.

commented

I used now a combination of CharacteristicTypes and ServiceTypes, which done the deal. This way, I get the specified UUID without the need of having find_characteristics_by_uuid involved. Works good enough to fish inside the list of characteristics as returned by list_accessories_and_characteristics to figure out which IIDs are used in the device.