add notifications

This commit is contained in:
Andrei Vereha 2021-06-22 22:27:29 +02:00
parent 3ebfe1b268
commit e51d071181
2 changed files with 121 additions and 27 deletions

View file

@ -130,7 +130,6 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun getPumpStatus(reason: String) { override fun getPumpStatus(reason: String) {
val throwable = getPodStatus().blockingGet() val throwable = getPodStatus().blockingGet()
if (throwable != null) { if (throwable != null) {
aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable) aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable)
@ -183,6 +182,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, "syncBolusWithPumpId on CANCEL_BOLUS returned: $sync") aapsLogger.info(LTag.PUMP, "syncBolusWithPumpId on CANCEL_BOLUS returned: $sync")
} }
} }
showNotification(
Notification.OMNIPOD_POD_FAULT,
podStateManager.alarmType.toString(),
Notification.URGENT,
R.raw.boluserror
)
} }
Completable.complete() Completable.complete()
} }
@ -192,20 +197,42 @@ class OmnipodDashPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(true).enacted(true) return PumpEnactResult(injector).success(true).enacted(true)
} }
val basalProgram = mapProfileToBasalProgram(profile) val basalProgram = mapProfileToBasalProgram(profile)
var deliverySuspended = false
return executeProgrammingCommand( return executeProgrammingCommand(
pre = suspendDeliveryIfActive(), pre = suspendDeliveryIfActive().doOnComplete {
if (podStateManager.activeCommand == null) {
// suspend delivery is confirmed
deliverySuspended = true
} },
historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE), historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE),
activeCommandEntry = { historyId -> activeCommandEntry = { historyId ->
podStateManager.createActiveCommand(historyId, basalProgram = basalProgram) podStateManager.createActiveCommand(historyId, basalProgram = basalProgram)
}, },
command = omnipodManager.setBasalProgram(basalProgram, hasBasalBeepEnabled()).ignoreElements(), command = omnipodManager.setBasalProgram(basalProgram, hasBasalBeepEnabled()).ignoreElements(),
post = failWhenUnconfirmed(), post = failWhenUnconfirmed(deliverySuspended), // mark as failed even if it worked OK and try again vs. mark ok and
// deny later
).toPumpEnactResult() ).toPumpEnactResult()
} }
private fun failWhenUnconfirmed(): Completable = Completable.defer { private fun failWhenUnconfirmed(deliverySuspended: Boolean): Completable = Completable.defer {
rxBus.send(EventTempBasalChange()) rxBus.send(EventTempBasalChange())
if (podStateManager.activeCommand != null) { if (podStateManager.activeCommand != null) {
if (deliverySuspended) {
showNotification(
Notification.FAILED_UPDATE_PROFILE,
"Failed to set the new basal profile. Delivery suspended",
Notification.URGENT,
R.raw.boluserror
)
} else {
showNotification(
Notification.FAILED_UPDATE_PROFILE,
"Setting basal profile might have failed. Delivery might be suspended!" +
" Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.",
Notification.URGENT,
R.raw.boluserror
)
}
Completable.error(java.lang.IllegalStateException("Command not confirmed")) Completable.error(java.lang.IllegalStateException("Command not confirmed"))
} else { } else {
Completable.complete() Completable.complete()
@ -229,8 +256,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
rxBus.send(EventTempBasalChange()) rxBus.send(EventTempBasalChange())
} }
.ignoreElements() .ignoreElements()
).doFinally {
notifyOnUnconfirmed(
Notification.FAILED_UPDATE_PROFILE,
"Suspend delivery is unconfirmed! " +
"Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.",
R.raw.boluserror,
) )
} }
}
/* override fun onStop() { /* override fun onStop() {
super.onStop() super.onStop()
@ -351,7 +385,23 @@ class OmnipodDashPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, "deliverTreatment: deliveredBolusAmount=$deliveredBolusAmount") aapsLogger.info(LTag.PUMP, "deliverTreatment: deliveredBolusAmount=$deliveredBolusAmount")
} }
.ignoreElement() .ignoreElement()
).toSingleDefault( ).doFinally {
if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) {
notifyOnUnconfirmed(
Notification.OMNIPOD_UNCERTAIN_SMB,
"Unable to verify whether SMB bolus (${requestedBolusAmount} U) succeeded. " +
"<b>Refresh pod status to confirm or deny this command.",
R.raw.boluserror
)
} else {
if (podStateManager.activeCommand != null) {
showErrorDialog(
"Bolus delivery status uncertain. Refresh pod status to confirm or deny.",
R.raw.boluserror
)
}
}
}.toSingleDefault(
PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(deliveredBolusAmount) PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(deliveredBolusAmount)
) )
.onErrorReturnItem( .onErrorReturnItem(
@ -510,8 +560,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
val tempBasalBeeps = hasTempBasalBeepEnabled() val tempBasalBeeps = hasTempBasalBeepEnabled()
aapsLogger.info( aapsLogger.info(
LTag.PUMP, LTag.PUMP,
"setTempBasalAbsolute: duration=$durationInMinutes min, rate=$absoluteRate U/h :: " + "setTempBasalAbsolute: " +
"enforce=$enforceNew, tbrType=$tbrType" "duration=$durationInMinutes min :: " +
"rate=$absoluteRate U/h :: " +
"enforce=$enforceNew ::" +
"tbrType=$tbrType"
) )
val ret = executeProgrammingCommand( val ret = executeProgrammingCommand(
@ -538,7 +591,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
.filter { podEvent -> podEvent.isCommandSent() } .filter { podEvent -> podEvent.isCommandSent() }
.map { pumpSyncTempBasal(absoluteRate, durationInMinutes.toLong(), tbrType) } .map { pumpSyncTempBasal(absoluteRate, durationInMinutes.toLong(), tbrType) }
.ignoreElements(), .ignoreElements(),
).toPumpEnactResult() ).doOnComplete {
notifyOnUnconfirmed(
Notification.OMNIPOD_TBR_ALERTS,
"Setting temp basal might have basal failed. If a temp basal was previously running, " +
"it has been cancelled. Please manually refresh the Pod status from the Omnipod tab.",
R.raw.boluserror,
)
}.toPumpEnactResult()
if (ret.success && ret.enacted) { if (ret.success && ret.enacted) {
ret.isPercent(false).absolute(absoluteRate).duration(durationInMinutes) ret.isPercent(false).absolute(absoluteRate).duration(durationInMinutes)
} }
@ -600,11 +661,18 @@ class OmnipodDashPumpPlugin @Inject constructor(
executeProgrammingCommand( executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements() command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements()
).doFinally {
notifyOnUnconfirmed(
Notification.OMNIPOD_TBR_ALERTS,
"Setting temp basal failed. If a temp basal was previously running, it might have been cancelled. " +
"Please manually refresh the Pod status from the Omnipod tab.", // TODO: i8n
R.raw.boluserror,
) )
} }
} }
} }
} }
}
override fun setTempBasalPercent( override fun setTempBasalPercent(
percent: Int, percent: Int,
@ -640,20 +708,22 @@ class OmnipodDashPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(true).enacted(false) return PumpEnactResult(injector).success(true).enacted(false)
} }
val ret = executeProgrammingCommand( return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements(), command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements(),
).doOnComplete { ).doOnComplete{
if (podStateManager.activeCommand != null) { notifyOnUnconfirmed(
showNotification(
Notification.OMNIPOD_TBR_ALERTS, Notification.OMNIPOD_TBR_ALERTS,
"Cancel temp basal result is uncertain", // TODO: localisation "Cancel temp basal result is uncertain", // TODO: i8n,
Notification.URGENT,
R.raw.boluserror, // TODO: add setting for this R.raw.boluserror, // TODO: add setting for this
) )
}
}.toPumpEnactResult() }.toPumpEnactResult()
return ret }
private fun notifyOnUnconfirmed(notificationId: Int, msg: String, sound: Int?) {
if (podStateManager.activeCommand != null) {
showNotification(notificationId, msg, Notification.URGENT, sound)
}
} }
private fun Completable.toPumpEnactResult(): PumpEnactResult { private fun Completable.toPumpEnactResult(): PumpEnactResult {
@ -770,7 +840,13 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
.ignoreElements(), .ignoreElements(),
pre = observeDeliveryActive(), pre = observeDeliveryActive(),
).toPumpEnactResult() ).doFinally {
notifyOnUnconfirmed(
Notification.PUMP_ERROR,
"Unconfirmed suspendDelivery command. Please refresh pod status",
R.raw.boluserror
)
}.toPumpEnactResult()
} }
private fun observeDeliveryActive(): Completable = Completable.defer { private fun observeDeliveryActive(): Completable = Completable.defer {
@ -787,7 +863,13 @@ class OmnipodDashPumpPlugin @Inject constructor(
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY), historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it), hasBasalBeepEnabled()) command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it), hasBasalBeepEnabled())
.ignoreElements() .ignoreElements()
).toPumpEnactResult() ).doFinally{
notifyOnUnconfirmed(
Notification.PUMP_ERROR,
"Unconfirmed resumeDelivery command. Please refresh pod status",
R.raw.boluserror
)
}.toPumpEnactResult()
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n
} }
@ -795,7 +877,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
val ret = executeProgrammingCommand( val ret = executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD), historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
command = omnipodManager.deactivatePod().ignoreElements() command = omnipodManager.deactivatePod().ignoreElements()
).toPumpEnactResult() ).doOnComplete{
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_FAULT))
}.toPumpEnactResult()
if (podStateManager.activeCommand != null) { if (podStateManager.activeCommand != null) {
ret.success(false) ret.success(false)
} }
@ -876,7 +961,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation") aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation")
when (historyEntry.commandType) { when (historyEntry.commandType) {
OmnipodCommandType.CANCEL_TEMPORARY_BASAL, OmnipodCommandType.CANCEL_TEMPORARY_BASAL,
OmnipodCommandType.RESUME_DELIVERY -> OmnipodCommandType.RESUME_DELIVERY -> {
// We can't invalidate this command, // We can't invalidate this command,
// and this is why it is pumpSync-ed at this point // and this is why it is pumpSync-ed at this point
if (confirmation.success) { if (confirmation.success) {
@ -888,6 +973,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
) )
podStateManager.tempBasal = null podStateManager.tempBasal = null
} }
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
}
OmnipodCommandType.SET_BASAL_PROFILE -> { OmnipodCommandType.SET_BASAL_PROFILE -> {
if (confirmation.success) { if (confirmation.success) {
@ -906,6 +993,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
serialNumber() serialNumber()
) )
} }
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
} }
OmnipodCommandType.SET_TEMPORARY_BASAL -> { OmnipodCommandType.SET_TEMPORARY_BASAL -> {
@ -920,6 +1008,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
} else { } else {
podStateManager.tempBasal = command.tempBasal podStateManager.tempBasal = command.tempBasal
} }
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
} }
OmnipodCommandType.SUSPEND_DELIVERY -> { OmnipodCommandType.SUSPEND_DELIVERY -> {
@ -964,17 +1053,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
type = null // TODO: set the correct bolus type here!!! type = null // TODO: set the correct bolus type here!!!
) )
} }
rxBus.send(EventDismissNotification(Notification.OMNIPOD_UNCERTAIN_SMB))
} }
OmnipodCommandType.CANCEL_BOLUS -> { OmnipodCommandType.CANCEL_BOLUS -> {
if (confirmation.success) { if (confirmation.success) {
podStateManager.lastBolus?.run { podStateManager.lastBolus?.run {
val deliveredUnits = markComplete() val deliveredUnits = markComplete()
val bolusHistoryEntry = history.getById(historyId) val bolusHistoryEntry = history.getById(historyId)
val sync = pumpSync.syncBolusWithPumpId( val sync = pumpSync.syncBolusWithPumpId(
timestamp = bolusHistoryEntry.createdAt, timestamp = bolusHistoryEntry.createdAt,
amount = deliveredUnits, // we just marked this bolus as complete amount = deliveredUnits,
pumpId = bolusHistoryEntry.pumpId(), pumpId = bolusHistoryEntry.pumpId(),
pumpType = PumpType.OMNIPOD_DASH, pumpType = PumpType.OMNIPOD_DASH,
pumpSerial = serialNumber(), pumpSerial = serialNumber(),

View file

@ -5,6 +5,9 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.omnipod.common.R import info.nightscout.androidaps.plugins.pump.omnipod.common.R
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.CommandDeactivatePod
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action.DeactivatePodViewModel import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.deactivation.viewmodel.action.DeactivatePodViewModel
@ -16,6 +19,7 @@ import javax.inject.Inject
class DashDeactivatePodViewModel @Inject constructor( class DashDeactivatePodViewModel @Inject constructor(
private val podStateManager: OmnipodDashPodStateManager, private val podStateManager: OmnipodDashPodStateManager,
private val commandQueueProvider: CommandQueueProvider, private val commandQueueProvider: CommandQueueProvider,
private val rxBus: RxBusWrapper,
injector: HasAndroidInjector, injector: HasAndroidInjector,
logger: AAPSLogger logger: AAPSLogger
) : DeactivatePodViewModel(injector, logger) { ) : DeactivatePodViewModel(injector, logger) {
@ -33,6 +37,7 @@ class DashDeactivatePodViewModel @Inject constructor(
override fun discardPod() { override fun discardPod() {
podStateManager.reset() podStateManager.reset()
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_FAULT))
} }
@StringRes @StringRes