23
23
`adafruit_ble.scanner`
24
24
====================================================
25
25
26
- UART-style communication.
26
+ Scan for nearby BLE Devices
27
27
28
28
* Author(s): Dan Halbert for Adafruit Industries
29
29
@@ -63,22 +63,21 @@ def scan(self, timeout, *, interval=0.1, window=0.1):
63
63
Must be in the range 0.0025 - 40.959375 seconds.
64
64
:param float window: the duration (in seconds) to scan a single BLE channel.
65
65
`window` must be <= `interval`.
66
- :returns: advertising packets found
67
- :rtype: list of `adafruit_ble.ScanEntry` objects
68
- """
69
- return [ScanEntry (entry ) for entry in self ._scanner .scan (timeout , interval = interval , window = window )]
66
+ :returns a list of `adafruit_ble.ScanEntry` objects.
70
67
68
+ """
69
+ return [ScanEntry (e ) for e in self ._scanner .scan (timeout , interval = interval , window = window )]
71
70
72
71
class ScanEntry :
73
72
"""
74
73
Information about an advertising packet from a BLE device received by a `Scanner`.
75
74
76
- :param bleio.ScanEntry entry : lower-level ScanEntry returned from `bleio.Scanner`.
77
- This constructor is normally used only `Scanner`.
75
+ :param bleio.ScanEntry scan_entry : lower-level ScanEntry returned from `bleio.Scanner`.
76
+ This constructor is normally used only by `Scanner`.
78
77
"""
79
78
80
- def __init__ (self , entry ):
81
- self ._bleio_entry = entry
79
+ def __init__ (self , scan_entry ):
80
+ self ._bleio_scan_entry = scan_entry
82
81
83
82
def item (self , item_type ):
84
83
"""Return the bytes in the advertising packet for given the element type.
@@ -96,23 +95,23 @@ def item(self, item_type):
96
95
# Type doesn't match: skip to next item.
97
96
i += item_length + 1
98
97
else :
99
- return adv_bytes [i + 2 :i + item_length ]
98
+ return adv_bytes [i + 2 :i + 1 + item_length ]
100
99
return None
101
100
102
101
@property
103
102
def advertisement_bytes (self ):
104
103
"""The raw bytes of the received advertisement."""
105
- return self ._bleio_entry . raw_data
104
+ return self ._bleio_scan_entry . advertisement_bytes
106
105
107
106
@property
108
107
def rssi (self ):
109
108
"""The signal strength of the device at the time of the scan. (read-only)."""
110
- return self ._bleio_entry .rssi
109
+ return self ._bleio_scan_entry .rssi
111
110
112
111
@property
113
112
def address (self ):
114
113
"""The address of the device. (read-only)."""
115
- return self ._bleio_entry .address
114
+ return self ._bleio_scan_entry .address
116
115
117
116
@property
118
117
def name (self ):
@@ -146,3 +145,22 @@ def service_uuids(self):
146
145
def manufacturer_specific_data (self ):
147
146
"""Manufacturer-specific data in the advertisement, returned as bytes."""
148
147
return self .item (AdvertisingPacket .MANUFACTURER_SPECIFIC_DATA )
148
+
149
+ def matches (self , other ):
150
+ """True if two scan entries appear to be from the same device. Their
151
+ addresses and advertisement_bytes must match.
152
+ """
153
+ return self .address == other .address and self .advertisement_bytes == other .advertisement_bytes
154
+
155
+ @classmethod
156
+ def unique (self , scan_entries ):
157
+ """Discard duplicate scan entries that appear to be from the same device.
158
+
159
+ :param sequence scan_entries: ScanEntry objects
160
+ :returns list: list with duplicates removed
161
+ """
162
+ unique = []
163
+ for entry in scan_entries :
164
+ if not any (entry .matches (unique_entry ) for unique_entry in unique ):
165
+ unique .append (entry );
166
+ return unique
0 commit comments