add pairing methods (#390)

This commit is contained in:
Fredrik Gustafsson 2023-03-06 19:07:58 +01:00 committed by GitHub
parent 0327f75414
commit 2041d747cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 172 additions and 45 deletions

View File

@ -1365,3 +1365,23 @@ message BluetoothGATTNotifyResponse {
uint64 address = 1;
uint32 handle = 2;
}
message BluetoothDevicePairingResponse {
option (id) = 85;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
bool paired = 2;
int32 error = 3;
}
message BluetoothDeviceUnpairingResponse {
option (id) = 86;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_BLUETOOTH_PROXY";
uint64 address = 1;
bool success = 2;
int32 error = 3;
}

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,9 @@ from .api_pb2 import ( # type: ignore
BinarySensorStateResponse,
BluetoothConnectionsFreeResponse,
BluetoothDeviceConnectionResponse,
BluetoothDevicePairingResponse,
BluetoothDeviceRequest,
BluetoothDeviceUnpairingResponse,
BluetoothGATTErrorResponse,
BluetoothGATTGetServicesDoneResponse,
BluetoothGATTGetServicesRequest,
@ -109,7 +111,9 @@ from .model import (
BinarySensorState,
BluetoothConnectionsFree,
BluetoothDeviceConnection,
BluetoothDevicePairing,
BluetoothDeviceRequestType,
BluetoothDeviceUnpairing,
BluetoothGATTError,
BluetoothGATTRead,
BluetoothGATTServices,
@ -585,6 +589,67 @@ class APIClient:
return unsub
async def bluetooth_device_pair(
self, address: int, timeout: float = DEFAULT_BLE_TIMEOUT
) -> BluetoothDevicePairing:
self._check_authenticated()
msg_types = (
BluetoothDevicePairingResponse,
BluetoothDeviceConnectionResponse,
)
assert self._connection is not None
def predicate_func(msg: message.Message) -> bool:
assert isinstance(msg, msg_types)
if msg.address != address:
return False
if isinstance(msg, BluetoothDeviceConnectionResponse):
raise APIConnectionError(
"Peripheral changed connections status while pairing"
)
return True
responses = await self._connection.send_message_await_response_complex(
BluetoothDeviceRequest(
address=address, request_type=BluetoothDeviceRequestType.PAIR
),
predicate_func,
predicate_func,
msg_types,
timeout=timeout,
)
assert len(responses) == 1
response = responses[0]
return BluetoothDevicePairing.from_pb(response)
async def bluetooth_device_unpair(
self, address: int, timeout: float = DEFAULT_BLE_TIMEOUT
) -> BluetoothDeviceUnpairing:
self._check_authenticated()
assert self._connection is not None
def predicate_func(msg: BluetoothDeviceUnpairingResponse) -> bool:
return bool(msg.address == address)
responses = await self._connection.send_message_await_response_complex(
BluetoothDeviceRequest(
address=address, request_type=BluetoothDeviceRequestType.UNPAIR
),
predicate_func,
predicate_func,
(BluetoothDeviceUnpairingResponse,),
timeout=timeout,
)
assert len(responses) == 1
response = responses[0]
return BluetoothDeviceUnpairing.from_pb(response)
async def bluetooth_device_disconnect(self, address: int) -> None:
self._check_authenticated()

View File

@ -6,7 +6,9 @@ from .api_pb2 import ( # type: ignore
BinarySensorStateResponse,
BluetoothConnectionsFreeResponse,
BluetoothDeviceConnectionResponse,
BluetoothDevicePairingResponse,
BluetoothDeviceRequest,
BluetoothDeviceUnpairingResponse,
BluetoothGATTErrorResponse,
BluetoothGATTGetServicesDoneResponse,
BluetoothGATTGetServicesRequest,
@ -302,4 +304,6 @@ MESSAGE_TYPE_TO_PROTO = {
82: BluetoothGATTErrorResponse,
83: BluetoothGATTWriteResponse,
84: BluetoothGATTNotifyResponse,
85: BluetoothDevicePairingResponse,
86: BluetoothDeviceUnpairingResponse,
}

View File

@ -867,6 +867,20 @@ class BluetoothDeviceConnection(APIModelBase):
error: int = 0
@dataclass(frozen=True)
class BluetoothDevicePairing(APIModelBase):
address: int = 0
paired: bool = False
error: int = 0
@dataclass(frozen=True)
class BluetoothDeviceUnpairing(APIModelBase):
address: int = 0
success: bool = False
error: int = 0
@dataclass(frozen=True)
class BluetoothGATTRead(APIModelBase):
address: int = 0