save temp basal to pod state

This commit is contained in:
Andrei Vereha 2021-06-05 18:14:13 +02:00
parent ffe3246fc0
commit fc919f24cd
4 changed files with 52 additions and 28 deletions

View file

@ -4,6 +4,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -39,7 +40,6 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.rxkotlin.blockingSubscribeBy
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
import org.json.JSONObject import org.json.JSONObject
import java.util.* import java.util.*
@ -140,7 +140,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
override fun setNewBasalProfile(profile: Profile): PumpEnactResult { override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
val basalProgram = mapProfileToBasalProgram(profile) val basalProgram = mapProfileToBasalProgram(profile)
return executeSimpleProgrammingCommand( return executeProgrammingCommand(
pre = suspendDeliveryIfActive(), pre = suspendDeliveryIfActive(),
historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE), historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE),
command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(), command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(),
@ -150,6 +150,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun failWhenUnconfirmed(): Completable = Completable.defer{ private fun failWhenUnconfirmed(): Completable = Completable.defer{
rxBus.send(EventTempBasalChange())
if (podStateManager.activeCommand != null) { if (podStateManager.activeCommand != null) {
Completable.error(java.lang.IllegalStateException("Command not confirmed")) Completable.error(java.lang.IllegalStateException("Command not confirmed"))
}else { }else {
@ -161,7 +162,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED) if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED)
Completable.complete() Completable.complete()
else else
executeSimpleProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
omnipodManager.suspendDelivery() omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent is PodEvent.CommandSent }
@ -172,6 +173,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
PodConstants.MAX_POD_LIFETIME.standardMinutes, PodConstants.MAX_POD_LIFETIME.standardMinutes,
PumpSync.TemporaryBasalType.PUMP_SUSPEND PumpSync.TemporaryBasalType.PUMP_SUSPEND
) )
rxBus.send(EventTempBasalChange())
} }
.ignoreElements(), .ignoreElements(),
) )
@ -274,7 +276,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
override fun stopBolusDelivering() { override fun stopBolusDelivering() {
// TODO update Treatments (?) // TODO update Treatments (?)
executeSimpleProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_BOLUS), history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
omnipodManager.stopBolus().ignoreElements() omnipodManager.stopBolus().ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
@ -288,8 +290,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
tbrType: PumpSync.TemporaryBasalType tbrType: PumpSync.TemporaryBasalType
): PumpEnactResult { ): PumpEnactResult {
val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false) val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false)
aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: $durationInMinutes min :: $absoluteRate U/h :: " +
return executeSimpleProgrammingCommand( "enforce: $enforceNew :: tbrType: $tbrType")
return executeProgrammingCommand(
historyEntry = history.createRecord( historyEntry = history.createRecord(
commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, commandType = OmnipodCommandType.SET_TEMPORARY_BASAL,
tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate)
@ -302,7 +305,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent is PodEvent.CommandSent }
.map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) } .map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) }
.ignoreElements(), .ignoreElements(),
pre = observeNoActiveTempBasal(enforceNew) pre = observeNoActiveTempBasal(enforceNew),
tempBasal = OmnipodDashPodStateManager.TempBasal(
startTime = System.currentTimeMillis(),
rate=absoluteRate,
durationInMinutes = durationInMinutes.toShort(),
)
).toPumpEnactResult() ).toPumpEnactResult()
} }
@ -356,7 +364,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
else -> { else -> {
// enforceNew == true // enforceNew == true
aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") aapsLogger.info(LTag.PUMP, "Canceling existing temp basal")
executeSimpleProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
omnipodManager.stopTempBasal().ignoreElements() omnipodManager.stopTempBasal().ignoreElements()
) )
@ -398,7 +406,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
return executeSimpleProgrammingCommand( return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
command = omnipodManager.stopTempBasal().ignoreElements(), command = omnipodManager.stopTempBasal().ignoreElements(),
pre = observeActiveTempBasal(), pre = observeActiveTempBasal(),
@ -526,7 +534,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun suspendDelivery(): PumpEnactResult { private fun suspendDelivery(): PumpEnactResult {
return executeSimpleProgrammingCommand( return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
command = omnipodManager.suspendDelivery() command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent is PodEvent.CommandSent }
@ -552,7 +560,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun resumeDelivery(): PumpEnactResult { private fun resumeDelivery(): PumpEnactResult {
return profileFunction.getProfile()?.let { return profileFunction.getProfile()?.let {
executeSimpleProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.RESUME_DELIVERY), history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements(), omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements(),
pre = observeDeliverySuspended(), pre = observeDeliverySuspended(),
@ -561,7 +569,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun deactivatePod(): PumpEnactResult { private fun deactivatePod(): PumpEnactResult {
return executeSimpleProgrammingCommand( return executeProgrammingCommand(
history.createRecord(OmnipodCommandType.DEACTIVATE_POD), history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
omnipodManager.deactivatePod().ignoreElements() omnipodManager.deactivatePod().ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
@ -578,7 +586,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun playTestBeep(): PumpEnactResult { private fun playTestBeep(): PumpEnactResult {
return executeSimpleProgrammingCommand( return executeProgrammingCommand(
history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP), history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements() omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
@ -605,19 +613,20 @@ class OmnipodDashPumpPlugin @Inject constructor(
commandQueue.customCommand(CommandHandleTimeChange(false), null) commandQueue.customCommand(CommandHandleTimeChange(false), null)
} }
private fun executeSimpleProgrammingCommand( private fun executeProgrammingCommand(
historyEntry: Single<String>, historyEntry: Single<String>,
command: Completable, command: Completable,
pre: Completable = Completable.complete(), pre: Completable = Completable.complete(),
basalProgram: BasalProgram? = null,
post: Completable = Completable.complete(), post: Completable = Completable.complete(),
basalProgram: BasalProgram? = null,
tempBasal: OmnipodDashPodStateManager.TempBasal? = null,
): Completable { ): Completable {
return Completable.concat( return Completable.concat(
listOf( listOf(
pre, pre,
podStateManager.observeNoActiveCommand().ignoreElements(), podStateManager.observeNoActiveCommand().ignoreElements(),
historyEntry historyEntry
.flatMap { podStateManager.createActiveCommand(it, basalProgram) } .flatMap { podStateManager.createActiveCommand(it, basalProgram, tempBasal) }
.ignoreElement(), .ignoreElement(),
command.doOnError { command.doOnError {
podStateManager.activeCommand?.sendError = it podStateManager.activeCommand?.sendError = it
@ -674,6 +683,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}") aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}")
if (!confirmation.success) { if (!confirmation.success) {
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) pumpSync.invalidateTemporaryBasal(historyEntry.pumpId())
} else {
podStateManager.tempBasal = command.tempBasal
} }
} }

View file

@ -58,7 +58,7 @@ interface OmnipodDashPodStateManager {
val minutesSinceActivation: Short? val minutesSinceActivation: Short?
val activeAlerts: EnumSet<AlertType>? val activeAlerts: EnumSet<AlertType>?
val tempBasal: TempBasal? var tempBasal: TempBasal?
val tempBasalActive: Boolean val tempBasalActive: Boolean
var basalProgram: BasalProgram? var basalProgram: BasalProgram?
val activeCommand: ActiveCommand? val activeCommand: ActiveCommand?
@ -73,7 +73,8 @@ interface OmnipodDashPodStateManager {
fun updateFromPairing(uniqueId: Id, pairResult: PairResult) fun updateFromPairing(uniqueId: Id, pairResult: PairResult)
fun reset() fun reset()
fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null): Single<ActiveCommand> fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null, tempBasal: TempBasal?=null):
Single<ActiveCommand>
fun updateActiveCommand(): Maybe<CommandConfirmed> fun updateActiveCommand(): Maybe<CommandConfirmed>
fun observeNoActiveCommand(): Observable<PodEvent> fun observeNoActiveCommand(): Observable<PodEvent>
fun getCommandConfirmationFromState(): CommandConfirmationFromState fun getCommandConfirmationFromState(): CommandConfirmationFromState
@ -84,7 +85,8 @@ interface OmnipodDashPodStateManager {
var sentRealtime: Long = 0, var sentRealtime: Long = 0,
val historyId: String, val historyId: String,
var sendError: Throwable?, var sendError: Throwable?,
var basalProgram: BasalProgram? var basalProgram: BasalProgram?,
val tempBasal: TempBasal?
) )
// TODO: set created to "now" on boot // TODO: set created to "now" on boot
data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable

View file

@ -137,15 +137,17 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val activeAlerts: EnumSet<AlertType>? override val activeAlerts: EnumSet<AlertType>?
get() = podState.activeAlerts get() = podState.activeAlerts
override val tempBasal: OmnipodDashPodStateManager.TempBasal? override var tempBasal: OmnipodDashPodStateManager.TempBasal?
get() = podState.tempBasal get() = podState.tempBasal
set(tempBasal) {
podState.tempBasal = tempBasal
store()
}
override val tempBasalActive: Boolean override val tempBasalActive: Boolean
get() = podState.deliveryStatus in get() = tempBasal?.let {
arrayOf( it.startTime + it.durationInMinutes *60 * 1000 > System.currentTimeMillis()
DeliveryStatus.TEMP_BASAL_ACTIVE, } ?: false
DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE
)
override var basalProgram: BasalProgram? override var basalProgram: BasalProgram?
get() = podState.basalProgram get() = podState.basalProgram
@ -188,7 +190,11 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
get() = podState.activeCommand get() = podState.activeCommand
@Synchronized @Synchronized
override fun createActiveCommand(historyId: String, basalProgram: BasalProgram?): override fun createActiveCommand(
historyId: String,
basalProgram: BasalProgram?,
tempBasal: OmnipodDashPodStateManager.TempBasal?
):
Single<OmnipodDashPodStateManager.ActiveCommand> { Single<OmnipodDashPodStateManager.ActiveCommand> {
return Single.create { source -> return Single.create { source ->
if (activeCommand == null) { if (activeCommand == null) {
@ -198,6 +204,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
historyId = historyId, historyId = historyId,
sendError = null, sendError = null,
basalProgram = basalProgram, basalProgram = basalProgram,
tempBasal = tempBasal,
) )
podState.activeCommand = command podState.activeCommand = command
source.onSuccess(command) source.onSuccess(command)

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.utils.ui.UIRunnable
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import org.joda.time.DateTime
import org.joda.time.Duration import org.joda.time.Duration
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -343,7 +344,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
) )
} }
podInfoBinding.podActiveAlerts.text = PLACEHOLDER podInfoBinding.podActiveAlerts.text = podStateManager.activeAlerts?.let {
it.map { it.toString() }.joinToString(",")
} ?: PLACEHOLDER
} }
if (errors.size == 0) { if (errors.size == 0) {
@ -503,7 +506,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
} }
private fun updateSilenceAlertsButton() { private fun updateSilenceAlertsButton() {
if (isAutomaticallySilenceAlertsEnabled() && podStateManager.isPodRunning && if (!isAutomaticallySilenceAlertsEnabled() &&
podStateManager.isPodRunning &&
( (
podStateManager.activeAlerts!!.size > 0 || podStateManager.activeAlerts!!.size > 0 ||
commandQueue.isCustomCommandInQueue(CommandSilenceAlerts::class.java) commandQueue.isCustomCommandInQueue(CommandSilenceAlerts::class.java)