Skip to content

Android SBeacon Framework Data Models

AigarsM edited this page Jan 27, 2026 · 3 revisions

Data Models

This page documents all data model classes used by the SBeacon SDK.


Trip Models

TripStatus

Represents the current state of a trip.

enum class TripStatus {
    IDLE,       // No trip in progress
    START,      // Trip is starting
    ACTIVE,     // Trip is in progress
    END,        // Trip has ended
    TIMEOUT,    // Trip timed out due to inactivity
    UNKNOWN     // Status could not be determined
}

TripRecord

Represents a completed trip stored on the beacon.

@Parcelize
data class TripRecord(
    val recordIndex: Int,        // Buffer index (0-99)
    val startTimestamp: Long,    // Unix timestamp (milliseconds)
    val endTimestamp: Long,      // Unix timestamp (milliseconds)
    val beaconMacAddress: String // Source beacon MAC
) : Parcelable {

    // Computed properties
    val durationMs: Long         // Trip duration in milliseconds
    val durationSeconds: Long    // Trip duration in seconds

    // Validation
    fun isValid(): Boolean       // true if endTimestamp > startTimestamp && startTimestamp > 0
}

Example:

val trip = TripRecord(
    recordIndex = 5,
    startTimestamp = 1704067200000,  // 2024-01-01 00:00:00
    endTimestamp = 1704070800000,    // 2024-01-01 01:00:00
    beaconMacAddress = "AA:BB:CC:DD:EE:FF"
)

println("Duration: ${trip.durationSeconds / 60} minutes")  // 60 minutes
println("Valid: ${trip.isValid()}")  // true

TripInformation

Contains trip status and pending sync counts.

data class TripInformation(
    val status: TripStatus,
    val unsyncedTripCount: Int,             // Trips pending upload
    val unsyncedIncidentCount: Int,         // Incidents pending upload
    val unsyncedDrivingBehaviorCount: Int   // DB events pending upload
)

Driving Behavior Models

DrivingBehaviorType

Enumeration of harsh driving event types.

@Parcelize
enum class DrivingBehaviorType(val rawValue: Int) : Parcelable {
    HARSH_ACCELERATION(4),  // Rapid speed increase
    HARSH_BRAKING(5),       // Rapid deceleration
    HARSH_CORNERING(6),     // Sharp turn
    ACCIDENT(8)             // Collision detected

    companion object {
        fun fromRawValue(value: Int): DrivingBehaviorType?
    }
}

DrivingBehaviorEvent

Detailed driving behavior event from beacon storage.

@Parcelize
data class DrivingBehaviorEvent(
    val recordIndex: Int,              // Buffer index (0-79)
    val eventType: DrivingBehaviorType,
    val timestamp: Long,               // Unix timestamp (milliseconds)
    val durationMs: Int,               // Event duration (milliseconds)
    val averageMagnitude: Float,       // Average G-force magnitude
    val maxMagnitude: Float,           // Peak G-force magnitude
    val averageX: Float,               // Lateral G-force
    val averageY: Float,               // Longitudinal G-force
    val averageZ: Float,               // Vertical G-force
    val beaconMacAddress: String       // Source beacon MAC
) : Parcelable
Property Description Unit
recordIndex Position in circular buffer 0-79
eventType Classification of event Enum
timestamp When event occurred Milliseconds since epoch
durationMs How long event lasted Milliseconds
averageMagnitude Average total G-force g (gravitational units)
maxMagnitude Peak total G-force g
averageX Average lateral force g (positive = right)
averageY Average longitudinal force g (positive = forward)
averageZ Average vertical force g (positive = up)

Example:

val event = DrivingBehaviorEvent(
    recordIndex = 12,
    eventType = DrivingBehaviorType.HARSH_BRAKING,
    timestamp = 1704067200000,
    durationMs = 1500,
    averageMagnitude = 0.52f,
    maxMagnitude = 0.78f,
    averageX = 0.05f,
    averageY = -0.51f,  // Negative = deceleration
    averageZ = 0.02f,
    beaconMacAddress = "AA:BB:CC:DD:EE:FF"
)

println("Braking event: ${event.maxMagnitude}g peak for ${event.durationMs}ms")

DrivingBehaviorConfig

Configuration for driving behavior detection.

@Parcelize
data class DrivingBehaviorConfig(
    val enabled: Boolean = false,
    val highPassFilterEnabled: Boolean = true,
    val lowPassFilterEnabled: Boolean = true,
    val corneringThreshold: Int = 450,     // milli-Gs
    val brakingThreshold: Int = 400,       // milli-Gs
    val accelerationThreshold: Int = 250,  // milli-Gs
    val durationThreshold: Int = 500       // milliseconds
) : Parcelable {

    // Serialization
    fun toConfigByte(): Int              // Convert to FDS byte format

    // Validation
    fun isValid(): Boolean               // Validate all thresholds

    // Convenience
    fun withAllFiltersEnabled(): DrivingBehaviorConfig

    companion object {
        // Constants
        const val ENABLE_DB_BIT = 0x01   // Bit 0: Enable feature
        const val ENABLE_HP_BIT = 0x02   // Bit 1: High-pass filter
        const val ENABLE_LP_BIT = 0x04   // Bit 2: Low-pass filter

        const val MIN_THRESHOLD = 50     // 0.05g
        const val MAX_THRESHOLD = 5000   // 5g
        const val MIN_DURATION = 1       // 1ms
        const val MAX_DURATION = 10000   // 10 seconds

        // Factory methods
        fun fromConfigByte(configByte: Int): DrivingBehaviorConfig
        fun enabledDefault(): DrivingBehaviorConfig
        fun disabled(): DrivingBehaviorConfig

        // Validation helpers
        fun isValidThreshold(value: Int): Boolean
        fun isValidDurationThreshold(value: Int): Boolean
    }
}

Example:

// Create custom configuration
val config = DrivingBehaviorConfig(
    enabled = true,
    highPassFilterEnabled = true,
    lowPassFilterEnabled = true,
    corneringThreshold = 500,      // More sensitive (0.5g)
    brakingThreshold = 350,        // More sensitive (0.35g)
    accelerationThreshold = 300,   // Less sensitive (0.3g)
    durationThreshold = 400        // Shorter duration (400ms)
)

if (config.isValid()) {
    bleManager.writeDrivingBehaviorConfig(beaconMac, config)
}

Incident Models

IncidentRecord

Represents a collision/accident event.

@Parcelize
data class IncidentRecord(
    var id: Int = 0,
    var timestamp: Long = 0L,                    // Device timestamp
    var actualIncidentTimestamp: Long = 0L,      // Adjusted timestamp
    var samples: Int = 0,                        // Number of accelerometer samples
    var vectorValues: ArrayList<Vector> = ArrayList(),  // Raw sample data
    var averageVector: Vector = Vector(),        // Average acceleration
    var averageResultantVector: Long = 0L,       // Average magnitude
    var maximumResultantVector: Long = 0L        // Peak magnitude
) : Parcelable

Vector

3D acceleration vector for incident data.

@Parcelize
data class Vector(
    var x: Int = 0,  // Lateral acceleration
    var y: Int = 0,  // Longitudinal acceleration
    var z: Int = 0   // Vertical acceleration
) : Parcelable

Example:

val incident = IncidentRecord(
    id = 1,
    timestamp = 1704067200000,
    samples = 50,
    averageVector = Vector(x = 100, y = -2500, z = 150),
    maximumResultantVector = 3200  // 3.2g peak
)

println("Collision detected: ${incident.maximumResultantVector / 1000.0}g peak")

Beacon Models

ScopeBeacon

Main beacon entity stored in local database.

@Entity(tableName = "scopeBeacons")
data class ScopeBeacon(
    @PrimaryKey var id: Int,
    var name: String,
    var macAddress: String,
    var UUId: String,
    var majorId: Int,
    var minorId: Int,
    var paired: Boolean = false,
    var isCalibrated: Boolean = false,
    var isSBeacon: Boolean = true,
    var tripStatus: TripStatus = TripStatus.UNKNOWN,
    var lastTimeUpdated: Long = 0L,
    var lastTimeScanned: Long = 0L,
    var lastFirmwareUpdate: Long = 0L,
    var latitude: Double = 0.0,
    var longitude: Double = 0.0,
    var range: Double = 0.0,
    var batteryVoltage: Float = 0f,
    var lastBatteryUpdate: Long = 0L,
    var sBeaconTimestampStart: Long = 0L,
    var subscriptionId: Int,
    var subscriptionUnitSerialNumber: String,
    var timeAddressUpdated: Long = 0L,
    var lastAddress: String = ""
) {
    fun isInRange(): Boolean
}
Property Description
id Unique identifier
name Display name
macAddress Bluetooth MAC address
UUId iBeacon UUID
majorId iBeacon major ID
minorId iBeacon minor ID
paired Whether beacon is paired
isCalibrated Whether accelerometer is calibrated
tripStatus Current trip status
batteryVoltage Last known battery voltage
subscriptionId Associated subscription ID
subscriptionUnitSerialNumber Vehicle serial number

Real-Time Event Models

DrivingBehaviorEventType (Internal)

Event type identifiers for real-time notifications.

enum class DrivingBehaviorEventType(val id: Int) {
    ACCIDENT(0xAAB1),
    RECKLESS_CORNERING(0xAAB2),
    HARSH_BRAKING(0xAAB3),
    HARSH_ACCELERATION(0xAAB4)

    fun toSharedType(): DrivingBehaviorType
}

AccelerometerAxis

Axis identifier for real-time events.

enum class AccelerometerAxis(val char: Char, val hex: Int) {
    X('X', 0x58),  // Lateral
    Y('Y', 0x59),  // Longitudinal
    Z('Z', 0x5A),  // Vertical
    R('R', 0x52)   // Radial (magnitude)
}

DrivingBehaviorStateFlags

Bitmask flags for accelerometer state.

data class DrivingBehaviorStateFlags(
    val accidentX: Boolean = false,      // Bit 0
    val accidentY: Boolean = false,      // Bit 1
    val accidentZ: Boolean = false,      // Bit 2
    val braking: Boolean = false,        // Bit 3
    val acceleration: Boolean = false,   // Bit 4
    val cornering: Boolean = false,      // Bit 5
    val harshBraking: Boolean = false,   // Bit 6
    val harshAcceleration: Boolean = false  // Bit 7
)

RealTimeDrivingBehaviorEvent (Internal)

Internal model for real-time notification parsing.

data class RealTimeDrivingBehaviorEvent(
    val eventType: DrivingBehaviorEventType,
    val axis: AccelerometerAxis,
    val stateFlags: DrivingBehaviorStateFlags,
    val timestamp: Long = System.currentTimeMillis()
)

Utility Classes

SBeaconByteBuffer

Helper for parsing beacon BLE responses.

class SBeaconByteBuffer internal constructor(data: ByteArray) {
    fun getByte(): Int          // Read unsigned byte
    fun getShort(): Int         // Read unsigned 16-bit little-endian
    fun getSignedShort(): Int   // Read signed 16-bit little-endian
    fun getInt(): Int           // Read unsigned 32-bit little-endian
    fun length(): Int           // Total buffer length
    fun remaining(): Int        // Bytes remaining
    fun skip(count: Int)        // Skip bytes
}

Type Conversions

G-Force Conversions

// milli-Gs to g
val gForce = milliGs / 1000.0f

// g to milli-Gs
val milliGs = (gForce * 1000).toInt()

// Examples
450 mG = 0.45g  // Cornering threshold
400 mG = 0.40g  // Braking threshold
250 mG = 0.25g  // Acceleration threshold

Timestamp Conversions

// Beacon timestamp to device timestamp
val deviceTimestamp = beaconTimestamp + beacon.sBeaconTimestampStart

// To Date object
val date = Date(deviceTimestamp)

// To formatted string
val formatted = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
    .format(date)

Related Pages

Clone this wiki locally