BWSI piPACT Reference/instructor developed code for Raspberry Pi based BLE RSSI measurement collection. Modified by Winner-exe.
Stated versions are tested and validated. Newer or older versions are not guaranteed to work.
- Python 3.7.3
- pybluez[ble]
- gattlib
- numpy
- pandas
- pyyaml
- sense_hat
- Install the requirement.
- Clone the repository.
- Navigate into the
piPACTfolder that was created.pi@raspberrypi:~ $ cd piPACT
- Test the repository by attempting to import the piPACT reference code without error.
pi@raspberrypi:~/piPACT $ python3 Python 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pi_pact >>>
This section addresses how to use the reference code to instantiate either a beacon advertiser or beacon scanner from the command line/terminal. Both are accessed from the same command line interface and use a common configuration file. Both also implement "user commanded stop" functionality via a simple control file mechanism explained in each section.
pi@raspberrypi:~ $ sudo python3 pi_pact.py --help
usage: pi_pact.py [-h] (-a | -s) [--config_yml CONFIG_YML]
[--control_file CONTROL_FILE] [--scan_prefix SCAN_PREFIX]
[--timeout TIMEOUT] [--uuid UUID] [--major MAJOR]
[--minor MINOR] [--tx_power TX_POWER] [--interval INTERVAL]
[--revist REVIST] [--distance DISTANCE] [--use_sense_hat USE_SENSE_HAT]
BLE beacon advertiser or scanner. Command line arguments will override their
corresponding value in a configuration file if specified.
optional arguments:
-h, --help show this help message and exit
-a, --advertiser Beacon advertiser mode.
-s, --scanner Beacon scanner mode.
--config_yml CONFIG_YML
Configuration YAML.
--control_file CONTROL_FILE
Control file.
--scan_prefix SCAN_PREFIX
Scan output file prefix.
--timeout TIMEOUT Timeout (s) for both beacon advertiser and scanner
modes.
--uuid UUID Beacon advertiser UUID.
--major MAJOR Beacon advertiser major value.
--minor MINOR Beacon advertiser minor value.
--tx_power TX_POWER Beacon advertiser TX power.
--interval INTERVAL Beacon advertiser interval (ms).
--revist REVIST Beacon scanner revisit interval (s).
--distance DISTANCE Pre-measured distance (m).
--use_sense_hat USE_SENSE_HAT Toggles use of sense hat.The configuration file is of the YAML format. It is provided with a default configuration which you should change to suit your needs. You will need to reference in-line comments and external module documentation to fully understand all configuration options.
The configuration YAML will only be used if specified as a command line argument. Many indiviudal configuration options can be overwritten by command line provided arguments.
# Configuration file for piPACT reference collection software
# Settings for beacon advertisment
advertiser:
control_file: 'advertiser_control' # Control file which stops beacon advertisement before timeout
timeout: 20 # Advertisement timeout (s)
uuid: '' # UUID, major, and minor values to advertise
major: 1
minor: 1
tx_power: 1 # Tx power at which to advertise
interval: 200 # Interval at which advertise (ms)
# Settings for beacon scanner
scanner:
control_file: 'scanner_control' # Control file which stops beacon scanner before timeout
scan_prefix: 'pi_pact_scan' # Prefix to attach to scan output files
timeout: 20 # Scanning timeout (s)
revisit: 1 # Interval at which to scan (s)
distance: 0.2 # Pre-measured distance between devices (m)
use_sense_hat: True # Toggles use of sense hat.
filters: # Filters
ADDRESS:
RSSI:
# Logger configuration
logger:
name: &name 'pi_pact.log'
config:
version: 1
formatters:
full:
format: '%(asctime)s %(module)-10s %(levelname)-8s %(message)s'
brief:
format: '%(asctime)s %(levelname)-8s %(message)s'
handlers:
console:
class: 'logging.StreamHandler'
level: 'INFO'
formatter: 'brief'
file:
class: 'logging.handlers.TimedRotatingFileHandler'
level: 'DEBUG'
formatter: 'full'
filename: *name
when: 'H'
interval: 1
loggers:
*name:
level: 'DEBUG' # Effective logging level
handlers:
- 'console'
- 'file'Filters are a special configuration specific to a scanner and only available via the configuration YAML. They allow users to filter received data such that only data that meets all specified filters. Filters are specified as key-value pairs where the key is the data field to filter on and the value is filter specification (value/bounds). If no filters are specified then all received data is logged.
There are two (2) categories of filters available:
- ID filters: Filter data based on exact match. These filters are associated with parts of a beacon advertisement that is fixed and unique to a beacon's identity. This filtering is done using pandas.DataFrame.isin functionality. Available ID filters are
- ADDRESS - Advertiser's beacon hardware address
- UUID - Advertiser's Universally Unique Identifier (UUID)
- MAJOR - Advertiser's Major value
- MINOR - Advertiser's Minor value
- TX POWER - Avertiser's stated Transmit (Tx) Power
- Measurement filters: Filter data based on within-range match. These filters are associated with measured values of the beacon advertisement that may vary and have no direct correlation with a beacon's identity. These are specified as 2-element list where the 1st element is the lower bound while the 2nd element is the upper bound. This filtering is done using pandas.DataFrame.query functionality. Available measurement filters are
- TIMESTAMP - Time window specified by a beginning and end timestamp.
- RSSI - Range of Received Signal Strength Indicator (RSSI) values (dBm)
Below is an example configuration of ADDRESS and RSSI filters. Note that the RSSI filter as an ID Filter value is a 2-element list.
# Settings for beacon scanner
scanner:
control_file: 'scanner_control' # Control file which stops beacon scanner before timeout
scan_prefix: 'pi_pact_scan' # Prefix to attach to scan output files
timeout: 20 # Scanning timeout (s)
revisit: 1 # Interval at which to scan (s)
filters: # Filters
ADDRESS: AA:BB:CC:DD:EE:FF
RSSI:
- -55
- 0An advertiser can be started in one of two primary modes concerning when and how to stop the advertiser. In either case, the user commanded stop is available.
In this mode, the advertiser will run infinitely until a user commanded stop is specified via the advertiser control file. The advertiser control file is specified either in the configuration YAML or overwritten by the command line argument.
- Start the advertiser. The addition of the
&flag causes the command to be executed in the background. This allows the user to retain control of the command line which makes commanding the advertiser to stop much easier.pi@raspberrypi:~ $ sudo python3 pi_pact.py -a --config_yml pi_pact_config.yml & [1] 2083
- Observe the informational log messages.
pi@raspberrypi:~ $ 2020-06-20 10:12:42,594 INFO Beacon advertiser mode selected. 2020-06-20 10:12:42,597 INFO Initialized beacon advertiser. 2020-06-20 10:12:42,599 INFO Starting beacon advertiser with timeout None.
- Stop the advertiser by placing any non-zero value into the advertiser control file.
pi@raspberrypi:~ $ echo 1 > advertiser_control pi@raspberrypi:~ $ 2020-06-20 10:12:58,623 INFO Stopping beacon advertiser.
In this mode, the advertiser will run either until the specified timeout or until a user commanded stop is specified via the advertiser control file. The advertiser control file is specified either in the configuration YAML or overwritten by the command line argument.
- Start the advertiser. The addition of the
&flag causes the command to be executed in the background. This allows the user to retain control of the command line which makes commanding the advertiser to stop much easier.pi@raspberrypi:~ $ sudo python3 pi_pact.py -a --config_yml pi_pact_config.yml --timeout 20 & [1] 2282
- Observe the informational log messages.
pi@raspberrypi:~ $ 2020-06-20 10:26:10,268 INFO Beacon advertiser mode selected. 2020-06-20 10:26:10,270 INFO Initialized beacon advertiser. 2020-06-20 10:26:10,273 INFO Starting beacon advertiser with timeout 20.0.
- Stop the advertiser either by waiting for the timeout
or by placing any non-zero value into the advertiser control file.
2020-06-20 10:26:30,301 INFO Stopping beacon advertiser.pi@raspberrypi:~ $ echo 1 > advertiser_control pi@raspberrypi:~ $ 2020-06-20 10:26:30,301 INFO Stopping beacon advertiser.
A scanner can be started in one of two primary modes concerning when and how to stop the scanner. In either case, the user commanded stop is available.
In this mode, the scanner will run infinitely until a user commanded stop is specified via the scanner control file. The scanner control file is specified either in the configuration YAML or overwritten by the command line argument.
- Start the scanner. The addition of the
&flag causes the command to be executed in the background. This allows the user to retain control of the command line which makes commanding the scanner to stop much easier.pi@raspberrypi:~ $ sudo python3 pi_pact.py -s --config pi_pact_config.yml & [1] 2083
- Observe the informational log messages.
pi@raspberrypi:~ $ 2020-06-20 10:12:42,594 INFO Beacon scanner mode selected. 2020-06-20 10:12:42,597 INFO Initialized beacon scanner. 2020-06-20 10:12:42,599 INFO Starting beacon scanner with timeout None.
- Stop the scanner by placing any non-zero value into the scanner control file.
pi@raspberrypi:~ $ echo 1 > scanner_control pi@raspberrypi:~ $ 2020-06-20 10:12:58,623 INFO Stopping beacon scanner.
In this mode, the scanner will run either until the specified timeout or until a user commanded stop is specified via the scanner control file. The scanner control file is specified either in the configuration YAML or overwritten by the command line argument.
- Start the scanner. The addition of the
&flag causes the command to be executed in the background. This allows the user to retain control of the command line which makes commanding the scanner to stop much easier.pi@raspberrypi:~ $ sudo python3 pi_pact.py -s --config pi_pact_config.yml --timeout 20 & [1] 2282
- Observe the informational log messages.
pi@raspberrypi:~ $ 2020-06-20 10:26:10,268 INFO Beacon scanner mode selected. 2020-06-20 10:26:10,270 INFO Initialized scanner advertiser. 2020-06-20 10:26:10,273 INFO Starting beacon scanner with timeout 20.0.
- Stop the advertiser either by waiting for the timeout
or by placing any non-zero value into the scanner control file.
2020-06-20 10:26:30,301 INFO Stopping beacon scanner.pi@raspberrypi:~ $ echo 1 > scanner_control pi@raspberrypi:~ $ 2020-06-20 10:26:30,301 INFO Stopping beacon scanner.
The only explicit output of this code are the published log messages (console and log file) and CSV files containing the beacons found by the beacon scanner. The default (and expected) format/headers of this CSV file are as follow.
- SCAN: The scan number during which this beacon advertisement was received.
- ADDRESS: The address of the beacon.
- TIMESTAMP: Timestamp (in beacon scanner device's time) at which this beacon advertisement was received.
- UUID: The UUID sent in beacon advertisement.
- MAJOR: The major value sent in beacon advertisement.
- MINOR: The minor value sent in beacon advertisement.
- TX POWER: The Tx power value sent in beacon advertisement.
- RSSI: The measured RSSI (dBm) of the received beacon advertisement.
- DISTANCE: The pre-measured distance (m) between the devices.
The following headers are only present if --use_sense_hat is set to True (enabled by default):
- TEMPERATURE: The temperature (degrees Celsius) measured using the humidity sensor.
- HUMIDITY: The percentage of relative humidity measured using the humidity sensor.
- PRESSURE: The pressure (millibars) measured using the pressure sensor.
- PITCH: The angle (degrees) measured using the aircraft principal axis of pitch.
- ROLL: The angle (degrees) measured using the aircraft principal axis of roll.
- YAW: The angle (degrees) measured using the aircraft principal axis of yaw.
The script pi_pact_repeat.py can be used to repeatedly execute pi_pact.py. This script can take the argument DISTANCE_INCREMENT (default value of 0) to automatically adjust the pre-measured distance with each run, although users should make sure they move the pis to their correct positions in between runs. Passing the argument WAIT_INTERVAL (default value of 60) can give the user more time to reposition the pis in between runs.
pi@raspberrypi:~ $ sudo python3 pi_pact_repeat.py --help
usage: pi_pact_repeat.py [-h] [--distance_increment DISTANCE_INCREMENT]
--distance DISTANCE --timeout TIMEOUT
[--wait_interval WAIT_INTERVAL]
(--distance_final DISTANCE_FINAL | --timeout_final TIMEOUT_FINAL | --iterations ITERATIONS)
(-a | -s) [--config_yml CONFIG_YML]
[--control_file CONTROL_FILE]
[--scan_prefix SCAN_PREFIX] [--uuid UUID]
[--major MAJOR] [--minor MINOR] [--tx_power TX_POWER]
[--interval INTERVAL] [--revist REVIST] [--use_sense_hat USE_SENSE_HAT]
Script to run pi_pact.py repeatedly with variable distance and interval
increments
optional arguments:
-h, --help show this help message and exit
--distance_increment DISTANCE_INCREMENT
The change in distance between runs (m).
--distance DISTANCE Initial pre-measured distance between the devices (m).
--timeout TIMEOUT Timeout (s) for both beacon advertiser and scanner
modes.
--wait_interval WAIT_INTERVAL
The wait in between runs (s).
--distance_final DISTANCE_FINAL
The final distance to run pi_pact.py on.
--timeout_final TIMEOUT_FINAL
The total timeout for this script (s).
--iterations ITERATIONS
The number of times to run pi_pact.py
-a, --advertiser Beacon advertiser mode.
-s, --scanner Beacon scanner mode.
--config_yml CONFIG_YML
Configuration YAML.
--control_file CONTROL_FILE
Control file.
--scan_prefix SCAN_PREFIX
Scan output file prefix.
--uuid UUID Beacon advertiser UUID.
--major MAJOR Beacon advertiser major value.
--minor MINOR Beacon advertiser minor value.
--tx_power TX_POWER Beacon advertiser TX power.
--interval INTERVAL Beacon advertiser interval (ms).
--revist REVIST Beacon scanner revisit interval (s)
--use_sense_hat USE_SENSE_HAT Toggles use of sense hat.