feat: Add BLE device support for 6 new Beats models

Solo Pro (0x0C20), Solo 4 (0x2520), Solo Buds (0x2620), Studio Buds (0x1120), Studio Buds+ (0x1620), Studio Pro (0x1720). Tests use handcrafted data pending real captures.
This commit is contained in:
darken
2026-03-31 19:17:09 +02:00
committed by Matthias Urhahn
parent c860ecc430
commit f65c6e4a29
13 changed files with 618 additions and 0 deletions
@@ -0,0 +1,20 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsSolo4Test : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsSolo4`() = runTest {
create<BeatsSolo4>("07 19 01 25 20 62 04 80 01 0F 40 0D 70 50 16 F2 40 83 16 BF 10 16 34 9B 74 84 E8") {
pubDeviceModel shouldBe 0x2520.toUShort()
batteryHeadsetPercent shouldBe 0.4f
model shouldBe PodModel.BEATS_SOLO_4
}
}
}
@@ -0,0 +1,21 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsSoloBudsTest : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsSoloBuds`() = runTest {
create<BeatsSoloBuds>("07 19 01 26 20 20 FA 8F 01 00 24 9B 9B 23 52 60 5A 8C 32 1C A5 C2 81 51 82 AF C8") {
pubDeviceModel shouldBe 0x2620.toUShort()
batteryLeftPodPercent shouldBe 1.0f
batteryRightPodPercent shouldBe null
model shouldBe PodModel.BEATS_SOLO_BUDS
}
}
}
@@ -0,0 +1,20 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsSoloProTest : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsSoloPro`() = runTest {
create<BeatsSoloPro>("07 19 01 0C 20 62 04 80 01 0F 40 0D 70 50 16 F2 40 83 16 BF 10 16 34 9B 74 84 E8") {
pubDeviceModel shouldBe 0x0C20.toUShort()
batteryHeadsetPercent shouldBe 0.4f
model shouldBe PodModel.BEATS_SOLO_PRO
}
}
}
@@ -0,0 +1,21 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsStudioBudsPlusTest : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsStudioBudsPlus`() = runTest {
create<BeatsStudioBudsPlus>("07 19 01 16 20 20 FA 8F 01 00 24 9B 9B 23 52 60 5A 8C 32 1C A5 C2 81 51 82 AF C8") {
pubDeviceModel shouldBe 0x1620.toUShort()
batteryLeftPodPercent shouldBe 1.0f
batteryRightPodPercent shouldBe null
model shouldBe PodModel.BEATS_STUDIO_BUDS_PLUS
}
}
}
@@ -0,0 +1,21 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsStudioBudsTest : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsStudioBuds`() = runTest {
create<BeatsStudioBuds>("07 19 01 11 20 20 FA 8F 01 00 24 9B 9B 23 52 60 5A 8C 32 1C A5 C2 81 51 82 AF C8") {
pubDeviceModel shouldBe 0x1120.toUShort()
batteryLeftPodPercent shouldBe 1.0f
batteryRightPodPercent shouldBe null
model shouldBe PodModel.BEATS_STUDIO_BUDS
}
}
}
@@ -0,0 +1,20 @@
package eu.darken.capod.pods.core.apple.ble.devices.beats
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.pods.core.apple.ble.devices.BaseBlePodsTest
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class BeatsStudioProTest : BaseBlePodsTest() {
// TODO Replace with real device data
@Test
fun `default BeatsStudioPro`() = runTest {
create<BeatsStudioPro>("07 19 01 17 20 62 04 80 01 0F 40 0D 70 50 16 F2 40 83 16 BF 10 16 34 9B 74 84 E8") {
pubDeviceModel shouldBe 0x1720.toUShort()
batteryHeadsetPercent shouldBe 0.4f
model shouldBe PodModel.BEATS_STUDIO_PRO
}
}
}