- 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 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 * Search for combination of temporaryId, PumpType, pumpSerial
* *
@ -110,9 +111,12 @@ interface PumpSync {
* @param pumpId pump id from history * @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO * @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number * @param pumpSerial pump serial number
* @param ignoreBolusTypeOnUpdate bolusType won't be updated, if item already exists
* @return true if record is successfully updated * @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 * Synchronization of boluses
@ -123,15 +127,40 @@ interface PumpSync {
* If exists, amount, type (if provided) and timestamp is updated * If exists, amount, type (if provided) and timestamp is updated
* isValid field is preserved * 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 timestamp timestamp of event from pump history
* @param amount amount of insulin * @param amount amount of insulin
* @param type type of bolus (NORMAL, SMB, PRIME) * @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpId pump id from history * @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO * @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number * @param pumpSerial pump serial number
* @param ignoreBolusTypeOnUpdate bolusType won't be updated, if item already exists
* @return true if new record is created * @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 * 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 if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
@ -150,7 +151,7 @@ class PumpSyncImplementation @Inject constructor(
pumpSerial = pumpSerial 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) } .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving Bolus", it) }
.blockingGet() .blockingGet()
.also { result -> .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 { 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 if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
@ -171,7 +185,7 @@ class PumpSyncImplementation @Inject constructor(
pumpSerial = pumpSerial 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) } .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving Bolus", it) }
.blockingGet() .blockingGet()
.also { result -> .also { result ->

View file

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

View file

@ -7,7 +7,8 @@ import info.nightscout.androidaps.database.entities.Bolus
*/ */
class SyncPumpBolusTransaction( class SyncPumpBolusTransaction(
private val bolus: Bolus, 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>() { ) : Transaction<SyncPumpBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
@ -18,6 +19,17 @@ class SyncPumpBolusTransaction(
if (current == null) { if (current == null) {
database.bolusDao.insertNewEntry(bolus) database.bolusDao.insertNewEntry(bolus)
result.inserted.add(bolus) result.inserted.add(bolus)
} else {
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 { } else {
if ( if (
current.timestamp != bolus.timestamp || current.timestamp != bolus.timestamp ||
@ -31,6 +43,7 @@ class SyncPumpBolusTransaction(
result.updated.add(current) result.updated.add(current)
} }
} }
}
return result 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.ResetRileyLinkConfigurationTask
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor 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.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.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry 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) return PumpEnactResult(injector).success(false).enacted(false)
.comment(R.string.medtronic_cmd_cant_cancel_tbr_stop_op) .comment(R.string.medtronic_cmd_cant_cancel_tbr_stop_op)
} else { } else {
cancelTBRWithTemporaryId()
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.") aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.")
} }
} }
@ -760,8 +762,9 @@ class MedtronicPumpPlugin @Inject constructor(
medtronicPumpStatus.tempBasalAmount = absoluteRate medtronicPumpStatus.tempBasalAmount = absoluteRate
medtronicPumpStatus.tempBasalLength = durationInMinutes 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) pumpSyncStorage.addTemporaryBasalRateWithTempId(tempData, true, this)
incrementStatistics(MedtronicConst.Statistics.TBRsSet) 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 { override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
return if (percent == 0) { return if (percent == 0) {
setTempBasalAbsolute(0.0, durationInMinutes, profile, enforceNew, tbrType) setTempBasalAbsolute(0.0, durationInMinutes, profile, enforceNew, tbrType)
@ -1001,7 +1059,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - Cancel TBR successful.") aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - Cancel TBR successful.")
val runningTBR = medtronicPumpStatus.runningTBR val runningTBR = medtronicPumpStatus.runningTBR
// TODO
if (runningTBR != null) { if (runningTBR != null) {
if (medtronicHistoryData.isTBRActive(runningTBR)) { if (medtronicHistoryData.isTBRActive(runningTBR)) {
@ -1026,6 +1084,8 @@ class MedtronicPumpPlugin @Inject constructor(
} }
} }
cancelTBRWithTemporaryId()
PumpEnactResult(injector).success(true).enacted(true) // PumpEnactResult(injector).success(true).enacted(true) //
.isTempCancel(true) .isTempCancel(true)
} }

View file

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

View file

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