- added bolus handling (complete)

- added PumpSyncStorage class for handling temporary data
This commit is contained in:
Andy Rozman 2021-04-30 15:28:24 +01:00
parent 727862c743
commit 6504498cd2
16 changed files with 515 additions and 149 deletions

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.queue.CommandQueue
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
@ -72,6 +73,16 @@ open class AppModule {
rxBus: RxBusWrapper rxBus: RxBusWrapper
): UploadQueueAdminInterface = UploadQueue(aapsLogger, databaseHelper, context, sp, rxBus) ): UploadQueueAdminInterface = UploadQueue(aapsLogger, databaseHelper, context, sp, rxBus)
@Provides
@Singleton
fun providesPumpSyncStorage(
pumpSync: PumpSync,
sp: SP,
aapsLogger: AAPSLogger
): PumpSyncStorage {
return PumpSyncStorage(pumpSync, sp, aapsLogger)
}
@Module @Module
interface AppBindings { interface AppBindings {
@Binds fun bindContext(mainApp: MainApp): Context @Binds fun bindContext(mainApp: MainApp): Context

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.plugins.pump.common.sync
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
data class PumpDbEntry constructor(var temporaryId: Long,
var date: Long,
var pumpType: PumpType,
var serialNumber: String,
var bolusData: PumpDbEntryBolus? = null,
var tbrData: PumpDbEntryTBR? = null ) {
constructor(temporaryId: Long,
date: Long,
pumpType: PumpType,
serialNumber: String,
detailedBolusInfo: DetailedBolusInfo) : this(temporaryId, date, pumpType, serialNumber) {
this.bolusData = PumpDbEntryBolus(
detailedBolusInfo.insulin,
detailedBolusInfo.carbs,
detailedBolusInfo.bolusType)
}
}
data class PumpDbEntryBolus(var insulin: Double,
var carbs: Double,
var bolusType: DetailedBolusInfo.BolusType)
data class PumpDbEntryTBR(var temporaryId: Long)

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.plugins.pump.common.sync;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
public interface PumpSyncEntriesCreator {
long generateTempId(Object dataObject);
PumpType model();
String serialNumber();
}

View file

@ -0,0 +1,154 @@
package info.nightscout.androidaps.plugins.pump.common.sync
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.lang.reflect.Type
import javax.inject.Inject
import javax.inject.Singleton
/**
* This class is intended for Pump Drivers that use temporaryId and need way to pair records
*/
@Singleton
class PumpSyncStorage @Inject constructor(
val pumpSync: PumpSync,
val sp: SP,
val aapsLogger: AAPSLogger
) {
val pumpSyncStorageKey: String = "pump_sync_storage"
var pumpSyncStorage: MutableMap<String,MutableList<PumpDbEntry>> = mutableMapOf()
var TBR: String = "TBR"
var BOLUS: String = "BOLUS"
var storageInitialized: Boolean = false
var gson: Gson = GsonBuilder().create()
init {
initStorage()
}
fun initStorage() {
if (storageInitialized)
return
var loaded = false
if (sp.contains(pumpSyncStorageKey)) {
val jsonData: String = sp.getString("pump_sync_storage", "");
if (!jsonData.isBlank()) {
val pumpSyncStorageType: Type = object : TypeToken<MutableMap<String, MutableList<PumpDbEntry>>>() {}.getType()
val baseMap: MutableMap<String, MutableList<PumpDbEntry>> = gson.fromJson(jsonData, pumpSyncStorageType) //as MutableMap<String, MutableList<PumpDbEntry>>
pumpSyncStorage = baseMap
aapsLogger.debug(String.format("Loading Pump Sync Storage: boluses=%d, tbrs=%d.", pumpSyncStorage[BOLUS]!!.size, pumpSyncStorage[TBR]!!.size))
loaded = true
}
}
if (!loaded) {
pumpSyncStorage[BOLUS] = mutableListOf()
pumpSyncStorage[TBR] = mutableListOf()
}
}
fun saveStorage() {
if (!isStorageEmpty()) {
sp.putString(pumpSyncStorageKey, gson.toJson(pumpSyncStorage))
aapsLogger.debug(String.format("Saving Pump Sync Storage: boluses=%d, tbrs=%d.", pumpSyncStorage[BOLUS]!!.size, pumpSyncStorage[TBR]!!.size))
}
}
fun isStorageEmpty() : Boolean {
return pumpSyncStorage[BOLUS]!!.isEmpty() && pumpSyncStorage[TBR]!!.isEmpty()
}
fun getBoluses() : MutableList<PumpDbEntry> {
return pumpSyncStorage[BOLUS]!!;
}
fun getTBRs() : MutableList<PumpDbEntry> {
return pumpSyncStorage[TBR]!!;
}
//abstract fun generateTempId(timeMillis: Long): Long
fun addBolusWithTempId(detailedBolusInfo: DetailedBolusInfo, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator): Boolean {
val temporaryId = creator.generateTempId(detailedBolusInfo.timestamp)
val response = pumpSync.addBolusWithTempId(
detailedBolusInfo.timestamp,
detailedBolusInfo.insulin,
temporaryId,
detailedBolusInfo.bolusType,
creator.model(),
creator.serialNumber())
if (response && writeToInternalHistory) {
var innerList: MutableList<PumpDbEntry> = pumpSyncStorage[BOLUS]!!
innerList.add(PumpDbEntry(temporaryId, detailedBolusInfo.timestamp, creator.model(), creator.serialNumber(), detailedBolusInfo))
pumpSyncStorage[BOLUS] = innerList
saveStorage()
}
return response
}
// TODO
fun addTemporaryBasalRateWithTempId(temporaryBasal: TemporaryBasal, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator) : Boolean {
// val temporaryId = generateTempId(temporaryBasal.date)
// val response = pumpSync.addBolusWithTempId(temporaryBasal.timestamp, detailedBolusInfo.insulin,
// generateTempId(detailedBolusInfo.timestamp), detailedBolusInfo.getBolusType(),
// getPumpType(), serialNumber());
//
// if (response && writeToInternalHistory) {
// driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
// sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory));
// }
//
// return response;
return false
}
fun removeBolusWithTemporaryId(temporaryId: Long) {
val bolusList = removeTemporaryId(temporaryId, pumpSyncStorage[BOLUS]!!)
pumpSyncStorage[BOLUS] = bolusList
saveStorage()
}
fun removeTemporaryBasalWithTemporaryId(temporaryId: Long) {
val tbrList = removeTemporaryId(temporaryId, pumpSyncStorage[TBR]!!)
pumpSyncStorage[TBR] = tbrList
saveStorage()
}
private fun removeTemporaryId(temporaryId: Long, list: MutableList<PumpDbEntry>): MutableList<PumpDbEntry> {
var dbEntry: PumpDbEntry? = null
for (pumpDbEntry in list) {
if (pumpDbEntry.temporaryId == temporaryId) {
dbEntry = pumpDbEntry
}
}
if (dbEntry!=null) {
list.remove(dbEntry)
}
return list
}
}

View file

@ -23,7 +23,6 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.pump.common.data.PumpDbEntry
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -56,14 +55,14 @@ abstract class PumpPluginAbstract protected constructor(
var sp: SP, var sp: SP,
var context: Context, var context: Context,
var fabricPrivacy: FabricPrivacy, var fabricPrivacy: FabricPrivacy,
dateUtil: DateUtil, var dateUtil: DateUtil,
aapsSchedulers: AapsSchedulers, var aapsSchedulers: AapsSchedulers,
pumpSync: PumpSync var pumpSync: PumpSync
) : PumpPluginBase(pluginDescription!!, injector!!, aapsLogger, resourceHelper, commandQueue), Pump, Constraints { ) : PumpPluginBase(pluginDescription!!, injector!!, aapsLogger, resourceHelper, commandQueue), Pump, Constraints {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
//protected override var injector: HasAndroidInjector? = null //protected override var injector: HasAndroidInjector? = null
protected var dateUtil: DateUtil //protected var dateUtil: DateUtil
// Pump capabilities // Pump capabilities
final override var pumpDescription = PumpDescription() final override var pumpDescription = PumpDescription()
@ -82,8 +81,8 @@ abstract class PumpPluginAbstract protected constructor(
} }
protected var aapsSchedulers: AapsSchedulers //protected var aapsSchedulers: AapsSchedulers
protected var pumpSync: PumpSync //protected var pumpSync: PumpSync
protected var gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() protected var gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
abstract fun initPumpStatusData() abstract fun initPumpStatusData()
@ -344,12 +343,12 @@ abstract class PumpPluginAbstract protected constructor(
// bolus needed, ask pump to deliver it // bolus needed, ask pump to deliver it
deliverBolus(detailedBolusInfo) deliverBolus(detailedBolusInfo)
} else { } else {
// TODO fix
// no bolus required, carb only treatment // no bolus required, carb only treatment
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true) // TODO carb only bolus - DONE
pumpSync.syncCarbsWithTimestamp(System.currentTimeMillis(), detailedBolusInfo.carbs, null, model(), serialNumber());
// activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true)
val bolusingEvent = EventOverviewBolusProgress val bolusingEvent = EventOverviewBolusProgress
bolusingEvent.t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType === DetailedBolusInfo.BolusType.SMB) bolusingEvent.t = EventOverviewBolusProgress.Treatment(0.0, detailedBolusInfo.carbs.toInt(), detailedBolusInfo.bolusType === DetailedBolusInfo.BolusType.SMB)
bolusingEvent.percent = 100 bolusingEvent.percent = 100
rxBus.send(bolusingEvent) rxBus.send(bolusingEvent)
aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.") aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment.")
@ -386,48 +385,13 @@ abstract class PumpPluginAbstract protected constructor(
return PumpEnactResult(injector).success(false).enacted(false).comment(resourceId) return PumpEnactResult(injector).success(false).enacted(false).comment(resourceId)
} }
// PumpSync
var driverHistory: MutableMap<Long, PumpDbEntry> = HashMap()
abstract fun generateTempId(timeMillis: Long): Long
protected fun addBolusWithTempId(detailedBolusInfo: DetailedBolusInfo, writeToInternalHistory: Boolean): Boolean {
val temporaryId = generateTempId(detailedBolusInfo.timestamp)
val response = pumpSync.addBolusWithTempId(detailedBolusInfo.timestamp, detailedBolusInfo.insulin,
temporaryId, detailedBolusInfo.bolusType,
pumpType, serialNumber())
if (response && writeToInternalHistory) {
driverHistory[temporaryId] = PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo)
sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory))
}
return response
}
// TODO
protected fun addTemporaryBasalRateWithTempId(temporaryBasal: TemporaryBasal, b: Boolean) {
val temporaryId = generateTempId(temporaryBasal.date)
val response = pumpSync.addBolusWithTempId(temporaryBasal.timestamp, detailedBolusInfo.insulin,
generateTempId(detailedBolusInfo.timestamp), detailedBolusInfo.getBolusType(),
getPumpType(), serialNumber());
if (response && writeToInternalHistory) {
driverHistory.put(temporaryId, new PumpDbEntry(temporaryId, model(), serialNumber(), detailedBolusInfo));
sp.putString(MedtronicConst.Statistics.InternalTemporaryDatabase, gson.toJson(driverHistory));
}
return response;
}
fun removeTemporaryId(temporaryId: Long) {
driverHistory.remove(temporaryId)
}
init { init {
pumpDescription.setPumpDescription(pumpType) pumpDescription.setPumpDescription(pumpType)
this.pumpType = pumpType this.pumpType = pumpType
this.dateUtil = dateUtil this.dateUtil = dateUtil
this.aapsSchedulers = aapsSchedulers this.aapsSchedulers = aapsSchedulers
this.pumpSync = pumpSync //this.pumpSync = pumpSync
} }
} }

View file

@ -1,9 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.data
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
data class PumpDbEntry(var temporaryId: Long,
var pumpType: PumpType,
var serialNumber: String,
var detailedBolusInfo: DetailedBolusInfo)

View file

@ -34,7 +34,7 @@ abstract class PumpStatus(var pumpType: PumpType) {
var maxDailyTotalUnits: String? = null var maxDailyTotalUnits: String? = null
var units : String? = null // Constants.MGDL or Constants.MMOL var units : String? = null // Constants.MGDL or Constants.MMOL
var pumpStatusType = PumpStatusType.Running var pumpStatusType = PumpStatusType.Running
var basalsByHour: Array<Double>? = null var basalsByHour: DoubleArray? = null
var tempBasalStart: Date? = null var tempBasalStart: Date? = null
var tempBasalAmount: Double? = 0.0 var tempBasalAmount: Double? = 0.0
var tempBasalLength: Int? = 0 var tempBasalLength: Int? = 0

View file

@ -37,7 +37,9 @@ 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.PumpSyncEntriesCreator
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.sync.PumpSyncStorage
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData
@ -88,7 +90,8 @@ class MedtronicPumpPlugin @Inject constructor(
private val serviceTaskExecutor: ServiceTaskExecutor, private val serviceTaskExecutor: ServiceTaskExecutor,
dateUtil: DateUtil, dateUtil: DateUtil,
aapsSchedulers: AapsSchedulers, aapsSchedulers: AapsSchedulers,
pumpSync: PumpSync pumpSync: PumpSync,
val pumpSyncStorage: PumpSyncStorage
) : PumpPluginAbstract(PluginDescription() // ) : PumpPluginAbstract(PluginDescription() //
.mainType(PluginType.PUMP) // .mainType(PluginType.PUMP) //
.fragmentClass(MedtronicFragment::class.java.name) // .fragmentClass(MedtronicFragment::class.java.name) //
@ -99,7 +102,7 @@ class MedtronicPumpPlugin @Inject constructor(
.description(R.string.description_pump_medtronic), // .description(R.string.description_pump_medtronic), //
PumpType.MEDTRONIC_522_722, // we default to most basic model, correct model from config is loaded later PumpType.MEDTRONIC_522_722, // we default to most basic model, correct model from config is loaded later
injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers, pumpSync injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers, pumpSync
), Pump, RileyLinkPumpDevice { ), Pump, RileyLinkPumpDevice, PumpSyncEntriesCreator {
private var rileyLinkMedtronicService: RileyLinkMedtronicService? = null private var rileyLinkMedtronicService: RileyLinkMedtronicService? = null
@ -167,6 +170,8 @@ class MedtronicPumpPlugin @Inject constructor(
sp.putLong(MedtronicConst.Statistics.FirstPumpStart, System.currentTimeMillis()) sp.putLong(MedtronicConst.Statistics.FirstPumpStart, System.currentTimeMillis())
} }
migrateSettings() migrateSettings()
pumpSyncStorage.initStorage();
} }
override fun triggerPumpConfigurationChangedEvent() { override fun triggerPumpConfigurationChangedEvent() {
@ -482,7 +487,7 @@ class MedtronicPumpPlugin @Inject constructor(
private fun isProfileSame(profile: Profile): Boolean { private fun isProfileSame(profile: Profile): Boolean {
var invalid = false var invalid = false
val basalsByHour: Array<Double>? = medtronicPumpStatus.basalsByHour val basalsByHour: DoubleArray? = medtronicPumpStatus.basalsByHour
aapsLogger.debug(LTag.PUMP, "Current Basals (h): " aapsLogger.debug(LTag.PUMP, "Current Basals (h): "
+ (basalsByHour?.let { getProfilesByHourToString(it) } ?: "null")) + (basalsByHour?.let { getProfilesByHourToString(it) } ?: "null"))
@ -526,13 +531,12 @@ class MedtronicPumpPlugin @Inject constructor(
rxBus.send(EventMedtronicPumpValuesChanged()) rxBus.send(EventMedtronicPumpValuesChanged())
} }
override fun generateTempId(timeMillis: Long): Long { override fun generateTempId(objectA: Any): Long {
return 0 val timestamp: Long = objectA as Long
return DateTimeUtil.toATechDate(timestamp)
} }
// @Override public String getSerial() {
// return null;
// }
private var bolusDeliveryType = BolusDeliveryType.Idle private var bolusDeliveryType = BolusDeliveryType.Idle
private enum class BolusDeliveryType { private enum class BolusDeliveryType {
@ -629,12 +633,15 @@ class MedtronicPumpPlugin @Inject constructor(
detailedBolusInfo.timestamp = now detailedBolusInfo.timestamp = now
detailedBolusInfo.deliverAtTheLatest = now // not sure about that one detailedBolusInfo.deliverAtTheLatest = now // not sure about that one
// TODO fix pumpSyncStorage.addBolusWithTempId(detailedBolusInfo, true, this)
if (usePumpSync) {
addBolusWithTempId(detailedBolusInfo, true)
} else { // // TODO fix
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true) // if (usePumpSync) {
} // pumpSyncStorage.addBolusWithTempId(detailedBolusInfo, true, this)
// } else {
// activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true)
// }
// we subtract insulin, exact amount will be visible with next remainingInsulin update. // we subtract insulin, exact amount will be visible with next remainingInsulin update.
medtronicPumpStatus.reservoirRemainingUnits = medtronicPumpStatus.reservoirRemainingUnits - detailedBolusInfo.insulin medtronicPumpStatus.reservoirRemainingUnits = medtronicPumpStatus.reservoirRemainingUnits - detailedBolusInfo.insulin
@ -767,7 +774,7 @@ class MedtronicPumpPlugin @Inject constructor(
// TODO fix // TODO fix
if (usePumpSync) { if (usePumpSync) {
addTemporaryBasalRateWithTempId(tempStart, true) pumpSyncStorage.addTemporaryBasalRateWithTempId(tempStart, true, this)
} else { } else {
activePlugin.activeTreatments.addToHistoryTempBasal(tempStart) activePlugin.activeTreatments.addToHistoryTempBasal(tempStart)
} }
@ -834,7 +841,7 @@ class MedtronicPumpPlugin @Inject constructor(
val debugHistory = false val debugHistory = false
var targetDate: LocalDateTime? = null var targetDate: LocalDateTime? = null
if (lastPumpHistoryEntry == null) { if (lastPumpHistoryEntry == null) { // first read
if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntry: null") if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntry: null")
val lastPumpHistoryEntryTime = lastPumpEntryTime val lastPumpHistoryEntryTime = lastPumpEntryTime
var timeMinus36h = LocalDateTime() var timeMinus36h = LocalDateTime()
@ -858,12 +865,9 @@ class MedtronicPumpPlugin @Inject constructor(
targetDate = if (timeMinus36h.isAfter(lastHistoryRecordTime)) timeMinus36h else lastHistoryRecordTime targetDate = if (timeMinus36h.isAfter(lastHistoryRecordTime)) timeMinus36h else lastHistoryRecordTime
if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): targetDate: " + targetDate) if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): targetDate: " + targetDate)
} }
} else { } else { // all other reads
if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + medtronicUtil.gsonInstance.toJson(lastPumpHistoryEntry)) if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntry: not null - " + medtronicUtil.gsonInstance.toJson(lastPumpHistoryEntry))
medtronicHistoryData.setIsInInit(false) medtronicHistoryData.setIsInInit(false)
// medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntry.atechDateTime);
// targetDate = lastPumpHistoryEntry.atechDateTime;
} }
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate); //aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
@ -883,20 +887,20 @@ class MedtronicPumpPlugin @Inject constructor(
medtronicHistoryData.filterNewEntries() medtronicHistoryData.filterNewEntries()
// determine if first run, if yes detrmine how much of update do we need // determine if first run, if yes detrmine how much of update do we need
// first run: // - first run:
// get last hiostory entry, if not there download 1.5 days of data // - get last history entry
// - if not there download 1.5 days of data
// - there: check if last entry is older than 1.5 days // - there: check if last entry is older than 1.5 days
// - yes: download 1.5 days // - yes: download 1.5 days
// - no: download with last entry // - no: download with last entry TODO 5min
// - not there: download 1.5 days // - not there: download 1.5 days
// //
// upload all new entries to NightScout (TBR, Bolus) // upload all new entries to NightScout (TBR, Bolus)
// determine pump status // determine pump status
//
// save last entry // save last entry
// //
// not first run: // - not first run:
// update to last entry // - update to last entry TODO 5min
// - save // - save
// - determine pump status // - determine pump status
} }
@ -1015,7 +1019,7 @@ class MedtronicPumpPlugin @Inject constructor(
// TODO fix // TODO fix
if (usePumpSync) { if (usePumpSync) {
addTemporaryBasalRateWithTempId(tempBasal, true) pumpSyncStorage.addTemporaryBasalRateWithTempId(tempBasal, true, this)
} else { } else {
activePlugin.activeTreatments.addToHistoryTempBasal(tempBasal) activePlugin.activeTreatments.addToHistoryTempBasal(tempBasal)
} }

View file

@ -551,10 +551,13 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
errorResponse = check errorResponse = check
} }
var basalProfile: BasalProfile? = null
checkResponseRawContent(data, commandType) { aapsLogger.debug(LTag.PUMPCOMM,"End Response: {}", ByteUtil.getHex(data))
basalProfile = medtronicConverter.decodeBasalProfile(medtronicPumpPlugin.pumpDescription.pumpType, data)
} var basalProfile: BasalProfile? = medtronicConverter.decodeBasalProfile(medtronicPumpPlugin.pumpDescription.pumpType, data)
// checkResponseRawContent(data, commandType) {
// basalProfile = medtronicConverter.decodeBasalProfile(medtronicPumpPlugin.pumpDescription.pumpType, data)
// }
if (basalProfile != null) { if (basalProfile != null) {
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, basalProfile)) aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, basalProfile))

View file

@ -47,7 +47,7 @@ enum class PumpHistoryEntryType // implements CodeEnum
BolusWizardEnabled(0x2d, "Bolus Wizard Enabled", PumpHistoryEntryGroup.Configuration), // V3 ? BolusWizardEnabled(0x2d, "Bolus Wizard Enabled", PumpHistoryEntryGroup.Configuration), // V3 ?
/* TODO */ EventUnknown_MM512_0x2e(0x2e, "Unknown Event 0x2e", PumpHistoryEntryGroup.Unknown, 2, 5, 100), // /* TODO */ EventUnknown_MM512_0x2e(0x2e, "Unknown Event 0x2e", PumpHistoryEntryGroup.Unknown, 2, 5, 100), //
BolusWizard512(0x2f, "Bolus Wizard (512)", PumpHistoryEntryGroup.Bolus, 2, 5, 12), // BolusWizard512(0x2f, "Bolus Wizard (512)", PumpHistoryEntryGroup.Bolus, 2, 5, 12), //
UnabsorbedInsulin512(0x30, "Unabsorbed Insulin (512)", PumpHistoryEntryGroup.Statistic, 5, 0, 0), // FIXME UnabsorbedInsulin512(0x30, "Unabsorbed Insulin (512)", PumpHistoryEntryGroup.Statistic, 5, 0, 0),
ChangeBGReminderOffset(0x31, "Change BG Reminder Offset", PumpHistoryEntryGroup.Configuration), // ChangeBGReminderOffset(0x31, "Change BG Reminder Offset", PumpHistoryEntryGroup.Configuration), //
ChangeAlarmClockTime(0x32, "Change Alarm Clock Time", PumpHistoryEntryGroup.Configuration), // ChangeAlarmClockTime(0x32, "Change Alarm Clock Time", PumpHistoryEntryGroup.Configuration), //
TempBasalRate(0x33, "TBR Rate", PumpHistoryEntryGroup.Basal, 2, 5, 1), // TempBasalRate(0x33, "TBR Rate", PumpHistoryEntryGroup.Basal, 2, 5, 1), //

View file

@ -51,8 +51,10 @@ class PumpHistoryResult(private val aapsLogger: AAPSLogger, searchEntry: PumpHis
} }
//aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry); //aapsLogger.debug(LTag.PUMPCOMM,"PE. Entry {} added.", unprocessedEntry);
validEntries.add(unprocessedEntry) validEntries.add(unprocessedEntry)
} }
// TODO 5minutes back
} }
SearchType.Date -> { SearchType.Date -> {

View file

@ -11,6 +11,8 @@ import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntry
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage
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.StringUtil import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder
@ -27,7 +29,6 @@ import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import org.joda.time.LocalDateTime import org.joda.time.LocalDateTime
import org.joda.time.Minutes
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -51,7 +52,8 @@ class MedtronicHistoryData @Inject constructor(
val medtronicPumpHistoryDecoder: MedtronicPumpHistoryDecoder, val medtronicPumpHistoryDecoder: MedtronicPumpHistoryDecoder,
val medtronicPumpStatus: MedtronicPumpStatus, val medtronicPumpStatus: MedtronicPumpStatus,
val databaseHelper: DatabaseHelperInterface, val databaseHelper: DatabaseHelperInterface,
val pumpSync: PumpSync val pumpSync: PumpSync,
val pumpSyncStorage: PumpSyncStorage
) { ) {
val allHistory: MutableList<PumpHistoryEntry> = mutableListOf() val allHistory: MutableList<PumpHistoryEntry> = mutableListOf()
@ -304,7 +306,7 @@ class MedtronicHistoryData @Inject constructor(
// TDD // TDD
val tdds: MutableList<PumpHistoryEntry> = getFilteredItems(setOf(PumpHistoryEntryType.EndResultTotals, tDDType)) val tdds: MutableList<PumpHistoryEntry> = getFilteredItems(setOf(PumpHistoryEntryType.EndResultTotals, tDDType))
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: TDD [count=%d, items=%s]", tdds.size, gson.toJson(tdds))) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: TDD [count=%d, items=%s]", tdds.size, gson.toJson(tdds)))
if (isCollectionNotEmpty(tdds)) { if (tdds.isNotEmpty()) {
try { try {
processTDDs(tdds) processTDDs(tdds)
} catch (ex: Exception) { } catch (ex: Exception) {
@ -317,7 +319,7 @@ class MedtronicHistoryData @Inject constructor(
// Bolus // Bolus
val treatments = getFilteredItems(PumpHistoryEntryType.Bolus) val treatments = getFilteredItems(PumpHistoryEntryType.Bolus)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: Bolus [count=%d, items=%s]", treatments.size, gson.toJson(treatments))) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: Bolus [count=%d, items=%s]", treatments.size, gson.toJson(treatments)))
if (treatments.size > 0) { if (treatments.isNotEmpty()) {
try { try {
processBolusEntries(treatments) processBolusEntries(treatments)
} catch (ex: Exception) { } catch (ex: Exception) {
@ -329,9 +331,9 @@ class MedtronicHistoryData @Inject constructor(
// TBR // TBR
val tbrs: MutableList<PumpHistoryEntry> = getFilteredItems(PumpHistoryEntryType.TempBasalCombined) val tbrs: MutableList<PumpHistoryEntry> = getFilteredItems(PumpHistoryEntryType.TempBasalCombined)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: TBRs Processed [count=%d, items=%s]", tbrs.size, gson.toJson(tbrs))) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: TBRs Processed [count=%d, items=%s]", tbrs.size, gson.toJson(tbrs)))
if (tbrs.size > 0) { if (tbrs.isNotEmpty()) {
try { try {
processTBREntries(tbrs) processTBREntries(tbrs) // TODO not implemented yet
} catch (ex: Exception) { } catch (ex: Exception) {
aapsLogger.error(LTag.PUMP, "ProcessHistoryData: Error processing TBR entries: " + ex.message, ex) aapsLogger.error(LTag.PUMP, "ProcessHistoryData: Error processing TBR entries: " + ex.message, ex)
throw ex throw ex
@ -348,9 +350,9 @@ class MedtronicHistoryData @Inject constructor(
} }
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: 'Delivery Suspend' Processed [count=%d, items=%s]", suspends.size, aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: 'Delivery Suspend' Processed [count=%d, items=%s]", suspends.size,
gson.toJson(suspends))) gson.toJson(suspends)))
if (isCollectionNotEmpty(suspends)) { if (suspends.isNotEmpty()) {
try { try {
processSuspends(suspends) processSuspends(suspends) // TODO not tested yet
} catch (ex: Exception) { } catch (ex: Exception) {
aapsLogger.error(LTag.PUMP, "ProcessHistoryData: Error processing Suspends entries: " + ex.message, ex) aapsLogger.error(LTag.PUMP, "ProcessHistoryData: Error processing Suspends entries: " + ex.message, ex)
throw ex throw ex
@ -410,13 +412,11 @@ class MedtronicHistoryData @Inject constructor(
private fun processTDDs(tddsIn: MutableList<PumpHistoryEntry>) { private fun processTDDs(tddsIn: MutableList<PumpHistoryEntry>) {
val tdds = filterTDDs(tddsIn) val tdds = filterTDDs(tddsIn)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, """
${logPrefix}TDDs found: %d. aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, logPrefix + "TDDs found: %d.\n%s",
%s tdds.size, gson.toJson(tdds)))
""".trimIndent(), tdds.size, gson.toJson(tdds)))
//val tddsDb = databaseHelper.getTDDsForLastXDays(3)
for (tdd in tdds) { for (tdd in tdds) {
//val tddDbEntry = findTDD(tdd.atechDateTime!!, tddsDb)
val totalsDTO = tdd.decodedData!!["Object"] as DailyTotalsDTO val totalsDTO = tdd.decodedData!!["Object"] as DailyTotalsDTO
pumpSync.createOrUpdateTotalDailyDose( pumpSync.createOrUpdateTotalDailyDose(
@ -428,10 +428,21 @@ class MedtronicHistoryData @Inject constructor(
medtronicPumpStatus.pumpType, medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!! medtronicPumpStatus.serialNumber!!
) )
}
}
// timestamp: Long, bolusAmount: Double, basalAmount: Double, totalAmount: Double,
// pumpId: Long?, pumpType: PumpType, pumpSerial: String
// private fun processTDDs_Old(tddsIn: MutableList<PumpHistoryEntry>) {
// val tdds = filterTDDs(tddsIn)
// aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, """
// ${logPrefix}TDDs found: %d.
// %s
// """.trimIndent(), tdds.size, gson.toJson(tdds)))
// //val tddsDb = databaseHelper.getTDDsForLastXDays(3)
// for (tdd in tdds) {
// //val tddDbEntry = findTDD(tdd.atechDateTime!!, tddsDb)
// val totalsDTO = tdd.decodedData!!["Object"] as DailyTotalsDTO
//
// aapsLogger.debug(LTag.PUMP, "DailyTotals: {}", totalsDTO); // aapsLogger.debug(LTag.PUMP, "DailyTotals: {}", totalsDTO);
// if (tddDbEntry == null) { // if (tddDbEntry == null) {
// val tddNew = TDD() // val tddNew = TDD()
@ -445,8 +456,8 @@ class MedtronicHistoryData @Inject constructor(
// databaseHelper.createOrUpdateTDD(tddDbEntry) // databaseHelper.createOrUpdateTDD(tddDbEntry)
// } // }
// } // }
} // }
} // }
private enum class ProcessHistoryRecord(val description: String) { private enum class ProcessHistoryRecord(val description: String) {
Bolus("Bolus"), Bolus("Bolus"),
@ -454,7 +465,111 @@ class MedtronicHistoryData @Inject constructor(
Suspend("Suspend"); Suspend("Suspend");
} }
private fun processBolusEntries(entryList: MutableList<PumpHistoryEntry>) { private fun processBolusEntries(entryList: MutableList<PumpHistoryEntry>) {
val boluses = pumpSyncStorage.getBoluses()
for (bolus in entryList) {
val bolusDTO = bolus.decodedData!!["Object"]!! as BolusDTO
var type: DetailedBolusInfo.BolusType = DetailedBolusInfo.BolusType.NORMAL
var multiwave = false
if (bolusDTO.bolusType==PumpBolusType.Extended) {
addExtendedBolus(bolus, bolusDTO, multiwave)
continue;
} else if (bolusDTO.bolusType==PumpBolusType.Multiwave) {
multiwave = true
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Multiwave bolus from pump, extended bolus and normal bolus will be added."))
addExtendedBolus(bolus, bolusDTO, multiwave);
}
val deliveredAmount: Double = if (multiwave) bolusDTO.immediateAmount!! else bolusDTO.deliveredAmount!!
var temporaryId: Long? = null
if (!multiwave) {
val entryWithTempId = findDbEntry(bolus, boluses)
if (entryWithTempId != null) {
temporaryId = entryWithTempId.temporaryId
pumpSyncStorage.removeBolusWithTemporaryId(temporaryId)
boluses.remove(entryWithTempId)
type = entryWithTempId.bolusData!!.bolusType
}
}
if (temporaryId!=null) {
val result = pumpSync.syncBolusWithTempId(
tryToGetByLocalTime(bolus.atechDateTime!!),
deliveredAmount,
temporaryId,
type,
bolus.pumpId,
medtronicPumpStatus.pumpType,
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!!)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithPumpId [date=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime!!, bolus.pumpId, deliveredAmount,
medtronicPumpStatus.serialNumber!!, result))
}
addCarbs(bolus)
}
}
private fun addExtendedBolus(bolus: PumpHistoryEntry, bolusDTO: BolusDTO, isMultiwave: Boolean) {
val durationMs : Long = bolusDTO.duration!! * 60L * 1000L
val result = pumpSync.syncExtendedBolusWithPumpId(
tryToGetByLocalTime(bolus.atechDateTime!!),
bolusDTO.deliveredAmount!!,
durationMs,
false,
bolus.pumpId!!,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncExtendedBolusWithPumpId [date=%d, amount=%.2f, duration=%d, pumpId=%d, pumpSerial=%s, multiwave=%b] - Result: %b",
bolus.atechDateTime!!, bolusDTO.deliveredAmount!!, bolusDTO.duration, bolus.pumpId,
medtronicPumpStatus.serialNumber!!, isMultiwave, result))
}
private fun addCarbs(bolus: PumpHistoryEntry) {
if (bolus.containsDecodedData("Estimate")) {
val bolusWizard = bolus.decodedData!!["Estimate"] as BolusWizardDTO
val result = pumpSync.syncCarbsWithTimestamp(
tryToGetByLocalTime(bolus.atechDateTime!!),
bolusWizard.carbs.toDouble(),
bolus.pumpId!!,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncCarbsWithTimestamp [date=%d, pumpId=%d, carbs=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime!!, bolusWizard.carbs.toDouble(), bolus.pumpId,
medtronicPumpStatus.serialNumber!!, result))
}
}
private fun processBolusEntries_Old(entryList: MutableList<PumpHistoryEntry>) {
val oldestTimestamp = getOldestTimestamp(entryList) val oldestTimestamp = getOldestTimestamp(entryList)
val entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.Bolus) val entriesFromHistory = getDatabaseEntriesByLastTimestamp(oldestTimestamp, ProcessHistoryRecord.Bolus)
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: List (before filter): %s, FromDb=%s", gson.toJson(entryList), if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: List (before filter): %s, FromDb=%s", gson.toJson(entryList),
@ -475,7 +590,7 @@ class MedtronicHistoryData @Inject constructor(
} }
} else { } else {
for (treatment in entryList) { for (treatment in entryList) {
val treatmentDb = findDbEntry(treatment, entriesFromHistory) val treatmentDb = findDbEntry_Old(treatment, entriesFromHistory)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Add Bolus %s - (entryFromDb=%s) ", treatment, treatmentDb)) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Add Bolus %s - (entryFromDb=%s) ", treatment, treatmentDb))
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: Add Bolus: FromDb=%s, Treatment=%s", treatmentDb, treatment)) if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: Add Bolus: FromDb=%s, Treatment=%s", treatmentDb, treatment))
addBolus(treatment, treatmentDb as Treatment?) addBolus(treatment, treatmentDb as Treatment?)
@ -558,7 +673,7 @@ class MedtronicHistoryData @Inject constructor(
tbr2!!.durationMinutes = tempBasalProcessDTO.duration tbr2!!.durationMinutes = tempBasalProcessDTO.duration
val tempBasal = findTempBasalWithPumpId(tempBasalProcessDTO.itemOne!!.pumpId!!, entriesFromHistory) val tempBasal = findTempBasalWithPumpId(tempBasalProcessDTO.itemOne!!.pumpId!!, entriesFromHistory)
if (tempBasal == null) { if (tempBasal == null) {
val treatmentDb = findDbEntry(treatment, entriesFromHistory) val treatmentDb = findDbEntry_Old(treatment, entriesFromHistory)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Add " + ProcessHistoryRecord.TBR.description + " %s - (entryFromDb=%s) ", treatment, treatmentDb)) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "Add " + ProcessHistoryRecord.TBR.description + " %s - (entryFromDb=%s) ", treatment, treatmentDb))
addTBR(treatment, treatmentDb as TemporaryBasal?) addTBR(treatment, treatmentDb as TemporaryBasal?)
} else { } else {
@ -593,7 +708,7 @@ class MedtronicHistoryData @Inject constructor(
* @param entriesFromHistory entries from history * @param entriesFromHistory entries from history
* @return DbObject from AAPS (if found) * @return DbObject from AAPS (if found)
*/ */
private fun findDbEntry(treatment: PumpHistoryEntry?, entriesFromHistory: List<DbObjectBase>): DbObjectBase? { private fun findDbEntry_Old(treatment: PumpHistoryEntry?, entriesFromHistory: List<DbObjectBase>): DbObjectBase? {
val proposedTime = DateTimeUtil.toMillisFromATD(treatment!!.atechDateTime!!) val proposedTime = DateTimeUtil.toMillisFromATD(treatment!!.atechDateTime!!)
//proposedTime += (this.pumpTime.timeDifference * 1000); //proposedTime += (this.pumpTime.timeDifference * 1000);
@ -644,11 +759,69 @@ class MedtronicHistoryData @Inject constructor(
return null return null
} }
/**
* Looks at all boluses that have temporaryId and find one that is correct for us (if such entry exists)
*/
private fun findDbEntry(treatment: PumpHistoryEntry?, temporaryEntries: MutableList<PumpDbEntry>): PumpDbEntry? {
if (temporaryEntries.isEmpty()) {
return null
}
var proposedTime = DateTimeUtil.toMillisFromATD(treatment!!.atechDateTime!!)
proposedTime += (this.pumpTime!!.timeDifference * 1000)
val proposedTimeDiff : LongArray = longArrayOf(proposedTime-(2*60*1000), proposedTime+(2L*60L*1000L))
val tempEntriesList: MutableList<PumpDbEntry> = mutableListOf()
for (temporaryEntry in temporaryEntries) {
if (temporaryEntry.date > proposedTimeDiff[0] && temporaryEntry.date < proposedTimeDiff[1]) {
tempEntriesList.add(temporaryEntry)
}
}
if (tempEntriesList.isEmpty()) {
return null
} else if (tempEntriesList.size==1) {
return tempEntriesList[0]
}
var min = 0
while (min < 2) {
var sec = 0
while (sec <= 50) {
if (min == 1 && sec == 50) {
sec = 59
}
val diff = sec * 1000
val outList: MutableList<PumpDbEntry> = mutableListOf()
for (treatment1 in tempEntriesList) {
if (treatment1.date > proposedTime - diff && treatment1.date < proposedTime + diff) {
outList.add(treatment1)
}
}
if (outList.size == 1) {
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: findDbEntry Treatment={}, FromDb={}. Type=EntrySelected, AtTimeMin={}, AtTimeSec={}", treatment, outList[0], min, sec))
return outList[0]
}
if (min == 0 && sec == 10 && outList.size > 1) {
aapsLogger.error(String.format(Locale.ENGLISH, "Too many entries (with too small diff): (timeDiff=[min=%d,sec=%d],count=%d,list=%s)",
min, sec, outList.size, gson.toJson(outList)))
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: findDbEntry Error - Too many entries (with too small diff): (timeDiff=[min=%d,sec=%d],count=%d,list=%s)",
min, sec, outList.size, gson.toJson(outList)))
}
sec += 10
}
min += 1
}
return null
}
private fun getDatabaseEntriesByLastTimestamp(startTimestamp: Long, processHistoryRecord: ProcessHistoryRecord): MutableList<DbObjectBase> { private fun getDatabaseEntriesByLastTimestamp(startTimestamp: Long, processHistoryRecord: ProcessHistoryRecord): MutableList<DbObjectBase> {
var outList: MutableList<DbObjectBase> = mutableListOf() var outList: MutableList<DbObjectBase> = mutableListOf()
if (processHistoryRecord == ProcessHistoryRecord.Bolus) { if (processHistoryRecord == ProcessHistoryRecord.Bolus) {
// TODO pumpSync - activeTreatments.getTreatmentsFromHistoryAfterTimestamp
outList.addAll(activePlugin.activeTreatments.getTreatmentsFromHistoryAfterTimestamp(startTimestamp)) outList.addAll(activePlugin.activeTreatments.getTreatmentsFromHistoryAfterTimestamp(startTimestamp))
} else { } else {
// TODO pumpSync - databaseHelper.getTemporaryBasalsDataFromTime(startTimestamp, true) // TODO pumpSync - databaseHelper.getTemporaryBasalsDataFromTime(startTimestamp, true)
@ -701,7 +874,6 @@ class MedtronicHistoryData @Inject constructor(
detailedBolusInfo.insulin = bolusDTO.deliveredAmount!! detailedBolusInfo.insulin = bolusDTO.deliveredAmount!!
addCarbsFromEstimate(detailedBolusInfo, bolus) addCarbsFromEstimate(detailedBolusInfo, bolus)
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament==null): DetailedBolusInfo=$detailedBolusInfo") if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament==null): DetailedBolusInfo=$detailedBolusInfo")
// TODO pumpSync - activeTreatments.addToHistoryTreatment
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
bolus.linkedObject = detailedBolusInfo bolus.linkedObject = detailedBolusInfo
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "addBolus - [date=%d,pumpId=%d, insulin=%.2f, newRecord=%b]", detailedBolusInfo.timestamp, aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "addBolus - [date=%d,pumpId=%d, insulin=%.2f, newRecord=%b]", detailedBolusInfo.timestamp,
@ -718,7 +890,6 @@ class MedtronicHistoryData @Inject constructor(
extendedBolus.durationInMinutes = bolusDTO.duration!! extendedBolus.durationInMinutes = bolusDTO.duration!!
bolus.linkedObject = extendedBolus bolus.linkedObject = extendedBolus
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament==null): ExtendedBolus=$extendedBolus") if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, "DoubleBolusDebug: addBolus(tretament==null): ExtendedBolus=$extendedBolus")
// TODO pumpSync - activeTreatments.addToHistoryExtendedBolus
activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "addBolus - Extended [date=%d,pumpId=%d, insulin=%.3f, duration=%d]", extendedBolus.date, aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "addBolus - Extended [date=%d,pumpId=%d, insulin=%.3f, duration=%d]", extendedBolus.date,
extendedBolus.pumpId, extendedBolus.insulin, extendedBolus.durationInMinutes)) extendedBolus.pumpId, extendedBolus.insulin, extendedBolus.durationInMinutes))
@ -729,7 +900,6 @@ class MedtronicHistoryData @Inject constructor(
treatment.source = Source.PUMP treatment.source = Source.PUMP
treatment.pumpId = bolus.pumpId!! treatment.pumpId = bolus.pumpId!!
treatment.insulin = bolusDTO!!.deliveredAmount!! treatment.insulin = bolusDTO!!.deliveredAmount!!
// TODO pumpSync - activeTreatments.createOrUpdateMedtronic(treatment)
val updateReturn = activePlugin.activeTreatments.createOrUpdateMedtronic(treatment, false) val updateReturn = activePlugin.activeTreatments.createOrUpdateMedtronic(treatment, false)
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addBolus(tretament!=null): NewTreatment=%s, UpdateReturn=%s", treatment, updateReturn)) if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addBolus(tretament!=null): NewTreatment=%s, UpdateReturn=%s", treatment, updateReturn))
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "editBolus - [date=%d,pumpId=%d, insulin=%.3f, newRecord=%s]", treatment.date, aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "editBolus - [date=%d,pumpId=%d, insulin=%.3f, newRecord=%s]", treatment.date,
@ -742,7 +912,6 @@ class MedtronicHistoryData @Inject constructor(
if (bolus!!.containsDecodedData("Estimate")) { if (bolus!!.containsDecodedData("Estimate")) {
val bolusWizard = bolus.decodedData!!["Estimate"] as BolusWizardDTO? val bolusWizard = bolus.decodedData!!["Estimate"] as BolusWizardDTO?
if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addCarbsFromEstimate: Bolus=%s, BolusWizardDTO=%s", bolus, bolusWizard)) if (doubleBolusDebug) aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "DoubleBolusDebug: addCarbsFromEstimate: Bolus=%s, BolusWizardDTO=%s", bolus, bolusWizard))
// TODO pumpSync - Carbs
detailedBolusInfo.carbs = bolusWizard!!.carbs.toDouble() detailedBolusInfo.carbs = bolusWizard!!.carbs.toDouble()
} }
} }
@ -772,7 +941,28 @@ class MedtronicHistoryData @Inject constructor(
temporaryBasalDb.durationInMinutes)) temporaryBasalDb.durationInMinutes))
} }
private fun processSuspends(tempBasalProcessList: List<TempBasalProcessDTO>) { private fun processSuspends(tempBasalProcessList: List<TempBasalProcessDTO>) {
for (tempBasalProcess in tempBasalProcessList) {
val result = pumpSync.syncTemporaryBasalWithPumpId(
tryToGetByLocalTime(tempBasalProcess.itemOne!!.atechDateTime!!),
0.0,
tempBasalProcess.duration * 60 * 1000L,
true,
PumpSync.TemporaryBasalType.PUMP_SUSPEND,
tempBasalProcess.itemOne!!.pumpId!!,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "processSuspends::syncTemporaryBasalWithPumpId [date=%d, rate=%.2f, duration=%d, pumpId=%d, pumpSerial=%s] - Result: %b",
tempBasalProcess.itemOne!!.atechDateTime!!, 0.0, tempBasalProcess.duration, tempBasalProcess.itemOne!!.pumpId!!,
medtronicPumpStatus.serialNumber!!, result))
}
}
private fun processSuspends_Old(tempBasalProcessList: List<TempBasalProcessDTO>) {
for (tempBasalProcess in tempBasalProcessList) { for (tempBasalProcess in tempBasalProcessList) {
// TODO pumpSync - databaseHelper.findTempBasalByPumpId // TODO pumpSync - databaseHelper.findTempBasalByPumpId
var tempBasal = databaseHelper.findTempBasalByPumpId(tempBasalProcess.itemOne!!.pumpId!!) var tempBasal = databaseHelper.findTempBasalByPumpId(tempBasalProcess.itemOne!!.pumpId!!)

View file

@ -229,7 +229,7 @@ class BasalProfile {
// return this.mRawData; // return this.mRawData;
} }
fun getProfilesByHour(pumpType: PumpType): Array<Double> { fun getProfilesByHour(pumpType: PumpType): DoubleArray {
var entriesCopy: List<BasalProfileEntry>? = null var entriesCopy: List<BasalProfileEntry>? = null
try { try {
entriesCopy = getEntries() entriesCopy = getEntries()
@ -241,7 +241,7 @@ class BasalProfile {
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null); //FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
} }
val basalByHour = arrayOf<Double>() val basalByHour = DoubleArray(24)
if (entriesCopy == null || entriesCopy.size == 0) { if (entriesCopy == null || entriesCopy.size == 0) {
for (i in 0..23) { for (i in 0..23) {
@ -249,6 +249,7 @@ class BasalProfile {
} }
return basalByHour return basalByHour
} }
for (i in entriesCopy.indices) { for (i in entriesCopy.indices) {
val current = entriesCopy[i] val current = entriesCopy[i]
var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1 var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
@ -301,7 +302,7 @@ class BasalProfile {
} }
@JvmStatic @JvmStatic
fun getProfilesByHourToString(data: Array<Double>): String { fun getProfilesByHourToString(data: DoubleArray): String {
val stringBuilder = StringBuilder() val stringBuilder = StringBuilder()
for (value in data) { for (value in data) {
stringBuilder.append(String.format("%.3f", value)) stringBuilder.append(String.format("%.3f", value))

View file

@ -58,7 +58,8 @@ enum class MedtronicCommandType
7, R.string.medtronic_cmd_desc_get_time), // 0x70 7, R.string.medtronic_cmd_desc_get_time), // 0x70
GetBatteryStatus(0x72, "Get Battery Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, GetBatteryStatus(0x72, "Get Battery Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters,
0, R.string.medtronic_cmd_desc_get_battery_status), // 0, R.string.medtronic_cmd_desc_get_battery_status), //
GetRemainingInsulin(0x73, "Read Remaining Insulin", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 2), // 115 GetRemainingInsulin(0x73, "Read Remaining Insulin", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters,
2, R.string.medtronic_cmd_desc_get_remaining_insulin), // 115
SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, // SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
0, R.string.medtronic_cmd_desc_set_bolus), // 66 0, R.string.medtronic_cmd_desc_set_bolus), // 66

View file

@ -41,11 +41,10 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
rileyLinkUtil.rileyLinkHistory.add(RLHistoryItem(pumpDeviceState, RileyLinkTargetDevice.MedtronicPump)) rileyLinkUtil.rileyLinkHistory.add(RLHistoryItem(pumpDeviceState, RileyLinkTargetDevice.MedtronicPump))
rxBus.send(EventRileyLinkDeviceStatusChange(pumpDeviceState)) rxBus.send(EventRileyLinkDeviceStatusChange(pumpDeviceState))
} }
var medtronicDeviceType: MedtronicDeviceType? = null
// fixme var medtronicDeviceType: MedtronicDeviceType? = null
var medtronicPumpMap: MutableMap<String, PumpType> = HashMap() var medtronicPumpMap: MutableMap<String, PumpType> = mutableMapOf()
var medtronicDeviceTypeMap: MutableMap<String, MedtronicDeviceType> = HashMap() var medtronicDeviceTypeMap: MutableMap<String, MedtronicDeviceType> = mutableMapOf()
var basalProfileStatus = BasalProfileStatus.NotInitialized var basalProfileStatus = BasalProfileStatus.NotInitialized
var batteryType = BatteryType.None var batteryType = BatteryType.None
@ -98,16 +97,16 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
} }
// Battery type // Battery type
private var mapByDescription: MutableMap<String, BatteryType?> = HashMap() private var batteryTypeByDescMap: MutableMap<String, BatteryType?> = HashMap()
fun getBatteryTypeByDescription(batteryTypeStr: String?): BatteryType? { fun getBatteryTypeByDescription(batteryTypeStr: String?): BatteryType? {
if (mapByDescription.size == 0) { if (batteryTypeByDescMap.size == 0) {
for (value in BatteryType.values()) { for (value in BatteryType.values()) {
mapByDescription[resourceHelper.gs(value.description)] = value batteryTypeByDescMap[resourceHelper.gs(value.description)] = value
} }
} }
return if (mapByDescription.containsKey(batteryTypeStr)) { return if (batteryTypeByDescMap.containsKey(batteryTypeStr)) {
mapByDescription[batteryTypeStr] batteryTypeByDescMap[batteryTypeStr]
} else BatteryType.None } else BatteryType.None
} }

View file

@ -105,6 +105,7 @@
<string name="medtronic_cmd_desc_get_tbr">Get Temporary Basal</string> <string name="medtronic_cmd_desc_get_tbr">Get Temporary Basal</string>
<string name="medtronic_cmd_desc_set_tbr">Set Temporary Basal</string> <string name="medtronic_cmd_desc_set_tbr">Set Temporary Basal</string>
<string name="medtronic_cmd_desc_set_bolus">Set Bolus</string> <string name="medtronic_cmd_desc_set_bolus">Set Bolus</string>
<string name="medtronic_cmd_desc_get_remaining_insulin">Get Remaining Insulin</string>
<string name="medtronic_pump_status_pump_unreachable">Pump unreachable</string> <string name="medtronic_pump_status_pump_unreachable">Pump unreachable</string>
<string name="medtronic_warning">Warning</string> <!-- medtronic_warning --> <string name="medtronic_warning">Warning</string> <!-- medtronic_warning -->