diff --git a/pump/combov2/comboctl/build.gradle b/pump/combov2/comboctl/build.gradle
index ba5ea343da..645f764f7c 100644
--- a/pump/combov2/comboctl/build.gradle
+++ b/pump/combov2/comboctl/build.gradle
@@ -1,8 +1,14 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+plugins {
+ id 'com.android.library'
+ id 'kotlin-android'
+ id 'kotlin-kapt'
+ id 'com.hiya.jacoco-android'
+}
apply from: "${project.rootDir}/core/main/android_dependencies.gradle"
+apply from: "${project.rootDir}/core/main/android_module_dependencies.gradle"
apply from: "${project.rootDir}/core/main/test_dependencies.gradle"
+apply from: "${project.rootDir}/core/main/jacoco_global.gradle"
android {
namespace 'info.nightscout.comboctl'
diff --git a/pump/combov2/comboctl/src/commonMain/kotlin/info/nightscout/comboctl/main/Pump.kt b/pump/combov2/comboctl/src/commonMain/kotlin/info/nightscout/comboctl/main/Pump.kt
index 0507cfe41b..745e23276c 100644
--- a/pump/combov2/comboctl/src/commonMain/kotlin/info/nightscout/comboctl/main/Pump.kt
+++ b/pump/combov2/comboctl/src/commonMain/kotlin/info/nightscout/comboctl/main/Pump.kt
@@ -1166,6 +1166,19 @@ class Pump(
*/
val setTbrProgressFlow = setTbrProgressReporter.progressFlow
+ /**
+ * Detail about the outcome of a successful [setTbr] call.
+ *
+ * Note that all of these describe a success. In case of failure,
+ * [setTbr] throws an exception.
+ */
+ enum class SetTbrOutcome {
+ SET_NORMAL_TBR,
+ SET_EMULATED_100_TBR,
+ LETTING_EMULATED_100_TBR_FINISH,
+ IGNORED_REDUNDANT_100_TBR
+ }
+
/**
* Sets the Combo's current temporary basal rate (TBR) via the remote terminal (RT) mode.
*
@@ -1199,6 +1212,9 @@ class Pump(
* via the [onEvent] callback. Likewise, when a TBR finishes or is cancelled,
* [Event.TbrEnded] is emitted.
*
+ * When this function finishes successfully, it informs about the exact
+ * outcome through its return value.
+ *
* @param percentage TBR percentage to set.
* @param durationInMinutes TBR duration in minutes to set.
* This argument is not used if [percentage] is 100.
@@ -1209,6 +1225,7 @@ class Pump(
* cancelling an ongoing TBR, which produces a W6 warning) or to fake a
* 100% TBR by setting 90% / 110% TBRs (see above).
* This argument is only used if [percentage] is 100.
+ * @return The specific outcome if setting the TBR succeeds.
* @throws IllegalArgumentException if the percentage is not in the 0-500 range,
* or if the percentage value is not an integer multiple of 10, or if
* the duration is <15 or not an integer multiple of 15 (see the note
@@ -1244,6 +1261,7 @@ class Pump(
val currentStatus = statusFlow.value ?: throw IllegalStateException("Cannot start TBR without a known pump status")
var expectedTbrPercentage: Int
var expectedTbrDuration: Int
+ val result: SetTbrOutcome
// In the code below, we always create a Tbr object _before_ calling
// setCurrentTbr to make use of the checks in the Tbr constructor.
@@ -1258,6 +1276,20 @@ class Pump(
reportOngoingTbrAsStopped()
expectedTbrPercentage = 100
expectedTbrDuration = 0
+ result = SetTbrOutcome.SET_NORMAL_TBR
+ } else if ((currentStatus.tbrPercentage in 90..110) && (currentStatus.remainingTbrDurationInMinutes <= 15)) {
+ // If the current TBR is in the 90-110% range, it is pretty much a fake 100% TBR.
+ // So, if that fake TBR is done within 15 minutes, we don't actually set anything.
+ // Instead, we just let it run. That way, the pump can actually reach 100% TBR,
+ // and the amount of TBR adjustments is reduced.
+ expectedTbrPercentage = currentStatus.tbrPercentage
+ expectedTbrDuration = currentStatus.remainingTbrDurationInMinutes
+ result = SetTbrOutcome.LETTING_EMULATED_100_TBR_FINISH
+ logger(LogLevel.INFO) {
+ "Current TBR percentage is in the 90-110% range (${currentStatus.tbrPercentage}%)," +
+ "and it will finish in ${currentStatus.remainingTbrDurationInMinutes} minute(s); " +
+ "letting it finish and faking a successful TBR set operation"
+ }
} else {
val newPercentage = if (currentStatus.tbrPercentage < 100) 110 else 90
val tbr = Tbr(
@@ -1270,6 +1302,7 @@ class Pump(
reportStartedTbr(tbr)
expectedTbrPercentage = newPercentage
expectedTbrDuration = 15
+ result = SetTbrOutcome.SET_EMULATED_100_TBR
}
} else {
// Current status shows that there is no TBR ongoing. This is
@@ -1278,6 +1311,7 @@ class Pump(
expectedTbrPercentage = 100
expectedTbrDuration = 0
logger(LogLevel.INFO) { "TBR was already cancelled" }
+ result = SetTbrOutcome.IGNORED_REDUNDANT_100_TBR
}
} else {
val tbr = Tbr(
@@ -1291,6 +1325,7 @@ class Pump(
reportStartedTbr(tbr)
expectedTbrPercentage = percentage
expectedTbrDuration = durationInMinutes
+ result = SetTbrOutcome.SET_NORMAL_TBR
}
// We just set the TBR. Now check the main screen contents to see if
@@ -1314,9 +1349,12 @@ class Pump(
throw ExtendedOrMultiwaveBolusActiveException(mainScreenContent)
is MainScreenContent.Normal -> {
- if (expectedTbrPercentage != 100) {
+ if ((expectedTbrPercentage != 100) && (expectedTbrDuration >= 2)) {
// We expected a TBR to be active, but there isn't any;
// we aren't seen any TBR main screen contents.
+ // Only consider this an error if the duration is >2 minutes.
+ // Otherwise, this was a TBR that was about to end, so it
+ // might have ended while these checks here were running.
throw UnexpectedTbrStateException(
expectedTbrPercentage = expectedTbrPercentage,
expectedTbrDuration = expectedTbrDuration,
@@ -1349,6 +1387,8 @@ class Pump(
}
}
}
+
+ return@executeCommand result
}
/**
diff --git a/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt b/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt
index b2e19253db..6a71eef58a 100644
--- a/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt
+++ b/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt
@@ -1091,17 +1091,34 @@ class ComboV2Plugin @Inject constructor (
return pumpEnactResult
}
- private fun setTbrInternal(percentage: Int, durationInMinutes: Int, tbrType: ComboCtlTbr.Type, force100Percent: Boolean, pumpEnactResult: PumpEnactResult) {
+ private fun setTbrInternal(
+ percentage: Int,
+ durationInMinutes: Int,
+ tbrType: ComboCtlTbr.Type,
+ force100Percent: Boolean,
+ pumpEnactResult: PumpEnactResult
+ ) {
runBlocking {
try {
executeCommand {
- pump!!.setTbr(percentage, durationInMinutes, tbrType, force100Percent)
- }
+ val setTbrOutcome = pump!!.setTbr(percentage, durationInMinutes, tbrType, force100Percent)
- pumpEnactResult.apply {
- success = true
- enacted = true
- comment = rh.gs(R.string.combov2_setting_tbr_succeeded)
+ val tbrComment = when (setTbrOutcome) {
+ ComboCtlPump.SetTbrOutcome.SET_NORMAL_TBR ->
+ rh.gs(R.string.combov2_setting_tbr_succeeded)
+ ComboCtlPump.SetTbrOutcome.SET_EMULATED_100_TBR ->
+ rh.gs(R.string.combov2_set_emulated_100_tbr)
+ ComboCtlPump.SetTbrOutcome.LETTING_EMULATED_100_TBR_FINISH ->
+ rh.gs(R.string.combov2_letting_emulated_100_tbr_finish)
+ ComboCtlPump.SetTbrOutcome.IGNORED_REDUNDANT_100_TBR ->
+ rh.gs(R.string.combov2_ignoring_redundant_100_tbr)
+ }
+
+ pumpEnactResult.apply {
+ success = true
+ enacted = true
+ comment = tbrComment
+ }
}
} catch (e: QuantityNotChangingException) {
aapsLogger.error(LTag.PUMP, "TBR percentage adjustment hit a limit: $e")
diff --git a/pump/combov2/src/main/res/values/strings.xml b/pump/combov2/src/main/res/values/strings.xml
index 0e0516736b..ca0047ff78 100644
--- a/pump/combov2/src/main/res/values/strings.xml
+++ b/pump/combov2/src/main/res/values/strings.xml
@@ -107,6 +107,9 @@ buttons at the same time to cancel pairing)\n
Pump reservoir level is low
Setting TBR succeeded
Setting TBR failed
+ Set emulated 100% TBR
+ Letting ongoing emulated 100% TBR finish
+ Ignoring redundant 100% TBR request
Unexpected limit encountered while adjusting TBR: target percentage was %1$d%%, hit a limit at %1$d%%
Cannot set absolute TBR if base basal rate is zero
Pair AndroidAPS and Android with a currently unpaired Accu-Chek Combo pump