Add missing characteristic type parameters

This commit is contained in:
Josh Wu
2025-04-16 17:08:07 +08:00
parent 2686663eb2
commit 5e9fc89f80
11 changed files with 89 additions and 81 deletions

View File

@@ -1244,7 +1244,7 @@ class Peer:
self, self,
uuids: Iterable[Union[core.UUID, str]] = (), uuids: Iterable[Union[core.UUID, str]] = (),
service: Optional[gatt_client.ServiceProxy] = None, service: Optional[gatt_client.ServiceProxy] = None,
) -> list[gatt_client.CharacteristicProxy]: ) -> list[gatt_client.CharacteristicProxy[bytes]]:
return await self.gatt_client.discover_characteristics( return await self.gatt_client.discover_characteristics(
uuids=uuids, service=service uuids=uuids, service=service
) )
@@ -1259,7 +1259,7 @@ class Peer:
characteristic, start_handle, end_handle characteristic, start_handle, end_handle
) )
async def discover_attributes(self) -> list[gatt_client.AttributeProxy]: async def discover_attributes(self) -> list[gatt_client.AttributeProxy[bytes]]:
return await self.gatt_client.discover_attributes() return await self.gatt_client.discover_attributes()
async def discover_all(self): async def discover_all(self):
@@ -1313,7 +1313,7 @@ class Peer:
self, self,
uuid: core.UUID, uuid: core.UUID,
service: Optional[Union[gatt_client.ServiceProxy, core.UUID]] = None, service: Optional[Union[gatt_client.ServiceProxy, core.UUID]] = None,
) -> list[gatt_client.CharacteristicProxy]: ) -> list[gatt_client.CharacteristicProxy[bytes]]:
if isinstance(service, core.UUID): if isinstance(service, core.UUID):
return list( return list(
itertools.chain( itertools.chain(

View File

@@ -149,7 +149,7 @@ class AttributeProxy(utils.EventEmitter, Generic[_T]):
class ServiceProxy(AttributeProxy): class ServiceProxy(AttributeProxy):
uuid: UUID uuid: UUID
characteristics: List[CharacteristicProxy] characteristics: List[CharacteristicProxy[bytes]]
included_services: List[ServiceProxy] included_services: List[ServiceProxy]
@staticmethod @staticmethod
@@ -170,14 +170,20 @@ class ServiceProxy(AttributeProxy):
self.uuid = uuid self.uuid = uuid
self.characteristics = [] self.characteristics = []
async def discover_characteristics(self, uuids=()) -> list[CharacteristicProxy]: async def discover_characteristics(
self, uuids=()
) -> list[CharacteristicProxy[bytes]]:
return await self.client.discover_characteristics(uuids, self) return await self.client.discover_characteristics(uuids, self)
def get_characteristics_by_uuid(self, uuid: UUID) -> list[CharacteristicProxy]: def get_characteristics_by_uuid(
self, uuid: UUID
) -> list[CharacteristicProxy[bytes]]:
"""Get all the characteristics with a specified UUID.""" """Get all the characteristics with a specified UUID."""
return self.client.get_characteristics_by_uuid(uuid, self) return self.client.get_characteristics_by_uuid(uuid, self)
def get_required_characteristic_by_uuid(self, uuid: UUID) -> CharacteristicProxy: def get_required_characteristic_by_uuid(
self, uuid: UUID
) -> CharacteristicProxy[bytes]:
""" """
Get the first characteristic with a specified UUID. Get the first characteristic with a specified UUID.
@@ -256,7 +262,7 @@ class CharacteristicProxy(AttributeProxy[_T]):
) )
class DescriptorProxy(AttributeProxy): class DescriptorProxy(AttributeProxy[bytes]):
def __init__(self, client: Client, handle: int, descriptor_type: UUID) -> None: def __init__(self, client: Client, handle: int, descriptor_type: UUID) -> None:
super().__init__(client, handle, 0, descriptor_type) super().__init__(client, handle, 0, descriptor_type)
@@ -376,7 +382,7 @@ class Client:
def get_characteristics_by_uuid( def get_characteristics_by_uuid(
self, uuid: UUID, service: Optional[ServiceProxy] = None self, uuid: UUID, service: Optional[ServiceProxy] = None
) -> List[CharacteristicProxy]: ) -> List[CharacteristicProxy[bytes]]:
services = [service] if service else self.services services = [service] if service else self.services
return [ return [
c c
@@ -628,7 +634,7 @@ class Client:
async def discover_characteristics( async def discover_characteristics(
self, uuids, service: Optional[ServiceProxy] self, uuids, service: Optional[ServiceProxy]
) -> List[CharacteristicProxy]: ) -> List[CharacteristicProxy[bytes]]:
''' '''
See Vol 3, Part G - 4.6.1 Discover All Characteristics of a Service and 4.6.2 See Vol 3, Part G - 4.6.1 Discover All Characteristics of a Service and 4.6.2
Discover Characteristics by UUID Discover Characteristics by UUID
@@ -641,12 +647,12 @@ class Client:
services = [service] if service else self.services services = [service] if service else self.services
# Perform characteristic discovery for each service # Perform characteristic discovery for each service
discovered_characteristics: List[CharacteristicProxy] = [] discovered_characteristics: List[CharacteristicProxy[bytes]] = []
for service in services: for service in services:
starting_handle = service.handle starting_handle = service.handle
ending_handle = service.end_group_handle ending_handle = service.end_group_handle
characteristics: List[CharacteristicProxy] = [] characteristics: List[CharacteristicProxy[bytes]] = []
while starting_handle <= ending_handle: while starting_handle <= ending_handle:
response = await self.send_request( response = await self.send_request(
ATT_Read_By_Type_Request( ATT_Read_By_Type_Request(
@@ -686,7 +692,7 @@ class Client:
properties, handle = struct.unpack_from('<BH', attribute_value) properties, handle = struct.unpack_from('<BH', attribute_value)
characteristic_uuid = UUID.from_bytes(attribute_value[3:]) characteristic_uuid = UUID.from_bytes(attribute_value[3:])
characteristic: CharacteristicProxy = CharacteristicProxy( characteristic = CharacteristicProxy[bytes](
self, handle, 0, characteristic_uuid, properties self, handle, 0, characteristic_uuid, properties
) )
@@ -779,7 +785,7 @@ class Client:
return descriptors return descriptors
async def discover_attributes(self) -> List[AttributeProxy]: async def discover_attributes(self) -> List[AttributeProxy[bytes]]:
''' '''
Discover all attributes, regardless of type Discover all attributes, regardless of type
''' '''
@@ -812,7 +818,7 @@ class Client:
logger.warning(f'bogus handle value: {attribute_handle}') logger.warning(f'bogus handle value: {attribute_handle}')
return [] return []
attribute: AttributeProxy = AttributeProxy( attribute = AttributeProxy[bytes](
self, attribute_handle, 0, UUID.from_bytes(attribute_uuid) self, attribute_handle, 0, UUID.from_bytes(attribute_uuid)
) )
attributes.append(attribute) attributes.append(attribute)

View File

@@ -599,7 +599,7 @@ class AudioStreamControlService(gatt.TemplateService):
UUID = gatt.GATT_AUDIO_STREAM_CONTROL_SERVICE UUID = gatt.GATT_AUDIO_STREAM_CONTROL_SERVICE
ase_state_machines: Dict[int, AseStateMachine] ase_state_machines: Dict[int, AseStateMachine]
ase_control_point: gatt.Characteristic ase_control_point: gatt.Characteristic[bytes]
_active_client: Optional[device.Connection] = None _active_client: Optional[device.Connection] = None
def __init__( def __init__(
@@ -717,9 +717,9 @@ class AudioStreamControlService(gatt.TemplateService):
class AudioStreamControlServiceProxy(gatt_client.ProfileServiceProxy): class AudioStreamControlServiceProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = AudioStreamControlService SERVICE_CLASS = AudioStreamControlService
sink_ase: List[gatt_client.CharacteristicProxy] sink_ase: List[gatt_client.CharacteristicProxy[bytes]]
source_ase: List[gatt_client.CharacteristicProxy] source_ase: List[gatt_client.CharacteristicProxy[bytes]]
ase_control_point: gatt_client.CharacteristicProxy ase_control_point: gatt_client.CharacteristicProxy[bytes]
def __init__(self, service_proxy: gatt_client.ServiceProxy): def __init__(self, service_proxy: gatt_client.ServiceProxy):
self.service_proxy = service_proxy self.service_proxy = service_proxy

View File

@@ -259,11 +259,11 @@ class AshaService(gatt.TemplateService):
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
class AshaServiceProxy(gatt_client.ProfileServiceProxy): class AshaServiceProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = AshaService SERVICE_CLASS = AshaService
read_only_properties_characteristic: gatt_client.CharacteristicProxy read_only_properties_characteristic: gatt_client.CharacteristicProxy[bytes]
audio_control_point_characteristic: gatt_client.CharacteristicProxy audio_control_point_characteristic: gatt_client.CharacteristicProxy[bytes]
audio_status_point_characteristic: gatt_client.CharacteristicProxy audio_status_point_characteristic: gatt_client.CharacteristicProxy[bytes]
volume_characteristic: gatt_client.CharacteristicProxy volume_characteristic: gatt_client.CharacteristicProxy[bytes]
psm_characteristic: gatt_client.CharacteristicProxy psm_characteristic: gatt_client.CharacteristicProxy[bytes]
def __init__(self, service_proxy: gatt_client.ServiceProxy) -> None: def __init__(self, service_proxy: gatt_client.ServiceProxy) -> None:
self.service_proxy = service_proxy self.service_proxy = service_proxy

View File

@@ -354,7 +354,7 @@ class BroadcastAudioScanService(gatt.TemplateService):
class BroadcastAudioScanServiceProxy(gatt_client.ProfileServiceProxy): class BroadcastAudioScanServiceProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = BroadcastAudioScanService SERVICE_CLASS = BroadcastAudioScanService
broadcast_audio_scan_control_point: gatt_client.CharacteristicProxy broadcast_audio_scan_control_point: gatt_client.CharacteristicProxy[bytes]
broadcast_receive_states: list[ broadcast_receive_states: list[
gatt_client.CharacteristicProxy[Optional[BroadcastReceiveState]] gatt_client.CharacteristicProxy[Optional[BroadcastReceiveState]]
] ]

View File

@@ -99,10 +99,10 @@ class CoordinatedSetIdentificationService(gatt.TemplateService):
UUID = gatt.GATT_COORDINATED_SET_IDENTIFICATION_SERVICE UUID = gatt.GATT_COORDINATED_SET_IDENTIFICATION_SERVICE
set_identity_resolving_key: bytes set_identity_resolving_key: bytes
set_identity_resolving_key_characteristic: gatt.Characteristic set_identity_resolving_key_characteristic: gatt.Characteristic[bytes]
coordinated_set_size_characteristic: Optional[gatt.Characteristic] = None coordinated_set_size_characteristic: Optional[gatt.Characteristic[bytes]] = None
set_member_lock_characteristic: Optional[gatt.Characteristic] = None set_member_lock_characteristic: Optional[gatt.Characteristic[bytes]] = None
set_member_rank_characteristic: Optional[gatt.Characteristic] = None set_member_rank_characteristic: Optional[gatt.Characteristic[bytes]] = None
def __init__( def __init__(
self, self,
@@ -203,10 +203,10 @@ class CoordinatedSetIdentificationService(gatt.TemplateService):
class CoordinatedSetIdentificationProxy(gatt_client.ProfileServiceProxy): class CoordinatedSetIdentificationProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = CoordinatedSetIdentificationService SERVICE_CLASS = CoordinatedSetIdentificationService
set_identity_resolving_key: gatt_client.CharacteristicProxy set_identity_resolving_key: gatt_client.CharacteristicProxy[bytes]
coordinated_set_size: Optional[gatt_client.CharacteristicProxy] = None coordinated_set_size: Optional[gatt_client.CharacteristicProxy[bytes]] = None
set_member_lock: Optional[gatt_client.CharacteristicProxy] = None set_member_lock: Optional[gatt_client.CharacteristicProxy[bytes]] = None
set_member_rank: Optional[gatt_client.CharacteristicProxy] = None set_member_rank: Optional[gatt_client.CharacteristicProxy[bytes]] = None
def __init__(self, service_proxy: gatt_client.ServiceProxy) -> None: def __init__(self, service_proxy: gatt_client.ServiceProxy) -> None:
self.service_proxy = service_proxy self.service_proxy = service_proxy

View File

@@ -32,10 +32,10 @@ class GenericAttributeProfileService(gatt.TemplateService):
UUID = gatt.GATT_GENERIC_ATTRIBUTE_SERVICE UUID = gatt.GATT_GENERIC_ATTRIBUTE_SERVICE
client_supported_features_characteristic: gatt.Characteristic | None = None client_supported_features_characteristic: gatt.Characteristic[bytes] | None = None
server_supported_features_characteristic: gatt.Characteristic | None = None server_supported_features_characteristic: gatt.Characteristic[bytes] | None = None
database_hash_characteristic: gatt.Characteristic | None = None database_hash_characteristic: gatt.Characteristic[bytes] | None = None
service_changed_characteristic: gatt.Characteristic | None = None service_changed_characteristic: gatt.Characteristic[bytes] | None = None
def __init__( def __init__(
self, self,
@@ -143,14 +143,14 @@ class GenericAttributeProfileService(gatt.TemplateService):
class GenericAttributeProfileServiceProxy(gatt_client.ProfileServiceProxy): class GenericAttributeProfileServiceProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = GenericAttributeProfileService SERVICE_CLASS = GenericAttributeProfileService
client_supported_features_characteristic: gatt_client.CharacteristicProxy | None = ( client_supported_features_characteristic: (
None gatt_client.CharacteristicProxy[bytes] | None
) ) = None
server_supported_features_characteristic: gatt_client.CharacteristicProxy | None = ( server_supported_features_characteristic: (
None gatt_client.CharacteristicProxy[bytes] | None
) ) = None
database_hash_characteristic: gatt_client.CharacteristicProxy | None = None database_hash_characteristic: gatt_client.CharacteristicProxy[bytes] | None = None
service_changed_characteristic: gatt_client.CharacteristicProxy | None = None service_changed_characteristic: gatt_client.CharacteristicProxy[bytes] | None = None
_CHARACTERISTICS = { _CHARACTERISTICS = {
gatt.GATT_CLIENT_SUPPORTED_FEATURES_CHARACTERISTIC: 'client_supported_features_characteristic', gatt.GATT_CLIENT_SUPPORTED_FEATURES_CHARACTERISTIC: 'client_supported_features_characteristic',

View File

@@ -224,9 +224,9 @@ class PresetRecord:
class HearingAccessService(gatt.TemplateService): class HearingAccessService(gatt.TemplateService):
UUID = gatt.GATT_HEARING_ACCESS_SERVICE UUID = gatt.GATT_HEARING_ACCESS_SERVICE
hearing_aid_features_characteristic: gatt.Characteristic hearing_aid_features_characteristic: gatt.Characteristic[bytes]
hearing_aid_preset_control_point: gatt.Characteristic hearing_aid_preset_control_point: gatt.Characteristic[bytes]
active_preset_index_characteristic: gatt.Characteristic active_preset_index_characteristic: gatt.Characteristic[bytes]
active_preset_index: int active_preset_index: int
active_preset_index_per_device: Dict[Address, int] active_preset_index_per_device: Dict[Address, int]

View File

@@ -338,30 +338,32 @@ class MediaControlServiceProxy(
'content_control_id': gatt.GATT_CONTENT_CONTROL_ID_CHARACTERISTIC, 'content_control_id': gatt.GATT_CONTENT_CONTROL_ID_CHARACTERISTIC,
} }
media_player_name: Optional[gatt_client.CharacteristicProxy] = None media_player_name: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_player_icon_object_id: Optional[gatt_client.CharacteristicProxy] = None media_player_icon_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_player_icon_url: Optional[gatt_client.CharacteristicProxy] = None media_player_icon_url: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_changed: Optional[gatt_client.CharacteristicProxy] = None track_changed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_title: Optional[gatt_client.CharacteristicProxy] = None track_title: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_duration: Optional[gatt_client.CharacteristicProxy] = None track_duration: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_position: Optional[gatt_client.CharacteristicProxy] = None track_position: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playback_speed: Optional[gatt_client.CharacteristicProxy] = None playback_speed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
seeking_speed: Optional[gatt_client.CharacteristicProxy] = None seeking_speed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
current_track_segments_object_id: Optional[gatt_client.CharacteristicProxy] = None current_track_segments_object_id: Optional[
current_track_object_id: Optional[gatt_client.CharacteristicProxy] = None gatt_client.CharacteristicProxy[bytes]
next_track_object_id: Optional[gatt_client.CharacteristicProxy] = None ] = None
parent_group_object_id: Optional[gatt_client.CharacteristicProxy] = None current_track_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
current_group_object_id: Optional[gatt_client.CharacteristicProxy] = None next_track_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playing_order: Optional[gatt_client.CharacteristicProxy] = None parent_group_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playing_orders_supported: Optional[gatt_client.CharacteristicProxy] = None current_group_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_state: Optional[gatt_client.CharacteristicProxy] = None playing_order: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_control_point: Optional[gatt_client.CharacteristicProxy] = None playing_orders_supported: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_control_point_opcodes_supported: Optional[gatt_client.CharacteristicProxy] = ( media_state: Optional[gatt_client.CharacteristicProxy[bytes]] = None
None media_control_point: Optional[gatt_client.CharacteristicProxy[bytes]] = None
) media_control_point_opcodes_supported: Optional[
search_control_point: Optional[gatt_client.CharacteristicProxy] = None gatt_client.CharacteristicProxy[bytes]
search_results_object_id: Optional[gatt_client.CharacteristicProxy] = None ] = None
content_control_id: Optional[gatt_client.CharacteristicProxy] = None search_control_point: Optional[gatt_client.CharacteristicProxy[bytes]] = None
search_results_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
content_control_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
if TYPE_CHECKING: if TYPE_CHECKING:
media_control_point_notifications: asyncio.Queue[bytes] media_control_point_notifications: asyncio.Queue[bytes]

View File

@@ -104,12 +104,12 @@ class PacRecord:
class PublishedAudioCapabilitiesService(gatt.TemplateService): class PublishedAudioCapabilitiesService(gatt.TemplateService):
UUID = gatt.GATT_PUBLISHED_AUDIO_CAPABILITIES_SERVICE UUID = gatt.GATT_PUBLISHED_AUDIO_CAPABILITIES_SERVICE
sink_pac: Optional[gatt.Characteristic] sink_pac: Optional[gatt.Characteristic[bytes]]
sink_audio_locations: Optional[gatt.Characteristic] sink_audio_locations: Optional[gatt.Characteristic[bytes]]
source_pac: Optional[gatt.Characteristic] source_pac: Optional[gatt.Characteristic[bytes]]
source_audio_locations: Optional[gatt.Characteristic] source_audio_locations: Optional[gatt.Characteristic[bytes]]
available_audio_contexts: gatt.Characteristic available_audio_contexts: gatt.Characteristic[bytes]
supported_audio_contexts: gatt.Characteristic supported_audio_contexts: gatt.Characteristic[bytes]
def __init__( def __init__(
self, self,

View File

@@ -91,9 +91,9 @@ class VolumeState:
class VolumeControlService(gatt.TemplateService): class VolumeControlService(gatt.TemplateService):
UUID = gatt.GATT_VOLUME_CONTROL_SERVICE UUID = gatt.GATT_VOLUME_CONTROL_SERVICE
volume_state: gatt.Characteristic volume_state: gatt.Characteristic[bytes]
volume_control_point: gatt.Characteristic volume_control_point: gatt.Characteristic[bytes]
volume_flags: gatt.Characteristic volume_flags: gatt.Characteristic[bytes]
volume_setting: int volume_setting: int
muted: int muted: int