Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/src/main/kotlin/app/aaps/implementations/ConfigImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ConfigImpl @Inject constructor(
private var ignoreNightscoutV3Errors: Boolean? = null
private var doNotSendSmsOnProfileChange: Boolean? = null
private var enableAutotune: Boolean? = null
private var enableOmnipodDriftCompensation: Boolean? = null
private var disableLeakCanary: Boolean? = null

override fun isEngineeringModeOrRelease(): Boolean = if (!APS) true else isEngineeringMode() || !isDev()
Expand All @@ -54,5 +55,6 @@ class ConfigImpl @Inject constructor(
override fun ignoreNightscoutV3Errors(): Boolean = ignoreNightscoutV3Errors ?: (fileListProvider.get().ensureExtraDirExists()?.findFile("ignore_nightscout_v3_errors") != null).also { ignoreNightscoutV3Errors = it }
override fun doNotSendSmsOnProfileChange(): Boolean = doNotSendSmsOnProfileChange ?: (fileListProvider.get().ensureExtraDirExists()?.findFile("do_not_send_sms_on_profile_change") != null).also { doNotSendSmsOnProfileChange = it }
override fun enableAutotune(): Boolean = enableAutotune ?: (fileListProvider.get().ensureExtraDirExists()?.findFile("enable_autotune") != null).also { enableAutotune = it }
override fun enableOmnipodDriftCompensation(): Boolean = enableOmnipodDriftCompensation ?: (fileListProvider.get().ensureExtraDirExists()?.findFile("omnipod_drift_compensation") != null).also { enableOmnipodDriftCompensation = it }
override fun disableLeakCanary(): Boolean = disableLeakCanary ?: (fileListProvider.get().ensureExtraDirExists()?.findFile("disable_leakcanary") != null).also { disableLeakCanary = it }
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface Config {
fun ignoreNightscoutV3Errors(): Boolean
fun doNotSendSmsOnProfileChange(): Boolean
fun enableAutotune(): Boolean
fun enableOmnipodDriftCompensation(): Boolean

/**
* Disable LeakCanary (memory leaks detection). By default it's enabled in DEBUG builds.
Expand Down
2 changes: 2 additions & 0 deletions pump/omnipod/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dependencies {
api(libs.androidx.navigation.fragment)
api(libs.com.google.android.material)

testImplementation(project(":shared:tests"))

ksp(libs.com.google.dagger.compiler)
ksp(libs.com.google.dagger.android.processor)
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ interface OmnipodDashPodStateManager {

fun updateLowReservoirAlertSettings(lowReservoirAlertEnabled: Boolean, lowReservoirAlertUnits: Int): Completable

var lastBasalCorrectionTime: Long?
var basalCorrectionInProgress: Boolean
fun needsBasalCorrection(): Boolean

data class ActiveCommand(
val sequence: Short,
val createdRealtime: Long,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package app.aaps.pump.omnipod.common.queue.command

import app.aaps.core.interfaces.queue.CustomCommand

class CommandDeliverBasalCorrection : CustomCommand {

override val statusDescription = "BASAL COMPENSATION BOLUS"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package app.aaps.pump.omnipod.common.bledriver.pod.state

import app.aaps.core.interfaces.configuration.Config
import app.aaps.core.keys.interfaces.Preferences
import app.aaps.shared.tests.TestBase
import com.google.common.truth.Truth.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock

/**
* Tests for [OmnipodDashPodStateManagerImpl.calculateBolusPulseIncrease].
*
* This function decides how many of the newly delivered pulses should be attributed to the
* active bolus vs. basal. Key scenarios:
* - No bolus in progress → all pulses attributed to bolus tracker (caller uses them for total)
* - Normal bolus delivery → total increase matches expected bolus decrease exactly
* - Concurrent basal delivery → total increase > bolus decrease, capped to bolus portion
* - Anomaly (fewer total pulses than expected) → returns actual increase and logs warning
*/
class CalculateBolusPulseIncreaseTest : TestBase() {

@Mock lateinit var preferences: Preferences
@Mock lateinit var config: Config

private lateinit var sut: OmnipodDashPodStateManagerImpl

@BeforeEach fun setUp() {
sut = OmnipodDashPodStateManagerImpl(aapsLogger, rxBus, preferences, config)
}

// ---- helpers ------------------------------------------------------------------------------

private fun increase(
prevTotal: Int,
newTotal: Int,
prevBolusPulsesRemaining: Int?,
newBolusPulsesRemaining: Int
): Short = sut.calculateBolusPulseIncrease(
previousTotalPulses = prevTotal.toShort(),
newTotalPulses = newTotal.toShort(),
previousBolusPulsesRemaining = prevBolusPulsesRemaining?.toShort(),
newBolusPulsesRemaining = newBolusPulsesRemaining.toShort()
)

// ---- no previous bolus tracking -----------------------------------------------------------

@Test fun `no previous tracking — full pulse increase returned`() {
// previousBolusPulsesRemaining = null means we have no reference point;
// return raw increase so the caller can record it
assertThat(increase(100, 103, null, 0)).isEqualTo(3.toShort())
}

@Test fun `no previous tracking, zero increase — returns zero`() {
assertThat(increase(100, 100, null, 0)).isEqualTo(0.toShort())
}

// ---- normal bolus delivery ----------------------------------------------------------------

@Test fun `normal bolus delivery — increase matches expected bolus decrease`() {
// 3 total pulses, 3 bolus pulses remaining → 0 now: clean match
assertThat(increase(100, 103, 3, 0)).isEqualTo(3.toShort())
}

@Test fun `bolus still in progress — partial delivery tracked correctly`() {
// 1 total pulse added, bolus remaining went from 2 → 1: expected 1 bolus pulse
assertThat(increase(100, 101, 2, 1)).isEqualTo(1.toShort())
}

@Test fun `zero increase during active bolus — returns zero`() {
assertThat(increase(100, 100, 3, 3)).isEqualTo(0.toShort())
}

// ---- concurrent basal delivery ------------------------------------------------------------

@Test fun `concurrent basal — total increase capped to bolus portion`() {
// 5 total pulses added, but bolus only accounted for 3 → 2 were basal corrections
// Result must be capped at 3 to avoid over-attributing to bolus
assertThat(increase(100, 105, 3, 0)).isEqualTo(3.toShort())
}

@Test fun `concurrent basal, partial bolus remaining — capped correctly`() {
// 4 total pulses, bolus remaining went 3 → 1 (2 bolus pulses expected), 2 basal
assertThat(increase(100, 104, 3, 1)).isEqualTo(2.toShort())
}

// ---- anomaly (total < expected) -----------------------------------------------------------

@Test fun `anomaly — fewer total pulses than expected bolus decrease — returns actual increase`() {
// Bolus remaining went 3 → 0 (expected 3), but only 2 total pulses added.
// We return the actual increase (2) and log a warning — do not over-attribute.
assertThat(increase(100, 102, 3, 0)).isEqualTo(2.toShort())
}
}
Loading
Loading