Average RSSI

This commit is contained in:
darken
2022-01-26 01:02:21 +01:00
parent 07b3f4320e
commit cde3afdcd9
14 changed files with 96 additions and 69 deletions
@@ -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
)