IobCobCalculator refactor
This commit is contained in:
parent
c637b7072c
commit
36040b7ed2
38 changed files with 1030 additions and 1022 deletions
|
@ -2,6 +2,22 @@
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<option name="AUTODETECT_INDENTS" value="false" />
|
<option name="AUTODETECT_INDENTS" value="false" />
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
|
<value>
|
||||||
|
<package name="java.util" alias="false" withSubpackages="false" />
|
||||||
|
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||||
|
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||||
|
<value>
|
||||||
|
<package name="" alias="false" withSubpackages="true" />
|
||||||
|
<package name="java" alias="false" withSubpackages="true" />
|
||||||
|
<package name="javax" alias="false" withSubpackages="true" />
|
||||||
|
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||||
|
<package name="" alias="true" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
|
||||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
|
||||||
|
|
|
@ -144,7 +144,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
||||||
validateInputs()
|
validateInputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
iobCobCalculator.actualBg()?.let { bgReading ->
|
iobCobCalculator.ads.actualBg()?.let { bgReading ->
|
||||||
if (bgReading.value < 72)
|
if (bgReading.value < 72)
|
||||||
binding.hypoTt.isChecked = true
|
binding.hypoTt.isChecked = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@ class WizardDialog : DaggerDialogFragment() {
|
||||||
binding.bgInput.setStep(0.1)
|
binding.bgInput.setStep(0.1)
|
||||||
|
|
||||||
// Set BG if not old
|
// Set BG if not old
|
||||||
binding.bgInput.value = iobCobCalculator.actualBg()?.valueToUnits(units) ?: 0.0
|
binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0
|
||||||
binding.ttcheckbox.isEnabled = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
binding.ttcheckbox.isEnabled = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
||||||
|
|
||||||
// IOB calculation
|
// IOB calculation
|
||||||
|
|
|
@ -124,7 +124,7 @@ open class LoopPlugin @Inject constructor(
|
||||||
.subscribe({ event: EventAutosensCalculationFinished ->
|
.subscribe({ event: EventAutosensCalculationFinished ->
|
||||||
// Autosens calculation not triggered by a new BG
|
// Autosens calculation not triggered by a new BG
|
||||||
if (event.cause !is EventNewBG) return@subscribe
|
if (event.cause !is EventNewBG) return@subscribe
|
||||||
val glucoseValue = iobCobCalculator.actualBg() ?: return@subscribe
|
val glucoseValue = iobCobCalculator.ads.actualBg() ?: return@subscribe
|
||||||
// BG outdated
|
// BG outdated
|
||||||
// already looped with that value
|
// already looped with that value
|
||||||
if (glucoseValue.timestamp <= lastBgTriggeredRun) return@subscribe
|
if (glucoseValue.timestamp <= lastBgTriggeredRun) return@subscribe
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R
|
||||||
})
|
})
|
||||||
tasks.add(object : Task(this, R.string.hasbgdata) {
|
tasks.add(object : Task(this, R.string.hasbgdata) {
|
||||||
override fun isCompleted(): Boolean {
|
override fun isCompleted(): Boolean {
|
||||||
return iobCobCalculator.lastBg() != null
|
return iobCobCalculator.ads.lastBg() != null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
tasks.add(object : Task(this, R.string.loopenabled) {
|
tasks.add(object : Task(this, R.string.loopenabled) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ class DataBroadcastPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bgStatus(bundle: Bundle) {
|
private fun bgStatus(bundle: Bundle) {
|
||||||
val lastBG = iobCobCalculator.lastBg() ?: return
|
val lastBG = iobCobCalculator.ads.lastBg() ?: return
|
||||||
val glucoseStatus = glucoseStatusProvider.glucoseStatusData ?: return
|
val glucoseStatus = glucoseStatusProvider.glucoseStatusData ?: return
|
||||||
|
|
||||||
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
|
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
|
||||||
|
|
|
@ -411,7 +411,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onClickQuickWizard() {
|
private fun onClickQuickWizard() {
|
||||||
val actualBg = iobCobCalculator.actualBg()
|
val actualBg = iobCobCalculator.ads.actualBg()
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
val profileName = profileFunction.getProfileName()
|
val profileName = profileFunction.getProfileName()
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
|
@ -446,11 +446,11 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun processButtonsVisibility() {
|
private fun processButtonsVisibility() {
|
||||||
val lastBG = iobCobCalculator.lastBg()
|
val lastBG = iobCobCalculator.ads.lastBg()
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
val profileName = profileFunction.getProfileName()
|
val profileName = profileFunction.getProfileName()
|
||||||
val actualBG = iobCobCalculator.actualBg()
|
val actualBG = iobCobCalculator.ads.actualBg()
|
||||||
|
|
||||||
// QuickWizard button
|
// QuickWizard button
|
||||||
val quickWizardEntry = quickWizard.getActive()
|
val quickWizardEntry = quickWizard.getActive()
|
||||||
|
@ -562,8 +562,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
binding.loopPumpStatusLayout.loopLayout.visibility = View.VISIBLE
|
binding.loopPumpStatusLayout.loopLayout.visibility = View.VISIBLE
|
||||||
|
|
||||||
val profile = profileFunction.getProfile() ?: return
|
val profile = profileFunction.getProfile() ?: return
|
||||||
val actualBG = iobCobCalculator.actualBg()
|
val actualBG = iobCobCalculator.ads.actualBg()
|
||||||
val lastBG = iobCobCalculator.lastBg()
|
val lastBG = iobCobCalculator.ads.lastBg()
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
val lowLine = defaultValueHelper.determineLowLine()
|
val lowLine = defaultValueHelper.determineLowLine()
|
||||||
|
@ -812,7 +812,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.infoLayout.sensitivity.text =
|
binding.infoLayout.sensitivity.text =
|
||||||
iobCobCalculator.getLastAutosensData("Overview")?.let { autosensData ->
|
iobCobCalculator.ads.getLastAutosensData("Overview", aapsLogger, dateUtil)?.let { autosensData ->
|
||||||
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
||||||
} ?: ""
|
} ?: ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ class GraphData(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addBucketedData(fromTime: Long, toTime: Long) {
|
fun addBucketedData(fromTime: Long, toTime: Long) {
|
||||||
val bucketedData = iobCobCalculator.getBucketedDataTableCopy() ?: return
|
val bucketedData = iobCobCalculator.ads.getBucketedDataTableCopy() ?: return
|
||||||
if (bucketedData.isEmpty()) {
|
if (bucketedData.isEmpty()) {
|
||||||
aapsLogger.debug("No bucketed data.")
|
aapsLogger.debug("No bucketed data.")
|
||||||
return
|
return
|
||||||
|
@ -77,7 +77,7 @@ class GraphData(
|
||||||
|
|
||||||
fun addBgReadings(fromTime: Long, toTime: Long, highLine: Double, predictions: MutableList<GlucoseValueDataPoint>?) {
|
fun addBgReadings(fromTime: Long, toTime: Long, highLine: Double, predictions: MutableList<GlucoseValueDataPoint>?) {
|
||||||
var maxBgValue = Double.MIN_VALUE
|
var maxBgValue = Double.MIN_VALUE
|
||||||
bgReadingsArray = repository.compatGetBgReadingsDataFromTime(fromTime, toTime, true).blockingGet()
|
bgReadingsArray = repository.compatGetBgReadingsDataFromTime(fromTime, toTime, false).blockingGet()
|
||||||
if (bgReadingsArray?.isEmpty() != false) {
|
if (bgReadingsArray?.isEmpty() != false) {
|
||||||
aapsLogger.debug("No BG data.")
|
aapsLogger.debug("No BG data.")
|
||||||
maxY = if (units == Constants.MGDL) 180.0 else 10.0
|
maxY = if (units == Constants.MGDL) 180.0 else 10.0
|
||||||
|
@ -302,8 +302,7 @@ class GraphData(
|
||||||
|
|
||||||
private fun getNearestBg(date: Long): Double {
|
private fun getNearestBg(date: Long): Double {
|
||||||
bgReadingsArray?.let { bgReadingsArray ->
|
bgReadingsArray?.let { bgReadingsArray ->
|
||||||
for (r in bgReadingsArray.indices) {
|
for (reading in bgReadingsArray) {
|
||||||
val reading = bgReadingsArray[r]
|
|
||||||
if (reading.timestamp > date) continue
|
if (reading.timestamp > date) continue
|
||||||
return Profile.fromMgdlToUnits(reading.value, units)
|
return Profile.fromMgdlToUnits(reading.value, units)
|
||||||
}
|
}
|
||||||
|
@ -325,7 +324,7 @@ class GraphData(
|
||||||
time += 5 * 60 * 1000L
|
time += 5 * 60 * 1000L
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
total = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(time, profile)
|
total = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
||||||
val act: Double = total.activity
|
val act: Double = total.activity
|
||||||
if (time <= now) actArrayHist.add(ScaledDataPoint(time, act, actScale)) else actArrayPrediction.add(ScaledDataPoint(time, act, actScale))
|
if (time <= now) actArrayHist.add(ScaledDataPoint(time, act, actScale)) else actArrayPrediction.add(ScaledDataPoint(time, act, actScale))
|
||||||
maxIAValue = max(maxIAValue, abs(act))
|
maxIAValue = max(maxIAValue, abs(act))
|
||||||
|
@ -366,10 +365,10 @@ class GraphData(
|
||||||
time += 5 * 60 * 1000L
|
time += 5 * 60 * 1000L
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val deviation = if (devBgiScale) iobCobCalculator.getAutosensData(time)?.deviation
|
val deviation = if (devBgiScale) iobCobCalculator.ads.getAutosensDataAtTime(time)?.deviation
|
||||||
?: 0.0 else 0.0
|
?: 0.0 else 0.0
|
||||||
|
|
||||||
total = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(time, profile)
|
total = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
||||||
val bgi: Double = total.activity * profile.getIsfMgdl(time) * 5.0
|
val bgi: Double = total.activity * profile.getIsfMgdl(time) * 5.0
|
||||||
if (time <= now) bgiArrayHist.add(ScaledDataPoint(time, bgi, bgiScale)) else bgiArrayPrediction.add(ScaledDataPoint(time, bgi, bgiScale))
|
if (time <= now) bgiArrayHist.add(ScaledDataPoint(time, bgi, bgiScale)) else bgiArrayPrediction.add(ScaledDataPoint(time, bgi, bgiScale))
|
||||||
maxBGIValue = max(maxBGIValue, max(abs(bgi), deviation))
|
maxBGIValue = max(maxBGIValue, max(abs(bgi), deviation))
|
||||||
|
@ -408,8 +407,8 @@ class GraphData(
|
||||||
var iob = 0.0
|
var iob = 0.0
|
||||||
var absIob = 0.0
|
var absIob = 0.0
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
iob = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(time, profile).iob
|
iob = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile).iob
|
||||||
if (absScale) absIob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTempsSynchronized(time).iob
|
if (absScale) absIob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
|
||||||
}
|
}
|
||||||
if (abs(lastIob - iob) > 0.02) {
|
if (abs(lastIob - iob) > 0.02) {
|
||||||
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
||||||
|
@ -465,7 +464,7 @@ class GraphData(
|
||||||
while (time <= toTime) {
|
while (time <= toTime) {
|
||||||
val profile = profileFunction.getProfile(time)
|
val profile = profileFunction.getProfile(time)
|
||||||
var iob = 0.0
|
var iob = 0.0
|
||||||
if (profile != null) iob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTempsSynchronized(time).iob
|
if (profile != null) iob = iobCobCalculator.calculateAbsInsulinFromTreatmentsAndTemps(time).iob
|
||||||
if (abs(lastIob - iob) > 0.02) {
|
if (abs(lastIob - iob) > 0.02) {
|
||||||
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
if (abs(lastIob - iob) > 0.2) iobArray.add(ScaledDataPoint(time, lastIob, iobScale))
|
||||||
iobArray.add(ScaledDataPoint(time, iob, iobScale))
|
iobArray.add(ScaledDataPoint(time, iob, iobScale))
|
||||||
|
@ -497,7 +496,7 @@ class GraphData(
|
||||||
val cobScale = Scale()
|
val cobScale = Scale()
|
||||||
var time = fromTime
|
var time = fromTime
|
||||||
while (time <= toTime) {
|
while (time <= toTime) {
|
||||||
iobCobCalculator.getAutosensData(time)?.let { autosensData ->
|
iobCobCalculator.ads.getAutosensDataAtTime(time)?.let { autosensData ->
|
||||||
val cob = autosensData.cob.toInt()
|
val cob = autosensData.cob.toInt()
|
||||||
if (cob != lastCob) {
|
if (cob != lastCob) {
|
||||||
if (autosensData.carbsFromBolus > 0) cobArray.add(ScaledDataPoint(time, lastCob.toDouble(), cobScale))
|
if (autosensData.carbsFromBolus > 0) cobArray.add(ScaledDataPoint(time, lastCob.toDouble(), cobScale))
|
||||||
|
@ -543,11 +542,11 @@ class GraphData(
|
||||||
// if align Dev Scale with BGI scale, then calculate BGI value, else bgi = 0.0
|
// if align Dev Scale with BGI scale, then calculate BGI value, else bgi = 0.0
|
||||||
val bgi: Double = if (devBgiScale) {
|
val bgi: Double = if (devBgiScale) {
|
||||||
val profile = profileFunction.getProfile(time) ?: continue
|
val profile = profileFunction.getProfile(time) ?: continue
|
||||||
total = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(time, profile)
|
total = iobCobCalculator.calculateFromTreatmentsAndTemps(time, profile)
|
||||||
total.activity * profile.getIsfMgdl(time) * 5.0
|
total.activity * profile.getIsfMgdl(time) * 5.0
|
||||||
} else 0.0
|
} else 0.0
|
||||||
|
|
||||||
iobCobCalculator.getAutosensData(time)?.let { autosensData ->
|
iobCobCalculator.ads.getAutosensDataAtTime(time)?.let { autosensData ->
|
||||||
var color = resourceHelper.gc(R.color.deviationblack) // "="
|
var color = resourceHelper.gc(R.color.deviationblack) // "="
|
||||||
if (autosensData.type == "" || autosensData.type == "non-meal") {
|
if (autosensData.type == "" || autosensData.type == "non-meal") {
|
||||||
if (autosensData.pastSensitivity == "C") color = resourceHelper.gc(R.color.deviationgrey)
|
if (autosensData.pastSensitivity == "C") color = resourceHelper.gc(R.color.deviationgrey)
|
||||||
|
@ -583,7 +582,7 @@ class GraphData(
|
||||||
val ratioScale = Scale()
|
val ratioScale = Scale()
|
||||||
var time = fromTime
|
var time = fromTime
|
||||||
while (time <= toTime) {
|
while (time <= toTime) {
|
||||||
iobCobCalculator.getAutosensData(time)?.let { autosensData ->
|
iobCobCalculator.ads.getAutosensDataAtTime(time)?.let { autosensData ->
|
||||||
ratioArray.add(ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale))
|
ratioArray.add(ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale))
|
||||||
maxRatioValueFound = max(maxRatioValueFound, autosensData.autosensResult.ratio - 1)
|
maxRatioValueFound = max(maxRatioValueFound, autosensData.autosensResult.ratio - 1)
|
||||||
minRatioValueFound = min(minRatioValueFound, autosensData.autosensResult.ratio - 1)
|
minRatioValueFound = min(minRatioValueFound, autosensData.autosensResult.ratio - 1)
|
||||||
|
@ -613,7 +612,7 @@ class GraphData(
|
||||||
val dsMinScale = Scale()
|
val dsMinScale = Scale()
|
||||||
var time = fromTime
|
var time = fromTime
|
||||||
while (time <= toTime) {
|
while (time <= toTime) {
|
||||||
iobCobCalculator.getAutosensData(time)?.let { autosensData ->
|
iobCobCalculator.ads.getAutosensDataAtTime(time)?.let { autosensData ->
|
||||||
dsMaxArray.add(ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale))
|
dsMaxArray.add(ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale))
|
||||||
dsMinArray.add(ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale))
|
dsMinArray.add(ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale))
|
||||||
maxFromMaxValueFound = max(maxFromMaxValueFound, abs(autosensData.slopeFromMaxDeviation))
|
maxFromMaxValueFound = max(maxFromMaxValueFound, abs(autosensData.slopeFromMaxDeviation))
|
||||||
|
|
|
@ -130,7 +130,7 @@ class PersistentNotificationPlugin @Inject constructor(
|
||||||
if (profileFunction.isProfileValid("Notification")) {
|
if (profileFunction.isProfileValid("Notification")) {
|
||||||
var line1aa: String
|
var line1aa: String
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
val lastBG = iobCobCalculator.lastBg()
|
val lastBG = iobCobCalculator.ads.lastBg()
|
||||||
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
|
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
|
||||||
if (lastBG != null) {
|
if (lastBG != null) {
|
||||||
line1aa = lastBG.valueToUnitsString(units)
|
line1aa = lastBG.valueToUnitsString(units)
|
||||||
|
|
|
@ -310,8 +310,8 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processBG(receivedSms: Sms) {
|
private fun processBG(receivedSms: Sms) {
|
||||||
val actualBG = iobCobCalculator.actualBg()
|
val actualBG = iobCobCalculator.ads.actualBg()
|
||||||
val lastBG = iobCobCalculator.lastBg()
|
val lastBG = iobCobCalculator.ads.lastBg()
|
||||||
var reply = ""
|
var reply = ""
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
if (actualBG != null) {
|
if (actualBG != null) {
|
||||||
|
@ -854,7 +854,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
} else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
|
} else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toTodayTime(hh_colon_mm: String): Long {
|
private fun toTodayTime(hh_colon_mm: String): Long {
|
||||||
val p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM| PM|AM|PM|)")
|
val p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM| PM|AM|PM|)")
|
||||||
val m = p.matcher(hh_colon_mm)
|
val m = p.matcher(hh_colon_mm)
|
||||||
var retval: Long = 0
|
var retval: Long = 0
|
||||||
|
|
|
@ -207,7 +207,7 @@ class ActionStringHandler @Inject constructor(
|
||||||
sendError("No profile found!")
|
sendError("No profile found!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val bgReading = iobCobCalculator.actualBg()
|
val bgReading = iobCobCalculator.ads.actualBg()
|
||||||
if (bgReading == null) {
|
if (bgReading == null) {
|
||||||
sendError("No recent BG to base calculation on!")
|
sendError("No recent BG to base calculation on!")
|
||||||
return
|
return
|
||||||
|
|
|
@ -279,7 +279,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
|
|
||||||
private void sendData() {
|
private void sendData() {
|
||||||
|
|
||||||
GlucoseValue lastBG = iobCobCalculator.lastBg();
|
GlucoseValue lastBG = iobCobCalculator.getAds().lastBg();
|
||||||
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
|
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
|
||||||
if (lastBG != null) {
|
if (lastBG != null) {
|
||||||
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData();
|
GlucoseStatus glucoseStatus = glucoseStatusProvider.getGlucoseStatusData();
|
||||||
|
@ -381,7 +381,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
googleApiConnect();
|
googleApiConnect();
|
||||||
}
|
}
|
||||||
long startTime = System.currentTimeMillis() - (long) (60000 * 60 * 5.5);
|
long startTime = System.currentTimeMillis() - (long) (60000 * 60 * 5.5);
|
||||||
GlucoseValue last_bg = iobCobCalculator.lastBg();
|
GlucoseValue last_bg = iobCobCalculator.getAds().lastBg();
|
||||||
|
|
||||||
if (last_bg == null) return;
|
if (last_bg == null) return;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import androidx.collection.LongSparseArray
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.InMemoryGlucoseValue
|
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.MealData
|
import info.nightscout.androidaps.data.MealData
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
@ -13,7 +12,6 @@ import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
import info.nightscout.androidaps.database.entities.Bolus
|
import info.nightscout.androidaps.database.entities.Bolus
|
||||||
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
|
||||||
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||||
import info.nightscout.androidaps.database.interfaces.end
|
import info.nightscout.androidaps.database.interfaces.end
|
||||||
import info.nightscout.androidaps.events.*
|
import info.nightscout.androidaps.events.*
|
||||||
|
@ -41,11 +39,9 @@ import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToLong
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
open class IobCobCalculatorPlugin @Inject constructor(
|
open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
|
@ -76,17 +72,11 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
|
|
||||||
private var iobTable = LongSparseArray<IobTotal>() // oldest at index 0
|
private var iobTable = LongSparseArray<IobTotal>() // oldest at index 0
|
||||||
private var absIobTable = LongSparseArray<IobTotal>() // oldest at index 0, absolute insulin in the body
|
private var absIobTable = LongSparseArray<IobTotal>() // oldest at index 0, absolute insulin in the body
|
||||||
private var autosensDataTable = LongSparseArray<AutosensData>() // oldest at index 0
|
|
||||||
private var basalDataTable = LongSparseArray<BasalData>() // oldest at index 0
|
private var basalDataTable = LongSparseArray<BasalData>() // oldest at index 0
|
||||||
internal var bgReadings: List<GlucoseValue> = listOf() // newest at index 0
|
|
||||||
|
|
||||||
internal var bucketedData: MutableList<InMemoryGlucoseValue>? = null
|
override var ads: AutosensDataStore = AutosensDataStore()
|
||||||
|
|
||||||
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
private val dataLock = Any()
|
||||||
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
|
||||||
var referenceTime: Long = -1
|
|
||||||
private var lastUsed5minCalculation: Boolean? = null // true if used 5min bucketed data
|
|
||||||
override val dataLock = Any()
|
|
||||||
var stopCalculationTrigger = false
|
var stopCalculationTrigger = false
|
||||||
private var thread: Thread? = null
|
private var thread: Thread? = null
|
||||||
|
|
||||||
|
@ -96,12 +86,12 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventConfigBuilderChange::class.java)
|
.toObservable(EventConfigBuilderChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ event -> resetData("onEventConfigBuilderChange", event) }, fabricPrivacy::logException)
|
.subscribe({ event -> resetDataAndRunCalculation("onEventConfigBuilderChange", event) }, fabricPrivacy::logException)
|
||||||
// EventNewBasalProfile
|
// EventNewBasalProfile
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewBasalProfile::class.java)
|
.toObservable(EventNewBasalProfile::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ event -> resetData("onNewProfile", event) }, fabricPrivacy::logException)
|
.subscribe({ event -> resetDataAndRunCalculation("onNewProfile", event) }, fabricPrivacy::logException)
|
||||||
// EventPreferenceChange
|
// EventPreferenceChange
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventPreferenceChange::class.java)
|
.toObservable(EventPreferenceChange::class.java)
|
||||||
|
@ -115,7 +105,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_max) ||
|
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_max) ||
|
||||||
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_min) ||
|
event.isChanged(resourceHelper, R.string.key_openapsama_autosens_min) ||
|
||||||
event.isChanged(resourceHelper, R.string.key_insulin_oref_peak)) {
|
event.isChanged(resourceHelper, R.string.key_insulin_oref_peak)) {
|
||||||
resetData("onEventPreferenceChange", event)
|
resetDataAndRunCalculation("onEventPreferenceChange", event)
|
||||||
}
|
}
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
// EventAppInitialized
|
// EventAppInitialized
|
||||||
|
@ -135,217 +125,19 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBgReadingsDataTableCopy(): List<GlucoseValue> = bgReadings.toList()
|
private fun resetDataAndRunCalculation(reason: String, event: Event?) {
|
||||||
override fun getBucketedDataTableCopy(): MutableList<InMemoryGlucoseValue>? = bucketedData?.toMutableList()
|
|
||||||
override fun getAutosensDataTable(): LongSparseArray<AutosensData> = autosensDataTable
|
|
||||||
|
|
||||||
private fun adjustToReferenceTime(someTime: Long): Long {
|
|
||||||
if (referenceTime == -1L) {
|
|
||||||
referenceTime = someTime
|
|
||||||
return someTime
|
|
||||||
}
|
|
||||||
var diff = abs(someTime - referenceTime)
|
|
||||||
diff %= T.mins(5).msecs()
|
|
||||||
if (diff > T.mins(2).plus(T.secs(30)).msecs()) diff -= T.mins(5).msecs()
|
|
||||||
return someTime + diff
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadBgData(to: Long) {
|
|
||||||
val profile = profileFunction.getProfile(to)
|
|
||||||
var dia = Constants.defaultDIA
|
|
||||||
if (profile != null) dia = profile.dia
|
|
||||||
val start = to - T.hours((24 + dia).toLong()).msecs()
|
|
||||||
if (dateUtil.isCloseToNow(to)) {
|
|
||||||
// if close to now expect there can be some readings with time in close future (caused by wrong time setting)
|
|
||||||
// so read all records
|
|
||||||
bgReadings = repository.compatGetBgReadingsDataFromTime(start, false).blockingGet()
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size + " Start date: " + dateUtil.dateAndTimeString(start))
|
|
||||||
} else {
|
|
||||||
bgReadings = repository.compatGetBgReadingsDataFromTime(start, to, false).blockingGet()
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size + " Start date: " + dateUtil.dateAndTimeString(start) + " End date: " + dateUtil.dateAndTimeString(to))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isAbout5minData: Boolean
|
|
||||||
get() {
|
|
||||||
synchronized(dataLock) {
|
|
||||||
if (bgReadings.size < 3) return true
|
|
||||||
|
|
||||||
var totalDiff: Long = 0
|
|
||||||
for (i in 1 until bgReadings.size) {
|
|
||||||
val bgTime = bgReadings[i].timestamp
|
|
||||||
val lastBgTime = bgReadings[i - 1].timestamp
|
|
||||||
var diff = lastBgTime - bgTime
|
|
||||||
diff %= T.mins(5).msecs()
|
|
||||||
if (diff > T.mins(2).plus(T.secs(30)).msecs()) diff -= T.mins(5).msecs()
|
|
||||||
totalDiff += diff
|
|
||||||
diff = abs(diff)
|
|
||||||
if (diff > T.secs(30).msecs()) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Interval detection: values: " + bgReadings.size + " diff: " + diff / 1000 + "[s] is5minData: " + false)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val averageDiff = totalDiff / bgReadings.size / 1000
|
|
||||||
val is5minData = averageDiff < 1
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Interval detection: values: " + bgReadings.size + " averageDiff: " + averageDiff + "[s] is5minData: " + is5minData)
|
|
||||||
return is5minData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resetData(reason: String, event: Event?) {
|
|
||||||
stopCalculation(reason)
|
stopCalculation(reason)
|
||||||
synchronized(dataLock) {
|
clearCache()
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Invalidating cached data because of $reason.")
|
ads.reset()
|
||||||
synchronized(dataLock) {
|
|
||||||
iobTable = LongSparseArray()
|
|
||||||
autosensDataTable = LongSparseArray()
|
|
||||||
basalDataTable = LongSparseArray()
|
|
||||||
absIobTable = LongSparseArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
runCalculation(reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
|
runCalculation(reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createBucketedData() {
|
fun clearCache() {
|
||||||
val fiveMinData = isAbout5minData
|
synchronized(dataLock) {
|
||||||
if (lastUsed5minCalculation != null && lastUsed5minCalculation != fiveMinData) {
|
aapsLogger.debug(LTag.AUTOSENS, "Clearing cached data.")
|
||||||
// changing mode => clear cache
|
iobTable = LongSparseArray()
|
||||||
aapsLogger.debug("Invalidating cached data because of changed mode.")
|
basalDataTable = LongSparseArray()
|
||||||
resetData("changed mode", null)
|
|
||||||
}
|
}
|
||||||
lastUsed5minCalculation = fiveMinData
|
|
||||||
if (isAbout5minData) createBucketedData5min() else createBucketedDataRecalculated()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findNewer(time: Long): GlucoseValue? {
|
|
||||||
var lastFound = bgReadings[0]
|
|
||||||
if (lastFound.timestamp < time) return null
|
|
||||||
for (i in 1 until bgReadings.size) {
|
|
||||||
if (bgReadings[i].timestamp == time) return bgReadings[i]
|
|
||||||
if (bgReadings[i].timestamp > time) continue
|
|
||||||
lastFound = bgReadings[i - 1]
|
|
||||||
if (bgReadings[i].timestamp < time) break
|
|
||||||
}
|
|
||||||
return lastFound
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findOlder(time: Long): GlucoseValue? {
|
|
||||||
var lastFound = bgReadings[bgReadings.size - 1]
|
|
||||||
if (lastFound.timestamp > time) return null
|
|
||||||
for (i in bgReadings.size - 2 downTo 0) {
|
|
||||||
if (bgReadings[i].timestamp == time) return bgReadings[i]
|
|
||||||
if (bgReadings[i].timestamp < time) continue
|
|
||||||
lastFound = bgReadings[i + 1]
|
|
||||||
if (bgReadings[i].timestamp > time) break
|
|
||||||
}
|
|
||||||
return lastFound
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createBucketedDataRecalculated() {
|
|
||||||
if (bgReadings.size < 3) {
|
|
||||||
bucketedData = null
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bucketedData = ArrayList()
|
|
||||||
var currentTime = bgReadings[0].timestamp - bgReadings[0].timestamp % T.mins(5).msecs()
|
|
||||||
currentTime = adjustToReferenceTime(currentTime)
|
|
||||||
aapsLogger.debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(currentTime))
|
|
||||||
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
|
|
||||||
while (true) {
|
|
||||||
// test if current value is older than current time
|
|
||||||
val newer = findNewer(currentTime)
|
|
||||||
val older = findOlder(currentTime)
|
|
||||||
if (newer == null || older == null) break
|
|
||||||
if (older.timestamp == newer.timestamp) { // direct hit
|
|
||||||
bucketedData?.add(InMemoryGlucoseValue(newer))
|
|
||||||
} else {
|
|
||||||
val bgDelta = newer.value - older.value
|
|
||||||
val timeDiffToNew = newer.timestamp - currentTime
|
|
||||||
val currentBg = newer.value - timeDiffToNew.toDouble() / (newer.timestamp - older.timestamp) * bgDelta
|
|
||||||
val newBgReading = InMemoryGlucoseValue(currentTime, currentBg.roundToLong().toDouble(), true)
|
|
||||||
bucketedData?.add(newBgReading)
|
|
||||||
//log.debug("BG: " + newBgReading.value + " (" + new Date(newBgReading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
|
|
||||||
}
|
|
||||||
currentTime -= T.mins(5).msecs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createBucketedData5min() {
|
|
||||||
if (bgReadings.size < 3) {
|
|
||||||
bucketedData = null
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val bData: MutableList<InMemoryGlucoseValue> = ArrayList()
|
|
||||||
bData.add(InMemoryGlucoseValue(bgReadings[0]))
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgReadings[0].timestamp) + " lastBgTime: " + "none-first-value" + " " + bgReadings[0].toString())
|
|
||||||
var j = 0
|
|
||||||
for (i in 1 until bgReadings.size) {
|
|
||||||
val bgTime = bgReadings[i].timestamp
|
|
||||||
var lastBgTime = bgReadings[i - 1].timestamp
|
|
||||||
//log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastBgTime).toString() + " " + bgReadings.get(i - 1).value);
|
|
||||||
check(!(bgReadings[i].value < 39 || bgReadings[i - 1].value < 39)) { "<39" }
|
|
||||||
var elapsedMinutes = (bgTime - lastBgTime) / (60 * 1000)
|
|
||||||
when {
|
|
||||||
abs(elapsedMinutes) > 8 -> {
|
|
||||||
// interpolate missing data points
|
|
||||||
var lastBg = bgReadings[i - 1].value
|
|
||||||
elapsedMinutes = abs(elapsedMinutes)
|
|
||||||
//console.error(elapsed_minutes);
|
|
||||||
var nextBgTime: Long
|
|
||||||
while (elapsedMinutes > 5) {
|
|
||||||
nextBgTime = lastBgTime - 5 * 60 * 1000
|
|
||||||
j++
|
|
||||||
val gapDelta = bgReadings[i].value - lastBg
|
|
||||||
//console.error(gapDelta, lastBg, elapsed_minutes);
|
|
||||||
val nextBg = lastBg + 5.0 / elapsedMinutes * gapDelta
|
|
||||||
val newBgReading = InMemoryGlucoseValue(nextBgTime, nextBg.roundToLong().toDouble(), true)
|
|
||||||
//console.error("Interpolated", bData[j]);
|
|
||||||
bData.add(newBgReading)
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
|
||||||
elapsedMinutes -= 5
|
|
||||||
lastBg = nextBg
|
|
||||||
lastBgTime = nextBgTime
|
|
||||||
}
|
|
||||||
j++
|
|
||||||
val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value)
|
|
||||||
bData.add(newBgReading)
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
abs(elapsedMinutes) > 2 -> {
|
|
||||||
j++
|
|
||||||
val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value)
|
|
||||||
bData.add(newBgReading)
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
bData[j].value = (bData[j].value + bgReadings[i].value) / 2
|
|
||||||
//log.error("***** Average");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize bucketed data
|
|
||||||
val oldest = bData[bData.size - 1]
|
|
||||||
oldest.timestamp = adjustToReferenceTime(oldest.timestamp)
|
|
||||||
aapsLogger.debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(oldest.timestamp))
|
|
||||||
for (i in bData.size - 2 downTo 0) {
|
|
||||||
val current = bData[i]
|
|
||||||
val previous = bData[i + 1]
|
|
||||||
val mSecDiff = current.timestamp - previous.timestamp
|
|
||||||
val adjusted = (mSecDiff - T.mins(5).msecs()) / 1000
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + dateUtil.dateAndTimeAndSecondsString(current.timestamp) + " to: " + dateUtil.dateAndTimeAndSecondsString(previous.timestamp + T.mins(5).msecs()) + " by " + adjusted + " sec")
|
|
||||||
if (abs(adjusted) > 90) {
|
|
||||||
// too big adjustment, fallback to non 5 min data
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Fallback to non 5 min data")
|
|
||||||
createBucketedDataRecalculated()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
current.timestamp = previous.timestamp + T.mins(5).msecs()
|
|
||||||
}
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Bucketed data created. Size: " + bData.size)
|
|
||||||
bucketedData = bData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun oldestDataAvailable(): Long {
|
private fun oldestDataAvailable(): Long {
|
||||||
|
@ -375,17 +167,9 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return getBGDataFrom
|
return getBGDataFrom
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun calculateFromTreatmentsAndTempsSynchronized(time: Long, profile: Profile): IobTotal {
|
override fun calculateFromTreatmentsAndTemps(fromTime: Long, profile: Profile): IobTotal {
|
||||||
synchronized(dataLock) { return calculateFromTreatmentsAndTemps(time, profile) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateFromTreatmentsAndTempsSynchronized(time: Long, lastAutosensResult: AutosensResult, exercise_mode: Boolean, half_basal_exercise_target: Int, isTempTarget: Boolean): IobTotal {
|
|
||||||
synchronized(dataLock) { return calculateFromTreatmentsAndTemps(time, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun calculateFromTreatmentsAndTemps(fromTime: Long, profile: Profile): IobTotal {
|
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
val time = roundUpTime(fromTime)
|
val time = ads.roundUpTime(fromTime)
|
||||||
val cacheHit = iobTable[time]
|
val cacheHit = iobTable[time]
|
||||||
if (time < now && cacheHit != null) {
|
if (time < now && cacheHit != null) {
|
||||||
//og.debug(">>> calculateFromTreatmentsAndTemps Cache hit " + new Date(time).toLocaleString());
|
//og.debug(">>> calculateFromTreatmentsAndTemps Cache hit " + new Date(time).toLocaleString());
|
||||||
|
@ -414,10 +198,10 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return iobTotal
|
return iobTotal
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun calculateAbsInsulinFromTreatmentsAndTempsSynchronized(fromTime: Long): IobTotal {
|
override fun calculateAbsInsulinFromTreatmentsAndTemps(fromTime: Long): IobTotal {
|
||||||
synchronized(dataLock) {
|
synchronized(dataLock) {
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
val time = roundUpTime(fromTime)
|
val time = ads.roundUpTime(fromTime)
|
||||||
val cacheHit = absIobTable[time]
|
val cacheHit = absIobTable[time]
|
||||||
if (time < now && cacheHit != null) {
|
if (time < now && cacheHit != null) {
|
||||||
//log.debug(">>> calculateFromTreatmentsAndTemps Cache hit " + new Date(time).toLocaleString());
|
//log.debug(">>> calculateFromTreatmentsAndTemps Cache hit " + new Date(time).toLocaleString());
|
||||||
|
@ -457,18 +241,10 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return IobTotal.combine(bolusIob, basalIob).round()
|
return IobTotal.combine(bolusIob, basalIob).round()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findPreviousTimeFromBucketedData(time: Long): Long? {
|
|
||||||
val bData = bucketedData ?: return null
|
|
||||||
for (index in bData.indices) {
|
|
||||||
if (bData[index].timestamp <= time) return bData[index].timestamp
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getBasalData(profile: Profile, fromTime: Long): BasalData {
|
override fun getBasalData(profile: Profile, fromTime: Long): BasalData {
|
||||||
synchronized(dataLock) {
|
synchronized(dataLock) {
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
val time = roundUpTime(fromTime)
|
val time = ads.roundUpTime(fromTime)
|
||||||
var retVal = basalDataTable[time]
|
var retVal = basalDataTable[time]
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
//log.debug(">>> getBasalData Cache miss " + new Date(time).toLocaleString());
|
//log.debug(">>> getBasalData Cache miss " + new Date(time).toLocaleString());
|
||||||
|
@ -490,19 +266,6 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAutosensData(fromTime: Long): AutosensData? {
|
|
||||||
var time = fromTime
|
|
||||||
synchronized(dataLock) {
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
if (time > now) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val previous = findPreviousTimeFromBucketedData(time) ?: return null
|
|
||||||
time = roundUpTime(previous)
|
|
||||||
return autosensDataTable[time]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData? {
|
override fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData? {
|
||||||
if (thread?.isAlive == true) {
|
if (thread?.isAlive == true) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA is waiting for calculation thread: $reason")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA is waiting for calculation thread: $reason")
|
||||||
|
@ -512,13 +275,13 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA finished waiting for calculation thread: $reason")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA finished waiting for calculation thread: $reason")
|
||||||
}
|
}
|
||||||
synchronized(dataLock) { return getLastAutosensData(reason) }
|
return ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo {
|
override fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo {
|
||||||
val autosensData =
|
val autosensData =
|
||||||
if (waitForCalculationFinish) getLastAutosensDataWithWaitForCalculationFinish(reason)
|
if (waitForCalculationFinish) getLastAutosensDataWithWaitForCalculationFinish(reason)
|
||||||
else getLastAutosensData(reason)
|
else ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
||||||
var displayCob: Double? = null
|
var displayCob: Double? = null
|
||||||
var futureCarbs = 0.0
|
var futureCarbs = 0.0
|
||||||
val now = dateUtil.now()
|
val now = dateUtil.now()
|
||||||
|
@ -526,7 +289,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
if (autosensData != null) {
|
if (autosensData != null) {
|
||||||
displayCob = autosensData.cob
|
displayCob = autosensData.cob
|
||||||
carbs.forEach { carb ->
|
carbs.forEach { carb ->
|
||||||
if (roundUpTime(carb.timestamp) > roundUpTime(autosensData.time) && carb.timestamp <= now) {
|
if (ads.roundUpTime(carb.timestamp) > ads.roundUpTime(autosensData.time) && carb.timestamp <= now) {
|
||||||
displayCob += carb.amount
|
displayCob += carb.amount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,52 +299,6 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return CobInfo(displayCob, futureCarbs)
|
return CobInfo(displayCob, futureCarbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun slowAbsorptionPercentage(timeInMinutes: Int): Double {
|
|
||||||
var sum = 0.0
|
|
||||||
var count = 0
|
|
||||||
val valuesToProcess = timeInMinutes / 5
|
|
||||||
synchronized(dataLock) {
|
|
||||||
var i = autosensDataTable.size() - 1
|
|
||||||
while (i >= 0 && count < valuesToProcess) {
|
|
||||||
if (autosensDataTable.valueAt(i).failoverToMinAbsorbtionRate) sum++
|
|
||||||
count++
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum / count
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLastAutosensData(reason: String): AutosensData? {
|
|
||||||
if (autosensDataTable.size() < 1) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: autosensDataTable empty ($reason)")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val data: AutosensData? = try {
|
|
||||||
autosensDataTable.valueAt(autosensDataTable.size() - 1)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// data can be processed on the background
|
|
||||||
// in this rare case better return null and do not block UI
|
|
||||||
// APS plugin should use getLastAutosensDataSynchronized where the blocking is not an issue
|
|
||||||
aapsLogger.error("AUTOSENSDATA null: Exception caught ($reason)")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
if (data == null) {
|
|
||||||
aapsLogger.error("AUTOSENSDATA null: data==null")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastData=" + dateUtil.dateAndTimeAndSecondsString(data.time))
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA ($reason) $data")
|
|
||||||
data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun lastDataTime(): String =
|
|
||||||
if (autosensDataTable.size() > 0) dateUtil.dateAndTimeAndSecondsString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time)
|
|
||||||
else "autosensDataTable empty"
|
|
||||||
|
|
||||||
override fun getMealDataWithWaitingForCalculationFinish(): MealData {
|
override fun getMealDataWithWaitingForCalculationFinish(): MealData {
|
||||||
val result = MealData()
|
val result = MealData()
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
|
@ -614,12 +331,12 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
override fun calculateIobArrayInDia(profile: Profile): Array<IobTotal> {
|
override fun calculateIobArrayInDia(profile: Profile): Array<IobTotal> {
|
||||||
// predict IOB out to DIA plus 30m
|
// predict IOB out to DIA plus 30m
|
||||||
var time = System.currentTimeMillis()
|
var time = System.currentTimeMillis()
|
||||||
time = roundUpTime(time)
|
time = ads.roundUpTime(time)
|
||||||
val len = ((profile.dia * 60 + 30) / 5).toInt()
|
val len = ((profile.dia * 60 + 30) / 5).toInt()
|
||||||
val array = Array(len) { IobTotal(0) }
|
val array = Array(len) { IobTotal(0) }
|
||||||
for ((pos, i) in (0 until len).withIndex()) {
|
for ((pos, i) in (0 until len).withIndex()) {
|
||||||
val t = time + i * 5 * 60000
|
val t = time + i * 5 * 60000
|
||||||
val iob = calculateFromTreatmentsAndTempsSynchronized(t, profile)
|
val iob = calculateFromTreatmentsAndTemps(t, profile)
|
||||||
array[pos] = iob
|
array[pos] = iob
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
|
@ -632,7 +349,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
val array = Array(len) { IobTotal(0) }
|
val array = Array(len) { IobTotal(0) }
|
||||||
for ((pos, i) in (0 until len).withIndex()) {
|
for ((pos, i) in (0 until len).withIndex()) {
|
||||||
val t = now + i * 5 * 60000
|
val t = now + i * 5 * 60000
|
||||||
val iob = calculateFromTreatmentsAndTempsSynchronized(t, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget)
|
val iob = calculateFromTreatmentsAndTemps(t, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget)
|
||||||
array[pos] = iob
|
array[pos] = iob
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
|
@ -649,10 +366,6 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun detectSensitivityWithLock(fromTime: Long, toTime: Long): AutosensResult {
|
|
||||||
synchronized(dataLock) { return activePlugin.activeSensitivity.detectSensitivity(this, fromTime, toTime) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stopCalculation(from: String) {
|
fun stopCalculation(from: String) {
|
||||||
if (thread?.state != Thread.State.TERMINATED) {
|
if (thread?.state != Thread.State.TERMINATED) {
|
||||||
stopCalculationTrigger = true
|
stopCalculationTrigger = true
|
||||||
|
@ -700,14 +413,6 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (index in autosensDataTable.size() - 1 downTo 0) {
|
|
||||||
if (autosensDataTable.keyAt(index) > time) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Removing from autosensDataTable: " + dateUtil.dateAndTimeAndSecondsString(autosensDataTable.keyAt(index)))
|
|
||||||
autosensDataTable.removeAt(index)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (index in basalDataTable.size() - 1 downTo 0) {
|
for (index in basalDataTable.size() - 1 downTo 0) {
|
||||||
if (basalDataTable.keyAt(index) > time) {
|
if (basalDataTable.keyAt(index) > time) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Removing from basalDataTable: " + dateUtil.dateAndTimeAndSecondsString(basalDataTable.keyAt(index)))
|
aapsLogger.debug(LTag.AUTOSENS, "Removing from basalDataTable: " + dateUtil.dateAndTimeAndSecondsString(basalDataTable.keyAt(index)))
|
||||||
|
@ -716,39 +421,12 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ads.newHistoryData(time, aapsLogger, dateUtil)
|
||||||
}
|
}
|
||||||
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), bgDataReload, true, event)
|
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), bgDataReload, true, event)
|
||||||
//log.debug("Releasing onNewHistoryData");
|
//log.debug("Releasing onNewHistoryData");
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearCache() {
|
|
||||||
synchronized(dataLock) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Clearing cached data.")
|
|
||||||
iobTable = LongSparseArray()
|
|
||||||
autosensDataTable = LongSparseArray()
|
|
||||||
basalDataTable = LongSparseArray()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return last BgReading from database or null if db is empty
|
|
||||||
*/
|
|
||||||
override fun lastBg(): GlucoseValue? {
|
|
||||||
val bgList = bgReadings
|
|
||||||
for (i in bgList.indices) if (bgList[i].value >= 39) return bgList[i]
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun actualBg(): GlucoseValue? {
|
|
||||||
val lastBg = lastBg() ?: return null
|
|
||||||
return if (lastBg.timestamp > System.currentTimeMillis() - T.mins(9).msecs()) lastBg else null
|
|
||||||
}
|
|
||||||
|
|
||||||
// roundup to whole minute
|
|
||||||
fun roundUpTime(time: Long): Long {
|
|
||||||
return if (time % 60000 == 0L) time else (time / 60000 + 1) * 60000
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convertToJSONArray(iobArray: Array<IobTotal>): JSONArray {
|
override fun convertToJSONArray(iobArray: Array<IobTotal>): JSONArray {
|
||||||
val array = JSONArray()
|
val array = JSONArray()
|
||||||
for (i in iobArray.indices) {
|
for (i in iobArray.indices) {
|
||||||
|
|
|
@ -10,6 +10,8 @@ import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.ValueWrapper
|
import info.nightscout.androidaps.database.ValueWrapper
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||||
|
import info.nightscout.androidaps.extensions.target
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
@ -21,9 +23,12 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.Profiler
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.extensions.target
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -51,6 +56,7 @@ class IobCobOref1Thread internal constructor(
|
||||||
@Inject lateinit var context: Context
|
@Inject lateinit var context: Context
|
||||||
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
||||||
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
||||||
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
@Inject lateinit var buildHelper: BuildHelper
|
@Inject lateinit var buildHelper: BuildHelper
|
||||||
@Inject lateinit var profiler: Profiler
|
@Inject lateinit var profiler: Profiler
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
@ -75,19 +81,20 @@ class IobCobOref1Thread internal constructor(
|
||||||
}
|
}
|
||||||
//log.debug("Locking calculateSensitivityData");
|
//log.debug("Locking calculateSensitivityData");
|
||||||
val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable)
|
val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable)
|
||||||
synchronized(iobCobCalculatorPlugin.dataLock) {
|
|
||||||
aapsLogger.debug("XXXXXXXXXXXXX START $from")
|
aapsLogger.debug("XXXXXXXXXXXXX START $from")
|
||||||
if (bgDataReload) {
|
if (bgDataReload) {
|
||||||
iobCobCalculatorPlugin.loadBgData(end)
|
iobCobCalculatorPlugin.ads.loadBgData(end, repository, aapsLogger, dateUtil)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.clearCache()
|
||||||
}
|
}
|
||||||
val bucketedData = iobCobCalculatorPlugin.getBucketedDataTableCopy()
|
// work on local copy and set back when finished
|
||||||
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()
|
val ads = iobCobCalculatorPlugin.ads.clone()
|
||||||
|
val bucketedData = ads.bucketedData
|
||||||
|
val autosensDataTable = ads.autosensDataTable
|
||||||
if (bucketedData == null || bucketedData.size < 3) {
|
if (bucketedData == null || bucketedData.size < 3) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val prevDataTime = iobCobCalculatorPlugin.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
|
val prevDataTime = ads.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime))
|
aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime))
|
||||||
var previous = autosensDataTable[prevDataTime]
|
var previous = autosensDataTable[prevDataTime]
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
|
@ -102,8 +109,8 @@ class IobCobOref1Thread internal constructor(
|
||||||
}
|
}
|
||||||
// check if data already exists
|
// check if data already exists
|
||||||
var bgTime = bucketedData[i].timestamp
|
var bgTime = bucketedData[i].timestamp
|
||||||
bgTime = iobCobCalculatorPlugin.roundUpTime(bgTime)
|
bgTime = ads.roundUpTime(bgTime)
|
||||||
if (bgTime > iobCobCalculatorPlugin.roundUpTime(dateUtil.now())) continue
|
if (bgTime > ads.roundUpTime(dateUtil.now())) continue
|
||||||
var existing: AutosensData?
|
var existing: AutosensData?
|
||||||
if (autosensDataTable[bgTime].also { existing = it } != null) {
|
if (autosensDataTable[bgTime].also { existing = it } != null) {
|
||||||
previous = existing
|
previous = existing
|
||||||
|
@ -144,7 +151,7 @@ class IobCobOref1Thread internal constructor(
|
||||||
@Suppress("UNUSED_VARIABLE") var maxDeviation = 0.0
|
@Suppress("UNUSED_VARIABLE") var maxDeviation = 0.0
|
||||||
@Suppress("UNUSED_VARIABLE") var minDeviation = 999.0
|
@Suppress("UNUSED_VARIABLE") var minDeviation = 999.0
|
||||||
val hourAgo = bgTime + 10 * 1000 - 60 * 60 * 1000L
|
val hourAgo = bgTime + 10 * 1000 - 60 * 60 * 1000L
|
||||||
val hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourAgo)
|
val hourAgoData = ads.getAutosensDataAtTime(hourAgo)
|
||||||
if (hourAgoData != null) {
|
if (hourAgoData != null) {
|
||||||
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
|
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString())
|
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString())
|
||||||
|
@ -309,13 +316,13 @@ class IobCobOref1Thread internal constructor(
|
||||||
if (min in 0..4 && hours % 2 == 0) autosensData.extraDeviation.add(0.0)
|
if (min in 0..4 && hours % 2 == 0) autosensData.extraDeviation.add(0.0)
|
||||||
previous = autosensData
|
previous = autosensData
|
||||||
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
|
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + ads.lastDataTime(dateUtil))
|
||||||
val sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime)
|
val sensitivity = activePlugin.activeSensitivity.detectSensitivity(ads, oldestTimeWithData, bgTime)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
|
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
|
||||||
autosensData.autosensResult = sensitivity
|
autosensData.autosensResult = sensitivity
|
||||||
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
||||||
}
|
}
|
||||||
}
|
iobCobCalculatorPlugin.ads = ads
|
||||||
Thread {
|
Thread {
|
||||||
SystemClock.sleep(1000)
|
SystemClock.sleep(1000)
|
||||||
rxBus.send(EventAutosensCalculationFinished(cause))
|
rxBus.send(EventAutosensCalculationFinished(cause))
|
||||||
|
@ -324,7 +331,6 @@ class IobCobOref1Thread internal constructor(
|
||||||
mWakeLock?.release()
|
mWakeLock?.release()
|
||||||
rxBus.send(EventIobCalculationProgress(""))
|
rxBus.send(EventIobCalculationProgress(""))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log())
|
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
@ -21,7 +22,11 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.Profiler
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
@ -50,6 +55,7 @@ class IobCobThread @Inject internal constructor(
|
||||||
@Inject lateinit var context: Context
|
@Inject lateinit var context: Context
|
||||||
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
||||||
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
||||||
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
@Inject lateinit var buildHelper: BuildHelper
|
@Inject lateinit var buildHelper: BuildHelper
|
||||||
@Inject lateinit var profiler: Profiler
|
@Inject lateinit var profiler: Profiler
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
@ -74,18 +80,19 @@ class IobCobThread @Inject internal constructor(
|
||||||
}
|
}
|
||||||
//log.debug("Locking calculateSensitivityData");
|
//log.debug("Locking calculateSensitivityData");
|
||||||
val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable)
|
val oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable)
|
||||||
synchronized(iobCobCalculatorPlugin.dataLock) {
|
|
||||||
if (bgDataReload) {
|
if (bgDataReload) {
|
||||||
iobCobCalculatorPlugin.loadBgData(end)
|
iobCobCalculatorPlugin.ads.loadBgData(end, repository, aapsLogger, dateUtil)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.clearCache()
|
||||||
}
|
}
|
||||||
val bucketedData = iobCobCalculatorPlugin.getBucketedDataTableCopy()
|
// work on local copy and set back when finished
|
||||||
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()
|
val ads = iobCobCalculatorPlugin.ads.clone()
|
||||||
|
val bucketedData = ads.bucketedData
|
||||||
|
val autosensDataTable = ads.autosensDataTable
|
||||||
if (bucketedData == null || bucketedData.size < 3) {
|
if (bucketedData == null || bucketedData.size < 3) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val prevDataTime = iobCobCalculatorPlugin.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
|
val prevDataTime = ads.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime))
|
aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime))
|
||||||
var previous = autosensDataTable[prevDataTime]
|
var previous = autosensDataTable[prevDataTime]
|
||||||
// start from oldest to be able sub cob
|
// start from oldest to be able sub cob
|
||||||
|
@ -99,8 +106,8 @@ class IobCobThread @Inject internal constructor(
|
||||||
}
|
}
|
||||||
// check if data already exists
|
// check if data already exists
|
||||||
var bgTime = bucketedData[i].timestamp
|
var bgTime = bucketedData[i].timestamp
|
||||||
bgTime = iobCobCalculatorPlugin.roundUpTime(bgTime)
|
bgTime = ads.roundUpTime(bgTime)
|
||||||
if (bgTime > iobCobCalculatorPlugin.roundUpTime(dateUtil.now())) continue
|
if (bgTime > ads.roundUpTime(dateUtil.now())) continue
|
||||||
var existing: AutosensData?
|
var existing: AutosensData?
|
||||||
if (autosensDataTable[bgTime].also { existing = it } != null) {
|
if (autosensDataTable[bgTime].also { existing = it } != null) {
|
||||||
previous = existing
|
previous = existing
|
||||||
|
@ -140,7 +147,7 @@ class IobCobThread @Inject internal constructor(
|
||||||
@Suppress("UNUSED_VARIABLE") var maxDeviation = 0.0
|
@Suppress("UNUSED_VARIABLE") var maxDeviation = 0.0
|
||||||
@Suppress("UNUSED_VARIABLE") var minDeviation = 999.0
|
@Suppress("UNUSED_VARIABLE") var minDeviation = 999.0
|
||||||
val hourAgo = bgTime + 10 * 1000 - 60 * 60 * 1000L
|
val hourAgo = bgTime + 10 * 1000 - 60 * 60 * 1000L
|
||||||
val hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourAgo)
|
val hourAgoData = ads.getAutosensDataAtTime(hourAgo)
|
||||||
if (hourAgoData != null) {
|
if (hourAgoData != null) {
|
||||||
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
|
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString())
|
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString())
|
||||||
|
@ -252,13 +259,13 @@ class IobCobThread @Inject internal constructor(
|
||||||
}
|
}
|
||||||
previous = autosensData
|
previous = autosensData
|
||||||
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
|
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + ads.lastDataTime(dateUtil))
|
||||||
val sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime)
|
val sensitivity = activePlugin.activeSensitivity.detectSensitivity(ads, oldestTimeWithData, bgTime)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
|
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
|
||||||
autosensData.autosensResult = sensitivity
|
autosensData.autosensResult = sensitivity
|
||||||
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
|
||||||
}
|
}
|
||||||
}
|
iobCobCalculatorPlugin.ads = ads
|
||||||
Thread {
|
Thread {
|
||||||
SystemClock.sleep(1000)
|
SystemClock.sleep(1000)
|
||||||
rxBus.send(EventAutosensCalculationFinished(cause))
|
rxBus.send(EventAutosensCalculationFinished(cause))
|
||||||
|
@ -267,7 +274,6 @@ class IobCobThread @Inject internal constructor(
|
||||||
mWakeLock?.release()
|
mWakeLock?.release()
|
||||||
rxBus.send(EventIobCalculationProgress(""))
|
rxBus.send(EventIobCalculationProgress(""))
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: $from")
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Midnights: " + MidnightTime.log())
|
|
||||||
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ package info.nightscout.androidaps.plugins.sensitivity
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.SensitivityInterface
|
import info.nightscout.androidaps.interfaces.SensitivityInterface
|
||||||
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.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import info.nightscout.androidaps.utils.SafeParse
|
import info.nightscout.androidaps.utils.SafeParse
|
||||||
|
@ -24,7 +24,7 @@ abstract class AbstractSensitivityPlugin(
|
||||||
val sp: SP
|
val sp: SP
|
||||||
) : PluginBase(pluginDescription, aapsLogger, resourceHelper, injector), SensitivityInterface {
|
) : PluginBase(pluginDescription, aapsLogger, resourceHelper, injector), SensitivityInterface {
|
||||||
|
|
||||||
abstract override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult
|
abstract override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult
|
||||||
|
|
||||||
fun fillResult(ratio: Double, carbsAbsorbed: Double, pastSensitivity: String,
|
fun fillResult(ratio: Double, carbsAbsorbed: Double, pastSensitivity: String,
|
||||||
ratioLimit: String, sensResult: String, deviationsArraySize: Int): AutosensResult {
|
ratioLimit: String, sensResult: String, deviationsArraySize: Int): AutosensResult {
|
||||||
|
|
|
@ -9,13 +9,13 @@ import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch
|
import info.nightscout.androidaps.db.ProfileSwitch
|
||||||
import info.nightscout.androidaps.extensions.isEvent5minBack
|
import info.nightscout.androidaps.extensions.isEvent5minBack
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.interfaces.SensitivityInterface.SensitivityType
|
import info.nightscout.androidaps.interfaces.SensitivityInterface.SensitivityType
|
||||||
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.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
@ -48,8 +48,7 @@ open class SensitivityAAPSPlugin @Inject constructor(
|
||||||
injector, aapsLogger, resourceHelper, sp
|
injector, aapsLogger, resourceHelper, sp
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult {
|
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
||||||
val autosensDataTable = plugin.getAutosensDataTable()
|
|
||||||
val age = sp.getString(R.string.key_age, "")
|
val age = sp.getString(R.string.key_age, "")
|
||||||
var defaultHours = 24
|
var defaultHours = 24
|
||||||
if (age == resourceHelper.gs(R.string.key_adult)) defaultHours = 24
|
if (age == resourceHelper.gs(R.string.key_adult)) defaultHours = 24
|
||||||
|
@ -61,13 +60,13 @@ open class SensitivityAAPSPlugin @Inject constructor(
|
||||||
aapsLogger.error("No profile")
|
aapsLogger.error("No profile")
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
if (autosensDataTable.size() < 4) {
|
if (ads.autosensDataTable.size() < 4) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
val current = plugin.getAutosensData(toTime) // this is running inside lock already
|
val current = ads.getAutosensDataAtTime(toTime) // this is running inside lock already
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
|
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
|
||||||
|
@ -75,8 +74,8 @@ open class SensitivityAAPSPlugin @Inject constructor(
|
||||||
val deviationsArray: MutableList<Double> = ArrayList()
|
val deviationsArray: MutableList<Double> = ArrayList()
|
||||||
var pastSensitivity = ""
|
var pastSensitivity = ""
|
||||||
var index = 0
|
var index = 0
|
||||||
while (index < autosensDataTable.size()) {
|
while (index < ads.autosensDataTable.size()) {
|
||||||
val autosensData = autosensDataTable.valueAt(index)
|
val autosensData = ads.autosensDataTable.valueAt(index)
|
||||||
if (autosensData.time < fromTime) {
|
if (autosensData.time < fromTime) {
|
||||||
index++
|
index++
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -9,7 +9,6 @@ import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch
|
import info.nightscout.androidaps.db.ProfileSwitch
|
||||||
import info.nightscout.androidaps.extensions.isEvent5minBack
|
import info.nightscout.androidaps.extensions.isEvent5minBack
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
@ -17,6 +16,7 @@ import info.nightscout.androidaps.interfaces.SensitivityInterface.SensitivityTyp
|
||||||
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.aps.openAPSSMB.SMBDefaults
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
@ -51,24 +51,23 @@ open class SensitivityOref1Plugin @Inject constructor(
|
||||||
injector, aapsLogger, resourceHelper, sp
|
injector, aapsLogger, resourceHelper, sp
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult {
|
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
||||||
// todo this method is called from the IobCobCalculatorPlugin, which leads to a circular
|
// todo this method is called from the IobCobCalculatorPlugin, which leads to a circular
|
||||||
// dependency, this should be avoided
|
// dependency, this should be avoided
|
||||||
val autosensDataTable = plugin.getAutosensDataTable()
|
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
aapsLogger.error("No profile")
|
aapsLogger.error("No profile")
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
if (autosensDataTable.size() < 4) {
|
if (ads.autosensDataTable.size() < 4) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
// the current
|
// the current
|
||||||
val current = plugin.getAutosensData(toTime) // this is running inside lock already
|
val current = ads.getAutosensDataAtTime(toTime) // this is running inside lock already
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
|
val siteChanges = repository.getTherapyEventDataFromTime(fromTime, TherapyEvent.Type.CANNULA_CHANGE, true).blockingGet()
|
||||||
|
@ -85,8 +84,8 @@ open class SensitivityOref1Plugin @Inject constructor(
|
||||||
val ratioLimitArray = mutableListOf("", "")
|
val ratioLimitArray = mutableListOf("", "")
|
||||||
val hoursDetection = listOf(8.0, 24.0)
|
val hoursDetection = listOf(8.0, 24.0)
|
||||||
var index = 0
|
var index = 0
|
||||||
while (index < autosensDataTable.size()) {
|
while (index < ads.autosensDataTable.size()) {
|
||||||
val autosensData = autosensDataTable.valueAt(index)
|
val autosensData = ads.autosensDataTable.valueAt(index)
|
||||||
if (autosensData.time < fromTime) {
|
if (autosensData.time < fromTime) {
|
||||||
index++
|
index++
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -8,17 +8,17 @@ import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch
|
import info.nightscout.androidaps.db.ProfileSwitch
|
||||||
|
import info.nightscout.androidaps.extensions.isEvent5minBack
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.interfaces.SensitivityInterface.SensitivityType
|
import info.nightscout.androidaps.interfaces.SensitivityInterface.SensitivityType
|
||||||
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.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.extensions.isEvent5minBack
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
|
@ -47,21 +47,20 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
|
||||||
injector, aapsLogger, resourceHelper, sp
|
injector, aapsLogger, resourceHelper, sp
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult {
|
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
||||||
val autosensDataTable = plugin.getAutosensDataTable()
|
|
||||||
val age = sp.getString(R.string.key_age, "")
|
val age = sp.getString(R.string.key_age, "")
|
||||||
var defaultHours = 24
|
var defaultHours = 24
|
||||||
if (age == resourceHelper.gs(R.string.key_adult)) defaultHours = 24
|
if (age == resourceHelper.gs(R.string.key_adult)) defaultHours = 24
|
||||||
if (age == resourceHelper.gs(R.string.key_teenage)) defaultHours = 4
|
if (age == resourceHelper.gs(R.string.key_teenage)) defaultHours = 4
|
||||||
if (age == resourceHelper.gs(R.string.key_child)) defaultHours = 4
|
if (age == resourceHelper.gs(R.string.key_child)) defaultHours = 4
|
||||||
val hoursForDetection = sp.getInt(R.string.key_openapsama_autosens_period, defaultHours)
|
val hoursForDetection = sp.getInt(R.string.key_openapsama_autosens_period, defaultHours)
|
||||||
if (autosensDataTable.size() < 4) {
|
if (ads.autosensDataTable.size() < 4) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. lastDataTime=" + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
val current = plugin.getAutosensData(toTime) // this is running inside lock already
|
val current = ads.getAutosensDataAtTime(toTime) // this is running inside lock already
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + plugin.lastDataTime())
|
aapsLogger.debug(LTag.AUTOSENS, "No autosens data available. toTime: " + dateUtil.dateAndTimeString(toTime) + " lastDataTime: " + ads.lastDataTime(dateUtil))
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
|
@ -74,8 +73,8 @@ open class SensitivityWeightedAveragePlugin @Inject constructor(
|
||||||
var pastSensitivity = ""
|
var pastSensitivity = ""
|
||||||
var index = 0
|
var index = 0
|
||||||
val data = LongSparseArray<Double>()
|
val data = LongSparseArray<Double>()
|
||||||
while (index < autosensDataTable.size()) {
|
while (index < ads.autosensDataTable.size()) {
|
||||||
val autosensData = autosensDataTable.valueAt(index)
|
val autosensData = ads.autosensDataTable.valueAt(index)
|
||||||
if (autosensData.time < fromTime) {
|
if (autosensData.time < fromTime) {
|
||||||
index++
|
index++
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -102,7 +102,7 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
var shouldUploadStatus = false
|
var shouldUploadStatus = false
|
||||||
if (config.NSCLIENT) return
|
if (config.NSCLIENT) return
|
||||||
if (config.PUMPCONTROL) shouldUploadStatus = true
|
if (config.PUMPCONTROL) shouldUploadStatus = true
|
||||||
else if (!loopPlugin.isEnabled() || iobCobCalculator.actualBg() == null)
|
else if (!loopPlugin.isEnabled() || iobCobCalculator.ads.actualBg() == null)
|
||||||
shouldUploadStatus = true
|
shouldUploadStatus = true
|
||||||
else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
|
else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
|
||||||
if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
|
if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
|
||||||
|
|
|
@ -110,7 +110,7 @@ class LocalAlertUtils @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkStaleBGAlert() {
|
fun checkStaleBGAlert() {
|
||||||
val bgReading = iobCobCalculator.lastBg()
|
val bgReading = iobCobCalculator.ads.lastBg()
|
||||||
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
||||||
&& bgReading != null && bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
|
&& bgReading != null && bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
|
||||||
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
|
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
|
||||||
|
|
|
@ -299,7 +299,7 @@ class BolusWizard @Inject constructor(
|
||||||
}
|
}
|
||||||
if (insulinFromCOB > 0) {
|
if (insulinFromCOB > 0) {
|
||||||
actions.add(resourceHelper.gs(R.string.cobvsiob) + ": " + resourceHelper.gs(R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG).formatColor(resourceHelper, R.color.cobAlert))
|
actions.add(resourceHelper.gs(R.string.cobvsiob) + ": " + resourceHelper.gs(R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG).formatColor(resourceHelper, R.color.cobAlert))
|
||||||
val absorptionRate = iobCobCalculator.slowAbsorptionPercentage(60)
|
val absorptionRate = iobCobCalculator.ads.slowAbsorptionPercentage(60)
|
||||||
if (absorptionRate > .25)
|
if (absorptionRate > .25)
|
||||||
actions.add(resourceHelper.gs(R.string.slowabsorptiondetected, resourceHelper.gc(R.color.cobAlert), (absorptionRate * 100).toInt()))
|
actions.add(resourceHelper.gs(R.string.slowabsorptiondetected, resourceHelper.gc(R.color.cobAlert), (absorptionRate * 100).toInt()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||||
|
@ -59,7 +60,7 @@ import java.util.*
|
||||||
ConstraintChecker::class, FabricPrivacy::class, VirtualPumpPlugin::class, XdripCalibrations::class,
|
ConstraintChecker::class, FabricPrivacy::class, VirtualPumpPlugin::class, XdripCalibrations::class,
|
||||||
SmsManager::class, CommandQueue::class, LocalProfilePlugin::class, DateUtil::class,
|
SmsManager::class, CommandQueue::class, LocalProfilePlugin::class, DateUtil::class,
|
||||||
OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class,
|
OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class,
|
||||||
AppRepository::class, DateUtil::class)
|
AppRepository::class, DateUtil::class, AutosensDataStore::class)
|
||||||
class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
|
@ -75,6 +76,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
@Mock lateinit var uel: UserEntryLogger
|
@Mock lateinit var uel: UserEntryLogger
|
||||||
@Mock lateinit var repository: AppRepository
|
@Mock lateinit var repository: AppRepository
|
||||||
@Mock lateinit var dateUtilMocked: DateUtil
|
@Mock lateinit var dateUtilMocked: DateUtil
|
||||||
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
|
|
||||||
var injector: HasAndroidInjector = HasAndroidInjector {
|
var injector: HasAndroidInjector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
@ -100,7 +102,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
bgList.add(reading)
|
bgList.add(reading)
|
||||||
|
|
||||||
`when`(iobCobCalculator.getCobInfo(false, "SMS COB")).thenReturn(CobInfo(10.0, 2.0))
|
`when`(iobCobCalculator.getCobInfo(false, "SMS COB")).thenReturn(CobInfo(10.0, 2.0))
|
||||||
`when`(iobCobCalculator.lastBg()).thenReturn(reading)
|
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
||||||
|
`when`(autosensDataStore.lastBg()).thenReturn(reading)
|
||||||
|
|
||||||
PowerMockito.mockStatic(SmsManager::class.java)
|
PowerMockito.mockStatic(SmsManager::class.java)
|
||||||
val smsManager = PowerMockito.mock(SmsManager::class.java)
|
val smsManager = PowerMockito.mock(SmsManager::class.java)
|
||||||
|
|
|
@ -3,10 +3,10 @@ package info.nightscout.androidaps.plugins.sensitivity
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.SensitivityInterface
|
import info.nightscout.androidaps.interfaces.SensitivityInterface
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
@ -26,7 +26,7 @@ class AbstractSensitivityPluginTest : TestBase() {
|
||||||
|
|
||||||
private inner class SensitivityTestClass(pluginDescription: PluginDescription, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, sp: SP) : AbstractSensitivityPlugin(pluginDescription, HasAndroidInjector { AndroidInjector { } }, aapsLogger, resourceHelper, sp) {
|
private inner class SensitivityTestClass(pluginDescription: PluginDescription, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, sp: SP) : AbstractSensitivityPlugin(pluginDescription, HasAndroidInjector { AndroidInjector { } }, aapsLogger, resourceHelper, sp) {
|
||||||
|
|
||||||
override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult {
|
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
||||||
return AutosensResult()
|
return AutosensResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.interfaces.*
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
@ -27,7 +28,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
|
||||||
import org.powermock.modules.junit4.PowerMockRunner
|
import org.powermock.modules.junit4.PowerMockRunner
|
||||||
|
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class, DateUtil::class)
|
@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class, DateUtil::class, AutosensDataStore::class)
|
||||||
class BolusWizardTest : TestBase() {
|
class BolusWizardTest : TestBase() {
|
||||||
|
|
||||||
private val pumpBolusStep = 0.1
|
private val pumpBolusStep = 0.1
|
||||||
|
@ -43,6 +44,7 @@ class BolusWizardTest : TestBase() {
|
||||||
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
|
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||||
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
||||||
@Mock lateinit var dateUtil: DateUtil
|
@Mock lateinit var dateUtil: DateUtil
|
||||||
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
@ -77,6 +79,7 @@ class BolusWizardTest : TestBase() {
|
||||||
val pumpDescription = PumpDescription()
|
val pumpDescription = PumpDescription()
|
||||||
pumpDescription.bolusStep = pumpBolusStep
|
pumpDescription.bolusStep = pumpBolusStep
|
||||||
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
|
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
|
||||||
|
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
||||||
|
|
||||||
Mockito.doAnswer { invocation: InvocationOnMock ->
|
Mockito.doAnswer { invocation: InvocationOnMock ->
|
||||||
invocation.getArgument<Constraint<Double>>(0)
|
invocation.getArgument<Constraint<Double>>(0)
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TriggerAutosensValue(injector: HasAndroidInjector) : Trigger(injector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldRun(): Boolean {
|
override fun shouldRun(): Boolean {
|
||||||
val autosensData = iobCobCalculator.getLastAutosensData("Automation trigger")
|
val autosensData = iobCobCalculator.ads.getLastAutosensData("Automation trigger", aapsLogger, dateUtil)
|
||||||
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||||
true
|
true
|
||||||
|
|
|
@ -34,7 +34,7 @@ class TriggerIob(injector: HasAndroidInjector) : Trigger(injector) {
|
||||||
|
|
||||||
override fun shouldRun(): Boolean {
|
override fun shouldRun(): Boolean {
|
||||||
val profile = profileFunction.getProfile() ?: return false
|
val profile = profileFunction.getProfile() ?: return false
|
||||||
val iob = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(dateUtil.now(), profile)
|
val iob = iobCobCalculator.calculateFromTreatmentsAndTemps(dateUtil.now(), profile)
|
||||||
if (comparator.value.check(iob.iob, insulin.value)) {
|
if (comparator.value.check(iob.iob, insulin.value)) {
|
||||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -25,7 +25,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
|
||||||
@Test fun shouldRunTest() {
|
@Test fun shouldRunTest() {
|
||||||
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_max), ArgumentMatchers.anyDouble())).thenReturn(1.2)
|
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_max), ArgumentMatchers.anyDouble())).thenReturn(1.2)
|
||||||
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_min), ArgumentMatchers.anyDouble())).thenReturn(0.7)
|
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_min), ArgumentMatchers.anyDouble())).thenReturn(0.7)
|
||||||
`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(generateAutosensData())
|
`when`(autosensDataStore.getLastAutosensData(anyObject(), anyObject(), anyObject())).thenReturn(generateAutosensData())
|
||||||
var t = TriggerAutosensValue(injector)
|
var t = TriggerAutosensValue(injector)
|
||||||
t.autosens.value = 110.0
|
t.autosens.value = 110.0
|
||||||
t.comparator.value = Comparator.Compare.IS_EQUAL
|
t.comparator.value = Comparator.Compare.IS_EQUAL
|
||||||
|
@ -65,14 +65,14 @@ class TriggerAutosensValueTest : TriggerTestBase() {
|
||||||
t.autosens.value = 390.0
|
t.autosens.value = 390.0
|
||||||
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
||||||
Assert.assertTrue(t.shouldRun())
|
Assert.assertTrue(t.shouldRun())
|
||||||
PowerMockito.`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(AutosensData(injector))
|
PowerMockito.`when`(autosensDataStore.getLastAutosensData(anyObject(), anyObject(), anyObject())).thenReturn(AutosensData(injector))
|
||||||
t = TriggerAutosensValue(injector)
|
t = TriggerAutosensValue(injector)
|
||||||
t.autosens.value = 80.0
|
t.autosens.value = 80.0
|
||||||
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
|
|
||||||
// Test autosensData == null and Comparator == IS_NOT_AVAILABLE
|
// Test autosensData == null and Comparator == IS_NOT_AVAILABLE
|
||||||
PowerMockito.`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(null)
|
PowerMockito.`when`(autosensDataStore.getLastAutosensData(anyObject(), anyObject(), anyObject())).thenReturn(null)
|
||||||
t = TriggerAutosensValue(injector)
|
t = TriggerAutosensValue(injector)
|
||||||
t.comparator.value = Comparator.Compare.IS_NOT_AVAILABLE
|
t.comparator.value = Comparator.Compare.IS_NOT_AVAILABLE
|
||||||
Assert.assertTrue(t.shouldRun())
|
Assert.assertTrue(t.shouldRun())
|
||||||
|
@ -109,7 +109,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun iconTest() {
|
@Test fun iconTest() {
|
||||||
Assert.assertEquals(Optional.of(R.drawable.`ic_as`), TriggerAutosensValue(injector).icon())
|
Assert.assertEquals(Optional.of(R.drawable.ic_as), TriggerAutosensValue(injector).icon())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -31,7 +31,7 @@ class TriggerBgTest : TriggerTestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shouldRunTest() {
|
fun shouldRunTest() {
|
||||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
||||||
var t: TriggerBg = TriggerBg(injector).setUnits(Constants.MMOL).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL)
|
var t: TriggerBg = TriggerBg(injector).setUnits(Constants.MMOL).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(214.0).comparator(Comparator.Compare.IS_EQUAL)
|
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(214.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
|
@ -50,7 +50,7 @@ class TriggerBgTest : TriggerTestBase() {
|
||||||
Assert.assertTrue(t.shouldRun())
|
Assert.assertTrue(t.shouldRun())
|
||||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
||||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerBg(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
t = TriggerBg(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TriggerDeltaTest : TriggerTestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun shouldRunTest() {
|
@Test fun shouldRunTest() {
|
||||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
||||||
var t = TriggerDelta(injector).units(Constants.MGDL).setValue(73.0, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL)
|
var t = TriggerDelta(injector).units(Constants.MGDL).setValue(73.0, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
Assert.assertEquals(DeltaType.LONG_AVERAGE, t.delta.deltaType)
|
Assert.assertEquals(DeltaType.LONG_AVERAGE, t.delta.deltaType)
|
||||||
|
@ -54,7 +54,7 @@ class TriggerDeltaTest : TriggerTestBase() {
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerDelta(injector).units(Constants.MGDL).setValue(-0.2, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
t = TriggerDelta(injector).units(Constants.MGDL).setValue(-0.2, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||||
Assert.assertTrue(t.shouldRun())
|
Assert.assertTrue(t.shouldRun())
|
||||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
||||||
t = TriggerDelta(injector).units(Constants.MGDL).setValue(213.0, DeltaType.DELTA).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
t = TriggerDelta(injector).units(Constants.MGDL).setValue(213.0, DeltaType.DELTA).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerDelta(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
t = TriggerDelta(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
||||||
|
|
|
@ -27,7 +27,7 @@ class TriggerIobTest : TriggerTestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun shouldRunTest() {
|
@Test fun shouldRunTest() {
|
||||||
`when`(iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(ArgumentMatchers.anyLong(), anyObject())).thenReturn(generateIobRecordData())
|
`when`(iobCobCalculator.calculateFromTreatmentsAndTemps(ArgumentMatchers.anyLong(), anyObject())).thenReturn(generateIobRecordData())
|
||||||
var t: TriggerIob = TriggerIob(injector).setValue(1.1).comparator(Comparator.Compare.IS_EQUAL)
|
var t: TriggerIob = TriggerIob(injector).setValue(1.1).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerIob(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
t = TriggerIob(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.androidaps.services.LastLocationDataContainer
|
import info.nightscout.androidaps.services.LastLocationDataContainer
|
||||||
|
@ -19,13 +20,14 @@ import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||||
|
|
||||||
@PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class)
|
@PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class, AutosensDataStore::class)
|
||||||
open class TriggerTestBase : TestBaseWithProfile() {
|
open class TriggerTestBase : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var locationDataContainer: LastLocationDataContainer
|
@Mock lateinit var locationDataContainer: LastLocationDataContainer
|
||||||
@Mock lateinit var activePlugin: ActivePluginProvider
|
@Mock lateinit var activePlugin: ActivePluginProvider
|
||||||
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var automationPlugin: AutomationPlugin
|
@Mock lateinit var automationPlugin: AutomationPlugin
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
|
||||||
receiverStatusStore = ReceiverStatusStore(context, rxBus)
|
receiverStatusStore = ReceiverStatusStore(context, rxBus)
|
||||||
testPumpPlugin = TestPumpPlugin(pluginDescription, aapsLogger, resourceHelper, injector)
|
testPumpPlugin = TestPumpPlugin(pluginDescription, aapsLogger, resourceHelper, injector)
|
||||||
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
|
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
|
||||||
|
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
var injector: HasAndroidInjector = HasAndroidInjector {
|
var injector: HasAndroidInjector = HasAndroidInjector {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package info.nightscout.androidaps.interfaces
|
package info.nightscout.androidaps.interfaces
|
||||||
|
|
||||||
import androidx.collection.LongSparseArray
|
|
||||||
import info.nightscout.androidaps.data.InMemoryGlucoseValue
|
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.MealData
|
import info.nightscout.androidaps.data.MealData
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
|
||||||
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.BasalData
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.BasalData
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
||||||
|
@ -16,36 +14,21 @@ import org.json.JSONArray
|
||||||
|
|
||||||
interface IobCobCalculator {
|
interface IobCobCalculator {
|
||||||
|
|
||||||
val dataLock: Any
|
var ads: AutosensDataStore
|
||||||
|
|
||||||
fun getBgReadingsDataTableCopy(): List<GlucoseValue>
|
|
||||||
fun getBucketedDataTableCopy(): MutableList<InMemoryGlucoseValue>?
|
|
||||||
fun getAutosensDataTable(): LongSparseArray<AutosensData>
|
|
||||||
|
|
||||||
|
|
||||||
fun getMealDataWithWaitingForCalculationFinish(): MealData
|
fun getMealDataWithWaitingForCalculationFinish(): MealData
|
||||||
fun lastDataTime(): String
|
|
||||||
fun getAutosensData(fromTime: Long): AutosensData?
|
|
||||||
fun getLastAutosensData(reason: String): AutosensData?
|
|
||||||
fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData?
|
fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData?
|
||||||
|
|
||||||
fun calculateIobArrayInDia(profile: Profile): Array<IobTotal>
|
fun calculateAbsInsulinFromTreatmentsAndTemps(fromTime: Long): IobTotal
|
||||||
fun calculateAbsInsulinFromTreatmentsAndTempsSynchronized(fromTime: Long): IobTotal
|
fun calculateFromTreatmentsAndTemps(time: Long, profile: Profile): IobTotal
|
||||||
fun calculateFromTreatmentsAndTempsSynchronized(time: Long, profile: Profile): IobTotal
|
|
||||||
|
|
||||||
fun getBasalData(profile: Profile, fromTime: Long): BasalData
|
fun getBasalData(profile: Profile, fromTime: Long): BasalData
|
||||||
|
|
||||||
|
fun calculateIobArrayInDia(profile: Profile): Array<IobTotal>
|
||||||
fun calculateIobArrayForSMB(lastAutosensResult: AutosensResult, exercise_mode: Boolean, half_basal_exercise_target: Int, isTempTarget: Boolean): Array<IobTotal>
|
fun calculateIobArrayForSMB(lastAutosensResult: AutosensResult, exercise_mode: Boolean, half_basal_exercise_target: Int, isTempTarget: Boolean): Array<IobTotal>
|
||||||
fun iobArrayToString(array: Array<IobTotal>): String
|
fun iobArrayToString(array: Array<IobTotal>): String
|
||||||
fun slowAbsorptionPercentage(timeInMinutes: Int): Double
|
|
||||||
fun convertToJSONArray(iobArray: Array<IobTotal>): JSONArray
|
fun convertToJSONArray(iobArray: Array<IobTotal>): JSONArray
|
||||||
|
|
||||||
/**
|
|
||||||
* Return last valid (>39) GlucoseValue from database or null if db is empty
|
|
||||||
*
|
|
||||||
* @return GlucoseValue or null
|
|
||||||
*/
|
|
||||||
fun lastBg(): GlucoseValue?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate CobInfo to now()
|
* Calculate CobInfo to now()
|
||||||
*
|
*
|
||||||
|
@ -55,13 +38,6 @@ interface IobCobCalculator {
|
||||||
*/
|
*/
|
||||||
fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo
|
fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide last GlucoseValue or null if none exists withing last 9 minutes
|
|
||||||
*
|
|
||||||
* @return GlucoseValue or null
|
|
||||||
*/
|
|
||||||
fun actualBg(): GlucoseValue?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate IobTotal from boluses and extended boluses to now().
|
* Calculate IobTotal from boluses and extended boluses to now().
|
||||||
* NOTE: Only isValid == true boluses are included
|
* NOTE: Only isValid == true boluses are included
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.interfaces
|
package info.nightscout.androidaps.interfaces
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||||
|
|
||||||
interface SensitivityInterface : ConfigExportImportInterface {
|
interface SensitivityInterface : ConfigExportImportInterface {
|
||||||
|
@ -11,15 +12,17 @@ interface SensitivityInterface : ConfigExportImportInterface {
|
||||||
SENSITIVITY_OREF1(2);
|
SENSITIVITY_OREF1(2);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val map = values().associateBy(SensitivityType::value)
|
private val map = values().associateBy(SensitivityType::value)
|
||||||
fun fromInt(type: Int) = map[type]
|
fun fromInt(type: Int) = map[type]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val id: SensitivityType
|
val id: SensitivityType
|
||||||
fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult
|
fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val MIN_HOURS = 1.0
|
const val MIN_HOURS = 1.0
|
||||||
const val MIN_HOURS_FULL_AUTOSENS = 4.0
|
const val MIN_HOURS_FULL_AUTOSENS = 4.0
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,350 @@
|
||||||
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
|
|
||||||
|
import androidx.collection.LongSparseArray
|
||||||
|
import info.nightscout.androidaps.data.InMemoryGlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.roundToLong
|
||||||
|
|
||||||
|
class AutosensDataStore {
|
||||||
|
|
||||||
|
private val dataLock = Any()
|
||||||
|
private var lastUsed5minCalculation: Boolean? = null // true if used 5min bucketed data
|
||||||
|
|
||||||
|
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
||||||
|
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
||||||
|
var referenceTime: Long = -1
|
||||||
|
|
||||||
|
var bgReadings: List<GlucoseValue> = listOf() // newest at index 0
|
||||||
|
@Synchronized set
|
||||||
|
@Synchronized get
|
||||||
|
|
||||||
|
var autosensDataTable = LongSparseArray<AutosensData>() // oldest at index 0
|
||||||
|
@Synchronized set
|
||||||
|
@Synchronized get
|
||||||
|
|
||||||
|
var bucketedData: MutableList<InMemoryGlucoseValue>? = null
|
||||||
|
@Synchronized set
|
||||||
|
@Synchronized get
|
||||||
|
|
||||||
|
fun clone(): AutosensDataStore =
|
||||||
|
AutosensDataStore().also {
|
||||||
|
synchronized(dataLock) {
|
||||||
|
it.bgReadings = this.bgReadings.toMutableList()
|
||||||
|
it.autosensDataTable = this.autosensDataTable.clone()
|
||||||
|
it.bucketedData = this.bucketedData?.toMutableList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBucketedDataTableCopy(): MutableList<InMemoryGlucoseValue>? = synchronized(dataLock) { bucketedData?.toMutableList() }
|
||||||
|
fun getBgReadingsDataTableCopy(): List<GlucoseValue> = synchronized(dataLock) { bgReadings.toMutableList() }
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
synchronized(autosensDataTable) { autosensDataTable = LongSparseArray() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newHistoryData(time: Long, aapsLogger: AAPSLogger, dateUtil: DateUtil) {
|
||||||
|
synchronized(autosensDataTable) {
|
||||||
|
for (index in autosensDataTable.size() - 1 downTo 0) {
|
||||||
|
if (autosensDataTable.keyAt(index) > time) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Removing from autosensDataTable: " + dateUtil.dateAndTimeAndSecondsString(autosensDataTable.keyAt(index)))
|
||||||
|
autosensDataTable.removeAt(index)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// roundup to whole minute
|
||||||
|
fun roundUpTime(time: Long): Long {
|
||||||
|
return if (time % 60000 == 0L) time else (time / 60000 + 1) * 60000
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return last valid (>39) GlucoseValue from database or null if db is empty
|
||||||
|
*
|
||||||
|
* @return GlucoseValue or null
|
||||||
|
*/
|
||||||
|
fun lastBg(): GlucoseValue? =
|
||||||
|
synchronized(dataLock) {
|
||||||
|
if (bgReadings.isNotEmpty()) bgReadings[0]
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide last GlucoseValue or null if none exists withing last 9 minutes
|
||||||
|
*
|
||||||
|
* @return GlucoseValue or null
|
||||||
|
*/
|
||||||
|
fun actualBg(): GlucoseValue? {
|
||||||
|
val lastBg = lastBg() ?: return null
|
||||||
|
return if (lastBg.timestamp > System.currentTimeMillis() - T.mins(9).msecs()) lastBg else null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun lastDataTime(dateUtil: DateUtil): String =
|
||||||
|
synchronized(dataLock) {
|
||||||
|
if (autosensDataTable.size() > 0) dateUtil.dateAndTimeAndSecondsString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time)
|
||||||
|
else "autosensDataTable empty"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findPreviousTimeFromBucketedData(time: Long): Long? {
|
||||||
|
val bData = bucketedData ?: return null
|
||||||
|
for (index in bData.indices) {
|
||||||
|
if (bData[index].timestamp <= time) return bData[index].timestamp
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAutosensDataAtTime(fromTime: Long): AutosensData? {
|
||||||
|
synchronized(dataLock) {
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (fromTime > now) return null
|
||||||
|
val previous = findPreviousTimeFromBucketedData(fromTime) ?: return null
|
||||||
|
return autosensDataTable[roundUpTime(previous)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastAutosensData(reason: String, aapsLogger: AAPSLogger, dateUtil: DateUtil): AutosensData? {
|
||||||
|
synchronized(dataLock) {
|
||||||
|
if (autosensDataTable.size() < 1) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: autosensDataTable empty ($reason)")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val data: AutosensData? = try {
|
||||||
|
autosensDataTable.valueAt(autosensDataTable.size() - 1)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// data can be processed on the background
|
||||||
|
// in this rare case better return null and do not block UI
|
||||||
|
// APS plugin should use getLastAutosensDataSynchronized where the blocking is not an issue
|
||||||
|
aapsLogger.error("AUTOSENSDATA null: Exception caught ($reason)")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (data == null) {
|
||||||
|
aapsLogger.error("AUTOSENSDATA null: data==null")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastData=" + dateUtil.dateAndTimeAndSecondsString(data.time))
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA ($reason) $data")
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun adjustToReferenceTime(someTime: Long): Long {
|
||||||
|
if (referenceTime == -1L) {
|
||||||
|
referenceTime = someTime
|
||||||
|
return someTime
|
||||||
|
}
|
||||||
|
var diff = abs(someTime - referenceTime)
|
||||||
|
diff %= T.mins(5).msecs()
|
||||||
|
if (diff > T.mins(2).plus(T.secs(30)).msecs()) diff -= T.mins(5).msecs()
|
||||||
|
return someTime + diff
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadBgData(to: Long, repository: AppRepository, aapsLogger: AAPSLogger, dateUtil: DateUtil) {
|
||||||
|
synchronized(dataLock) {
|
||||||
|
val start = to - T.hours((24 + 10 /* max dia */).toLong()).msecs()
|
||||||
|
// there can be some readings with time in close future (caused by wrong time setting on sensor)
|
||||||
|
// so add 2 minutes
|
||||||
|
bgReadings = repository
|
||||||
|
.compatGetBgReadingsDataFromTime(start, to + T.mins(2).msecs(), false)
|
||||||
|
.blockingGet()
|
||||||
|
.filter { it.value >= 39 }
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size + " Start date: " + dateUtil.dateAndTimeString(start) + " End date: " + dateUtil.dateAndTimeString(to))
|
||||||
|
createBucketedData(aapsLogger, dateUtil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAbout5minData(aapsLogger: AAPSLogger): Boolean {
|
||||||
|
synchronized(dataLock) {
|
||||||
|
if (bgReadings.size < 3) return true
|
||||||
|
|
||||||
|
var totalDiff: Long = 0
|
||||||
|
for (i in 1 until bgReadings.size) {
|
||||||
|
val bgTime = bgReadings[i].timestamp
|
||||||
|
val lastBgTime = bgReadings[i - 1].timestamp
|
||||||
|
var diff = lastBgTime - bgTime
|
||||||
|
diff %= T.mins(5).msecs()
|
||||||
|
if (diff > T.mins(2).plus(T.secs(30)).msecs()) diff -= T.mins(5).msecs()
|
||||||
|
totalDiff += diff
|
||||||
|
diff = abs(diff)
|
||||||
|
if (diff > T.secs(30).msecs()) {
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Interval detection: values: " + bgReadings.size + " diff: " + diff / 1000 + "[s] is5minData: " + false)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val averageDiff = totalDiff / bgReadings.size / 1000
|
||||||
|
val is5minData = averageDiff < 1
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Interval detection: values: " + bgReadings.size + " averageDiff: " + averageDiff + "[s] is5minData: " + is5minData)
|
||||||
|
return is5minData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createBucketedData(aapsLogger: AAPSLogger, dateUtil: DateUtil) {
|
||||||
|
val fiveMinData = isAbout5minData(aapsLogger)
|
||||||
|
if (lastUsed5minCalculation != null && lastUsed5minCalculation != fiveMinData) {
|
||||||
|
// changing mode => clear cache
|
||||||
|
aapsLogger.debug("Invalidating cached data because of changed mode.")
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
lastUsed5minCalculation = fiveMinData
|
||||||
|
if (fiveMinData) createBucketedData5min(aapsLogger, dateUtil) else createBucketedDataRecalculated(aapsLogger, dateUtil)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findNewer(time: Long): GlucoseValue? {
|
||||||
|
var lastFound = bgReadings[0]
|
||||||
|
if (lastFound.timestamp < time) return null
|
||||||
|
for (i in 1 until bgReadings.size) {
|
||||||
|
if (bgReadings[i].timestamp == time) return bgReadings[i]
|
||||||
|
if (bgReadings[i].timestamp > time) continue
|
||||||
|
lastFound = bgReadings[i - 1]
|
||||||
|
if (bgReadings[i].timestamp < time) break
|
||||||
|
}
|
||||||
|
return lastFound
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findOlder(time: Long): GlucoseValue? {
|
||||||
|
var lastFound = bgReadings[bgReadings.size - 1]
|
||||||
|
if (lastFound.timestamp > time) return null
|
||||||
|
for (i in bgReadings.size - 2 downTo 0) {
|
||||||
|
if (bgReadings[i].timestamp == time) return bgReadings[i]
|
||||||
|
if (bgReadings[i].timestamp < time) continue
|
||||||
|
lastFound = bgReadings[i + 1]
|
||||||
|
if (bgReadings[i].timestamp > time) break
|
||||||
|
}
|
||||||
|
return lastFound
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createBucketedDataRecalculated(aapsLogger: AAPSLogger, dateUtil: DateUtil) {
|
||||||
|
if (bgReadings.size < 3) {
|
||||||
|
bucketedData = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val newBucketedData = ArrayList<InMemoryGlucoseValue>()
|
||||||
|
var currentTime = bgReadings[0].timestamp - bgReadings[0].timestamp % T.mins(5).msecs()
|
||||||
|
currentTime = adjustToReferenceTime(currentTime)
|
||||||
|
aapsLogger.debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(currentTime))
|
||||||
|
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
|
||||||
|
while (true) {
|
||||||
|
// test if current value is older than current time
|
||||||
|
val newer = findNewer(currentTime)
|
||||||
|
val older = findOlder(currentTime)
|
||||||
|
if (newer == null || older == null) break
|
||||||
|
if (older.timestamp == newer.timestamp) { // direct hit
|
||||||
|
newBucketedData.add(InMemoryGlucoseValue(newer))
|
||||||
|
} else {
|
||||||
|
val bgDelta = newer.value - older.value
|
||||||
|
val timeDiffToNew = newer.timestamp - currentTime
|
||||||
|
val currentBg = newer.value - timeDiffToNew.toDouble() / (newer.timestamp - older.timestamp) * bgDelta
|
||||||
|
val newBgReading = InMemoryGlucoseValue(currentTime, currentBg.roundToLong().toDouble(), true)
|
||||||
|
newBucketedData.add(newBgReading)
|
||||||
|
//log.debug("BG: " + newBgReading.value + " (" + new Date(newBgReading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
|
||||||
|
}
|
||||||
|
currentTime -= T.mins(5).msecs()
|
||||||
|
}
|
||||||
|
bucketedData = newBucketedData
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createBucketedData5min(aapsLogger: AAPSLogger, dateUtil: DateUtil) {
|
||||||
|
if (bgReadings.size < 3) {
|
||||||
|
bucketedData = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val bData: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||||
|
bData.add(InMemoryGlucoseValue(bgReadings[0]))
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgReadings[0].timestamp) + " lastBgTime: " + "none-first-value" + " " + bgReadings[0].toString())
|
||||||
|
var j = 0
|
||||||
|
for (i in 1 until bgReadings.size) {
|
||||||
|
val bgTime = bgReadings[i].timestamp
|
||||||
|
var lastBgTime = bgReadings[i - 1].timestamp
|
||||||
|
//log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastBgTime).toString() + " " + bgReadings.get(i - 1).value);
|
||||||
|
var elapsedMinutes = (bgTime - lastBgTime) / (60 * 1000)
|
||||||
|
when {
|
||||||
|
abs(elapsedMinutes) > 8 -> {
|
||||||
|
// interpolate missing data points
|
||||||
|
var lastBg = bgReadings[i - 1].value
|
||||||
|
elapsedMinutes = abs(elapsedMinutes)
|
||||||
|
//console.error(elapsed_minutes);
|
||||||
|
var nextBgTime: Long
|
||||||
|
while (elapsedMinutes > 5) {
|
||||||
|
nextBgTime = lastBgTime - 5 * 60 * 1000
|
||||||
|
j++
|
||||||
|
val gapDelta = bgReadings[i].value - lastBg
|
||||||
|
//console.error(gapDelta, lastBg, elapsed_minutes);
|
||||||
|
val nextBg = lastBg + 5.0 / elapsedMinutes * gapDelta
|
||||||
|
val newBgReading = InMemoryGlucoseValue(nextBgTime, nextBg.roundToLong().toDouble(), true)
|
||||||
|
//console.error("Interpolated", bData[j]);
|
||||||
|
bData.add(newBgReading)
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
||||||
|
elapsedMinutes -= 5
|
||||||
|
lastBg = nextBg
|
||||||
|
lastBgTime = nextBgTime
|
||||||
|
}
|
||||||
|
j++
|
||||||
|
val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value)
|
||||||
|
bData.add(newBgReading)
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
abs(elapsedMinutes) > 2 -> {
|
||||||
|
j++
|
||||||
|
val newBgReading = InMemoryGlucoseValue(bgTime, bgReadings[i].value)
|
||||||
|
bData.add(newBgReading)
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Adding. bgTime: " + dateUtil.toISOString(bgTime) + " lastBgTime: " + dateUtil.toISOString(lastBgTime) + " " + newBgReading.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
bData[j].value = (bData[j].value + bgReadings[i].value) / 2
|
||||||
|
//log.error("***** Average");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize bucketed data
|
||||||
|
val oldest = bData[bData.size - 1]
|
||||||
|
oldest.timestamp = adjustToReferenceTime(oldest.timestamp)
|
||||||
|
aapsLogger.debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(oldest.timestamp))
|
||||||
|
for (i in bData.size - 2 downTo 0) {
|
||||||
|
val current = bData[i]
|
||||||
|
val previous = bData[i + 1]
|
||||||
|
val mSecDiff = current.timestamp - previous.timestamp
|
||||||
|
val adjusted = (mSecDiff - T.mins(5).msecs()) / 1000
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + dateUtil.dateAndTimeAndSecondsString(current.timestamp) + " to: " + dateUtil.dateAndTimeAndSecondsString(previous.timestamp + T.mins(5).msecs()) + " by " + adjusted + " sec")
|
||||||
|
if (abs(adjusted) > 90) {
|
||||||
|
// too big adjustment, fallback to non 5 min data
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Fallback to non 5 min data")
|
||||||
|
createBucketedDataRecalculated(aapsLogger, dateUtil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
current.timestamp = previous.timestamp + T.mins(5).msecs()
|
||||||
|
}
|
||||||
|
aapsLogger.debug(LTag.AUTOSENS, "Bucketed data created. Size: " + bData.size)
|
||||||
|
bucketedData = bData
|
||||||
|
}
|
||||||
|
|
||||||
|
fun slowAbsorptionPercentage(timeInMinutes: Int): Double {
|
||||||
|
var sum = 0.0
|
||||||
|
var count = 0
|
||||||
|
val valuesToProcess = timeInMinutes / 5
|
||||||
|
synchronized(dataLock) {
|
||||||
|
var i = autosensDataTable.size() - 1
|
||||||
|
while (i >= 0 && count < valuesToProcess) {
|
||||||
|
if (autosensDataTable.valueAt(i).failoverToMinAbsorbtionRate) sum++
|
||||||
|
count++
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (count != 0) sum / count else 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ class GlucoseStatusProvider @Inject constructor(
|
||||||
get() = getGlucoseStatusData()
|
get() = getGlucoseStatusData()
|
||||||
|
|
||||||
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
|
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
|
||||||
val data = iobCobCalculator.getBgReadingsDataTableCopy()
|
val data = iobCobCalculator.ads.getBgReadingsDataTableCopy()
|
||||||
val sizeRecords = data.size
|
val sizeRecords = data.size
|
||||||
if (sizeRecords == 0) {
|
if (sizeRecords == 0) {
|
||||||
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
|
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.iob.iobCalculator
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.asRounded
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.asRounded
|
||||||
|
@ -13,6 +14,7 @@ import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.`when`
|
||||||
import org.powermock.api.mockito.PowerMockito
|
import org.powermock.api.mockito.PowerMockito
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||||
import org.powermock.modules.junit4.PowerMockRunner
|
import org.powermock.modules.junit4.PowerMockRunner
|
||||||
|
@ -23,11 +25,17 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(DateUtil::class)
|
@PrepareForTest(DateUtil::class, AutosensDataStore::class)
|
||||||
class GlucoseStatusTest : TestBase() {
|
class GlucoseStatusTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var dateUtil: DateUtil
|
@Mock lateinit var dateUtil: DateUtil
|
||||||
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
|
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
|
||||||
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun prepare() {
|
||||||
|
`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun toStringShouldBeOverloaded() {
|
@Test fun toStringShouldBeOverloaded() {
|
||||||
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
|
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
|
||||||
|
@ -40,7 +48,7 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun calculateValidGlucoseStatus() {
|
@Test fun calculateValidGlucoseStatus() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
||||||
val glucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
val glucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||||
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
||||||
Assert.assertEquals(-2.0, glucoseStatus.delta, 0.001)
|
Assert.assertEquals(-2.0, glucoseStatus.delta, 0.001)
|
||||||
|
@ -50,7 +58,7 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun calculateMostRecentGlucoseStatus() {
|
@Test fun calculateMostRecentGlucoseStatus() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateMostRecentBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateMostRecentBgData())
|
||||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||||
Assert.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
|
Assert.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
|
||||||
Assert.assertEquals(-1.0, glucoseStatus.delta, 0.001)
|
Assert.assertEquals(-1.0, glucoseStatus.delta, 0.001)
|
||||||
|
@ -60,7 +68,7 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun oneRecordShouldProduceZeroDeltas() {
|
@Test fun oneRecordShouldProduceZeroDeltas() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
||||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||||
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
||||||
Assert.assertEquals(0.0, glucoseStatus.delta, 0.001)
|
Assert.assertEquals(0.0, glucoseStatus.delta, 0.001)
|
||||||
|
@ -70,19 +78,19 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun insufficientDataShouldReturnNull() {
|
@Test fun insufficientDataShouldReturnNull() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateInsufficientBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateInsufficientBgData())
|
||||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
||||||
Assert.assertEquals(null, glucoseStatus)
|
Assert.assertEquals(null, glucoseStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun oldDataShouldReturnNull() {
|
@Test fun oldDataShouldReturnNull() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
||||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
||||||
Assert.assertEquals(null, glucoseStatus)
|
Assert.assertEquals(null, glucoseStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun returnOldDataIfAllowed() {
|
@Test fun returnOldDataIfAllowed() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
||||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
|
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
|
||||||
Assert.assertNotEquals(null, glucoseStatus)
|
Assert.assertNotEquals(null, glucoseStatus)
|
||||||
}
|
}
|
||||||
|
@ -92,7 +100,7 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun calculateGlucoseStatusForLibreTestBgData() {
|
@Test fun calculateGlucoseStatusForLibreTestBgData() {
|
||||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateLibreTestData())
|
PowerMockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateLibreTestData())
|
||||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||||
Assert.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
|
Assert.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
|
||||||
Assert.assertEquals(-10.0, glucoseStatus.delta, 0.001)
|
Assert.assertEquals(-10.0, glucoseStatus.delta, 0.001)
|
||||||
|
@ -103,7 +111,8 @@ class GlucoseStatusTest : TestBase() {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun initMocking() {
|
fun initMocking() {
|
||||||
PowerMockito.`when`(dateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs())
|
`when`(dateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs())
|
||||||
|
`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
|
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
|
||||||
|
|
|
@ -1,68 +1,27 @@
|
||||||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.PowerManager
|
|
||||||
import dagger.android.AndroidInjector
|
|
||||||
import dagger.android.HasAndroidInjector
|
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
|
||||||
import org.powermock.modules.junit4.PowerMockRunner
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@RunWith(PowerMockRunner::class)
|
class AutosensDataStoreTest : TestBase() {
|
||||||
@PrepareForTest(FabricPrivacy::class, AppRepository::class)
|
|
||||||
class IobCobCalculatorPluginTest : TestBase() {
|
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
|
||||||
private val rxBus = RxBusWrapper(aapsSchedulers)
|
|
||||||
@Mock lateinit var resourceHelper: ResourceHelper
|
|
||||||
@Mock lateinit var profileFunction: ProfileFunction
|
|
||||||
@Mock lateinit var activePlugin: ActivePluginProvider
|
|
||||||
@Mock lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin
|
|
||||||
@Mock lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
|
||||||
@Mock lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
|
||||||
@Mock lateinit var repository: AppRepository
|
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var powerManager: PowerManager
|
|
||||||
|
|
||||||
lateinit var dateUtil: DateUtil
|
lateinit var dateUtil: DateUtil
|
||||||
private lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
private val autosensDataStore = AutosensDataStore()
|
||||||
AndroidInjector {
|
|
||||||
if (it is IobCobThread) {
|
|
||||||
it.context = context
|
|
||||||
it.resourceHelper = resourceHelper
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun mock() {
|
fun mock() {
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtil(context)
|
||||||
`when`(context.applicationContext).thenReturn(context)
|
|
||||||
`when`(context.getSystemService(anyObject())).thenReturn(powerManager)
|
|
||||||
iobCobCalculatorPlugin = IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction, activePlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -75,8 +34,8 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
|
|
||||||
// too much shifted data should return false
|
// too much shifted data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -84,16 +43,16 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
|
|
||||||
// too much shifted and missing data should return false
|
// too much shifted and missing data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
|
|
||||||
// too much shifted and missing data should return false
|
// too much shifted and missing data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -111,8 +70,8 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(28).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(28).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(23).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(23).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(16).plus(T.secs(36)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(16).plus(T.secs(36)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
|
|
||||||
// slightly shifted data should return true
|
// slightly shifted data should return true
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -120,16 +79,16 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
|
|
||||||
// slightly shifted and missing data should return true
|
// slightly shifted and missing data should return true
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -142,24 +101,24 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(bgReadingList[0].timestamp, iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(bgReadingList[3].timestamp, iobCobCalculatorPlugin.bucketedData!![3].timestamp)
|
Assert.assertEquals(bgReadingList[3].timestamp, autosensDataStore.bucketedData!![3].timestamp)
|
||||||
Assert.assertEquals(bgReadingList.size.toLong(), iobCobCalculatorPlugin.bucketedData!!.size.toLong())
|
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||||
|
|
||||||
// Missing value should be replaced
|
// Missing value should be replaced
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(bgReadingList[0].timestamp, iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(bgReadingList[2].timestamp, iobCobCalculatorPlugin.bucketedData!![3].timestamp)
|
Assert.assertEquals(bgReadingList[2].timestamp, autosensDataStore.bucketedData!![3].timestamp)
|
||||||
Assert.assertEquals(bgReadingList.size + 1.toLong(), iobCobCalculatorPlugin.bucketedData!!.size.toLong())
|
Assert.assertEquals(bgReadingList.size + 1.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||||
|
|
||||||
// drift should be cleared
|
// drift should be cleared
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -168,55 +127,55 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(T.mins(15).msecs(), iobCobCalculatorPlugin.bucketedData!![1].timestamp)
|
Assert.assertEquals(T.mins(15).msecs(), autosensDataStore.bucketedData!![1].timestamp)
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.bucketedData!![2].timestamp)
|
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.bucketedData!![2].timestamp)
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.bucketedData!![3].timestamp)
|
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.bucketedData!![3].timestamp)
|
||||||
Assert.assertEquals(bgReadingList.size.toLong(), iobCobCalculatorPlugin.bucketedData!!.size.toLong())
|
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||||
|
|
||||||
// bucketed data should return null if not enough bg data
|
// bucketed data should return null if not enough bg data
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(30).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(30).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.bucketedData)
|
Assert.assertEquals(null, autosensDataStore.bucketedData)
|
||||||
|
|
||||||
// data should be reconstructed
|
// data should be reconstructed
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 90.0, timestamp = T.mins(45).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 90.0, timestamp = T.mins(45).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(T.mins(50).msecs(), iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.bucketedData!![6].timestamp)
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
|
||||||
Assert.assertEquals(7, iobCobCalculatorPlugin.bucketedData!!.size.toLong())
|
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
|
||||||
Assert.assertEquals(100.0, iobCobCalculatorPlugin.bucketedData!![0].value, 1.0)
|
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
|
||||||
Assert.assertEquals(90.0, iobCobCalculatorPlugin.bucketedData!![1].value, 1.0)
|
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
|
||||||
Assert.assertEquals(50.0, iobCobCalculatorPlugin.bucketedData!![5].value, 1.0)
|
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
|
||||||
Assert.assertEquals(40.0, iobCobCalculatorPlugin.bucketedData!![6].value, 1.0)
|
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
|
||||||
|
|
||||||
// non 5min data should be reconstructed
|
// non 5min data should be reconstructed
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 96.0, timestamp = T.mins(48).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 96.0, timestamp = T.mins(48).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(T.mins(50).msecs(), iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.bucketedData!![6].timestamp)
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
|
||||||
Assert.assertEquals(7, iobCobCalculatorPlugin.bucketedData!!.size.toLong())
|
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
|
||||||
Assert.assertEquals(100.0, iobCobCalculatorPlugin.bucketedData!![0].value, 1.0)
|
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
|
||||||
Assert.assertEquals(90.0, iobCobCalculatorPlugin.bucketedData!![1].value, 1.0)
|
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
|
||||||
Assert.assertEquals(50.0, iobCobCalculatorPlugin.bucketedData!![5].value, 1.0)
|
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
|
||||||
Assert.assertEquals(40.0, iobCobCalculatorPlugin.bucketedData!![6].value, 1.0)
|
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -224,9 +183,9 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
|
|
||||||
//bucketed data should be null if no bg data available
|
//bucketed data should be null if no bg data available
|
||||||
iobCobCalculatorPlugin.bgReadings = ArrayList()
|
autosensDataStore.bgReadings = ArrayList()
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.bucketedData)
|
Assert.assertEquals(null, autosensDataStore.bucketedData)
|
||||||
|
|
||||||
// real data gap test
|
// real data gap test
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -258,12 +217,12 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:54:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:54:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:50:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:50:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:44:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:44:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.referenceTime = -1
|
autosensDataStore.referenceTime = -1
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T13:34:57Z"), iobCobCalculatorPlugin.bucketedData!![0].timestamp)
|
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T13:34:57Z"), autosensDataStore.bucketedData!![0].timestamp)
|
||||||
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T03:44:57Z"), iobCobCalculatorPlugin.bucketedData!![iobCobCalculatorPlugin.bucketedData!!.size - 1].timestamp)
|
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T03:44:57Z"), autosensDataStore.bucketedData!![autosensDataStore.bucketedData!!.size - 1].timestamp)
|
||||||
|
|
||||||
// 5min 4sec data
|
// 5min 4sec data
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -288,20 +247,20 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:02:26Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:02:26Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:57:21Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:57:21Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:52:17Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:52:17Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun bgReadingsTest() {
|
fun bgReadingsTest() {
|
||||||
val bgReadingList: List<GlucoseValue> = ArrayList()
|
val bgReadingList: List<GlucoseValue> = ArrayList()
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(bgReadingList, iobCobCalculatorPlugin.bgReadings)
|
Assert.assertEquals(bgReadingList, autosensDataStore.bgReadings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun roundUpTimeTest() {
|
fun roundUpTimeTest() {
|
||||||
Assert.assertEquals(T.mins(3).msecs(), iobCobCalculatorPlugin.roundUpTime(T.secs(155).msecs()))
|
Assert.assertEquals(T.mins(3).msecs(), autosensDataStore.roundUpTime(T.secs(155).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -311,12 +270,12 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(8).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(8).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(5).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findNewer(T.mins(5).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(10).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(10).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(20).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findNewer(T.mins(20).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findNewer(T.mins(22).msecs()))
|
Assert.assertEquals(null, autosensDataStore.findNewer(T.mins(22).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -326,20 +285,20 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(8).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(8).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(5).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(5).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(10).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findOlder(T.mins(10).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(20).msecs())!!.timestamp)
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findOlder(T.mins(20).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findOlder(T.mins(4).msecs()))
|
Assert.assertEquals(null, autosensDataStore.findOlder(T.mins(4).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun findPreviousTimeFromBucketedDataTest() {
|
fun findPreviousTimeFromBucketedDataTest() {
|
||||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(1000))
|
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(1000))
|
||||||
|
|
||||||
// Super data should not be touched
|
// Super data should not be touched
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
|
@ -347,11 +306,11 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
autosensDataStore.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
|
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(6).msecs()))
|
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(6).msecs()))
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
|
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue