@@ -54,9 +54,9 @@ class Scanner:
54
54
def __init__ (self ):
55
55
self ._scanner = bleio .Scanner ()
56
56
57
- def scan_unique (self , timeout , * , interval = 0.1 , window = 0.1 ):
57
+ def scan (self , timeout , * , interval = 0.1 , window = 0.1 ):
58
58
"""Scan for advertisements from BLE devices. Suppress duplicates
59
- in returned `ScanEntry` objects.
59
+ in returned `ScanEntry` objects, so there is only one entry per address (device) .
60
60
61
61
:param int timeout: how long to scan for (in seconds)
62
62
:param float interval: the interval (in seconds) between the start
@@ -67,10 +67,11 @@ def scan_unique(self, timeout, *, interval=0.1, window=0.1):
67
67
:returns a list of `adafruit_ble.ScanEntry` objects.
68
68
69
69
"""
70
- return ScanEntry .unique (self .scan (timeout , interval = interval , window = window ))
70
+ return ScanEntry .unique_devices (self .raw_scan (timeout , interval = interval , window = window ))
71
71
72
- def scan (self , timeout , * , interval = 0.1 , window = 0.1 ):
73
- """Scan for advertisements from BLE devices.
72
+ def raw_scan (self , timeout , * , interval = 0.1 , window = 0.1 ):
73
+ """Scan for advertisements from BLE devices. Include every scan entry,
74
+ even duplicates.
74
75
75
76
:param int timeout: how long to scan for (in seconds)
76
77
:param float interval: the interval (in seconds) between the start
@@ -92,63 +93,46 @@ class ScanEntry:
92
93
"""
93
94
94
95
def __init__ (self , scan_entry ):
95
- self ._bleio_scan_entry = scan_entry
96
-
97
- def item (self , item_type ):
98
- """Return the bytes in the advertising packet for given the element type.
99
-
100
- :param int element_type: An integer designating an element type.
101
- A number are defined in `AdvertisingPacket`, such as `AdvertisingPacket.TX_POWER`.
102
- :returns: bytes that are the value for the given element type.
103
- If the element type is not present in the packet, return ``None``.
104
- """
105
- i = 0
106
- adv_bytes = self .advertisement_bytes
107
- while i < len (adv_bytes ):
108
- item_length = adv_bytes [i ]
109
- if item_type != adv_bytes [i + 1 ]:
110
- # Type doesn't match: skip to next item.
111
- i += item_length + 1
112
- else :
113
- return adv_bytes [i + 2 :i + 1 + item_length ]
114
- return None
96
+ self ._rssi = scan_entry .rssi
97
+ self ._address = scan_entry .address
98
+ self ._packet = AdvertisingPacket (scan_entry .advertisement_bytes )
115
99
116
100
@property
117
- def advertisement_bytes (self ):
118
- """The raw bytes of the received advertisement ."""
119
- return self ._bleio_scan_entry . advertisement_bytes
101
+ def advertisement_packet (self ):
102
+ """The received advertising packet ."""
103
+ return self ._packet
120
104
121
105
@property
122
106
def rssi (self ):
123
107
"""The signal strength of the device at the time of the scan. (read-only)."""
124
- return self ._bleio_scan_entry . rssi
108
+ return self ._rssi
125
109
126
110
@property
127
111
def address (self ):
128
112
"""The address of the device. (read-only)."""
129
- return self ._bleio_scan_entry . address
113
+ return self ._address
130
114
131
115
@property
132
116
def name (self ):
133
117
"""The name of the device. (read-only)"""
134
- name = self .item (AdvertisingPacket .COMPLETE_LOCAL_NAME )
135
- return name if name else self .item (AdvertisingPacket .SHORT_LOCAL_NAME )
118
+ name = self ._packet . get (AdvertisingPacket .COMPLETE_LOCAL_NAME )
119
+ return name if name else self ._packet . get (AdvertisingPacket .SHORT_LOCAL_NAME )
136
120
137
121
@property
138
122
def service_uuids (self ):
139
123
"""List of all the service UUIDs in the advertisement."""
140
124
uuid_values = []
141
125
142
- concat_uuids = self .item (AdvertisingPacket .ALL_16_BIT_SERVICE_UUIDS )
143
- concat_uuids = concat_uuids if concat_uuids else self .item (
126
+ concat_uuids = self ._packet . get (AdvertisingPacket .ALL_16_BIT_SERVICE_UUIDS )
127
+ concat_uuids = concat_uuids if concat_uuids else self ._packet . get (
144
128
AdvertisingPacket .SOME_16_BIT_SERVICE_UUIDS )
145
129
146
130
if concat_uuids :
147
131
for i in range (0 , len (concat_uuids ), 2 ):
148
132
uuid_values .extend (struct .unpack ("<H" , concat_uuids [i :i + 2 ]))
149
133
150
- concat_uuids = self .item (AdvertisingPacket .ALL_128_BIT_SERVICE_UUIDS )
151
- concat_uuids = concat_uuids if concat_uuids else self .item (
134
+ concat_uuids = self ._packet . get (AdvertisingPacket .ALL_128_BIT_SERVICE_UUIDS )
135
+ concat_uuids = concat_uuids if concat_uuids else self ._packet . get (
152
136
AdvertisingPacket .SOME_128_BIT_SERVICE_UUIDS )
153
137
154
138
if concat_uuids :
@@ -160,29 +144,30 @@ def service_uuids(self):
160
144
@property
161
145
def manufacturer_specific_data (self ):
162
146
"""Manufacturer-specific data in the advertisement, returned as bytes."""
163
- return self .item (AdvertisingPacket .MANUFACTURER_SPECIFIC_DATA )
147
+ return self ._packet . get (AdvertisingPacket .MANUFACTURER_SPECIFIC_DATA )
164
148
165
- def matches (self , other ):
149
+ def same_device (self , other ):
166
150
"""True if two scan entries appear to be from the same device. Their
167
- addresses and advertisement_bytes must match.
151
+ addresses and advertisement must match.
168
152
"""
169
153
return (self .address == other .address and
170
- self .advertisement_bytes == other .advertisement_bytes )
154
+ self .advertisement_packet .packet_bytes ==
155
+ other .advertisement_packet .packet_bytes )
171
156
172
157
@staticmethod
173
158
def with_service_uuid (scan_entries , service_uuid ):
174
159
"""Return all scan entries advertising the given service_uuid."""
175
160
return [se for se in scan_entries if service_uuid in se .service_uuids ]
176
161
177
162
@staticmethod
178
- def unique (scan_entries ):
163
+ def unique_devices (scan_entries ):
179
164
"""Discard duplicate scan entries that appear to be from the same device.
180
165
181
166
:param sequence scan_entries: ScanEntry objects
182
167
:returns list: list with duplicates removed
183
168
"""
184
169
unique = []
185
170
for entry in scan_entries :
186
- if not any (entry .matches (unique_entry ) for unique_entry in unique ):
171
+ if not any (entry .same_device (unique_entry ) for unique_entry in unique ):
187
172
unique .append (entry )
188
173
return unique
0 commit comments