Skip to content

Cannot effectively scan with OSX, RasPi, or Feather Sense #15

Closed
@alexwhittemore

Description

@alexwhittemore

This might be related to #11 but I can't say for sure - the symptoms don't totally overlap. The gist is, ble.start_scan(adafruit_ble_broadcastnet.AdafruitSensorMeasurement) will never return any advertisements to process, tested on Mac and RasPi. If, on the other hand, I ble.start_scan(), plenty of the relevant ads ARE getting scanned.

I'm running the following code on a Feather Sense:

import time
import microcontroller
import adafruit_ble_broadcastnet

from adafruit_ble import BLERadio
from adafruit_ble.advertising.adafruit import AdafruitColor
import random

ble = BLERadio()

print("This is BroadcastNet sensor:", adafruit_ble_broadcastnet.device_address)

while True:
   measurement = adafruit_ble_broadcastnet.AdafruitSensorMeasurement()
   measurement.temperature = (
      microcontroller.cpu.temperature  # pylint: disable=no-member
   )
   print(measurement)
   print(measurement.__repr__())
   #adafruit_ble_broadcastnet.broadcast(measurement, broadcast_time=3)
   ble.start_advertising(measurement)
   time.sleep(10)
   ble.stop_advertising()

On the RasPi, I'm using the following to scan:

import time
from adafruit_ble.advertising.standard import ManufacturerDataField
import adafruit_ble
import adafruit_ble_broadcastnet



ble = adafruit_ble.BLERadio()
bridge_address = adafruit_ble_broadcastnet.device_address
print("This is BroadcastNet bridge:", bridge_address)
print()

print("scanning")
print()
sequence_numbers = {}
# By providing Advertisement as well we include everything, not just specific advertisements.

# ====== Switch between these two lines for A/B testing ======
# for measurement in ble.start_scan(adafruit_ble_broadcastnet.AdafruitSensorMeasurement, interval=0.5):
for measurement in ble.start_scan(interval=0.5): 
    reversed_address = [measurement.address.address_bytes[i] for i in range(5, -1, -1)]
    sensor_address = "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}".format(*reversed_address)
    if sensor_address == "f5bfcae0c159": ## On RasPi, the self-identified MAC address gets returned, so this looks sane.
        print(measurement.__repr__())

print("scan done")

On Mac, I'm using the following to implement the same test:

"""This example bridges from BLE to Adafruit IO on a Raspberry Pi, but without actually interacting with AIO at all"""
import time
from adafruit_ble.advertising.standard import ManufacturerDataField
import adafruit_ble
import adafruit_ble_broadcastnet

ble = adafruit_ble.BLERadio()
bridge_address = adafruit_ble_broadcastnet.device_address
print("This is BroadcastNet bridge:", bridge_address)
print()

print("scanning")
print()
sequence_numbers = {}

# ==== Again, switch between these two lines for testing ====
# for measurement in ble.start_scan(adafruit_ble_broadcastnet.AdafruitSensorMeasurement, interval=0.5):
for measurement in ble.start_scan(interval=0.5): 
    # Bleak on macOS doesn't deal in 6-byte MACs, so this obnoxious UUID is how things work.
    # Had to figure this out by waiting for an ad with the right complete_name, then checking this value.
    # Don't want to filter by name alone as some ads might be surfaced without complete_name.
    if measurement.address.string == "3A8F6F02-DA05-41C9-83D4-835F626674DC":
        print(measurement.__repr__())
print("scan done")

The result of this test:

# Ad as printed by the Feather:
Advertisement(data=b"\x0a\xff\x22\x08\x06\x04\x0a\x00\x00\xae\x41")

# Ad as it comes through on Mac in a generic scan:
Advertisement(data=b"\x0a\xff\x22\x08\x06\x04\x0a\x00\x00\xae\x41\x0e\x09\x43\x49\x52\x43\x55\x49\x54\x50\x59\x63\x31\x35\x39")

# Ad as it comes through on the Pi in a generic scan (these two ads repeat in alternation - I guess the Pi reports the 
# add, then reports again if a scan_response comes through, where Mac waits to avoid duplication.)
Advertisement(data=b"\x0a\xff\x22\x08\x06\x04\x0a\x00\x00\xae\x41")
Advertisement(data=b"\x02\x0a\x00\x0e\x09\x43\x49\x52\x43\x55\x49\x54\x50\x59\x63\x31\x35\x39")

# As ads come through on the Feather Sense in a generic scan, which looks identical to the Pi. Note that the reported temperature changed, because this is a new test at a different time (0xAE vs 0xB6).
Advertisement(data=b"\x0a\xff\x22\x08\x06\x04\x0a\x00\x00\xb6\x41")
Advertisement(data=b"\x02\x0a\x00\x0e\x09\x43\x49\x52\x43\x55\x49\x54\x50\x59\x63\x31\x35\x39")

I'm not quite sure what to make of this, but it looks like the check of match_prefixes is failing for some non-obvious reason, given that the ad data payload looks pretty matchy to me in the Mac case, and in at least the shorter Pi case.

EDIT: I just tested with a second Feather Sense running the RasPi version of the gateway code, and got matching results to the Pi. I noticed at the same time that the manufacturer data appears to be included in the first advertisement but not the second, which I guess is normal - the scan_response doesn't duplicate the original manufacturer data payload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions