36
36
from micropython import const
37
37
import _bleio
38
38
from adafruit_ble .advertising import Advertisement , Struct , AdvertisingDataField
39
- from adafruit_ble .advertising .standard import ManufacturerData
40
39
41
40
try :
42
- from typing import Optional , Union , Any , Type , Tuple , Sequence
41
+ from typing import Optional , Union , Type , Tuple , Sequence
43
42
except ImportError :
44
43
pass
45
44
46
45
__version__ = "0.0.0+auto.0"
47
46
__repo__ = "https://github.com/tekktrik/Adafruit_CircuitPython_BLE_Beacon.git"
48
47
48
+
49
49
_MANUFACTURING_DATA_ADT = const (0xFF )
50
50
51
51
_APPLE_COMPANY_ID = const (0x004C )
52
52
_IBEACON_TYPE = const (0x02 )
53
53
_IBEACON_LENGTH = const (0x15 )
54
54
55
- # TODO: fix this
56
- _APPLE_COMPANY_ID_FLIPPED = const (0x4C00 )
57
-
58
55
59
56
class MultiStruct (AdvertisingDataField ):
60
57
"""`struct` encoded data in an Advertisement."""
@@ -65,7 +62,7 @@ def __init__(self, struct_format: str, *, advertising_data_type: int) -> None:
65
62
66
63
def __get__ (
67
64
self , obj : Optional ["Advertisement" ], cls : Type ["Advertisement" ]
68
- ) -> Optional [Union [Tuple , "Struct " ]]:
65
+ ) -> Optional [Union [Tuple , "MultiStruct " ]]:
69
66
if obj is None :
70
67
return self
71
68
if self ._adt not in obj .data_dict :
@@ -75,14 +72,16 @@ def __get__(
75
72
def __set__ (self , obj : "Advertisement" , value : Sequence ) -> None :
76
73
obj .data_dict [self ._adt ] = struct .pack (self ._format , * value )
77
74
75
+
78
76
class _BeaconAdvertisement (Advertisement ):
79
77
"""Advertisement for location beacons like iBeacon"""
80
78
81
- path_loss_const : int = 3
79
+ path_loss_const : float = 3
82
80
"""The path loss constant, typically between 2-4"""
83
81
84
82
@property
85
83
def uuid (self ) -> bytes :
84
+ """The UUID of the beacon"""
86
85
raise NotImplementedError ("Must be implemented in beacon subclass" )
87
86
88
87
@uuid .setter
@@ -91,22 +90,31 @@ def uuid(self, id: bytes) -> None:
91
90
92
91
@property
93
92
def distance (self ) -> float :
94
- """The approximate distance to the beacon"""
95
-
96
- return 10 ** ((self .beacon_tx_power - self .rssi ) / (10 * self .path_loss_const ))
93
+ """The approximate distance to the beacon, in meters"""
94
+ return 10 ** ((self .beacon_tx_power - self .rssi ) / (10 * self .path_loss_const ))
97
95
98
96
@property
99
97
def beacon_tx_power (self ) -> int :
98
+ """The beacon TX power"""
100
99
raise NotImplementedError ("Must be implemented in beacon subclass" )
101
100
102
101
@beacon_tx_power .setter
103
102
def beacon_txt_power (self , power : int ) -> None :
104
103
raise NotImplementedError ("Must be implemented in beacon subclass" )
105
104
106
-
107
- class iBeaconAdvertisement (_BeaconAdvertisement ):
108
105
109
- match_prefixes = (struct .pack ("<BHBB" , _MANUFACTURING_DATA_ADT , _APPLE_COMPANY_ID , _IBEACON_TYPE , _IBEACON_LENGTH ),)
106
+ class iBeaconAdvertisement (_BeaconAdvertisement ):
107
+ """An iBeacon advertisement"""
108
+
109
+ match_prefixes = (
110
+ struct .pack (
111
+ "<BHBB" ,
112
+ _MANUFACTURING_DATA_ADT ,
113
+ _APPLE_COMPANY_ID ,
114
+ _IBEACON_TYPE ,
115
+ _IBEACON_LENGTH ,
116
+ ),
117
+ )
110
118
111
119
_data_format = ">HBBQQHHb"
112
120
_beacon_data = MultiStruct (_data_format , advertising_data_type = 0xFF )
@@ -117,14 +125,14 @@ class iBeaconAdvertisement(_BeaconAdvertisement):
117
125
_minor_index = 6
118
126
_beacon_tx_power_index = 7
119
127
120
-
121
- def __init__ (self , * , entry : Optional [_bleio .ScanEntry ] = None , ) -> None :
128
+ def __init__ (self , * , entry : Optional [_bleio .ScanEntry ] = None ) -> None :
122
129
super ().__init__ (entry = entry )
123
130
if not entry :
124
131
self ._init_struct ()
125
-
132
+
126
133
@property
127
134
def uuid (self ) -> bytes :
135
+ """The UUID of the beacon"""
128
136
uuid_msb = self ._get_struct_index (self ._uuid_msb_index )
129
137
uuid_lsb = self ._get_struct_index (self ._uuid_lsb_index )
130
138
return struct .pack (">QQ" , uuid_msb , uuid_lsb )
@@ -137,6 +145,7 @@ def uuid(self, id: bytes) -> None:
137
145
138
146
@property
139
147
def major (self ) -> int :
148
+ """The major store number for the beacon"""
140
149
return self ._get_struct_index (self ._major_index )
141
150
142
151
@major .setter
@@ -145,6 +154,7 @@ def major(self, number: int) -> None:
145
154
146
155
@property
147
156
def minor (self ) -> int :
157
+ """The minor store number for the beacon"""
148
158
return self ._get_struct_index (self ._minor_index )
149
159
150
160
@minor .setter
@@ -153,6 +163,7 @@ def minor(self, number: int) -> None:
153
163
154
164
@property
155
165
def beacon_tx_power (self ) -> int :
166
+ """The beacon TX power"""
156
167
return self ._get_struct_index (self ._beacon_tx_power_index )
157
168
158
169
@beacon_tx_power .setter
@@ -170,4 +181,13 @@ def _get_struct_index(self, index: int) -> int:
170
181
171
182
def _init_struct (self ) -> None :
172
183
apple_id_flipped = struct .unpack (">H" , struct .pack ("<H" , _APPLE_COMPANY_ID ))
173
- self ._beacon_data = (apple_id_flipped , _IBEACON_TYPE , _IBEACON_LENGTH , 0 , 0 , 0 , 0 , 0 )
184
+ self ._beacon_data = (
185
+ apple_id_flipped ,
186
+ _IBEACON_TYPE ,
187
+ _IBEACON_LENGTH ,
188
+ 0 ,
189
+ 0 ,
190
+ 0 ,
191
+ 0 ,
192
+ 0 ,
193
+ )
0 commit comments