AutotunePlugin -> plugins module
This commit is contained in:
parent
efcae9f073
commit
f0f5a89fe6
|
@ -37,13 +37,11 @@ import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDyn
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotunePlugin
|
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
|
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
|
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
|
||||||
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
|
||||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||||
|
@ -67,7 +65,9 @@ import info.nightscout.androidaps.utils.protection.ProtectionCheck.ProtectionTyp
|
||||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck.ProtectionType.CUSTOM_PIN
|
import info.nightscout.androidaps.utils.protection.ProtectionCheck.ProtectionType.CUSTOM_PIN
|
||||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck.ProtectionType.NONE
|
import info.nightscout.androidaps.utils.protection.ProtectionCheck.ProtectionType.NONE
|
||||||
import info.nightscout.automation.AutomationPlugin
|
import info.nightscout.automation.AutomationPlugin
|
||||||
|
import info.nightscout.plugins.general.autotune.AutotunePlugin
|
||||||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||||
|
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
||||||
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
||||||
import info.nightscout.shared.SafeParse
|
import info.nightscout.shared.SafeParse
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
@ -405,7 +405,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
||||||
} else {
|
} else {
|
||||||
if (pref.key.contains("pin")) {
|
if (pref.key.contains("pin")) {
|
||||||
pref.summary = rh.gs(R.string.pin_not_set)
|
pref.summary = rh.gs(R.string.pin_not_set)
|
||||||
}else {
|
} else {
|
||||||
pref.summary = rh.gs(R.string.password_not_set)
|
pref.summary = rh.gs(R.string.password_not_set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import info.nightscout.androidaps.dana.di.DanaModule
|
||||||
import info.nightscout.androidaps.danar.di.DanaRModule
|
import info.nightscout.androidaps.danar.di.DanaRModule
|
||||||
import info.nightscout.androidaps.danars.di.DanaRSModule
|
import info.nightscout.androidaps.danars.di.DanaRSModule
|
||||||
import info.nightscout.androidaps.database.DatabaseModule
|
import info.nightscout.androidaps.database.DatabaseModule
|
||||||
import info.nightscout.androidaps.dependencyInjection.AutotuneModule
|
|
||||||
import info.nightscout.androidaps.diaconn.di.DiaconnG8Module
|
import info.nightscout.androidaps.diaconn.di.DiaconnG8Module
|
||||||
import info.nightscout.androidaps.insight.di.InsightDatabaseModule
|
import info.nightscout.androidaps.insight.di.InsightDatabaseModule
|
||||||
import info.nightscout.androidaps.insight.di.InsightModule
|
import info.nightscout.androidaps.insight.di.InsightModule
|
||||||
|
@ -40,7 +39,6 @@ import javax.inject.Singleton
|
||||||
FragmentsModule::class,
|
FragmentsModule::class,
|
||||||
ReceiversModule::class,
|
ReceiversModule::class,
|
||||||
ServicesModule::class,
|
ServicesModule::class,
|
||||||
AutotuneModule::class,
|
|
||||||
ObjectivesModule::class,
|
ObjectivesModule::class,
|
||||||
WizardModule::class,
|
WizardModule::class,
|
||||||
APSModule::class,
|
APSModule::class,
|
||||||
|
|
|
@ -42,7 +42,6 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImpl
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImpl
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotunePlugin
|
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
|
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation
|
import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation
|
||||||
|
@ -71,6 +70,7 @@ import info.nightscout.implementation.queue.CommandQueueImplementation
|
||||||
import info.nightscout.implementation.stats.DexcomTirCalculatorImpl
|
import info.nightscout.implementation.stats.DexcomTirCalculatorImpl
|
||||||
import info.nightscout.implementation.stats.TddCalculatorImpl
|
import info.nightscout.implementation.stats.TddCalculatorImpl
|
||||||
import info.nightscout.implementation.stats.TirCalculatorImpl
|
import info.nightscout.implementation.stats.TirCalculatorImpl
|
||||||
|
import info.nightscout.plugins.general.autotune.AutotunePlugin
|
||||||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
|
|
@ -27,17 +27,16 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderFragment
|
||||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment
|
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment
|
||||||
import info.nightscout.androidaps.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
import info.nightscout.androidaps.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
||||||
import info.nightscout.androidaps.plugins.general.actions.ActionsFragment
|
import info.nightscout.androidaps.plugins.general.actions.ActionsFragment
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotuneFragment
|
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
|
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
|
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
|
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
|
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
||||||
import info.nightscout.plugins.profile.ProfileFragment
|
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||||
|
import info.nightscout.plugins.general.autotune.AutotuneFragment
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -48,10 +47,7 @@ abstract class FragmentsModule {
|
||||||
@ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment
|
@ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesAutotuneFragment(): AutotuneFragment
|
@ContributesAndroidInjector abstract fun contributesAutotuneFragment(): AutotuneFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||||
|
|
||||||
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||||
|
|
||||||
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment
|
|
||||||
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
|
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment
|
@ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
||||||
|
|
|
@ -24,18 +24,14 @@ import info.nightscout.androidaps.plugins.constraints.signatureVerifier.Signatur
|
||||||
import info.nightscout.androidaps.plugins.constraints.storage.StorageConstraintPlugin
|
import info.nightscout.androidaps.plugins.constraints.storage.StorageConstraintPlugin
|
||||||
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerPlugin
|
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin
|
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotunePlugin
|
|
||||||
import info.nightscout.androidaps.plugins.general.dataBroadcaster.DataBroadcastPlugin
|
import info.nightscout.androidaps.plugins.general.dataBroadcaster.DataBroadcastPlugin
|
||||||
import info.nightscout.plugins.general.food.FoodPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
|
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
|
||||||
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
|
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
|
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.plugins.profile.ProfilePlugin
|
|
||||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||||
|
@ -58,12 +54,16 @@ import info.nightscout.androidaps.plugins.source.RandomBgPlugin
|
||||||
import info.nightscout.androidaps.plugins.source.TomatoPlugin
|
import info.nightscout.androidaps.plugins.source.TomatoPlugin
|
||||||
import info.nightscout.androidaps.plugins.source.XdripPlugin
|
import info.nightscout.androidaps.plugins.source.XdripPlugin
|
||||||
import info.nightscout.automation.AutomationPlugin
|
import info.nightscout.automation.AutomationPlugin
|
||||||
|
import info.nightscout.plugins.general.autotune.AutotunePlugin
|
||||||
|
import info.nightscout.plugins.general.food.FoodPlugin
|
||||||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||||
|
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
|
||||||
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
||||||
import info.nightscout.plugins.insulin.InsulinLyumjevPlugin
|
import info.nightscout.plugins.insulin.InsulinLyumjevPlugin
|
||||||
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
||||||
import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin
|
import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin
|
||||||
import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||||
|
import info.nightscout.plugins.profile.ProfilePlugin
|
||||||
import javax.inject.Qualifier
|
import javax.inject.Qualifier
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
|
|
@ -7,17 +7,23 @@ import androidx.core.content.FileProvider
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.BuildConfig
|
import info.nightscout.androidaps.BuildConfig
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.interfaces.BuildHelper
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
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.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
|
||||||
import info.nightscout.androidaps.interfaces.BuildHelper
|
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
||||||
|
import info.nightscout.plugins.general.maintenance.LoggerUtils
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import java.io.*
|
import java.io.BufferedInputStream
|
||||||
import java.util.*
|
import java.io.BufferedOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.Arrays
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
|
@ -51,7 +51,6 @@ import java.util.concurrent.ScheduledFuture
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.floor
|
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
@ -450,23 +449,6 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
// From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2
|
|
||||||
// Returns the value at a given percentile in a sorted numeric array.
|
|
||||||
// "Linear interpolation between closest ranks" method
|
|
||||||
fun percentile(arr: Array<Double>, p: Double): Double {
|
|
||||||
if (arr.isEmpty()) return 0.0
|
|
||||||
if (p <= 0) return arr[0]
|
|
||||||
if (p >= 1) return arr[arr.size - 1]
|
|
||||||
val index = arr.size * p
|
|
||||||
val lower = floor(index)
|
|
||||||
val upper = lower + 1
|
|
||||||
val weight = index % 1
|
|
||||||
return if (upper >= arr.size) arr[lower.toInt()] else arr[lower.toInt()] * (1 - weight) + arr[upper.toInt()] * weight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time range to the past for IOB calculation
|
* Time range to the past for IOB calculation
|
||||||
* @return milliseconds
|
* @return milliseconds
|
||||||
|
|
|
@ -12,18 +12,18 @@ import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
|
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.shared.logging.LTag
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
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.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.plugins.utils.Percentile
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.Arrays
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
@ -116,7 +116,7 @@ class SensitivityAAPSPlugin @Inject constructor(
|
||||||
val sensResult: String
|
val sensResult: String
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
|
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
|
||||||
Arrays.sort(deviations)
|
Arrays.sort(deviations)
|
||||||
val percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50)
|
val percentile = Percentile.percentile(deviations, 0.50)
|
||||||
val basalOff = percentile * (60.0 / 5.0) / sens
|
val basalOff = percentile * (60.0 / 5.0) / sens
|
||||||
val ratio = 1 + basalOff / profile.getMaxDailyBasal()
|
val ratio = 1 + basalOff / profile.getMaxDailyBasal()
|
||||||
sensResult = when {
|
sensResult = when {
|
||||||
|
@ -126,13 +126,16 @@ class SensitivityAAPSPlugin @Inject constructor(
|
||||||
|
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.AUTOSENS, sensResult)
|
aapsLogger.debug(LTag.AUTOSENS, sensResult)
|
||||||
val output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit,
|
val output = fillResult(
|
||||||
sensResult, deviationsArray.size)
|
ratio, current.cob, pastSensitivity, ratioLimit,
|
||||||
|
sensResult, deviationsArray.size
|
||||||
|
)
|
||||||
aapsLogger.debug(
|
aapsLogger.debug(
|
||||||
LTag.AUTOSENS, "Sensitivity to: "
|
LTag.AUTOSENS, "Sensitivity to: "
|
||||||
+ dateUtil.dateAndTimeString(toTime) +
|
+ dateUtil.dateAndTimeString(toTime) +
|
||||||
" ratio: " + output.ratio
|
" ratio: " + output.ratio
|
||||||
+ " mealCOB: " + current.cob)
|
+ " mealCOB: " + current.cob
|
||||||
|
)
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity to: deviations " + deviations.contentToString())
|
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity to: deviations " + deviations.contentToString())
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
@ -158,7 +161,10 @@ class SensitivityAAPSPlugin @Inject constructor(
|
||||||
override fun applyConfiguration(configuration: JSONObject) {
|
override fun applyConfiguration(configuration: JSONObject) {
|
||||||
try {
|
try {
|
||||||
if (configuration.has(rh.gs(R.string.key_absorption_maxtime))) sp.putDouble(R.string.key_absorption_maxtime, configuration.getDouble(rh.gs(R.string.key_absorption_maxtime)))
|
if (configuration.has(rh.gs(R.string.key_absorption_maxtime))) sp.putDouble(R.string.key_absorption_maxtime, configuration.getDouble(rh.gs(R.string.key_absorption_maxtime)))
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_period))) sp.putDouble(R.string.key_openapsama_autosens_period, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_period)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_period))) sp.putDouble(
|
||||||
|
R.string.key_openapsama_autosens_period,
|
||||||
|
configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_period))
|
||||||
|
)
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_max))) sp.getDouble(R.string.key_openapsama_autosens_max, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_max)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_max))) sp.getDouble(R.string.key_openapsama_autosens_max, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_max)))
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_min))) sp.getDouble(R.string.key_openapsama_autosens_min, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_min)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_min))) sp.getDouble(R.string.key_openapsama_autosens_min, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_min)))
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
|
|
|
@ -12,19 +12,19 @@ import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
|
import info.nightscout.androidaps.interfaces.Sensitivity.SensitivityType
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.shared.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.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.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.plugins.utils.Percentile
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.Arrays
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
@ -75,7 +75,7 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
//[0] = 8 hour
|
//[0] = 8 hour
|
||||||
//[1] = 24 hour
|
//[1] = 24 hour
|
||||||
//deviationsHour has DeviationsArray
|
//deviationsHour has DeviationsArray
|
||||||
val deviationsHour = mutableListOf(ArrayList<Double>(), ArrayList<Double>())
|
val deviationsHour = mutableListOf(ArrayList(), ArrayList<Double>())
|
||||||
val pastSensitivityArray = mutableListOf("", "")
|
val pastSensitivityArray = mutableListOf("", "")
|
||||||
val sensResultArray = mutableListOf("", "")
|
val sensResultArray = mutableListOf("", "")
|
||||||
val ratioArray = mutableListOf(0.0, 0.0)
|
val ratioArray = mutableListOf(0.0, 0.0)
|
||||||
|
@ -160,8 +160,8 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
val sens = profile.getIsfMgdl()
|
val sens = profile.getIsfMgdl()
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
|
aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity")
|
||||||
Arrays.sort(deviations)
|
Arrays.sort(deviations)
|
||||||
val pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50)
|
val pSensitive = Percentile.percentile(deviations, 0.50)
|
||||||
val pResistant = IobCobCalculatorPlugin.percentile(deviations, 0.50)
|
val pResistant = Percentile.percentile(deviations, 0.50)
|
||||||
var basalOff = 0.0
|
var basalOff = 0.0
|
||||||
when {
|
when {
|
||||||
pSensitive < 0 -> { // sensitive
|
pSensitive < 0 -> { // sensitive
|
||||||
|
@ -198,7 +198,8 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
LTag.AUTOSENS, "Sensitivity to: "
|
LTag.AUTOSENS, "Sensitivity to: "
|
||||||
+ dateUtil.dateAndTimeString(toTime) +
|
+ dateUtil.dateAndTimeString(toTime) +
|
||||||
" ratio: " + output.ratio
|
" ratio: " + output.ratio
|
||||||
+ " mealCOB: " + current.cob)
|
+ " mealCOB: " + current.cob
|
||||||
|
)
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +220,10 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
|
|
||||||
override fun applyConfiguration(configuration: JSONObject) {
|
override fun applyConfiguration(configuration: JSONObject) {
|
||||||
try {
|
try {
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_min_5m_carbimpact))) sp.putDouble(R.string.key_openapsama_min_5m_carbimpact, configuration.getDouble(rh.gs(R.string.key_openapsama_min_5m_carbimpact)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_min_5m_carbimpact))) sp.putDouble(
|
||||||
|
R.string.key_openapsama_min_5m_carbimpact,
|
||||||
|
configuration.getDouble(rh.gs(R.string.key_openapsama_min_5m_carbimpact))
|
||||||
|
)
|
||||||
if (configuration.has(rh.gs(R.string.key_absorption_cutoff))) sp.putDouble(R.string.key_absorption_cutoff, configuration.getDouble(rh.gs(R.string.key_absorption_cutoff)))
|
if (configuration.has(rh.gs(R.string.key_absorption_cutoff))) sp.putDouble(R.string.key_absorption_cutoff, configuration.getDouble(rh.gs(R.string.key_absorption_cutoff)))
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_max))) sp.getDouble(R.string.key_openapsama_autosens_max, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_max)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_max))) sp.getDouble(R.string.key_openapsama_autosens_max, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_max)))
|
||||||
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_min))) sp.getDouble(R.string.key_openapsama_autosens_min, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_min)))
|
if (configuration.has(rh.gs(R.string.key_openapsama_autosens_min))) sp.getDouble(R.string.key_openapsama_autosens_min, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_min)))
|
||||||
|
|
|
@ -270,8 +270,6 @@
|
||||||
<string name="show_queue">Show queue</string>
|
<string name="show_queue">Show queue</string>
|
||||||
<string name="queue">Queue:</string>
|
<string name="queue">Queue:</string>
|
||||||
<string name="status">Status:</string>
|
<string name="status">Status:</string>
|
||||||
<string name="key_nsclientinternal_url" translatable="false">nsclientinternal_url</string>
|
|
||||||
<string name="key_nsclientinternal_api_secret" translatable="false">nsclientinternal_api_secret</string>
|
|
||||||
<string name="clearlog">Clear log</string>
|
<string name="clearlog">Clear log</string>
|
||||||
<string name="key_nsclientinternal_autoscroll" translatable="false">nsclientinternal_autoscroll</string>
|
<string name="key_nsclientinternal_autoscroll" translatable="false">nsclientinternal_autoscroll</string>
|
||||||
<string name="key_nsclientinternal_paused" translatable="false">nsclientinternal_paused</string>
|
<string name="key_nsclientinternal_paused" translatable="false">nsclientinternal_paused</string>
|
||||||
|
@ -529,7 +527,6 @@
|
||||||
<string name="overview_show_basals">Basals</string>
|
<string name="overview_show_basals">Basals</string>
|
||||||
<string name="closed_loop_disabled_on_dev_branch">Running dev version. Closed loop is disabled.</string>
|
<string name="closed_loop_disabled_on_dev_branch">Running dev version. Closed loop is disabled.</string>
|
||||||
<string name="engineering_mode_enabled">Engineering mode enabled</string>
|
<string name="engineering_mode_enabled">Engineering mode enabled</string>
|
||||||
<string name="profileswitch_ismissing">ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile.</string>
|
|
||||||
<string name="pumpisnottempbasalcapable">Pump is not temp basal capable</string>
|
<string name="pumpisnottempbasalcapable">Pump is not temp basal capable</string>
|
||||||
<string name="closedmodedisabledinpreferences">Closed loop mode disabled in preferences</string>
|
<string name="closedmodedisabledinpreferences">Closed loop mode disabled in preferences</string>
|
||||||
<string name="autosensdisabledinpreferences">Autosens disabled in preferences</string>
|
<string name="autosensdisabledinpreferences">Autosens disabled in preferences</string>
|
||||||
|
|
|
@ -3,10 +3,11 @@ package info.nightscout.androidaps.plugins.general.maintenance
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
|
||||||
import info.nightscout.androidaps.interfaces.BuildHelper
|
import info.nightscout.androidaps.interfaces.BuildHelper
|
||||||
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
||||||
|
import info.nightscout.plugins.general.maintenance.LoggerUtils
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
@ -27,7 +28,7 @@ class MaintenancePluginTest : TestBase() {
|
||||||
@Mock lateinit var fileListProvider: PrefFileListProvider
|
@Mock lateinit var fileListProvider: PrefFileListProvider
|
||||||
@Mock lateinit var config: Config
|
@Mock lateinit var config: Config
|
||||||
|
|
||||||
lateinit var sut: MaintenancePlugin
|
private lateinit var sut: MaintenancePlugin
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun mock() {
|
fun mock() {
|
||||||
|
|
|
@ -86,6 +86,8 @@
|
||||||
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
|
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
|
||||||
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
|
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
|
||||||
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
||||||
|
<string name="key_nsclientinternal_url" translatable="false">nsclientinternal_url</string>
|
||||||
|
<string name="key_nsclientinternal_api_secret" translatable="false">nsclientinternal_api_secret</string>
|
||||||
|
|
||||||
<!-- General-->
|
<!-- General-->
|
||||||
<string name="refresh">Refresh</string>
|
<string name="refresh">Refresh</string>
|
||||||
|
@ -233,6 +235,8 @@
|
||||||
<string name="remove_label">REMOVE</string>
|
<string name="remove_label">REMOVE</string>
|
||||||
<string name="activate_profile">Activate profile</string>
|
<string name="activate_profile">Activate profile</string>
|
||||||
<string name="reset">reset</string>
|
<string name="reset">reset</string>
|
||||||
|
<string name="profileswitch_ismissing">ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile.</string>
|
||||||
|
<string name="profile">Profile</string>
|
||||||
|
|
||||||
<!-- Constraints-->
|
<!-- Constraints-->
|
||||||
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>
|
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package info.nightscout.androidaps.dependencyInjection
|
package info.nightscout.plugins.di
|
||||||
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotuneCore
|
import info.nightscout.plugins.general.autotune.AutotuneCore
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotuneIob
|
import info.nightscout.plugins.general.autotune.AutotuneFS
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotunePrep
|
import info.nightscout.plugins.general.autotune.AutotuneIob
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.AutotuneFS
|
import info.nightscout.plugins.general.autotune.AutotunePrep
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.BGDatum
|
||||||
|
import info.nightscout.plugins.general.autotune.data.CRDatum
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
|
@ -6,7 +6,9 @@ import dagger.Module
|
||||||
includes = [
|
includes = [
|
||||||
InsulinModule::class,
|
InsulinModule::class,
|
||||||
FoodModule::class,
|
FoodModule::class,
|
||||||
SMSCommunicatorModule::class
|
SMSCommunicatorModule::class,
|
||||||
|
AutotuneModule::class,
|
||||||
|
ProfileModule::class
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package info.nightscout.plugins.di
|
||||||
|
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.android.ContributesAndroidInjector
|
||||||
|
import info.nightscout.plugins.profile.ProfileFragment
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@Suppress("unused")
|
||||||
|
abstract class ProfileModule {
|
||||||
|
|
||||||
|
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment
|
||||||
|
}
|
|
@ -1,15 +1,16 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
|
import info.nightscout.plugins.utils.Percentile
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class AutotuneCore @Inject constructor(
|
class AutotuneCore @Inject constructor(
|
||||||
|
@ -47,8 +48,7 @@ class AutotuneCore @Inject constructor(
|
||||||
|
|
||||||
// tune DIA
|
// tune DIA
|
||||||
var newDia = dia
|
var newDia = dia
|
||||||
if (diaDeviations.size > 0)
|
if (diaDeviations.isNotEmpty()) {
|
||||||
{
|
|
||||||
val currentDiaMeanDev = diaDeviations[2].meanDeviation
|
val currentDiaMeanDev = diaDeviations[2].meanDeviation
|
||||||
val currentDiaRMSDev = diaDeviations[2].rmsDeviation
|
val currentDiaRMSDev = diaDeviations[2].rmsDeviation
|
||||||
//Console.WriteLine(DIA,currentDIAMeanDev,currentDIARMSDev);
|
//Console.WriteLine(DIA,currentDIAMeanDev,currentDIARMSDev);
|
||||||
|
@ -56,35 +56,28 @@ class AutotuneCore @Inject constructor(
|
||||||
var minRmsDeviations = 1000000.0
|
var minRmsDeviations = 1000000.0
|
||||||
var meanBest = 2
|
var meanBest = 2
|
||||||
var rmsBest = 2
|
var rmsBest = 2
|
||||||
for (i in 0..diaDeviations.size-1)
|
for (i in diaDeviations.indices) {
|
||||||
{
|
|
||||||
val meanDeviations = diaDeviations[i].meanDeviation
|
val meanDeviations = diaDeviations[i].meanDeviation
|
||||||
val rmsDeviations = diaDeviations[i].rmsDeviation
|
val rmsDeviations = diaDeviations[i].rmsDeviation
|
||||||
if (meanDeviations < minMeanDeviations)
|
if (meanDeviations < minMeanDeviations) {
|
||||||
{
|
|
||||||
minMeanDeviations = Round.roundTo(meanDeviations, 0.001)
|
minMeanDeviations = Round.roundTo(meanDeviations, 0.001)
|
||||||
meanBest = i
|
meanBest = i
|
||||||
}
|
}
|
||||||
if (rmsDeviations < minRmsDeviations)
|
if (rmsDeviations < minRmsDeviations) {
|
||||||
{
|
|
||||||
minRmsDeviations = Round.roundTo(rmsDeviations, 0.001)
|
minRmsDeviations = Round.roundTo(rmsDeviations, 0.001)
|
||||||
rmsBest = i
|
rmsBest = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("Best insulinEndTime for meanDeviations: ${diaDeviations[meanBest].dia} hours")
|
log("Best insulinEndTime for meanDeviations: ${diaDeviations[meanBest].dia} hours")
|
||||||
log("Best insulinEndTime for RMSDeviations: ${diaDeviations[rmsBest].dia} hours")
|
log("Best insulinEndTime for RMSDeviations: ${diaDeviations[rmsBest].dia} hours")
|
||||||
if (meanBest < 2 && rmsBest < 2)
|
if (meanBest < 2 && rmsBest < 2) {
|
||||||
{
|
|
||||||
if (diaDeviations[1].meanDeviation < currentDiaMeanDev * 0.99 && diaDeviations[1].rmsDeviation < currentDiaRMSDev * 0.99)
|
if (diaDeviations[1].meanDeviation < currentDiaMeanDev * 0.99 && diaDeviations[1].rmsDeviation < currentDiaRMSDev * 0.99)
|
||||||
newDia = diaDeviations[1].dia
|
newDia = diaDeviations[1].dia
|
||||||
}
|
} else if (meanBest > 2 && rmsBest > 2) {
|
||||||
else if (meanBest > 2 && rmsBest > 2)
|
|
||||||
{
|
|
||||||
if (diaDeviations[3].meanDeviation < currentDiaMeanDev * 0.99 && diaDeviations[3].rmsDeviation < currentDiaRMSDev * 0.99)
|
if (diaDeviations[3].meanDeviation < currentDiaMeanDev * 0.99 && diaDeviations[3].rmsDeviation < currentDiaRMSDev * 0.99)
|
||||||
newDia = diaDeviations[3].dia
|
newDia = diaDeviations[3].dia
|
||||||
}
|
}
|
||||||
if (newDia > 12.0)
|
if (newDia > 12.0) {
|
||||||
{
|
|
||||||
log("insulinEndTime maximum is 12h: not raising further")
|
log("insulinEndTime maximum is 12h: not raising further")
|
||||||
newDia = 12.0
|
newDia = 12.0
|
||||||
}
|
}
|
||||||
|
@ -96,8 +89,7 @@ class AutotuneCore @Inject constructor(
|
||||||
|
|
||||||
// tune insulinPeakTime
|
// tune insulinPeakTime
|
||||||
var newPeak = peak
|
var newPeak = peak
|
||||||
if (peakDeviations.size > 2)
|
if (peakDeviations.size > 2) {
|
||||||
{
|
|
||||||
val currentPeakMeanDev = peakDeviations[2].meanDeviation
|
val currentPeakMeanDev = peakDeviations[2].meanDeviation
|
||||||
val currentPeakRMSDev = peakDeviations[2].rmsDeviation
|
val currentPeakRMSDev = peakDeviations[2].rmsDeviation
|
||||||
//Console.WriteLine(currentPeakMeanDev);
|
//Console.WriteLine(currentPeakMeanDev);
|
||||||
|
@ -105,37 +97,31 @@ class AutotuneCore @Inject constructor(
|
||||||
var minRmsDeviations = 1000000.0
|
var minRmsDeviations = 1000000.0
|
||||||
var meanBest = 2
|
var meanBest = 2
|
||||||
var rmsBest = 2
|
var rmsBest = 2
|
||||||
for (i in 0..peakDeviations.size-1)
|
for (i in peakDeviations.indices) {
|
||||||
{
|
val meanDeviations = peakDeviations[i].meanDeviation
|
||||||
val meanDeviations = peakDeviations[i].meanDeviation;
|
val rmsDeviations = peakDeviations[i].rmsDeviation
|
||||||
val rmsDeviations = peakDeviations[i].rmsDeviation;
|
if (meanDeviations < minMeanDeviations) {
|
||||||
if (meanDeviations < minMeanDeviations)
|
|
||||||
{
|
|
||||||
minMeanDeviations = Round.roundTo(meanDeviations, 0.001)
|
minMeanDeviations = Round.roundTo(meanDeviations, 0.001)
|
||||||
meanBest = i
|
meanBest = i
|
||||||
}
|
}
|
||||||
if (rmsDeviations < minRmsDeviations)
|
if (rmsDeviations < minRmsDeviations) {
|
||||||
{
|
|
||||||
minRmsDeviations = Round.roundTo(rmsDeviations, 0.001)
|
minRmsDeviations = Round.roundTo(rmsDeviations, 0.001)
|
||||||
rmsBest = i
|
rmsBest = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("Best insulinPeakTime for meanDeviations: ${peakDeviations[meanBest].peak} minutes")
|
log("Best insulinPeakTime for meanDeviations: ${peakDeviations[meanBest].peak} minutes")
|
||||||
log("Best insulinPeakTime for RMSDeviations: ${peakDeviations[rmsBest].peak} minutes")
|
log("Best insulinPeakTime for RMSDeviations: ${peakDeviations[rmsBest].peak} minutes")
|
||||||
if (meanBest < 2 && rmsBest < 2)
|
if (meanBest < 2 && rmsBest < 2) {
|
||||||
{
|
|
||||||
if (peakDeviations[1].meanDeviation < currentPeakMeanDev * 0.99 && peakDeviations[1].rmsDeviation < currentPeakRMSDev * 0.99)
|
if (peakDeviations[1].meanDeviation < currentPeakMeanDev * 0.99 && peakDeviations[1].rmsDeviation < currentPeakRMSDev * 0.99)
|
||||||
newPeak = peakDeviations[1].peak
|
newPeak = peakDeviations[1].peak
|
||||||
}
|
} else if (meanBest > 2 && rmsBest > 2) {
|
||||||
else if (meanBest > 2 && rmsBest > 2)
|
|
||||||
{
|
|
||||||
if (peakDeviations[3].meanDeviation < currentPeakMeanDev * 0.99 && peakDeviations[3].rmsDeviation < currentPeakRMSDev * 0.99)
|
if (peakDeviations[3].meanDeviation < currentPeakMeanDev * 0.99 && peakDeviations[3].rmsDeviation < currentPeakRMSDev * 0.99)
|
||||||
newPeak = peakDeviations[3].peak
|
newPeak = peakDeviations[3].peak
|
||||||
}
|
}
|
||||||
if (newPeak != peak)
|
if (newPeak != peak)
|
||||||
log("Adjusting insulinPeakTime from " + peak + " to " + newPeak + " minutes")
|
log("Adjusting insulinPeakTime from $peak to $newPeak minutes")
|
||||||
else
|
else
|
||||||
log("Leaving insulinPeakTime unchanged at " + peak)
|
log("Leaving insulinPeakTime unchanged at $peak")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate carb ratio (CR) independently of csf and isf
|
// Calculate carb ratio (CR) independently of csf and isf
|
||||||
|
@ -180,22 +166,22 @@ class AutotuneCore @Inject constructor(
|
||||||
for (i in 0..23) {
|
for (i in 0..23) {
|
||||||
newHourlyBasalProfile[i] = hourlyBasalProfile[i]
|
newHourlyBasalProfile[i] = hourlyBasalProfile[i]
|
||||||
}
|
}
|
||||||
val basalUntuned = previousAutotune.basalUntuned
|
val basalUnTuned = previousAutotune.basalUntuned
|
||||||
|
|
||||||
//autotune-core (lib/autotune/index.js) #210-#266
|
//autotune-core (lib/autotune/index.js) #210-#266
|
||||||
// look at net deviations for each hour
|
// look at net deviations for each hour
|
||||||
for (hour in 0..23) {
|
for (hour in 0..23) {
|
||||||
var deviations = 0.0
|
var deviations = 0.0
|
||||||
for (i in basalGlucose.indices) {
|
for (i in basalGlucose.indices) {
|
||||||
val BGTime = Calendar.getInstance()
|
val bgTime = Calendar.getInstance()
|
||||||
//var BGTime: Date? = null
|
//var BGTime: Date? = null
|
||||||
if (basalGlucose[i].date != 0L) {
|
if (basalGlucose[i].date != 0L) {
|
||||||
BGTime.setTimeInMillis(basalGlucose[i].date)
|
bgTime.timeInMillis = basalGlucose[i].date
|
||||||
//BGTime = Date(basalGlucose[i].date)
|
//BGTime = Date(basalGlucose[i].date)
|
||||||
} else {
|
} else {
|
||||||
log("Could not determine last BG time")
|
log("Could not determine last BG time")
|
||||||
}
|
}
|
||||||
val myHour = BGTime.get(Calendar.HOUR_OF_DAY)
|
val myHour = bgTime.get(Calendar.HOUR_OF_DAY)
|
||||||
//val myHour = BGTime!!.hours
|
//val myHour = BGTime!!.hours
|
||||||
if (hour == myHour) {
|
if (hour == myHour) {
|
||||||
//log.debug(basalGlucose[i].deviation);
|
//log.debug(basalGlucose[i].deviation);
|
||||||
|
@ -280,7 +266,7 @@ class AutotuneCore @Inject constructor(
|
||||||
}
|
}
|
||||||
//log.debug(hour, newHourlyBasalProfile);
|
//log.debug(hour, newHourlyBasalProfile);
|
||||||
newHourlyBasalProfile[hour] = Round.roundTo(0.8 * hourlyBasalProfile[hour] + 0.1 * newHourlyBasalProfile[lastAdjustedHour] + 0.1 * newHourlyBasalProfile[nextAdjustedHour], 0.001)
|
newHourlyBasalProfile[hour] = Round.roundTo(0.8 * hourlyBasalProfile[hour] + 0.1 * newHourlyBasalProfile[lastAdjustedHour] + 0.1 * newHourlyBasalProfile[nextAdjustedHour], 0.001)
|
||||||
basalUntuned[hour]++
|
basalUnTuned[hour]++
|
||||||
log("Adjusting hour " + hour + " basal from " + hourlyBasalProfile[hour] + " to " + newHourlyBasalProfile[hour] + " based on hour " + lastAdjustedHour + " = " + newHourlyBasalProfile[lastAdjustedHour] + " and hour " + nextAdjustedHour + " = " + newHourlyBasalProfile[nextAdjustedHour])
|
log("Adjusting hour " + hour + " basal from " + hourlyBasalProfile[hour] + " to " + newHourlyBasalProfile[hour] + " based on hour " + lastAdjustedHour + " = " + newHourlyBasalProfile[lastAdjustedHour] + " and hour " + nextAdjustedHour + " = " + newHourlyBasalProfile[nextAdjustedHour])
|
||||||
} else {
|
} else {
|
||||||
lastAdjustedHour = hour
|
lastAdjustedHour = hour
|
||||||
|
@ -301,7 +287,6 @@ class AutotuneCore @Inject constructor(
|
||||||
var mealCarbs = 0
|
var mealCarbs = 0
|
||||||
var totalMealCarbs = 0
|
var totalMealCarbs = 0
|
||||||
var totalDeviations = 0.0
|
var totalDeviations = 0.0
|
||||||
val fullNewCSF: Double
|
|
||||||
//log.debug(CSFGlucose[0].mealAbsorption);
|
//log.debug(CSFGlucose[0].mealAbsorption);
|
||||||
//log.debug(CSFGlucose[0]);
|
//log.debug(CSFGlucose[0]);
|
||||||
//autotune-core (lib/autotune/index.js) #346-#365
|
//autotune-core (lib/autotune/index.js) #346-#365
|
||||||
|
@ -321,8 +306,8 @@ class AutotuneCore @Inject constructor(
|
||||||
totalDeviations += deviations
|
totalDeviations += deviations
|
||||||
} else {
|
} else {
|
||||||
//todo Philoul check 0 * min5minCarbImpact ???
|
//todo Philoul check 0 * min5minCarbImpact ???
|
||||||
deviations += Math.max(0 * min5minCarbImpact, csfGlucose[i].deviation)
|
deviations += max(0 * min5minCarbImpact, csfGlucose[i].deviation)
|
||||||
mealCarbs = Math.max(mealCarbs, csfGlucose[i].mealCarbs)
|
mealCarbs = max(mealCarbs, csfGlucose[i].mealCarbs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// at midnight, write down the mealcarbs as total meal carbs (to prevent special case of when only one meal and it not finishing absorbing by midnight)
|
// at midnight, write down the mealcarbs as total meal carbs (to prevent special case of when only one meal and it not finishing absorbing by midnight)
|
||||||
|
@ -334,7 +319,7 @@ class AutotuneCore @Inject constructor(
|
||||||
totalDeviations += deviations
|
totalDeviations += deviations
|
||||||
}
|
}
|
||||||
//log.debug(totalDeviations, totalMealCarbs);
|
//log.debug(totalDeviations, totalMealCarbs);
|
||||||
fullNewCSF = if (totalMealCarbs == 0) {
|
val fullNewCSF: Double = if (totalMealCarbs == 0) {
|
||||||
// if no meals today, csf is unchanged
|
// if no meals today, csf is unchanged
|
||||||
csf
|
csf
|
||||||
} else {
|
} else {
|
||||||
|
@ -420,22 +405,22 @@ class AutotuneCore @Inject constructor(
|
||||||
for (i in isfGlucose.indices) {
|
for (i in isfGlucose.indices) {
|
||||||
val deviation = isfGlucose[i].deviation
|
val deviation = isfGlucose[i].deviation
|
||||||
isfDeviations.add(deviation)
|
isfDeviations.add(deviation)
|
||||||
val BGI = isfGlucose[i].bgi
|
val bgi = isfGlucose[i].bgi
|
||||||
bGIs.add(BGI)
|
bGIs.add(bgi)
|
||||||
val avgDelta = isfGlucose[i].avgDelta
|
val avgDelta = isfGlucose[i].avgDelta
|
||||||
avgDeltas.add(avgDelta)
|
avgDeltas.add(avgDelta)
|
||||||
val ratio = 1 + deviation / BGI
|
val ratio = 1 + deviation / bgi
|
||||||
//log.debug("Deviation:",deviation,"BGI:",BGI,"avgDelta:",avgDelta,"ratio:",ratio);
|
//log.debug("Deviation:",deviation,"BGI:",BGI,"avgDelta:",avgDelta,"ratio:",ratio);
|
||||||
ratios.add(ratio)
|
ratios.add(ratio)
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
Collections.sort(avgDeltas)
|
avgDeltas.sort()
|
||||||
Collections.sort(bGIs)
|
bGIs.sort()
|
||||||
Collections.sort(isfDeviations)
|
isfDeviations.sort()
|
||||||
Collections.sort(ratios)
|
ratios.sort()
|
||||||
var p50deviation = IobCobCalculatorPlugin.percentile(isfDeviations.toTypedArray(), 0.50)
|
var p50deviation = Percentile.percentile(isfDeviations.toTypedArray(), 0.50)
|
||||||
var p50BGI = IobCobCalculatorPlugin.percentile(bGIs.toTypedArray(), 0.50)
|
var p50BGI = Percentile.percentile(bGIs.toTypedArray(), 0.50)
|
||||||
val p50ratios = Round.roundTo(IobCobCalculatorPlugin.percentile(ratios.toTypedArray(), 0.50), 0.001)
|
val p50ratios = Round.roundTo(Percentile.percentile(ratios.toTypedArray(), 0.50), 0.001)
|
||||||
var fullNewISF = isf
|
var fullNewISF = isf
|
||||||
if (count < 10) {
|
if (count < 10) {
|
||||||
// leave isf unchanged if fewer than 5 isf data points
|
// leave isf unchanged if fewer than 5 isf data points
|
||||||
|
@ -446,13 +431,12 @@ class AutotuneCore @Inject constructor(
|
||||||
}
|
}
|
||||||
fullNewISF = Round.roundTo(fullNewISF, 0.001)
|
fullNewISF = Round.roundTo(fullNewISF, 0.001)
|
||||||
// adjust the target isf to be a weighted average of fullNewISF and pumpISF
|
// adjust the target isf to be a weighted average of fullNewISF and pumpISF
|
||||||
val adjustmentFraction: Double
|
|
||||||
/*
|
/*
|
||||||
// TODO: philoul may be allow adjustmentFraction in settings with safety limits ?)
|
// TODO: philoul may be allow adjustmentFraction in settings with safety limits ?)
|
||||||
if (typeof(pumpProfile.autotune_isf_adjustmentFraction) !== 'undefined') {
|
if (typeof(pumpProfile.autotune_isf_adjustmentFraction) !== 'undefined') {
|
||||||
adjustmentFraction = pumpProfile.autotune_isf_adjustmentFraction;
|
adjustmentFraction = pumpProfile.autotune_isf_adjustmentFraction;
|
||||||
} else {*/
|
} else {*/
|
||||||
adjustmentFraction = 1.0
|
val adjustmentFraction = 1.0
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// low autosens ratio = high isf
|
// low autosens ratio = high isf
|
||||||
|
@ -501,7 +485,7 @@ class AutotuneCore @Inject constructor(
|
||||||
previousAutotune.basal = basalProfile
|
previousAutotune.basal = basalProfile
|
||||||
previousAutotune.isf = isf
|
previousAutotune.isf = isf
|
||||||
previousAutotune.ic = Round.roundTo(carbRatio, 0.001)
|
previousAutotune.ic = Round.roundTo(carbRatio, 0.001)
|
||||||
previousAutotune.basalUntuned = basalUntuned
|
previousAutotune.basalUntuned = basalUnTuned
|
||||||
previousAutotune.dia = newDia
|
previousAutotune.dia = newDia
|
||||||
previousAutotune.peak = newPeak
|
previousAutotune.peak = newPeak
|
||||||
val localInsulin = LocalInsulin("Ins_$newPeak-$newDia", newPeak, newDia)
|
val localInsulin = LocalInsulin("Ins_$newPeak-$newDia", newPeak, newDia)
|
|
@ -1,13 +1,21 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
import info.nightscout.plugins.R
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.plugins.general.maintenance.LoggerUtils
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.*
|
import java.io.BufferedInputStream
|
||||||
|
import java.io.BufferedOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.FileWriter
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.PrintWriter
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
@ -28,7 +36,6 @@ class AutotuneFS @Inject constructor(
|
||||||
val AAPSBOLUSESPREF = "aaps-boluses."
|
val AAPSBOLUSESPREF = "aaps-boluses."
|
||||||
val PREPPEDPREF = "aaps-autotune."
|
val PREPPEDPREF = "aaps-autotune."
|
||||||
val SETTINGS = "settings.json"
|
val SETTINGS = "settings.json"
|
||||||
val PROFIL = "profil"
|
|
||||||
val PUMPPROFILE = "pumpprofile.json"
|
val PUMPPROFILE = "pumpprofile.json"
|
||||||
val TUNEDPROFILE = "newaapsprofile."
|
val TUNEDPROFILE = "newaapsprofile."
|
||||||
val LOGPREF = "autotune."
|
val LOGPREF = "autotune."
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
@ -20,12 +20,10 @@ import android.widget.TextView
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.data.ProfileSealed
|
import info.nightscout.androidaps.data.ProfileSealed
|
||||||
import info.nightscout.androidaps.database.entities.UserEntry
|
import info.nightscout.androidaps.database.entities.UserEntry
|
||||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||||
import info.nightscout.androidaps.databinding.AutotuneFragmentBinding
|
|
||||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||||
import info.nightscout.androidaps.extensions.runOnUiThread
|
import info.nightscout.androidaps.extensions.runOnUiThread
|
||||||
import info.nightscout.androidaps.extensions.toVisibility
|
import info.nightscout.androidaps.extensions.toVisibility
|
||||||
|
@ -37,16 +35,18 @@ import info.nightscout.androidaps.interfaces.ProfileStore
|
||||||
import info.nightscout.androidaps.interfaces.ResourceHelper
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui
|
|
||||||
import info.nightscout.plugins.profile.ProfilePlugin
|
|
||||||
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.MidnightTime
|
import info.nightscout.androidaps.utils.MidnightTime
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.databinding.AutotuneFragmentBinding
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.events.EventAutotuneUpdateGui
|
||||||
|
import info.nightscout.plugins.profile.ProfilePlugin
|
||||||
|
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
|
||||||
import info.nightscout.shared.SafeParse
|
import info.nightscout.shared.SafeParse
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
@ -126,7 +126,7 @@ class AutotuneFragment : DaggerFragment() {
|
||||||
updateGui()
|
updateGui()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.autotuneCopylocal.setOnClickListener {
|
binding.autotuneCopyLocal.setOnClickListener {
|
||||||
val localName = rh.gs(R.string.autotune_tunedprofile_name) + " " + dateUtil.dateAndTimeString(autotunePlugin.lastRun)
|
val localName = rh.gs(R.string.autotune_tunedprofile_name) + " " + dateUtil.dateAndTimeString(autotunePlugin.lastRun)
|
||||||
val circadian = sp.getBoolean(R.string.key_autotune_circadian_ic_isf, false)
|
val circadian = sp.getBoolean(R.string.key_autotune_circadian_ic_isf, false)
|
||||||
autotunePlugin.tunedProfile?.let { tunedProfile ->
|
autotunePlugin.tunedProfile?.let { tunedProfile ->
|
||||||
|
@ -265,14 +265,14 @@ class AutotuneFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tuneLastrun.setOnClickListener {
|
binding.tuneLastRun.setOnClickListener {
|
||||||
if (!autotunePlugin.calculationRunning) {
|
if (!autotunePlugin.calculationRunning) {
|
||||||
autotunePlugin.loadLastRun()
|
autotunePlugin.loadLastRun()
|
||||||
binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble()
|
binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble()
|
||||||
updateGui()
|
updateGui()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.tuneLastrun.paintFlags = binding.tuneLastrun.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
binding.tuneLastRun.paintFlags = binding.tuneLastRun.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -315,7 +315,7 @@ class AutotuneFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
binding.autotuneRun.visibility = View.GONE
|
binding.autotuneRun.visibility = View.GONE
|
||||||
binding.autotuneCheckInputProfile.visibility = View.GONE
|
binding.autotuneCheckInputProfile.visibility = View.GONE
|
||||||
binding.autotuneCopylocal.visibility = View.GONE
|
binding.autotuneCopyLocal.visibility = View.GONE
|
||||||
binding.autotuneUpdateProfile.visibility = View.GONE
|
binding.autotuneUpdateProfile.visibility = View.GONE
|
||||||
binding.autotuneRevertProfile.visibility = View.GONE
|
binding.autotuneRevertProfile.visibility = View.GONE
|
||||||
binding.autotuneProfileswitch.visibility = View.GONE
|
binding.autotuneProfileswitch.visibility = View.GONE
|
||||||
|
@ -326,7 +326,7 @@ class AutotuneFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
autotunePlugin.lastRunSuccess -> {
|
autotunePlugin.lastRunSuccess -> {
|
||||||
binding.autotuneCopylocal.visibility = View.VISIBLE
|
binding.autotuneCopyLocal.visibility = View.VISIBLE
|
||||||
binding.autotuneUpdateProfile.visibility = autotunePlugin.updateButtonVisibility
|
binding.autotuneUpdateProfile.visibility = autotunePlugin.updateButtonVisibility
|
||||||
binding.autotuneRevertProfile.visibility = if (autotunePlugin.updateButtonVisibility == View.VISIBLE) View.GONE else View.VISIBLE
|
binding.autotuneRevertProfile.visibility = if (autotunePlugin.updateButtonVisibility == View.VISIBLE) View.GONE else View.VISIBLE
|
||||||
binding.autotuneProfileswitch.visibility = View.VISIBLE
|
binding.autotuneProfileswitch.visibility = View.VISIBLE
|
||||||
|
@ -339,7 +339,7 @@ class AutotuneFragment : DaggerFragment() {
|
||||||
binding.autotuneCheckInputProfile.visibility = View.VISIBLE
|
binding.autotuneCheckInputProfile.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.tuneLastrun.text = dateUtil.dateAndTimeString(autotunePlugin.lastRun)
|
binding.tuneLastRun.text = dateUtil.dateAndTimeString(autotunePlugin.lastRun)
|
||||||
showResults()
|
showResults()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,32 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
||||||
import info.nightscout.androidaps.database.entities.*
|
import info.nightscout.androidaps.database.entities.Bolus
|
||||||
|
import info.nightscout.androidaps.database.entities.Carbs
|
||||||
|
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.TherapyEvent
|
||||||
import info.nightscout.androidaps.extensions.durationInMinutes
|
import info.nightscout.androidaps.extensions.durationInMinutes
|
||||||
import info.nightscout.androidaps.extensions.iobCalc
|
import info.nightscout.androidaps.extensions.iobCalc
|
||||||
import info.nightscout.androidaps.extensions.toJson
|
import info.nightscout.androidaps.extensions.toJson
|
||||||
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
@ -44,7 +47,7 @@ open class AutotuneIob @Inject constructor(
|
||||||
lateinit var glucose: List<GlucoseValue> // newest at index 0
|
lateinit var glucose: List<GlucoseValue> // newest at index 0
|
||||||
private lateinit var tempBasals: ArrayList<TemporaryBasal>
|
private lateinit var tempBasals: ArrayList<TemporaryBasal>
|
||||||
var startBG: Long = 0
|
var startBG: Long = 0
|
||||||
var endBG: Long = 0
|
private var endBG: Long = 0
|
||||||
private fun range(): Long = (60 * 60 * 1000L * dia + T.hours(2).msecs()).toLong()
|
private fun range(): Long = (60 * 60 * 1000L * dia + T.hours(2).msecs()).toLong()
|
||||||
|
|
||||||
fun initializeData(from: Long, to: Long, tunedProfile: ATProfile) {
|
fun initializeData(from: Long, to: Long, tunedProfile: ATProfile) {
|
||||||
|
@ -236,11 +239,10 @@ open class AutotuneIob @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
open fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||||
val bolusIob = getCalculationToTimeTreatments(time, localInsulin).round()
|
return getCalculationToTimeTreatments(time, localInsulin).round()
|
||||||
return bolusIob
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCalculationToTimeTreatments(time: Long, localInsulin: LocalInsulin): IobTotal {
|
private fun getCalculationToTimeTreatments(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||||
val total = IobTotal(time)
|
val total = IobTotal(time)
|
||||||
val detailedLog = sp.getBoolean(R.string.key_autotune_additional_log, false)
|
val detailedLog = sp.getBoolean(R.string.key_autotune_additional_log, false)
|
||||||
for (pos in boluses.indices) {
|
for (pos in boluses.indices) {
|
||||||
|
@ -257,7 +259,7 @@ open class AutotuneIob @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun convertToBoluses(eb: ExtendedBolus): MutableList<Bolus> {
|
private fun convertToBoluses(eb: ExtendedBolus): MutableList<Bolus> {
|
||||||
val result: MutableList<Bolus> = ArrayList()
|
val result: MutableList<Bolus> = ArrayList()
|
||||||
val aboutFiveMinIntervals = ceil(eb.duration / 5.0).toInt()
|
val aboutFiveMinIntervals = ceil(eb.duration / 5.0).toInt()
|
||||||
val spacing = eb.duration / aboutFiveMinIntervals.toDouble()
|
val spacing = eb.duration / aboutFiveMinIntervals.toDouble()
|
||||||
|
@ -277,7 +279,7 @@ open class AutotuneIob @Inject constructor(
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertToBoluses(tbr: TemporaryBasal, profile: Profile, tunedProfile: Profile): MutableList<Bolus> {
|
private fun convertToBoluses(tbr: TemporaryBasal, profile: Profile, tunedProfile: Profile): MutableList<Bolus> {
|
||||||
val result: MutableList<Bolus> = ArrayList()
|
val result: MutableList<Bolus> = ArrayList()
|
||||||
val realDuration = tbr.durationInMinutes
|
val realDuration = tbr.durationInMinutes
|
||||||
val basalRate = profile.getBasal(tbr.timestamp)
|
val basalRate = profile.getBasal(tbr.timestamp)
|
|
@ -1,32 +1,41 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.data.ProfileSealed
|
import info.nightscout.androidaps.data.ProfileSealed
|
||||||
import info.nightscout.androidaps.database.entities.UserEntry
|
import info.nightscout.androidaps.database.entities.UserEntry
|
||||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
import info.nightscout.androidaps.interfaces.Autotune
|
||||||
|
import info.nightscout.androidaps.interfaces.BuildHelper
|
||||||
|
import info.nightscout.androidaps.interfaces.Insulin
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
|
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneUpdateGui
|
|
||||||
import info.nightscout.plugins.profile.ProfilePlugin
|
|
||||||
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.JsonHelper
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import info.nightscout.androidaps.utils.MidnightTime
|
import info.nightscout.androidaps.utils.MidnightTime
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.interfaces.BuildHelper
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
|
import info.nightscout.plugins.general.autotune.events.EventAutotuneUpdateGui
|
||||||
|
import info.nightscout.plugins.profile.ProfilePlugin
|
||||||
|
import info.nightscout.plugins.profile.events.EventLocalProfileChanged
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.shared.logging.LTag
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.TimeZone
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -54,7 +63,8 @@ class AutotunePlugin @Inject constructor(
|
||||||
private val buildHelper: BuildHelper,
|
private val buildHelper: BuildHelper,
|
||||||
private val uel: UserEntryLogger,
|
private val uel: UserEntryLogger,
|
||||||
aapsLogger: AAPSLogger
|
aapsLogger: AAPSLogger
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(
|
||||||
|
PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
.fragmentClass(AutotuneFragment::class.qualifiedName)
|
.fragmentClass(AutotuneFragment::class.qualifiedName)
|
||||||
.pluginIcon(R.drawable.ic_autotune)
|
.pluginIcon(R.drawable.ic_autotune)
|
||||||
|
@ -65,6 +75,7 @@ class AutotunePlugin @Inject constructor(
|
||||||
.description(R.string.autotune_description),
|
.description(R.string.autotune_description),
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), Autotune {
|
), Autotune {
|
||||||
|
|
||||||
@Volatile override var lastRunSuccess: Boolean = false
|
@Volatile override var lastRunSuccess: Boolean = false
|
||||||
@Volatile var result: String = ""
|
@Volatile var result: String = ""
|
||||||
@Volatile override var calculationRunning: Boolean = false
|
@Volatile override var calculationRunning: Boolean = false
|
||||||
|
@ -106,7 +117,7 @@ class AutotunePlugin @Inject constructor(
|
||||||
calculationRunning = false
|
calculationRunning = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selectedProfile = if (profileToTune.isEmpty()) profileFunction.getProfileName() else profileToTune
|
selectedProfile = profileToTune.ifEmpty { profileFunction.getProfileName() }
|
||||||
profileFunction.getProfile()?.let { currentProfile ->
|
profileFunction.getProfile()?.let { currentProfile ->
|
||||||
profile = profileStore.getSpecificProfile(profileToTune)?.let { ProfileSealed.Pure(it) } ?: currentProfile
|
profile = profileStore.getSpecificProfile(profileToTune)?.let { ProfileSealed.Pure(it) } ?: currentProfile
|
||||||
}
|
}
|
||||||
|
@ -132,7 +143,7 @@ class AutotunePlugin @Inject constructor(
|
||||||
val from = starttime + i * 24 * 60 * 60 * 1000L // get 24 hours BG values from 4 AM to 4 AM next day
|
val from = starttime + i * 24 * 60 * 60 * 1000L // get 24 hours BG values from 4 AM to 4 AM next day
|
||||||
val to = from + 24 * 60 * 60 * 1000L
|
val to = from + 24 * 60 * 60 * 1000L
|
||||||
log("Tune day " + (i + 1) + " of " + daysBack)
|
log("Tune day " + (i + 1) + " of " + daysBack)
|
||||||
tunedProfile?.let { it ->
|
tunedProfile?.let {
|
||||||
autotuneIob.initializeData(from, to, it) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries)
|
autotuneIob.initializeData(from, to, it) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries)
|
||||||
if (autotuneIob.boluses.size == 0) {
|
if (autotuneIob.boluses.size == 0) {
|
||||||
result = rh.gs(R.string.autotune_error)
|
result = rh.gs(R.string.autotune_error)
|
||||||
|
@ -209,7 +220,8 @@ class AutotunePlugin @Inject constructor(
|
||||||
UserEntry.Action.PROFILE_SWITCH,
|
UserEntry.Action.PROFILE_SWITCH,
|
||||||
UserEntry.Sources.Automation,
|
UserEntry.Sources.Automation,
|
||||||
rh.gs(R.string.autotune),
|
rh.gs(R.string.autotune),
|
||||||
ValueWithUnit.SimpleString(tunedP.profilename))
|
ValueWithUnit.SimpleString(tunedP.profilename)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
rxBus.send(EventLocalProfileChanged())
|
rxBus.send(EventLocalProfileChanged())
|
||||||
}
|
}
|
||||||
|
@ -265,8 +277,8 @@ class AutotunePlugin @Inject constructor(
|
||||||
val jsonSettings = JSONObject()
|
val jsonSettings = JSONObject()
|
||||||
val insulinInterface = activePlugin.activeInsulin
|
val insulinInterface = activePlugin.activeInsulin
|
||||||
val utcOffset = T.msecs(TimeZone.getDefault().getOffset(dateUtil.now()).toLong()).hours()
|
val utcOffset = T.msecs(TimeZone.getDefault().getOffset(dateUtil.now()).toLong()).hours()
|
||||||
val startDateString = dateUtil.toISOString(firstloopstart).substring(0,10)
|
val startDateString = dateUtil.toISOString(firstloopstart).substring(0, 10)
|
||||||
val endDateString = dateUtil.toISOString(lastloopend - 24 * 60 * 60 * 1000L).substring(0,10)
|
val endDateString = dateUtil.toISOString(lastloopend - 24 * 60 * 60 * 1000L).substring(0, 10)
|
||||||
val nsUrl = sp.getString(R.string.key_nsclientinternal_url, "")
|
val nsUrl = sp.getString(R.string.key_nsclientinternal_url, "")
|
||||||
val optCategorizeUam = if (sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)) "-c=true" else ""
|
val optCategorizeUam = if (sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)) "-c=true" else ""
|
||||||
val optInsulinCurve = if (sp.getBoolean(R.string.key_autotune_tune_insulin_curve, false)) "-i=true" else ""
|
val optInsulinCurve = if (sp.getBoolean(R.string.key_autotune_tune_insulin_curve, false)) "-i=true" else ""
|
||||||
|
@ -291,7 +303,7 @@ class AutotunePlugin @Inject constructor(
|
||||||
|
|
||||||
val peaktime: Int = insulinInterface.peak
|
val peaktime: Int = insulinInterface.peak
|
||||||
if (insulinInterface.id === Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING)
|
if (insulinInterface.id === Insulin.InsulinType.OREF_ULTRA_RAPID_ACTING)
|
||||||
jsonSettings.put("curve","ultra-rapid")
|
jsonSettings.put("curve", "ultra-rapid")
|
||||||
else if (insulinInterface.id === Insulin.InsulinType.OREF_RAPID_ACTING)
|
else if (insulinInterface.id === Insulin.InsulinType.OREF_RAPID_ACTING)
|
||||||
jsonSettings.put("curve", "rapid-acting")
|
jsonSettings.put("curve", "rapid-acting")
|
||||||
else if (insulinInterface.id === Insulin.InsulinType.OREF_LYUMJEV) {
|
else if (insulinInterface.id === Insulin.InsulinType.OREF_LYUMJEV) {
|
||||||
|
@ -304,7 +316,9 @@ class AutotunePlugin @Inject constructor(
|
||||||
jsonSettings.put("insulinPeakTime", peaktime)
|
jsonSettings.put("insulinPeakTime", peaktime)
|
||||||
}
|
}
|
||||||
jsonString = jsonSettings.toString(4).replace("\\/", "/")
|
jsonString = jsonSettings.toString(4).replace("\\/", "/")
|
||||||
} catch (e: JSONException) { }
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error(LTag.AUTOTUNE, e.localizedMessage ?: e.toString())
|
||||||
|
}
|
||||||
return jsonString
|
return jsonString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +346,7 @@ class AutotunePlugin @Inject constructor(
|
||||||
fun saveLastRun() {
|
fun saveLastRun() {
|
||||||
val json = JSONObject()
|
val json = JSONObject()
|
||||||
json.put("lastNbDays", lastNbDays)
|
json.put("lastNbDays", lastNbDays)
|
||||||
json.put("lastRun",lastRun)
|
json.put("lastRun", lastRun)
|
||||||
json.put("pumpProfile", pumpProfile.profile.toPureNsJson(dateUtil))
|
json.put("pumpProfile", pumpProfile.profile.toPureNsJson(dateUtil))
|
||||||
json.put("pumpProfileName", pumpProfile.profilename)
|
json.put("pumpProfileName", pumpProfile.profilename)
|
||||||
json.put("pumpPeak", pumpProfile.peak)
|
json.put("pumpPeak", pumpProfile.peak)
|
||||||
|
@ -378,13 +392,14 @@ class AutotunePlugin @Inject constructor(
|
||||||
atProfile.profilename = tunedProfileName
|
atProfile.profilename = tunedProfileName
|
||||||
atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned)
|
atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned)
|
||||||
for (i in 0..23) {
|
for (i in 0..23) {
|
||||||
atProfile.basalUntuned[i] = JsonHelper.safeGetInt(json,"missingDays_$i")
|
atProfile.basalUntuned[i] = JsonHelper.safeGetInt(json, "missingDays_$i")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = JsonHelper.safeGetString(json, "result", "")
|
result = JsonHelper.safeGetString(json, "result", "")
|
||||||
updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility")
|
updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility")
|
||||||
lastRunSuccess = true
|
lastRunSuccess = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
aapsLogger.error(LTag.AUTOTUNE, e.localizedMessage ?: e.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,71 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
|
||||||
import info.nightscout.androidaps.database.entities.Bolus
|
import info.nightscout.androidaps.database.entities.Bolus
|
||||||
import info.nightscout.androidaps.database.entities.Carbs
|
import info.nightscout.androidaps.database.entities.Carbs
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.MidnightTime
|
import info.nightscout.androidaps.utils.MidnightTime
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.plugins.R
|
||||||
import info.nightscout.shared.logging.LTag
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.BGDatum
|
||||||
|
import info.nightscout.plugins.general.autotune.data.CRDatum
|
||||||
|
import info.nightscout.plugins.general.autotune.data.DiaDeviation
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PeakDeviation
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class AutotunePrep @Inject constructor(
|
class AutotunePrep @Inject constructor(
|
||||||
private val aapsLogger: AAPSLogger,
|
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val autotuneFS: AutotuneFS,
|
private val autotuneFS: AutotuneFS,
|
||||||
private val autotuneIob: AutotuneIob
|
private val autotuneIob: AutotuneIob
|
||||||
) {
|
) {
|
||||||
fun categorize(tunedprofile: ATProfile): PreppedGlucose? {
|
|
||||||
val preppedGlucose = categorizeBGDatums(tunedprofile, tunedprofile.localInsulin)
|
fun categorize(tunedProfile: ATProfile): PreppedGlucose? {
|
||||||
|
val preppedGlucose = categorizeBGDatums(tunedProfile, tunedProfile.localInsulin)
|
||||||
val tuneInsulin = sp.getBoolean(R.string.key_autotune_tune_insulin_curve, false)
|
val tuneInsulin = sp.getBoolean(R.string.key_autotune_tune_insulin_curve, false)
|
||||||
if (tuneInsulin) {
|
if (tuneInsulin) {
|
||||||
var minDeviations = 1000000.0
|
var minDeviations = 1000000.0
|
||||||
val diaDeviations: MutableList<DiaDeviation> = ArrayList()
|
val diaDeviations: MutableList<DiaDeviation> = ArrayList()
|
||||||
val peakDeviations: MutableList<PeakDeviation> = ArrayList()
|
val peakDeviations: MutableList<PeakDeviation> = ArrayList()
|
||||||
val currentDIA = tunedprofile.localInsulin.dia
|
val currentDIA = tunedProfile.localInsulin.dia
|
||||||
val currentPeak = tunedprofile.localInsulin.peak
|
val currentPeak = tunedProfile.localInsulin.peak
|
||||||
|
|
||||||
var dia = currentDIA - 2
|
var dia = currentDIA - 2
|
||||||
val endDIA = currentDIA + 2
|
val endDIA = currentDIA + 2
|
||||||
while (dia <= endDIA)
|
while (dia <= endDIA) {
|
||||||
{
|
|
||||||
var sqrtDeviations = 0.0
|
var sqrtDeviations = 0.0
|
||||||
var deviations = 0.0
|
var deviations = 0.0
|
||||||
var deviationsSq = 0.0
|
var deviationsSq = 0.0
|
||||||
val localInsulin = LocalInsulin("Ins_$currentPeak-$dia", currentPeak, dia)
|
val localInsulin = LocalInsulin("Ins_$currentPeak-$dia", currentPeak, dia)
|
||||||
val curve_output = categorizeBGDatums(tunedprofile, localInsulin, false)
|
val curveOutput = categorizeBGDatums(tunedProfile, localInsulin, false)
|
||||||
val basalGlucose = curve_output?.basalGlucoseData
|
val basalGlucose = curveOutput?.basalGlucoseData
|
||||||
|
|
||||||
basalGlucose?.let {
|
basalGlucose?.let {
|
||||||
for (hour in 0..23) {
|
for (hour in 0..23) {
|
||||||
for (i in 0..(basalGlucose.size-1)) {
|
for (i in basalGlucose.indices) {
|
||||||
val myHour = ((basalGlucose[i].date - MidnightTime.calc(basalGlucose[i].date)) / T.hours(1).msecs()).toInt()
|
val myHour = ((basalGlucose[i].date - MidnightTime.calc(basalGlucose[i].date)) / T.hours(1).msecs()).toInt()
|
||||||
if (hour == myHour) {
|
if (hour == myHour) {
|
||||||
sqrtDeviations += Math.pow(Math.abs(basalGlucose[i].deviation), 0.5)
|
sqrtDeviations += abs(basalGlucose[i].deviation).pow(0.5)
|
||||||
deviations += Math.abs(basalGlucose[i].deviation)
|
deviations += abs(basalGlucose[i].deviation)
|
||||||
deviationsSq += Math.pow(basalGlucose[i].deviation, 2.0)
|
deviationsSq += basalGlucose[i].deviation.pow(2.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val meanDeviation = Round.roundTo(Math.abs(deviations / basalGlucose.size), 0.001)
|
val meanDeviation = Round.roundTo(abs(deviations / basalGlucose.size), 0.001)
|
||||||
val smrDeviation = Round.roundTo(Math.pow(sqrtDeviations / basalGlucose.size, 2.0), 0.001)
|
val smrDeviation = Round.roundTo((sqrtDeviations / basalGlucose.size).pow(2.0), 0.001)
|
||||||
val rmsDeviation = Round.roundTo(Math.pow(deviationsSq / basalGlucose.size, 0.5), 0.001)
|
val rmsDeviation = Round.roundTo((deviationsSq / basalGlucose.size).pow(0.5), 0.001)
|
||||||
log("insulinEndTime $dia meanDeviation: $meanDeviation SMRDeviation: $smrDeviation RMSDeviation: $rmsDeviation (mg/dL)")
|
log("insulinEndTime $dia meanDeviation: $meanDeviation SMRDeviation: $smrDeviation RMSDeviation: $rmsDeviation (mg/dL)")
|
||||||
diaDeviations.add(
|
diaDeviations.add(
|
||||||
DiaDeviation(
|
DiaDeviation(
|
||||||
|
@ -85,31 +90,30 @@ class AutotunePrep @Inject constructor(
|
||||||
minDeviations = 1000000.0
|
minDeviations = 1000000.0
|
||||||
var peak = currentPeak - 10
|
var peak = currentPeak - 10
|
||||||
val endPeak = currentPeak + 10
|
val endPeak = currentPeak + 10
|
||||||
while (peak <= endPeak)
|
while (peak <= endPeak) {
|
||||||
{
|
|
||||||
var sqrtDeviations = 0.0
|
var sqrtDeviations = 0.0
|
||||||
var deviations = 0.0
|
var deviations = 0.0
|
||||||
var deviationsSq = 0.0
|
var deviationsSq = 0.0
|
||||||
val localInsulin = LocalInsulin("Ins_$peak-$currentDIA", peak, currentDIA)
|
val localInsulin = LocalInsulin("Ins_$peak-$currentDIA", peak, currentDIA)
|
||||||
val curve_output = categorizeBGDatums(tunedprofile, localInsulin, false)
|
val curveOutput = categorizeBGDatums(tunedProfile, localInsulin, false)
|
||||||
val basalGlucose = curve_output?.basalGlucoseData
|
val basalGlucose = curveOutput?.basalGlucoseData
|
||||||
|
|
||||||
basalGlucose?.let {
|
basalGlucose?.let {
|
||||||
for (hour in 0..23) {
|
for (hour in 0..23) {
|
||||||
for (i in 0..(basalGlucose.size - 1)) {
|
for (i in basalGlucose.indices) {
|
||||||
val myHour = ((basalGlucose[i].date - MidnightTime.calc(basalGlucose[i].date)) / T.hours(1).msecs()).toInt()
|
val myHour = ((basalGlucose[i].date - MidnightTime.calc(basalGlucose[i].date)) / T.hours(1).msecs()).toInt()
|
||||||
if (hour == myHour) {
|
if (hour == myHour) {
|
||||||
//console.error(basalGlucose[i].deviation);
|
//console.error(basalGlucose[i].deviation);
|
||||||
sqrtDeviations += Math.pow(Math.abs(basalGlucose[i].deviation), 0.5)
|
sqrtDeviations += abs(basalGlucose[i].deviation).pow(0.5)
|
||||||
deviations += Math.abs(basalGlucose[i].deviation)
|
deviations += abs(basalGlucose[i].deviation)
|
||||||
deviationsSq += Math.pow(basalGlucose[i].deviation, 2.0)
|
deviationsSq += basalGlucose[i].deviation.pow(2.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val meanDeviation = Round.roundTo(deviations / basalGlucose.size, 0.001)
|
val meanDeviation = Round.roundTo(deviations / basalGlucose.size, 0.001)
|
||||||
val smrDeviation = Round.roundTo(Math.pow(sqrtDeviations / basalGlucose.size, 2.0), 0.001)
|
val smrDeviation = Round.roundTo((sqrtDeviations / basalGlucose.size).pow(2.0), 0.001)
|
||||||
val rmsDeviation = Round.roundTo(Math.pow(deviationsSq / basalGlucose.size, 0.5), 0.001)
|
val rmsDeviation = Round.roundTo((deviationsSq / basalGlucose.size).pow(0.5), 0.001)
|
||||||
log("insulinPeakTime $peak meanDeviation: $meanDeviation SMRDeviation: $smrDeviation RMSDeviation: $rmsDeviation (mg/dL)")
|
log("insulinPeakTime $peak meanDeviation: $meanDeviation SMRDeviation: $smrDeviation RMSDeviation: $rmsDeviation (mg/dL)")
|
||||||
peakDeviations.add(
|
peakDeviations.add(
|
||||||
PeakDeviation
|
PeakDeviation
|
||||||
|
@ -122,7 +126,7 @@ class AutotunePrep @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
deviations = Round.roundTo(deviations, 0.001);
|
deviations = Round.roundTo(deviations, 0.001)
|
||||||
if (deviations < minDeviations)
|
if (deviations < minDeviations)
|
||||||
minDeviations = Round.roundTo(deviations, 0.001)
|
minDeviations = Round.roundTo(deviations, 0.001)
|
||||||
peak += 5
|
peak += 5
|
||||||
|
@ -136,7 +140,7 @@ class AutotunePrep @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static Logger log = LoggerFactory.getLogger(AutotunePlugin.class);
|
// private static Logger log = LoggerFactory.getLogger(AutotunePlugin.class);
|
||||||
fun categorizeBGDatums(tunedprofile: ATProfile, localInsulin: LocalInsulin, verbose: Boolean = true): PreppedGlucose? {
|
fun categorizeBGDatums(tunedProfile: ATProfile, localInsulin: LocalInsulin, verbose: Boolean = true): PreppedGlucose? {
|
||||||
//lib/meals is called before to get only meals data (in AAPS it's done in AutotuneIob)
|
//lib/meals is called before to get only meals data (in AAPS it's done in AutotuneIob)
|
||||||
val treatments: MutableList<Carbs> = autotuneIob.meals
|
val treatments: MutableList<Carbs> = autotuneIob.meals
|
||||||
val boluses: MutableList<Bolus> = autotuneIob.boluses
|
val boluses: MutableList<Bolus> = autotuneIob.boluses
|
||||||
|
@ -148,14 +152,14 @@ class AutotunePrep @Inject constructor(
|
||||||
glucoseData.add(glucose[i])
|
glucoseData.add(glucose[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (glucose.size == 0 || glucoseData.size == 0 ) {
|
if (glucose.isEmpty() || glucoseData.size == 0) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "No BG value received")
|
//aapsLogger.debug(LTag.AUTOTUNE, "No BG value received")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("No BG value received")
|
log("No BG value received")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
glucoseData.sortWith(object: Comparator<GlucoseValue>{ override fun compare(o1: GlucoseValue, o2: GlucoseValue): Int = (o2.timestamp - o1.timestamp).toInt() })
|
glucoseData.sortWith { o1, o2 -> (o2.timestamp - o1.timestamp).toInt() }
|
||||||
|
|
||||||
// Bloc below replace bloc between #55 and #71
|
// Bloc below replace bloc between #55 and #71
|
||||||
// boluses and maxCarbs not used here ?,
|
// boluses and maxCarbs not used here ?,
|
||||||
|
@ -189,10 +193,10 @@ class AutotunePrep @Inject constructor(
|
||||||
var k = 0 // index of first value used by bucket
|
var k = 0 // index of first value used by bucket
|
||||||
//for loop to validate and bucket the data
|
//for loop to validate and bucket the data
|
||||||
for (i in 1 until glucoseData.size) {
|
for (i in 1 until glucoseData.size) {
|
||||||
val BGTime = glucoseData[i].timestamp
|
val bgTime = glucoseData[i].timestamp
|
||||||
val lastBGTime = glucoseData[k].timestamp
|
val lastBGTime = glucoseData[k].timestamp
|
||||||
val elapsedMinutes = (BGTime - lastBGTime) / (60 * 1000)
|
val elapsedMinutes = (bgTime - lastBGTime) / (60 * 1000)
|
||||||
if (Math.abs(elapsedMinutes) >= 2) {
|
if (abs(elapsedMinutes) >= 2) {
|
||||||
//j++; // move to next bucket
|
//j++; // move to next bucket
|
||||||
k = i // store index of first value used by bucket
|
k = i // store index of first value used by bucket
|
||||||
bucketedData.add(BGDatum(glucoseData[i], dateUtil))
|
bucketedData.add(BGDatum(glucoseData[i], dateUtil))
|
||||||
|
@ -229,14 +233,14 @@ class AutotunePrep @Inject constructor(
|
||||||
for (i in bucketedData.size - 5 downTo 1) {
|
for (i in bucketedData.size - 5 downTo 1) {
|
||||||
val glucoseDatum = bucketedData[i]
|
val glucoseDatum = bucketedData[i]
|
||||||
//log.debug(glucoseDatum);
|
//log.debug(glucoseDatum);
|
||||||
val BGTime = glucoseDatum.date
|
val bgTime = glucoseDatum.date
|
||||||
|
|
||||||
// As we're processing each data point, go through the treatment.carbs and see if any of them are older than
|
// As we're processing each data point, go through the treatment.carbs and see if any of them are older than
|
||||||
// the current BG data point. If so, add those carbs to COB.
|
// the current BG data point. If so, add those carbs to COB.
|
||||||
val treatment = if (treatments.size > 0) treatments[treatments.size - 1] else null
|
val treatment = if (treatments.size > 0) treatments[treatments.size - 1] else null
|
||||||
var myCarbs = 0.0
|
var myCarbs = 0.0
|
||||||
if (treatment != null) {
|
if (treatment != null) {
|
||||||
if (treatment.timestamp < BGTime) {
|
if (treatment.timestamp < bgTime) {
|
||||||
if (treatment.amount > 0.0) {
|
if (treatment.amount > 0.0) {
|
||||||
mealCOB += treatment.amount
|
mealCOB += treatment.amount
|
||||||
mealCarbs += treatment.amount
|
mealCarbs += treatment.amount
|
||||||
|
@ -267,7 +271,7 @@ class AutotunePrep @Inject constructor(
|
||||||
glucoseDatum.avgDelta = avgDelta
|
glucoseDatum.avgDelta = avgDelta
|
||||||
|
|
||||||
//sens = ISF
|
//sens = ISF
|
||||||
val sens = tunedprofile.isf
|
val sens = tunedProfile.isf
|
||||||
|
|
||||||
// for IOB calculations, use the average of the last 4 hours' basals to help convergence;
|
// for IOB calculations, use the average of the last 4 hours' basals to help convergence;
|
||||||
// this helps since the basal this hour could be different from previous, especially if with autotune they start to diverge.
|
// this helps since the basal this hour could be different from previous, especially if with autotune they start to diverge.
|
||||||
|
@ -280,7 +284,7 @@ class AutotunePrep @Inject constructor(
|
||||||
currentPumpBasal = Round.roundTo(currentPumpBasal / 4, 0.001) //CurrentPumpBasal for iob calculation is average of 4 last pumpProfile Basal rate
|
currentPumpBasal = Round.roundTo(currentPumpBasal / 4, 0.001) //CurrentPumpBasal for iob calculation is average of 4 last pumpProfile Basal rate
|
||||||
*/
|
*/
|
||||||
// this is the current autotuned basal, used for everything else besides IOB calculations
|
// this is the current autotuned basal, used for everything else besides IOB calculations
|
||||||
val currentBasal = tunedprofile.getBasal(BGTime)
|
val currentBasal = tunedProfile.getBasal(bgTime)
|
||||||
|
|
||||||
// basalBGI is BGI of basal insulin activity.
|
// basalBGI is BGI of basal insulin activity.
|
||||||
val basalBGI = Round.roundTo(currentBasal * sens / 60 * 5, 0.01) // U/hr * mg/dL/U * 1 hr / 60 minutes * 5 = mg/dL/5m
|
val basalBGI = Round.roundTo(currentBasal * sens / 60 * 5, 0.01) // U/hr * mg/dL/U * 1 hr / 60 minutes * 5 = mg/dL/5m
|
||||||
|
@ -289,14 +293,14 @@ class AutotunePrep @Inject constructor(
|
||||||
//var iob = getIOB(IOBInputs)[0];
|
//var iob = getIOB(IOBInputs)[0];
|
||||||
// in autotune iob is calculated with 6 hours of history data, tunedProfile and average pumpProfile basal rate...
|
// in autotune iob is calculated with 6 hours of history data, tunedProfile and average pumpProfile basal rate...
|
||||||
//log("currentBasal: " + currentBasal + " BGTime: " + BGTime + " / " + dateUtil!!.timeStringWithSeconds(BGTime) + "******************************************************************************************")
|
//log("currentBasal: " + currentBasal + " BGTime: " + BGTime + " / " + dateUtil!!.timeStringWithSeconds(BGTime) + "******************************************************************************************")
|
||||||
val iob = autotuneIob.getIOB(BGTime, localInsulin) // add localInsulin to be independent to InsulinPlugin
|
val iob = autotuneIob.getIOB(bgTime, localInsulin) // add localInsulin to be independent to InsulinPlugin
|
||||||
|
|
||||||
// activity times ISF times 5 minutes is BGI
|
// activity times ISF times 5 minutes is BGI
|
||||||
val BGI = Round.roundTo(-iob.activity * sens * 5, 0.01)
|
val bgi = Round.roundTo(-iob.activity * sens * 5, 0.01)
|
||||||
// datum = one glucose data point (being prepped to store in output)
|
// datum = one glucose data point (being prepped to store in output)
|
||||||
glucoseDatum.bgi = BGI
|
glucoseDatum.bgi = bgi
|
||||||
// calculating deviation
|
// calculating deviation
|
||||||
var deviation = avgDelta - BGI
|
var deviation = avgDelta - bgi
|
||||||
|
|
||||||
// set positive deviations to zero if BG is below 80
|
// set positive deviations to zero if BG is below 80
|
||||||
if (bg < 80 && deviation > 0) {
|
if (bg < 80 && deviation > 0) {
|
||||||
|
@ -309,10 +313,10 @@ class AutotunePrep @Inject constructor(
|
||||||
|
|
||||||
// Then, calculate carb absorption for that 5m interval using the deviation.
|
// Then, calculate carb absorption for that 5m interval using the deviation.
|
||||||
if (mealCOB > 0) {
|
if (mealCOB > 0) {
|
||||||
val ci = Math.max(deviation, sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0))
|
val ci = max(deviation, sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0))
|
||||||
val absorbed = ci * tunedprofile.ic / sens
|
val absorbed = ci * tunedProfile.ic / sens
|
||||||
// Store the COB, and use it as the starting point for the next data point.
|
// Store the COB, and use it as the starting point for the next data point.
|
||||||
mealCOB = Math.max(0.0, mealCOB - absorbed)
|
mealCOB = max(0.0, mealCOB - absorbed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate carb ratio (CR) independently of CSF and ISF
|
// Calculate carb ratio (CR) independently of CSF and ISF
|
||||||
|
@ -323,7 +327,7 @@ class AutotunePrep @Inject constructor(
|
||||||
if (mealCOB > 0 || calculatingCR) {
|
if (mealCOB > 0 || calculatingCR) {
|
||||||
// set initial values when we first see COB
|
// set initial values when we first see COB
|
||||||
crCarbs += myCarbs
|
crCarbs += myCarbs
|
||||||
if (calculatingCR == false) {
|
if (!calculatingCR) {
|
||||||
crInitialIOB = iob.iob
|
crInitialIOB = iob.iob
|
||||||
crInitialBG = glucoseDatum.value
|
crInitialBG = glucoseDatum.value
|
||||||
crInitialCarbTime = glucoseDatum.date
|
crInitialCarbTime = glucoseDatum.date
|
||||||
|
@ -354,13 +358,13 @@ class AutotunePrep @Inject constructor(
|
||||||
crDatum.crCarbs = crCarbs
|
crDatum.crCarbs = crCarbs
|
||||||
//log.debug(CRDatum);
|
//log.debug(CRDatum);
|
||||||
//String crDataString = "{\"CRInitialIOB\": " + CRInitialIOB + ", \"CRInitialBG\": " + CRInitialBG + ", \"CRInitialCarbTime\": " + CRInitialCarbTime + ", \"CREndIOB\": " + CREndIOB + ", \"CREndBG\": " + CREndBG + ", \"CREndTime\": " + CREndTime + ", \"CRCarbs\": " + CRCarbs + "}";
|
//String crDataString = "{\"CRInitialIOB\": " + CRInitialIOB + ", \"CRInitialBG\": " + CRInitialBG + ", \"CRInitialCarbTime\": " + CRInitialCarbTime + ", \"CREndIOB\": " + CREndIOB + ", \"CREndBG\": " + CREndBG + ", \"CREndTime\": " + CREndTime + ", \"CRCarbs\": " + CRCarbs + "}";
|
||||||
val CRElapsedMinutes = Math.round((crEndTime - crInitialCarbTime) / (1000 * 60).toFloat())
|
val crElapsedMinutes = ((crEndTime - crInitialCarbTime) / (1000 * 60).toFloat()).roundToInt()
|
||||||
|
|
||||||
//log.debug(CREndTime - CRInitialCarbTime, CRElapsedMinutes);
|
//log.debug(CREndTime - CRInitialCarbTime, CRElapsedMinutes);
|
||||||
if (CRElapsedMinutes < 60 || i == 1 && mealCOB > 0) {
|
if (crElapsedMinutes < 60 || i == 1 && mealCOB > 0) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Ignoring $CRElapsedMinutes m CR period.")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Ignoring $CRElapsedMinutes m CR period.")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("Ignoring $CRElapsedMinutes m CR period.")
|
log("Ignoring $crElapsedMinutes m CR period.")
|
||||||
} else {
|
} else {
|
||||||
crData.add(crDatum)
|
crData.add(crDatum)
|
||||||
}
|
}
|
||||||
|
@ -376,11 +380,7 @@ class AutotunePrep @Inject constructor(
|
||||||
absorbing = if (iob.iob < currentBasal / 2) {
|
absorbing = if (iob.iob < currentBasal / 2) {
|
||||||
false
|
false
|
||||||
// otherwise, as long as deviations are positive, keep tracking carb deviations
|
// otherwise, as long as deviations are positive, keep tracking carb deviations
|
||||||
} else if (deviation > 0) {
|
} else deviation > 0
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
if (!absorbing && mealCOB == 0.0) {
|
if (!absorbing && mealCOB == 0.0) {
|
||||||
mealCarbs = 0.0
|
mealCarbs = 0.0
|
||||||
}
|
}
|
||||||
|
@ -405,11 +405,7 @@ class AutotunePrep @Inject constructor(
|
||||||
log("${csfGlucoseData[csfGlucoseData.size - 1].mealAbsorption} carb absorption")
|
log("${csfGlucoseData[csfGlucoseData.size - 1].mealAbsorption} carb absorption")
|
||||||
}
|
}
|
||||||
if (iob.iob > 2 * currentBasal || deviation > 6 || uam) {
|
if (iob.iob > 2 * currentBasal || deviation > 6 || uam) {
|
||||||
uam = if (deviation > 0) {
|
uam = deviation > 0
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
if (type != "uam") {
|
if (type != "uam") {
|
||||||
glucoseDatum.uamAbsorption = "start"
|
glucoseDatum.uamAbsorption = "start"
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "${glucoseDatum.uamAbsorption} unannnounced meal absorption")
|
//aapsLogger.debug(LTag.AUTOTUNE, "${glucoseDatum.uamAbsorption} unannnounced meal absorption")
|
||||||
|
@ -431,11 +427,11 @@ class AutotunePrep @Inject constructor(
|
||||||
// When BGI is smaller than about 1/4 of basalBGI, we want to use that data to tune basals
|
// When BGI is smaller than about 1/4 of basalBGI, we want to use that data to tune basals
|
||||||
// When BGI is negative and more than about 1/4 of basalBGI, we can use that data to tune ISF,
|
// When BGI is negative and more than about 1/4 of basalBGI, we can use that data to tune ISF,
|
||||||
// unless avgDelta is positive: then that's some sort of unexplained rise we don't want to use for ISF, so that means basals
|
// unless avgDelta is positive: then that's some sort of unexplained rise we don't want to use for ISF, so that means basals
|
||||||
if (basalBGI > -4 * BGI) {
|
if (basalBGI > -4 * bgi) {
|
||||||
type = "basal"
|
type = "basal"
|
||||||
basalGlucoseData.add(glucoseDatum)
|
basalGlucoseData.add(glucoseDatum)
|
||||||
} else {
|
} else {
|
||||||
if (avgDelta > 0 && avgDelta > -2 * BGI) {
|
if (avgDelta > 0 && avgDelta > -2 * bgi) {
|
||||||
//type="unknown"
|
//type="unknown"
|
||||||
type = "basal"
|
type = "basal"
|
||||||
basalGlucoseData.add(glucoseDatum)
|
basalGlucoseData.add(glucoseDatum)
|
||||||
|
@ -449,8 +445,12 @@ class AutotunePrep @Inject constructor(
|
||||||
// debug line to print out all the things
|
// debug line to print out all the things
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "${(if (absorbing) 1 else 0)} mealCOB: ${Round.roundTo(mealCOB, 0.1)} mealCarbs: ${Math.round(mealCarbs)} basalBGI: ${Round.roundTo(basalBGI, 0.1)} BGI: ${Round.roundTo(BGI, 0.1)} IOB: ${iob.iob} Activity: ${iob.activity} at ${dateUtil.timeStringWithSeconds(BGTime)} dev: $deviation avgDelta: $avgDelta $type")
|
//aapsLogger.debug(LTag.AUTOTUNE, "${(if (absorbing) 1 else 0)} mealCOB: ${Round.roundTo(mealCOB, 0.1)} mealCarbs: ${Math.round(mealCarbs)} basalBGI: ${Round.roundTo(basalBGI, 0.1)} BGI: ${Round.roundTo(BGI, 0.1)} IOB: ${iob.iob} Activity: ${iob.activity} at ${dateUtil.timeStringWithSeconds(BGTime)} dev: $deviation avgDelta: $avgDelta $type")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("${(if (absorbing) 1 else 0)} mealCOB: ${Round.roundTo(mealCOB, 0.1)} mealCarbs: ${Math.round(mealCarbs)} basalBGI: ${Round.roundTo(basalBGI, 0.1)} BGI: ${Round
|
log(
|
||||||
.roundTo(BGI, 0.1)} IOB: ${iob.iob} Activity: ${iob.activity} at ${dateUtil.timeStringWithSeconds(BGTime)} dev: $deviation avgDelta: $avgDelta $type")
|
"${(if (absorbing) 1 else 0)} mealCOB: ${Round.roundTo(mealCOB, 0.1)} mealCarbs: ${mealCarbs.roundToInt()} basalBGI: ${Round.roundTo(basalBGI, 0.1)} BGI: ${
|
||||||
|
Round
|
||||||
|
.roundTo(bgi, 0.1)
|
||||||
|
} IOB: ${iob.iob} Activity: ${iob.activity} at ${dateUtil.timeStringWithSeconds(bgTime)} dev: $deviation avgDelta: $avgDelta $type"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
//****************************************************************************************************************************************
|
//****************************************************************************************************************************************
|
||||||
|
@ -460,33 +460,33 @@ class AutotunePrep @Inject constructor(
|
||||||
crDatum.crInsulin = dosed(crDatum.crInitialCarbTime, crDatum.crEndTime, boluses)
|
crDatum.crInsulin = dosed(crDatum.crInitialCarbTime, crDatum.crEndTime, boluses)
|
||||||
}
|
}
|
||||||
// categorize.js Lines 384-436
|
// categorize.js Lines 384-436
|
||||||
val CSFLength = csfGlucoseData.size
|
val csfLength = csfGlucoseData.size
|
||||||
var ISFLength = isfGlucoseData.size
|
var isfLength = isfGlucoseData.size
|
||||||
val UAMLength = uamGlucoseData.size
|
val uamLength = uamGlucoseData.size
|
||||||
var basalLength = basalGlucoseData.size
|
var basalLength = basalGlucoseData.size
|
||||||
if (sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)) {
|
if (sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Categorizing all UAM data as basal.")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Categorizing all UAM data as basal.")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("Categorizing all UAM data as basal.")
|
log("Categorizing all UAM data as basal.")
|
||||||
basalGlucoseData.addAll(uamGlucoseData)
|
basalGlucoseData.addAll(uamGlucoseData)
|
||||||
} else if (CSFLength > 12) {
|
} else if (csfLength > 12) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Found at least 1h of carb: assuming meals were announced, and categorizing UAM data as basal.")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Found at least 1h of carb: assuming meals were announced, and categorizing UAM data as basal.")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("Found at least 1h of carb: assuming meals were announced, and categorizing UAM data as basal.")
|
log("Found at least 1h of carb: assuming meals were announced, and categorizing UAM data as basal.")
|
||||||
basalGlucoseData.addAll(uamGlucoseData)
|
basalGlucoseData.addAll(uamGlucoseData)
|
||||||
} else {
|
} else {
|
||||||
if (2 * basalLength < UAMLength) {
|
if (2 * basalLength < uamLength) {
|
||||||
//log.debug(basalGlucoseData, UAMGlucoseData);
|
//log.debug(basalGlucoseData, UAMGlucoseData);
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as UnAnnounced Meals")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as UnAnnounced Meals")
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $UAMLength UAM deviations to $basalLength basal ones")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $UAMLength UAM deviations to $basalLength basal ones")
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
log("Warning: too many deviations categorized as UnAnnounced Meals")
|
log("Warning: too many deviations categorized as UnAnnounced Meals")
|
||||||
log("Adding $UAMLength UAM deviations to $basalLength basal ones")
|
log("Adding $uamLength UAM deviations to $basalLength basal ones")
|
||||||
}
|
}
|
||||||
basalGlucoseData.addAll(uamGlucoseData)
|
basalGlucoseData.addAll(uamGlucoseData)
|
||||||
//log.debug(basalGlucoseData);
|
//log.debug(basalGlucoseData);
|
||||||
// if too much data is excluded as UAM, add in the UAM deviations, but then discard the highest 50%
|
// if too much data is excluded as UAM, add in the UAM deviations, but then discard the highest 50%
|
||||||
basalGlucoseData.sortWith(object: Comparator<BGDatum>{ override fun compare(o1: BGDatum, o2: BGDatum): Int = (100 * o1.deviation - 100 * o2.deviation).toInt() }) //deviation rouded to 0.01, so *100 to avoid crash during sort
|
basalGlucoseData.sortWith { o1, o2 -> (100 * o1.deviation - 100 * o2.deviation).toInt() } //deviation rouded to 0.01, so *100 to avoid crash during sort
|
||||||
val newBasalGlucose: MutableList<BGDatum> = ArrayList()
|
val newBasalGlucose: MutableList<BGDatum> = ArrayList()
|
||||||
for (i in 0 until basalGlucoseData.size / 2) {
|
for (i in 0 until basalGlucoseData.size / 2) {
|
||||||
newBasalGlucose.add(basalGlucoseData[i])
|
newBasalGlucose.add(basalGlucoseData[i])
|
||||||
|
@ -497,13 +497,13 @@ class AutotunePrep @Inject constructor(
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("and selecting the lowest 50%, leaving ${basalGlucoseData.size} basal+UAM ones")
|
log("and selecting the lowest 50%, leaving ${basalGlucoseData.size} basal+UAM ones")
|
||||||
}
|
}
|
||||||
if (2 * ISFLength < UAMLength) {
|
if (2 * isfLength < uamLength) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $UAMLength UAM deviations to $ISFLength ISF ones")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $UAMLength UAM deviations to $ISFLength ISF ones")
|
||||||
if (verbose)
|
if (verbose)
|
||||||
log("Adding $UAMLength UAM deviations to $ISFLength ISF ones")
|
log("Adding $uamLength UAM deviations to $isfLength ISF ones")
|
||||||
isfGlucoseData.addAll(uamGlucoseData)
|
isfGlucoseData.addAll(uamGlucoseData)
|
||||||
// if too much data is excluded as UAM, add in the UAM deviations to ISF, but then discard the highest 50%
|
// if too much data is excluded as UAM, add in the UAM deviations to ISF, but then discard the highest 50%
|
||||||
isfGlucoseData.sortWith(object: Comparator<BGDatum>{ override fun compare(o1: BGDatum, o2: BGDatum): Int = (100 * o1.deviation - 100 * o2.deviation).toInt() }) //deviation rouded to 0.01, so *100 to avoid crash during sort
|
isfGlucoseData.sortWith { o1, o2 -> (100 * o1.deviation - 100 * o2.deviation).toInt() } //deviation rouded to 0.01, so *100 to avoid crash during sort
|
||||||
val newISFGlucose: MutableList<BGDatum> = ArrayList()
|
val newISFGlucose: MutableList<BGDatum> = ArrayList()
|
||||||
for (i in 0 until isfGlucoseData.size / 2) {
|
for (i in 0 until isfGlucoseData.size / 2) {
|
||||||
newISFGlucose.add(isfGlucoseData[i])
|
newISFGlucose.add(isfGlucoseData[i])
|
||||||
|
@ -517,15 +517,15 @@ class AutotunePrep @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
basalLength = basalGlucoseData.size
|
basalLength = basalGlucoseData.size
|
||||||
ISFLength = isfGlucoseData.size
|
isfLength = isfGlucoseData.size
|
||||||
if (4 * basalLength + ISFLength < CSFLength && ISFLength < 10) {
|
if (4 * basalLength + isfLength < csfLength && isfLength < 10) {
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as meals")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as meals")
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $CSFLength CSF deviations to $ISFLength ISF ones")
|
//aapsLogger.debug(LTag.AUTOTUNE, "Adding $CSFLength CSF deviations to $ISFLength ISF ones")
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
log("Warning: too many deviations categorized as meals")
|
log("Warning: too many deviations categorized as meals")
|
||||||
//log.debug("Adding",CSFLength,"CSF deviations to",basalLength,"basal ones");
|
//log.debug("Adding",CSFLength,"CSF deviations to",basalLength,"basal ones");
|
||||||
//var basalGlucoseData = basalGlucoseData.concat(CSFGlucoseData);
|
//var basalGlucoseData = basalGlucoseData.concat(CSFGlucoseData);
|
||||||
log("Adding $CSFLength CSF deviations to $ISFLength ISF ones")
|
log("Adding $csfLength CSF deviations to $isfLength ISF ones")
|
||||||
}
|
}
|
||||||
isfGlucoseData.addAll(csfGlucoseData)
|
isfGlucoseData.addAll(csfGlucoseData)
|
||||||
csfGlucoseData = ArrayList()
|
csfGlucoseData = ArrayList()
|
||||||
|
@ -543,7 +543,7 @@ class AutotunePrep @Inject constructor(
|
||||||
private fun dosed(start: Long, end: Long, treatments: List<Bolus>): Double {
|
private fun dosed(start: Long, end: Long, treatments: List<Bolus>): Double {
|
||||||
var insulinDosed = 0.0
|
var insulinDosed = 0.0
|
||||||
//aapsLogger.debug(LTag.AUTOTUNE, "No treatments to process.")
|
//aapsLogger.debug(LTag.AUTOTUNE, "No treatments to process.")
|
||||||
if (treatments.size == 0) {
|
if (treatments.isEmpty()) {
|
||||||
log("No treatments to process.")
|
log("No treatments to process.")
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.core.R
|
import info.nightscout.androidaps.core.R
|
||||||
|
@ -8,7 +8,14 @@ import info.nightscout.androidaps.data.PureProfile
|
||||||
import info.nightscout.androidaps.database.data.Block
|
import info.nightscout.androidaps.database.data.Block
|
||||||
import info.nightscout.androidaps.extensions.blockValueBySeconds
|
import info.nightscout.androidaps.extensions.blockValueBySeconds
|
||||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.interfaces.Insulin
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
@ -19,7 +26,7 @@ import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.*
|
import java.util.TimeZone
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: HasAndroidInjector) {
|
class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: HasAndroidInjector) {
|
||||||
|
@ -56,18 +63,19 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
val avgIC: Double
|
val avgIC: Double
|
||||||
get() = if (profile.getIcsValues().size == 1) profile.getIcsValues().get(0).value else Round.roundTo(averageProfileValue(profile.getIcsValues()), 0.01)
|
get() = if (profile.getIcsValues().size == 1) profile.getIcsValues().get(0).value else Round.roundTo(averageProfileValue(profile.getIcsValues()), 0.01)
|
||||||
|
|
||||||
fun getBasal(timestamp: Long): Double = basal[Profile.secondsFromMidnight(timestamp)/3600]
|
fun getBasal(timestamp: Long): Double = basal[Profile.secondsFromMidnight(timestamp) / 3600]
|
||||||
|
|
||||||
// for localProfilePlugin Synchronisation
|
// for localProfilePlugin Synchronisation
|
||||||
fun basal() = jsonArray(basal)
|
fun basal() = jsonArray(basal)
|
||||||
fun ic(circadian: Boolean = false): JSONArray {
|
fun ic(circadian: Boolean = false): JSONArray {
|
||||||
if(circadian)
|
if (circadian)
|
||||||
return jsonArray(pumpProfile.icBlocks, avgIC/pumpProfileAvgIC)
|
return jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC)
|
||||||
return jsonArray(ic)
|
return jsonArray(ic)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isf(circadian: Boolean = false): JSONArray {
|
fun isf(circadian: Boolean = false): JSONArray {
|
||||||
if(circadian)
|
if (circadian)
|
||||||
return jsonArray(pumpProfile.isfBlocks, avgISF/pumpProfileAvgISF)
|
return jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF)
|
||||||
return jsonArray(Profile.fromMgdlToUnits(isf, profile.units))
|
return jsonArray(Profile.fromMgdlToUnits(isf, profile.units))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +123,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
JSONObject()
|
JSONObject()
|
||||||
.put("start", time)
|
.put("start", time)
|
||||||
.put("minutes", h * 60)
|
.put("minutes", h * 60)
|
||||||
.put("rate", profile.getBasalTimeFromMidnight(secondfrommidnight)
|
.put(
|
||||||
|
"rate", profile.getBasalTimeFromMidnight(secondfrommidnight)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +143,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
json.put("units", GlucoseUnit.MGDL.asText)
|
json.put("units", GlucoseUnit.MGDL.asText)
|
||||||
json.put("timezone", TimeZone.getDefault().id)
|
json.put("timezone", TimeZone.getDefault().id)
|
||||||
jsonString = json.toString(2).replace("\\/", "/")
|
jsonString = json.toString(2).replace("\\/", "/")
|
||||||
} catch (e: JSONException) {}
|
} catch (e: JSONException) {
|
||||||
|
}
|
||||||
|
|
||||||
return jsonString
|
return jsonString
|
||||||
}
|
}
|
||||||
|
@ -144,8 +154,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
try {
|
try {
|
||||||
json.put("dia", dia)
|
json.put("dia", dia)
|
||||||
if (circadian) {
|
if (circadian) {
|
||||||
json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF/pumpProfileAvgISF))
|
json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF))
|
||||||
json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC/pumpProfileAvgIC))
|
json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC))
|
||||||
} else {
|
} else {
|
||||||
json.put("sens", jsonArray(Profile.fromMgdlToUnits(isf, profile.units)))
|
json.put("sens", jsonArray(Profile.fromMgdlToUnits(isf, profile.units)))
|
||||||
json.put("carbratio", jsonArray(ic))
|
json.put("carbratio", jsonArray(ic))
|
||||||
|
@ -156,8 +166,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
return pureProfileFromJson(json, dateUtil, profile.units.asText)
|
return pureProfileFromJson(json, dateUtil, profile.units.asText)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun profileStore(circadian: Boolean = false): ProfileStore?
|
fun profileStore(circadian: Boolean = false): ProfileStore? {
|
||||||
{
|
|
||||||
var profileStore: ProfileStore? = null
|
var profileStore: ProfileStore? = null
|
||||||
val json = JSONObject()
|
val json = JSONObject()
|
||||||
val store = JSONObject()
|
val store = JSONObject()
|
||||||
|
@ -170,7 +179,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
|
||||||
json.put("store", store)
|
json.put("store", store)
|
||||||
json.put("startDate", dateUtil.toISOAsUTC(dateUtil.now()))
|
json.put("startDate", dateUtil.toISOAsUTC(dateUtil.now()))
|
||||||
profileStore = ProfileStore(injector, json, dateUtil)
|
profileStore = ProfileStore(injector, json, dateUtil)
|
||||||
} catch (e: JSONException) { }
|
} catch (e: JSONException) {
|
||||||
|
}
|
||||||
return profileStore
|
return profileStore
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow
|
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.TimeZone
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Rumen Georgiev on 2/24/2018.
|
* Created by Rumen Georgiev on 2/24/2018.
|
||||||
*/
|
*/
|
||||||
class BGDatum {
|
class BGDatum {
|
||||||
|
|
||||||
//Added by Rumen for autotune
|
//Added by Rumen for autotune
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
var date = 0L
|
var date = 0L
|
||||||
|
@ -27,7 +28,10 @@ class BGDatum {
|
||||||
private set
|
private set
|
||||||
var dateUtil: DateUtil
|
var dateUtil: DateUtil
|
||||||
|
|
||||||
constructor(dateUtil: DateUtil) { this.dateUtil = dateUtil}
|
constructor(dateUtil: DateUtil) {
|
||||||
|
this.dateUtil = dateUtil
|
||||||
|
}
|
||||||
|
|
||||||
constructor(json: JSONObject, dateUtil: DateUtil) {
|
constructor(json: JSONObject, dateUtil: DateUtil) {
|
||||||
this.dateUtil = dateUtil
|
this.dateUtil = dateUtil
|
||||||
try {
|
try {
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
|
@ -20,7 +20,10 @@ class CRDatum {
|
||||||
var crInsulinTotal = 0.0
|
var crInsulinTotal = 0.0
|
||||||
var dateUtil: DateUtil
|
var dateUtil: DateUtil
|
||||||
|
|
||||||
constructor(dateUtil: DateUtil) { this.dateUtil = dateUtil}
|
constructor(dateUtil: DateUtil) {
|
||||||
|
this.dateUtil = dateUtil
|
||||||
|
}
|
||||||
|
|
||||||
constructor(json: JSONObject, dateUtil: DateUtil) {
|
constructor(json: JSONObject, dateUtil: DateUtil) {
|
||||||
this.dateUtil = dateUtil
|
this.dateUtil = dateUtil
|
||||||
try {
|
try {
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
|
@ -1,10 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.data
|
package info.nightscout.plugins.general.autotune.data
|
||||||
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class PreppedGlucose {
|
class PreppedGlucose {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune.events
|
package info.nightscout.plugins.general.autotune.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.general.maintenance
|
package info.nightscout.plugins.general.maintenance
|
||||||
|
|
||||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||||
|
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class LoggerUtils @Inject constructor(
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
This is failing after slf4j update to 2.0.0
|
This is failing after slf4j update to 2.0.0
|
||||||
It would be better to find a way to read the value from xml
|
It would be better to find a way to read the value from xml
|
||||||
So far replaced by static value
|
So far replaced by static value
|
||||||
|
@ -30,6 +31,6 @@ class LoggerUtils @Inject constructor(
|
||||||
val lc = LoggerFactory.getILoggerFactory() as LoggerContext
|
val lc = LoggerFactory.getILoggerFactory() as LoggerContext
|
||||||
return lc.getProperty("EXT_FILES_DIR")
|
return lc.getProperty("EXT_FILES_DIR")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
val logDirectory get() = prefFileListProvider.logsPath
|
val logDirectory get() = prefFileListProvider.logsPath
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package info.nightscout.plugins.utils
|
||||||
|
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
object Percentile {
|
||||||
|
|
||||||
|
// From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2
|
||||||
|
// Returns the value at a given percentile in a sorted numeric array.
|
||||||
|
// "Linear interpolation between closest ranks" method
|
||||||
|
fun percentile(arr: Array<Double>, p: Double): Double {
|
||||||
|
if (arr.isEmpty()) return 0.0
|
||||||
|
if (p <= 0) return arr[0]
|
||||||
|
if (p >= 1) return arr[arr.size - 1]
|
||||||
|
val index = arr.size * p
|
||||||
|
val lower = floor(index)
|
||||||
|
val upper = lower + 1
|
||||||
|
val weight = index % 1
|
||||||
|
return if (upper >= arr.size) arr[lower.toInt()] else arr[lower.toInt()] * (1 - weight) + arr[upper.toInt()] * weight
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".plugins.general.autotune.AutotuneFragment">
|
tools:context="info.nightscout.plugins.general.autotune.AutotuneFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tune_lastrun"
|
android:id="@+id/tune_last_run"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
@ -246,7 +246,7 @@
|
||||||
app:layout_row="0" />
|
app:layout_row="0" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/autotune_copylocal"
|
android:id="@+id/autotune_copy_local"
|
||||||
style="@style/GrayButton"
|
style="@style/GrayButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
|
@ -1,18 +1,19 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.TestBaseWithProfile
|
import info.nightscout.androidaps.TestBaseWithProfile
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
import info.nightscout.androidaps.data.ProfileSealed
|
import info.nightscout.androidaps.data.ProfileSealed
|
||||||
import info.nightscout.androidaps.data.PureProfile
|
import info.nightscout.androidaps.data.PureProfile
|
||||||
import info.nightscout.androidaps.database.data.Block
|
import info.nightscout.androidaps.database.data.Block
|
||||||
import info.nightscout.androidaps.database.data.TargetBlock
|
import info.nightscout.androidaps.database.data.TargetBlock
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.JsonHelper
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
@ -22,14 +23,13 @@ import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.TimeZone
|
||||||
|
|
||||||
class AutotuneCoreTest : TestBaseWithProfile() {
|
class AutotuneCoreTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var autotuneFS: AutotuneFS
|
@Mock lateinit var autotuneFS: AutotuneFS
|
||||||
@Mock lateinit var injector: HasAndroidInjector
|
@Mock lateinit var injector: HasAndroidInjector
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
|
||||||
private lateinit var autotuneCore: AutotuneCore
|
private lateinit var autotuneCore: AutotuneCore
|
||||||
private var min5mCarbImpact = 0.0
|
private var min5mCarbImpact = 0.0
|
||||||
private var autotuneMin = 0.0
|
private var autotuneMin = 0.0
|
|
@ -1,7 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.R
|
|
||||||
import info.nightscout.androidaps.TestBaseWithProfile
|
import info.nightscout.androidaps.TestBaseWithProfile
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.LocalInsulin
|
import info.nightscout.androidaps.data.LocalInsulin
|
||||||
|
@ -14,11 +13,14 @@ import info.nightscout.androidaps.database.entities.Bolus
|
||||||
import info.nightscout.androidaps.database.entities.Carbs
|
import info.nightscout.androidaps.database.entities.Carbs
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.extensions.shiftBlock
|
import info.nightscout.androidaps.extensions.shiftBlock
|
||||||
import info.nightscout.androidaps.interfaces.*
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.JsonHelper
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.plugins.R
|
||||||
|
import info.nightscout.plugins.general.autotune.data.ATProfile
|
||||||
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
|
@ -29,14 +31,13 @@ import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.TimeZone
|
||||||
|
|
||||||
class AutotunePrepTest : TestBaseWithProfile() {
|
class AutotunePrepTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var autotuneFS: AutotuneFS
|
@Mock lateinit var autotuneFS: AutotuneFS
|
||||||
@Mock lateinit var injector: HasAndroidInjector
|
@Mock lateinit var injector: HasAndroidInjector
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
|
||||||
@Mock lateinit var repository: AppRepository
|
@Mock lateinit var repository: AppRepository
|
||||||
private lateinit var autotunePrep: AutotunePrep
|
private lateinit var autotunePrep: AutotunePrep
|
||||||
private lateinit var autotuneIob: TestAutotuneIob
|
private lateinit var autotuneIob: TestAutotuneIob
|
||||||
|
@ -55,8 +56,8 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
||||||
fun autotunePrepTest1() { // Test if categorisation with standard treatments with carbs is Ok
|
fun autotunePrepTest1() { // Test if categorisation with standard treatments with carbs is Ok
|
||||||
val inputIobJson = File("src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
val inputIobJson = File("src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, autotuneFS, iobOapsCalculation)
|
||||||
autotunePrep = AutotunePrep(aapsLogger, sp, dateUtil, autotuneFS, autotuneIob)
|
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||||
val prepJson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
val prepJson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||||
|
@ -94,8 +95,8 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
||||||
fun autotunePrepTest2() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal false is Ok
|
fun autotunePrepTest2() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal false is Ok
|
||||||
val inputIobJson = File("src/test/res/autotune/test2/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
val inputIobJson = File("src/test/res/autotune/test2/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, autotuneFS, iobOapsCalculation)
|
||||||
autotunePrep = AutotunePrep(aapsLogger, sp, dateUtil, autotuneFS, autotuneIob)
|
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||||
val inputProfileJson = File("src/test/res/autotune/test2/profile.pump.json").readText()
|
val inputProfileJson = File("src/test/res/autotune/test2/profile.pump.json").readText()
|
||||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||||
val prepJson = File("src/test/res/autotune/test2/autotune.2022-05-21.json").readText()
|
val prepJson = File("src/test/res/autotune/test2/autotune.2022-05-21.json").readText()
|
||||||
|
@ -133,8 +134,8 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
||||||
fun autotunePrepTest3() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal true is Ok
|
fun autotunePrepTest3() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal true is Ok
|
||||||
val inputIobJson = File("src/test/res/autotune/test3/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
val inputIobJson = File("src/test/res/autotune/test3/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, autotuneFS, iobOapsCalculation)
|
||||||
autotunePrep = AutotunePrep(aapsLogger, sp, dateUtil, autotuneFS, autotuneIob)
|
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||||
val inputProfileJson = File("src/test/res/autotune/test3/profile.pump.json").readText()
|
val inputProfileJson = File("src/test/res/autotune/test3/profile.pump.json").readText()
|
||||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||||
val prepJson = File("src/test/res/autotune/test3/autotune.2022-05-21.json").readText()
|
val prepJson = File("src/test/res/autotune/test3/autotune.2022-05-21.json").readText()
|
||||||
|
@ -305,10 +306,9 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
||||||
class TestAutotuneIob(
|
class TestAutotuneIob(
|
||||||
val aapsLogger: AAPSLogger,
|
val aapsLogger: AAPSLogger,
|
||||||
repository: AppRepository,
|
repository: AppRepository,
|
||||||
val profileFunction: ProfileFunction,
|
profileFunction: ProfileFunction,
|
||||||
val sp: SP,
|
sp: SP,
|
||||||
val dateUtil: DateUtil,
|
dateUtil: DateUtil,
|
||||||
val activePlugin: ActivePlugin,
|
|
||||||
autotuneFS: AutotuneFS,
|
autotuneFS: AutotuneFS,
|
||||||
private val iobOapsCalculation: ArrayList<IobTotal>
|
private val iobOapsCalculation: ArrayList<IobTotal>
|
||||||
) : AutotuneIob(
|
) : AutotuneIob(
|
|
@ -1,9 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.general.autotune
|
package info.nightscout.plugins.general.autotune
|
||||||
|
|
||||||
import info.nightscout.androidaps.TestBaseWithProfile
|
import info.nightscout.androidaps.TestBaseWithProfile
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.BGDatum
|
import info.nightscout.plugins.general.autotune.data.BGDatum
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.CRDatum
|
import info.nightscout.plugins.general.autotune.data.CRDatum
|
||||||
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
|
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
|
@ -28,7 +28,6 @@
|
||||||
<string name="invalid_weight">Invalid weight entry</string>
|
<string name="invalid_weight">Invalid weight entry</string>
|
||||||
<string name="id">ID:</string>
|
<string name="id">ID:</string>
|
||||||
<string name="submit">Submit</string>
|
<string name="submit">Submit</string>
|
||||||
<string name="profile">Profile</string>
|
|
||||||
<string name="age">Age</string>
|
<string name="age">Age</string>
|
||||||
<string name="weight_label">Weight</string>
|
<string name="weight_label">Weight</string>
|
||||||
<string name="most_common_profile">Most common profile:</string>
|
<string name="most_common_profile">Most common profile:</string>
|
||||||
|
|
Loading…
Reference in a new issue