46
46
47
47
def broadcast (measurement , * , broadcast_time = 0.1 , extended = False ):
48
48
"""Broadcasts the given measurement for the given broadcast time. If extended is False and the
49
- measurement would be too long, it will be split into multiple measurements for transmission.
50
- """
49
+ measurement would be too long, it will be split into multiple measurements for transmission.
50
+ """
51
51
global _sequence_number # pylint: disable=global-statement,invalid-name
52
52
for submeasurement in measurement .split (252 if extended else 31 ):
53
53
submeasurement .sequence_number = _sequence_number
@@ -61,14 +61,17 @@ def broadcast(measurement, *, broadcast_time=0.1, extended=False):
61
61
if not hasattr (os , "environ" ) or (
62
62
"GITHUB_ACTION" not in os .environ and "READTHEDOCS" not in os .environ
63
63
):
64
- device_address = "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}" .format ( # pylint: disable=invalid-name
65
- * reversed (
66
- list (
67
- _ble ._adapter .address .address_bytes # pylint: disable=protected-access
64
+ if _ble ._adapter .address : # pylint: disable=protected-access
65
+ device_address = "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}" .format ( # pylint: disable=invalid-name
66
+ * reversed (
67
+ list (
68
+ _ble ._adapter .address .address_bytes # pylint: disable=protected-access
69
+ )
68
70
)
69
71
)
70
- )
71
- """Device address as a string."""
72
+ else :
73
+ device_address = "000000000000" # pylint: disable=invalid-name
74
+ """Device address as a string."""
72
75
73
76
_MANUFACTURING_DATA_ADT = const (0xFF )
74
77
_ADAFRUIT_COMPANY_ID = const (0x0822 )
@@ -79,7 +82,10 @@ class AdafruitSensorMeasurement(Advertisement):
79
82
80
83
# This prefix matches all
81
84
match_prefixes = (
82
- struct .pack ("<BBH" , 3 , _MANUFACTURING_DATA_ADT , _ADAFRUIT_COMPANY_ID ),
85
+ # Matches the sequence number field header (length+ID)
86
+ struct .pack (
87
+ "<BHBH" , _MANUFACTURING_DATA_ADT , _ADAFRUIT_COMPANY_ID , 0x03 , 0x0003
88
+ ),
83
89
)
84
90
85
91
manufacturer_data = LazyObjectField (
@@ -175,9 +181,16 @@ def __str__(self):
175
181
parts .append ("{}={}" .format (attr , str (value )))
176
182
return "<{} {} >" .format (self .__class__ .__name__ , " " .join (parts ))
177
183
184
+ def __bytes__ (self ):
185
+ """The raw packet bytes."""
186
+ # Must reorder the ManufacturerData contents so the sequence number field is always first.
187
+ # Necessary to ensure that match_prefixes works right to reconstruct on the receiver.
188
+ self .data_dict [255 ].data .move_to_end (3 , last = False )
189
+ return super ().__bytes__ ()
190
+
178
191
def split (self , max_packet_size = 31 ):
179
192
"""Split the measurement into multiple measurements with the given max_packet_size. Yields
180
- each submeasurement."""
193
+ each submeasurement."""
181
194
current_size = 8 # baseline for mfg data and sequence number
182
195
if current_size + len (self .manufacturer_data ) < max_packet_size :
183
196
yield self
0 commit comments