Prioritize private payload for battery info in single headset devices

This commit modifies `SingleApplePods`, `AirPodsMaxUsbc`, and `AirPodsMax` to prioritize battery information from the decrypted private payload when available.

Specifically:
- `SingleApplePods.batteryHeadsetPercent`: Now checks `payload.private?.asBatteryState(1)?.level` first. If the private payload is not available or doesn't contain battery information at position 1, it falls back to the existing logic using `pubPodsBattery`.
- `AirPodsMaxUsbc.isHeadsetBeingCharged` and `AirPodsMax.isHeadsetBeingCharged`: Now check `payload.private?.asBatteryState(1)?.isCharging` first. If the private payload is not available or doesn't contain charging status at position 1, they fall back to the existing logic using `pubFlags.isBitSet(0)`.

This change allows for more accurate battery level and charging status reporting when the private payload can be decrypted.
This commit is contained in:
darken
2025-06-06 06:03:41 +02:00
committed by Matthias Urhahn
parent 5df809a492
commit e9b29a2a43
3 changed files with 24 additions and 9 deletions
@@ -10,13 +10,18 @@ import eu.darken.capod.pods.core.SinglePodDevice
interface SingleApplePods : ApplePods, SinglePodDevice, HasAppleColor {
override val batteryHeadsetPercent: Float?
get() = when (val value = pubPodsBattery.lowerNibble.toInt()) {
15 -> null
else -> if (value > 10) {
log { "Headset above 100% battery: $value" }
1.0f
} else {
(value / 10f)
get() {
payload.private?.asBatteryState(1)?.let {
return it.level
}
return when (val value = pubPodsBattery.lowerNibble.toInt()) {
15 -> null
else -> if (value > 10) {
log { "Headset above 100% battery: $value" }
1.0f
} else {
(value / 10f)
}
}
}
}
@@ -35,7 +35,12 @@ data class AirPodsMax(
get() = rssiAverage ?: super<SingleApplePods>.rssi
override val isHeadsetBeingCharged: Boolean
get() = pubFlags.isBitSet(0)
get() {
payload.private?.asBatteryState(1)?.let {
return it.isCharging
}
return pubFlags.isBitSet(0)
}
override val isBeingWorn: Boolean
get() = pubStatus.isBitSet(5)
@@ -35,7 +35,12 @@ data class AirPodsMaxUsbc(
get() = rssiAverage ?: super<SingleApplePods>.rssi
override val isHeadsetBeingCharged: Boolean
get() = pubFlags.isBitSet(0)
get() {
payload.private?.asBatteryState(1)?.let {
return it.isCharging
}
return pubFlags.isBitSet(0)
}
override val isBeingWorn: Boolean
get() = pubStatus.isBitSet(5)