- TBR problem fix: when TBR is cancelled, if there is TBR with TemporalId waiting, we update duration on that item

- Bolus/SMB problem: extended pumpSync to add ignoreBolusTypeOnUpdate to both methods: syncBolusWithTempId, syncBolusWithPumpId
This commit is contained in:
Andy Rozman 2021-10-31 12:39:23 +00:00
parent 42daad43f4
commit 63ddf99913
7 changed files with 156 additions and 34 deletions

View file

@ -90,8 +90,9 @@ interface PumpSync {
**/
fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String): Boolean
/**
* Synchronization of boluses with temporary id
* Synchronization of boluses with temporary id (with
*
* Search for combination of temporaryId, PumpType, pumpSerial
*
@ -110,9 +111,12 @@ interface PumpSync {
* @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number
* @param ignoreBolusTypeOnUpdate bolusType won't be updated, if item already exists
* @return true if record is successfully updated
**/
fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean
fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String, ignoreBolusTypeOnUpdate :
Boolean = false): Boolean
/**
* Synchronization of boluses
@ -123,15 +127,40 @@ interface PumpSync {
* If exists, amount, type (if provided) and timestamp is updated
* isValid field is preserved
*
* NOTE: this method can be removed, when all drivers are in kotlin
*
* @param timestamp timestamp of event from pump history
* @param amount amount of insulin
* @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number
* @return true if new record is created
**/
fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean
/**
* Synchronization of boluses (with bolusType ignore)
*
* Search for combination of pumpId, PumpType, pumpSerial
*
* If db record doesn't exist, new record is created.
* If exists, amount, type (if provided) and timestamp is updated
* isValid field is preserved
*
* @param timestamp timestamp of event from pump history
* @param amount amount of insulin
* @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number
* @param ignoreBolusTypeOnUpdate bolusType won't be updated, if item already exists
* @return true if new record is created
**/
fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean
fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String, ignoreBolusTypeOnUpdate :
Boolean = false): Boolean
/**
* Synchronization of carbs

View file

@ -137,7 +137,8 @@ class PumpSyncImplementation @Inject constructor(
}
}
override fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
override fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String, ignoreBolusTypeOnUpdate :
Boolean): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
@ -150,7 +151,7 @@ class PumpSyncImplementation @Inject constructor(
pumpSerial = pumpSerial
)
)
repository.runTransactionForResult(SyncBolusWithTempIdTransaction(bolus, type?.toDBbBolusType()))
repository.runTransactionForResult(SyncBolusWithTempIdTransaction(bolus, type?.toDBbBolusType(), ignoreBolusTypeOnUpdate))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving Bolus", it) }
.blockingGet()
.also { result ->
@ -160,6 +161,19 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
return syncBolusWithPumpId(
timestamp = timestamp,
amount = amount,
type = type,
pumpId = pumpId,
pumpType = pumpType,
pumpSerial = pumpSerial,
ignoreBolusTypeOnUpdate = false
)
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String, ignoreBolusTypeOnUpdate :
Boolean): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
@ -171,7 +185,7 @@ class PumpSyncImplementation @Inject constructor(
pumpSerial = pumpSerial
)
)
repository.runTransactionForResult(SyncPumpBolusTransaction(bolus, type?.toDBbBolusType()))
repository.runTransactionForResult(SyncPumpBolusTransaction(bolus, type?.toDBbBolusType(), ignoreBolusTypeOnUpdate))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving Bolus", it) }
.blockingGet()
.also { result ->

View file

@ -7,7 +7,8 @@ import info.nightscout.androidaps.database.entities.Bolus
*/
class SyncBolusWithTempIdTransaction(
private val bolus: Bolus,
private val newType: Bolus.Type?
private val newType: Bolus.Type?,
private val ignoreBolusTypeOnUpdate: Boolean
) : Transaction<SyncBolusWithTempIdTransaction.TransactionResult>() {
override fun run(): TransactionResult {
@ -18,7 +19,9 @@ class SyncBolusWithTempIdTransaction(
if (current != null) {
current.timestamp = bolus.timestamp
current.amount = bolus.amount
current.type = newType ?: current.type
if (!ignoreBolusTypeOnUpdate) {
current.type = newType ?: current.type
}
current.interfaceIDs.pumpId = bolus.interfaceIDs.pumpId
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)

View file

@ -7,7 +7,8 @@ import info.nightscout.androidaps.database.entities.Bolus
*/
class SyncPumpBolusTransaction(
private val bolus: Bolus,
private val bolusType: Bolus.Type? // extra parameter because field is not nullable in Bolus.class
private val bolusType: Bolus.Type?, // extra parameter because field is not nullable in Bolus.class
private val ignoreBolusTypeOnUpdate: Boolean
) : Transaction<SyncPumpBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult {
@ -19,16 +20,28 @@ class SyncPumpBolusTransaction(
database.bolusDao.insertNewEntry(bolus)
result.inserted.add(bolus)
} else {
if (
current.timestamp != bolus.timestamp ||
current.amount != bolus.amount ||
current.type != bolusType ?: current.type
) {
current.timestamp = bolus.timestamp
current.amount = bolus.amount
current.type = bolusType ?: current.type
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)
if (ignoreBolusTypeOnUpdate) {
if (
current.timestamp != bolus.timestamp ||
current.amount != bolus.amount
) {
current.timestamp = bolus.timestamp
current.amount = bolus.amount
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)
}
} else {
if (
current.timestamp != bolus.timestamp ||
current.amount != bolus.amount ||
current.type != bolusType ?: current.type
) {
current.timestamp = bolus.timestamp
current.amount = bolus.amount
current.type = bolusType ?: current.type
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)
}
}
}
return result

View file

@ -32,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
@ -742,6 +743,7 @@ class MedtronicPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(false).enacted(false)
.comment(R.string.medtronic_cmd_cant_cancel_tbr_stop_op)
} else {
cancelTBRWithTemporaryId()
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.")
}
}
@ -760,8 +762,9 @@ class MedtronicPumpPlugin @Inject constructor(
medtronicPumpStatus.tempBasalAmount = absoluteRate
medtronicPumpStatus.tempBasalLength = durationInMinutes
val tempData = info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR(absoluteRate, true, durationInMinutes, tbrType)
val tempData = PumpDbEntryTBR(absoluteRate, true, durationInMinutes, tbrType)
medtronicPumpStatus.runningTBRWithTemp = tempData
pumpSyncStorage.addTemporaryBasalRateWithTempId(tempData, true, this)
incrementStatistics(MedtronicConst.Statistics.TBRsSet)
@ -771,6 +774,61 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
private fun cancelTBRWithTemporaryId() {
val tbrs : MutableList<PumpDbEntryTBR> = pumpSyncStorage.getTBRs()
if (tbrs.size > 0 && medtronicPumpStatus.runningTBRWithTemp!=null) {
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTBRWithTemporaryId - TBR items: ${tbrs.size}")
var item : PumpDbEntryTBR? = null
if (tbrs.size==1) {
item = tbrs.get(0);
} else {
for (tbr in tbrs) {
if (tbr.date == medtronicPumpStatus.runningTBRWithTemp!!.date) {
item = tbr
break;
}
}
}
if (item!=null) {
aapsLogger.debug(LTag.PUMP, "DD: cancelTBRWithTemporaryId: tempIdEntry=${item}")
val differenceS = (System.currentTimeMillis() - item.date) / 1000
aapsLogger.debug(LTag.PUMP, "syncTemporaryBasalWithTempId " +
"[date=${item.date}, " +
"rate=${item.rate}, " +
"duration=${differenceS} s, " +
"isAbsolute=${!item.isAbsolute}, temporaryId=${item.temporaryId}, " +
"pumpId=NO, pumpType=${medtronicPumpStatus.pumpType}, " +
"pumpSerial=${medtronicPumpStatus.serialNumber}]")
val result = pumpSync.syncTemporaryBasalWithTempId(
timestamp = item.date,
rate = item.rate,
duration= differenceS * 1000L,
isAbsolute = item.isAbsolute,
temporaryId = item.temporaryId,
type = item.tbrType,
pumpId = null,
pumpType = medtronicPumpStatus.pumpType,
pumpSerial = medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, "syncTemporaryBasalWithTempId - Result: $result")
}
} else {
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTBRWithTemporaryId - TBR items: ${tbrs.size}, runningTBRWithTemp=${medtronicPumpStatus.runningTBRWithTemp}")
}
if (medtronicPumpStatus.runningTBRWithTemp!=null) {
medtronicPumpStatus.runningTBRWithTemp = null
}
}
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
return if (percent == 0) {
setTempBasalAbsolute(0.0, durationInMinutes, profile, enforceNew, tbrType)
@ -1001,7 +1059,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - Cancel TBR successful.")
val runningTBR = medtronicPumpStatus.runningTBR
// TODO
if (runningTBR != null) {
if (medtronicHistoryData.isTBRActive(runningTBR)) {
@ -1026,6 +1084,8 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
cancelTBRWithTemporaryId()
PumpEnactResult(injector).success(true).enacted(true) //
.isTempCancel(true)
}

View file

@ -508,25 +508,27 @@ class MedtronicHistoryData @Inject constructor(
if (temporaryId != null) {
val result = pumpSync.syncBolusWithTempId(
tryToGetByLocalTime(bolus.atechDateTime),
deliveredAmount,
temporaryId,
type,
bolus.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber)
timestamp = tryToGetByLocalTime(bolus.atechDateTime),
amount = deliveredAmount,
temporaryId = temporaryId,
type = type,
pumpId = bolus.pumpId,
pumpType = medtronicPumpStatus.pumpType,
pumpSerial = medtronicPumpStatus.serialNumber,
ignoreBolusTypeOnUpdate = true)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithTempId [date=%d, temporaryId=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime, temporaryId, bolus.pumpId, deliveredAmount,
medtronicPumpStatus.serialNumber, result))
} else {
val result = pumpSync.syncBolusWithPumpId(
tryToGetByLocalTime(bolus.atechDateTime),
deliveredAmount,
type,
bolus.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber)
timestamp = tryToGetByLocalTime(bolus.atechDateTime),
amount = deliveredAmount,
type = type,
pumpId = bolus.pumpId,
pumpType = medtronicPumpStatus.pumpType,
pumpSerial = medtronicPumpStatus.serialNumber,
ignoreBolusTypeOnUpdate = true)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithPumpId [date=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime, bolus.pumpId, deliveredAmount,

View file

@ -34,6 +34,7 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
var maxBolus: Double? = null
var maxBasal: Double? = null
var runningTBR: PumpDbEntryTBR? = null
var runningTBRWithTemp: PumpDbEntryTBR? = null
// statuses
var pumpDeviceState = PumpDeviceState.NeverContacted