iOS SBeacon Framework Driving Behavior - scopetech/Mobile-Public GitHub Wiki
Driving Behavior
iOS SBeacon Framework v1.0.8
This guide covers driving behavior event detection, configuration, and data retrieval from SBeacon devices.
Overview
SBeacon devices can detect harsh driving events including acceleration, braking, cornering, and accidents. Events are stored in beacon memory (up to 80 events) and can be retrieved, configured, and cleared via BLE.
Prerequisites
- Beacon Pairing - Beacon must be paired
- Calibration - CRITICAL: Beacon MUST be calibrated for accurate detection
Event Types
DrivingBehaviorEventType Enum
public enum DrivingBehaviorEventType: UInt8 {
case acceleration = 4 // Harsh acceleration (forward)
case braking = 5 // Harsh braking (deceleration)
case cornering = 6 // Harsh cornering (lateral)
case accident = 8 // Collision/impact
}
Detection Axes:
- Acceleration/Braking: Y-axis (longitudinal, forward/backward)
- Cornering: X-axis (lateral, side-to-side)
- Accident: Any axis (resultant magnitude)
DrivingBehaviorEvent Model
public struct DrivingBehaviorEvent {
let index: UInt8 // Record index (0-79)
let eventType: DrivingBehaviorEventType
let timestamp: UInt32 // Beacon timestamp (seconds)
let duration: UInt16 // Event duration (milliseconds)
let avgMagnitude: Float // Average G-force
let maxMagnitude: Float // Maximum G-force
let avgX: Float // Average X-axis (G)
let avgY: Float // Average Y-axis (G)
let avgZ: Float // Average Z-axis (G)
var actualTimestamp: Int64? // Real-world time (ms)
var actualDate: Date? // Computed date
var durationSeconds: TimeInterval // Duration in seconds
}
Retrieving Driving Behavior Events
Request All Events
import BLEFramework
func fetchDrivingBehaviorEvents(for beacon: SCPBeacon) {
// Set callback
SBeaconManager.shared.drivingBehaviorEventsReceived = { [weak self] events in
print("Received \(events.count) driving behavior events")
self?.processDrivingBehaviorEvents(events)
}
// Request events
SBeaconManager.shared.requestDrivingBehaviorEvents(beacon: beacon)
}
private func processDrivingBehaviorEvents(_ events: [DrivingBehaviorEvent]) {
for event in events {
guard let date = event.actualDate else { continue }
print("Event \(event.index): \(event.eventType.description)")
print(" Date: \(date)")
print(" Max G-force: \(String(format: "%.2f", event.maxMagnitude))G")
print(" Duration: \(event.duration)ms")
print(" Axis values: X=\(event.avgX), Y=\(event.avgY), Z=\(event.avgZ)")
// Upload to server
uploadEvent(event)
}
}
Clearing Events
Clear Specific Event
// Clear event at index 5
SBeaconManager.shared.clearDrivingBehaviorEvent(index: 5, beacon: beacon)
Clear All Events
// Clear all stored events from beacon memory
SBeaconManager.shared.clearAllDrivingBehaviorEvents(beacon: beacon)
Best Practice: Clear events after successfully uploading to server to free beacon memory.
Real-Time Event Detection
Real-Time Callback
Events detected during active trips trigger instant notifications:
SBeaconManager.shared.realTimeDrivingBehaviorEventDetected = { [weak self] event in
print("REAL-TIME EVENT: \(event.eventType.description)")
print("Axis: \(event.axis.description)")
// Show alert, play sound, update UI, etc.
self?.handleRealTimeEvent(event)
}
RealTimeDrivingBehaviorEvent Model
public struct RealTimeDrivingBehaviorEvent {
let eventType: DrivingBehaviorEventType
let axis: DrivingBehaviorAxis // x, y, z, or radial
let flags: UInt8 // Additional flags
}
Configuration
Detection Thresholds
G-Force Thresholds
Configure sensitivity for each event type:
| Event Type | Range (mG) | Range (G) | Default |
|---|---|---|---|
| Cornering | 50 - 5000 | 0.05 - 5.0 | 300 mG (0.3G) |
| Braking | 50 - 5000 | 0.05 - 5.0 | 400 mG (0.4G) |
| Acceleration | 50 - 5000 | 0.05 - 5.0 | 350 mG (0.35G) |
Unit: Milli-G (1000 mG = 1 G)
Duration Threshold
Minimum event duration to record:
- Range: 1 - 10000 milliseconds
- Default: 500 ms
- Purpose: Filter out brief vibrations/bumps
Set Individual Thresholds
// Set cornering threshold to 300 mG (0.3G)
SBeaconManager.shared.setCorneringThreshold(300, beacon: beacon)
// Set braking threshold to 400 mG (0.4G)
SBeaconManager.shared.setBrakingThreshold(400, beacon: beacon)
// Set acceleration threshold to 350 mG (0.35G)
SBeaconManager.shared.setAccelerationThreshold(350, beacon: beacon)
// Set minimum duration to 500 ms
SBeaconManager.shared.setDurationThreshold(500, beacon: beacon)
Batch Configuration
Apply complete configuration at once:
import BLEFramework
let config = DrivingBehaviorConfig(
corneringThreshold: 300, // 0.3G
brakingThreshold: 400, // 0.4G
accelerationThreshold: 350, // 0.35G
durationThreshold: 500, // 500ms
enableFlagsValue: DrivingBehaviorConfig.enableAllValue
)
SBeaconManager.shared.applyDrivingBehaviorConfig(config, beacon: beacon)
Enable/Disable Detection
// Enable all driving behavior detection
SBeaconManager.shared.enableDrivingBehavior(true, beacon: beacon)
// Disable all driving behavior detection
SBeaconManager.shared.enableDrivingBehavior(false, beacon: beacon)
Read Current Configuration
// Read enable flags
SBeaconManager.shared.drivingBehaviorEnableFlagsReceived = { enableFlags in
print("Cornering enabled: \(enableFlags.corneringEnabled)")
print("Braking enabled: \(enableFlags.brakingEnabled)")
print("Acceleration enabled: \(enableFlags.accelerationEnabled)")
}
SBeaconManager.shared.readDrivingBehaviorEnableFlags(beacon: beacon)
// Read individual thresholds
SBeaconManager.shared.readCorneringThreshold(beacon: beacon)
SBeaconManager.shared.readBrakingThreshold(beacon: beacon)
SBeaconManager.shared.readAccelerationThreshold(beacon: beacon)
SBeaconManager.shared.readDurationThreshold(beacon: beacon)
Complete Example
import SwiftUI
import BLEFramework
class DrivingBehaviorViewModel: ObservableObject {
@Published var events: [DrivingBehaviorEvent] = []
@Published var corneringThreshold: UInt16 = 300
@Published var brakingThreshold: UInt16 = 400
@Published var accelerationThreshold: UInt16 = 350
@Published var isEnabled = false
private let beacon: SCPBeacon
init(beacon: SCPBeacon) {
self.beacon = beacon
setupCallbacks()
}
func setupCallbacks() {
SBeaconManager.shared.drivingBehaviorEventsReceived = { [weak self] events in
self?.events = events
}
SBeaconManager.shared.realTimeDrivingBehaviorEventDetected = { [weak self] event in
self?.handleRealTimeEvent(event)
}
SBeaconManager.shared.drivingBehaviorEnableFlagsReceived = { [weak self] enableFlags in
self?.isEnabled = enableFlags.enabled
}
}
func fetchEvents() {
SBeaconManager.shared.requestDrivingBehaviorEvents(beacon: beacon)
}
func clearAllEvents() {
SBeaconManager.shared.clearAllDrivingBehaviorEvents(beacon: beacon)
events.removeAll()
}
func applyConfiguration() {
let config = DrivingBehaviorConfig(
corneringThreshold: corneringThreshold,
brakingThreshold: brakingThreshold,
accelerationThreshold: accelerationThreshold,
durationThreshold: 500,
enableFlagsValue: isEnabled ? DrivingBehaviorConfig.enableAllValue : 0
)
SBeaconManager.shared.applyDrivingBehaviorConfig(config, beacon: beacon)
}
func toggleEnabled() {
isEnabled.toggle()
SBeaconManager.shared.enableDrivingBehavior(isEnabled, beacon: beacon)
}
private func handleRealTimeEvent(_ event: RealTimeDrivingBehaviorEvent) {
// Show notification, play sound, etc.
print("REAL-TIME: \(event.eventType.description) on \(event.axis.description)")
}
deinit {
SBeaconManager.shared.drivingBehaviorEventsReceived = nil
SBeaconManager.shared.realTimeDrivingBehaviorEventDetected = nil
SBeaconManager.shared.drivingBehaviorEnableFlagsReceived = nil
}
}
Best Practices
- Always Calibrate First: Uncalibrated beacons produce inaccurate G-force readings
- Set Appropriate Thresholds: Too sensitive = false positives, too high = missed events
- Clear After Upload: Free beacon memory by clearing synced events
- Handle Real-Time Events: Provide immediate feedback to drivers
- Batch Configuration: Use
applyDrivingBehaviorConfig()for multiple settings - Validate Thresholds: Framework validates range (50-5000 mG)
- Monitor Battery: Frequent event detection drains battery faster
Troubleshooting
No Events Detected
Solutions:
- Ensure beacon is calibrated (
beacon.isCalibrated == true) - Check detection is enabled
- Verify thresholds aren't too high
- Confirm beacon is mounted correctly in vehicle
Inaccurate G-Force Values
Solutions:
- Recalibrate beacon on flat surface
- Check beacon mounting orientation (ISO8855 standard)
- Verify beacon isn't loose/vibrating
Events Not Retrieved
Solutions:
- Check beacon is connected
- Verify
drivingBehaviorEventsReceivedcallback is set - Ensure beacon has events (check count first)
Related Pages
- Calibration - Required before using driving behavior
- Trip Management - Events occur during trips
- Data Models - DrivingBehaviorEvent structure
- API Reference - Complete method list