diff --git a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt index eb61606e37..b5c849d9e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt @@ -37,13 +37,11 @@ import info.nightscout.androidaps.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDyn import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.PluginStore 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.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin 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.eopatch.EopatchPumpPlugin 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.NONE import info.nightscout.automation.AutomationPlugin +import info.nightscout.plugins.general.autotune.AutotunePlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin +import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin import info.nightscout.shared.SafeParse import info.nightscout.shared.sharedPreferences.SP @@ -335,9 +335,9 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang p.initialExpandedChildrenCount = Int.MAX_VALUE } } else { - visible = visible || p.key?.contains(filter, true) == true - visible = visible || p.title?.contains(filter, true) == true - visible = visible || p.summary?.contains(filter, true) == true + visible = visible || p.key?.contains(filter, true) == true + visible = visible || p.title?.contains(filter, true) == true + visible = visible || p.summary?.contains(filter, true) == true } p.isVisible = visible @@ -405,7 +405,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang } else { if (pref.key.contains("pin")) { pref.summary = rh.gs(R.string.pin_not_set) - }else { + } else { pref.summary = rh.gs(R.string.password_not_set) } } diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt index d199ee8391..406286242c 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppComponent.kt @@ -11,7 +11,6 @@ import info.nightscout.androidaps.dana.di.DanaModule import info.nightscout.androidaps.danar.di.DanaRModule import info.nightscout.androidaps.danars.di.DanaRSModule import info.nightscout.androidaps.database.DatabaseModule -import info.nightscout.androidaps.dependencyInjection.AutotuneModule import info.nightscout.androidaps.diaconn.di.DiaconnG8Module import info.nightscout.androidaps.insight.di.InsightDatabaseModule import info.nightscout.androidaps.insight.di.InsightModule @@ -40,7 +39,6 @@ import javax.inject.Singleton FragmentsModule::class, ReceiversModule::class, ServicesModule::class, - AutotuneModule::class, ObjectivesModule::class, WizardModule::class, APSModule::class, diff --git a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt index 3b3c2424d5..d4abd543c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -42,7 +42,6 @@ import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.PluginStore 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.PrefFileListProvider 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.TddCalculatorImpl import info.nightscout.implementation.stats.TirCalculatorImpl +import info.nightscout.plugins.general.autotune.AutotunePlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt index a2293a3bc5..07af8b35bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt @@ -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.activities.ObjectivesExamDialog 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.nsclient.NSClientFragment import info.nightscout.androidaps.plugins.general.overview.OverviewFragment import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment 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.source.BGSourceFragment import info.nightscout.androidaps.utils.protection.PasswordCheck +import info.nightscout.plugins.general.autotune.AutotuneFragment @Module @Suppress("unused") @@ -48,10 +47,7 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment @ContributesAndroidInjector abstract fun contributesAutotuneFragment(): AutotuneFragment @ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment - @ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment - - @ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment @ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment @ContributesAndroidInjector abstract fun contributesOpenAPSFragment(): OpenAPSFragment @ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment diff --git a/app/src/main/java/info/nightscout/androidaps/di/PluginsListModule.kt b/app/src/main/java/info/nightscout/androidaps/di/PluginsListModule.kt index a8d3838096..2ef2125e4f 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/PluginsListModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/PluginsListModule.kt @@ -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.versionChecker.VersionCheckerPlugin 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.plugins.general.food.FoodPlugin import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin 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.wear.WearPlugin 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.eopatch.EopatchPumpPlugin 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.XdripPlugin 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.themes.ThemeSwitcherPlugin import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin import info.nightscout.plugins.insulin.InsulinLyumjevPlugin import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin +import info.nightscout.plugins.profile.ProfilePlugin import javax.inject.Qualifier @Suppress("unused") diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt index 1ccdd3b467..fdcf2a87ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt @@ -7,17 +7,23 @@ import androidx.core.content.FileProvider import dagger.android.HasAndroidInjector import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.R +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginDescription 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.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 java.io.* -import java.util.* +import java.io.BufferedInputStream +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.ZipOutputStream import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt index a6f96631d8..5bcb4ddf82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.kt @@ -51,7 +51,6 @@ import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton -import kotlin.math.floor import kotlin.math.max import kotlin.math.min @@ -450,23 +449,6 @@ class IobCobCalculatorPlugin @Inject constructor( 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, 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 * @return milliseconds diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.kt index dee4efb932..9550e9f8f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.kt @@ -12,18 +12,18 @@ 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.ResourceHelper 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.AutosensResult -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin 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 org.json.JSONException import org.json.JSONObject -import java.util.* +import java.util.Arrays import javax.inject.Inject import javax.inject.Singleton import kotlin.math.roundToInt @@ -116,7 +116,7 @@ class SensitivityAAPSPlugin @Inject constructor( val sensResult: String aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity") 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 ratio = 1 + basalOff / profile.getMaxDailyBasal() sensResult = when { @@ -126,13 +126,16 @@ class SensitivityAAPSPlugin @Inject constructor( } aapsLogger.debug(LTag.AUTOSENS, sensResult) - val output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit, - sensResult, deviationsArray.size) + val output = fillResult( + ratio, current.cob, pastSensitivity, ratioLimit, + sensResult, deviationsArray.size + ) aapsLogger.debug( LTag.AUTOSENS, "Sensitivity to: " - + dateUtil.dateAndTimeString(toTime) + - " ratio: " + output.ratio - + " mealCOB: " + current.cob) + + dateUtil.dateAndTimeString(toTime) + + " ratio: " + output.ratio + + " mealCOB: " + current.cob + ) aapsLogger.debug(LTag.AUTOSENS, "Sensitivity to: deviations " + deviations.contentToString()) return output } @@ -158,7 +161,10 @@ class SensitivityAAPSPlugin @Inject constructor( override fun applyConfiguration(configuration: JSONObject) { 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_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_min))) sp.getDouble(R.string.key_openapsama_autosens_min, configuration.getDouble(rh.gs(R.string.key_openapsama_autosens_min))) } catch (e: JSONException) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.kt index cccd3cbeff..34ace702d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.kt @@ -12,19 +12,19 @@ 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.ResourceHelper 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.iob.iobCobCalculator.AutosensDataStore 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.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 org.json.JSONException import org.json.JSONObject -import java.util.* +import java.util.Arrays import javax.inject.Inject import javax.inject.Singleton import kotlin.math.roundToInt @@ -75,7 +75,7 @@ class SensitivityOref1Plugin @Inject constructor( //[0] = 8 hour //[1] = 24 hour //deviationsHour has DeviationsArray - val deviationsHour = mutableListOf(ArrayList(), ArrayList()) + val deviationsHour = mutableListOf(ArrayList(), ArrayList()) val pastSensitivityArray = mutableListOf("", "") val sensResultArray = mutableListOf("", "") val ratioArray = mutableListOf(0.0, 0.0) @@ -160,8 +160,8 @@ class SensitivityOref1Plugin @Inject constructor( val sens = profile.getIsfMgdl() aapsLogger.debug(LTag.AUTOSENS, "Records: $index $pastSensitivity") Arrays.sort(deviations) - val pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50) - val pResistant = IobCobCalculatorPlugin.percentile(deviations, 0.50) + val pSensitive = Percentile.percentile(deviations, 0.50) + val pResistant = Percentile.percentile(deviations, 0.50) var basalOff = 0.0 when { pSensitive < 0 -> { // sensitive @@ -196,9 +196,10 @@ class SensitivityOref1Plugin @Inject constructor( val output = fillResult(ratioArray[key], current.cob, pastSensitivityArray[key], ratioLimitArray[key], sensResultArray[key] + comparison, deviationsHour[key].size) aapsLogger.debug( LTag.AUTOSENS, "Sensitivity to: " - + dateUtil.dateAndTimeString(toTime) + - " ratio: " + output.ratio - + " mealCOB: " + current.cob) + + dateUtil.dateAndTimeString(toTime) + + " ratio: " + output.ratio + + " mealCOB: " + current.cob + ) return output } @@ -219,7 +220,10 @@ class SensitivityOref1Plugin @Inject constructor( override fun applyConfiguration(configuration: JSONObject) { 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_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))) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7e139e9eaa..e8ce54c71b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -270,8 +270,6 @@ Show queue Queue: Status: - nsclientinternal_url - nsclientinternal_api_secret Clear log nsclientinternal_autoscroll nsclientinternal_paused @@ -529,7 +527,6 @@ Basals Running dev version. Closed loop is disabled. Engineering mode enabled - ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile. Pump is not temp basal capable Closed loop mode disabled in preferences Autosens disabled in preferences diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePluginTest.kt index a055f7c519..76a0af8d38 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePluginTest.kt @@ -3,10 +3,11 @@ package info.nightscout.androidaps.plugins.general.maintenance import android.content.Context import dagger.android.HasAndroidInjector 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.Config 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 org.junit.Assert import org.junit.Before @@ -27,7 +28,7 @@ class MaintenancePluginTest : TestBase() { @Mock lateinit var fileListProvider: PrefFileListProvider @Mock lateinit var config: Config - lateinit var sut: MaintenancePlugin + private lateinit var sut: MaintenancePlugin @Before fun mock() { diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index a98747c804..1cd4f3cd4c 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -86,6 +86,8 @@ rangetodisplay local_profile_last_change ns_receive_profile_store + nsclientinternal_url + nsclientinternal_api_secret Refresh @@ -233,6 +235,8 @@ REMOVE Activate profile reset + ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile. + Profile Limiting max basal rate to %1$.2f U/h because of %2$s diff --git a/app/src/main/java/info/nightscout/androidaps/di/AutotuneModule.kt b/plugins/src/main/java/info/nightscout/plugins/di/AutotuneModule.kt similarity index 60% rename from app/src/main/java/info/nightscout/androidaps/di/AutotuneModule.kt rename to plugins/src/main/java/info/nightscout/plugins/di/AutotuneModule.kt index eaed4a09db..36259705e0 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AutotuneModule.kt +++ b/plugins/src/main/java/info/nightscout/plugins/di/AutotuneModule.kt @@ -1,12 +1,15 @@ -package info.nightscout.androidaps.dependencyInjection +package info.nightscout.plugins.di import dagger.Module import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.plugins.general.autotune.AutotuneCore -import info.nightscout.androidaps.plugins.general.autotune.AutotuneIob -import info.nightscout.androidaps.plugins.general.autotune.AutotunePrep -import info.nightscout.androidaps.plugins.general.autotune.AutotuneFS -import info.nightscout.androidaps.plugins.general.autotune.data.* +import info.nightscout.plugins.general.autotune.AutotuneCore +import info.nightscout.plugins.general.autotune.AutotuneFS +import info.nightscout.plugins.general.autotune.AutotuneIob +import info.nightscout.plugins.general.autotune.AutotunePrep +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 @Suppress("unused") diff --git a/plugins/src/main/java/info/nightscout/plugins/di/PluginsModule.kt b/plugins/src/main/java/info/nightscout/plugins/di/PluginsModule.kt index d634f23bed..086dad48e1 100644 --- a/plugins/src/main/java/info/nightscout/plugins/di/PluginsModule.kt +++ b/plugins/src/main/java/info/nightscout/plugins/di/PluginsModule.kt @@ -6,7 +6,9 @@ import dagger.Module includes = [ InsulinModule::class, FoodModule::class, - SMSCommunicatorModule::class + SMSCommunicatorModule::class, + AutotuneModule::class, + ProfileModule::class ] ) diff --git a/plugins/src/main/java/info/nightscout/plugins/di/ProfileModule.kt b/plugins/src/main/java/info/nightscout/plugins/di/ProfileModule.kt new file mode 100644 index 0000000000..b39aff6f75 --- /dev/null +++ b/plugins/src/main/java/info/nightscout/plugins/di/ProfileModule.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneCore.kt similarity index 90% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneCore.kt index d0dc4da9be..713540de25 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneCore.kt @@ -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.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.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 java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.max @Singleton class AutotuneCore @Inject constructor( @@ -47,8 +48,7 @@ class AutotuneCore @Inject constructor( // tune DIA var newDia = dia - if (diaDeviations.size > 0) - { + if (diaDeviations.isNotEmpty()) { val currentDiaMeanDev = diaDeviations[2].meanDeviation val currentDiaRMSDev = diaDeviations[2].rmsDeviation //Console.WriteLine(DIA,currentDIAMeanDev,currentDIARMSDev); @@ -56,35 +56,28 @@ class AutotuneCore @Inject constructor( var minRmsDeviations = 1000000.0 var meanBest = 2 var rmsBest = 2 - for (i in 0..diaDeviations.size-1) - { + for (i in diaDeviations.indices) { val meanDeviations = diaDeviations[i].meanDeviation val rmsDeviations = diaDeviations[i].rmsDeviation - if (meanDeviations < minMeanDeviations) - { + if (meanDeviations < minMeanDeviations) { minMeanDeviations = Round.roundTo(meanDeviations, 0.001) meanBest = i } - if (rmsDeviations < minRmsDeviations) - { + if (rmsDeviations < minRmsDeviations) { minRmsDeviations = Round.roundTo(rmsDeviations, 0.001) rmsBest = i } } log("Best insulinEndTime for meanDeviations: ${diaDeviations[meanBest].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) 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) newDia = diaDeviations[3].dia } - if (newDia > 12.0) - { + if (newDia > 12.0) { log("insulinEndTime maximum is 12h: not raising further") newDia = 12.0 } @@ -96,8 +89,7 @@ class AutotuneCore @Inject constructor( // tune insulinPeakTime var newPeak = peak - if (peakDeviations.size > 2) - { + if (peakDeviations.size > 2) { val currentPeakMeanDev = peakDeviations[2].meanDeviation val currentPeakRMSDev = peakDeviations[2].rmsDeviation //Console.WriteLine(currentPeakMeanDev); @@ -105,37 +97,31 @@ class AutotuneCore @Inject constructor( var minRmsDeviations = 1000000.0 var meanBest = 2 var rmsBest = 2 - for (i in 0..peakDeviations.size-1) - { - val meanDeviations = peakDeviations[i].meanDeviation; - val rmsDeviations = peakDeviations[i].rmsDeviation; - if (meanDeviations < minMeanDeviations) - { + for (i in peakDeviations.indices) { + val meanDeviations = peakDeviations[i].meanDeviation + val rmsDeviations = peakDeviations[i].rmsDeviation + if (meanDeviations < minMeanDeviations) { minMeanDeviations = Round.roundTo(meanDeviations, 0.001) meanBest = i } - if (rmsDeviations < minRmsDeviations) - { + if (rmsDeviations < minRmsDeviations) { minRmsDeviations = Round.roundTo(rmsDeviations, 0.001) rmsBest = i } } log("Best insulinPeakTime for meanDeviations: ${peakDeviations[meanBest].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) 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) newPeak = peakDeviations[3].peak } if (newPeak != peak) - log("Adjusting insulinPeakTime from " + peak + " to " + newPeak + " minutes") + log("Adjusting insulinPeakTime from $peak to $newPeak minutes") else - log("Leaving insulinPeakTime unchanged at " + peak) + log("Leaving insulinPeakTime unchanged at $peak") } // Calculate carb ratio (CR) independently of csf and isf @@ -180,22 +166,22 @@ class AutotuneCore @Inject constructor( for (i in 0..23) { newHourlyBasalProfile[i] = hourlyBasalProfile[i] } - val basalUntuned = previousAutotune.basalUntuned + val basalUnTuned = previousAutotune.basalUntuned //autotune-core (lib/autotune/index.js) #210-#266 // look at net deviations for each hour for (hour in 0..23) { var deviations = 0.0 for (i in basalGlucose.indices) { - val BGTime = Calendar.getInstance() + val bgTime = Calendar.getInstance() //var BGTime: Date? = null if (basalGlucose[i].date != 0L) { - BGTime.setTimeInMillis(basalGlucose[i].date) + bgTime.timeInMillis = basalGlucose[i].date //BGTime = Date(basalGlucose[i].date) } else { 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 if (hour == myHour) { //log.debug(basalGlucose[i].deviation); @@ -280,7 +266,7 @@ class AutotuneCore @Inject constructor( } //log.debug(hour, newHourlyBasalProfile); 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]) } else { lastAdjustedHour = hour @@ -301,7 +287,6 @@ class AutotuneCore @Inject constructor( var mealCarbs = 0 var totalMealCarbs = 0 var totalDeviations = 0.0 - val fullNewCSF: Double //log.debug(CSFGlucose[0].mealAbsorption); //log.debug(CSFGlucose[0]); //autotune-core (lib/autotune/index.js) #346-#365 @@ -321,8 +306,8 @@ class AutotuneCore @Inject constructor( totalDeviations += deviations } else { //todo Philoul check 0 * min5minCarbImpact ??? - deviations += Math.max(0 * min5minCarbImpact, csfGlucose[i].deviation) - mealCarbs = Math.max(mealCarbs, csfGlucose[i].mealCarbs) + deviations += max(0 * min5minCarbImpact, csfGlucose[i].deviation) + 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) @@ -334,7 +319,7 @@ class AutotuneCore @Inject constructor( totalDeviations += deviations } //log.debug(totalDeviations, totalMealCarbs); - fullNewCSF = if (totalMealCarbs == 0) { + val fullNewCSF: Double = if (totalMealCarbs == 0) { // if no meals today, csf is unchanged csf } else { @@ -420,22 +405,22 @@ class AutotuneCore @Inject constructor( for (i in isfGlucose.indices) { val deviation = isfGlucose[i].deviation isfDeviations.add(deviation) - val BGI = isfGlucose[i].bgi - bGIs.add(BGI) + val bgi = isfGlucose[i].bgi + bGIs.add(bgi) val avgDelta = isfGlucose[i].avgDelta avgDeltas.add(avgDelta) - val ratio = 1 + deviation / BGI + val ratio = 1 + deviation / bgi //log.debug("Deviation:",deviation,"BGI:",BGI,"avgDelta:",avgDelta,"ratio:",ratio); ratios.add(ratio) count++ } - Collections.sort(avgDeltas) - Collections.sort(bGIs) - Collections.sort(isfDeviations) - Collections.sort(ratios) - var p50deviation = IobCobCalculatorPlugin.percentile(isfDeviations.toTypedArray(), 0.50) - var p50BGI = IobCobCalculatorPlugin.percentile(bGIs.toTypedArray(), 0.50) - val p50ratios = Round.roundTo(IobCobCalculatorPlugin.percentile(ratios.toTypedArray(), 0.50), 0.001) + avgDeltas.sort() + bGIs.sort() + isfDeviations.sort() + ratios.sort() + var p50deviation = Percentile.percentile(isfDeviations.toTypedArray(), 0.50) + var p50BGI = Percentile.percentile(bGIs.toTypedArray(), 0.50) + val p50ratios = Round.roundTo(Percentile.percentile(ratios.toTypedArray(), 0.50), 0.001) var fullNewISF = isf if (count < 10) { // leave isf unchanged if fewer than 5 isf data points @@ -446,13 +431,12 @@ class AutotuneCore @Inject constructor( } fullNewISF = Round.roundTo(fullNewISF, 0.001) // 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 ?) if (typeof(pumpProfile.autotune_isf_adjustmentFraction) !== 'undefined') { adjustmentFraction = pumpProfile.autotune_isf_adjustmentFraction; } else {*/ - adjustmentFraction = 1.0 + val adjustmentFraction = 1.0 // } // low autosens ratio = high isf @@ -501,7 +485,7 @@ class AutotuneCore @Inject constructor( previousAutotune.basal = basalProfile previousAutotune.isf = isf previousAutotune.ic = Round.roundTo(carbRatio, 0.001) - previousAutotune.basalUntuned = basalUntuned + previousAutotune.basalUntuned = basalUnTuned previousAutotune.dia = newDia previousAutotune.peak = newPeak val localInsulin = LocalInsulin("Ins_$newPeak-$newDia", newPeak, newDia) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFS.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFS.kt similarity index 93% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFS.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFS.kt index 5f1d3a9959..317e1d5c07 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFS.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFS.kt @@ -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.plugins.general.autotune.data.ATProfile -import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose -import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils -import info.nightscout.androidaps.R +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.maintenance.LoggerUtils import org.json.JSONException 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.util.zip.ZipEntry import java.util.zip.ZipOutputStream @@ -28,7 +36,6 @@ class AutotuneFS @Inject constructor( val AAPSBOLUSESPREF = "aaps-boluses." val PREPPEDPREF = "aaps-autotune." val SETTINGS = "settings.json" - val PROFIL = "profil" val PUMPPROFILE = "pumpprofile.json" val TUNEDPROFILE = "newaapsprofile." val LOGPREF = "autotune." diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFragment.kt similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFragment.kt index 497182f6b4..42ccf771d8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneFragment.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.autotune +package info.nightscout.plugins.general.autotune import android.content.Context import android.graphics.Paint @@ -20,12 +20,10 @@ import android.widget.TextView import dagger.android.HasAndroidInjector import dagger.android.support.DaggerFragment import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.LocalInsulin import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.ValueWithUnit -import info.nightscout.androidaps.databinding.AutotuneFragmentBinding import info.nightscout.androidaps.dialogs.ProfileViewerDialog import info.nightscout.androidaps.extensions.runOnUiThread 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.logging.UserEntryLogger 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.FabricPrivacy import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation 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.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -126,7 +126,7 @@ class AutotuneFragment : DaggerFragment() { updateGui() } - binding.autotuneCopylocal.setOnClickListener { + binding.autotuneCopyLocal.setOnClickListener { 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) autotunePlugin.tunedProfile?.let { tunedProfile -> @@ -265,14 +265,14 @@ class AutotuneFragment : DaggerFragment() { } } - binding.tuneLastrun.setOnClickListener { + binding.tuneLastRun.setOnClickListener { if (!autotunePlugin.calculationRunning) { autotunePlugin.loadLastRun() binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble() updateGui() } } - binding.tuneLastrun.paintFlags = binding.tuneLastrun.paintFlags or Paint.UNDERLINE_TEXT_FLAG + binding.tuneLastRun.paintFlags = binding.tuneLastRun.paintFlags or Paint.UNDERLINE_TEXT_FLAG } @Synchronized @@ -315,7 +315,7 @@ class AutotuneFragment : DaggerFragment() { } binding.autotuneRun.visibility = View.GONE binding.autotuneCheckInputProfile.visibility = View.GONE - binding.autotuneCopylocal.visibility = View.GONE + binding.autotuneCopyLocal.visibility = View.GONE binding.autotuneUpdateProfile.visibility = View.GONE binding.autotuneRevertProfile.visibility = View.GONE binding.autotuneProfileswitch.visibility = View.GONE @@ -326,7 +326,7 @@ class AutotuneFragment : DaggerFragment() { } autotunePlugin.lastRunSuccess -> { - binding.autotuneCopylocal.visibility = View.VISIBLE + binding.autotuneCopyLocal.visibility = View.VISIBLE binding.autotuneUpdateProfile.visibility = autotunePlugin.updateButtonVisibility binding.autotuneRevertProfile.visibility = if (autotunePlugin.updateButtonVisibility == View.VISIBLE) View.GONE else View.VISIBLE binding.autotuneProfileswitch.visibility = View.VISIBLE @@ -339,7 +339,7 @@ class AutotuneFragment : DaggerFragment() { binding.autotuneCheckInputProfile.visibility = View.VISIBLE } } - binding.tuneLastrun.text = dateUtil.dateAndTimeString(autotunePlugin.lastRun) + binding.tuneLastRun.text = dateUtil.dateAndTimeString(autotunePlugin.lastRun) showResults() } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneIob.kt similarity index 94% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneIob.kt index 649838a0b0..a16f7d1cc1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotuneIob.kt @@ -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.R import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.data.LocalInsulin import info.nightscout.androidaps.database.AppRepository 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.iobCalc import info.nightscout.androidaps.extensions.toJson import info.nightscout.androidaps.extensions.toTemporaryBasal -import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Profile 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.Round 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.LTag import info.nightscout.shared.sharedPreferences.SP import org.json.JSONArray import org.json.JSONObject -import java.util.* import javax.inject.Inject import javax.inject.Singleton import kotlin.math.ceil @@ -44,7 +47,7 @@ open class AutotuneIob @Inject constructor( lateinit var glucose: List // newest at index 0 private lateinit var tempBasals: ArrayList 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() 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 { - val bolusIob = getCalculationToTimeTreatments(time, localInsulin).round() - return bolusIob + return getCalculationToTimeTreatments(time, localInsulin).round() } - fun getCalculationToTimeTreatments(time: Long, localInsulin: LocalInsulin): IobTotal { + private fun getCalculationToTimeTreatments(time: Long, localInsulin: LocalInsulin): IobTotal { val total = IobTotal(time) val detailedLog = sp.getBoolean(R.string.key_autotune_additional_log, false) for (pos in boluses.indices) { @@ -257,7 +259,7 @@ open class AutotuneIob @Inject constructor( } - fun convertToBoluses(eb: ExtendedBolus): MutableList { + private fun convertToBoluses(eb: ExtendedBolus): MutableList { val result: MutableList = ArrayList() val aboutFiveMinIntervals = ceil(eb.duration / 5.0).toInt() val spacing = eb.duration / aboutFiveMinIntervals.toDouble() @@ -277,7 +279,7 @@ open class AutotuneIob @Inject constructor( return result } - fun convertToBoluses(tbr: TemporaryBasal, profile: Profile, tunedProfile: Profile): MutableList { + private fun convertToBoluses(tbr: TemporaryBasal, profile: Profile, tunedProfile: Profile): MutableList { val result: MutableList = ArrayList() val realDuration = tbr.durationInMinutes val basalRate = profile.getBasal(tbr.timestamp) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePlugin.kt similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePlugin.kt index c501923173..9626a941a0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePlugin.kt @@ -1,32 +1,41 @@ -package info.nightscout.androidaps.plugins.general.autotune +package info.nightscout.plugins.general.autotune import android.view.View import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.R import info.nightscout.androidaps.data.LocalInsulin import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.ValueWithUnit 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.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.JsonHelper import info.nightscout.androidaps.utils.MidnightTime 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.LTag import info.nightscout.shared.sharedPreferences.SP import org.json.JSONException import org.json.JSONObject -import java.util.* +import java.util.TimeZone import javax.inject.Inject import javax.inject.Singleton @@ -54,17 +63,19 @@ class AutotunePlugin @Inject constructor( private val buildHelper: BuildHelper, private val uel: UserEntryLogger, aapsLogger: AAPSLogger -) : PluginBase(PluginDescription() - .mainType(PluginType.GENERAL) - .fragmentClass(AutotuneFragment::class.qualifiedName) - .pluginIcon(R.drawable.ic_autotune) - .pluginName(R.string.autotune) - .shortName(R.string.autotune_shortname) - .preferencesId(R.xml.pref_autotune) - .showInList(buildHelper.isEngineeringMode() && buildHelper.isDev()) - .description(R.string.autotune_description), +) : PluginBase( + PluginDescription() + .mainType(PluginType.GENERAL) + .fragmentClass(AutotuneFragment::class.qualifiedName) + .pluginIcon(R.drawable.ic_autotune) + .pluginName(R.string.autotune) + .shortName(R.string.autotune_shortname) + .preferencesId(R.xml.pref_autotune) + .showInList(buildHelper.isEngineeringMode() && buildHelper.isDev()) + .description(R.string.autotune_description), aapsLogger, resourceHelper, injector ), Autotune { + @Volatile override var lastRunSuccess: Boolean = false @Volatile var result: String = "" @Volatile override var calculationRunning: Boolean = false @@ -106,7 +117,7 @@ class AutotunePlugin @Inject constructor( calculationRunning = false return } - selectedProfile = if (profileToTune.isEmpty()) profileFunction.getProfileName() else profileToTune + selectedProfile = profileToTune.ifEmpty { profileFunction.getProfileName() } profileFunction.getProfile()?.let { 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 to = from + 24 * 60 * 60 * 1000L 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) if (autotuneIob.boluses.size == 0) { result = rh.gs(R.string.autotune_error) @@ -209,7 +220,8 @@ class AutotunePlugin @Inject constructor( UserEntry.Action.PROFILE_SWITCH, UserEntry.Sources.Automation, rh.gs(R.string.autotune), - ValueWithUnit.SimpleString(tunedP.profilename)) + ValueWithUnit.SimpleString(tunedP.profilename) + ) } rxBus.send(EventLocalProfileChanged()) } @@ -265,8 +277,8 @@ class AutotunePlugin @Inject constructor( val jsonSettings = JSONObject() val insulinInterface = activePlugin.activeInsulin val utcOffset = T.msecs(TimeZone.getDefault().getOffset(dateUtil.now()).toLong()).hours() - val startDateString = dateUtil.toISOString(firstloopstart).substring(0,10) - val endDateString = dateUtil.toISOString(lastloopend - 24 * 60 * 60 * 1000L).substring(0,10) + val startDateString = dateUtil.toISOString(firstloopstart).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 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 "" @@ -291,7 +303,7 @@ class AutotunePlugin @Inject constructor( val peaktime: Int = insulinInterface.peak 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) jsonSettings.put("curve", "rapid-acting") else if (insulinInterface.id === Insulin.InsulinType.OREF_LYUMJEV) { @@ -304,7 +316,9 @@ class AutotunePlugin @Inject constructor( jsonSettings.put("insulinPeakTime", peaktime) } jsonString = jsonSettings.toString(4).replace("\\/", "/") - } catch (e: JSONException) { } + } catch (e: JSONException) { + aapsLogger.error(LTag.AUTOTUNE, e.localizedMessage ?: e.toString()) + } return jsonString } @@ -332,7 +346,7 @@ class AutotunePlugin @Inject constructor( fun saveLastRun() { val json = JSONObject() json.put("lastNbDays", lastNbDays) - json.put("lastRun",lastRun) + json.put("lastRun", lastRun) json.put("pumpProfile", pumpProfile.profile.toPureNsJson(dateUtil)) json.put("pumpProfileName", pumpProfile.profilename) json.put("pumpPeak", pumpProfile.peak) @@ -378,13 +392,14 @@ class AutotunePlugin @Inject constructor( atProfile.profilename = tunedProfileName atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned) 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", "") updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility") lastRunSuccess = true } catch (e: Exception) { + aapsLogger.error(LTag.AUTOTUNE, e.localizedMessage ?: e.toString()) } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePrep.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePrep.kt similarity index 82% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePrep.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePrep.kt index 63617e908e..a6e80ba27c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePrep.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/AutotunePrep.kt @@ -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.database.entities.GlucoseValue -import info.nightscout.androidaps.plugins.general.autotune.data.* import info.nightscout.androidaps.database.entities.Bolus 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.MidnightTime import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.T -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.plugins.R +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 java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.pow +import kotlin.math.roundToInt @Singleton class AutotunePrep @Inject constructor( - private val aapsLogger: AAPSLogger, private val sp: SP, private val dateUtil: DateUtil, private val autotuneFS: AutotuneFS, 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) if (tuneInsulin) { var minDeviations = 1000000.0 val diaDeviations: MutableList = ArrayList() val peakDeviations: MutableList = ArrayList() - val currentDIA = tunedprofile.localInsulin.dia - val currentPeak = tunedprofile.localInsulin.peak + val currentDIA = tunedProfile.localInsulin.dia + val currentPeak = tunedProfile.localInsulin.peak var dia = currentDIA - 2 val endDIA = currentDIA + 2 - while (dia <= endDIA) - { + while (dia <= endDIA) { var sqrtDeviations = 0.0 var deviations = 0.0 var deviationsSq = 0.0 val localInsulin = LocalInsulin("Ins_$currentPeak-$dia", currentPeak, dia) - val curve_output = categorizeBGDatums(tunedprofile, localInsulin, false) - val basalGlucose = curve_output?.basalGlucoseData + val curveOutput = categorizeBGDatums(tunedProfile, localInsulin, false) + val basalGlucose = curveOutput?.basalGlucoseData basalGlucose?.let { 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() if (hour == myHour) { - sqrtDeviations += Math.pow(Math.abs(basalGlucose[i].deviation), 0.5) - deviations += Math.abs(basalGlucose[i].deviation) - deviationsSq += Math.pow(basalGlucose[i].deviation, 2.0) + sqrtDeviations += abs(basalGlucose[i].deviation).pow(0.5) + deviations += abs(basalGlucose[i].deviation) + deviationsSq += basalGlucose[i].deviation.pow(2.0) } } } - val meanDeviation = Round.roundTo(Math.abs(deviations / basalGlucose.size), 0.001) - val smrDeviation = Round.roundTo(Math.pow(sqrtDeviations / basalGlucose.size, 2.0), 0.001) - val rmsDeviation = Round.roundTo(Math.pow(deviationsSq / basalGlucose.size, 0.5), 0.001) + val meanDeviation = Round.roundTo(abs(deviations / basalGlucose.size), 0.001) + val smrDeviation = Round.roundTo((sqrtDeviations / basalGlucose.size).pow(2.0), 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)") diaDeviations.add( DiaDeviation( @@ -85,31 +90,30 @@ class AutotunePrep @Inject constructor( minDeviations = 1000000.0 var peak = currentPeak - 10 val endPeak = currentPeak + 10 - while (peak <= endPeak) - { + while (peak <= endPeak) { var sqrtDeviations = 0.0 var deviations = 0.0 var deviationsSq = 0.0 val localInsulin = LocalInsulin("Ins_$peak-$currentDIA", peak, currentDIA) - val curve_output = categorizeBGDatums(tunedprofile, localInsulin, false) - val basalGlucose = curve_output?.basalGlucoseData + val curveOutput = categorizeBGDatums(tunedProfile, localInsulin, false) + val basalGlucose = curveOutput?.basalGlucoseData basalGlucose?.let { 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() if (hour == myHour) { //console.error(basalGlucose[i].deviation); - sqrtDeviations += Math.pow(Math.abs(basalGlucose[i].deviation), 0.5) - deviations += Math.abs(basalGlucose[i].deviation) - deviationsSq += Math.pow(basalGlucose[i].deviation, 2.0) + sqrtDeviations += abs(basalGlucose[i].deviation).pow(0.5) + deviations += abs(basalGlucose[i].deviation) + deviationsSq += basalGlucose[i].deviation.pow(2.0) } } } val meanDeviation = Round.roundTo(deviations / basalGlucose.size, 0.001) - val smrDeviation = Round.roundTo(Math.pow(sqrtDeviations / basalGlucose.size, 2.0), 0.001) - val rmsDeviation = Round.roundTo(Math.pow(deviationsSq / basalGlucose.size, 0.5), 0.001) + val smrDeviation = Round.roundTo((sqrtDeviations / basalGlucose.size).pow(2.0), 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)") peakDeviations.add( PeakDeviation @@ -122,7 +126,7 @@ class AutotunePrep @Inject constructor( ) } - deviations = Round.roundTo(deviations, 0.001); + deviations = Round.roundTo(deviations, 0.001) if (deviations < minDeviations) minDeviations = Round.roundTo(deviations, 0.001) peak += 5 @@ -136,7 +140,7 @@ class AutotunePrep @Inject constructor( } // 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) val treatments: MutableList = autotuneIob.meals val boluses: MutableList = autotuneIob.boluses @@ -148,14 +152,14 @@ class AutotunePrep @Inject constructor( 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") if (verbose) log("No BG value received") return null } - glucoseData.sortWith(object: Comparator{ 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 // boluses and maxCarbs not used here ?, @@ -189,10 +193,10 @@ class AutotunePrep @Inject constructor( var k = 0 // index of first value used by bucket //for loop to validate and bucket the data for (i in 1 until glucoseData.size) { - val BGTime = glucoseData[i].timestamp + val bgTime = glucoseData[i].timestamp val lastBGTime = glucoseData[k].timestamp - val elapsedMinutes = (BGTime - lastBGTime) / (60 * 1000) - if (Math.abs(elapsedMinutes) >= 2) { + val elapsedMinutes = (bgTime - lastBGTime) / (60 * 1000) + if (abs(elapsedMinutes) >= 2) { //j++; // move to next bucket k = i // store index of first value used by bucket bucketedData.add(BGDatum(glucoseData[i], dateUtil)) @@ -229,14 +233,14 @@ class AutotunePrep @Inject constructor( for (i in bucketedData.size - 5 downTo 1) { val glucoseDatum = bucketedData[i] //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 // the current BG data point. If so, add those carbs to COB. val treatment = if (treatments.size > 0) treatments[treatments.size - 1] else null var myCarbs = 0.0 if (treatment != null) { - if (treatment.timestamp < BGTime) { + if (treatment.timestamp < bgTime) { if (treatment.amount > 0.0) { mealCOB += treatment.amount mealCarbs += treatment.amount @@ -267,7 +271,7 @@ class AutotunePrep @Inject constructor( glucoseDatum.avgDelta = avgDelta //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; // 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 */ // 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. 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]; // 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) + "******************************************************************************************") - 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 - 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) - glucoseDatum.bgi = BGI + glucoseDatum.bgi = bgi // calculating deviation - var deviation = avgDelta - BGI + var deviation = avgDelta - bgi // set positive deviations to zero if BG is below 80 if (bg < 80 && deviation > 0) { @@ -309,10 +313,10 @@ class AutotunePrep @Inject constructor( // Then, calculate carb absorption for that 5m interval using the deviation. if (mealCOB > 0) { - val ci = Math.max(deviation, sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)) - val absorbed = ci * tunedprofile.ic / sens + val ci = max(deviation, sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)) + val absorbed = ci * tunedProfile.ic / sens // 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 @@ -323,7 +327,7 @@ class AutotunePrep @Inject constructor( if (mealCOB > 0 || calculatingCR) { // set initial values when we first see COB crCarbs += myCarbs - if (calculatingCR == false) { + if (!calculatingCR) { crInitialIOB = iob.iob crInitialBG = glucoseDatum.value crInitialCarbTime = glucoseDatum.date @@ -354,13 +358,13 @@ class AutotunePrep @Inject constructor( crDatum.crCarbs = crCarbs //log.debug(CRDatum); //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); - if (CRElapsedMinutes < 60 || i == 1 && mealCOB > 0) { + if (crElapsedMinutes < 60 || i == 1 && mealCOB > 0) { //aapsLogger.debug(LTag.AUTOTUNE, "Ignoring $CRElapsedMinutes m CR period.") if (verbose) - log("Ignoring $CRElapsedMinutes m CR period.") + log("Ignoring $crElapsedMinutes m CR period.") } else { crData.add(crDatum) } @@ -376,11 +380,7 @@ class AutotunePrep @Inject constructor( absorbing = if (iob.iob < currentBasal / 2) { false // otherwise, as long as deviations are positive, keep tracking carb deviations - } else if (deviation > 0) { - true - } else { - false - } + } else deviation > 0 if (!absorbing && mealCOB == 0.0) { mealCarbs = 0.0 } @@ -405,11 +405,7 @@ class AutotunePrep @Inject constructor( log("${csfGlucoseData[csfGlucoseData.size - 1].mealAbsorption} carb absorption") } if (iob.iob > 2 * currentBasal || deviation > 6 || uam) { - uam = if (deviation > 0) { - true - } else { - false - } + uam = deviation > 0 if (type != "uam") { glucoseDatum.uamAbsorption = "start" //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 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 - if (basalBGI > -4 * BGI) { + if (basalBGI > -4 * bgi) { type = "basal" basalGlucoseData.add(glucoseDatum) } else { - if (avgDelta > 0 && avgDelta > -2 * BGI) { + if (avgDelta > 0 && avgDelta > -2 * bgi) { //type="unknown" type = "basal" basalGlucoseData.add(glucoseDatum) @@ -449,8 +445,12 @@ class AutotunePrep @Inject constructor( // 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") 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 - .roundTo(BGI, 0.1)} IOB: ${iob.iob} Activity: ${iob.activity} at ${dateUtil.timeStringWithSeconds(BGTime)} dev: $deviation avgDelta: $avgDelta $type") + log( + "${(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) } // categorize.js Lines 384-436 - val CSFLength = csfGlucoseData.size - var ISFLength = isfGlucoseData.size - val UAMLength = uamGlucoseData.size + val csfLength = csfGlucoseData.size + var isfLength = isfGlucoseData.size + val uamLength = uamGlucoseData.size var basalLength = basalGlucoseData.size if (sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)) { //aapsLogger.debug(LTag.AUTOTUNE, "Categorizing all UAM data as basal.") if (verbose) log("Categorizing all UAM data as basal.") 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.") if (verbose) log("Found at least 1h of carb: assuming meals were announced, and categorizing UAM data as basal.") basalGlucoseData.addAll(uamGlucoseData) } else { - if (2 * basalLength < UAMLength) { + if (2 * basalLength < uamLength) { //log.debug(basalGlucoseData, UAMGlucoseData); //aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as UnAnnounced Meals") //aapsLogger.debug(LTag.AUTOTUNE, "Adding $UAMLength UAM deviations to $basalLength basal ones") if (verbose) { 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) //log.debug(basalGlucoseData); // if too much data is excluded as UAM, add in the UAM deviations, but then discard the highest 50% - basalGlucoseData.sortWith(object: Comparator{ 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 = ArrayList() for (i in 0 until basalGlucoseData.size / 2) { newBasalGlucose.add(basalGlucoseData[i]) @@ -497,13 +497,13 @@ class AutotunePrep @Inject constructor( if (verbose) 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") if (verbose) - log("Adding $UAMLength UAM deviations to $ISFLength ISF ones") + log("Adding $uamLength UAM deviations to $isfLength ISF ones") isfGlucoseData.addAll(uamGlucoseData) // 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{ 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 = ArrayList() for (i in 0 until isfGlucoseData.size / 2) { newISFGlucose.add(isfGlucoseData[i]) @@ -517,15 +517,15 @@ class AutotunePrep @Inject constructor( } } basalLength = basalGlucoseData.size - ISFLength = isfGlucoseData.size - if (4 * basalLength + ISFLength < CSFLength && ISFLength < 10) { + isfLength = isfGlucoseData.size + if (4 * basalLength + isfLength < csfLength && isfLength < 10) { //aapsLogger.debug(LTag.AUTOTUNE, "Warning: too many deviations categorized as meals") //aapsLogger.debug(LTag.AUTOTUNE, "Adding $CSFLength CSF deviations to $ISFLength ISF ones") if (verbose) { log("Warning: too many deviations categorized as meals") //log.debug("Adding",CSFLength,"CSF deviations to",basalLength,"basal ones"); //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) csfGlucoseData = ArrayList() @@ -543,7 +543,7 @@ class AutotunePrep @Inject constructor( private fun dosed(start: Long, end: Long, treatments: List): Double { var insulinDosed = 0.0 //aapsLogger.debug(LTag.AUTOTUNE, "No treatments to process.") - if (treatments.size == 0) { + if (treatments.isEmpty()) { log("No treatments to process.") return 0.0 } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/ATProfile.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/ATProfile.kt similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/ATProfile.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/ATProfile.kt index d3d9d947dd..c5394c9312 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/ATProfile.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/ATProfile.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.general.autotune.data +package info.nightscout.plugins.general.autotune.data import dagger.android.HasAndroidInjector 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.extensions.blockValueBySeconds 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.utils.DateUtil import info.nightscout.androidaps.utils.Round @@ -19,7 +26,7 @@ import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.text.DecimalFormat -import java.util.* +import java.util.TimeZone import javax.inject.Inject 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 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 fun basal() = jsonArray(basal) fun ic(circadian: Boolean = false): JSONArray { - if(circadian) - return jsonArray(pumpProfile.icBlocks, avgIC/pumpProfileAvgIC) + if (circadian) + return jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC) return jsonArray(ic) } + fun isf(circadian: Boolean = false): JSONArray { - if(circadian) - return jsonArray(pumpProfile.isfBlocks, avgISF/pumpProfileAvgISF) + if (circadian) + return jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF) return jsonArray(Profile.fromMgdlToUnits(isf, profile.units)) } @@ -88,7 +96,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: fun profiletoOrefJSON(): String { var jsonString = "" val json = JSONObject() - val insulinInterface: Insulin = activePlugin.activeInsulin + val insulinInterface: Insulin = activePlugin.activeInsulin try { json.put("name", profilename) json.put("min_5m_carbimpact", sp.getDouble("openapsama_min_5m_carbimpact", 3.0)) @@ -115,7 +123,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: JSONObject() .put("start", time) .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("timezone", TimeZone.getDefault().id) jsonString = json.toString(2).replace("\\/", "/") - } catch (e: JSONException) {} + } catch (e: JSONException) { + } return jsonString } @@ -144,8 +154,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: try { json.put("dia", dia) if (circadian) { - json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF/pumpProfileAvgISF)) - json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC/pumpProfileAvgIC)) + json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF)) + json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC)) } else { json.put("sens", jsonArray(Profile.fromMgdlToUnits(isf, profile.units))) 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) } - fun profileStore(circadian: Boolean = false): ProfileStore? - { + fun profileStore(circadian: Boolean = false): ProfileStore? { var profileStore: ProfileStore? = null val json = JSONObject() val store = JSONObject() @@ -170,7 +179,8 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector: json.put("store", store) json.put("startDate", dateUtil.toISOAsUTC(dateUtil.now())) profileStore = ProfileStore(injector, json, dateUtil) - } catch (e: JSONException) { } + } catch (e: JSONException) { + } return profileStore } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/BGDatum.kt similarity index 95% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/BGDatum.kt index 7d2f7b6f8c..176aaf9237 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/BGDatum.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/BGDatum.kt @@ -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.TrendArrow import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T import org.json.JSONException import org.json.JSONObject -import java.util.* +import java.util.TimeZone /** * Created by Rumen Georgiev on 2/24/2018. */ class BGDatum { + //Added by Rumen for autotune var id: Long = 0 var date = 0L @@ -27,7 +28,10 @@ class BGDatum { private set var dateUtil: DateUtil - constructor(dateUtil: DateUtil) { this.dateUtil = dateUtil} + constructor(dateUtil: DateUtil) { + this.dateUtil = dateUtil + } + constructor(json: JSONObject, dateUtil: DateUtil) { this.dateUtil = dateUtil try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/CRDatum.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/CRDatum.kt similarity index 95% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/CRDatum.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/CRDatum.kt index 5e4c83dc99..44a802e5a4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/CRDatum.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/CRDatum.kt @@ -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 org.json.JSONException @@ -20,7 +20,10 @@ class CRDatum { var crInsulinTotal = 0.0 var dateUtil: DateUtil - constructor(dateUtil: DateUtil) { this.dateUtil = dateUtil} + constructor(dateUtil: DateUtil) { + this.dateUtil = dateUtil + } + constructor(json: JSONObject, dateUtil: DateUtil) { this.dateUtil = dateUtil try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/DiaDeviation.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/DiaDeviation.kt similarity index 93% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/DiaDeviation.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/DiaDeviation.kt index 9be016d39c..c774d33e1f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/DiaDeviation.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/DiaDeviation.kt @@ -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.JSONObject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PeakDeviation.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PeakDeviation.kt similarity index 93% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PeakDeviation.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PeakDeviation.kt index c9e3f66581..703fc42235 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PeakDeviation.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PeakDeviation.kt @@ -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.JSONObject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PreppedGlucose.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PreppedGlucose.kt similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PreppedGlucose.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PreppedGlucose.kt index 3015dd6122..6b5cc6fc27 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/data/PreppedGlucose.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/data/PreppedGlucose.kt @@ -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 org.json.JSONArray import org.json.JSONException import org.json.JSONObject -import java.util.* class PreppedGlucose { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/events/EventAutotuneUpdateGui.kt b/plugins/src/main/java/info/nightscout/plugins/general/autotune/events/EventAutotuneUpdateGui.kt similarity index 56% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/events/EventAutotuneUpdateGui.kt rename to plugins/src/main/java/info/nightscout/plugins/general/autotune/events/EventAutotuneUpdateGui.kt index 2a607d475e..7adff76e9d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/events/EventAutotuneUpdateGui.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/autotune/events/EventAutotuneUpdateGui.kt @@ -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 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/LoggerUtils.kt b/plugins/src/main/java/info/nightscout/plugins/general/maintenance/LoggerUtils.kt similarity index 53% rename from app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/LoggerUtils.kt rename to plugins/src/main/java/info/nightscout/plugins/general/maintenance/LoggerUtils.kt index 888c6ff71c..b572292ab2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/LoggerUtils.kt +++ b/plugins/src/main/java/info/nightscout/plugins/general/maintenance/LoggerUtils.kt @@ -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.plugins.general.maintenance.PrefFileListProvider import javax.inject.Inject import javax.inject.Singleton @@ -21,15 +22,15 @@ class LoggerUtils @Inject constructor( * * @return */ -/* - This is failing after slf4j update to 2.0.0 - It would be better to find a way to read the value from xml - So far replaced by static value - val logDirectory: String - get() { - val lc = LoggerFactory.getILoggerFactory() as LoggerContext - return lc.getProperty("EXT_FILES_DIR") - } -*/ + /* + This is failing after slf4j update to 2.0.0 + It would be better to find a way to read the value from xml + So far replaced by static value + val logDirectory: String + get() { + val lc = LoggerFactory.getILoggerFactory() as LoggerContext + return lc.getProperty("EXT_FILES_DIR") + } + */ val logDirectory get() = prefFileListProvider.logsPath } \ No newline at end of file diff --git a/plugins/src/main/java/info/nightscout/plugins/utils/Percentile.kt b/plugins/src/main/java/info/nightscout/plugins/utils/Percentile.kt new file mode 100644 index 0000000000..46e2ae4ec6 --- /dev/null +++ b/plugins/src/main/java/info/nightscout/plugins/utils/Percentile.kt @@ -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, 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 + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_clone_48.xml b/plugins/src/main/res/drawable/ic_clone_48.xml similarity index 100% rename from app/src/main/res/drawable/ic_clone_48.xml rename to plugins/src/main/res/drawable/ic_clone_48.xml diff --git a/app/src/main/res/layout/autotune_fragment.xml b/plugins/src/main/res/layout/autotune_fragment.xml similarity index 98% rename from app/src/main/res/layout/autotune_fragment.xml rename to plugins/src/main/res/layout/autotune_fragment.xml index f72b666298..fea9b91985 100644 --- a/app/src/main/res/layout/autotune_fragment.xml +++ b/plugins/src/main/res/layout/autotune_fragment.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".plugins.general.autotune.AutotuneFragment"> + tools:context="info.nightscout.plugins.general.autotune.AutotuneFragment"> ) : AutotuneIob( diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/autotune/PreppedGlucoseTest.kt b/plugins/src/test/java/info/nightscout/plugins/general/autotune/PreppedGlucoseTest.kt similarity index 90% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/autotune/PreppedGlucoseTest.kt rename to plugins/src/test/java/info/nightscout/plugins/general/autotune/PreppedGlucoseTest.kt index 9150c87bb2..a20f33e31a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/autotune/PreppedGlucoseTest.kt +++ b/plugins/src/test/java/info/nightscout/plugins/general/autotune/PreppedGlucoseTest.kt @@ -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.plugins.general.autotune.data.BGDatum -import info.nightscout.androidaps.plugins.general.autotune.data.CRDatum -import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose +import info.nightscout.plugins.general.autotune.data.BGDatum +import info.nightscout.plugins.general.autotune.data.CRDatum +import info.nightscout.plugins.general.autotune.data.PreppedGlucose import org.json.JSONObject import org.junit.Assert import org.junit.Before diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index eaf6914ce6..fc6331d542 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -28,7 +28,6 @@ Invalid weight entry ID: Submit - Profile Age Weight Most common profile: