Merge pull request #929 from andyrozman/bug798_meal_tbr

Bug798 - smb to meal bolus and zero tbr termination
This commit is contained in:
Milos Kozak 2021-11-15 00:31:21 +01:00 committed by GitHub
commit a7118b1a7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 2072 additions and 92 deletions

View file

@ -265,11 +265,11 @@ public class DateTimeUtil {
}
public static long getATDWithAddedMinutes(long atd, int minutesDiff) {
public static long getATDWithAddedSeconds(Long atd, int addedSeconds) {
GregorianCalendar oldestEntryTime = DateTimeUtil.toGregorianCalendar(atd);
oldestEntryTime.add(Calendar.MINUTE, minutesDiff);
oldestEntryTime.add(Calendar.SECOND, addedSeconds);
return oldestEntryTime.getTimeInMillis();
return toATechDate(oldestEntryTime.getTimeInMillis());
}
@ -279,7 +279,6 @@ public class DateTimeUtil {
return toATechDate(oldestEntryTime);
}
public static long getTimeInFutureFromMinutes(long startTime, int minutes) {
return startTime + getTimeInMs(minutes);
}

11
medtronic/Changelog.txt Normal file
View file

@ -0,0 +1,11 @@
V1 - Medtronic initial implementation
... lots of changes
V2 - Rewrite into kotlin, new database (for v3.0)
0001 - initial version
0002 - some fixes
0003 - SMB fix (798)
0004 - Zero TBR Duration fix (798), refactoring of TempBasalProcessDTO
0005 - fixes to MedtronicHistoryEntry lateinit problem

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
@ -111,7 +112,7 @@ class MedtronicPumpPlugin @Inject constructor(
private var isBusy = false
override fun onStart() {
aapsLogger.debug(LTag.PUMP, deviceID() + " started.")
aapsLogger.debug(LTag.PUMP, deviceID() + " started. (V2.0005)")
serviceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is disconnected")
@ -468,6 +469,7 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
@Synchronized
override fun isThisProfileSet(profile: Profile): Boolean {
aapsLogger.debug(LTag.PUMP, "isThisProfileSet: basalInitalized=" + medtronicPumpStatus.basalProfileStatus)
if (!isInitialized) return true
@ -580,6 +582,7 @@ class MedtronicPumpPlugin @Inject constructor(
scheduleNextRefresh(MedtronicStatusRefreshType.PumpTime, 0)
}
@Synchronized
override fun deliverBolus(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
aapsLogger.info(LTag.PUMP, "MedtronicPumpPlugin::deliverBolus - " + BolusDeliveryType.DeliveryPrepared)
setRefreshButtonEnabled(false)
@ -691,6 +694,7 @@ class MedtronicPumpPlugin @Inject constructor(
// if enforceNew===true current temp basal is canceled and new TBR set (duration is prolonged),
// if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed
@Synchronized
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
setRefreshButtonEnabled(false)
if (isPumpNotReachable) {
@ -742,6 +746,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 +765,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 +777,63 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
@Deprecated("Not used, TBRs fixed in history, should be removed.")
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
}
}
@Synchronized
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)
@ -966,6 +1029,7 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
@Synchronized
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - started")
if (isPumpNotReachable) {
@ -1001,7 +1065,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 +1090,8 @@ class MedtronicPumpPlugin @Inject constructor(
}
}
//cancelTBRWithTemporaryId()
PumpEnactResult(injector).success(true).enacted(true) //
.isTempCancel(true)
}
@ -1043,6 +1109,7 @@ class MedtronicPumpPlugin @Inject constructor(
return medtronicPumpStatus.serialNumber
}
@Synchronized
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
aapsLogger.info(LTag.PUMP, logPrefix + "setNewBasalProfile")

View file

@ -14,13 +14,13 @@ import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
*/
abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
lateinit var rawData: List<Byte>
var rawData: List<Byte> = listOf()
protected var sizes = IntArray(3)
lateinit var head: ByteArray
lateinit var datetime: ByteArray
lateinit var body: ByteArray
var head: ByteArray = byteArrayOf()
var datetime: ByteArray = byteArrayOf()
var body: ByteArray = byteArrayOf()
var id: Long = 0
@ -41,7 +41,13 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
/**
* Pump id that will be used with AAPS object (time * 1000 + historyType (max is FF = 255)
*/
open var pumpId: Long = 0L
var pumpId: Long = 0L
get() {
if (field == 0L) {
field = generatePumpId()
}
return field
}
/**
* if history object is already linked to AAPS object (either Treatment, TempBasal or TDD (tdd's
@ -158,7 +164,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
sb.append("]")
return sb.toString()
}
if (head.size != 0) {
if (head!=null && head.size != 0) {
sb.append(", head=")
sb.append(ByteUtil.shortHexString(head))
}

View file

@ -92,14 +92,6 @@ class PumpHistoryEntry : MedtronicHistoryEntry() {
}
}
override var pumpId: Long = 0L
get() {
if (field == 0L) {
field = generatePumpId()
}
return field
}
fun hasBolusChanged(entry: PumpHistoryEntry): Boolean {
if (entryType == PumpHistoryEntryType.Bolus) {
val thisOne: BolusDTO = this.decodedData["Object"] as BolusDTO

View file

@ -508,25 +508,25 @@ 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 = null,
pumpId = bolus.pumpId,
pumpType = medtronicPumpStatus.pumpType,
pumpSerial = medtronicPumpStatus.serialNumber)
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 = null,
pumpId = bolus.pumpId,
pumpType = medtronicPumpStatus.pumpType,
pumpSerial = medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithPumpId [date=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime, bolus.pumpId, deliveredAmount,
@ -571,62 +571,42 @@ class MedtronicHistoryData @Inject constructor(
private fun processTBREntries(entryList: MutableList<PumpHistoryEntry>) {
entryList.reverse()
val tbr = entryList[0].getDecodedDataEntry("Object") as TempBasalPair
var readOldItem = false
if (tbr.isCancelTBR) {
val oneMoreEntryFromHistory = getOneMoreEntryFromHistory(PumpHistoryEntryType.TempBasalCombined)
// var readOldItem = false
val oneMoreEntryFromHistory = getOneMoreEntryFromHistory(PumpHistoryEntryType.TempBasalCombined)
if (tbr.isCancelTBR) { // if we have cancel we need to limit previous TBR with this cancel
if (oneMoreEntryFromHistory != null) {
entryList.add(0, oneMoreEntryFromHistory)
readOldItem = true
} else {
entryList.removeAt(0)
}
} else {
if (oneMoreEntryFromHistory != null) {
val tbrPrev = oneMoreEntryFromHistory.getDecodedDataEntry("Object") as TempBasalPair
if (tbrPrev.isZeroTBR) { // if we had Zere TBR in last previous TBR, then we need to limit it, so we need to process it too
entryList.add(0, oneMoreEntryFromHistory)
}
}
}
val tbrRecords = pumpSyncStorage.getTBRs()
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, ProcessHistoryRecord.TBR.description + " List (before filter): %s, FromDb=%s", gson.toJson(entryList),
tbrRecords))
var processDTO: TempBasalProcessDTO? = null
val processList: MutableList<TempBasalProcessDTO> = mutableListOf()
for (treatment in entryList) {
val tbr2 = treatment.getDecodedDataEntry("Object") as TempBasalPair
if (tbr2.isCancelTBR) {
if (processDTO != null) {
processDTO.itemTwo = treatment
processDTO.cancelPresent = true
if (readOldItem) {
processDTO.processOperation = TempBasalProcessDTO.Operation.Edit
readOldItem = false
}
} else {
aapsLogger.warn(LTag.PUMP, "processDTO was null - shouldn't happen, ignoring item. ItemTwo=$treatment")
}
} else {
if (processDTO != null) {
processList.add(processDTO)
}
processDTO = TempBasalProcessDTO(
itemOne = treatment,
processOperation = TempBasalProcessDTO.Operation.Add,
aapsLogger = aapsLogger,
objectType = TempBasalProcessDTO.ObjectType.TemporaryBasal
)
}
}
if (processDTO != null) {
processList.add(processDTO)
}
val processList: MutableList<TempBasalProcessDTO> = createTBRProcessList(entryList);
if (processList.isNotEmpty()) {
for (tempBasalProcessDTO in processList) {
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemOne: " + gson.toJson(tempBasalProcessDTO.itemOne))
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemTwo: " + (if (tempBasalProcessDTO.itemTwo == null) "null" else gson.toJson(tempBasalProcessDTO.itemTwo!!)))
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO: " + tempBasalProcessDTO.toTreatmentString())
//aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemOne: " + gson.toJson(tempBasalProcessDTO.itemOne))
//aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemTwo: " + (if (tempBasalProcessDTO.itemTwo == null) "null" else gson.toJson(tempBasalProcessDTO.itemTwo!!)))
@Suppress("Unchecked_Cast")
val entryWithTempId = findDbEntry(tempBasalProcessDTO.itemOne, tbrRecords as MutableList<PumpDbEntry>) as PumpDbEntryTBR?
aapsLogger.debug(LTag.PUMP, "DD: entryWithTempId: " + (entryWithTempId?.toString() ?: "null"))
val tbrEntry = tempBasalProcessDTO.itemOneTbr //.getDecodedDataEntry("Object") as TempBasalPair
val tbrEntry = tempBasalProcessDTO.itemOneTbr
aapsLogger.debug(LTag.PUMP, String.format("DD: tbrEntry=%s, tempBasalProcessDTO=%s", gson.toJson(tbrEntry), gson.toJson(tempBasalProcessDTO)))
@ -649,7 +629,7 @@ class MedtronicHistoryData @Inject constructor(
tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
tbrEntry.insulinRate,
tempBasalProcessDTO.durationAsSeconds * 1000L,
!tbrEntry.isPercent,
isAbsolute = !tbrEntry.isPercent,
entryWithTempId.temporaryId,
PumpSync.TemporaryBasalType.NORMAL,
tempBasalProcessDTO.pumpId,
@ -705,10 +685,10 @@ class MedtronicHistoryData @Inject constructor(
date = tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
pumpType = medtronicPumpStatus.pumpType,
serialNumber = medtronicPumpStatus.serialNumber,
entry = PumpDbEntryTBR(rate = tbrEntry.insulinRate,
isAbsolute = !tbrEntry.isPercent,
durationInSeconds = tempBasalProcessDTO.durationAsSeconds,
tbrType = PumpSync.TemporaryBasalType.NORMAL),
rate = tbrEntry.insulinRate,
isAbsolute = !tbrEntry.isPercent,
durationInSeconds = tempBasalProcessDTO.durationAsSeconds,
tbrType = PumpSync.TemporaryBasalType.NORMAL,
pumpId = tempBasalProcessDTO.pumpId)
}
}
@ -720,6 +700,56 @@ class MedtronicHistoryData @Inject constructor(
} // collection
}
fun createTBRProcessList(entryList: MutableList<PumpHistoryEntry>) : MutableList<TempBasalProcessDTO> {
aapsLogger.debug(LTag.PUMP, "${ProcessHistoryRecord.TBR.description} List (before filter): ${gson.toJson(entryList)}")
var processDTO: TempBasalProcessDTO? = null
val processList: MutableList<TempBasalProcessDTO> = mutableListOf()
for (treatment in entryList) {
val tbr2 = treatment.getDecodedDataEntry("Object") as TempBasalPair
if (tbr2.isCancelTBR) {
if (processDTO != null) {
processDTO.itemTwo = treatment
} else {
aapsLogger.warn(LTag.PUMP, "processDTO was null - shouldn't happen, ignoring item. ItemTwo=$treatment")
}
} else {
if (processDTO != null) {
processList.add(processDTO)
}
processDTO = TempBasalProcessDTO(
itemOne = treatment,
aapsLogger = aapsLogger,
objectType = TempBasalProcessDTO.ObjectType.TemporaryBasal
)
}
}
if (processDTO != null) {
processList.add(processDTO)
}
var previousItem: TempBasalProcessDTO? = null
// fix for Zero TBRs
for (tempBasalProcessDTO in processList) {
if (previousItem!=null) {
var pheEnd = PumpHistoryEntry()
pheEnd.atechDateTime = DateTimeUtil.getATDWithAddedSeconds(tempBasalProcessDTO.itemOne.atechDateTime, -2)
pheEnd.addDecodedData("Object", TempBasalPair(0.0, false, 0))
previousItem.itemTwo = pheEnd
previousItem = null
}
if (tempBasalProcessDTO.itemOneTbr!!.isZeroTBR) {
previousItem = tempBasalProcessDTO
}
}
return processList
}
fun isTBRActive(dbEntry: PumpDbEntryTBR): Boolean {
@ -881,7 +911,6 @@ class MedtronicHistoryData @Inject constructor(
while (i < filtered2Items.size) {
val tbrProcess = TempBasalProcessDTO(
itemOne = filtered2Items[i],
processOperation = TempBasalProcessDTO.Operation.Add,
aapsLogger = aapsLogger,
objectType = TempBasalProcessDTO.ObjectType.Suspend)
@ -959,7 +988,6 @@ class MedtronicHistoryData @Inject constructor(
if (items.size > 0) {
val tbrProcess = TempBasalProcessDTO(
itemOne = items[items.size - 1],
processOperation = TempBasalProcessDTO.Operation.Add,
aapsLogger = aapsLogger,
objectType = TempBasalProcessDTO.ObjectType.Suspend)
@ -975,7 +1003,6 @@ class MedtronicHistoryData @Inject constructor(
if (items.size > 0) {
val tbrProcess = TempBasalProcessDTO(
itemOne = items[0],
processOperation = TempBasalProcessDTO.Operation.Add,
aapsLogger = aapsLogger,
objectType = TempBasalProcessDTO.ObjectType.Suspend)

View file

@ -91,6 +91,9 @@ class TempBasalPair : TempBasalPair {
val isCancelTBR: Boolean
get() = MedtronicUtil.isSame(insulinRate, 0.0) && durationMinutes == 0
val isZeroTBR: Boolean
get() = MedtronicUtil.isSame(insulinRate, 0.0) && durationMinutes != 0
val description: String
get() {
if (isCancelTBR) {

View file

@ -4,9 +4,9 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
import java.lang.StringBuilder
class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry,
var processOperation: Operation = Operation.None,
var aapsLogger: AAPSLogger,
var objectType: ObjectType = ObjectType.TemporaryBasal) {
@ -21,8 +21,6 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry,
var itemOneTbr: TempBasalPair? = null
var itemTwoTbr: TempBasalPair? = null
var cancelPresent: Boolean = false
val atechDateTime: Long
get() = itemOne.atechDateTime
@ -31,26 +29,26 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry,
val durationAsSeconds: Int
get() {
aapsLogger.debug(LTag.PUMP, "durationAsSeconds: [objectType=$objectType]")
//aapsLogger.debug(LTag.PUMP, "durationAsSeconds: [objectType=$objectType]")
if (objectType == ObjectType.TemporaryBasal) {
if (itemTwo == null) {
if (itemOneTbr != null) {
aapsLogger.debug("TemporaryBasalPair - itemOneSingle: $itemOneTbr")
//aapsLogger.debug("TemporaryBasalPair - itemOneSingle: $itemOneTbr")
return itemOneTbr!!.durationMinutes * 60
} else {
aapsLogger.error("Couldn't find TempBasalPair in entry: $itemOne")
//aapsLogger.error("Couldn't find TempBasalPair in entry: $itemOne")
return 0
}
} else {
aapsLogger.debug(LTag.PUMP, "Found 2 items for duration: itemOne=$itemOne, itemTwo=$itemTwo")
//aapsLogger.debug(LTag.PUMP, "Found 2 items for duration: itemOne=$itemOne, itemTwo=$itemTwo")
val secondsDiff = DateTimeUtil.getATechDateDiferenceAsSeconds(itemOne.atechDateTime, itemTwo!!.atechDateTime)
aapsLogger.debug(LTag.PUMP, "Difference in seconds: $secondsDiff")
//aapsLogger.debug(LTag.PUMP, "Difference in seconds: $secondsDiff")
return secondsDiff
}
} else {
aapsLogger.debug(LTag.PUMP, "Found 2 items for duration (in SuspendMode): itemOne=$itemOne, itemTwo=$itemTwo")
//aapsLogger.debug(LTag.PUMP, "Found 2 items for duration (in SuspendMode): itemOne=$itemOne, itemTwo=$itemTwo")
val secondsDiff = DateTimeUtil.getATechDateDiferenceAsSeconds(itemOne.atechDateTime, itemTwo!!.atechDateTime)
aapsLogger.debug(LTag.PUMP, "Difference in seconds: $secondsDiff")
//aapsLogger.debug(LTag.PUMP, "Difference in seconds: $secondsDiff")
return secondsDiff
}
}
@ -61,8 +59,31 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry,
}
}
fun toTreatmentString(): String {
val stringBuilder = StringBuilder()
stringBuilder.append(itemOne.DT)
if (itemTwo!=null) {
stringBuilder.append(" - ")
stringBuilder.append(itemTwo!!.DT)
}
var dur = durationAsSeconds
stringBuilder.append(" " + durationAsSeconds + " s (" + durationAsSeconds/60 + ")")
if (itemTwoTbr!=null) {
stringBuilder.append(" " + itemOneTbr!!.insulinRate + " / " + itemTwoTbr!!.insulinRate)
} else {
stringBuilder.append(" " + itemOneTbr!!.insulinRate)
}
return stringBuilder.toString()
}
override fun toString(): String {
return "ItemOne: $itemOne, ItemTwo: $itemTwo, Duration: $durationAsSeconds, Operation: $processOperation, ObjectType: $objectType"
return "ItemOne: $itemOne, ItemTwo: $itemTwo, Duration: $durationAsSeconds, ObjectType: $objectType"
}
enum class Operation {

View file

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

View file

@ -0,0 +1,91 @@
package info.nightscout.androidaps.plugins.pump.medtronic.data
import java.lang.reflect.Type
import com.google.gson.reflect.TypeToken
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.internal.LinkedTreeMap
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.hamcrest.Matchers.notNullValue
import org.junit.Assert.*
import org.junit.Test
import org.mockito.Mock
import java.io.File
import java.net.URL
class MedtronicHistoryDataUTest : TestBase() {
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var medtronicUtil: MedtronicUtil
@Mock lateinit var medtronicPumpHistoryDecoder: MedtronicPumpHistoryDecoder
@Mock lateinit var medtronicPumpStatus: MedtronicPumpStatus
@Mock lateinit var pumpSync: PumpSync
@Mock lateinit var pumpSyncStorage: PumpSyncStorage
@Mock lateinit var sp: SP
private val packetInjector = HasAndroidInjector {
AndroidInjector {
}
}
@Test
fun createTBRProcessList() {
var unitToTest = MedtronicHistoryData(packetInjector, aapsLogger, sp, activePlugin,
medtronicUtil, medtronicPumpHistoryDecoder,
medtronicPumpStatus,
pumpSync,
pumpSyncStorage)
val gson = Gson()
val fileText = ClassLoader.getSystemResource("tbr_data.json").readText()
val listType: Type = object : TypeToken<MutableList<PumpHistoryEntry?>?>() {}.getType()
val yourClassList: MutableList<PumpHistoryEntry> = gson.fromJson(fileText, listType)
for (pumpHistoryEntry in yourClassList) {
val stringObject = pumpHistoryEntry.decodedData["Object"] as LinkedTreeMap<String,Object>
val rate : Double = stringObject.get("insulinRate") as Double
val durationMinutes: Double = stringObject.get("durationMinutes") as Double
val durationMinutesInt : Int = durationMinutes.toInt()
var tmbPair = TempBasalPair(rate, false, durationMinutesInt)
pumpHistoryEntry.decodedData.remove("Object")
pumpHistoryEntry.addDecodedData("Object", tmbPair)
}
System.out.println("TBR Pre-Process List: " + gson.toJson(yourClassList))
val createTBRProcessList = unitToTest.createTBRProcessList(yourClassList)
System.out.println("TBR Process List: " + createTBRProcessList.size)
for (tempBasalProcessDTO in createTBRProcessList) {
System.out.println(tempBasalProcessDTO.toTreatmentString())
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -323,6 +323,7 @@ abstract class PumpPluginAbstract protected constructor(
return ret
}
@Synchronized
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
return try {
if (detailedBolusInfo.insulin == 0.0 && detailedBolusInfo.carbs == 0.0) {