Merge pull request #50 from 0pen-dash/avereha/notifications
Avereha/notifications
This commit is contained in:
commit
7c1c621cc7
13 changed files with 460 additions and 128 deletions
|
@ -1,6 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity.Companion.runAlarm
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||
|
@ -12,12 +16,15 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|||
import info.nightscout.androidaps.plugins.common.ManufacturerType
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.*
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
|
||||
|
@ -36,7 +43,6 @@ import info.nightscout.androidaps.queue.commands.CustomCommand
|
|||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.TimeChangeType
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
|
@ -56,11 +62,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
private val history: DashHistory,
|
||||
private val pumpSync: PumpSync,
|
||||
private val rxBus: RxBusWrapper,
|
||||
private val aapsSchedulers: AapsSchedulers,
|
||||
private val bleManager: OmnipodDashBleManager,
|
||||
|
||||
// private val disposable: CompositeDisposable = CompositeDisposable(),
|
||||
// private val aapsSchedulers: AapsSchedulers,
|
||||
private val context: Context,
|
||||
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
|
@ -68,10 +70,14 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
commandQueue: CommandQueueProvider
|
||||
) : PumpPluginBase(pluginDescription, injector, aapsLogger, resourceHelper, commandQueue), Pump {
|
||||
@Volatile var bolusCanceled = false
|
||||
private val handler: Handler = Handler(Looper.getMainLooper())
|
||||
lateinit private var statusChecker: Runnable
|
||||
var nextPodWarningCheck : Long = 0
|
||||
|
||||
companion object {
|
||||
private const val BOLUS_RETRY_INTERVAL_MS = 2000.toLong()
|
||||
private const val BOLUS_RETRIES = 5 // numer of retries for cancel/get bolus status
|
||||
private const val BOLUS_RETRIES = 5 // number of retries for cancel/get bolus status
|
||||
private const val STATUS_CHECK_INTERVAL_MS = (60L * 1000)
|
||||
|
||||
private val pluginDescription = PluginDescription()
|
||||
.mainType(PluginType.PUMP)
|
||||
|
@ -85,6 +91,52 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
private val pumpDescription = PumpDescription(PumpType.OMNIPOD_DASH)
|
||||
}
|
||||
|
||||
init {
|
||||
statusChecker = Runnable {
|
||||
refreshStatusOnUnacknowledgedCommands()
|
||||
updatePodWarnings()
|
||||
handler.postDelayed(statusChecker, STATUS_CHECK_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePodWarnings() {
|
||||
if (System.currentTimeMillis() > nextPodWarningCheck) {
|
||||
if (!podStateManager.isPodRunning) {
|
||||
val notification =
|
||||
Notification(
|
||||
Notification.OMNIPOD_POD_NOT_ATTACHED,
|
||||
"Pod not activated",
|
||||
Notification.NORMAL
|
||||
)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
} else {
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED))
|
||||
if (podStateManager.isSuspended) {
|
||||
val notification =
|
||||
Notification(
|
||||
Notification.OMNIPOD_POD_SUSPENDED,
|
||||
"Insulin delivery suspended",
|
||||
Notification.NORMAL
|
||||
)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
} else {
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED))
|
||||
// TODO: time out of sync notification?
|
||||
}
|
||||
}
|
||||
nextPodWarningCheck = DateTimeUtil.getTimeInFutureFromMinutes(15)
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshStatusOnUnacknowledgedCommands() {
|
||||
if (podStateManager.isPodRunning &&
|
||||
podStateManager.activeCommand != null &&
|
||||
commandQueue.size() == 0 &&
|
||||
commandQueue.performing() == null) {
|
||||
commandQueue.readStatus("Unconfirmed command", null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isInitialized(): Boolean {
|
||||
// TODO
|
||||
return true
|
||||
|
@ -130,12 +182,27 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun getPumpStatus(reason: String) {
|
||||
aapsLogger.debug(LTag.PUMP, "getPumpStatus reason=$reason")
|
||||
if (reason != "REQUESTED BY USER" && !podStateManager.isActivationCompleted) {
|
||||
// prevent races on BLE when the pod is not activated
|
||||
return
|
||||
}
|
||||
|
||||
val throwable = getPodStatus().blockingGet()
|
||||
if (throwable != null) {
|
||||
aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable)
|
||||
} else {
|
||||
aapsLogger.info(LTag.PUMP, "getPumpStatus executed with success")
|
||||
if (!podStateManager.isActivationCompleted) {
|
||||
val msg = podStateManager.recoverActivationFromPodStatus()
|
||||
msg?.let {
|
||||
// TODO: show dialog with "try again, the pod is busy now"
|
||||
aapsLogger.info(LTag.PUMP, "recoverActivationFromPodStatus msg=$msg")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,6 +250,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
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()
|
||||
}
|
||||
|
@ -191,21 +264,45 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
if (!podStateManager.isActivationCompleted) {
|
||||
return PumpEnactResult(injector).success(true).enacted(true)
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMP, "setNewBasalProfile profile=$profile")
|
||||
val basalProgram = mapProfileToBasalProgram(profile)
|
||||
var deliverySuspended = false
|
||||
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),
|
||||
activeCommandEntry = { historyId ->
|
||||
podStateManager.createActiveCommand(historyId, basalProgram = basalProgram)
|
||||
},
|
||||
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()
|
||||
}
|
||||
|
||||
private fun failWhenUnconfirmed(): Completable = Completable.defer {
|
||||
private fun failWhenUnconfirmed(deliverySuspended: Boolean): Completable = Completable.defer {
|
||||
rxBus.send(EventTempBasalChange())
|
||||
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"))
|
||||
} else {
|
||||
Completable.complete()
|
||||
|
@ -229,15 +326,26 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
rxBus.send(EventTempBasalChange())
|
||||
}
|
||||
.ignoreElements()
|
||||
)
|
||||
).doOnComplete {
|
||||
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() {
|
||||
super.onStop()
|
||||
disposable.clear()
|
||||
}
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
podStateManager.onStart()
|
||||
handler.postDelayed(statusChecker, STATUS_CHECK_INTERVAL_MS)
|
||||
}
|
||||
|
||||
*/
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
handler.removeCallbacks(statusChecker)
|
||||
}
|
||||
|
||||
private fun observeDeliverySuspended(): Completable = Completable.defer {
|
||||
if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED)
|
||||
|
@ -351,7 +459,23 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
aapsLogger.info(LTag.PUMP, "deliverTreatment: deliveredBolusAmount=$deliveredBolusAmount")
|
||||
}
|
||||
.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)
|
||||
)
|
||||
.onErrorReturnItem(
|
||||
|
@ -415,7 +539,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
continue
|
||||
}
|
||||
val percent = (waited.toFloat() / estimatedDeliveryTimeSeconds) * 100
|
||||
updateBolusProgressDialog(resourceHelper.gs(R.string.bolusdelivering, requestedBolusAmount), percent.toInt())
|
||||
updateBolusProgressDialog(
|
||||
resourceHelper.gs(R.string.bolusdelivering, requestedBolusAmount),
|
||||
percent.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
for (tryNumber in 1..maxTries) {
|
||||
|
@ -508,8 +635,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
val tempBasalBeeps = hasTempBasalBeepEnabled()
|
||||
aapsLogger.info(
|
||||
LTag.PUMP,
|
||||
"setTempBasalAbsolute: duration=$durationInMinutes min, rate=$absoluteRate U/h :: " +
|
||||
"enforce=$enforceNew, tbrType=$tbrType"
|
||||
"setTempBasalAbsolute: " +
|
||||
"duration=$durationInMinutes min :: " +
|
||||
"rate=$absoluteRate U/h :: " +
|
||||
"enforce=$enforceNew ::" +
|
||||
"tbrType=$tbrType"
|
||||
)
|
||||
|
||||
val ret = executeProgrammingCommand(
|
||||
|
@ -536,7 +666,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
.filter { podEvent -> podEvent.isCommandSent() }
|
||||
.map { pumpSyncTempBasal(absoluteRate, durationInMinutes.toLong(), tbrType) }
|
||||
.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) {
|
||||
ret.isPercent(false).absolute(absoluteRate).duration(durationInMinutes)
|
||||
}
|
||||
|
@ -557,7 +695,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
)
|
||||
}
|
||||
val historyEntry = history.getById(activeCommand.historyId)
|
||||
aapsLogger.debug(LTag.PUMP, "pumpSyncTempBasal: absoluteRate=$absoluteRate, durationInMinutes=$durationInMinutes")
|
||||
aapsLogger.debug(
|
||||
LTag.PUMP,
|
||||
"pumpSyncTempBasal: absoluteRate=$absoluteRate, durationInMinutes=$durationInMinutes"
|
||||
)
|
||||
val ret = pumpSync.syncTemporaryBasalWithPumpId(
|
||||
timestamp = historyEntry.createdAt,
|
||||
rate = absoluteRate,
|
||||
|
@ -595,7 +736,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
|
||||
command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements()
|
||||
)
|
||||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.OMNIPOD_TBR_ALERTS,
|
||||
"Cancelling temp basal might have 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -638,7 +787,20 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
return executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
|
||||
command = omnipodManager.stopTempBasal(hasTempBasalBeepEnabled()).ignoreElements(),
|
||||
).toPumpEnactResult()
|
||||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.OMNIPOD_TBR_ALERTS,
|
||||
"Cancel temp basal result is uncertain", // TODO: i8n,
|
||||
R.raw.boluserror, // TODO: add setting for this
|
||||
)
|
||||
}.toPumpEnactResult()
|
||||
}
|
||||
|
||||
private fun notifyOnUnconfirmed(notificationId: Int, msg: String, sound: Int?) {
|
||||
if (podStateManager.activeCommand != null) {
|
||||
aapsLogger.debug(LTag.PUMP, "Notification for active command: ${podStateManager.activeCommand}")
|
||||
showNotification(notificationId, msg, Notification.URGENT, sound)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Completable.toPumpEnactResult(): PumpEnactResult {
|
||||
|
@ -755,7 +917,13 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
.ignoreElements(),
|
||||
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 {
|
||||
|
@ -770,8 +938,15 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
executeProgrammingCommand(
|
||||
pre = observeDeliverySuspended(),
|
||||
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
||||
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it), hasBasalBeepEnabled()).ignoreElements()
|
||||
).toPumpEnactResult()
|
||||
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it), hasBasalBeepEnabled())
|
||||
.ignoreElements()
|
||||
).doFinally {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.FAILED_UPDATE_PROFILE,
|
||||
"Unconfirmed resumeDelivery command. Please refresh pod status",
|
||||
R.raw.boluserror
|
||||
)
|
||||
}.toPumpEnactResult()
|
||||
} ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n
|
||||
}
|
||||
|
||||
|
@ -779,7 +954,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
val ret = executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
|
||||
command = omnipodManager.deactivatePod().ignoreElements()
|
||||
).toPumpEnactResult()
|
||||
).doOnComplete {
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_FAULT))
|
||||
}.toPumpEnactResult()
|
||||
|
||||
if (podStateManager.activeCommand != null) {
|
||||
ret.success(false)
|
||||
}
|
||||
|
@ -862,8 +1040,19 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
val historyEntry = history.getById(command.historyId)
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation")
|
||||
when (historyEntry.commandType) {
|
||||
OmnipodCommandType.CANCEL_TEMPORARY_BASAL,
|
||||
OmnipodCommandType.RESUME_DELIVERY ->
|
||||
OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> {
|
||||
if (confirmation.success) {
|
||||
pumpSync.syncStopTemporaryBasalWithPumpId(
|
||||
historyEntry.createdAt,
|
||||
historyEntry.pumpId(),
|
||||
PumpType.OMNIPOD_DASH,
|
||||
serialNumber()
|
||||
)
|
||||
podStateManager.tempBasal = null
|
||||
}
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
}
|
||||
OmnipodCommandType.RESUME_DELIVERY -> {
|
||||
// We can't invalidate this command,
|
||||
// and this is why it is pumpSync-ed at this point
|
||||
if (confirmation.success) {
|
||||
|
@ -874,7 +1063,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
serialNumber()
|
||||
)
|
||||
podStateManager.tempBasal = null
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED))
|
||||
}
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
}
|
||||
|
||||
OmnipodCommandType.SET_BASAL_PROFILE -> {
|
||||
if (confirmation.success) {
|
||||
|
@ -892,6 +1084,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
PumpType.OMNIPOD_DASH,
|
||||
serialNumber()
|
||||
)
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED))
|
||||
rxBus.send(EventDismissNotification(Notification.FAILED_UPDATE_PROFILE))
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,11 +1102,16 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
} else {
|
||||
podStateManager.tempBasal = command.tempBasal
|
||||
}
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_TBR_ALERTS))
|
||||
}
|
||||
|
||||
OmnipodCommandType.SUSPEND_DELIVERY -> {
|
||||
if (!confirmation.success) {
|
||||
pumpSync.invalidateTemporaryBasalWithPumpId(historyEntry.pumpId(), PumpType.OMNIPOD_DASH, serialNumber())
|
||||
pumpSync.invalidateTemporaryBasalWithPumpId(
|
||||
historyEntry.pumpId(),
|
||||
PumpType.OMNIPOD_DASH,
|
||||
serialNumber()
|
||||
)
|
||||
} else {
|
||||
podStateManager.tempBasal = null
|
||||
}
|
||||
|
@ -947,17 +1147,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
type = null // TODO: set the correct bolus type here!!!
|
||||
)
|
||||
}
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_UNCERTAIN_SMB))
|
||||
}
|
||||
|
||||
OmnipodCommandType.CANCEL_BOLUS -> {
|
||||
if (confirmation.success) {
|
||||
|
||||
podStateManager.lastBolus?.run {
|
||||
val deliveredUnits = markComplete()
|
||||
val bolusHistoryEntry = history.getById(historyId)
|
||||
val sync = pumpSync.syncBolusWithPumpId(
|
||||
timestamp = bolusHistoryEntry.createdAt,
|
||||
amount = deliveredUnits, // we just marked this bolus as complete
|
||||
amount = deliveredUnits,
|
||||
pumpId = bolusHistoryEntry.pumpId(),
|
||||
pumpType = PumpType.OMNIPOD_DASH,
|
||||
pumpSerial = serialNumber(),
|
||||
|
@ -976,4 +1176,26 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorDialog(message: String, sound: Int) {
|
||||
runAlarm(context, message, resourceHelper.gs(R.string.error), sound)
|
||||
}
|
||||
|
||||
private fun showNotification(id: Int, message: String, urgency: Int, sound: Int?) {
|
||||
val notification = Notification(
|
||||
id,
|
||||
message,
|
||||
urgency
|
||||
)
|
||||
// TODO add back sound when we have options to disable it
|
||||
/*
|
||||
if (sound != null) {
|
||||
notification.soundId = sound
|
||||
}*/
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
|
||||
private fun dismissNotification(id: Int) {
|
||||
rxBus.send(EventDismissNotification(id))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,8 +173,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
DefaultStatusResponse::class
|
||||
)
|
||||
}.doOnComplete {
|
||||
// TODO: remove podStateManager.basalProgram?
|
||||
podStateManager.basalProgram = basalProgram
|
||||
podStateManager.timeZone = TimeZone.getDefault()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,6 +245,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
observeVerifyPrime.doOnComplete(ActivationProgressUpdater(ActivationProgress.PRIME_COMPLETED))
|
||||
)
|
||||
}
|
||||
|
||||
if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING)) {
|
||||
observables.add(observeConnectToPod) // connection can time out while waiting
|
||||
observables.add(
|
||||
|
@ -270,6 +270,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
}.doOnComplete(ActivationProgressUpdater(ActivationProgress.PRIMING))
|
||||
)
|
||||
}
|
||||
|
||||
if (podStateManager.activationProgress.isBefore(ActivationProgress.REPROGRAMMED_LUMP_OF_COAL_ALERT)) {
|
||||
observables.add(
|
||||
observeSendProgramAlertsCommand(
|
||||
|
@ -304,6 +305,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
).doOnComplete(ActivationProgressUpdater(ActivationProgress.PROGRAMMED_LOW_RESERVOIR_ALERTS))
|
||||
)
|
||||
}
|
||||
|
||||
if (podStateManager.activationProgress.isBefore(ActivationProgress.SET_UNIQUE_ID)) {
|
||||
observables.add(
|
||||
observeSendSetUniqueIdCommand.doOnComplete(ActivationProgressUpdater(ActivationProgress.SET_UNIQUE_ID))
|
||||
|
|
|
@ -125,7 +125,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
|||
for (i in 1..MAX_NUMBER_OF_CONNECTION_ATTEMPTS) {
|
||||
try {
|
||||
// wait i * CONNECTION_TIMEOUT
|
||||
conn.connect(i)
|
||||
conn.connect(CONNECT_TIMEOUT_MULTIPLIER)
|
||||
break
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.warn(LTag.PUMPBTCOMM, "connect error=$e")
|
||||
|
@ -240,7 +240,8 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_NUMBER_OF_CONNECTION_ATTEMPTS = 3
|
||||
const val MAX_NUMBER_OF_CONNECTION_ATTEMPTS = 2
|
||||
const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
||||
private const val CONNECT_TIMEOUT_MULTIPLIER = 4
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ class ServiceDiscoverer(
|
|||
*/
|
||||
fun discoverServices(): Map<CharacteristicType, BluetoothGattCharacteristic> {
|
||||
logger.debug(LTag.PUMPBTCOMM, "Discovering services")
|
||||
bleCallbacks.startServiceDiscovery()
|
||||
val discover = gatt.discoverServices()
|
||||
if (!discover) {
|
||||
throw ConnectException("Could not start discovering services`")
|
||||
|
|
|
@ -61,6 +61,10 @@ class BleCommCallbacks(
|
|||
}
|
||||
}
|
||||
|
||||
fun startServiceDiscovery() {
|
||||
serviceDiscoveryComplete = CountDownLatch(1)
|
||||
}
|
||||
|
||||
fun waitForServiceDiscovery(timeoutMs: Int) {
|
||||
try {
|
||||
serviceDiscoveryComplete.await(timeoutMs.toLong(), TimeUnit.MILLISECONDS)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
||||
|
||||
interface ConnectionStateChangeHandler {
|
||||
|
||||
fun onConnectionStateChange(status: Int, newState: Int)
|
||||
}
|
|
@ -13,6 +13,9 @@ import io.reactivex.Completable
|
|||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.Duration
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
|
@ -33,8 +36,12 @@ interface OmnipodDashPodStateManager {
|
|||
val isPodKaput: Boolean
|
||||
var bluetoothConnectionState: BluetoothConnectionState
|
||||
|
||||
var timeZone: TimeZone
|
||||
val lastUpdatedSystem: Long // System.currentTimeMillis()
|
||||
val lastStatusResponseReceived: Long
|
||||
val time: DateTime?
|
||||
val timeDrift: Duration?
|
||||
val expiry: DateTime?
|
||||
|
||||
val messageSequenceNumber: Short
|
||||
val sequenceNumberOfLastProgrammingCommand: Short?
|
||||
|
@ -90,6 +97,13 @@ interface OmnipodDashPodStateManager {
|
|||
|
||||
fun createLastBolus(requestedUnits: Double, historyId: String, bolusType: DetailedBolusInfo.BolusType)
|
||||
fun markLastBolusComplete(): LastBolus?
|
||||
fun onStart()
|
||||
/*
|
||||
This is called only:. It overwrites activationStatus
|
||||
- when activation was interrupted(application crash, killed, etc)
|
||||
- after getPodStatus was successful(we have an up-to-date podStatus)
|
||||
*/
|
||||
fun recoverActivationFromPodStatus(): String?
|
||||
|
||||
data class ActiveCommand(
|
||||
val sequence: Short,
|
||||
|
|
|
@ -22,6 +22,9 @@ import io.reactivex.Completable
|
|||
import io.reactivex.Maybe
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.Duration
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
@ -97,6 +100,13 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override var timeZone: TimeZone
|
||||
get() = TimeZone.getTimeZone(podState.timeZone)
|
||||
set(tz) {
|
||||
podState.timeZone = tz.getDisplayName(true, TimeZone.SHORT)
|
||||
store()
|
||||
}
|
||||
|
||||
override val bluetoothVersion: SoftwareVersion?
|
||||
get() = podState.bleVersion
|
||||
|
||||
|
@ -173,6 +183,34 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
override val lastStatusResponseReceived: Long
|
||||
get() = podState.lastStatusResponseReceived
|
||||
|
||||
override val time: DateTime?
|
||||
get() {
|
||||
val minutesSinceActivation = podState.minutesSinceActivation
|
||||
val activationTime = podState.activationTime
|
||||
if ((activationTime != null) && (minutesSinceActivation != null)) {
|
||||
return DateTime(activationTime)
|
||||
.plusMinutes(minutesSinceActivation.toInt())
|
||||
.plus(Duration(podState.lastUpdatedSystem, System.currentTimeMillis()))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override val timeDrift: Duration?
|
||||
get() {
|
||||
return Duration(DateTime.now(), time)
|
||||
}
|
||||
|
||||
override val expiry: DateTime?
|
||||
// TODO: Consider storing expiry datetime in pod state saving continuously recalculating to the same value
|
||||
get() {
|
||||
val podLifeInHours = podLifeInHours
|
||||
val activationTime = podState.activationTime
|
||||
if (podLifeInHours != null && activationTime != null) {
|
||||
return DateTime(podState.activationTime).plusHours(podLifeInHours.toInt())
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState
|
||||
get() = podState.bluetoothConnectionState
|
||||
set(bluetoothConnectionState) {
|
||||
|
@ -286,6 +324,29 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun recoverActivationFromPodStatus(): String? {
|
||||
val newActivationProgress = when (podState.podStatus) {
|
||||
PodStatus.FILLED ->
|
||||
ActivationProgress.NOT_STARTED
|
||||
PodStatus.UID_SET ->
|
||||
ActivationProgress.SET_UNIQUE_ID
|
||||
PodStatus.ENGAGING_CLUTCH_DRIVE, PodStatus.PRIMING ->
|
||||
return "Busy"
|
||||
PodStatus.CLUTCH_DRIVE_ENGAGED ->
|
||||
ActivationProgress.PRIME_COMPLETED
|
||||
PodStatus.BASAL_PROGRAM_SET ->
|
||||
ActivationProgress.PROGRAMMED_BASAL
|
||||
PodStatus.RUNNING_ABOVE_MIN_VOLUME, PodStatus.RUNNING_BELOW_MIN_VOLUME ->
|
||||
ActivationProgress.CANNULA_INSERTED
|
||||
else ->
|
||||
null
|
||||
}
|
||||
newActivationProgress?.let {
|
||||
podState.activationProgress = it
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun updateActiveCommand() = Maybe.create<CommandConfirmed> { source ->
|
||||
val activeCommand = podState.activeCommand
|
||||
|
@ -365,6 +426,32 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
store()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
when (getCommandConfirmationFromState()) {
|
||||
CommandConfirmationSuccess, CommandConfirmationDenied -> {
|
||||
val now = System.currentTimeMillis()
|
||||
val newCommand = podState.activeCommand?.copy(
|
||||
createdRealtime = now,
|
||||
sentRealtime = now + 1
|
||||
)
|
||||
podState.lastStatusResponseReceived = now + 2
|
||||
podState.activeCommand = newCommand
|
||||
}
|
||||
|
||||
CommandSendingNotConfirmed -> {
|
||||
val now = System.currentTimeMillis()
|
||||
val newCommand = podState.activeCommand?.copy(
|
||||
createdRealtime = now,
|
||||
sentRealtime = now + 1
|
||||
)
|
||||
podState.lastStatusResponseReceived = 0
|
||||
}
|
||||
|
||||
CommandSendingFailure, NoActiveCommand ->
|
||||
podState.activeCommand = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateFromDefaultStatusResponse(response: DefaultStatusResponse) {
|
||||
logger.debug(LTag.PUMPCOMM, "Default status response :$response")
|
||||
podState.deliveryStatus = response.deliveryStatus
|
||||
|
@ -380,6 +467,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
podState.lastUpdatedSystem = System.currentTimeMillis()
|
||||
podState.lastStatusResponseReceived = SystemClock.elapsedRealtime()
|
||||
updateLastBolusFromResponse(response.bolusPulsesRemaining)
|
||||
if (podState.activationTime == null) {
|
||||
podState.activationTime = System.currentTimeMillis() - (response.minutesSinceActivation * 60_000)
|
||||
}
|
||||
|
||||
store()
|
||||
rxBus.send(EventOmnipodDashPumpValuesChanged())
|
||||
|
@ -428,12 +518,6 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
podState.uniqueId = response.uniqueIdReceivedInCommand
|
||||
|
||||
podState.lastUpdatedSystem = System.currentTimeMillis()
|
||||
// TODO: what is considered to be the pod activation time?
|
||||
// LTK negotiation ?
|
||||
// setUniqueId?
|
||||
// compute it from the number of "minutesOnPod"?
|
||||
podState.activationTime = System.currentTimeMillis()
|
||||
|
||||
store()
|
||||
rxBus.send(EventOmnipodDashPumpValuesChanged())
|
||||
}
|
||||
|
@ -514,6 +598,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
var ltk: ByteArray? = null
|
||||
var eapAkaSequenceNumber: Long = 1
|
||||
var bolusPulsesRemaining: Short = 0
|
||||
var timeZone: String = "" // TimeZone ID (e.g. "Europe/Amsterdam")
|
||||
|
||||
var bleVersion: SoftwareVersion? = null
|
||||
var firmwareVersion: SoftwareVersion? = null
|
||||
|
|
|
@ -125,8 +125,8 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
binding.buttonActivatePod.isEnabled = podStateManager.activationProgress.isBefore(ActivationProgress.COMPLETED)
|
||||
binding.buttonDeactivatePod.isEnabled =
|
||||
podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) ||
|
||||
podStateManager.podStatus == PodStatus.ALARM
|
||||
podStateManager.ltk != null ||
|
||||
podStateManager.podStatus == PodStatus.ALARM
|
||||
|
||||
if (podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED)) {
|
||||
if (commandQueue.isCustomCommandInQueue(CommandPlayTestBeep::class.java)) {
|
||||
|
|
|
@ -45,7 +45,6 @@ import io.reactivex.disposables.CompositeDisposable
|
|||
import io.reactivex.rxkotlin.plusAssign
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.Duration
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
@ -69,6 +68,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
|
||||
private const val REFRESH_INTERVAL_MILLIS = 15 * 1000L // 15 seconds
|
||||
private const val PLACEHOLDER = "-"
|
||||
private const val MAX_TIME_DEVIATION_MINUTES = 10L
|
||||
}
|
||||
|
||||
private var disposables: CompositeDisposable = CompositeDisposable()
|
||||
|
@ -236,29 +236,6 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
// Get time on pos from activation time and minutes since activation
|
||||
private fun getTimeOnPod(): DateTime? {
|
||||
var timeOnPod: DateTime? = null
|
||||
val minutesSinceActivation = podStateManager.minutesSinceActivation
|
||||
val activationTime = podStateManager.activationTime
|
||||
if ((activationTime != null) and (minutesSinceActivation != null)) {
|
||||
timeOnPod = DateTime(activationTime!!).plusMinutes(minutesSinceActivation!!.toInt())
|
||||
}
|
||||
return timeOnPod
|
||||
}
|
||||
|
||||
// TODO: Consider storing expiry datetime in pod state saving continuesly recalculating to the same value
|
||||
private fun getExpiryAt(): DateTime? {
|
||||
var expiresAt: DateTime? = null
|
||||
val podLifeInHours = podStateManager.podLifeInHours
|
||||
val minutesSinceActivation = podStateManager.minutesSinceActivation
|
||||
if ((podLifeInHours != null) and (minutesSinceActivation != null)) {
|
||||
val expiresInMinutes = (podLifeInHours!! * 60) - minutesSinceActivation!!
|
||||
expiresAt = DateTime().plusMinutes(expiresInMinutes)
|
||||
}
|
||||
return expiresAt
|
||||
}
|
||||
|
||||
private fun updateOmnipodStatus() {
|
||||
updateLastConnection()
|
||||
updateLastBolus()
|
||||
|
@ -291,52 +268,36 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
)
|
||||
|
||||
// Update time on Pod
|
||||
// TODO: For now: derive from podStateManager.minutesSinceActivation
|
||||
val timeOnPod = getTimeOnPod()
|
||||
if (timeOnPod == null) {
|
||||
podInfoBinding.timeOnPod.text = "???"
|
||||
} else {
|
||||
podInfoBinding.timeOnPod.text = readableZonedTime(timeOnPod)
|
||||
}
|
||||
podInfoBinding.timeOnPod.text = podStateManager.time?.let {
|
||||
readableZonedTime(it)
|
||||
} ?: PLACEHOLDER
|
||||
|
||||
// TODO
|
||||
/*
|
||||
podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) {
|
||||
Color.RED
|
||||
} else {
|
||||
Color.WHITE
|
||||
})
|
||||
*/
|
||||
|
||||
// TODO: Active command
|
||||
if (podStateManager.activeCommand != null) {
|
||||
podInfoBinding.podExpiryDate.setTextColor(Color.RED)
|
||||
podInfoBinding.podExpiryDate.text = "Active command"
|
||||
} else {
|
||||
podInfoBinding.podExpiryDate.text = PLACEHOLDER
|
||||
podInfoBinding.podExpiryDate.setTextColor(Color.WHITE)
|
||||
}
|
||||
podInfoBinding.timeOnPod.setTextColor(
|
||||
podStateManager.timeDrift?.let {
|
||||
if (it.abs().isLongerThan(Duration.standardMinutes(MAX_TIME_DEVIATION_MINUTES))) {
|
||||
Color.RED
|
||||
} else {
|
||||
Color.WHITE
|
||||
}
|
||||
} ?: Color.WHITE
|
||||
)
|
||||
|
||||
// Update Pod expiry time
|
||||
val expiresAt = getExpiryAt()
|
||||
if (expiresAt is Nothing) {
|
||||
val expiresAt = podStateManager.expiry
|
||||
if (expiresAt == null) {
|
||||
podInfoBinding.podExpiryDate.text = PLACEHOLDER
|
||||
podInfoBinding.podExpiryDate.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
podInfoBinding.podExpiryDate.text = readableZonedTime(expiresAt!!)
|
||||
podInfoBinding.podExpiryDate.setTextColor(if (DateTime.now().isAfter(expiresAt)) {
|
||||
Color.RED
|
||||
} else {
|
||||
Color.WHITE
|
||||
})
|
||||
podInfoBinding.podExpiryDate.text = readableZonedTime(expiresAt)
|
||||
podInfoBinding.podExpiryDate.setTextColor(
|
||||
if (DateTime.now().isAfter(expiresAt)) {
|
||||
Color.RED
|
||||
} else {
|
||||
Color.WHITE
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/* TODO
|
||||
if (podStateManager.isPodFaulted) {
|
||||
val faultEventCode = podStateManager.faultEventCode
|
||||
errors.add(resourceHelper.gs(R.string.omnipod_common_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name))
|
||||
}
|
||||
*/
|
||||
podStateManager.alarmType?.let {
|
||||
errors.add(
|
||||
resourceHelper.gs(
|
||||
|
@ -425,9 +386,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
podInfoBinding.lastConnection.setTextColor(lastConnectionColor)
|
||||
} else {
|
||||
podInfoBinding.lastConnection.setTextColor(Color.WHITE)
|
||||
podInfoBinding.lastConnection.text = readableDuration(
|
||||
Duration(podStateManager.lastUpdatedSystem, System.currentTimeMillis())
|
||||
)
|
||||
podInfoBinding.lastConnection.text = PLACEHOLDER
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,7 +523,6 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
private fun updateRefreshStatusButton() {
|
||||
buttonBinding.buttonRefreshStatus.isEnabled =
|
||||
podStateManager.isUniqueIdSet &&
|
||||
podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) &&
|
||||
isQueueEmpty()
|
||||
}
|
||||
|
||||
|
@ -625,7 +583,6 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
}
|
||||
|
||||
private fun isSuspendDeliveryButtonEnabled(): Boolean {
|
||||
R.string.key_omnipod_common_basal_beeps_enabled
|
||||
return sp.getBoolean(R.string.key_omnipod_common_suspend_delivery_button_enabled, false)
|
||||
}
|
||||
|
||||
|
@ -643,25 +600,41 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getTimeZone(): DateTimeZone {
|
||||
// TODO: Get timezone as configured/podState
|
||||
// return getSafe(() -> podState.getTimeZone());
|
||||
return DateTimeZone.getDefault()
|
||||
// private fun getTimeZone(): DateTimeZone {
|
||||
// // return getSafe(() -> podState.getTimeZone());
|
||||
// return podStateManager.timeZone
|
||||
// }
|
||||
private fun getTimeZone(): TimeZone {
|
||||
// Return timezone ID (e.g "Europe/Amsterdam")
|
||||
return podStateManager.timeZone
|
||||
}
|
||||
|
||||
private fun readableZonedTime(time: DateTime): String {
|
||||
val timeAsJavaData = time.toLocalDateTime().toDate()
|
||||
return dateUtil.dateAndTimeString(timeAsJavaData.time)
|
||||
|
||||
val timeZone = getTimeZone().toTimeZone()
|
||||
if (timeZone == TimeZone.getDefault()) {
|
||||
return dateUtil.dateAndTimeString(timeAsJavaData.time)
|
||||
}
|
||||
|
||||
// Get full timezoned time
|
||||
val isDaylightTime = timeZone.inDaylightTime(timeAsJavaData)
|
||||
val locale = resources.configuration.locales.get(0)
|
||||
val timeZoneDisplayName = timeZone.getDisplayName(isDaylightTime, TimeZone.SHORT, locale) + " " + timeZone.getDisplayName(isDaylightTime, TimeZone.LONG, locale)
|
||||
return resourceHelper.gs(R.string.omnipod_common_time_with_timezone, dateUtil.dateAndTimeString(timeAsJavaData.time), timeZoneDisplayName)
|
||||
// // TODO: Handle timeZone ID
|
||||
// val timeZone = getTimeZone()
|
||||
// if (timeZone == "") {
|
||||
// // No timezone defined, use local time (default)
|
||||
// return dateUtil.dateAndTimeString(timeAsJavaData.time)
|
||||
// }
|
||||
// else {
|
||||
// // Get full timezoned time
|
||||
// val isDaylightTime = timeZone.inDaylightTime(timeAsJavaData)
|
||||
// val locale = resources.configuration.locales.get(0)
|
||||
// val timeZoneDisplayName =
|
||||
// timeZone.getDisplayName(isDaylightTime, TimeZone.SHORT, locale) + " " + timeZone.getDisplayName(
|
||||
// isDaylightTime,
|
||||
// TimeZone.LONG,
|
||||
// locale
|
||||
// )
|
||||
// return resourceHelper.gs(
|
||||
// R.string.omnipod_common_time_with_timezone,
|
||||
// dateUtil.dateAndTimeString(timeAsJavaData.time),
|
||||
// timeZoneDisplayName
|
||||
// )
|
||||
// }
|
||||
}
|
||||
|
||||
private fun readableDuration(duration: Duration): String {
|
||||
|
|
|
@ -2,13 +2,17 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activatio
|
|||
|
||||
import androidx.annotation.StringRes
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.interfaces.PumpSync
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InsertCannulaViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
|
@ -17,6 +21,8 @@ import javax.inject.Inject
|
|||
class DashInsertCannulaViewModel @Inject constructor(
|
||||
private val omnipodManager: OmnipodDashManager,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val pumpSync: PumpSync,
|
||||
private val podStateManager: OmnipodDashPodStateManager,
|
||||
injector: HasAndroidInjector,
|
||||
logger: AAPSLogger
|
||||
) : InsertCannulaViewModel(injector, logger) {
|
||||
|
@ -52,6 +58,19 @@ class DashInsertCannulaViewModel @Inject constructor(
|
|||
},
|
||||
onComplete = {
|
||||
logger.debug("Pod activation part 2 completed")
|
||||
pumpSync.connectNewPump()
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
type = DetailedBolusInfo.EventType.CANNULA_CHANGE,
|
||||
pumpType = PumpType.OMNIPOD_DASH,
|
||||
pumpSerial = podStateManager.uniqueId?.toString() ?: "n/a"
|
||||
)
|
||||
pumpSync.insertTherapyEventIfNewWithTimestamp(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
type = DetailedBolusInfo.EventType.INSULIN_CHANGE,
|
||||
pumpType = PumpType.OMNIPOD_DASH,
|
||||
pumpSerial = podStateManager.uniqueId?.toString() ?: "n/a"
|
||||
)
|
||||
source.onSuccess(PumpEnactResult(injector).success(true))
|
||||
}
|
||||
)
|
||||
|
|
|
@ -5,6 +5,9 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
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.queue.command.CommandDeactivatePod
|
||||
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(
|
||||
private val podStateManager: OmnipodDashPodStateManager,
|
||||
private val commandQueueProvider: CommandQueueProvider,
|
||||
private val rxBus: RxBusWrapper,
|
||||
injector: HasAndroidInjector,
|
||||
logger: AAPSLogger
|
||||
) : DeactivatePodViewModel(injector, logger) {
|
||||
|
@ -33,6 +37,7 @@ class DashDeactivatePodViewModel @Inject constructor(
|
|||
|
||||
override fun discardPod() {
|
||||
podStateManager.reset()
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_FAULT))
|
||||
}
|
||||
|
||||
@StringRes
|
||||
|
|
|
@ -150,7 +150,7 @@ dependencies {
|
|||
}
|
||||
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
||||
implementation "androidx.core:core-ktx:+"
|
||||
implementation "androidx.core:core-ktx:$coreVersion"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
repositories {
|
||||
|
|
Loading…
Reference in a new issue