Cache TDD calculations

This commit is contained in:
Milos Kozak 2022-06-09 15:22:02 +02:00
parent 16c5b27bdd
commit 845879d916
7 changed files with 261 additions and 189 deletions

View file

@ -39,7 +39,6 @@ import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils

View file

@ -30,6 +30,7 @@ import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.workflow.CalculationWorkflow
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -127,10 +128,20 @@ class IobCobCalculatorPlugin @Inject constructor(
} }
private fun resetDataAndRunCalculation(reason: String, event: Event?) { private fun resetDataAndRunCalculation(reason: String, event: Event?) {
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,reason) calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, reason)
clearCache() clearCache()
ads.reset() ads.reset()
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event, runLoop = true) calculationWorkflow.runCalculation(
CalculationWorkflow.MAIN_CALCULATION,
this,
overviewData,
reason,
System.currentTimeMillis(),
bgDataReload = false,
limitDataToOldestAvailable = true,
cause = event,
runLoop = true
)
} }
override fun clearCache() { override fun clearCache() {
@ -363,9 +374,11 @@ class IobCobCalculatorPlugin @Inject constructor(
scheduledHistoryPost?.cancel(false) scheduledHistoryPost?.cancel(false)
// prepare task for execution in 1 sec // prepare task for execution in 1 sec
scheduledEvent = event scheduledEvent = event
scheduledHistoryPost = historyWorker.schedule({ scheduledHistoryPost = historyWorker.schedule(
{
synchronized(this) { synchronized(this) {
aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData") aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData")
repository.clearCachedData(MidnightTime.calc(event.oldDataTimestamp))
newHistoryData( newHistoryData(
event.oldDataTimestamp, event.oldDataTimestamp,
event.reloadBgData, event.reloadBgData,
@ -374,7 +387,8 @@ class IobCobCalculatorPlugin @Inject constructor(
scheduledEvent = null scheduledEvent = null
scheduledHistoryPost = null scheduledHistoryPost = null
} }
}, 1L, TimeUnit.SECONDS) }, 1L, TimeUnit.SECONDS
)
} else { } else {
// asked reload is newer -> adjust params only // asked reload is newer -> adjust params only
scheduledEvent?.let { scheduledEvent?.let {
@ -391,7 +405,7 @@ class IobCobCalculatorPlugin @Inject constructor(
// When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated // When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated
private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) { private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) {
//log.debug("Locking onNewHistoryData"); //log.debug("Locking onNewHistoryData");
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,"onEventNewHistoryData") calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, "onEventNewHistoryData")
synchronized(dataLock) { synchronized(dataLock) {
// clear up 5 min back for proper COB calculation // clear up 5 min back for proper COB calculation
@ -415,7 +429,7 @@ class IobCobCalculatorPlugin @Inject constructor(
} }
ads.newHistoryData(time, aapsLogger, dateUtil) ads.newHistoryData(time, aapsLogger, dateUtil)
} }
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true) calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION, this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true)
//log.debug("Releasing onNewHistoryData"); //log.debug("Releasing onNewHistoryData");
} }

View file

@ -11,6 +11,8 @@ import android.widget.TableRow
import android.widget.TextView import android.widget.TextView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TotalDailyDose import info.nightscout.androidaps.database.entities.TotalDailyDose
import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.convertedToAbsolute
@ -19,10 +21,10 @@ import info.nightscout.androidaps.extensions.toTableRowHeader
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
@ -38,10 +40,19 @@ class TddCalculator @Inject constructor(
) { ) {
fun calculate(days: Long): LongSparseArray<TotalDailyDose> { fun calculate(days: Long): LongSparseArray<TotalDailyDose> {
val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs()) var startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs())
val endTime = MidnightTime.calc(dateUtil.now()) val endTime = MidnightTime.calc(dateUtil.now())
val result = LongSparseArray<TotalDailyDose>() val result = LongSparseArray<TotalDailyDose>()
// Try to load cached values
while (startTime < endTime) {
val tdd = repository.getCalculatedTotalDailyDose(startTime).blockingGet()
if (tdd is ValueWrapper.Existing) result.put(startTime, tdd.value)
else break
startTime += T.hours(24).msecs()
}
if (endTime > startTime) {
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }
.forEach { t -> .forEach { t ->
@ -75,11 +86,16 @@ class TddCalculator @Inject constructor(
} }
result.put(midnight, tdd) result.put(midnight, tdd)
} }
}
for (i in 0 until result.size()) { for (i in 0 until result.size()) {
val tdd = result.valueAt(i) val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
if (tdd.interfaceIDs.pumpType != InterfaceIDs.PumpType.CACHE) {
tdd.interfaceIDs.pumpType = InterfaceIDs.PumpType.CACHE
aapsLogger.debug(LTag.CORE, "Storing TDD $tdd")
repository.createTotalDailyDose(tdd)
}
} }
aapsLogger.debug(LTag.CORE, result.toString())
return result return result
} }
@ -91,22 +107,13 @@ class TddCalculator @Inject constructor(
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }
.forEach { t -> .forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
} }
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount tdd.carbs += t.amount
//result.put(midnight, tdd)
} }
val calculationStep = T.mins(5).msecs() val calculationStep = T.mins(5).msecs()
for (t in startTime until endTime step calculationStep) { for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
@ -118,13 +125,8 @@ class TddCalculator @Inject constructor(
val absoluteEbRate = eb?.rate ?: 0.0 val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
} }
//result.put(midnight, tdd)
} }
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString()) aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd return tdd
} }
@ -133,27 +135,16 @@ class TddCalculator @Inject constructor(
val startTime = dateUtil.now() - T.hours(hour = 24).msecs() val startTime = dateUtil.now() - T.hours(hour = 24).msecs()
val endTime = dateUtil.now() val endTime = dateUtil.now()
val tdd = TotalDailyDose(timestamp = startTime) val tdd = TotalDailyDose(timestamp = startTime)
//val result = TotalDailyDose()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }
.forEach { t -> .forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
} }
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount tdd.carbs += t.amount
//result.put(midnight, tdd)
} }
val calculationStep = T.mins(5).msecs() val calculationStep = T.mins(5).msecs()
//val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
for (t in startTime until endTime step calculationStep) { for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
@ -165,13 +156,8 @@ class TddCalculator @Inject constructor(
val absoluteEbRate = eb?.rate ?: 0.0 val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
} }
//result.put(midnight, tdd)
} }
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString()) aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd return tdd
} }

View file

@ -11,7 +11,8 @@ import kotlin.math.min
@Suppress("unused") @Suppress("unused")
enum class PumpType { enum class PumpType {
GENERIC_AAPS(description = "Generic AAPS", GENERIC_AAPS(
description = "Generic AAPS",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
model = "VirtualPump", model = "VirtualPump",
bolusSize = 0.1, bolusSize = 0.1,
@ -23,9 +24,11 @@ enum class PumpType {
baseBasalMinValue = 0.01, baseBasalMinValue = 0.01,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
CELLNOVO(description = "Cellnovo", CELLNOVO(
description = "Cellnovo",
manufacturer = ManufacturerType.Cellnovo, manufacturer = ManufacturerType.Cellnovo,
model = "Cellnovo", model = "Cellnovo",
bolusSize = 0.05, bolusSize = 0.05,
@ -37,9 +40,11 @@ enum class PumpType {
baseBasalMinValue = 0.05, baseBasalMinValue = 0.05,
baseBasalStep = 0.05, baseBasalStep = 0.05,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
ACCU_CHEK_COMBO(description = "Accu-Chek Combo", ACCU_CHEK_COMBO(
description = "Accu-Chek Combo",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Combo", model = "Combo",
bolusSize = 0.1, bolusSize = 0.1,
@ -53,8 +58,10 @@ enum class PumpType {
baseBasalSpecialSteps = DoseStepSize.ComboBasal, baseBasalSpecialSteps = DoseStepSize.ComboBasal,
pumpCapability = PumpCapability.ComboCapabilities, pumpCapability = PumpCapability.ComboCapabilities,
source = Sources.Combo, source = Sources.Combo,
supportBatteryLevel = false), supportBatteryLevel = false
ACCU_CHEK_SPIRIT(description = "Accu-Chek Spirit", ),
ACCU_CHEK_SPIRIT(
description = "Accu-Chek Spirit",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Spirit", model = "Spirit",
bolusSize = 0.1, bolusSize = 0.1,
@ -66,8 +73,10 @@ enum class PumpType {
baseBasalMinValue = 0.01, baseBasalMinValue = 0.01,
baseBasalStep = 0.1, baseBasalStep = 0.1,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
ACCU_CHEK_INSIGHT_VIRTUAL(description = "Accu-Chek Insight", ),
ACCU_CHEK_INSIGHT_VIRTUAL(
description = "Accu-Chek Insight",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Insight", model = "Insight",
bolusSize = 0.05, bolusSize = 0.05,
@ -79,8 +88,10 @@ enum class PumpType {
baseBasalMinValue = 0.02, baseBasalMinValue = 0.02,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.InsightCapabilities), pumpCapability = PumpCapability.InsightCapabilities
ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight", ),
ACCU_CHEK_INSIGHT(
description = "Accu-Chek Insight",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Insight", model = "Insight",
bolusSize = 0.01, bolusSize = 0.01,
@ -94,8 +105,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.InsightBasal, baseBasalSpecialSteps = DoseStepSize.InsightBasal,
pumpCapability = PumpCapability.InsightCapabilities, pumpCapability = PumpCapability.InsightCapabilities,
source = Sources.Insight), source = Sources.Insight
ACCU_CHEK_SOLO(description = "Accu-Chek Solo", ),
ACCU_CHEK_SOLO(
description = "Accu-Chek Solo",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Solo", model = "Solo",
bolusSize = 0.01, bolusSize = 0.01,
@ -108,9 +121,11 @@ enum class PumpType {
baseBasalMaxValue = null, baseBasalMaxValue = null,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.InsightBolus, baseBasalSpecialSteps = DoseStepSize.InsightBolus,
pumpCapability = PumpCapability.InsightCapabilities), pumpCapability = PumpCapability.InsightCapabilities
),
ANIMAS_VIBE(description = "Animas Vibe", ANIMAS_VIBE(
description = "Animas Vibe",
manufacturer = ManufacturerType.Animas, manufacturer = ManufacturerType.Animas,
model = "Vibe", model = "Vibe",
bolusSize = 0.05, bolusSize = 0.05,
@ -123,9 +138,11 @@ enum class PumpType {
baseBasalMaxValue = 5.0, baseBasalMaxValue = 5.0,
baseBasalStep = 0.0, baseBasalStep = 0.0,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE), ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE),
DANA_R(description = "DanaR", DANA_R(
description = "DanaR",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaR", model = "DanaR",
bolusSize = 0.05, bolusSize = 0.05,
@ -138,8 +155,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaCapabilities, pumpCapability = PumpCapability.DanaCapabilities,
source = Sources.DanaR), source = Sources.DanaR
DANA_R_KOREAN(description = "DanaR Korean", ),
DANA_R_KOREAN(
description = "DanaR Korean",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaRKorean", model = "DanaRKorean",
bolusSize = 0.05, bolusSize = 0.05,
@ -152,8 +171,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaCapabilities, pumpCapability = PumpCapability.DanaCapabilities,
source = Sources.DanaRC), source = Sources.DanaRC
DANA_RS(description = "DanaRS", ),
DANA_RS(
description = "DanaRS",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaRS", model = "DanaRS",
bolusSize = 0.05, bolusSize = 0.05,
@ -166,11 +187,13 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaWithHistoryCapabilities, pumpCapability = PumpCapability.DanaWithHistoryCapabilities,
source = Sources.DanaRS), source = Sources.DanaRS
),
DANA_RS_KOREAN(description = "DanaRSKorean", model = "DanaRSKorean", parent = DANA_RS), DANA_RS_KOREAN(description = "DanaRSKorean", model = "DanaRSKorean", parent = DANA_RS),
DANA_I(description = "DanaI", model = "DanaI", parent = DANA_RS, source = Sources.DanaI), DANA_I(description = "DanaI", model = "DanaI", parent = DANA_RS, source = Sources.DanaI),
DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS, source = Sources.DanaRv2), DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS, source = Sources.DanaRv2),
OMNIPOD_EROS(description = "Omnipod Eros", OMNIPOD_EROS(
description = "Omnipod Eros",
manufacturer = ManufacturerType.Insulet, manufacturer = ManufacturerType.Insulet,
model = "Eros", model = "Eros",
bolusSize = 0.05, bolusSize = 0.05,
@ -188,8 +211,10 @@ enum class PumpType {
isPatchPump = true, isPatchPump = true,
useHardwareLink = true, useHardwareLink = true,
supportBatteryLevel = false, supportBatteryLevel = false,
source = Sources.OmnipodEros), source = Sources.OmnipodEros
OMNIPOD_DASH(description = "Omnipod Dash", ),
OMNIPOD_DASH(
description = "Omnipod Dash",
manufacturer = ManufacturerType.Insulet, manufacturer = ManufacturerType.Insulet,
model = "Dash", model = "Dash",
bolusSize = 0.05, bolusSize = 0.05,
@ -205,8 +230,10 @@ enum class PumpType {
isPatchPump = true, isPatchPump = true,
pumpCapability = PumpCapability.OmnipodCapabilities, pumpCapability = PumpCapability.OmnipodCapabilities,
hasCustomUnreachableAlertCheck = false, hasCustomUnreachableAlertCheck = false,
supportBatteryLevel = false), supportBatteryLevel = false
MEDTRONIC_512_712(description = "Medtronic 512/712", ),
MEDTRONIC_512_712(
description = "Medtronic 512/712",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "512/712", model = "512/712",
bolusSize = 0.1, bolusSize = 0.1,
@ -219,14 +246,20 @@ enum class PumpType {
baseBasalStep = 0.05, baseBasalStep = 0.05,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.MedtronicCapabilities, pumpCapability = PumpCapability.MedtronicCapabilities,
source = Sources.Medtronic), source = Sources.Medtronic
MEDTRONIC_515_715(description = "Medtronic 515/715", ),
MEDTRONIC_515_715(
description = "Medtronic 515/715",
model = "515/715", model = "515/715",
parent = MEDTRONIC_512_712), parent = MEDTRONIC_512_712
MEDTRONIC_522_722(description = "Medtronic 522/722", ),
MEDTRONIC_522_722(
description = "Medtronic 522/722",
model = "522/722", model = "522/722",
parent = MEDTRONIC_512_712), parent = MEDTRONIC_512_712
MEDTRONIC_523_723_REVEL(description = "Medtronic 523/723 (Revel)", ),
MEDTRONIC_523_723_REVEL(
description = "Medtronic 523/723 (Revel)",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "523/723 (Revel)", model = "523/723 (Revel)",
bolusSize = 0.05, bolusSize = 0.05,
@ -239,9 +272,11 @@ enum class PumpType {
baseBasalStep = 0.025, baseBasalStep = 0.025,
baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal,
pumpCapability = PumpCapability.MedtronicCapabilities, pumpCapability = PumpCapability.MedtronicCapabilities,
source = Sources.Medtronic), source = Sources.Medtronic
),
MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL), MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL),
MEDTRONIC_640G(description = "Medtronic 640G", MEDTRONIC_640G(
description = "Medtronic 640G",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "640G", model = "640G",
bolusSize = 0.025, bolusSize = 0.025,
@ -253,9 +288,11 @@ enum class PumpType {
baseBasalMinValue = 0.025, baseBasalMinValue = 0.025,
baseBasalStep = 0.025, baseBasalStep = 0.025,
baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
TANDEM_T_SLIM(description = "Tandem t:slim", TANDEM_T_SLIM(
description = "Tandem t:slim",
manufacturer = ManufacturerType.Tandem, manufacturer = ManufacturerType.Tandem,
model = "t:slim", model = "t:slim",
bolusSize = 0.01, bolusSize = 0.01,
@ -267,12 +304,14 @@ enum class PumpType {
baseBasalMinValue = 0.1, baseBasalMinValue = 0.1,
baseBasalStep = 0.001, baseBasalStep = 0.001,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM), TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM),
TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM),
TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM),
YPSOPUMP(description = "YpsoPump", YPSOPUMP(
description = "YpsoPump",
manufacturer = ManufacturerType.Ypsomed, manufacturer = ManufacturerType.Ypsomed,
model = "Ypsopump", model = "Ypsopump",
bolusSize = 0.1, bolusSize = 0.1,
@ -285,26 +324,39 @@ enum class PumpType {
baseBasalMaxValue = 40.0, baseBasalMaxValue = 40.0,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal, baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal,
pumpCapability = PumpCapability.YpsomedCapabilities), pumpCapability = PumpCapability.YpsomedCapabilities
MDI(description = "MDI", ),
MDI(
description = "MDI",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
bolusSize = 0.5, bolusSize = 0.5,
model = "MDI", model = "MDI",
tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0),
extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1),
pumpCapability = PumpCapability.MDI), pumpCapability = PumpCapability.MDI
),
// Not real pump. Used for User as a source // Not real pump. Used for User as a source
USER(description = "USER", USER(
description = "USER",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
model = "USER", model = "USER",
tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0),
extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1),
pumpCapability = PumpCapability.MDI, pumpCapability = PumpCapability.MDI,
source = Sources.MDI), source = Sources.MDI
),
// Not real, cached value
CACHE(
description = "CACHE",
model = "CACHE",
parent = USER
),
//Diaconn Pump //Diaconn Pump
DIACONN_G8(description = "Diaconn G8", DIACONN_G8(
description = "Diaconn G8",
manufacturer = ManufacturerType.G2e, manufacturer = ManufacturerType.G2e,
model = "DiaconnG8", model = "DiaconnG8",
bolusSize = 0.01, bolusSize = 0.01,
@ -319,7 +371,8 @@ enum class PumpType {
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DiaconnCapabilities, pumpCapability = PumpCapability.DiaconnCapabilities,
source = Sources.DiaconnG8, source = Sources.DiaconnG8,
useHardwareLink = true); useHardwareLink = true
);
val description: String val description: String
var manufacturer: ManufacturerType? = null var manufacturer: ManufacturerType? = null
@ -407,6 +460,7 @@ enum class PumpType {
InterfaceIDs.PumpType.MDI -> MDI InterfaceIDs.PumpType.MDI -> MDI
InterfaceIDs.PumpType.USER -> USER InterfaceIDs.PumpType.USER -> USER
InterfaceIDs.PumpType.DIACONN_G8 -> DIACONN_G8 InterfaceIDs.PumpType.DIACONN_G8 -> DIACONN_G8
InterfaceIDs.PumpType.CACHE -> TODO()
} }
} }
@ -418,7 +472,8 @@ enum class PumpType {
parent.model = model parent.model = model
} }
constructor(description: String, constructor(
description: String,
manufacturer: ManufacturerType, manufacturer: ManufacturerType,
model: String, model: String,
bolusSize: Double = 0.0, bolusSize: Double = 0.0,
@ -436,7 +491,8 @@ enum class PumpType {
isPatchPump: Boolean = false, isPatchPump: Boolean = false,
supportBatteryLevel: Boolean = true, supportBatteryLevel: Boolean = true,
useHardwareLink: Boolean = false, useHardwareLink: Boolean = false,
source: Sources = Sources.VirtualPump) { source: Sources = Sources.VirtualPump
) {
this.description = description this.description = description
this.manufacturer = manufacturer this.manufacturer = manufacturer
this.model = model this.model = model
@ -463,12 +519,14 @@ enum class PumpType {
val eb = extendedBolusSettings ?: return "INVALID" val eb = extendedBolusSettings ?: return "INVALID"
val tbr = tbrSettings ?: return "INVALID" val tbr = tbrSettings ?: return "INVALID"
val extendedNote = if (hasExtendedBasals) rh.gs(R.string.def_extended_note) else "" val extendedNote = if (hasExtendedBasals) rh.gs(R.string.def_extended_note) else ""
return String.format(i18nTemplate, return String.format(
i18nTemplate,
getStep("" + bolusSize, specialBolusSize), getStep("" + bolusSize, specialBolusSize),
eb.step, eb.durationStep, eb.maxDuration / 60, eb.step, eb.durationStep, eb.maxDuration / 60,
getStep(baseBasalRange(), baseBasalSpecialSteps), getStep(baseBasalRange(), baseBasalSpecialSteps),
tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit, tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit,
tbr.durationStep, tbr.maxDuration / 60, extendedNote) tbr.durationStep, tbr.maxDuration / 60, extendedNote
)
} }
private fun baseBasalRange(): String = private fun baseBasalRange(): String =
@ -494,8 +552,10 @@ enum class PumpType {
fun determineCorrectBasalSize(basalAmount: Double): Double { fun determineCorrectBasalSize(basalAmount: Double): Double {
val tSettings = tbrSettings ?: throw IllegalStateException() val tSettings = tbrSettings ?: throw IllegalStateException()
return Round.roundTo(min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount) return Round.roundTo(
?: baseBasalStep) min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount)
?: baseBasalStep
)
} }
fun toDbPumpType(): InterfaceIDs.PumpType = fun toDbPumpType(): InterfaceIDs.PumpType =
@ -531,5 +591,6 @@ enum class PumpType {
MDI -> InterfaceIDs.PumpType.MDI MDI -> InterfaceIDs.PumpType.MDI
USER -> InterfaceIDs.PumpType.USER USER -> InterfaceIDs.PumpType.USER
DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8 DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
CACHE -> InterfaceIDs.PumpType.CACHE
} }
} }

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.database
import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.database.data.NewEntries import info.nightscout.androidaps.database.data.NewEntries
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.entities.*
import info.nightscout.androidaps.database.interfaces.DBEntry import info.nightscout.androidaps.database.interfaces.DBEntry
import info.nightscout.androidaps.database.transactions.Transaction import info.nightscout.androidaps.database.transactions.Transaction
@ -59,6 +60,10 @@ import kotlin.math.roundToInt
fun clearDatabases() = database.clearAllTables() fun clearDatabases() = database.clearAllTables()
fun clearCachedData(from: Long) {
database.totalDailyDoseDao.deleteNewerThan(from, InterfaceIDs.PumpType.CACHE)
}
//BG READINGS -- only valid records //BG READINGS -- only valid records
fun compatGetBgReadingsDataFromTime(timestamp: Long, ascending: Boolean): Single<List<GlucoseValue>> = fun compatGetBgReadingsDataFromTime(timestamp: Long, ascending: Boolean): Single<List<GlucoseValue>> =
database.glucoseValueDao.compatGetBgReadingsDataFromTime(timestamp) database.glucoseValueDao.compatGetBgReadingsDataFromTime(timestamp)
@ -775,22 +780,26 @@ import kotlin.math.roundToInt
fun getOldestExtendedBolusRecord(): ExtendedBolus? = fun getOldestExtendedBolusRecord(): ExtendedBolus? =
database.extendedBolusDao.getOldestRecord() database.extendedBolusDao.getOldestRecord()
// TotalDailyDose fun getLastExtendedBolusIdWrapped(): Single<ValueWrapper<Long>> =
fun getAllTotalDailyDoses(ascending: Boolean): Single<List<TotalDailyDose>> = database.extendedBolusDao.getLastId()
database.totalDailyDoseDao.getAllTotalDailyDoses()
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.toWrappedSingle()
// TotalDailyDose
fun getLastTotalDailyDoses(count: Int, ascending: Boolean): Single<List<TotalDailyDose>> = fun getLastTotalDailyDoses(count: Int, ascending: Boolean): Single<List<TotalDailyDose>> =
database.totalDailyDoseDao.getLastTotalDailyDoses(count) database.totalDailyDoseDao.getLastTotalDailyDoses(count)
.map { if (!ascending) it.reversed() else it } .map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
fun getLastExtendedBolusIdWrapped(): Single<ValueWrapper<Long>> = fun getCalculatedTotalDailyDose(timestamp: Long): Single<ValueWrapper<TotalDailyDose>> =
database.extendedBolusDao.getLastId() database.totalDailyDoseDao.findByTimestamp(timestamp, InterfaceIDs.PumpType.CACHE)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.toWrappedSingle() .toWrappedSingle()
fun createTotalDailyDose(tdd: TotalDailyDose) {
database.totalDailyDoseDao.insert(tdd)
}
// OFFLINE EVENT // OFFLINE EVENT
/* /*
* returns a Pair of the next entity to sync and the ID of the "update". * returns a Pair of the next entity to sync and the ID of the "update".

View file

@ -2,11 +2,10 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS
import info.nightscout.androidaps.database.TABLE_TOTAL_DAILY_DOSES import info.nightscout.androidaps.database.TABLE_TOTAL_DAILY_DOSES
import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TotalDailyDose import info.nightscout.androidaps.database.entities.TotalDailyDose
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName") @Suppress("FunctionName")
@ -25,13 +24,16 @@ internal interface TotalDailyDoseDao : TraceableDao<TotalDailyDose> {
@Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp = :timestamp AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL") @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp = :timestamp AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL")
fun findByPumpTimestamp(timestamp: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): TotalDailyDose? fun findByPumpTimestamp(timestamp: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): TotalDailyDose?
@Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL ORDER BY timestamp ASC") @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp = :timestamp AND pumpType = :pumpType AND referenceId IS NULL")
fun getAllTotalDailyDoses(): Single<List<TotalDailyDose>> fun findByTimestamp(timestamp: Long, pumpType: InterfaceIDs.PumpType): Maybe<TotalDailyDose>
@Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL ORDER BY timestamp DESC LIMIT :count") @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL AND pumpType <> :exclude ORDER BY timestamp DESC LIMIT :count")
fun getLastTotalDailyDoses(count: Int): Single<List<TotalDailyDose>> fun getLastTotalDailyDoses(count: Int, exclude: InterfaceIDs.PumpType = InterfaceIDs.PumpType.CACHE): Single<List<TotalDailyDose>>
@Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset") @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset")
suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<TotalDailyDose> suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<TotalDailyDose>
@Query("DELETE FROM $TABLE_TOTAL_DAILY_DOSES WHERE dateCreated >= :since AND pumpType = :pumpType")
fun deleteNewerThan(since: Long, pumpType: InterfaceIDs.PumpType)
} }

View file

@ -42,7 +42,8 @@ data class InterfaceIDs(
YPSOPUMP, YPSOPUMP,
MDI, MDI,
DIACONN_G8, DIACONN_G8,
USER; USER,
CACHE;
companion object { companion object {