mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Average RSSI
This commit is contained in:
@@ -20,8 +20,10 @@ interface PodDevice {
|
||||
|
||||
val scanResult: BleScanResult
|
||||
|
||||
val rssiHistory: List<Int>
|
||||
|
||||
val rssi: Int
|
||||
get() = scanResult.rssi
|
||||
get() = rssiHistory.sum() / rssiHistory.size
|
||||
|
||||
/**
|
||||
* This is not correct but it works ¯\_(ツ)_/¯
|
||||
|
||||
@@ -67,6 +67,7 @@ interface ApplePods : PodDevice {
|
||||
val identifier: PodDevice.Id,
|
||||
val scanResult: BleScanResult,
|
||||
val message: ProximityPairing.Message,
|
||||
val rssiHistory: List<Int> = emptyList()
|
||||
) {
|
||||
val address: String
|
||||
get() = scanResult.address
|
||||
@@ -85,46 +86,46 @@ interface ApplePods : PodDevice {
|
||||
|
||||
private val knownDevs = mutableMapOf<PodDevice.Id, KnownDevice>()
|
||||
|
||||
internal fun recognizeDevice(scanResult: BleScanResult, message: ProximityPairing.Message): PodDevice.Id {
|
||||
internal fun recognizeDevice(scanResult: BleScanResult, message: ProximityPairing.Message): KnownDevice {
|
||||
val address = scanResult.address
|
||||
|
||||
var identifier: PodDevice.Id? = null
|
||||
var recognizedDevice: KnownDevice? = knownDevs.values
|
||||
.firstOrNull { it.address == address }
|
||||
?.also { log(tag, VERBOSE) { "recognizeDevice: Recovered previous ID via address: $it" } }
|
||||
|
||||
knownDevs.values.firstOrNull { it.address == address }?.let {
|
||||
log(tag, VERBOSE) { "recognizeDevice: Recovered previous ID via address: $it" }
|
||||
knownDevs[it.identifier] = it.copy(
|
||||
scanResult = scanResult,
|
||||
message = message,
|
||||
)
|
||||
identifier = it.identifier
|
||||
}
|
||||
|
||||
if (identifier == null) {
|
||||
if (recognizedDevice == null) {
|
||||
val currentMarkers = message.getRecogMarkers()
|
||||
knownDevs.values
|
||||
recognizedDevice = knownDevs.values
|
||||
.firstOrNull { it.message.getRecogMarkers() == currentMarkers }
|
||||
?.let {
|
||||
?.also {
|
||||
log(tag, DEBUG) { "recognizeDevice: Close match based similarity markers." }
|
||||
log(tag, DEBUG) { "recognizeDevice: Old marker: ${it.message.getRecogMarkers()}" }
|
||||
log(tag, DEBUG) { "recognizeDevice: New marker: $currentMarkers" }
|
||||
knownDevs[it.identifier] = it.copy(
|
||||
scanResult = scanResult,
|
||||
message = message,
|
||||
)
|
||||
identifier = it.identifier
|
||||
}
|
||||
}
|
||||
|
||||
if (identifier == null) {
|
||||
recognizedDevice = if (recognizedDevice == null) {
|
||||
log(tag, VERBOSE) { "recognizeDevice: Mapping as new device" }
|
||||
identifier = PodDevice.Id()
|
||||
KnownDevice(
|
||||
identifier = PodDevice.Id(),
|
||||
scanResult = scanResult,
|
||||
message = message,
|
||||
rssiHistory = listOf(scanResult.rssi)
|
||||
)
|
||||
} else {
|
||||
recognizedDevice.copy(
|
||||
scanResult = scanResult,
|
||||
message = message,
|
||||
rssiHistory = recognizedDevice.rssiHistory
|
||||
.toMutableList()
|
||||
.let {
|
||||
if (it.size > 2) it.removeAt(0)
|
||||
it.plus(scanResult.rssi)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
knownDevs[identifier!!] = KnownDevice(
|
||||
identifier = identifier!!,
|
||||
scanResult = scanResult,
|
||||
message = message
|
||||
)
|
||||
knownDevs[recognizedDevice.identifier] = recognizedDevice
|
||||
|
||||
knownDevs.values.toList().forEach { knownDevice ->
|
||||
if (knownDevice.isOlderThan(Duration.ofSeconds(20))) {
|
||||
@@ -133,7 +134,7 @@ interface ApplePods : PodDevice {
|
||||
}
|
||||
}
|
||||
|
||||
return identifier!!
|
||||
return recognizedDevice
|
||||
}
|
||||
|
||||
data class ModelInfo(
|
||||
|
||||
@@ -13,7 +13,8 @@ data class UnknownAppleDevice(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>
|
||||
) : ApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.UNKNOWN
|
||||
@@ -27,12 +28,13 @@ data class UnknownAppleDevice(
|
||||
scanResult: BleScanResult,
|
||||
proximityMessage: ProximityPairing.Message,
|
||||
): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return UnknownAppleDevice(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ data class AirPodsGen1 constructor(
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
private val cachedBatteryPercentage: Float?
|
||||
private val cachedBatteryPercentage: Float?,
|
||||
override val rssiHistory: List<Int>
|
||||
) : DualApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN1
|
||||
@@ -28,16 +29,17 @@ data class AirPodsGen1 constructor(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
val device = AirPodsGen1(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
cachedBatteryPercentage = cachedValues[identifier]?.caseBatteryPercentage
|
||||
cachedBatteryPercentage = cachedValues[recognized.identifier]?.caseBatteryPercentage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
|
||||
cachedValues[identifier] = ValueCache(
|
||||
cachedValues[recognized.identifier] = ValueCache(
|
||||
caseBatteryPercentage = device.batteryCasePercent
|
||||
)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ data class AirPodsGen2 constructor(
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
private val cachedBatteryPercentage: Float?,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : DualApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN2
|
||||
@@ -28,16 +29,17 @@ data class AirPodsGen2 constructor(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
val device = AirPodsGen2(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
cachedBatteryPercentage = cachedValues[identifier]?.caseBatteryPercentage
|
||||
cachedBatteryPercentage = cachedValues[recognized.identifier]?.caseBatteryPercentage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
|
||||
cachedValues[identifier] = ValueCache(
|
||||
cachedValues[recognized.identifier] = ValueCache(
|
||||
caseBatteryPercentage = device.batteryCasePercent
|
||||
)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ data class AirPodsGen3 constructor(
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
private val cachedBatteryPercentage: Float?,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : DualApplePods {
|
||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN3
|
||||
|
||||
@@ -27,16 +28,17 @@ data class AirPodsGen3 constructor(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
val device = AirPodsGen3(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
cachedBatteryPercentage = cachedValues[identifier]?.caseBatteryPercentage
|
||||
cachedBatteryPercentage = cachedValues[recognized.identifier]?.caseBatteryPercentage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
|
||||
cachedValues[identifier] = ValueCache(
|
||||
cachedValues[recognized.identifier] = ValueCache(
|
||||
caseBatteryPercentage = device.batteryCasePercent
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ data class AirPodsMax(
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : SingleApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX
|
||||
@@ -24,12 +25,13 @@ data class AirPodsMax(
|
||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return AirPodsMax(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ data class AirPodsPro(
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
private val cachedBatteryPercentage: Float?,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : DualApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO
|
||||
@@ -28,16 +29,17 @@ data class AirPodsPro(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
val device = AirPodsPro(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
cachedBatteryPercentage = cachedValues[identifier]?.caseBatteryPercentage
|
||||
cachedBatteryPercentage = cachedValues[recognized.identifier]?.caseBatteryPercentage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
|
||||
cachedValues[identifier] = ValueCache(
|
||||
cachedValues[recognized.identifier] = ValueCache(
|
||||
caseBatteryPercentage = device.batteryCasePercent
|
||||
)
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ data class BeatsFlex(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : BasicSingleApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_FLEX
|
||||
@@ -24,12 +25,13 @@ data class BeatsFlex(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return BeatsFlex(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ data class BeatsSolo3(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : BasicSingleApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_SOLO_3
|
||||
@@ -24,12 +25,13 @@ data class BeatsSolo3(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return BeatsSolo3(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ data class BeatsStudio3(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : BasicSingleApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_STUDIO_3
|
||||
@@ -24,12 +25,13 @@ data class BeatsStudio3(
|
||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return BeatsStudio3(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ data class BeatsX(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : BasicSingleApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_X
|
||||
@@ -24,12 +25,13 @@ data class BeatsX(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return BeatsX(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ data class PowerBeats3(
|
||||
override val identifier: PodDevice.Id = PodDevice.Id(),
|
||||
override val lastSeenAt: Instant = Instant.now(),
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : BasicSingleApplePods {
|
||||
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_3
|
||||
|
||||
@@ -23,12 +24,13 @@ data class PowerBeats3(
|
||||
proximityMessage.getModelInfo().full == DEVICE_CODE
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
return PowerBeats3(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ data class PowerBeatsPro(
|
||||
override val scanResult: BleScanResult,
|
||||
override val proximityMessage: ProximityPairing.Message,
|
||||
private val cachedBatteryPercentage: Float?,
|
||||
override val rssiHistory: List<Int>,
|
||||
) : DualApplePods {
|
||||
|
||||
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_PRO
|
||||
@@ -28,16 +29,17 @@ data class PowerBeatsPro(
|
||||
proximityMessage.getModelInfo().dirty == DEVICE_CODE_DIRTY
|
||||
|
||||
override fun create(scanResult: BleScanResult, proximityMessage: ProximityPairing.Message): ApplePods {
|
||||
val identifier = recognizeDevice(scanResult, proximityMessage)
|
||||
val recognized = recognizeDevice(scanResult, proximityMessage)
|
||||
|
||||
val device = PowerBeatsPro(
|
||||
identifier = identifier,
|
||||
identifier = recognized.identifier,
|
||||
scanResult = scanResult,
|
||||
proximityMessage = proximityMessage,
|
||||
cachedBatteryPercentage = cachedValues[identifier]?.caseBatteryPercentage
|
||||
cachedBatteryPercentage = cachedValues[recognized.identifier]?.caseBatteryPercentage,
|
||||
rssiHistory = recognized.rssiHistory,
|
||||
)
|
||||
|
||||
cachedValues[identifier] = ValueCache(
|
||||
cachedValues[recognized.identifier] = ValueCache(
|
||||
caseBatteryPercentage = device.batteryCasePercent
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user