Merge pull request #32 from 0pen-dash/avereha/temp-basals
Avereha/temp basals
This commit is contained in:
commit
9036544516
26 changed files with 350 additions and 229 deletions
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEven
|
||||||
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.BeepType
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmed
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
||||||
|
@ -25,9 +26,11 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBas
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
|
||||||
import info.nightscout.androidaps.queue.commands.CustomCommand
|
import info.nightscout.androidaps.queue.commands.CustomCommand
|
||||||
|
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.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
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.blockingSubscribeBy
|
||||||
|
@ -44,6 +47,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val history: DashHistory,
|
private val history: DashHistory,
|
||||||
|
private val pumpSync: PumpSync,
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
resourceHelper: ResourceHelper,
|
resourceHelper: ResourceHelper,
|
||||||
|
@ -151,12 +155,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
||||||
return executeProgrammingCommand(
|
return executeSimpleProgrammingCommand(
|
||||||
history.createRecord(
|
history.createRecord(
|
||||||
commandType = OmnipodCommandType.SET_BASAL_PROFILE
|
commandType = OmnipodCommandType.SET_BASAL_PROFILE
|
||||||
),
|
),
|
||||||
omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile))
|
omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).ignoreElements()
|
||||||
)
|
).toPumpEnactResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let {
|
override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let {
|
||||||
|
@ -240,10 +244,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
|
|
||||||
override fun stopBolusDelivering() {
|
override fun stopBolusDelivering() {
|
||||||
// TODO update Treatments (?)
|
// TODO update Treatments (?)
|
||||||
executeProgrammingCommand(
|
executeSimpleProgrammingCommand(
|
||||||
history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
|
history.createRecord(OmnipodCommandType.CANCEL_BOLUS),
|
||||||
omnipodManager.stopBolus(),
|
omnipodManager.stopBolus().ignoreElements()
|
||||||
)
|
).toPumpEnactResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setTempBasalAbsolute(
|
override fun setTempBasalAbsolute(
|
||||||
|
@ -253,25 +257,85 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
enforceNew: Boolean,
|
enforceNew: Boolean,
|
||||||
tbrType: PumpSync.TemporaryBasalType
|
tbrType: PumpSync.TemporaryBasalType
|
||||||
): PumpEnactResult {
|
): PumpEnactResult {
|
||||||
// TODO update Treatments
|
val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false)
|
||||||
// TODO check for existing basal
|
|
||||||
// check existing basal(locally and maybe? get status)
|
return executeSimpleProgrammingCommand(
|
||||||
// if enforceNew -> cancel it()
|
historyEntry = history.createRecord(
|
||||||
// else -> return error that existing basal is running
|
|
||||||
// set new temp basal
|
|
||||||
// update treatments
|
|
||||||
// profit
|
|
||||||
return executeProgrammingCommand(
|
|
||||||
history.createRecord(
|
|
||||||
commandType = OmnipodCommandType.SET_TEMPORARY_BASAL,
|
commandType = OmnipodCommandType.SET_TEMPORARY_BASAL,
|
||||||
tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate)
|
tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate)
|
||||||
),
|
),
|
||||||
omnipodManager.setTempBasal(
|
command = omnipodManager.setTempBasal(
|
||||||
absoluteRate,
|
absoluteRate,
|
||||||
durationInMinutes.toShort()
|
durationInMinutes.toShort(),
|
||||||
|
tempBasalBeeps
|
||||||
|
)
|
||||||
|
.filter { podEvent -> podEvent is PodEvent.CommandSent }
|
||||||
|
.map { pumpSyncTempBasal(it, tbrType) }
|
||||||
|
.ignoreElements(),
|
||||||
|
pre = observeNoActiveTempBasal()
|
||||||
|
).toPumpEnactResult()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pumpSyncTempBasal(
|
||||||
|
podEvent: PodEvent,
|
||||||
|
tbrType: PumpSync.TemporaryBasalType
|
||||||
|
): Boolean {
|
||||||
|
val activeCommand = podStateManager.activeCommand
|
||||||
|
if (activeCommand == null || podEvent !is PodEvent.CommandSent) {
|
||||||
|
throw IllegalArgumentException(
|
||||||
|
"No active command or illegal podEvent: " +
|
||||||
|
"activeCommand=$activeCommand" +
|
||||||
|
"podEvent=$podEvent"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val historyEntry = history.getById(activeCommand.historyId)
|
||||||
|
val record = historyEntry.record
|
||||||
|
if (record == null || !(record is TempBasalRecord)) {
|
||||||
|
throw IllegalArgumentException("Illegal recording in history: $record. Expected a temp basal")
|
||||||
|
}
|
||||||
|
val ret = pumpSync.syncTemporaryBasalWithPumpId(
|
||||||
|
timestamp = historyEntry.createdAt,
|
||||||
|
rate = record.rate,
|
||||||
|
duration = T.mins(record.duration.toLong()).msecs(),
|
||||||
|
isAbsolute = true,
|
||||||
|
type = tbrType,
|
||||||
|
pumpId = historyEntry.pumpId(),
|
||||||
|
pumpType = PumpType.OMNIPOD_DASH,
|
||||||
|
pumpSerial = serialNumber()
|
||||||
|
)
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Pump sync temp basal: $ret")
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeNoActiveTempBasal(): Completable {
|
||||||
|
return Completable.defer {
|
||||||
|
val expectedState = pumpSync.expectedPumpState()
|
||||||
|
if (expectedState.temporaryBasal == null) {
|
||||||
|
aapsLogger.info(LTag.PUMP, "No temporary basal to cancel")
|
||||||
|
Completable.complete()
|
||||||
|
} else {
|
||||||
|
// enforceNew == true
|
||||||
|
aapsLogger.info(LTag.PUMP, "Canceling existing temp basal")
|
||||||
|
executeSimpleProgrammingCommand(
|
||||||
|
history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
|
||||||
|
omnipodManager.stopTempBasal().ignoreElements()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeActiveTempBasal(): Completable {
|
||||||
|
return Completable.defer {
|
||||||
|
if (podStateManager.tempBasalActive)
|
||||||
|
Completable.complete()
|
||||||
|
else
|
||||||
|
Completable.error(
|
||||||
|
java.lang.IllegalStateException(
|
||||||
|
"There is no active basal to cancel"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setTempBasalPercent(
|
override fun setTempBasalPercent(
|
||||||
percent: Int,
|
percent: Int,
|
||||||
|
@ -292,12 +356,48 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
|
||||||
// TODO update Treatments
|
return executeSimpleProgrammingCommand(
|
||||||
return executeProgrammingCommand(
|
historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
|
||||||
history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL),
|
command = omnipodManager.stopTempBasal().ignoreElements(),
|
||||||
omnipodManager.stopTempBasal()
|
pre = observeActiveTempBasal(),
|
||||||
|
).toPumpEnactResult()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Completable.toPumpEnactResult(): PumpEnactResult {
|
||||||
|
return this.toSingleDefault(PumpEnactResult(injector).success(true).enacted(true))
|
||||||
|
.onErrorReturnItem(PumpEnactResult(injector).success(false).enacted(false))
|
||||||
|
.blockingGet()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleCommandConfirmation(confirmation: CommandConfirmed) {
|
||||||
|
val historyEntry = history.getById(confirmation.historyId)
|
||||||
|
when (historyEntry.commandType) {
|
||||||
|
OmnipodCommandType.CANCEL_TEMPORARY_BASAL ->
|
||||||
|
// We can't invalidate this command,
|
||||||
|
// and this is why it is pumpSync-ed at this point
|
||||||
|
if (confirmation.success) {
|
||||||
|
pumpSync.syncStopTemporaryBasalWithPumpId(
|
||||||
|
historyEntry.createdAt,
|
||||||
|
historyEntry.pumpId(),
|
||||||
|
PumpType.OMNIPOD_DASH,
|
||||||
|
serialNumber()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
OmnipodCommandType.SET_TEMPORARY_BASAL ->
|
||||||
|
// This treatment was synced before sending the command
|
||||||
|
if (!confirmation.success) {
|
||||||
|
// TODO: the ID here is the temp basal id, not the pumpId!!
|
||||||
|
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId())
|
||||||
|
}
|
||||||
|
|
||||||
|
else ->
|
||||||
|
aapsLogger.warn(
|
||||||
|
LTag.PUMP,
|
||||||
|
"Will not sync confirmed command of type: $historyEntry and " +
|
||||||
|
"succes: ${confirmation.success}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun cancelExtendedBolus(): PumpEnactResult {
|
override fun cancelExtendedBolus(): PumpEnactResult {
|
||||||
// TODO i18n
|
// TODO i18n
|
||||||
|
@ -414,26 +514,26 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun suspendDelivery(): PumpEnactResult {
|
private fun suspendDelivery(): PumpEnactResult {
|
||||||
return executeProgrammingCommand(
|
return executeSimpleProgrammingCommand(
|
||||||
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
||||||
omnipodManager.suspendDelivery()
|
omnipodManager.suspendDelivery().ignoreElements()
|
||||||
)
|
).toPumpEnactResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resumeDelivery(): PumpEnactResult {
|
private fun resumeDelivery(): PumpEnactResult {
|
||||||
return profileFunction.getProfile()?.let {
|
return profileFunction.getProfile()?.let {
|
||||||
executeProgrammingCommand(
|
executeSimpleProgrammingCommand(
|
||||||
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
||||||
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it))
|
omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements()
|
||||||
)
|
).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 executeSimpleProgrammingCommand(
|
||||||
history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
|
history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
|
||||||
omnipodManager.deactivatePod()
|
omnipodManager.deactivatePod().ignoreElements()
|
||||||
)
|
).toPumpEnactResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleTimeChange(): PumpEnactResult {
|
private fun handleTimeChange(): PumpEnactResult {
|
||||||
|
@ -447,10 +547,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playTestBeep(): PumpEnactResult {
|
private fun playTestBeep(): PumpEnactResult {
|
||||||
return executeProgrammingCommand(
|
return executeSimpleProgrammingCommand(
|
||||||
history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
|
history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP),
|
||||||
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP)
|
omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements()
|
||||||
)
|
).toPumpEnactResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {
|
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {
|
||||||
|
@ -474,50 +574,27 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
||||||
commandQueue.customCommand(CommandHandleTimeChange(false), null)
|
commandQueue.customCommand(CommandHandleTimeChange(false), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeAddNewActiveCommandToHistory(observeCreateHistoryEntry: Single<String>): Observable<PodEvent> {
|
private fun executeSimpleProgrammingCommand(
|
||||||
return observeCreateHistoryEntry.flatMapObservable {
|
historyEntry: Single<String>,
|
||||||
podStateManager.createActiveCommand(it).toObservable<PodEvent>()
|
command: Completable,
|
||||||
}
|
pre: Completable = Completable.complete(),
|
||||||
}
|
): Completable {
|
||||||
|
return Completable.concat(
|
||||||
private fun executeProgrammingCommand(
|
|
||||||
observeCreateHistoryEntry: Single<String>,
|
|
||||||
command: Observable<PodEvent>
|
|
||||||
): PumpEnactResult {
|
|
||||||
return Single.create<PumpEnactResult> { source ->
|
|
||||||
Observable.concat(
|
|
||||||
listOf(
|
listOf(
|
||||||
podStateManager.observeNoActiveCommand(),
|
pre,
|
||||||
observeAddNewActiveCommandToHistory(observeCreateHistoryEntry),
|
podStateManager.observeNoActiveCommand().ignoreElements(),
|
||||||
command,
|
historyEntry
|
||||||
history.updateFromState(podStateManager).toObservable(),
|
.flatMap { podStateManager.createActiveCommand(it) }
|
||||||
podStateManager.updateActiveCommand().toObservable(),
|
.ignoreElement(),
|
||||||
|
command.doOnError {
|
||||||
|
podStateManager.activeCommand?.sendError = it
|
||||||
|
aapsLogger.error(LTag.PUMP, "Error executing command", it)
|
||||||
|
}.onErrorComplete(),
|
||||||
|
history.updateFromState(podStateManager),
|
||||||
|
podStateManager.updateActiveCommand()
|
||||||
|
.map { handleCommandConfirmation(it) }
|
||||||
|
.ignoreElement()
|
||||||
)
|
)
|
||||||
).subscribeBy(
|
|
||||||
onNext = { podEvent ->
|
|
||||||
aapsLogger.debug(
|
|
||||||
LTag.PUMP,
|
|
||||||
"Received PodEvent: $podEvent"
|
|
||||||
)
|
)
|
||||||
},
|
|
||||||
onError = { throwable ->
|
|
||||||
aapsLogger.error(LTag.PUMP, "Error executing command", throwable)
|
|
||||||
// Here we assume that onError will be called only BEFORE we manage to send a command
|
|
||||||
// If it gets called later, we will have the command as "not sent" in history and will not try to
|
|
||||||
// get it's final status, even if it was send
|
|
||||||
|
|
||||||
podStateManager.maybeMarkActiveCommandFailed()
|
|
||||||
source.onSuccess(
|
|
||||||
PumpEnactResult(injector).success(false).enacted(false).comment(throwable.toString())
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onComplete = {
|
|
||||||
aapsLogger.debug("Command completed")
|
|
||||||
source.onSuccess(
|
|
||||||
PumpEnactResult(injector).success(true).enacted(true)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}.blockingGet()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ interface OmnipodDashManager {
|
||||||
|
|
||||||
fun setTime(): Observable<PodEvent>
|
fun setTime(): Observable<PodEvent>
|
||||||
|
|
||||||
fun setTempBasal(rate: Double, durationInMinutes: Short): Observable<PodEvent>
|
fun setTempBasal(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable<PodEvent>
|
||||||
|
|
||||||
fun stopTempBasal(): Observable<PodEvent>
|
fun stopTempBasal(): Observable<PodEvent>
|
||||||
|
|
||||||
|
|
|
@ -460,14 +460,14 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
return Observable.empty()
|
return Observable.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeSendProgramTempBasalCommand(rate: Double, durationInMinutes: Short): Observable<PodEvent> {
|
private fun observeSendProgramTempBasalCommand(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable<PodEvent> {
|
||||||
return Observable.defer {
|
return Observable.defer {
|
||||||
// TODO cancel current temp basal (if active)
|
|
||||||
bleManager.sendCommand(
|
bleManager.sendCommand(
|
||||||
ProgramTempBasalCommand.Builder()
|
ProgramTempBasalCommand.Builder()
|
||||||
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
||||||
.setUniqueId(podStateManager.uniqueId!!.toInt())
|
.setUniqueId(podStateManager.uniqueId!!.toInt())
|
||||||
.setNonce(NONCE)
|
.setNonce(NONCE)
|
||||||
|
.setProgramReminder(ProgramReminder(tempBasalBeeps, tempBasalBeeps, 0))
|
||||||
.setRateInUnitsPerHour(rate)
|
.setRateInUnitsPerHour(rate)
|
||||||
.setDurationInMinutes(durationInMinutes)
|
.setDurationInMinutes(durationInMinutes)
|
||||||
.build(),
|
.build(),
|
||||||
|
@ -476,11 +476,11 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setTempBasal(rate: Double, durationInMinutes: Short): Observable<PodEvent> {
|
override fun setTempBasal(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable<PodEvent> {
|
||||||
return Observable.concat(
|
return Observable.concat(
|
||||||
observePodRunning,
|
observePodRunning,
|
||||||
observeConnectToPod,
|
observeConnectToPod,
|
||||||
observeSendProgramTempBasalCommand(rate, durationInMinutes)
|
observeSendProgramTempBasalCommand(rate, durationInMinutes, tempBasalBeeps)
|
||||||
)
|
)
|
||||||
// TODO these would be common for any observable returned in a public function in this class
|
// TODO these would be common for any observable returned in a public function in this class
|
||||||
.doOnNext(PodEventInterceptor())
|
.doOnNext(PodEventInterceptor())
|
||||||
|
@ -700,7 +700,7 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
inner class ErrorInterceptor : Consumer<Throwable> {
|
inner class ErrorInterceptor : Consumer<Throwable> {
|
||||||
|
|
||||||
override fun accept(throwable: Throwable) {
|
override fun accept(throwable: Throwable) {
|
||||||
logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable.javaClass.simpleName}")
|
logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: $throwable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.ConnectionState
|
||||||
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.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.Response
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
|
||||||
|
@ -11,7 +11,7 @@ interface OmnipodDashBleManager {
|
||||||
|
|
||||||
fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent>
|
fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent>
|
||||||
|
|
||||||
fun getStatus(): ConnectionStatus
|
fun getStatus(): ConnectionState
|
||||||
|
|
||||||
fun connect(): Observable<PodEvent>
|
fun connect(): Observable<PodEvent>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptio
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.*
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.*
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
|
||||||
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.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.Response
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
|
||||||
|
@ -34,7 +33,6 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
|
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
|
||||||
private var connection: Connection? = null
|
private var connection: Connection? = null
|
||||||
private var status: ConnectionStatus = ConnectionStatus.IDLE
|
|
||||||
private val ids = Ids(podState)
|
private val ids = Ids(podState)
|
||||||
|
|
||||||
override fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> =
|
override fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> =
|
||||||
|
@ -85,13 +83,9 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
?: throw NotConnectedException("Missing session")
|
?: throw NotConnectedException("Missing session")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStatus(): ConnectionStatus {
|
override fun getStatus(): ConnectionState {
|
||||||
// TODO is this used?
|
return connection?.let { getStatus() }
|
||||||
var s: ConnectionStatus
|
?: NotConnected
|
||||||
synchronized(status) {
|
|
||||||
s = status
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun connect(): Observable<PodEvent> = Observable.create { emitter ->
|
override fun connect(): Observable<PodEvent> = Observable.create { emitter ->
|
||||||
|
@ -106,9 +100,10 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
?: throw FailedToConnectException("Missing bluetoothAddress, activate the pod first")
|
?: throw FailedToConnectException("Missing bluetoothAddress, activate the pod first")
|
||||||
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
||||||
val conn = connection
|
val conn = connection
|
||||||
?: Connection(podDevice, aapsLogger, context)
|
?: Connection(podDevice, aapsLogger, context, podState)
|
||||||
connection = conn
|
connection = conn
|
||||||
if (conn.connectionState() is Connected) {
|
if (conn.connectionState() is Connected) {
|
||||||
|
podState.lastConnection = System.currentTimeMillis()
|
||||||
if (conn.session == null) {
|
if (conn.session == null) {
|
||||||
emitter.onNext(PodEvent.EstablishingSession)
|
emitter.onNext(PodEvent.EstablishingSession)
|
||||||
establishSession(1.toByte())
|
establishSession(1.toByte())
|
||||||
|
@ -121,7 +116,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
conn.connect()
|
conn.connect()
|
||||||
emitter.onNext(PodEvent.BluetoothConnected(podAddress))
|
emitter.onNext(PodEvent.BluetoothConnected(podAddress))
|
||||||
|
podState.lastConnection = System.currentTimeMillis()
|
||||||
emitter.onNext(PodEvent.EstablishingSession)
|
emitter.onNext(PodEvent.EstablishingSession)
|
||||||
establishSession(1.toByte())
|
establishSession(1.toByte())
|
||||||
emitter.onNext(PodEvent.Connected)
|
emitter.onNext(PodEvent.Connected)
|
||||||
|
@ -190,7 +185,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
|
|
||||||
emitter.onNext(PodEvent.BluetoothConnecting)
|
emitter.onNext(PodEvent.BluetoothConnecting)
|
||||||
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
||||||
val conn = Connection(podDevice, aapsLogger, context)
|
val conn = Connection(podDevice, aapsLogger, context, podState)
|
||||||
connection = conn
|
connection = conn
|
||||||
emitter.onNext(PodEvent.BluetoothConnected(podAddress))
|
emitter.onNext(PodEvent.BluetoothConnected(podAddress))
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io
|
|
||||||
|
|
||||||
enum class IOState {
|
|
||||||
IDLE, WRITING, READING
|
|
||||||
}
|
|
|
@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CmdBl
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.DataBleIO
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.DataBleIO
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.IncomingPackets
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.IncomingPackets
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||||
|
|
||||||
sealed class ConnectionState
|
sealed class ConnectionState
|
||||||
|
|
||||||
|
@ -29,7 +30,8 @@ object NotConnected : ConnectionState()
|
||||||
class Connection(
|
class Connection(
|
||||||
private val podDevice: BluetoothDevice,
|
private val podDevice: BluetoothDevice,
|
||||||
private val aapsLogger: AAPSLogger,
|
private val aapsLogger: AAPSLogger,
|
||||||
context: Context
|
context: Context,
|
||||||
|
private val podState: OmnipodDashPodStateManager
|
||||||
) : DisconnectHandler {
|
) : DisconnectHandler {
|
||||||
|
|
||||||
private val incomingPackets = IncomingPackets()
|
private val incomingPackets = IncomingPackets()
|
||||||
|
@ -50,13 +52,15 @@ class Connection(
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}")
|
||||||
|
|
||||||
val autoConnect = false
|
val autoConnect = false
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
|
||||||
gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
|
gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
|
||||||
// OnDisconnect can be called after this point!!!
|
// OnDisconnect can be called after this point!!!
|
||||||
val state = waitForConnection()
|
val state = waitForConnection()
|
||||||
if (state !is Connected) {
|
if (state !is Connected) {
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
|
||||||
throw FailedToConnectException(podDevice.address)
|
throw FailedToConnectException(podDevice.address)
|
||||||
}
|
}
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
|
||||||
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
|
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
|
||||||
val discoveredCharacteristics = discoverer.discoverServices()
|
val discoveredCharacteristics = discoverer.discoverServices()
|
||||||
cmdBleIO = CmdBleIO(
|
cmdBleIO = CmdBleIO(
|
||||||
|
@ -90,13 +94,17 @@ class Connection(
|
||||||
disconnect()
|
disconnect()
|
||||||
}
|
}
|
||||||
aapsLogger.debug("Connecting")
|
aapsLogger.debug("Connecting")
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
|
||||||
|
|
||||||
if (!gattConnection.connect()) {
|
if (!gattConnection.connect()) {
|
||||||
throw FailedToConnectException("connect() returned false")
|
throw FailedToConnectException("connect() returned false")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitForConnection() is NotConnected) {
|
if (waitForConnection() !is Connected) {
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
|
||||||
throw FailedToConnectException(podDevice.address)
|
throw FailedToConnectException(podDevice.address)
|
||||||
}
|
}
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
|
||||||
|
|
||||||
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
|
val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks)
|
||||||
val discovered = discoverer.discoverServices()
|
val discovered = discoverer.discoverServices()
|
||||||
|
@ -110,6 +118,8 @@ class Connection(
|
||||||
|
|
||||||
fun disconnect() {
|
fun disconnect() {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting")
|
||||||
|
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
|
||||||
|
|
||||||
gattConnection.disconnect()
|
gattConnection.disconnect()
|
||||||
bleCommCallbacks.resetConnection()
|
bleCommCallbacks.resetConnection()
|
||||||
session = null
|
session = null
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status
|
|
||||||
|
|
||||||
enum class ConnectionStatus {
|
|
||||||
IDLE,
|
|
||||||
BUSY,
|
|
||||||
CONNECTING,
|
|
||||||
ESTABLISHING_SESSION,
|
|
||||||
PAIRING,
|
|
||||||
RUNNING_COMMAND;
|
|
||||||
}
|
|
|
@ -65,6 +65,4 @@ sealed class PodEvent {
|
||||||
return "ResponseReceived(command=$command, response=$response)"
|
return "ResponseReceived(command=$command, response=$response)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CommandConfirmed(val historyId: String, val success: Boolean) : PodEvent()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state
|
||||||
|
|
||||||
|
class CommandConfirmed(val historyId: String, val success: Boolean)
|
|
@ -8,9 +8,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ interface OmnipodDashPodStateManager {
|
||||||
val isSuspended: Boolean
|
val isSuspended: Boolean
|
||||||
val isPodRunning: Boolean
|
val isPodRunning: Boolean
|
||||||
var lastConnection: Long
|
var lastConnection: Long
|
||||||
|
var bluetoothConnectionState: BluetoothConnectionState
|
||||||
|
|
||||||
val lastUpdatedSystem: Long // System.currentTimeMillis()
|
val lastUpdatedSystem: Long // System.currentTimeMillis()
|
||||||
val lastStatusResponseReceived: Long
|
val lastStatusResponseReceived: Long
|
||||||
|
@ -66,17 +67,21 @@ interface OmnipodDashPodStateManager {
|
||||||
fun updateFromPairing(uniqueId: Id, pairResult: PairResult)
|
fun updateFromPairing(uniqueId: Id, pairResult: PairResult)
|
||||||
fun reset()
|
fun reset()
|
||||||
|
|
||||||
fun createActiveCommand(historyId: String): Completable
|
fun createActiveCommand(historyId: String): Single<ActiveCommand>
|
||||||
fun updateActiveCommand(): Maybe<PodEvent>
|
fun updateActiveCommand(): Maybe<CommandConfirmed>
|
||||||
fun observeNoActiveCommand(): Observable<PodEvent>
|
fun observeNoActiveCommand(): Observable<PodEvent>
|
||||||
fun maybeMarkActiveCommandFailed()
|
|
||||||
|
|
||||||
data class ActiveCommand(
|
data class ActiveCommand(
|
||||||
val sequence: Short,
|
val sequence: Short,
|
||||||
val createdRealtime: Long,
|
val createdRealtime: Long,
|
||||||
var sentRealtime: Long = 0,
|
var sentRealtime: Long = 0,
|
||||||
val historyId: String
|
val historyId: String,
|
||||||
|
var sendError: Throwable?,
|
||||||
)
|
)
|
||||||
// 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
|
||||||
|
|
||||||
|
enum class BluetoothConnectionState {
|
||||||
|
CONNECTING, CONNECTED, DISCONNECTED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -148,7 +148,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
get() = podState.tempBasal
|
get() = podState.tempBasal
|
||||||
|
|
||||||
override val tempBasalActive: Boolean
|
override val tempBasalActive: Boolean
|
||||||
get() = tempBasal != null && tempBasal!!.startTime + tempBasal!!.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
|
get() = podState.deliveryStatus in arrayOf(DeliveryStatus.TEMP_BASAL_ACTIVE, DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE)
|
||||||
|
|
||||||
override var basalProgram: BasalProgram?
|
override var basalProgram: BasalProgram?
|
||||||
get() = podState.basalProgram
|
get() = podState.basalProgram
|
||||||
|
@ -160,6 +160,14 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
override val lastStatusResponseReceived: Long
|
override val lastStatusResponseReceived: Long
|
||||||
get() = podState.lastStatusResponseReceived
|
get() = podState.lastStatusResponseReceived
|
||||||
|
|
||||||
|
override var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState
|
||||||
|
get() = podState.bluetoothConnectionState
|
||||||
|
set(bluetoothConnectionState) {
|
||||||
|
podState.bluetoothConnectionState = bluetoothConnectionState
|
||||||
|
rxBus.send(EventOmnipodDashPumpValuesChanged())
|
||||||
|
// do not store
|
||||||
|
}
|
||||||
|
|
||||||
override fun increaseMessageSequenceNumber() {
|
override fun increaseMessageSequenceNumber() {
|
||||||
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
|
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
|
||||||
store()
|
store()
|
||||||
|
@ -183,14 +191,17 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
get() = podState.activeCommand
|
get() = podState.activeCommand
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun createActiveCommand(historyId: String) = Completable.create { source ->
|
override fun createActiveCommand(historyId: String): Single<OmnipodDashPodStateManager.ActiveCommand> {
|
||||||
|
return Single.create { source ->
|
||||||
if (activeCommand == null) {
|
if (activeCommand == null) {
|
||||||
podState.activeCommand = OmnipodDashPodStateManager.ActiveCommand(
|
val command = OmnipodDashPodStateManager.ActiveCommand(
|
||||||
podState.messageSequenceNumber,
|
podState.messageSequenceNumber,
|
||||||
createdRealtime = SystemClock.elapsedRealtime(),
|
createdRealtime = SystemClock.elapsedRealtime(),
|
||||||
historyId = historyId
|
historyId = historyId,
|
||||||
|
sendError = null,
|
||||||
)
|
)
|
||||||
source.onComplete()
|
podState.activeCommand = command
|
||||||
|
source.onSuccess(command)
|
||||||
} else {
|
} else {
|
||||||
source.onError(
|
source.onError(
|
||||||
java.lang.IllegalStateException(
|
java.lang.IllegalStateException(
|
||||||
|
@ -200,6 +211,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun observeNoActiveCommand(): Observable<PodEvent> {
|
override fun observeNoActiveCommand(): Observable<PodEvent> {
|
||||||
|
@ -218,35 +230,35 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun maybeMarkActiveCommandFailed() {
|
override fun updateActiveCommand() = Maybe.create<CommandConfirmed> { source ->
|
||||||
podState.activeCommand?.run {
|
|
||||||
if (sentRealtime < createdRealtime) {
|
|
||||||
// command was not sent
|
|
||||||
podState.activeCommand = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun updateActiveCommand() = Maybe.create<PodEvent> { source ->
|
|
||||||
podState.activeCommand?.run {
|
podState.activeCommand?.run {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Trying to confirm active command with parameters: $activeCommand " +
|
"Trying to confirm active command with parameters: $activeCommand " +
|
||||||
"lastResponse=$lastStatusResponseReceived " +
|
"lastResponse=$lastStatusResponseReceived " +
|
||||||
"$sequenceNumberOfLastProgrammingCommand $historyId"
|
"$sequenceNumberOfLastProgrammingCommand $historyId"
|
||||||
)
|
)
|
||||||
if (createdRealtime >= lastStatusResponseReceived)
|
|
||||||
|
if (sentRealtime < createdRealtime) { // command was not sent, clear it up
|
||||||
|
podState.activeCommand = null
|
||||||
|
source.onError(
|
||||||
|
this.sendError
|
||||||
|
?: java.lang.IllegalStateException(
|
||||||
|
"Could not send command and sendError is " +
|
||||||
|
"missing"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else if (createdRealtime >= lastStatusResponseReceived)
|
||||||
// we did not receive a valid response yet
|
// we did not receive a valid response yet
|
||||||
source.onComplete()
|
source.onComplete()
|
||||||
else {
|
else {
|
||||||
podState.activeCommand = null
|
podState.activeCommand = null
|
||||||
if (sequenceNumberOfLastProgrammingCommand == sequence)
|
if (sequenceNumberOfLastProgrammingCommand == sequence)
|
||||||
source.onSuccess(PodEvent.CommandConfirmed(historyId, true))
|
source.onSuccess(CommandConfirmed(historyId, true))
|
||||||
else
|
else
|
||||||
source.onSuccess(PodEvent.CommandConfirmed(historyId, false))
|
source.onSuccess(CommandConfirmed(historyId, false))
|
||||||
}
|
}
|
||||||
}
|
} ?: source.onComplete()
|
||||||
?: source.onComplete() // no active programming command
|
// no active programming command
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun increaseEapAkaSequenceNumber(): ByteArray {
|
override fun increaseEapAkaSequenceNumber(): ByteArray {
|
||||||
|
@ -377,7 +389,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
||||||
var lastConnection: Long = 0
|
var lastConnection: Long = 0
|
||||||
var lastUpdatedSystem: Long = 0
|
var lastUpdatedSystem: Long = 0
|
||||||
var lastStatusResponseReceived: Long = 0
|
var lastStatusResponseReceived: Long = 0
|
||||||
|
var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState =
|
||||||
|
OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
|
||||||
var messageSequenceNumber: Short = 0
|
var messageSequenceNumber: Short = 0
|
||||||
var sequenceNumberOfLastProgrammingCommand: Short? = null
|
var sequenceNumberOfLastProgrammingCommand: Short? = null
|
||||||
var activationTime: Long? = null
|
var activationTime: Long? = null
|
||||||
|
|
|
@ -35,6 +35,14 @@ class DashHistory @Inject constructor(
|
||||||
currentTimeMillis()
|
currentTimeMillis()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun getById(id: String): HistoryRecord {
|
||||||
|
val entry = dao.byIdBlocking(id)
|
||||||
|
if (entry == null) {
|
||||||
|
throw java.lang.IllegalArgumentException("history entry [$id] not found")
|
||||||
|
}
|
||||||
|
return historyMapper.entityToDomain(entry)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("ReturnCount")
|
@Suppress("ReturnCount")
|
||||||
fun createRecord(
|
fun createRecord(
|
||||||
commandType: OmnipodCommandType,
|
commandType: OmnipodCommandType,
|
||||||
|
@ -77,7 +85,6 @@ class DashHistory @Inject constructor(
|
||||||
fun updateFromState(podState: OmnipodDashPodStateManager) = Completable.defer {
|
fun updateFromState(podState: OmnipodDashPodStateManager) = Completable.defer {
|
||||||
podState.activeCommand?.run {
|
podState.activeCommand?.run {
|
||||||
when {
|
when {
|
||||||
|
|
||||||
createdRealtime <= podState.lastStatusResponseReceived &&
|
createdRealtime <= podState.lastStatusResponseReceived &&
|
||||||
sequence == podState.sequenceNumberOfLastProgrammingCommand ->
|
sequence == podState.sequenceNumberOfLastProgrammingCommand ->
|
||||||
dao.setInitialResult(historyId, InitialResult.SENT)
|
dao.setInitialResult(historyId, InitialResult.SENT)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
|
||||||
|
|
||||||
|
import com.github.guepardoapps.kulid.ULID
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
data class HistoryRecord(
|
data class HistoryRecord(
|
||||||
val id: String, // ULID
|
val id: String, // ULID
|
||||||
|
@ -11,4 +13,9 @@ data class HistoryRecord(
|
||||||
val record: Record?,
|
val record: Record?,
|
||||||
val resolvedResult: ResolvedResult?,
|
val resolvedResult: ResolvedResult?,
|
||||||
val resolvedAt: Long?
|
val resolvedAt: Long?
|
||||||
)
|
) {
|
||||||
|
fun pumpId(): Long {
|
||||||
|
val entropy = ULID.getEntropy(id)
|
||||||
|
return ByteBuffer.wrap(entropy).getLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ enum class BolusType {
|
||||||
companion object {
|
companion object {
|
||||||
fun fromBolusInfoBolusType(type: DetailedBolusInfo.BolusType): BolusType {
|
fun fromBolusInfoBolusType(type: DetailedBolusInfo.BolusType): BolusType {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
DetailedBolusInfo.BolusType.SMB -> SMB;
|
DetailedBolusInfo.BolusType.SMB -> SMB
|
||||||
else -> DEFAULT
|
else -> DEFAULT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ abstract class HistoryRecordDao {
|
||||||
@Query("SELECT * from historyrecords WHERE createdAt <= :since")
|
@Query("SELECT * from historyrecords WHERE createdAt <= :since")
|
||||||
abstract fun allSince(since: Long): Single<List<HistoryRecordEntity>>
|
abstract fun allSince(since: Long): Single<List<HistoryRecordEntity>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM historyrecords WHERE id = :id LIMIT 1")
|
||||||
|
abstract fun byIdBlocking(id: String): HistoryRecordEntity?
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
abstract fun saveBlocking(historyRecordEntity: HistoryRecordEntity)
|
abstract fun saveBlocking(historyRecordEntity: HistoryRecordEntity)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpSync
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||||
|
@ -58,6 +59,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
|
@Inject lateinit var pumpSync: PumpSync
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -211,11 +213,26 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
|
|
||||||
private fun updateUi() {
|
private fun updateUi() {
|
||||||
// TODO update bluetooth status
|
// TODO update bluetooth status
|
||||||
|
updateBluetoothStatus()
|
||||||
updateOmnipodStatus()
|
updateOmnipodStatus()
|
||||||
updatePodActionButtons()
|
updatePodActionButtons()
|
||||||
updateQueueStatus()
|
updateQueueStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateBluetoothStatus() {
|
||||||
|
bluetoothStatusBinding.omnipodDashBluetoothAddress.text = podStateManager.bluetoothAddress
|
||||||
|
?: PLACEHOLDER
|
||||||
|
bluetoothStatusBinding.omnipodDashBluetoothStatus.text =
|
||||||
|
when (podStateManager.bluetoothConnectionState) {
|
||||||
|
OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED ->
|
||||||
|
"{fa-bluetooth}"
|
||||||
|
OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED ->
|
||||||
|
"{fa-bluetooth-b}"
|
||||||
|
OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING ->
|
||||||
|
"{fa-bluetooth-b spin}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateOmnipodStatus() {
|
private fun updateOmnipodStatus() {
|
||||||
updateLastConnection()
|
updateLastConnection()
|
||||||
updateLastBolus()
|
updateLastBolus()
|
||||||
|
@ -246,10 +263,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
podStateManager.firmwareVersion.toString(),
|
podStateManager.firmwareVersion.toString(),
|
||||||
podStateManager.bluetoothVersion.toString()
|
podStateManager.bluetoothVersion.toString()
|
||||||
)
|
)
|
||||||
|
podInfoBinding.timeOnPod.text = podStateManager.minutesSinceActivation.toString() + " minutes"
|
||||||
// TODO
|
// TODO
|
||||||
/*
|
/*
|
||||||
podInfoBinding.timeOnPod.text = readableZonedTime(podStateManager.time)
|
|
||||||
podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) {
|
podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) {
|
||||||
Color.RED
|
Color.RED
|
||||||
} else {
|
} else {
|
||||||
|
@ -373,7 +389,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
if (podStateManager.isSuspended) {
|
if (podStateManager.isSuspended) {
|
||||||
resourceHelper.gs(R.string.omnipod_common_pod_status_suspended)
|
resourceHelper.gs(R.string.omnipod_common_pod_status_suspended)
|
||||||
} else {
|
} else {
|
||||||
resourceHelper.gs(R.string.omnipod_common_pod_status_running)
|
resourceHelper.gs(R.string.omnipod_common_pod_status_running) +
|
||||||
|
podStateManager.deliveryStatus?.let { " " + podStateManager.deliveryStatus.toString() }
|
||||||
|
// TODO Display deliveryStatus in a nice way
|
||||||
}
|
}
|
||||||
// TODO
|
// TODO
|
||||||
/*
|
/*
|
||||||
|
@ -421,10 +439,11 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTempBasal() {
|
private fun updateTempBasal() {
|
||||||
if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive) {
|
val tempBasal = podStateManager.tempBasal
|
||||||
val startTime = podStateManager.tempBasal!!.startTime
|
if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive && tempBasal != null) {
|
||||||
val rate = podStateManager.tempBasal!!.rate
|
val startTime = tempBasal.startTime
|
||||||
val duration = podStateManager.tempBasal!!.durationInMinutes
|
val rate = tempBasal.rate
|
||||||
|
val duration = tempBasal.durationInMinutes
|
||||||
|
|
||||||
val minutesRunning = 0 // TODO
|
val minutesRunning = 0 // TODO
|
||||||
|
|
||||||
|
@ -560,12 +579,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private fun readableDuration(time: Long): String {
|
private fun readableDuration(dateTime: Long): String {
|
||||||
// TODO
|
val duration = Duration(dateTime, System.currentTimeMillis())
|
||||||
return "TODO"
|
|
||||||
|
|
||||||
/*
|
|
||||||
val duration = Duration(dateTime, DateTime.now())
|
|
||||||
val hours = duration.standardHours.toInt()
|
val hours = duration.standardHours.toInt()
|
||||||
val minutes = duration.standardMinutes.toInt()
|
val minutes = duration.standardMinutes.toInt()
|
||||||
val seconds = duration.standardSeconds.toInt()
|
val seconds = duration.standardSeconds.toInt()
|
||||||
|
@ -585,8 +600,10 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
seconds < 24 * 60 * 60 -> { // < 1 day
|
seconds < 24 * 60 * 60 -> { // < 1 day
|
||||||
val minutesLeft = minutes % 60
|
val minutesLeft = minutes % 60
|
||||||
if (minutesLeft > 0)
|
if (minutesLeft > 0)
|
||||||
return resourceHelper.gs(R.string.omnipod_common_time_ago,
|
return resourceHelper.gs(
|
||||||
resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_common_minutes, minutesLeft, minutesLeft)))
|
R.string.omnipod_common_time_ago,
|
||||||
|
resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_common_minutes, minutesLeft, minutesLeft))
|
||||||
|
)
|
||||||
return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours))
|
return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,12 +611,13 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
|
||||||
val days = hours / 24
|
val days = hours / 24
|
||||||
val hoursLeft = hours % 24
|
val hoursLeft = hours % 24
|
||||||
if (hoursLeft > 0)
|
if (hoursLeft > 0)
|
||||||
return resourceHelper.gs(R.string.omnipod_common_time_ago,
|
return resourceHelper.gs(
|
||||||
resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_days, days, days), resourceHelper.gq(R.plurals.omnipod_common_hours, hoursLeft, hoursLeft)))
|
R.string.omnipod_common_time_ago,
|
||||||
|
resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_days, days, days), resourceHelper.gq(R.plurals.omnipod_common_hours, hoursLeft, hoursLeft))
|
||||||
|
)
|
||||||
return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days))
|
return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isQueueEmpty(): Boolean {
|
private fun isQueueEmpty(): Boolean {
|
||||||
|
|
|
@ -1,44 +1,6 @@
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1.5"
|
|
||||||
android:gravity="end"
|
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:text="@string/omnipod_dash_overview_bluetooth_address"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="5dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:paddingStart="2dp"
|
|
||||||
android:paddingEnd="2dp"
|
|
||||||
android:text=":"
|
|
||||||
android:textSize="14sp"
|
|
||||||
tools:ignore="HardcodedText" />
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/omnipod_dash_bluetooth_status"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="start"
|
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -65,7 +27,8 @@
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<com.joanzapata.iconify.widget.IconTextView
|
|
||||||
|
<TextView
|
||||||
android:id="@+id/omnipod_dash_bluetooth_address"
|
android:id="@+id/omnipod_dash_bluetooth_address"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -73,6 +36,43 @@
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
android:paddingStart="5dp"
|
android:paddingStart="5dp"
|
||||||
android:paddingEnd="5dp"
|
android:paddingEnd="5dp"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.5"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:text="@string/omnipod_dash_overview_bluetooth_address"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="5dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:paddingStart="2dp"
|
||||||
|
android:paddingEnd="2dp"
|
||||||
|
android:text=":"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<com.joanzapata.iconify.widget.IconTextView
|
||||||
|
android:id="@+id/omnipod_dash_bluetooth_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="start"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
android:text="{fa-bluetooth-b} "
|
android:text="{fa-bluetooth-b} "
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.spongycastle.util.encoders.Hex
|
import org.spongycastle.util.encoders.Hex
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||||
|
|
||||||
import com.google.crypto.tink.subtle.Hex
|
import com.google.crypto.tink.subtle.Hex
|
||||||
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||||
|
|
||||||
import com.google.crypto.tink.subtle.Hex
|
import com.google.crypto.tink.subtle.Hex
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner
|
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||||
|
|
||||||
import com.google.crypto.tink.subtle.Hex
|
import com.google.crypto.tink.subtle.Hex
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter
|
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.ArgumentMatchers.anyInt
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
||||||
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.spongycastle.util.encoders.Hex
|
import org.spongycastle.util.encoders.Hex
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
||||||
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
|
||||||
import info.nightscout.androidaps.extensions.toHex
|
import info.nightscout.androidaps.extensions.toHex
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.spongycastle.util.encoders.Hex
|
import org.spongycastle.util.encoders.Hex
|
||||||
|
|
Loading…
Reference in a new issue