feat(battery): Add a shared battery tier for level colours

The overview duplicates the same 30%/15% thresholds in four places, with two
subtly different unknown checks: the capsule and the pod gauge accept any
percent >= 0f, so Float.POSITIVE_INFINITY renders as a full, healthy ring.
batteryTier() settles that on the finite check the other two already use.
This commit is contained in:
darken
2026-08-25 22:33:42 +02:00
committed by Matthias Urhahn
parent fec512175b
commit 0f95538f39
2 changed files with 73 additions and 0 deletions
@@ -0,0 +1,23 @@
package eu.darken.capod.monitor.core.battery
/** Battery bands behind the overview's colour semantics. */
enum class BatteryTier {
UNKNOWN,
CRITICAL,
WARN,
GOOD,
}
/**
* Maps a battery fraction onto a [BatteryTier]. Only a finite, non-negative fraction has a level;
* anything else is [BatteryTier.UNKNOWN]. Values above 1 count as full.
*/
fun batteryTier(percent: Float): BatteryTier {
if (!percent.isFinite() || percent < 0f) return BatteryTier.UNKNOWN
val clamped = percent.coerceIn(0f, 1f)
return when {
clamped > 0.30f -> BatteryTier.GOOD
clamped >= 0.15f -> BatteryTier.WARN
else -> BatteryTier.CRITICAL
}
}
@@ -0,0 +1,50 @@
package eu.darken.capod.monitor.core.battery
import eu.darken.capod.pods.core.apple.ble.BATTERY_UNKNOWN
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
class BatteryTierTest : BaseTest() {
@Test
fun `unknown battery has no tier`() {
batteryTier(BATTERY_UNKNOWN) shouldBe BatteryTier.UNKNOWN
batteryTier(-0.01f) shouldBe BatteryTier.UNKNOWN
batteryTier(-100f) shouldBe BatteryTier.UNKNOWN
}
@Test
fun `non-finite values have no tier`() {
batteryTier(Float.NaN) shouldBe BatteryTier.UNKNOWN
batteryTier(Float.POSITIVE_INFINITY) shouldBe BatteryTier.UNKNOWN
batteryTier(Float.NEGATIVE_INFINITY) shouldBe BatteryTier.UNKNOWN
}
@Test
fun `values at and above full are good`() {
batteryTier(1f) shouldBe BatteryTier.GOOD
batteryTier(1.5f) shouldBe BatteryTier.GOOD
batteryTier(Float.MAX_VALUE) shouldBe BatteryTier.GOOD
}
@Test
fun `the good boundary is exclusive`() {
batteryTier(0.30f) shouldBe BatteryTier.WARN
batteryTier(0.30f + 0.0001f) shouldBe BatteryTier.GOOD
batteryTier(0.30f - 0.0001f) shouldBe BatteryTier.WARN
}
@Test
fun `the warn boundary is inclusive`() {
batteryTier(0.15f) shouldBe BatteryTier.WARN
batteryTier(0.15f + 0.0001f) shouldBe BatteryTier.WARN
batteryTier(0.15f - 0.0001f) shouldBe BatteryTier.CRITICAL
}
@Test
fun `an empty battery is critical`() {
batteryTier(0f) shouldBe BatteryTier.CRITICAL
batteryTier(0.05f) shouldBe BatteryTier.CRITICAL
}
}