simplify executeProgrammingCommand. Start implementing alerts

This commit is contained in:
Andrei Vereha 2021-06-06 10:47:29 +02:00
parent c72f2f352f
commit 79b4a5d656
6 changed files with 60 additions and 57 deletions

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash
import dagger.android.HasAndroidInjector 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.EventPreferenceChange
import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.events.EventTempBasalChange import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
@ -19,7 +18,6 @@ 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.OmnipodDashManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants
@ -37,13 +35,10 @@ import info.nightscout.androidaps.queue.commands.CustomCommand
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP 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.disposables.CompositeDisposable
import io.reactivex.functions.Consumer
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
import org.json.JSONObject import org.json.JSONObject
@ -61,7 +56,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
private val pumpSync: PumpSync, private val pumpSync: PumpSync,
private val rxBus: RxBusWrapper, private val rxBus: RxBusWrapper,
// private val disposable: CompositeDisposable = CompositeDisposable(), // private val disposable: CompositeDisposable = CompositeDisposable(),
// private val aapsSchedulers: AapsSchedulers, // private val aapsSchedulers: AapsSchedulers,
injector: HasAndroidInjector, injector: HasAndroidInjector,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
@ -128,20 +123,21 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
override fun getPumpStatus(reason: String) { override fun getPumpStatus(reason: String) {
val throwable = Completable.concat(listOf( val throwable = Completable.concat(
omnipodManager listOf(
.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE) omnipodManager
.ignoreElements(), .getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE)
history.updateFromState(podStateManager), .ignoreElements(),
podStateManager.updateActiveCommand() history.updateFromState(podStateManager),
.map { handleCommandConfirmation(it) } podStateManager.updateActiveCommand()
.ignoreElement(), .map { handleCommandConfirmation(it) }
)).blockingGet() .ignoreElement(),
if (throwable != null){ )
).blockingGet()
if (throwable != null) {
aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable) aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable)
} else { } else {
aapsLogger.info(LTag.PUMP, "getPumpStatus executed with success") aapsLogger.info(LTag.PUMP, "getPumpStatus executed with success")
} }
} }
@ -150,17 +146,19 @@ class OmnipodDashPumpPlugin @Inject constructor(
return executeProgrammingCommand( return executeProgrammingCommand(
pre = suspendDeliveryIfActive(), pre = suspendDeliveryIfActive(),
historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE), historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE),
activeCommandEntry = { historyId ->
podStateManager.createActiveCommand(historyId, basalProgram = basalProgram)
},
command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(), command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(),
basalProgram = basalProgram,
post = failWhenUnconfirmed(), post = failWhenUnconfirmed(),
).toPumpEnactResult() ).toPumpEnactResult()
} }
private fun failWhenUnconfirmed(): Completable = Completable.defer{ private fun failWhenUnconfirmed(): Completable = Completable.defer {
rxBus.send(EventTempBasalChange()) 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 {
Completable.complete() Completable.complete()
} }
} }
@ -170,8 +168,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
Completable.complete() Completable.complete()
else else
executeProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
omnipodManager.suspendDelivery() command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent is PodEvent.CommandSent }
.map { .map {
pumpSyncTempBasal( pumpSyncTempBasal(
@ -190,7 +188,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
super.onStop() super.onStop()
disposable.clear() disposable.clear()
} }
*/ */
private fun observeDeliverySuspended(): Completable = Completable.defer { private fun observeDeliverySuspended(): Completable = Completable.defer {
@ -296,8 +294,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
override fun stopBolusDelivering() { override fun stopBolusDelivering() {
// TODO update Treatments (?) // TODO update Treatments (?)
executeProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_BOLUS), historyEntry = history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
omnipodManager.stopBolus().ignoreElements() command = omnipodManager.stopBolus().ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
} }
@ -310,14 +308,25 @@ class OmnipodDashPumpPlugin @Inject constructor(
): 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( aapsLogger.info(
LTag.PUMP, "setTempBasalAbsolute: $durationInMinutes min :: $absoluteRate U/h :: " + LTag.PUMP,
"enforce: $enforceNew :: tbrType: $tbrType" "setTempBasalAbsolute: $durationInMinutes min :: $absoluteRate U/h :: " +
"enforce: $enforceNew :: tbrType: $tbrType"
) )
return executeProgrammingCommand( 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)
), ),
activeCommandEntry = { historyId ->
podStateManager.createActiveCommand(
historyId,
tempBasal = OmnipodDashPodStateManager.TempBasal(
startTime = System.currentTimeMillis(),
rate = absoluteRate,
durationInMinutes = durationInMinutes.toShort(),
)
)
},
command = omnipodManager.setTempBasal( command = omnipodManager.setTempBasal(
absoluteRate, absoluteRate,
durationInMinutes.toShort(), durationInMinutes.toShort(),
@ -327,11 +336,6 @@ class OmnipodDashPumpPlugin @Inject constructor(
.map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) } .map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) }
.ignoreElements(), .ignoreElements(),
pre = observeNoActiveTempBasal(true), pre = observeNoActiveTempBasal(true),
tempBasal = OmnipodDashPodStateManager.TempBasal(
startTime = System.currentTimeMillis(),
rate = absoluteRate,
durationInMinutes = durationInMinutes.toShort(),
)
).toPumpEnactResult() ).toPumpEnactResult()
} }
@ -386,8 +390,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
// enforceNew == true // enforceNew == true
aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") aapsLogger.info(LTag.PUMP, "Canceling existing temp basal")
executeProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
omnipodManager.stopTempBasal().ignoreElements() command = omnipodManager.stopTempBasal().ignoreElements()
) )
} }
} }
@ -582,17 +586,17 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun resumeDelivery(): PumpEnactResult { private fun resumeDelivery(): PumpEnactResult {
return profileFunction.getProfile()?.let { return profileFunction.getProfile()?.let {
executeProgrammingCommand( executeProgrammingCommand(
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements(),
pre = observeDeliverySuspended(), pre = observeDeliverySuspended(),
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements()
).toPumpEnactResult() ).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
} }
private fun deactivatePod(): PumpEnactResult { private fun deactivatePod(): PumpEnactResult {
return executeProgrammingCommand( return executeProgrammingCommand(
history.createRecord(OmnipodCommandType.DEACTIVATE_POD), historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
omnipodManager.deactivatePod().ignoreElements() command = omnipodManager.deactivatePod().ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
} }
@ -608,8 +612,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun playTestBeep(): PumpEnactResult { private fun playTestBeep(): PumpEnactResult {
return executeProgrammingCommand( return executeProgrammingCommand(
history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP), historyEntry = history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements() command = omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements()
).toPumpEnactResult() ).toPumpEnactResult()
} }
@ -635,19 +639,19 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun executeProgrammingCommand( private fun executeProgrammingCommand(
historyEntry: Single<String>,
command: Completable,
pre: Completable = Completable.complete(), pre: Completable = Completable.complete(),
historyEntry: Single<String>,
activeCommandEntry: (historyId: String) -> Single<OmnipodDashPodStateManager.ActiveCommand> =
{ historyId -> podStateManager.createActiveCommand(historyId) },
command: Completable,
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, tempBasal) } .flatMap { activeCommandEntry(it) }
.ignoreElement(), .ignoreElement(),
command.doOnError { command.doOnError {
podStateManager.activeCommand?.sendError = it podStateManager.activeCommand?.sendError = it

View file

@ -6,15 +6,10 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.NakResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PodAlarmException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.NakResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -88,7 +83,7 @@ class Session(
val response = parseResponse(decrypted) val response = parseResponse(decrypted)
if (!responseType.isInstance(response)) { /*if (!responseType.isInstance(response)) {
if (response is AlarmStatusResponse) { if (response is AlarmStatusResponse) {
throw PodAlarmException(response) throw PodAlarmException(response)
} }
@ -98,6 +93,8 @@ class Session(
throw IllegalResponseException(responseType, response) throw IllegalResponseException(responseType, response)
} }
*/
sessionKeys.msgSequenceNumber++ sessionKeys.msgSequenceNumber++
val ack = getAck(responseMsgPacket) val ack = getAck(responseMsgPacket)
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack") aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack")

View file

@ -23,7 +23,7 @@ class BasalProgram(
val hourOfDay = instance[Calendar.HOUR_OF_DAY] val hourOfDay = instance[Calendar.HOUR_OF_DAY]
val minuteOfHour = instance[Calendar.MINUTE] val minuteOfHour = instance[Calendar.MINUTE]
val slotIndex = hourOfDay * 2 + minuteOfHour.div(30) val slotIndex = hourOfDay * 2 + minuteOfHour.div(30)
val slot = segments.find { it.startSlotIndex <= slotIndex && slotIndex< it.endSlotIndex } val slot = segments.find { it.startSlotIndex <= slotIndex && slotIndex < it.endSlotIndex }
return (slot?.basalRateInHundredthUnitsPerHour ?: 0).toDouble() / 100 return (slot?.basalRateInHundredthUnitsPerHour ?: 0).toDouble() / 100
} }

View file

@ -73,7 +73,7 @@ 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, tempBasal: TempBasal?=null): fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null, tempBasal: TempBasal? = null):
Single<ActiveCommand> Single<ActiveCommand>
fun updateActiveCommand(): Maybe<CommandConfirmed> fun updateActiveCommand(): Maybe<CommandConfirmed>
fun observeNoActiveCommand(): Observable<PodEvent> fun observeNoActiveCommand(): Observable<PodEvent>

View file

@ -147,7 +147,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
override val tempBasalActive: Boolean override val tempBasalActive: Boolean
get() = !isSuspended && tempBasal?.let { get() = !isSuspended && tempBasal?.let {
it.startTime + it.durationInMinutes *60 * 1000 > System.currentTimeMillis() it.startTime + it.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
} ?: false } ?: false
override var basalProgram: BasalProgram? override var basalProgram: BasalProgram?
@ -388,7 +388,10 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
LTag.PUMP, LTag.PUMP,
"Not implemented: OmnipodDashPodStateManagerImpl.updateFromAlarmStatusResponse(AlarmStatusResponse)" "Not implemented: OmnipodDashPodStateManagerImpl.updateFromAlarmStatusResponse(AlarmStatusResponse)"
) )
logger.info(
LTag.PUMP,
"Received AlarmStatusReponse: $response"
)
store() store()
rxBus.send(EventOmnipodDashPumpValuesChanged()) rxBus.send(EventOmnipodDashPumpValuesChanged())
} }

View file

@ -42,7 +42,6 @@ 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
@ -346,7 +345,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
podInfoBinding.podActiveAlerts.text = podStateManager.activeAlerts?.let { podInfoBinding.podActiveAlerts.text = podStateManager.activeAlerts?.let {
it.map { it.toString() }.joinToString(",") it.map { it.toString() }.joinToString(",")
} ?: PLACEHOLDER } ?: PLACEHOLDER
} }
if (errors.size == 0) { if (errors.size == 0) {