diff --git a/app/build.gradle b/app/build.gradle index f125a9e74c..132de499a8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -104,12 +104,14 @@ tasks.matching { it instanceof Test }.all { } android { + + namespace 'info.nightscout.androidaps' ndkVersion "21.1.6352462" defaultConfig { multiDexEnabled true versionCode 1500 - version "3.0.0.2-dev-l" + version "3.0.0.2-dev-m" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index aaa245f3bf..8fb0dea2f6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,5 @@ - + @@ -48,7 +46,7 @@ android:restoreAnyVersion="true" android:roundIcon="${appIconRound}" android:supportsRtl="true" - android:theme="@style/AppTheme.Launcher" > + android:theme="@style/AppTheme.Launcher"> + android:exported="true"> @@ -83,69 +81,86 @@ android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" /> - + + - - + + - - - - - - + android:name=".receivers.DataReceiver" + android:enabled="true" + android:exported="true"> - + - + - + - + - + - + - + + android:name=".receivers.SmsReceiver" + android:enabled="true" + android:exported="true" + android:permission="android.permission.BROADCAST_SMS"> - + @@ -212,15 +227,23 @@ + android:exported="false" + android:label="@string/title_activity_setup_wizard" + android:theme="@style/AppTheme" /> - - - + + + @@ -228,7 +251,9 @@ - + diff --git a/app/src/main/assets/OpenAPSAMA/determine-basal.js b/app/src/main/assets/OpenAPSAMA/determine-basal.js index 4e052e8e01..e31fb90a28 100644 --- a/app/src/main/assets/OpenAPSAMA/determine-basal.js +++ b/app/src/main/assets/OpenAPSAMA/determine-basal.js @@ -324,7 +324,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ rT.reason += ", but Min. Delta " + minDelta.toFixed(2) + " > Exp. Delta " + expectedDelta; } if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) { - rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr"; + rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr"; return rT; } else { rT.reason += "; setting current basal of " + round(basal, 2) + " as temp"; @@ -367,10 +367,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr"; + rT.reason += ", temp " + (currenttemp.rate).toFixed(3) + " ~< req " + round(rate, 2) + "U/hr"; return rT; } else { - rT.reason += ", setting " + rate + "U/hr"; + rT.reason += ", setting " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } } @@ -476,22 +476,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + rate + "U/hr"; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration == 'undefined' || currenttemp.duration == 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr"; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr"; + rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " >~ req " + round(rate, 2) + "U/hr"; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr"; + rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " < " + round(rate, 2) + "U/hr"; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } diff --git a/app/src/main/assets/OpenAPSSMB/determine-basal.js b/app/src/main/assets/OpenAPSSMB/determine-basal.js index f7d952f141..f69317bfa6 100644 --- a/app/src/main/assets/OpenAPSSMB/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMB/determine-basal.js @@ -955,7 +955,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. "; + rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. "; return rT; } else { // calculate a long enough zero temp to eventually correct back up to target @@ -976,7 +976,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp); } } else { - rT.reason += ", setting " + rate + "U/hr. "; + rT.reason += ", setting " + round(rate, 2) + "U/hr. "; } return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } @@ -1143,22 +1143,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr. "; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. "; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } diff --git a/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js b/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js index adaa126a8c..81b09e4730 100644 --- a/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMBDynamicISF/determine-basal.js @@ -1085,7 +1085,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { - rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. "; + rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. "; return rT; } else { // calculate a long enough zero temp to eventually correct back up to target @@ -1106,7 +1106,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp); } } else { - rT.reason += ", setting " + rate + "U/hr. "; + rT.reason += ", setting " + round(rate, 2) + "U/hr. "; } return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } @@ -1273,22 +1273,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate - rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; + rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set - rT.reason += "no temp, setting " + rate + "U/hr. "; + rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal - rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. "; return rT; } // required temp > existing temp basal - rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; + rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. "; return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); } diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index e4960d913f..241da0bed9 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -39,7 +39,6 @@ import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils @@ -49,7 +48,7 @@ import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.protection.PasswordCheck diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.kt b/app/src/main/java/info/nightscout/androidaps/MainApp.kt index 003c52ffe9..bc201bf3c8 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.kt @@ -43,7 +43,7 @@ import info.nightscout.androidaps.utils.ActivityMonitor import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.LocalAlertUtils import info.nightscout.androidaps.utils.ProcessLifecycleListener -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.widget.updateWidget import info.nightscout.shared.logging.AAPSLogger @@ -188,11 +188,33 @@ class MainApp : DaggerApplication() { } } + @Suppress("SpellCheckingInspection") private fun doMigrations() { // set values for different builds if (!sp.contains(R.string.key_ns_alarms)) sp.putBoolean(R.string.key_ns_alarms, config.NSCLIENT) if (!sp.contains(R.string.key_ns_announcements)) sp.putBoolean(R.string.key_ns_announcements, config.NSCLIENT) if (!sp.contains(R.string.key_language)) sp.putString(R.string.key_language, "default") + // 3.1.0 + if (sp.contains("ns_wifionly")) { + if (sp.getBoolean("ns_wifionly", false)) { + sp.putBoolean(R.string.key_ns_cellular, false) + sp.putBoolean(R.string.key_ns_wifi, true) + } else { + sp.putBoolean(R.string.key_ns_cellular, true) + sp.putBoolean(R.string.key_ns_wifi, false) + } + sp.remove("ns_wifionly") + } + if (sp.contains("ns_charginonly")) { + if (sp.getBoolean("ns_charginonly", false)) { + sp.putBoolean(R.string.key_ns_battery, false) + sp.putBoolean(R.string.key_ns_charging, true) + } else { + sp.putBoolean(R.string.key_ns_battery, true) + sp.putBoolean(R.string.key_ns_charging, true) + } + sp.remove("ns_charginonly") + } } override fun applicationInjector(): AndroidInjector { @@ -227,7 +249,7 @@ class MainApp : DaggerApplication() { override fun onTerminate() { aapsLogger.debug(LTag.CORE, "onTerminate") unregisterActivityLifecycleCallbacks(activityMonitor) - alarmSoundServiceHelper.stopService(this) + alarmSoundServiceHelper.stopService(this, "onTerminate") super.onTerminate() } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt index d5b3dccb61..20bed45c84 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt @@ -37,7 +37,7 @@ import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.Translator -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.shared.logging.LTag @@ -99,7 +99,8 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { activePlugin, defaultValueHelper, profileFunction, - repository + repository, + fabricPrivacy ) iobCobCalculator = IobCobCalculatorPlugin( diff --git a/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt index 3b88ff8770..d8c71fa70f 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/TreatmentsActivity.kt @@ -11,7 +11,7 @@ import info.nightscout.androidaps.activities.fragments.* import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import javax.inject.Inject class TreatmentsActivity : NoSplashAppCompatActivity() { diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt index 1f7b9686e6..02e4e864f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt @@ -40,7 +40,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt index a1de658977..d34301a3e6 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt @@ -25,7 +25,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt index 08e91af77a..4eda0aa1e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt @@ -36,7 +36,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt index 09e138bcee..4876e22dc2 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt @@ -35,7 +35,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientR import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag 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 5cb0e30721..545c497c69 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/AppModule.kt @@ -28,7 +28,7 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.ConfigImpl import info.nightscout.androidaps.utils.resources.IconsProviderImplementation diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 5b5d56f93e..c234ef63a2 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -3,6 +3,8 @@ package info.nightscout.androidaps.dialogs import android.annotation.SuppressLint import android.content.Context import android.os.Bundle +import android.os.Handler +import android.os.HandlerThread import android.text.Editable import android.text.TextWatcher import android.view.LayoutInflater @@ -24,6 +26,7 @@ import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.databinding.DialogWizardBinding import info.nightscout.androidaps.events.EventAutosensCalculationFinished import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.extensions.runOnUiThread import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.valueToUnits import info.nightscout.androidaps.interfaces.* @@ -63,6 +66,8 @@ class WizardDialog : DaggerDialogFragment() { @Inject lateinit var dateUtil: DateUtil @Inject lateinit var protectionCheck: ProtectionCheck + private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) + private var queryingProtection = false private var wizard: BolusWizard? = null private var calculatedPercentage = 100.0 @@ -168,7 +173,7 @@ class WizardDialog : DaggerDialogFragment() { savedInstanceState?.getDouble("carb_time_input") ?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.okcancel.ok, timeTextWatcher ) - initDialog() + handler.post { initDialog() } calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble() binding.percentUsed.text = rh.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100)) // ok button @@ -257,6 +262,7 @@ class WizardDialog : DaggerDialogFragment() { override fun onDestroyView() { super.onDestroyView() disposable.clear() + handler.removeCallbacksAndMessages(null) _binding = null } @@ -323,14 +329,9 @@ class WizardDialog : DaggerDialogFragment() { else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL) private fun initDialog() { - if (carbsPassedIntoWizard != 0.0) { - binding.carbsInput.value = carbsPassedIntoWizard - } - if (notesPassedIntoWizard.isNotBlank()) { - binding.notesLayout.notes.setText(notesPassedIntoWizard) - } val profile = profileFunction.getProfile() val profileStore = activePlugin.activeProfileSource.profile + val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() if (profile == null || profileStore == null) { ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofile)) @@ -338,32 +339,40 @@ class WizardDialog : DaggerDialogFragment() { return } - val profileList: ArrayList = profileStore.getProfileList() - profileList.add(0, rh.gs(R.string.active)) - context?.let { context -> - binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList)) - binding.profileList.setText(profileList[0], false) - } - - val units = profileFunction.getUnits() - binding.bgUnits.text = units.asText - binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1 - - // Set BG if not old - binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0 - - binding.ttCheckbox.isEnabled = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing - binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility() - // IOB calculation val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() - binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob) + runOnUiThread { + if (carbsPassedIntoWizard != 0.0) { + binding.carbsInput.value = carbsPassedIntoWizard + } + if (notesPassedIntoWizard.isNotBlank()) { + binding.notesLayout.notes.setText(notesPassedIntoWizard) + } - calculateInsulin() + val profileList: ArrayList = profileStore.getProfileList() + profileList.add(0, rh.gs(R.string.active)) + context?.let { context -> + binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList)) + binding.profileList.setText(profileList[0], false) + } - binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility() + val units = profileFunction.getUnits() + binding.bgUnits.text = units.asText + binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1 + + // Set BG if not old + binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0 + + binding.ttCheckbox.isEnabled = tempTarget is ValueWrapper.Existing + binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility() + binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob) + + calculateInsulin() + + binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility() + } } @SuppressLint("SetTextI18n") @@ -496,7 +505,7 @@ class WizardDialog : DaggerDialogFragment() { override fun onResume() { super.onResume() - if(!queryingProtection) { + if (!queryingProtection) { queryingProtection = true activity?.let { activity -> val cancelFail = { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt index 90f297bb08..1ec1c3907d 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt @@ -60,7 +60,7 @@ class WizardInfoDialog : DaggerDialogFragment() { override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putString("data", data.toJson(true, dateUtil).toString()) + outState.putString("data", data.toJson(true, dateUtil, profileFunction).toString()) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt index 3c7878676c..f3978aacf1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt @@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProv import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Profiler -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt index a8aab6ee56..34d058ac5c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt @@ -23,7 +23,7 @@ import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.events.EventConfigBuilderUpdateGui import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.PREFERENCES import info.nightscout.androidaps.interfaces.ResourceHelper diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt index 651e5b18a6..4f4a835e9f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt @@ -19,7 +19,7 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Round -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.json.JSONObject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index 5e2342770c..92002eab4d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -39,7 +39,7 @@ import info.nightscout.androidaps.skins.SkinProvider import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt index 9bfb851952..d0dc4da9be 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneCore.kt @@ -28,9 +28,9 @@ class AutotuneCore @Inject constructor( //console.error(isf); var carbRatio = previousAutotune.ic //console.error(carbRatio); - var csf = isf / carbRatio - var dia = previousAutotune.dia - var peak = previousAutotune.peak + val csf = isf / carbRatio + val dia = previousAutotune.dia + val peak = previousAutotune.peak val csfGlucose = preppedGlucose.csfGlucoseData val isfGlucose = preppedGlucose.isfGlucoseData val basalGlucose = preppedGlucose.basalGlucoseData diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt index b968c7fc88..2b467cb500 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneFragment.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.general.autotune +import android.graphics.Paint import android.graphics.Typeface import android.os.Bundle import android.text.Editable @@ -79,7 +80,8 @@ class AutotuneFragment : DaggerFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sp.putBoolean(R.string.key_autotune_tune_insulin_curve, false) // put to false tune insulin curve - autotunePlugin.lastRun = sp.getLong(R.string.key_autotune_last_run, 0) + sp.putBoolean(R.string.key_autotune_additional_log, false) // put to false additional log + autotunePlugin.loadLastRun() if (autotunePlugin.lastNbDays.isEmpty()) autotunePlugin.lastNbDays = sp.getInt(R.string.key_autotune_default_tune_days, 5).toString() val defaultValue = sp.getInt(R.string.key_autotune_default_tune_days, 5).toDouble() @@ -144,6 +146,7 @@ class AutotuneFragment : DaggerFragment() { autotunePlugin.tunedProfile?.profilename = localName autotunePlugin.updateProfile(autotunePlugin.tunedProfile) autotunePlugin.updateButtonVisibility = View.GONE + autotunePlugin.saveLastRun() uel.log( UserEntry.Action.STORE_PROFILE, UserEntry.Sources.Autotune, @@ -163,6 +166,7 @@ class AutotuneFragment : DaggerFragment() { autotunePlugin.tunedProfile?.profilename = "" autotunePlugin.updateProfile(autotunePlugin.pumpProfile) autotunePlugin.updateButtonVisibility = View.VISIBLE + autotunePlugin.saveLastRun() uel.log( UserEntry.Action.STORE_PROFILE, UserEntry.Sources.Autotune, @@ -251,6 +255,14 @@ class AutotuneFragment : DaggerFragment() { } } } + + binding.tuneLastrun.setOnClickListener { + if (!autotunePlugin.calculationRunning) { + autotunePlugin.loadLastRun() + updateGui() + } + } + binding.tuneLastrun.paintFlags = binding.tuneLastrun.paintFlags or Paint.UNDERLINE_TEXT_FLAG } @Synchronized @@ -263,7 +275,6 @@ class AutotuneFragment : DaggerFragment() { updateGui() }, { fabricPrivacy.logException(it) }) checkNewDay() - binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble() updateGui() } @@ -276,6 +287,7 @@ class AutotuneFragment : DaggerFragment() { @Synchronized private fun updateGui() { _binding ?: return + binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble() profileStore = activePlugin.activeProfileSource.profile ?: ProfileStore(injector, JSONObject(), dateUtil) profileName = if (binding.profileList.text.toString() == rh.gs(R.string.active)) "" else binding.profileList.text.toString() profileFunction.getProfile()?.let { currentProfile -> diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt index 5dea75afd2..13079e418c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotuneIob.kt @@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory import java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.ceil import kotlin.math.roundToInt @Singleton @@ -181,7 +182,7 @@ class AutotuneIob @Inject constructor( // even if profile rate is not the same private fun toSplittedTimestampTB(tb: TemporaryBasal, tunedProfile: ATProfile) { var splittedTimestamp = tb.timestamp - val cutInMilliSec = T.mins(30).msecs() //30 min to compare with oref0 + val cutInMilliSec = T.mins(60).msecs() //30 min to compare with oref0, 60 min to improve accuracy var splittedDuration = tb.duration if (tb.isValid && tb.durationInMinutes > 0) { val endTimestamp = splittedTimestamp + splittedDuration @@ -248,21 +249,20 @@ class AutotuneIob @Inject constructor( fun convertToBoluses(eb: ExtendedBolus): MutableList { val result: MutableList = ArrayList() - val tempBolusSize = 0.05 - val tempBolusCount : Int = (eb.amount / tempBolusSize).roundToInt() - if(tempBolusCount > 0) { - val tempBolusSpacing = eb.duration / tempBolusCount - for (j in 0L until tempBolusCount) { - val calcDate = eb.timestamp + j * tempBolusSpacing - val bolusInterfaceIDs = InterfaceIDs().also { it.nightscoutId = eb.interfaceIDs.nightscoutId + "_eb_$j" } - val tempBolusPart = Bolus( - interfaceIDs_backing = bolusInterfaceIDs, - timestamp = calcDate, - amount = tempBolusSize, - type = Bolus.Type.NORMAL - ) - result.add(tempBolusPart) - } + val aboutFiveMinIntervals = ceil(eb.duration / 5.0).toInt() + val spacing = eb.duration / aboutFiveMinIntervals.toDouble() + for (j in 0L until aboutFiveMinIntervals) { + // find middle of the interval + val calcDate = (eb.timestamp + j * spacing * 60 * 1000 + 0.5 * spacing * 60 * 1000).toLong() + val tempBolusSize: Double = eb.amount / aboutFiveMinIntervals + val bolusInterfaceIDs = InterfaceIDs().also { it.nightscoutId = eb.interfaceIDs.nightscoutId + "_eb_$j" } + val tempBolusPart = Bolus( + interfaceIDs_backing = bolusInterfaceIDs, + timestamp = calcDate, + amount = tempBolusSize, + type = Bolus.Type.NORMAL + ) + result.add(tempBolusPart) } return result } @@ -277,22 +277,20 @@ class AutotuneIob @Inject constructor( } else { tbr.rate / 100.0 * basalRate - tunedRate }, 0.001) - val tempBolusSize = if (netBasalRate < 0 ) -0.05 else 0.05 - val netBasalAmount: Double = Round.roundTo(netBasalRate * realDuration / 60.0, 0.01) - val tempBolusCount : Int = (netBasalAmount / tempBolusSize).roundToInt() - if(tempBolusCount > 0) { - val tempBolusSpacing = realDuration * 60 * 1000 / tempBolusCount - for (j in 0L until tempBolusCount) { - val calcDate = tbr.timestamp + j * tempBolusSpacing - val bolusInterfaceIDs = InterfaceIDs().also { it.nightscoutId = tbr.interfaceIDs.nightscoutId + "_tbr_$j" } - val tempBolusPart = Bolus( - interfaceIDs_backing = bolusInterfaceIDs, - timestamp = calcDate, - amount = tempBolusSize, - type = Bolus.Type.NORMAL - ) - result.add(tempBolusPart) - } + val aboutFiveMinIntervals = ceil(realDuration / 5.0).toInt() + val tempBolusSpacing = realDuration / aboutFiveMinIntervals.toDouble() + for (j in 0L until aboutFiveMinIntervals) { + // find middle of the interval + val calcDate = (tbr.timestamp + j * tempBolusSpacing * 60 * 1000 + 0.5 * tempBolusSpacing * 60 * 1000).toLong() + val tempBolusSize = netBasalRate * tempBolusSpacing / 60.0 + val bolusInterfaceIDs = InterfaceIDs().also { it.nightscoutId = tbr.interfaceIDs.nightscoutId + "_tbr_$j" } + val tempBolusPart = Bolus( + interfaceIDs_backing = bolusInterfaceIDs, + timestamp = calcDate, + amount = tempBolusSize, + type = Bolus.Type.NORMAL + ) + result.add(tempBolusPart) } return result } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt index 9a7839f600..5f926c28c5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/autotune/AutotunePlugin.kt @@ -7,6 +7,7 @@ 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.logging.UserEntryLogger import info.nightscout.androidaps.plugins.bus.RxBus @@ -16,9 +17,10 @@ import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneU import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.profile.local.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.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import org.json.JSONException @@ -48,7 +50,7 @@ class AutotunePlugin @Inject constructor( private val autotuneIob: AutotuneIob, private val autotunePrep: AutotunePrep, private val autotuneCore: AutotuneCore, - private val buildHelper:BuildHelper, + private val buildHelper: BuildHelper, private val uel: UserEntryLogger, aapsLogger: AAPSLogger ) : PluginBase(PluginDescription() @@ -115,37 +117,39 @@ 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 { tunedProfile -> - autotuneIob.initializeData(from, to, tunedProfile) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries) + tunedProfile?.let { it -> + autotuneIob.initializeData(from, to, it) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries) autotuneFS.exportEntries(autotuneIob) //<=> ns-entries.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine autotuneFS.exportTreatments(autotuneIob) //<=> ns-treatments.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine (include treatments ,tempBasal and extended - preppedGlucose = autotunePrep.categorize(tunedProfile) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + preppedGlucose = autotunePrep.categorize(it) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + preppedGlucose?.let { preppedGlucose -> + autotuneFS.exportPreppedGlucose(preppedGlucose) + tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, it, pumpProfile).also { tunedProfile -> + autotuneFS.exportTunedProfile(tunedProfile) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine + if (i < daysBack - 1) { + log("Partial result for day ${i + 1}".trimIndent()) + result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack) + rxBus.send(EventAutotuneUpdateGui()) + } + logResult = showResults(tunedProfile, pumpProfile) + if (detailedLog) + autotuneFS.exportLog(lastRun, i + 1) + } + } + ?: { + log("preppedGlucose is null on day ${i + 1}") + tunedProfile = null + } } - - if (preppedGlucose == null || tunedProfile == null) { + if (tunedProfile == null) { result = rh.gs(R.string.autotune_error) - log(result) + log("TunedProfile is null on day ${i + 1}") calculationRunning = false rxBus.send(EventAutotuneUpdateGui()) - tunedProfile = null autotuneFS.exportResult(result) autotuneFS.exportLogAndZip(lastRun) return result } - preppedGlucose?.let { preppedGlucose -> //preppedGlucose and tunedProfile should never be null here - autotuneFS.exportPreppedGlucose(preppedGlucose) - tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, tunedProfile!!, pumpProfile) - } - // localInsulin = LocalInsulin("TunedInsulin", tunedProfile!!.peak, tunedProfile!!.dia) // Todo: Add tune Insulin option - autotuneFS.exportTunedProfile(tunedProfile!!) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine - if (i < daysBack - 1) { - log("Partial result for day ${i + 1}".trimIndent()) - result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack) - rxBus.send(EventAutotuneUpdateGui()) - } - logResult = showResults(tunedProfile, pumpProfile) - if (detailedLog) - autotuneFS.exportLog(lastRun, i + 1) } result = rh.gs(R.string.autotune_result, dateUtil.dateAndTimeString(lastRun)) if (!detailedLog) @@ -161,7 +165,8 @@ class AutotunePlugin @Inject constructor( updateProfile(tunedP) uel.log( UserEntry.Action.STORE_PROFILE, - UserEntry.Sources.Autotune, + UserEntry.Sources.Automation, + rh.gs(R.string.autotune), ValueWithUnit.SimpleString(tunedP.profilename) ) updateButtonVisibility = View.GONE @@ -178,22 +183,23 @@ class AutotunePlugin @Inject constructor( log("Profile Switch succeed ${tunedP.profilename}") uel.log( UserEntry.Action.PROFILE_SWITCH, - UserEntry.Sources.Autotune, - "Autotune AutoSwitch", + UserEntry.Sources.Automation, + rh.gs(R.string.autotune), ValueWithUnit.SimpleString(tunedP.profilename)) } rxBus.send(EventLocalProfileChanged()) } } } - lastRunSuccess = true - sp.putLong(R.string.key_autotune_last_run, lastRun) - rxBus.send(EventAutotuneUpdateGui()) - calculationRunning = false + tunedProfile?.let { + lastRunSuccess = true + saveLastRun() + rxBus.send(EventAutotuneUpdateGui()) + calculationRunning = false return result } - return "No Result" // should never occurs + return rh.gs(R.string.autotune_error) } private fun showResults(tunedProfile: ATProfile?, pumpProfile: ATProfile): String { @@ -296,6 +302,64 @@ class AutotunePlugin @Inject constructor( localProfilePlugin.storeSettings() } + fun saveLastRun() { + val json = JSONObject() + json.put("lastNbDays", lastNbDays) + json.put("lastRun",lastRun) + json.put("pumpProfile", pumpProfile.profile.toPureNsJson(dateUtil)) + json.put("pumpProfileName", pumpProfile.profilename) + json.put("pumpPeak", pumpProfile.peak) + json.put("pumpDia", pumpProfile.dia) + tunedProfile?.let { atProfile -> + json.put("tunedProfile", atProfile.profile.toPureNsJson(dateUtil)) + json.put("tunedCircadianProfile", atProfile.circadianProfile.toPureNsJson(dateUtil)) + json.put("tunedProfileName", atProfile.profilename) + json.put("tunedPeak", atProfile.peak) + json.put("tunedDia", atProfile.dia) + for (i in 0..23) { + json.put("missingDays_$i", atProfile.basalUntuned[i]) + } + } + json.put("result", result) + json.put("updateButtonVisibility", updateButtonVisibility) + sp.putString(R.string.key_autotune_last_run, json.toString()) + } + + fun loadLastRun() { + result = "" + lastRunSuccess = false + try { + val json = JSONObject(sp.getString(R.string.key_autotune_last_run, "")) + lastNbDays = JsonHelper.safeGetString(json, "lastNbDays", "") + lastRun = JsonHelper.safeGetLong(json, "lastRun") + val pumpPeak = JsonHelper.safeGetInt(json, "pumpPeak") + val pumpDia = JsonHelper.safeGetDouble(json, "pumpDia") + var localInsulin = LocalInsulin("PumpInsulin", pumpPeak, pumpDia) + selectedProfile = JsonHelper.safeGetString(json, "pumpProfileName", "") + val profile = JsonHelper.safeGetJSONObject(json, "pumpProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + pumpProfile = ATProfile(ProfileSealed.Pure(profile), localInsulin, injector).also { it.profilename = selectedProfile } + val tunedPeak = JsonHelper.safeGetInt(json, "tunedPeak") + val tunedDia = JsonHelper.safeGetDouble(json, "tunedDia") + localInsulin = LocalInsulin("PumpInsulin", tunedPeak, tunedDia) + val tunedProfileName = JsonHelper.safeGetString(json, "tunedProfileName", "") + val tuned = JsonHelper.safeGetJSONObject(json, "tunedProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + val circadianTuned = JsonHelper.safeGetJSONObject(json, "tunedCircadianProfile", null)?.let { pureProfileFromJson(it, dateUtil) } + ?: return + tunedProfile = ATProfile(ProfileSealed.Pure(tuned), localInsulin, injector).also { atProfile -> + atProfile.profilename = tunedProfileName + atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned) + for (i in 0..23) { + atProfile.basalUntuned[i] = JsonHelper.safeGetInt(json,"missingDays_$i") + } + } + result = JsonHelper.safeGetString(json, "result", "") + updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility") + lastRunSuccess = true + } catch (e: Exception) { + } + } private fun log(message: String) { atLog("[Plugin] $message") diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt index 5a108666ba..6e6e0ab684 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefsImpl.kt @@ -39,7 +39,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog import info.nightscout.androidaps.utils.alertDialogs.WarningDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper 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 90f051f2a1..0c466e7027 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 @@ -13,7 +13,7 @@ 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.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import java.io.* diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt index f3ab04a81f..ff88b7e38f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt @@ -286,14 +286,14 @@ class DataSyncSelectorImplementation @Inject constructor( bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> nsClientPlugin.nsClientService?.dbAdd( "treatments", - bolusCalculatorResult.first.toJson(true, dateUtil), + bolusCalculatorResult.first.toJson(true, dateUtil, profileFunction), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" ) // with nsId = update bolusCalculatorResult.first.interfaceIDs.nightscoutId != null -> nsClientPlugin.nsClientService?.dbUpdate( - "treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil), + "treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil, profileFunction), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" ) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt index 7c01449ba6..5707cd439c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt @@ -27,7 +27,7 @@ import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper.safeGetLong -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.sharedPreferences.SP import java.util.concurrent.TimeUnit import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt index a4c6386c17..a64d04ab0d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientMbgWorker.kt @@ -14,7 +14,7 @@ import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg import info.nightscout.androidaps.receivers.DataWorker -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.kt index 180440f6db..2a8954c583 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientPlugin.kt @@ -21,8 +21,7 @@ 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.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm @@ -34,12 +33,13 @@ import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientServ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HtmlHelper.fromHtml import info.nightscout.androidaps.utils.ToastUtils -import info.nightscout.androidaps.utils.buildHelper.BuildHelper -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable -import java.util.* +import io.reactivex.rxjava3.kotlin.plusAssign import javax.inject.Inject import javax.inject.Singleton @@ -80,62 +80,49 @@ class NSClientPlugin @Inject constructor( var nsClientService: NSClientService? = null val isAllowed: Boolean get() = nsClientReceiverDelegate.allowed + val blockingReason: String + get() = nsClientReceiverDelegate.blockingReason override fun onStart() { paused = sp.getBoolean(R.string.key_nsclientinternal_paused, false) autoscroll = sp.getBoolean(R.string.key_nsclientinternal_autoscroll, true) - val intent = Intent(context, NSClientService::class.java) - context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) + context.bindService(Intent(context, NSClientService::class.java), mConnection, Context.BIND_AUTO_CREATE) super.onStart() nsClientReceiverDelegate.grabReceiversState() - disposable.add( - rxBus - .toObservable(EventNSClientStatus::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ event: EventNSClientStatus -> - status = event.getStatus(rh) - rxBus.send(EventNSClientUpdateGUI()) - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventNetworkChange::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventPreferenceChange::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventAppExit::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ if (nsClientService != null) context.unbindService(mConnection) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventNSClientNewLog::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ event: EventNSClientNewLog -> - addToLog(event) - aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText) - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventChargingState::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventNSClientResend::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException) - ) + disposable += rxBus + .toObservable(EventNSClientStatus::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ event: EventNSClientStatus -> + status = event.getStatus(rh) + rxBus.send(EventNSClientUpdateGUI()) + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventNetworkChange::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventPreferenceChange::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventAppExit::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ if (nsClientService != null) context.unbindService(mConnection) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventNSClientNewLog::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ event: EventNSClientNewLog -> + addToLog(event) + aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText) + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventChargingState::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventNSClientResend::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException) } override fun onStop() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegate.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegate.kt index 46b537bd86..ad69554a51 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegate.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegate.kt @@ -22,19 +22,26 @@ class NsClientReceiverDelegate @Inject constructor( private var allowedChargingState = true private var allowedNetworkState = true var allowed = true + var blockingReason = "" fun grabReceiversState() { receiverStatusStore.updateNetworkStatus() } fun onStatusEvent(ev: EventPreferenceChange) { - if (ev.isChanged(rh, R.string.key_ns_wifionly) || - ev.isChanged(rh, R.string.key_ns_wifi_ssids) || - ev.isChanged(rh, R.string.key_ns_allowroaming)) { - receiverStatusStore.updateNetworkStatus() - onStatusEvent(receiverStatusStore.lastNetworkEvent) - } else if (ev.isChanged(rh, R.string.key_ns_chargingonly)) { - receiverStatusStore.broadcastChargingState() + when { + ev.isChanged(rh, R.string.key_ns_wifi) || + ev.isChanged(rh, R.string.key_ns_cellular) || + ev.isChanged(rh, R.string.key_ns_wifi_ssids) || + ev.isChanged(rh, R.string.key_ns_allow_roaming) -> { + receiverStatusStore.updateNetworkStatus() + receiverStatusStore.lastNetworkEvent?.let { onStatusEvent(it) } + } + + ev.isChanged(rh, R.string.key_ns_charging) || + ev.isChanged(rh, R.string.key_ns_battery) -> { + receiverStatusStore.broadcastChargingState() + } } } @@ -42,14 +49,16 @@ class NsClientReceiverDelegate @Inject constructor( val newChargingState = calculateStatus(ev) if (newChargingState != allowedChargingState) { allowedChargingState = newChargingState + blockingReason = rh.gs(R.string.blocked_by_charging) processStateChange() } } - fun onStatusEvent(ev: EventNetworkChange?) { + fun onStatusEvent(ev: EventNetworkChange) { val newNetworkState = calculateStatus(ev) if (newNetworkState != allowedNetworkState) { allowedNetworkState = newNetworkState + blockingReason = rh.gs(R.string.blocked_by_connectivity) processStateChange() } } @@ -62,30 +71,13 @@ class NsClientReceiverDelegate @Inject constructor( } } - fun calculateStatus(ev: EventChargingState): Boolean { - val chargingOnly = sp.getBoolean(R.string.key_ns_chargingonly, false) - var newAllowedState = true - if (!ev.isCharging && chargingOnly) { - newAllowedState = false - } - return newAllowedState - } + fun calculateStatus(ev: EventChargingState): Boolean = + !ev.isCharging && sp.getBoolean(R.string.key_ns_battery, true) || + ev.isCharging && sp.getBoolean(R.string.key_ns_charging, true) - fun calculateStatus(ev: EventNetworkChange?): Boolean { - val wifiOnly = sp.getBoolean(R.string.key_ns_wifionly, false) - val allowedSsidString = sp.getString(R.string.key_ns_wifi_ssids, "") - val allowedSSIDs: List = if (allowedSsidString.isEmpty()) List(0) { "" } else allowedSsidString.split(";") - val allowRoaming = sp.getBoolean(R.string.key_ns_allowroaming, true) - var newAllowedState = true - if (ev?.wifiConnected == true) { - if (allowedSSIDs.isNotEmpty() && !allowedSSIDs.contains(ev.ssid)) { - newAllowedState = false - } - } else { - if (!allowRoaming && ev?.roaming == true || wifiOnly) { - newAllowedState = false - } - } - return newAllowedState - } + fun calculateStatus(ev: EventNetworkChange): Boolean = + ev.mobileConnected && sp.getBoolean(R.string.key_ns_cellular, true) && !ev.roaming || + ev.mobileConnected && sp.getBoolean(R.string.key_ns_cellular, true) && ev.roaming && sp.getBoolean(R.string.key_ns_allow_roaming, true) || + ev.wifiConnected && sp.getBoolean(R.string.key_ns_wifi, true) && sp.getString(R.string.key_ns_wifi_ssids, "").isEmpty() || + ev.wifiConnected && sp.getBoolean(R.string.key_ns_wifi, true) && sp.getString(R.string.key_ns_wifi_ssids, "").split(";").contains(ev.ssid) } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt index 2f6c503318..cd08db55fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt @@ -16,9 +16,14 @@ import info.nightscout.androidaps.events.EventConfigBuilderChange import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.DataSyncSelector +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.food.FoodPlugin.FoodWorker -import info.nightscout.androidaps.plugins.general.nsclient.* +import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddAckWorker +import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker +import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker +import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin +import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAddAck import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAuthAck import info.nightscout.androidaps.plugins.general.nsclient.acks.NSUpdateAck @@ -43,13 +48,13 @@ import info.nightscout.androidaps.utils.JsonHelper.safeGetString import info.nightscout.androidaps.utils.JsonHelper.safeGetStringAllowNull import info.nightscout.androidaps.utils.T.Companion.mins import info.nightscout.androidaps.utils.XDripBroadcast -import info.nightscout.androidaps.utils.buildHelper.BuildHelper -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.kotlin.plusAssign import io.socket.client.IO import io.socket.client.Socket import io.socket.emitter.Emitter @@ -114,70 +119,56 @@ class NSClientService : DaggerService() { wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService") wakeLock?.acquire() initialize() - disposable.add( - rxBus - .toObservable(EventConfigBuilderChange::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ - if (nsEnabled != nsClientPlugin.isEnabled()) { - latestDateInReceivedData = 0 - destroy() - initialize() - } - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventPreferenceChange::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ event: EventPreferenceChange -> - if (event.isChanged(rh, R.string.key_nsclientinternal_url) || - event.isChanged(rh, R.string.key_nsclientinternal_api_secret) || - event.isChanged(rh, R.string.key_nsclientinternal_paused) - ) { - latestDateInReceivedData = 0 - destroy() - initialize() - } - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventAppExit::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ - aapsLogger.debug(LTag.NSCLIENT, "EventAppExit received") - destroy() - stopSelf() - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(EventNSClientRestart::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ + disposable += rxBus + .toObservable(EventConfigBuilderChange::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ + if (nsEnabled != nsClientPlugin.isEnabled()) { latestDateInReceivedData = 0 - restart() - }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(NSAuthAck::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(NSUpdateAck::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ack -> processUpdateAck(ack) }, fabricPrivacy::logException) - ) - disposable.add( - rxBus - .toObservable(NSAddAck::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ack -> processAddAck(ack) }, fabricPrivacy::logException) - ) + destroy() + initialize() + } + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventPreferenceChange::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ event: EventPreferenceChange -> + if (event.isChanged(rh, R.string.key_nsclientinternal_url) || + event.isChanged(rh, R.string.key_nsclientinternal_api_secret) || + event.isChanged(rh, R.string.key_nsclientinternal_paused) + ) { + latestDateInReceivedData = 0 + destroy() + initialize() + } + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventAppExit::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ + aapsLogger.debug(LTag.NSCLIENT, "EventAppExit received") + destroy() + stopSelf() + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventNSClientRestart::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ + latestDateInReceivedData = 0 + restart() + }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(NSAuthAck::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(NSUpdateAck::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ack -> processUpdateAck(ack) }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(NSAddAck::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ ack -> processAddAck(ack) }, fabricPrivacy::logException) } override fun onDestroy() { @@ -234,13 +225,9 @@ class NSClientService : DaggerService() { get() = this@NSClientService } - override fun onBind(intent: Intent): IBinder { - return binder - } + override fun onBind(intent: Intent): IBinder = binder - override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { - return START_STICKY - } + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int = START_STICKY fun initialize() { dataCounter = 0 @@ -249,8 +236,8 @@ class NSClientService : DaggerService() { if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString() rxBus.send(EventNSClientStatus("Initializing")) if (!nsClientPlugin.isAllowed) { - rxBus.send(EventNSClientNewLog("NSCLIENT", "not allowed")) - rxBus.send(EventNSClientStatus("Not allowed")) + rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason)) + rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason)) } else if (nsClientPlugin.paused) { rxBus.send(EventNSClientNewLog("NSCLIENT", "paused")) rxBus.send(EventNSClientStatus("Paused")) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt index 139d3a8a93..d114f19847 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewData.kt @@ -29,6 +29,7 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import java.util.* @@ -44,7 +45,8 @@ class OverviewData @Inject constructor( private val activePlugin: ActivePlugin, private val defaultValueHelper: DefaultValueHelper, private val profileFunction: ProfileFunction, - private val repository: AppRepository + private val repository: AppRepository, + private val fabricPrivacy: FabricPrivacy ) { var rangeToDisplay = 6 // for graph @@ -205,8 +207,8 @@ class OverviewData @Inject constructor( * IOB, COB */ - fun bolusIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromBolus().round() - fun basalIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() + fun bolusIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromBolus().round(fabricPrivacy) + fun basalIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round(fabricPrivacy) fun cobInfo(iobCobCalculator: IobCobCalculator): CobInfo = iobCobCalculator.getCobInfo(true, "Overview COB") val lastCarbsTime: Long @@ -249,7 +251,6 @@ class OverviewData @Inject constructor( var bgReadingGraphSeries: PointsWithLabelGraphSeries = PointsWithLabelGraphSeries() var predictionsGraphSeries: PointsWithLabelGraphSeries = PointsWithLabelGraphSeries() - var maxBasalValueFound = 0.0 val basalScale = Scale() var baseBasalGraphSeries: LineGraphSeries = LineGraphSeries() var tempBasalGraphSeries: LineGraphSeries = LineGraphSeries() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 426b197249..4374fd0c05 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -66,7 +66,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.TrendCalculator import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.ui.SingleClickButton @@ -224,7 +224,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList disposable += activePlugin.activeOverview.overviewBus .toObservable(EventUpdateOverviewIobCob::class.java) .debounce(1L, TimeUnit.SECONDS) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateIobCob() }, fabricPrivacy::logException) disposable += activePlugin.activeOverview.overviewBus .toObservable(EventUpdateOverviewSensitivity::class.java) @@ -256,7 +256,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList disposable += rxBus .toObservable(EventNewBG::class.java) .debounce(1L, TimeUnit.SECONDS) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateBg() }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventRefreshOverview::class.java) @@ -287,19 +287,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventEffectiveProfileSwitchChanged::class.java) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateProfile() }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventTempTargetChange::class.java) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateTemporaryTarget() }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventExtendedBolusChange::class.java) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateExtendedBolus() }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventTempBasalChange::class.java) - .observeOn(aapsSchedulers.main) + .observeOn(aapsSchedulers.io) .subscribe({ updateTemporaryBasal() }, fabricPrivacy::logException) refreshLoop = Runnable { @@ -316,17 +316,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList fun refreshAll() { runOnUiThread { _binding ?: return@runOnUiThread - updateBg() updateTime() - updateProfile() - updateTemporaryBasal() - updateExtendedBolus() - updateTemporaryTarget() - updateIobCob() updateSensitivity() updateGraph() updateNotification() } + updateBg() + updateTemporaryBasal() + updateExtendedBolus() + updateIobCob() + processButtonsVisibility() + processAps() + updateProfile() + updateTemporaryTarget() } @Synchronized @@ -513,13 +515,16 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList // QuickWizard button val quickWizardEntry = quickWizard.getActive() - if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) { - binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE - val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false) - binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(R.string.format_carbs, quickWizardEntry.carbs()) + - " " + rh.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin) - if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE - } else binding.buttonsLayout.quickWizardButton.visibility = View.GONE + runOnUiThread { + _binding ?: return@runOnUiThread + if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) { + binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE + val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false) + binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(R.string.format_carbs, quickWizardEntry.carbs()) + + " " + rh.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin) + if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE + } else binding.buttonsLayout.quickWizardButton.visibility = View.GONE + } // **** Temp button **** val lastRun = loop.lastRun @@ -530,72 +535,76 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList (lastRun.lastOpenModeAccept == 0L || lastRun.lastOpenModeAccept < lastRun.lastAPSRun) &&// never accepted or before last result lastRun.constraintsProcessed?.isChangeRequested == true // change is requested - if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && (loop as PluginBase).isEnabled()) { - binding.buttonsLayout.acceptTempButton.visibility = View.VISIBLE - binding.buttonsLayout.acceptTempButton.text = "${rh.gs(R.string.setbasalquestion)}\n${lastRun!!.constraintsProcessed}" - } else { - binding.buttonsLayout.acceptTempButton.visibility = View.GONE - } - - // **** Various treatment buttons **** - binding.buttonsLayout.carbsButton.visibility = - ((!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) && profile != null - && sp.getBoolean(R.string.key_show_carbs_button, true)).toVisibility() - binding.buttonsLayout.treatmentButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null - && sp.getBoolean(R.string.key_show_treatment_button, false)).toVisibility() - binding.buttonsLayout.wizardButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null - && sp.getBoolean(R.string.key_show_wizard_button, true)).toVisibility() - binding.buttonsLayout.insulinButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null - && sp.getBoolean(R.string.key_show_insulin_button, true)).toVisibility() - - // **** Calibration & CGM buttons **** - val xDripIsBgSource = xdripPlugin.isEnabled() - val dexcomIsSource = dexcomPlugin.isEnabled() - binding.buttonsLayout.calibrationButton.visibility = (xDripIsBgSource && actualBG != null && sp.getBoolean(R.string.key_show_calibration_button, true)).toVisibility() - if (dexcomIsSource) { - binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null) - for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) { - drawable?.mutate() - drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmDexColor), PorterDuff.Mode.SRC_IN) + runOnUiThread { + _binding ?: return@runOnUiThread + if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && (loop as PluginBase).isEnabled()) { + binding.buttonsLayout.acceptTempButton.visibility = View.VISIBLE + binding.buttonsLayout.acceptTempButton.text = "${rh.gs(R.string.setbasalquestion)}\n${lastRun!!.constraintsProcessed}" + } else { + binding.buttonsLayout.acceptTempButton.visibility = View.GONE } - binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmDexColor)) - } else if (xDripIsBgSource) { - binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null) - for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) { - drawable?.mutate() - drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmXdripColor), PorterDuff.Mode.SRC_IN) + + // **** Various treatment buttons **** + binding.buttonsLayout.carbsButton.visibility = + ((!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) && profile != null + && sp.getBoolean(R.string.key_show_carbs_button, true)).toVisibility() + binding.buttonsLayout.treatmentButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null + && sp.getBoolean(R.string.key_show_treatment_button, false)).toVisibility() + binding.buttonsLayout.wizardButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null + && sp.getBoolean(R.string.key_show_wizard_button, true)).toVisibility() + binding.buttonsLayout.insulinButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null + && sp.getBoolean(R.string.key_show_insulin_button, true)).toVisibility() + + // **** Calibration & CGM buttons **** + val xDripIsBgSource = xdripPlugin.isEnabled() + val dexcomIsSource = dexcomPlugin.isEnabled() + binding.buttonsLayout.calibrationButton.visibility = (xDripIsBgSource && actualBG != null && sp.getBoolean(R.string.key_show_calibration_button, true)).toVisibility() + if (dexcomIsSource) { + binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null) + for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) { + drawable?.mutate() + drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmDexColor), PorterDuff.Mode.SRC_IN) + } + binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmDexColor)) + } else if (xDripIsBgSource) { + binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null) + for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) { + drawable?.mutate() + drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmXdripColor), PorterDuff.Mode.SRC_IN) + } + binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmXdripColor)) } - binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmXdripColor)) - } - binding.buttonsLayout.cgmButton.visibility = (sp.getBoolean(R.string.key_show_cgm_button, false) && (xDripIsBgSource || dexcomIsSource)).toVisibility() + binding.buttonsLayout.cgmButton.visibility = (sp.getBoolean(R.string.key_show_cgm_button, false) && (xDripIsBgSource || dexcomIsSource)).toVisibility() - // Automation buttons - binding.buttonsLayout.userButtonsLayout.removeAllViews() - val events = automationPlugin.userEvents() - if (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null) - for (event in events) - if (event.isEnabled && event.trigger.shouldRun()) - context?.let { context -> - SingleClickButton(context).also { - it.setTextColor(rh.gac(context, R.attr.treatmentButton)) - it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f) - it.layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 0.5f).also { l -> - l.setMargins(0, 0, rh.dpToPx(-4), 0) - } - it.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_danar_useropt), null, null) - it.text = event.title + // Automation buttons + binding.buttonsLayout.userButtonsLayout.removeAllViews() + val events = automationPlugin.userEvents() + if (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null) + for (event in events) + if (event.isEnabled && event.trigger.shouldRun()) + context?.let { context -> + SingleClickButton(context).also { + it.setTextColor(rh.gac(context, R.attr.treatmentButton)) + it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f) + it.layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 0.5f).also { l -> + l.setMargins(0, 0, rh.dpToPx(-4), 0) + } + it.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_danar_useropt), null, null) + it.text = event.title - it.setOnClickListener { - OKDialog.showConfirmation(context, rh.gs(R.string.run_question, event.title), { handler.post { automationPlugin.processEvent(event) } }) + it.setOnClickListener { + OKDialog.showConfirmation(context, rh.gs(R.string.run_question, event.title), { handler.post { automationPlugin.processEvent(event) } }) + } + binding.buttonsLayout.userButtonsLayout.addView(it) } - binding.buttonsLayout.userButtonsLayout.addView(it) } - } - binding.buttonsLayout.userButtonsLayout.visibility = events.isNotEmpty().toVisibility() + binding.buttonsLayout.userButtonsLayout.visibility = events.isNotEmpty().toVisibility() + } } private fun processAps() { val pump = activePlugin.activePump + val profile = profileFunction.getProfile() // aps mode val closedLoopEnabled = constraintChecker.isClosedLoopAllowed() @@ -608,103 +617,106 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList } } - if (config.APS && pump.pumpDescription.isTempBasalCapable) { - binding.infoLayout.apsMode.visibility = View.VISIBLE - binding.infoLayout.timeLayout.visibility = View.GONE - when { - (loop as PluginBase).isEnabled() && loop.isSuperBolus -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_superbolus) - apsModeSetA11yLabel(R.string.superbolus) - binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) - binding.infoLayout.apsModeText.visibility = View.VISIBLE - } + runOnUiThread { + _binding ?: return@runOnUiThread + if (config.APS && pump.pumpDescription.isTempBasalCapable) { + binding.infoLayout.apsMode.visibility = View.VISIBLE + binding.infoLayout.timeLayout.visibility = View.GONE + when { + (loop as PluginBase).isEnabled() && loop.isSuperBolus -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_superbolus) + apsModeSetA11yLabel(R.string.superbolus) + binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) + binding.infoLayout.apsModeText.visibility = View.VISIBLE + } - loop.isDisconnected -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disconnected) - apsModeSetA11yLabel(R.string.disconnected) - binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) - binding.infoLayout.apsModeText.visibility = View.VISIBLE - } + loop.isDisconnected -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disconnected) + apsModeSetA11yLabel(R.string.disconnected) + binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) + binding.infoLayout.apsModeText.visibility = View.VISIBLE + } - (loop as PluginBase).isEnabled() && loop.isSuspended -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_paused) - apsModeSetA11yLabel(R.string.suspendloop_label) - binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) - binding.infoLayout.apsModeText.visibility = View.VISIBLE - } + (loop as PluginBase).isEnabled() && loop.isSuspended -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_paused) + apsModeSetA11yLabel(R.string.suspendloop_label) + binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) + binding.infoLayout.apsModeText.visibility = View.VISIBLE + } - pump.isSuspended() -> { - binding.infoLayout.apsMode.setImageResource( - if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) { - // For Omnipod, indicate the pump as disconnected when it's suspended. - // The only way to 'reconnect' it, is through the Omnipod tab - apsModeSetA11yLabel(R.string.disconnected) - R.drawable.ic_loop_disconnected - } else { - apsModeSetA11yLabel(R.string.pump_paused) - R.drawable.ic_loop_paused - } - ) - binding.infoLayout.apsModeText.visibility = View.GONE - } - - (loop as PluginBase).isEnabled() && closedLoopEnabled.value() && loop.isLGS -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_lgs) - apsModeSetA11yLabel(R.string.uel_lgs_loop_mode) - binding.infoLayout.apsModeText.visibility = View.GONE - } - - (loop as PluginBase).isEnabled() && closedLoopEnabled.value() -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_closed) - apsModeSetA11yLabel(R.string.closedloop) - binding.infoLayout.apsModeText.visibility = View.GONE - } - - (loop as PluginBase).isEnabled() && !closedLoopEnabled.value() -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_open) - apsModeSetA11yLabel(R.string.openloop) - binding.infoLayout.apsModeText.visibility = View.GONE - } - - else -> { - binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disabled) - apsModeSetA11yLabel(R.string.disabledloop) - binding.infoLayout.apsModeText.visibility = View.GONE - } - } - // Show variable sensitivity - val request = loop.lastRun?.request - if (request is DetermineBasalResultSMB) { - val isfMgdl = profileFunction.getProfile()?.getIsfMgdl() - val variableSens = request.variableSens - if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) { - binding.infoLayout.variableSensitivity.text = - String.format( - Locale.getDefault(), "%1$.1f→%2$.1f", - Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()), - Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()) + pump.isSuspended() -> { + binding.infoLayout.apsMode.setImageResource( + if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) { + // For Omnipod, indicate the pump as disconnected when it's suspended. + // The only way to 'reconnect' it, is through the Omnipod tab + apsModeSetA11yLabel(R.string.disconnected) + R.drawable.ic_loop_disconnected + } else { + apsModeSetA11yLabel(R.string.pump_paused) + R.drawable.ic_loop_paused + } ) - binding.infoLayout.variableSensitivity.visibility = View.VISIBLE + binding.infoLayout.apsModeText.visibility = View.GONE + } + + (loop as PluginBase).isEnabled() && closedLoopEnabled.value() && loop.isLGS -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_lgs) + apsModeSetA11yLabel(R.string.uel_lgs_loop_mode) + binding.infoLayout.apsModeText.visibility = View.GONE + } + + (loop as PluginBase).isEnabled() && closedLoopEnabled.value() -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_closed) + apsModeSetA11yLabel(R.string.closedloop) + binding.infoLayout.apsModeText.visibility = View.GONE + } + + (loop as PluginBase).isEnabled() && !closedLoopEnabled.value() -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_open) + apsModeSetA11yLabel(R.string.openloop) + binding.infoLayout.apsModeText.visibility = View.GONE + } + + else -> { + binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disabled) + apsModeSetA11yLabel(R.string.disabledloop) + binding.infoLayout.apsModeText.visibility = View.GONE + } + } + // Show variable sensitivity + val request = loop.lastRun?.request + if (request is DetermineBasalResultSMB) { + val isfMgdl = profile?.getIsfMgdl() + val variableSens = request.variableSens + if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) { + binding.infoLayout.variableSensitivity.text = + String.format( + Locale.getDefault(), "%1$.1f→%2$.1f", + Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()), + Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()) + ) + binding.infoLayout.variableSensitivity.visibility = View.VISIBLE + } else binding.infoLayout.variableSensitivity.visibility = View.GONE } else binding.infoLayout.variableSensitivity.visibility = View.GONE - } else binding.infoLayout.variableSensitivity.visibility = View.GONE - } else { - //nsclient - binding.infoLayout.apsMode.visibility = View.GONE - binding.infoLayout.apsModeText.visibility = View.GONE - binding.infoLayout.timeLayout.visibility = View.VISIBLE + } else { + //nsclient + binding.infoLayout.apsMode.visibility = View.GONE + binding.infoLayout.apsModeText.visibility = View.GONE + binding.infoLayout.timeLayout.visibility = View.VISIBLE + } + + // pump status from ns + binding.pump.text = nsDeviceStatus.pumpStatus + binding.pump.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.pump), nsDeviceStatus.extendedPumpStatus) } } + + // OpenAPS status from ns + binding.openaps.text = nsDeviceStatus.openApsStatus + binding.openaps.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.openaps), nsDeviceStatus.extendedOpenApsStatus) } } + + // Uploader status from ns + binding.uploader.text = nsDeviceStatus.uploaderStatusSpanned + binding.uploader.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.uploader), nsDeviceStatus.extendedUploaderStatus) } } } - - // pump status from ns - binding.pump.text = nsDeviceStatus.pumpStatus - binding.pump.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.pump), nsDeviceStatus.extendedPumpStatus) } } - - // OpenAPS status from ns - binding.openaps.text = nsDeviceStatus.openApsStatus - binding.openaps.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.openaps), nsDeviceStatus.extendedOpenApsStatus) } } - - // Uploader status from ns - binding.uploader.text = nsDeviceStatus.uploaderStatusSpanned - binding.uploader.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.uploader), nsDeviceStatus.extendedUploaderStatus) } } } private fun prepareGraphsIfNeeded(numOfGraphs: Int) { @@ -760,59 +772,67 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList @SuppressLint("SetTextI18n") fun updateBg() { - _binding ?: return val units = profileFunction.getUnits() - binding.infoLayout.bg.text = overviewData.lastBg?.valueToUnitsString(units) - ?: rh.gs(R.string.notavailable) - binding.infoLayout.bg.setTextColor(overviewData.lastBgColor(context)) - binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(overviewData.lastBg).directionToIcon()) - binding.infoLayout.arrow.setColorFilter(overviewData.lastBgColor(context)) - binding.infoLayout.arrow.contentDescription = overviewData.lastBgDescription + " " + rh.gs(R.string.and) + " " + trendCalculator.getTrendDescription(overviewData.lastBg) - + val lastBg = overviewData.lastBg + val lastBgColor = overviewData.lastBgColor(context) + val isActualBg = overviewData.isActualBg val glucoseStatus = glucoseStatusProvider.glucoseStatusData - if (glucoseStatus != null) { - binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) - binding.infoLayout.deltaLarge.setTextColor(overviewData.lastBgColor(context)) - binding.infoLayout.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) - binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units) - binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units) - } else { - binding.infoLayout.deltaLarge.text = "" - binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.notavailable) - binding.infoLayout.avgDelta.text = "" - binding.infoLayout.longAvgDelta.text = "" - } + val trendDescription = trendCalculator.getTrendDescription(lastBg) + val trendArrow = trendCalculator.getTrendArrow(lastBg) + val lastBgDescription = overviewData.lastBgDescription + runOnUiThread { + _binding ?: return@runOnUiThread + binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units) + ?: rh.gs(R.string.notavailable) + binding.infoLayout.bg.setTextColor(lastBgColor) + binding.infoLayout.arrow.setImageResource(trendArrow.directionToIcon()) + binding.infoLayout.arrow.setColorFilter(lastBgColor) + binding.infoLayout.arrow.contentDescription = lastBgDescription + " " + rh.gs(R.string.and) + " " + trendDescription - // strike through if BG is old - binding.infoLayout.bg.paintFlags = - if (!overviewData.isActualBg) binding.infoLayout.bg.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG - else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() - - val outDate = (if (!overviewData.isActualBg) rh.gs(R.string.a11y_bg_outdated) else "") - binding.infoLayout.bg.contentDescription = - rh.gs(R.string.a11y_blood_glucose) + " " + binding.infoLayout.bg.text.toString() + " " + overviewData.lastBgDescription + " " + outDate - - binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, overviewData.lastBg?.timestamp) - binding.infoLayout.timeAgo.contentDescription = dateUtil.minAgoLong(rh, overviewData.lastBg?.timestamp) - binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")" - - val qualityIcon = bgQualityCheckPlugin.icon() - if (qualityIcon != 0) { - binding.infoLayout.bgQuality.visibility = View.VISIBLE - binding.infoLayout.bgQuality.setImageResource(qualityIcon) - binding.infoLayout.bgQuality.contentDescription = rh.gs(R.string.a11y_bg_quality) + " " + bgQualityCheckPlugin.stateDescription() - binding.infoLayout.bgQuality.setOnClickListener { - context?.let { context -> OKDialog.show(context, rh.gs(R.string.data_status), bgQualityCheckPlugin.message) } + if (glucoseStatus != null) { + binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + binding.infoLayout.deltaLarge.setTextColor(lastBgColor) + binding.infoLayout.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units) + binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units) + } else { + binding.infoLayout.deltaLarge.text = "" + binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.notavailable) + binding.infoLayout.avgDelta.text = "" + binding.infoLayout.longAvgDelta.text = "" + } + + // strike through if BG is old + binding.infoLayout.bg.paintFlags = + if (!isActualBg) binding.infoLayout.bg.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG + else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() + + val outDate = (if (!isActualBg) rh.gs(R.string.a11y_bg_outdated) else "") + binding.infoLayout.bg.contentDescription = rh.gs(R.string.a11y_blood_glucose) + " " + binding.infoLayout.bg.text.toString() + " " + lastBgDescription + " " + outDate + + binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, lastBg?.timestamp) + binding.infoLayout.timeAgo.contentDescription = dateUtil.minAgoLong(rh, lastBg?.timestamp) + binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(lastBg?.timestamp) + ")" + + val qualityIcon = bgQualityCheckPlugin.icon() + if (qualityIcon != 0) { + binding.infoLayout.bgQuality.visibility = View.VISIBLE + binding.infoLayout.bgQuality.setImageResource(qualityIcon) + binding.infoLayout.bgQuality.contentDescription = rh.gs(R.string.a11y_bg_quality) + " " + bgQualityCheckPlugin.stateDescription() + binding.infoLayout.bgQuality.setOnClickListener { + context?.let { context -> OKDialog.show(context, rh.gs(R.string.data_status), bgQualityCheckPlugin.message) } + } + } else { + binding.infoLayout.bgQuality.visibility = View.GONE } - } else { - binding.infoLayout.bgQuality.visibility = View.GONE } } fun updateProfile() { - _binding ?: return - val profileBackgroundColor = - profileFunction.getProfile()?.let { + val profile = profileFunction.getProfile() + runOnUiThread { + _binding ?: return@runOnUiThread + val profileBackgroundColor = profile?.let { if (it is ProfileSealed.EPS) { if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L) R.attr.ribbonWarningColor @@ -824,8 +844,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList } } ?: R.attr.ribbonCriticalColor - val profileTextColor = - profileFunction.getProfile()?.let { + val profileTextColor = profile?.let { if (it is ProfileSealed.EPS) { if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L) R.attr.ribbonTextWarningColor @@ -836,27 +855,35 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList R.attr.ribbonTextDefaultColor } } ?: R.attr.ribbonTextDefaultColor - setRibbon(binding.activeProfile, profileTextColor, profileBackgroundColor, profileFunction.getProfileNameWithRemainingTime()) + setRibbon(binding.activeProfile, profileTextColor, profileBackgroundColor, profileFunction.getProfileNameWithRemainingTime()) + } } private fun updateTemporaryBasal() { - _binding ?: return - binding.infoLayout.baseBasal.text = overviewData.temporaryBasalText(iobCobCalculator) - binding.infoLayout.baseBasal.setTextColor(overviewData.temporaryBasalColor(context, iobCobCalculator)) - binding.infoLayout.baseBasalIcon.setImageResource(overviewData.temporaryBasalIcon(iobCobCalculator)) - binding.infoLayout.basalLayout.setOnClickListener { - activity?.let { OKDialog.show(it, rh.gs(R.string.basal), overviewData.temporaryBasalDialogText(iobCobCalculator)) } + val temporaryBasalText = overviewData.temporaryBasalText(iobCobCalculator) + val temporaryBasalColor = overviewData.temporaryBasalColor(context, iobCobCalculator) + val temporaryBasalIcon = overviewData.temporaryBasalIcon(iobCobCalculator) + val temporaryBasalDialogText = overviewData.temporaryBasalDialogText(iobCobCalculator) + runOnUiThread { + _binding ?: return@runOnUiThread + binding.infoLayout.baseBasal.text = temporaryBasalText + binding.infoLayout.baseBasal.setTextColor(temporaryBasalColor) + binding.infoLayout.baseBasalIcon.setImageResource(temporaryBasalIcon) + binding.infoLayout.basalLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.basal), temporaryBasalDialogText) } } } } private fun updateExtendedBolus() { - _binding ?: return val pump = activePlugin.activePump - binding.infoLayout.extendedBolus.text = overviewData.extendedBolusText(iobCobCalculator) - binding.infoLayout.extendedLayout.setOnClickListener { - activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), overviewData.extendedBolusDialogText(iobCobCalculator)) } + val extendedBolus = iobCobCalculator.getExtendedBolus(dateUtil.now()) + val extendedBolusText = overviewData.extendedBolusText(iobCobCalculator) + val extendedBolusDialogText = overviewData.extendedBolusDialogText(iobCobCalculator) + runOnUiThread { + _binding ?: return@runOnUiThread + binding.infoLayout.extendedBolus.text = extendedBolusText + binding.infoLayout.extendedLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), extendedBolusDialogText) } } + binding.infoLayout.extendedLayout.visibility = (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses).toVisibility() } - binding.infoLayout.extendedLayout.visibility = (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility() } fun updateTime() { @@ -887,69 +914,73 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList binding.statusLightsLayout.pbAge, binding.statusLightsLayout.batteryLevel ) - processButtonsVisibility() - processAps() } fun updateIobCob() { - _binding ?: return - binding.infoLayout.iob.text = overviewData.iobText(iobCobCalculator) - binding.infoLayout.iobLayout.setOnClickListener { - activity?.let { OKDialog.show(it, rh.gs(R.string.iob), overviewData.iobDialogText(iobCobCalculator)) } - } - // cob - var cobText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, buildHelper.isEngineeringMode()) ?: rh.gs(R.string.value_unavailable_short) + val iobText = overviewData.iobText(iobCobCalculator) + val iobDialogText = overviewData.iobDialogText(iobCobCalculator) + val displayText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, buildHelper.isEngineeringMode()) + val lastCarbsTime = overviewData.lastCarbsTime + runOnUiThread { + _binding ?: return@runOnUiThread + binding.infoLayout.iob.text = iobText + binding.infoLayout.iobLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.iob), iobDialogText) } } + // cob + var cobText = displayText ?: rh.gs(R.string.value_unavailable_short) - val constraintsProcessed = loop.lastRun?.constraintsProcessed - val lastRun = loop.lastRun - if (config.APS && constraintsProcessed != null && lastRun != null) { - if (constraintsProcessed.carbsReq > 0) { - //only display carbsreq when carbs have not been entered recently - if (overviewData.lastCarbsTime < lastRun.lastAPSRun) { - cobText += " | " + constraintsProcessed.carbsReq + " " + rh.gs(R.string.required) + val constraintsProcessed = loop.lastRun?.constraintsProcessed + val lastRun = loop.lastRun + if (config.APS && constraintsProcessed != null && lastRun != null) { + if (constraintsProcessed.carbsReq > 0) { + //only display carbsreq when carbs have not been entered recently + if (lastCarbsTime < lastRun.lastAPSRun) { + cobText += " | " + constraintsProcessed.carbsReq + " " + rh.gs(R.string.required) + } + if (carbAnimation?.isRunning == false) + carbAnimation?.start() + } else { + carbAnimation?.stop() + carbAnimation?.selectDrawable(0) } - if (carbAnimation?.isRunning == false) - carbAnimation?.start() - } else { - carbAnimation?.stop() - carbAnimation?.selectDrawable(0) } + binding.infoLayout.cob.text = cobText } - binding.infoLayout.cob.text = cobText } @SuppressLint("SetTextI18n") fun updateTemporaryTarget() { - _binding ?: return val units = profileFunction.getUnits() val tempTarget = overviewData.temporaryTarget - if (tempTarget != null) { - setRibbon( - binding.tempTarget, - R.attr.ribbonTextWarningColor, - R.attr.ribbonWarningColor, - Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh) - ) - } else { - // If the target is not the same as set in the profile then oref has overridden it - profileFunction.getProfile()?.let { profile -> - val targetUsed = loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0 + runOnUiThread { + _binding ?: return@runOnUiThread + if (tempTarget != null) { + setRibbon( + binding.tempTarget, + R.attr.ribbonTextWarningColor, + R.attr.ribbonWarningColor, + Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh) + ) + } else { + // If the target is not the same as set in the profile then oref has overridden it + profileFunction.getProfile()?.let { profile -> + val targetUsed = loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0 - if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) { - aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed") - setRibbon( - binding.tempTarget, - R.attr.ribbonTextWarningColor, - R.attr.tempTargetBackgroundColor, - Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units) - ) - } else { - setRibbon( - binding.tempTarget, - R.attr.ribbonTextDefaultColor, - R.attr.ribbonDefaultColor, - Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units) - ) + if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) { + aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed") + setRibbon( + binding.tempTarget, + R.attr.ribbonTextWarningColor, + R.attr.tempTargetBackgroundColor, + Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units) + ) + } else { + setRibbon( + binding.tempTarget, + R.attr.ribbonTextDefaultColor, + R.attr.ribbonDefaultColor, + Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units) + ) + } } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt index 42db526cd4..e388adb8bf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt @@ -19,7 +19,7 @@ import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt index 11de792fbd..04095b64a8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.general.overview -import android.graphics.Color import android.widget.TextView import androidx.annotation.StringRes import info.nightscout.androidaps.R @@ -97,7 +96,7 @@ class StatusLightHandler @Inject constructor( if (level > OmnipodConstants.MAX_RESERVOIR_READING) { @Suppress("SetTextI18n") view?.text = " 50+$units" - view?.setTextColor(Color.WHITE) + view?.setTextColor(rh.gac(view.context, R.attr.defaultTextColor)) } else { handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt index 0e9fa99b8b..7b34ba26c3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.kt @@ -73,12 +73,16 @@ class GraphData( } fun addBasals() { - val scale = defaultValueHelper.determineLowLine() / maxY / 1.2 + overviewData.basalScale.multiplier = 1.0 // get unscaled Y-values for max calculation + var maxBasalValue = maxOf(0.1, overviewData.baseBasalGraphSeries.highestValueY, overviewData.tempBasalGraphSeries.highestValueY) + maxBasalValue = maxOf(maxBasalValue, overviewData.basalLineGraphSeries.highestValueY, overviewData.absoluteBasalGraphSeries.highestValueY) addSeries(overviewData.baseBasalGraphSeries) addSeries(overviewData.tempBasalGraphSeries) addSeries(overviewData.basalLineGraphSeries) addSeries(overviewData.absoluteBasalGraphSeries) - overviewData.basalScale.multiplier = maxY * scale / overviewData.maxBasalValueFound + maxY = max(maxY, defaultValueHelper.determineHighLine()) + val scale = defaultValueHelper.determineLowLine() / maxY / 1.2 + overviewData.basalScale.multiplier = maxY * scale / maxBasalValue } fun addTargetLine() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationStore.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationStore.kt index ddfd52f32e..6fefe0c3ad 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationStore.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationStore.kt @@ -17,12 +17,12 @@ import info.nightscout.androidaps.databinding.OverviewNotificationItemBinding import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.IconsProvider import info.nightscout.androidaps.interfaces.NotificationHolder -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewNotification import info.nightscout.androidaps.services.AlarmSoundServiceHelper import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import java.util.* import javax.inject.Inject @@ -68,7 +68,7 @@ class NotificationStore @Inject constructor( store.add(n) if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction) raiseSystemNotification(n) - if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId!!) + if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId!!, n.text) Collections.sort(store, NotificationComparator()) return true } @@ -77,7 +77,7 @@ class NotificationStore @Inject constructor( fun remove(id: Int): Boolean { for (i in store.indices) { if (store[i].id == id) { - if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context) + if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context, "Removed " + store[i].text) aapsLogger.debug(LTag.NOTIFICATION, "Notification removed: " + store[i].text) store.removeAt(i) return true @@ -92,7 +92,7 @@ class NotificationStore @Inject constructor( while (i < store.size) { val n = store[i] if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) { - if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context) + if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context, "Expired " + store[i].text) aapsLogger.debug(LTag.NOTIFICATION, "Notification expired: " + store[i].text) store.removeAt(i) i-- diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index 61021d55bc..311b1999fa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -966,6 +966,7 @@ class SmsCommunicatorPlugin @Inject constructor( var keyTarget = 0 var defaultTargetMMOL = 0.0 var defaultTargetMGDL = 0.0 + var reason = TemporaryTarget.Reason.EATING_SOON when { isMeal -> { keyDuration = R.string.key_eatingsoon_duration @@ -973,6 +974,7 @@ class SmsCommunicatorPlugin @Inject constructor( keyTarget = R.string.key_eatingsoon_target defaultTargetMMOL = Constants.defaultEatingSoonTTmmol defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl + reason = TemporaryTarget.Reason.EATING_SOON } isActivity -> { @@ -981,6 +983,7 @@ class SmsCommunicatorPlugin @Inject constructor( keyTarget = R.string.key_activity_target defaultTargetMMOL = Constants.defaultActivityTTmmol defaultTargetMGDL = Constants.defaultActivityTTmgdl + reason = TemporaryTarget.Reason.ACTIVITY } isHypo -> { @@ -989,6 +992,7 @@ class SmsCommunicatorPlugin @Inject constructor( keyTarget = R.string.key_hypo_target defaultTargetMMOL = Constants.defaultHypoTTmmol defaultTargetMGDL = Constants.defaultHypoTTmgdl + reason = TemporaryTarget.Reason.HYPOGLYCEMIA } } var ttDuration = sp.getInt(keyDuration, defaultTargetDuration) @@ -999,7 +1003,7 @@ class SmsCommunicatorPlugin @Inject constructor( disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction( timestamp = dateUtil.now(), duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()), - reason = TemporaryTarget.Reason.EATING_SOON, + reason = reason, lowTarget = Profile.toMgdl(tt, profileFunction.getUnits()), highTarget = Profile.toMgdl(tt, profileFunction.getUnits()) )).subscribe({ result -> diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatusLinePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatusLinePlugin.kt index 104949730d..1c54ea4feb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatusLinePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatusLinePlugin.kt @@ -123,8 +123,8 @@ class StatusLinePlugin @Inject constructor( status += activeTemp.toStringShort() + " " } //IOB - val bolusIob = iobCobCalculator.calculateIobFromBolus().round() - val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() + val bolusIob = iobCobCalculator.calculateIobFromBolus().round(fabricPrivacy) + val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round(fabricPrivacy) status += DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U" if (sp.getBoolean(R.string.key_xdripstatus_detailediob, true)) { status += ("(" 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 6d76621a6d..00fa1dd6dd 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 @@ -30,6 +30,7 @@ import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP @@ -127,10 +128,20 @@ class IobCobCalculatorPlugin @Inject constructor( } private fun resetDataAndRunCalculation(reason: String, event: Event?) { - calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,reason) + calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, reason) clearCache() ads.reset() - calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event, runLoop = true) + calculationWorkflow.runCalculation( + CalculationWorkflow.MAIN_CALCULATION, + this, + overviewData, + reason, + System.currentTimeMillis(), + bgDataReload = false, + limitDataToOldestAvailable = true, + cause = event, + runLoop = true + ) } override fun clearCache() { @@ -363,18 +374,21 @@ class IobCobCalculatorPlugin @Inject constructor( scheduledHistoryPost?.cancel(false) // prepare task for execution in 1 sec scheduledEvent = event - scheduledHistoryPost = historyWorker.schedule({ - synchronized(this) { - aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData") - newHistoryData( - event.oldDataTimestamp, - event.reloadBgData, - if (event.newestGlucoseValue != null) EventNewBG(event.newestGlucoseValue) else event - ) - scheduledEvent = null - scheduledHistoryPost = null - } - }, 1L, TimeUnit.SECONDS) + scheduledHistoryPost = historyWorker.schedule( + { + synchronized(this) { + aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData") + repository.clearCachedData(MidnightTime.calc(event.oldDataTimestamp)) + newHistoryData( + event.oldDataTimestamp, + event.reloadBgData, + if (event.newestGlucoseValue != null) EventNewBG(event.newestGlucoseValue) else event + ) + scheduledEvent = null + scheduledHistoryPost = null + } + }, 1L, TimeUnit.SECONDS + ) } else { // asked reload is newer -> adjust params only scheduledEvent?.let { @@ -391,7 +405,7 @@ class IobCobCalculatorPlugin @Inject constructor( // When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) { //log.debug("Locking onNewHistoryData"); - calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,"onEventNewHistoryData") + calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, "onEventNewHistoryData") synchronized(dataLock) { // clear up 5 min back for proper COB calculation @@ -415,7 +429,7 @@ class IobCobCalculatorPlugin @Inject constructor( } ads.newHistoryData(time, aapsLogger, dateUtil) } - calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true) + calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION, this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true) //log.debug("Releasing onNewHistoryData"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt index 854e08aebc..4d157a874a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Worker.kt @@ -30,7 +30,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt index a093a3c2b9..347d4bb573 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOrefWorker.kt @@ -28,7 +28,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.shared.logging.AAPSLogger diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt index 459575c234..3e0a9d2d8c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/AidexPlugin.kt @@ -10,13 +10,10 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.transactions.CgmSourceTransaction -import info.nightscout.androidaps.interfaces.BgSource -import info.nightscout.androidaps.interfaces.PluginBase -import info.nightscout.androidaps.interfaces.PluginDescription -import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.receivers.Intents -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import javax.inject.Inject @@ -26,7 +23,9 @@ import javax.inject.Singleton class AidexPlugin @Inject constructor( injector: HasAndroidInjector, rh: ResourceHelper, - aapsLogger: AAPSLogger + aapsLogger: AAPSLogger, + private val buildHelper: BuildHelper, + private val config: Config ) : PluginBase( PluginDescription() .mainType(PluginType.BGSOURCE) @@ -49,6 +48,11 @@ class AidexPlugin @Inject constructor( return advancedFiltering } + // Allow only for pumpcontrol or dev & engineering_mode + override fun specialEnableCondition(): Boolean { + return config.APS.not() || buildHelper.isDev() && buildHelper.isEngineeringMode() + } + // cannot be inner class because of needed injection class AidexWorker( context: Context, diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt index caf4bc9f49..bbfbd91d31 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueueImplementation.kt @@ -35,7 +35,7 @@ import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger @@ -327,7 +327,7 @@ class CommandQueueImplementation @Inject constructor( } removeAll(CommandType.BOLUS) removeAll(CommandType.SMB_BOLUS) - Thread { activePlugin.activePump.stopBolusDelivering() }.run() + Thread { activePlugin.activePump.stopBolusDelivering() }.start() } // returns true if command is queued diff --git a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt b/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt index cf96415ef2..512f1b2d53 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt @@ -12,15 +12,15 @@ import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnoun import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +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.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin -import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -128,7 +128,7 @@ class LocalAlertUtils @Inject constructor( rxBus.send(EventNewNotification(n)) uel.log(Action.CAREPORTAL, Sources.Aaps, rh.gs(R.string.missed_bg_readings), ValueWithUnit.TherapyEventType(TherapyEvent.Type.ANNOUNCEMENT)) if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { - n.text?.let { disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(it)).subscribe() } + disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(n.text)).subscribe() } } else if (dateUtil.isOlderThan(bgReading.timestamp, 5).not()) { rxBus.send(EventDismissNotification(Notification.BG_READINGS_MISSED)) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelperImpl.kt b/app/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelperImpl.kt index 77e725e998..5408591634 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelperImpl.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelperImpl.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.utils.buildHelper import info.nightscout.androidaps.BuildConfig +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import java.io.File diff --git a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt index 91ef25a1f8..e6261c5e37 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/stats/TddCalculator.kt @@ -11,6 +11,8 @@ import android.widget.TableRow import android.widget.TextView import info.nightscout.androidaps.R import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.database.ValueWrapper +import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.TotalDailyDose import info.nightscout.androidaps.extensions.convertedToAbsolute @@ -19,10 +21,10 @@ import info.nightscout.androidaps.extensions.toTableRowHeader import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import javax.inject.Inject @@ -38,48 +40,62 @@ class TddCalculator @Inject constructor( ) { fun calculate(days: Long): LongSparseArray { - val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs()) + var startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs()) val endTime = MidnightTime.calc(dateUtil.now()) val result = LongSparseArray() - repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() - .filter { it.type != Bolus.Type.PRIMING } - .forEach { t -> - val midnight = MidnightTime.calc(t.timestamp) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - tdd.bolusAmount += t.amount - result.put(midnight, tdd) - } - repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> - val midnight = MidnightTime.calc(t.timestamp) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - tdd.carbs += t.amount - result.put(midnight, tdd) + // Try to load cached values + while (startTime < endTime) { + val tdd = repository.getCalculatedTotalDailyDose(startTime).blockingGet() + if (tdd is ValueWrapper.Existing) result.put(startTime, tdd.value) + else break + startTime += T.hours(24).msecs() } - val calculationStep = T.mins(5).msecs() - val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep) - for (t in startTime until endTime step calculationStep) { - val midnight = MidnightTime.calc(t) - val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) - val tbr = tempBasals[t] - val profile = profileFunction.getProfile(t) ?: continue - val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) - tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() - - if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) { - // they are not included in TBRs - val eb = iobCobCalculator.getExtendedBolus(t) - val absoluteEbRate = eb?.rate ?: 0.0 - tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() + if (endTime > startTime) { + repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() + .filter { it.type != Bolus.Type.PRIMING } + .forEach { t -> + val midnight = MidnightTime.calc(t.timestamp) + val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) + tdd.bolusAmount += t.amount + result.put(midnight, tdd) + } + repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> + val midnight = MidnightTime.calc(t.timestamp) + val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) + tdd.carbs += t.amount + result.put(midnight, tdd) + } + + val calculationStep = T.mins(5).msecs() + val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep) + for (t in startTime until endTime step calculationStep) { + val midnight = MidnightTime.calc(t) + val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) + val tbr = tempBasals[t] + val profile = profileFunction.getProfile(t) ?: continue + val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) + tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() + + if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) { + // they are not included in TBRs + val eb = iobCobCalculator.getExtendedBolus(t) + val absoluteEbRate = eb?.rate ?: 0.0 + tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() + } + result.put(midnight, tdd) } - result.put(midnight, tdd) } for (i in 0 until result.size()) { val tdd = result.valueAt(i) tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount + if (tdd.interfaceIDs.pumpType != InterfaceIDs.PumpType.CACHE) { + tdd.interfaceIDs.pumpType = InterfaceIDs.PumpType.CACHE + aapsLogger.debug(LTag.CORE, "Storing TDD $tdd") + repository.createTotalDailyDose(tdd) + } } - aapsLogger.debug(LTag.CORE, result.toString()) return result } @@ -91,22 +107,13 @@ class TddCalculator @Inject constructor( repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() .filter { it.type != Bolus.Type.PRIMING } .forEach { t -> - //val midnight = MidnightTime.calc(t.timestamp) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) tdd.bolusAmount += t.amount - //result.put(midnight, tdd) } repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> - //val midnight = MidnightTime.calc(t.timestamp) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) tdd.carbs += t.amount - //result.put(midnight, tdd) } val calculationStep = T.mins(5).msecs() for (t in startTime until endTime step calculationStep) { - - //val midnight = MidnightTime.calc(t) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val profile = profileFunction.getProfile(t) ?: continue val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) @@ -118,13 +125,8 @@ class TddCalculator @Inject constructor( val absoluteEbRate = eb?.rate ?: 0.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 } - //result.put(midnight, tdd) } - //for (i in 0 until tdd.size()) { - //val tdd = result.valueAt(i) tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount - //} - aapsLogger.debug(LTag.CORE, tdd.toString()) return tdd } @@ -133,27 +135,16 @@ class TddCalculator @Inject constructor( val startTime = dateUtil.now() - T.hours(hour = 24).msecs() val endTime = dateUtil.now() val tdd = TotalDailyDose(timestamp = startTime) - //val result = TotalDailyDose() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() .filter { it.type != Bolus.Type.PRIMING } .forEach { t -> - //val midnight = MidnightTime.calc(t.timestamp) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) tdd.bolusAmount += t.amount - //result.put(midnight, tdd) } repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> - //val midnight = MidnightTime.calc(t.timestamp) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) tdd.carbs += t.amount - //result.put(midnight, tdd) } val calculationStep = T.mins(5).msecs() - //val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep) for (t in startTime until endTime step calculationStep) { - - //val midnight = MidnightTime.calc(t) - //val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val profile = profileFunction.getProfile(t) ?: continue val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) @@ -165,13 +156,8 @@ class TddCalculator @Inject constructor( val absoluteEbRate = eb?.rate ?: 0.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 } - //result.put(midnight, tdd) } - //for (i in 0 until tdd.size()) { - //val tdd = result.valueAt(i) tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount - //} - aapsLogger.debug(LTag.CORE, tdd.toString()) return tdd } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/ui/TimeListEdit.java b/app/src/main/java/info/nightscout/androidaps/utils/ui/TimeListEdit.java index 1d79a9205e..437bb3cbd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/ui/TimeListEdit.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/ui/TimeListEdit.java @@ -182,7 +182,7 @@ public class TimeListEdit { numberPickers1[position].setTextWatcher(new TextWatcher() { @Override public void afterTextChanged(Editable s) { - Double value1 = SafeParse.stringToDouble(numberPickers1[position].getText()); + Double value1 = SafeParse.INSTANCE.stringToDouble(numberPickers1[position].getText()); Double value2 = value2(position); if (data2 != null && value1 > value2) { value2 = value1; @@ -209,7 +209,7 @@ public class TimeListEdit { @Override public void afterTextChanged(Editable s) { Double value1 = value1(position); - Double value2 = SafeParse.stringToDouble(numberPickers2[position].getText()); + Double value2 = SafeParse.INSTANCE.stringToDouble(numberPickers2[position].getText()); if (data2 != null && value2 < value1) { value1 = value2; numberPickers1[position].setValue(value1); diff --git a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBasalDataWorker.kt b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBasalDataWorker.kt index b2bff7a245..45f8bd4e0c 100644 --- a/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBasalDataWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/workflow/PrepareBasalDataWorker.kt @@ -47,7 +47,6 @@ class PrepareBasalDataWorker( ?: return Result.failure(workDataOf("Error" to "missing input data")) rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, 0, null)) - data.overviewData.maxBasalValueFound = 0.0 val baseBasalArray: MutableList = ArrayList() val tempBasalArray: MutableList = ArrayList() val basalLineArray: MutableList = ArrayList() @@ -104,7 +103,6 @@ class PrepareBasalDataWorker( lastAbsoluteLineBasal = absoluteLineValue lastLineBasal = baseBasalValue lastTempBasal = tempBasalValue - data.overviewData.maxBasalValueFound = max(data.overviewData.maxBasalValueFound, max(tempBasalValue, baseBasalValue)) time += 60 * 1000L } diff --git a/app/src/main/res/layout/autotune_fragment.xml b/app/src/main/res/layout/autotune_fragment.xml index 003699e6ba..744b9a260e 100644 --- a/app/src/main/res/layout/autotune_fragment.xml +++ b/app/src/main/res/layout/autotune_fragment.xml @@ -140,7 +140,8 @@ android:gravity="start" android:paddingStart="5dp" android:paddingEnd="5dp" - android:textSize="14sp" /> + android:textSize="14sp" + android:textColor="@color/colorCalculatorButton"/> diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index 421e2254c6..809877af52 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -127,6 +127,7 @@ Eindverbruiker Lisensie Ooreenkoms MOET NIE GEBRUIK WORD OM MEDIESE BESLUITE TE MAAK NIE. DAAR IS GEEN WAARBORG DAT DIE PROGRAM, ONDERWORPE AAN TOEPASSELIKE WETTE EN WETGEWING. TENSY ANDERS GEMELD IN TEKS VOORSIEN DIE KOPIEREG-HOUERS EN / OF ANDER PARTYE DIE PROGRAM \"AS IS\" SONDER ËNIGE WAARBORG VAN ENIGE ORDE, UITDRUKKELIK OF IMPLISIET, INKLUSIEF, MAAR NIE BEPERK TOT DIE IMPLISIETE WAARBORG VAN TOEPAASBAARHEID OF NUT VIR EEN SPESIFIEKE DOEL. DIE TOTALE EN ALLE RISIKOVIR DIE KWALITEIT EN PRESTASIE VAN DIE PROGRAM RUS MET JOUSELF. VIR ENIGE PROGRAM DEFEKTIEWE OF FALINGS MOET JY PERSOONLIK DIE KOSTE EN REGSAANSPREEKLIKHEID DRA VAN ALLE NODIGE AKSIES, DIENS, REPARASIES OF KORREKSIES VIR USELF OF ENIGE DERDE PARTYE EN/OF AKSIES, DIENS, REPARASIES OF KORREKSIES WAT DEUR DIE PROGRAM GEDOEN WAS. EK VERSTAAN en STEM IN + Stoor Herlaai profiel SMS Communicator Toegelate telefoon nommers @@ -457,9 +458,7 @@ Tweede koolhidrate inkrement Derde koolhidrate inkrement CGM - Gebruik slegs WiFi verbinding WiFi SSID - Slegs wanneer laai Verbindinginstellings Toegelate SSID\'s (kommapunt geskei) Laat verbindings toe terwyl swerf diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 39a40f5ee2..0cd5f28707 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -591,9 +591,7 @@ Стойност на втория бърз бутон [гр] Стойност на третия бърз бутон [гр] CGM - Използвай само WiFi WiFi име - Само при зареждане на телефона Настройки за свързване Разрешени WiFi мрежи(разделени с запетая) Позволи връзка в роуминг @@ -881,5 +879,6 @@ Недостъпно + Вход diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index 34b622bacc..7319244844 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -154,6 +154,7 @@ Acord de llicència per a l\'usuari final NO S\'HA D\'UTILITZAR PER A PRENDRE DECISIONS MÈDIQUES. EL PROGRAMA NO TÉ GARANTIA, EN LA MESURA QUE HO PERMET LA LLEI APLICABLE. EXCEPTE QUAN S\'INDIQUI EL CONTRARI PER ESCRIT, ELS PROPIETARIS DEL COPYRIGHT I/O ALTRES PARTS PROPORCIONEN EL PROGRAMA \"TAL QUAL\" SENSE CAP MENA DE GARANTIA, NI IMPLÍCITA NI EXPLÍCITA, INCLOENT, PERÒ SENSE ESTAR LIMITADES A, LES GARANTIES IMPLÍCITES DE COMERCIALITZACIÓ I ADEQUACIÓ A UN OBJECTIU PARTICULAR. US FEU RESPONSABLES TOTALMENT DELS RISCOS EN QUANT A LA QUALITAT I EL RENDIMENT DEL PROGRAMA. SI EL PROGRAMA FOS DEFECTUÓS, VOSALTRES ASSUMIU EL COST DE TOT SERVEI, REPARACIÓ O CORRECCIÓ. ENTENC I ACCEPTO + Desar Recarregar perfil Comunicador SMS Nrs. de telèfon permesos @@ -314,5 +315,6 @@ + Iniciar sessió diff --git a/app/src/main/res/values-cs-rCZ/exam.xml b/app/src/main/res/values-cs-rCZ/exam.xml index ba1f0cb394..674f46bec9 100644 --- a/app/src/main/res/values-cs-rCZ/exam.xml +++ b/app/src/main/res/values-cs-rCZ/exam.xml @@ -123,6 +123,7 @@ Výměna kanyly nebo změna profilu automaticky nastaví Autosense zpět na 100%. Některé pluginy mají konfigurovatelné časové rozmezí, které může nastavit uživatel. https://androidaps.readthedocs.io/en/latest/CROWDIN/cs/Configuration/Config-Builder.html#detekce-citlivosti + https://androidaps.readthedocs.io/cs/latest/Usage/Open-APS-features.html#autosens Chyby při zadávání sacharidů Co byste měli udělat, pokud jste zadali chybně sacharidy? Odstraňte nesprávný záznam v Ošetření a zadejte správnou novou hodnotu sacharidů. diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 1630a7852a..bf56dddb8f 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -604,9 +604,11 @@ Druhý přídavek sacharidů Třetí přídavek sacharidů CGM - Používat pouze WiFi + Použít mobilní připojení + Použít WiFi připojení WiFi SSID - Pouze při nabíjení + Při nabíjení + Na baterii Nastavení připojení Povolené SSID (oddělené středníkem) Povolit připojení pro roamingu @@ -1037,4 +1039,6 @@ GlucoRx Aidex Aidex Přijímat hodnoty glykémie ze senzoru GlucoRx Aidex. + Zablokováno možností nabíjení + Zablokováno možností připojení diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml index 37a54940e9..c906acf229 100644 --- a/app/src/main/res/values-da-rDK/strings.xml +++ b/app/src/main/res/values-da-rDK/strings.xml @@ -603,9 +603,7 @@ Anden kulhydratstigning Tredje kulhydratstigning CGM - Brug kun WiFi forbindelse WiFi SSID - Kun under opladning Indstillinger for forbindelse Tilladte SSID\'er (semikolon separeret) Tillad forbindelse i roaming diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 0b4aad4f3a..0ccb861169 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -159,6 +159,7 @@ Endbenutzervereinbarung DAS PROGRAMM DARF NICHT FÜR MEDIZINISCHE ENTSCHEIDUNGEN BENUTZT WERDEN. ES GIBT IN DIESEM PROJEKT KEINE GEWÄHRLEISTUNG ODER GARANTIERTE UNTERSTÜTZUNG IN IRGENDEINER ART. WENN DU DICH ENTSCHEIDEST, ES ZU NUTZEN, HÄNGT DIE QUALITÄT UND LEISTUNGSFÄHIGKEIT DIESES PROJEKTES VON DIR SELBST AB. ES WIRD \"WIE BESEHEN\" ZUR VERFÜGUNG GESTELLT. SOLLTE SICH DAS PROGRAMM ALS FEHLERHAFT ERWEISEN, ÜBERNIMMST DU ALLE NOTWENDIGEN KRANKHEITSKOSTEN, SERVICELEISTUNGEN, REPARATUREN ODER KORREKTUREN. Ich verstehe und stimme zu. + Speichern Profil neuladen SMS-Kommunikator Erlaubte Telefonnummern @@ -597,9 +598,7 @@ Zweite KH-Erhöhung Dritte KH-Erhöhung CGM - Benutze nur WLAN Verbindung WLAN SSID - Nur während des Ladens Verbindungs-Einstellungen Erlaubte SSIDs (durch Semikolon getrennt) Erlaube Verbindung bei Roaming @@ -941,5 +940,7 @@ Unerwartetes Verhalten. Kohlenhydrate & Bolus Sind Sie sicher, dass Sie diese(s) %1$d Element(e) löschen möchten? %1$d ausgewählt + Sortieren + Login diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index a1612db037..f7514986ed 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -459,9 +459,7 @@ Δεύτερη αύξηση υδατανθράκων Τρίτη αύξηση υδατανθράκων CGM - Χρησιμοποιήστε μόνο σύνδεση Wi-Fi WiFi SSID - Μόνο κατά τη φόρτιση Ρυθμίσεις σύνδεσης Επιτρέπονται SSID (διαχωρίζονται με ελληνικό ερωτηματικό) Επιτρέψτε τη σύνδεση περιαγωγής diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 3719c72aa2..edbe12fdeb 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -604,9 +604,11 @@ Segundo incremento de carbohidratos Tercer incremento de carbohidratos MCG - Usar sólo con WiFi + Usar conexión móvil + Usar conexión WiFi WiFi SSID - Sólo si está cargando + Durante la carga + Con batería Ajustes de conexión SSID\'s permitidos (separados por punto y coma) Permitir conexión en roaming @@ -1037,4 +1039,6 @@ GlucoRx Aidex Aidex Recibir los valores de glucosa de GlucoRx Aidex CGMS + Bloqueado por opciones de carga + Bloqueado por opciones de conectividad diff --git a/app/src/main/res/values-fr-rFR/exam.xml b/app/src/main/res/values-fr-rFR/exam.xml index 35675bf5b4..bab13d862d 100644 --- a/app/src/main/res/values-fr-rFR/exam.xml +++ b/app/src/main/res/values-fr-rFR/exam.xml @@ -123,6 +123,7 @@ Le changement de canule réinitialisera le ratio Autosens à 100%. Certaines des options du plugin ont des plages de temps configurables qui peuvent être définies par l\'utilisateur. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/fr/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens Entrées de glucides erronées Que devez-vous faire si vous avez renseigné une valeur erronée de glucides ? Supprimez l\'entrée incorrecte dans les Traitements et entrez la nouvelle valeur correcte de glucides. diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 9b5131b9d4..9e0ec5ebc8 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -605,9 +605,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Deuxième incrément de glucides Troisième incrément de glucides MGC - Utilisez uniquement connexion Wi-fi + Utiliser la connexion mobile + Utilisez la connexion Wi-Fi Wi-fi SSID - Uniquement si en charge + Pendant la charge + Sur batterie Paramètres de connexion SSIDs autorisés (séparés par point-virgule) Autoriser connexion données itinérance @@ -682,9 +684,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Le traitement (insuline : %1$.2f, glucides : %2$d, à : %3$s) n\'a pas pu être ajouté aux traitements. Vérifiez et ajoutez SVP manuellement ce traitement. eCarbs : %1$d g (%2$d h), retard : %3$d m Pas de données d\'Autosens disponibles + Fichiers log + Divers Paramètres journal Réinitialiser les valeurs par défaut - Dysfonctionnement NSClient. Faites une réinitialisation de NS et de NSClient. + Dysfonctionnement NSClient. Redémarrez NS et NSClient. Décalage horaire Rappel du bolus plus tard Mode APS préféré @@ -774,6 +778,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S % saisi invalide Moyenne Cible Gly + TIR Jour + TIR Nuit + Détail de 14 jours + SD: %1$s + HbA1c : Moniteur d\'activité Voulez-vous réinitialiser les stats d\'activité ? Statistiques @@ -999,6 +1008,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S %1$d sélectionnée(s) Trier Boîte de dialogue annulée + Très bas + Bas + Haut + Très haut En-dessous Dans la cible Au-dessus @@ -1008,6 +1021,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Configurer l’opacité État de la boucle Échelle du graph. + Profil 1 + Profil2 + Connexion + Supprimer tout + Réinitialiser le démarrage Code QR pour configurer un mot de passe à usage unique ouvrir les paramètres définir l\'alarme du minuteur de glucides @@ -1021,4 +1039,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S GlucoRx Aidex Aidex Recevoir les valeurs de glycémie du MGC GlucoRx Aidex. + Bloqué par les options de recharge + Bloqué par les options de connectivité diff --git a/app/src/main/res/values-ga-rIE/strings.xml b/app/src/main/res/values-ga-rIE/strings.xml index f098100eb4..115e43452f 100644 --- a/app/src/main/res/values-ga-rIE/strings.xml +++ b/app/src/main/res/values-ga-rIE/strings.xml @@ -59,6 +59,7 @@ Socruithe Easpórtáil Socruithe Iompórtáil Iompórtáil + Sábháil Athlódáil próifíl Is lúb díchumasaithe Is lúb cumasaithe @@ -159,7 +160,6 @@ Ar Aghaidh Roimhe seo CGM - Úsáid WiFi nasc amháin WiFi SSID Socruithe Ginearálta Poctech diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 39f0310df2..eb81d05f9f 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -603,9 +603,7 @@ Secondo incremento di CHO Terzo incremento di CHO CGM - Usa solo connessione WiFi WiFi SSID - Solo se in carica Impostazioni connessione SSID ammessi (separati da punto e virgola) Consenti connessione in roaming diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index 3989c6ff09..df974a2eec 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -603,9 +603,7 @@ תוספת פחמימות שניה תוספת פחמימות שלישית סנסור - השתמש בחיבור WiFi בלבד WiFi SSID - במצב טעינה בלבד הגדרות חיבור SSID מורשים (מופרדים בנקודה-פסיק) אפשר חיבור בנדידה @@ -678,6 +676,8 @@ לא ניתן להוסיף טיפול (אינסולין: %1$.2f, פחמ\': %2$d, בשעה: %3$s) לטיפולים. נא לבדוק ולהוסיף רשומה באופן ידני כנדרש. פחמימות ממושכות: %1$d גר\' (%2$d ש\'), עיכוב %3$d דק\' אין נתוני Autosens זמינים + קבצי יומן + שונות הגדרות יומן רישום אפס לברירת המחדל תקלה ב-NSClient. שקלו להפעיל את Nightscout ו-NSClient מחדש. diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 7d639884aa..90652a8a7a 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -155,6 +155,7 @@ 최종 사용자 라이선스 동의서 이 프로그램을 의학적 결정을 내리는 데 사용해서는 안되며, 여기에 대한 어떠한 보증도 없습니다. 이 프로그램의 품질과 성능에 관한 모든 위험은 사용자에게 있습니다.\nMUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 모두 이해하였고 동의합니다. + 저장 프로파일 새로고침 SMS 통신기 허가된 전화번호 @@ -586,9 +587,7 @@ 2차 탄수화물 증분 3차 탄수화물 증분 CGM - 와이파이 연결만 사용하기 와이파이 SSID - 충전중일때만 연결 설정 허가된 SSIDs(세미콜론으로 구분) 로밍에서 연결 허용 @@ -851,5 +850,6 @@ 계산 진행 중 + 로그인 diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index cc5cd5d678..211286d69f 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -159,6 +159,7 @@ Licencinė sutartis su vartotoju PROGRAMA NEGALI BŪTI NAUDOJAMA GYDYMO SPRENDIMAMS PRIIMTI. PAGAL GALIOJANČIUS ĮSTATYMUS PROGRAMA NESUTEIKIA JOKIŲ GARANTIJŲ VARTOTOJUI. JEI RAŠTU NENURODYTA KITAIP, PROGRAMOS AUTORINIŲ TEISIŲ TURĖTOJAS IR/AR KITOS ŠALYS PATEIKIA PROGRAMĄ \"KAIP YRA\" BE JOKIŲ GARANTIJŲ, TIEK AKIVAIZDŽIŲ, TIEK NUMANOMŲ, ĮSKAITANT, BET NEAPSIRIBOJANT GALIMYBĘ NAUDOTI PROGRAMĄ KOMERCINIAMS AR KITOKIEMS DALINIAMS TIKSLAMS. RIZIKĄ, KYLANČIĄ NAUDOJANT PROGRAMĄ PRISIIMA PATS VARTOTOJAS. JEI PROGRAMA VEIKIA NETINKAMAI, IŠLAIDOS, SUSIJUSIOS SU PROGRAMOS SERVISU, TAISYMU AR KOREGAVIMU, TENKA VARTOTOJUI. SUPRATAU IR SUTINKU + Išsaugoti Atnaujinti profilį SMS komunikatorius Leidžiami telefono numeriai @@ -595,9 +596,7 @@ Antras angliavandenių kiekio žingsnis Trečias angliavandenių kiekio žingsnis NGJ - Naudoti tik WiFi WiFi pavadinimas - Tik įkraunant Ryšio nustatymai Leidžiami tinklai (atskirti kabliataškiais) Leisti sujungimą tarptinkliniu ryšiu @@ -895,5 +894,6 @@ Negalimas + Prisijungti diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index 5f07504605..dc28fa97db 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -604,9 +604,7 @@ Tweede koolhydraten increment Derde koolhydraten increment CGM - Gebuik enkel de WiFi verbinding WiFi SSID - Enkel tijdens opladen Verbindings instellingen Toegelaten SSIDs (gescheiden door puntkomma) Sta verbinding tijdens roaming toe diff --git a/app/src/main/res/values-no-rNO/exam.xml b/app/src/main/res/values-no-rNO/exam.xml index e65ff09029..087dc7d9be 100644 --- a/app/src/main/res/values-no-rNO/exam.xml +++ b/app/src/main/res/values-no-rNO/exam.xml @@ -123,6 +123,7 @@ Hvis du logger bytte av kanyle vil Autosens verdien tilbakestilles til 100%. Noen plugins har konfigurerbare tidsintervall som kan settes av brukeren. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/en/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens Feil i KH angivelse Hva skal du gjøre hvis du har gjort en feilaktig registrering av karbohydrater? Fjern den feilaktige registreringen i Behandlinger og legg inn riktig verdi for karbohydrater. diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index 1e1059afc8..7e12b4f62e 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -604,9 +604,11 @@ Andre økning hurtigknapp for karbohydrater Tredje økning hurtigknapp for karbohydrater CGM - Bare kun WiFi tilkoblinger + Bruk mobildata + Bruk Wi-Fi-tilkobling WiFi nettverksnavn - Bare under lading + Under lading + På batteri Tilkoblingsinnstillinger Tillatte nettverksnavn SSID (separert med semikolon) Tillat tilkobling i roaming @@ -681,6 +683,8 @@ En behandling (insulin: %1$.2f, karbohydrater: %2$d, tid: %3$s) kunne ikke legges til Behandlinger. Vennligst kontroller og manuelt legg til en registrering der det er aktuelt. eKarbo: %1$d g (%2$d t), forsinkelse: %3$d m Ingen data tilgjengelig for autosens + Loggfiler + Annet Logginnstillinger Gjenopprett standardinnstillinger NSClient feil. Vurder omstart av NS og NSClient. @@ -773,6 +777,11 @@ Ugyldig % oppføring Gjennomsnitt TIR + Dag TIR + Natt TIR + Detaljert 14 dager + SD: %1$s + HbA1c: Overvåking av aktivitet Vil du tilbakestille aktivitets statistikk? Statistikk @@ -999,6 +1008,10 @@ %1$d valgt Sorter Dialog avbrutt + Veldig lavt + Lavt + Høyt + Veldig høyt Under I målområdet Over @@ -1026,4 +1039,6 @@ GlucoRx Aidex Aidex Motta BS verdier fra GlucoRx Aidex CGM. + Blokkert på grunn av ladealternativer + Blokkert på grunn av tilkoblingsalternativer diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 504d21df25..716f005083 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -159,6 +159,7 @@ Umowa licencyjna użytkownika końcowego NIE MOŻE BY WYKORZYSTYWANY DO PODEJMOWANIA DECYZJI MEDYCZNYCH. NIE MA ŻADNEJ GWARANCJI NA PROGRAM, W ZAKRESIE DOZWOLONYM PRZEZ OBOWIĄZUJĄCE PRAWO. Z WYJĄTKIEM PRZYPADKÓW, GDY W INNY SPOSÓB PISMO OŚWIADCZENIA PRAW AUTORSKICH I / LUB INNYCH STRON, PRZEDSTAWIAĆ PROGRAM \"W STANIE TAKIM, W JAKIM SIĘ ZNAJDUJE\" BEZ JAKIEJKOLWIEK GWARANCJI, WYRAŹNEJ LUB DOMNIEMANEJ, W TYM MIĘDZY INNYMI DOMNIEMANYCH GWARANCJI PRZYDATNOŚCI HANDLOWEJ I PRZYDATNOŚCI DO OKREŚLONEGO CELU. CAŁKOWITE RYZYKO ZWIĄZANE Z JAKOŚCIĄ I WYNIKIEM PROGRAMU JEST PO PAŃSTWA STRONIE. W PRZYPADKU USZKODZENIA PROGRAMU UŻYTKOWNIK PONOSI KOSZT CAŁEGO NIEZBĘDNEGO SERWISU, NAPRAWY LUB POPRAWEK. W PRZYPADKU NIEPOROZUMIEŃ ZASTOSOWANIE PRAWNE MA UMOWA W ANGIELSKIEJ WERSJI JĘZYKOWEJ!!! ROZUMIEM I WYRAŻAM ZGODĘ + ZACHOWAJ Załaduj profil ponownie Komunikator SMS Dozwolone numery telefonów @@ -595,9 +596,7 @@ Drugi stopień przyrostu węglow. Trzeci stopień przyrostu węglow. CGM - Używaj tylko połączenia WiFi WiFi SSID - Tylko gdy się ładuje Ustawienia połączenia Dozwolone SSID (rozdzielone średnikiem) Zezwalaj na połączenia w roamingu @@ -895,5 +894,10 @@ Niedostępne + Usuń wybrane pozycje + Czy na pewno chcesz usunąć %1$d pozycji + Wybrany %1$d + Sortuj + Zaloguj się diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index ad3cd4ce00..cc897fcb4c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -570,9 +570,7 @@ Segundo incremento hidratos Terceiro incremento hidratos CGM - Utilize apenas uma conexão WiFi WiFi SSID - Apenas quando estiver a carregar Definições de ligação SSIDs permitidos (separada por ponto e vírgula) Permitir ligação em roaming diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 2c6f3d9c56..1049c0380e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -159,6 +159,7 @@ Condições de Utilização NÃO DEVE SER USADO PARA FAZER DECISÕES MÉDICAS. NÃO HÁ NENHUMA GARANTIA PARA O PROGRAMA, NA EXTENSÃO PERMITIDA PELA LEGISLAÇÃO APLICÁVEL. EXCEPTO QUANDO DE OUTRA FORMA, POR ESCRITO, OS TITULARES DOS DIREITOS DE AUTOR E / OU OUTRAS PARTES FORNECEM O PROGRAMA “TAL COMO ESTÁ”, SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO, ÀS GARANTIAS IMPLÍCITAS DE COMERCIALIZAÇÃO E ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. TODO O RISCO QUANTO À QUALIDADE E DESEMPENHO DO PROGRAMA É CONSIGO. CASO O PROGRAMA SEJA DEFEITUOSO, ASSUME O CUSTO DE TODOS OS SERVIÇOS, REPAROS OU CORREÇÕES NECESSÁRIOS. EU ENTENDO E CONCORDO + Guardar Recarregar perfil Comunicador SMS Número de telefones permitidos @@ -595,9 +596,7 @@ Segundo incremento hidratos Terceiro incremento hidratos CGM - Utilize apenas uma conexão WiFi WiFi SSID - Apenas quando estiver a carregar Definições de ligação SSIDs permitidos (separada por ponto e vírgula) Permitir ligação em roaming @@ -896,5 +895,6 @@ Indisponível + Login diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index e4878a539e..2d55df640a 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -159,6 +159,7 @@ Licență utilizator final NU FOLOSIȚI PENTRU LUAREA DE DECIZII MEDICALE. NU EXISTĂ RĂSPUNDERE LEGALĂ SAU GARANȚIE PENTRU ACEST PROGRAM, ÎN LIMITA APLICABILĂ A LEGII. CU EXCEPTIA CAZURILOR SPECIAL MENȚIONATE, AUTORUL ȘI/SAU ALTE PERSOANE IMPLICATE PUN LA DISPOZIȚIE ACEST PROGRAM FĂRĂ NICIO GARANȚIE, IMPLICITĂ SAU EXPLICITĂ, INCLUZÂND, DAR FĂRĂ A SE LIMITA LA, GARANȚIILE LEGATE DE VĂNZAREA SAU POTRIVIREA PENTRU UN ANUME SCOP. ÎNTREGUL RISC LEGAT DE CALITATEA ȘI PERFORMANȚA ACESTUI PROGRAM CAD ÎN RESPONSABILITATEA DUMNEAVOASTRĂ. DACĂ PROGRAMUL SE DOVEDEȘTE A FI DEFECT, DUMNEAVOASTRĂ VĂ ASUMAȚI ÎNTREAGA RĂSPUNDERE, PRECUM ȘI TOATE COSTURILE LEGATE DE SERVICE, REPARAȚII SAU CORECȚII. ÎNȚELEG ȘI SUNT DE ACORD + Salvează Reîncarcă profilul Comunicator SMS Numere de telefon permise @@ -595,9 +596,7 @@ Al doilea increment de carbohidrați Al treilea increment de carbohidrați CGM - Folosește doar conexiune WiFi SSID WiFi - Doar când se încarcă Setări conexiune SSIDuri permise (separare prin punct și virgulă) Permite conexiuni în roaming @@ -896,5 +895,8 @@ Nu este disponibil + Sigur vrei să elimini %1$d element(e) + Sortează + Autentificare diff --git a/app/src/main/res/values-ru-rRU/exam.xml b/app/src/main/res/values-ru-rRU/exam.xml index 0c8efbd035..d5edb09ce2 100644 --- a/app/src/main/res/values-ru-rRU/exam.xml +++ b/app/src/main/res/values-ru-rRU/exam.xml @@ -123,6 +123,7 @@ Внесение записи о замене катетера вернет коэффициент Autosens к 100%. У некоторых опций модуля есть настраиваемые диапазоны времени, которые может задать пользователь. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/en/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens Ошибки записи углеводов Что нужно делать, если сделан неправильный ввод углеводов? Удалить неверную запись в Журнале терапии и заново ввести правильное значение углеводов. diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 1e77d5b1f8..d41d36c2e4 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -440,6 +440,7 @@ Поиск незапланированного приема пищи Время пика действующего инс IOB время пика (в мин.) + Пик Свободный от пиков Oref Быстро действующий Oref Сверхбыстрый Oref @@ -603,9 +604,11 @@ Второй шаг увеличения углеводов Третий шаг увеличения углеводов Мониторинг ГК - Использовать только WiFi соединение + Использовать мобильное подключение + Использовать WiFi соединение WiFi SSID - Только при зарядке + Во время зарядки + От батареи Параметры подключения Разрешенные SSID (разделенные точкой с запятой) Разрешить подключение в роуминге @@ -680,6 +683,8 @@ Назначение (инсулин: %1$.2f, углеводы: %2$d, в: %3$s) не было добавлено. Пожалуйста, проверьте и при необходимости добавьте запись вручную. eCarbs: %1$d г. (%2$d h), задержка: %3$d m Данные autosens недоступны + Файлы журналов + Разное Настройки журнала Восстановить значения по умолчанию Некорректная работа NSClient. Возможно следует перезапустить NS и NSClient. @@ -772,6 +777,11 @@ Некорректный ввод % Средний Время в целевом диапазоне TIR + Время в целевом диапазоне днем + Время в целевом диапазоне ночью + Подробно 14 дней + СтандОткл: %1$s + HbA1c: Монитор активности Хотите сбросить статистику активности? Статистика @@ -966,9 +976,11 @@ Активный профиль не установлен! Неизвестный COB! Отсутствуют данные ГК или приложения недавно перезапущено? Нарушено ограничение по углеводам! + Кальк (IC:%1$.1f ISF: %2$.1f) Углеводов: %1$.2fгУ Акт Инс COB: %1$.0fг %2$.2fед ГК: %1$.2f + IOB: %1$.2fед Суперболюсный: %1$.2fед тренд 15\': %1$.2f Процент: %1$.2fU x %2$d%% = %3$.2f @@ -995,6 +1007,10 @@ %1$d выбрано Сортировать Диалог отменен + Очень низкий + Низкий + Высокий + Очень высокий Ниже целевых В целевом диапазоне Выше целевых @@ -1002,5 +1018,26 @@ Скрыть записи цикла Виджет androidAPS Настроить прозрачность + Статус цикла + Масштаб графика + Профиль 1 + Профиль 2 + Логин + Удалить всё + Перезапустить старт + QR код для введения временного пароля + открыть настройки + задать оповещение таймера углеводов + Все + Телефон + Часы + только на часах + только на телефоне + якорь перетягивания + Aidex GlucoRx + Aidex + Получить значения ГК от GlucoRx Aidex + Заблокировано опциями зарядки + Заблокировано настройками подключения diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index d9fea3abd0..b0e22b54b4 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -604,9 +604,11 @@ Druhý prídavok sacharidov Tretí prídavok sacharidov CGM - Používať iba WiFi + Použiť mobilné pripojenie + Použiť WiFi pripojenie WiFi SSID - Len pri nabíjaní + Počas nabíjania + Na batérii Nastavenie pripojenia Povolené SSID (oddelené bodkočiarkou) Povoliť pripojenie pri roamingu @@ -681,6 +683,8 @@ Ošetrenie (inzulín: %1$.2f, sacharidy: %2$d, čas: %3$s) nie je možné pridať. Skontrolujte a podľa potreby manuálne pridajte záznam. eCarbs: %1$d g (%2$d h), Oneskorenie: %3$d m Nedostupné dáta o glykémiách + Log súbory + Rôzne Nastavenie logovania Obnoviť predvolené Chyba NSClienta. Zvážte reštart NS a NSClienta. @@ -1035,4 +1039,6 @@ GlucoRx Aidex Aidex Prijímať hodnoty glykémie zo senzora GlucoRx Aidex. + Zablokované možnosti nabíjania + Zablokované možnosti pripojenia diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index f59d25c23d..ee5c7d8905 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -161,6 +161,7 @@ Eversense-appen. Licensavtal för slutanvändare FÅR INTE ANVÄNDAS FÖR ATT FATTA MEDICINSKA BESLUT. DET FINNS INGEN GARANTI FÖR PROGRAMMET I DEN UTSTRÄCKNING SOM TILLÅTS AV GÄLLANDE LAG. FÖRUTOM NÄR ANNAT ANGES SKRIFTLIGEN LEVERERAS APPLIKATIONEN SOM DEN ÄR HELT UTAN GARANTIER I NÅGON SOM HELST FORM, VARKEN UTTRYCKTA ELLER UNDERFÖRSTÅDDA, INKLUSIVE MEN INTE BEGRÄNSAT TILL SÄLJBARHET OCH LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL. HELA RISKEN VAD GÄLLER KVALITET OCH PRESTANDA AV PROGRAMMET ÅLIGGER ANVÄNDAREN. OM PROGRAMMET VISAR SIG VARA DEFEKT ANTAR ANVÄNDAREN DEN FULLA FÖR KOSTNADEN FÖR ALL NÖDVÄNDIG SERVICE, REPARATION ELLER KORRIGERING. JAG FÖRSTÅR OCH GODKÄNNER + Spara Ladda om profil SMS-tjänst Godkända telefonnummer @@ -600,9 +601,7 @@ Eversense-appen. Andra snabbknabben för kolhydrater Tredje snabbknabben för kolhydrater CGM - Använd endast WiFi WiFi nätverksnamn - Endast vid laddning Anslutningsinställningar Tillåtna nätverksnamn (separerade med semikolon) Tillåt NS-data vid roaming @@ -964,5 +963,6 @@ Eversense-appen. Okänt kommando: Procent Appens standardinställning + Logga in diff --git a/app/src/main/res/values-tr-rTR/exam.xml b/app/src/main/res/values-tr-rTR/exam.xml index 209deea3b6..979bfb5b2e 100644 --- a/app/src/main/res/values-tr-rTR/exam.xml +++ b/app/src/main/res/values-tr-rTR/exam.xml @@ -123,6 +123,7 @@ Bir kanül değişikliğinin kaydedilmesi, Otoduyarlılık oranını %100\'e sıfırlayacaktır. Eklenti seçeneklerinden bazıları, kullanıcı tarafından ayarlanabilen yapılandırılabilir zaman aralıklarına sahiptir. https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/tr/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens Karbonhidrat Giriş Hataları Yanlış bir karbonhidrat girişi yaptıysanız ne yapmalısınız? Tedavilerdeki yanlış girişi siler ve doğru karbonhidrat değerini girerim. diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index fd78a4f34a..fcf6eccb0b 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -475,7 +475,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Yerel uyarılar KŞ bilgisi alınmadığında uyar Pompa ulaşılamıyorsa uyar - Pompa ulaşılamaz eşiği [min] + Pompa ulaşılamaz eşiği [dk] Karbonhidrat gerekliyse uyar Acil önemli Alarm BİLGİ @@ -605,9 +605,11 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d İkinci karbonhidrat artışı Üçüncü karbonhidrat artışı CGM - Sadece WiFi bağlantı kullanın + Mobil veri kullan + Wi-Fi bağlantısı kullan WiFi SSID - Sadece şarj olurken + Şarj olurken + Pilde Bağlantı Ayarları İzin verilen SSID (noktalı virgülle ayrılmış) Roaming bağlantıya izin ver @@ -682,6 +684,8 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Tedavilere (insülin: %1$.2f, karbonhidrat: %2$d, %3$s) şeklinde bir tedavi eklenemedi. Lütfen kontrol edin ve uygun şekilde elle bir kayıt ekleyin. yKarb: %1$d g (%2$d sa), gecikme: %3$d dk Otoduyarlılık verileri mevcut değil + Günlük dosyaları + Diğer Ayarlar Günlük ayarları Varsayılanlara sıfırla NSClient arızası. NS ve NSClient yeniden başlatmayı düşünün. @@ -774,6 +778,11 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Geçersiz % giriş Ortalama TIR + Gündüz TIR + Gece TIR + Ayrıntılı 14 gün + SD: %1$s + HbA1c: Aktivite monitörü Etkinlik istatistiklerini sıfırlamak istiyor musunuz? İstatistikler @@ -1000,6 +1009,10 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d %1$d seçildi Sırala İletişim kutusu iptal edildi + Çok düşük + Düşük + Yüksek + Çok yüksek Altında Aralık içinde Üstünde @@ -1027,4 +1040,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d GlucoRx Aidex Aidex GlucoRx Aidex CGMS\'den KŞ değerleri alır. + Şarj seçenekleri tarafından engellendi + Bağlantı seçenekleri tarafından engellendi diff --git a/app/src/main/res/values-zh-rCN/exam.xml b/app/src/main/res/values-zh-rCN/exam.xml index addb42c8b4..ae7b8c0ad4 100644 --- a/app/src/main/res/values-zh-rCN/exam.xml +++ b/app/src/main/res/values-zh-rCN/exam.xml @@ -123,6 +123,7 @@ 记录输注导管更换会将Autosens比率重置回100%。 一些插件选项具有可配置的时间范围,可由用户设置。 https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html + https://androidaps.readthedocs.io/en/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens 碳水化合物输入错误 如果您输入了不正确的碳水化合物,该怎么办? 删除治疗数据中的错误条目,并重新输入正确的碳水值。 diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 192f069438..0258e545fb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -603,9 +603,7 @@ 第二碳水化合物增量 第三碳水化合物增量 CGM - 仅使用 WiFi 连接 WiFi SSID - 仅在充电时 连接设置 允许的 SSIDs (分号分隔) 允许在漫游中连接 @@ -772,6 +770,7 @@ 输入的百分比无效 平均 TIR + 糖化血红蛋白: 活动监视器 您想要重置所有的统计信息吗? 统计 @@ -967,9 +966,11 @@ 没有激活的个人配置文件! 未知的活性碳水!血糖读取缺失或最近重新启动了应用程序? 碳水违反约束条件! + 计算 (IC: %1$.1f, ISF: %2$.1f) 碳水: %1$.2fU 活性碳水: %1$.0f克 %2$.2fU 血糖: %1$.2fU + 活性胰岛素: %1$.2fU 超级大剂量:%1$.2fU 15分钟趋势:%1$.2fU 百分比:%1$.2fU x %2$d%% ≈ %3$.2fU @@ -996,6 +997,10 @@ 已选中 %1$d 排序 对话框已取消 + 非常低 + + + 非常高 底部 在范围内 上方 @@ -1003,6 +1008,12 @@ 隐藏闭环记录 AndroidAPS小部件 配置透明度 + 闭环状态 + 图形缩放 + 配置文件 1 + 配置文件 2 + 登录 + 删除全部 用于安装一次性随机验证码的二维码 打开设置 设置碳水计时器提醒 @@ -1016,4 +1027,6 @@ GlucoRx Aidex动泰 Aidex动泰 从GlucoRx Aidex动泰持续葡萄糖监测系统接收血糖值。 + 被充电选项阻止 + 被连接选项阻止 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ec5c8d5676..f60b454a22 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -733,13 +733,17 @@ Second carbs increment Third carbs increment CGM - ns_wifionly + ns_cellular + ns_wifi ns_wifi_ssids - ns_allowroaming - ns_chargingonly - Use WiFi connection only + ns_allowroaming + ns_battery + ns_charging + Use Cellular connection + Use WiFi connection WiFi SSID - Only if charging + During charging + On battery Connection settings Allowed SSIDs (semicolon separated) Allow connection in roaming @@ -1240,6 +1244,8 @@ GlucoRx Aidex Aidex Receive BG values from GlucoRx Aidex CGMS. + Blocked by charging options + Blocked by connectivity options diff --git a/app/src/main/res/xml/pref_autotune.xml b/app/src/main/res/xml/pref_autotune.xml index 35abef7d12..fc5f6dbc72 100644 --- a/app/src/main/res/xml/pref_autotune.xml +++ b/app/src/main/res/xml/pref_autotune.xml @@ -36,11 +36,12 @@ android:key="@string/key_autotune_circadian_ic_isf" android:summary="@string/autotune_circadian_ic_isf_summary" android:title="@string/autotune_circadian_ic_isf_title" /> - + \ No newline at end of file diff --git a/app/src/main/res/xml/pref_nsclientinternal.xml b/app/src/main/res/xml/pref_nsclientinternal.xml index 9d9aca0133..bc0a0b3143 100644 --- a/app/src/main/res/xml/pref_nsclientinternal.xml +++ b/app/src/main/res/xml/pref_nsclientinternal.xml @@ -138,26 +138,36 @@ + android:key="@string/key_ns_cellular" + android:title="@string/ns_cellular" /> + + + + + android:key="@string/key_ns_battery" + android:title="@string/ns_battery" /> + android:defaultValue="true" + android:key="@string/key_ns_charging" + android:title="@string/ns_charging" /> diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt index cd46c1048d..ee67c07b13 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt @@ -31,7 +31,6 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Profiler -import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt index 5575c973f7..da0e9b7187 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPluginTest.kt @@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.utils.HardLimits -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt index 1b14ba64d0..37fe08b20a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersionsTest.kt @@ -1,16 +1,52 @@ package info.nightscout.androidaps.plugins.constraints.versionChecker -import org.joda.time.DateTime import org.joda.time.LocalDate -import org.junit.Assert -import org.junit.Assert.* +import org.json.JSONArray +import org.json.JSONObject +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Test class AllowedVersionsTest { + fun generateSupportedVersions(): String = + JSONArray() + // Android API versions + .put(JSONObject().apply { + put("minAndroid", 1) // 1.0 + put("maxAndroid", 23) // 6.0.1 + }) + .put(JSONObject().apply { + put("minAndroid", 24) // 7.0 + put("maxAndroid", 25) // 7.1.2 + put("supported", "2.6.2") + }) + .put(JSONObject().apply { + put("minAndroid", 26) // 8.0 + put("maxAndroid", 27) // 8.1 + put("supported", "2.8.2") + }) + .put(JSONObject().apply { + put("minAndroid", 28) // 9.0 + put("maxAndroid", 99) + put("supported", "2.8.2") + }) + // Version time limitation + .put(JSONObject().apply { + put("endDate", "2021-11-07") + put("version", "2.9.0-beta1") + }) + .put(JSONObject().apply { + put("endDate", "2021-11-07") + put("version", "3.0-beta1") + }) + .toString() + @Test fun generateSupportedVersionsTest() { - val definition = AllowedVersions().generateSupportedVersions() + val definition = generateSupportedVersions() assertNull(AllowedVersions().findByApi(definition, 0)) assertFalse(AllowedVersions().findByApi(definition, 1)?.has("supported") ?: true) assertFalse(AllowedVersions().findByApi(definition, 23)?.has("supported") ?: true) @@ -24,9 +60,10 @@ class AllowedVersionsTest { @Test fun findByVersionTest() { //val definition = AllowedVersions().generateSupportedVersions() - val definition = "[{\"minAndroid\":1,\"maxAndroid\":23},{\"minAndroid\":24,\"maxAndroid\":25,\"supported\":\"2.6.2\"},{\"minAndroid\":26,\"maxAndroid\":27,\"supported\":\"2.8.2\"},{\"minAndroid\":28,\"maxAndroid\":99,\"supported\":\"2.8.2\"},{\"endDate\":\"2021-11-07\",\"version\":\"2.9.0-beta1\"},{\"endDate\":\"2021-11-02\",\"version\":\"3.0-beta1\"},{\"endDate\":\"2021-11-04\",\"version\":\"3.0-beta2\"},{\"endDate\":\"2021-11-10\",\"version\":\"3.0-beta3\"},{\"endDate\":\"2021-11-14\",\"version\":\"3.0-beta4\"}\n" + - " ,{\"endDate\":\"2021-11-16\",\"version\":\"3.0-beta5\"}\n" + - "]" + val definition = + "[{\"minAndroid\":1,\"maxAndroid\":23},{\"minAndroid\":24,\"maxAndroid\":25,\"supported\":\"2.6.2\"},{\"minAndroid\":26,\"maxAndroid\":27,\"supported\":\"2.8.2\"},{\"minAndroid\":28,\"maxAndroid\":99,\"supported\":\"2.8.2\"},{\"endDate\":\"2021-11-07\",\"version\":\"2.9.0-beta1\"},{\"endDate\":\"2021-11-02\",\"version\":\"3.0-beta1\"},{\"endDate\":\"2021-11-04\",\"version\":\"3.0-beta2\"},{\"endDate\":\"2021-11-10\",\"version\":\"3.0-beta3\"},{\"endDate\":\"2021-11-14\",\"version\":\"3.0-beta4\"}\n" + + " ,{\"endDate\":\"2021-11-16\",\"version\":\"3.0-beta5\"}\n" + + "]" assertNull(AllowedVersions().findByVersion(definition, "2.6.0")) assertTrue(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.has("endDate") ?: false) assertEquals("2021-11-07", AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate")) @@ -34,7 +71,7 @@ class AllowedVersionsTest { @Test fun endDateToMilliseconds() { - val definition = AllowedVersions().generateSupportedVersions() + val definition = generateSupportedVersions() val endDate = AllowedVersions().endDateToMilliseconds(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate") ?: "1000/01/01") val dateTime = LocalDate(endDate) assertEquals(2021, dateTime.year) 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 02ae75b90c..a055f7c519 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 @@ -5,7 +5,7 @@ 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.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt index aac7fc9774..e98190d4fd 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt @@ -5,17 +5,13 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.events.EventChargingState import info.nightscout.androidaps.events.EventNetworkChange +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.receivers.ReceiverStatusStore -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before import org.junit.Test -import org.mockito.ArgumentMatchers.anyBoolean -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.anyLong -import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock import org.mockito.Mockito.`when` @@ -24,98 +20,71 @@ class NsClientReceiverDelegateTest : TestBase() { @Mock lateinit var context: Context @Mock lateinit var sp: SP @Mock lateinit var rh: ResourceHelper - - lateinit var receiverStatusStore: ReceiverStatusStore val rxBus = RxBus(aapsSchedulers, aapsLogger) - private var sut: NsClientReceiverDelegate? = null + private lateinit var receiverStatusStore: ReceiverStatusStore + private lateinit var sut: NsClientReceiverDelegate - @Before fun prepare() { + + @Before + fun prepare() { receiverStatusStore = ReceiverStatusStore(context, rxBus) - `when`(sp.getLong(anyInt(), anyLong())).thenReturn(0L) - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(false) - `when`(sp.getInt(anyInt(), anyInt())).thenReturn(0) - `when`(sp.getString(anyInt(), anyString())).thenReturn("") - sut = NsClientReceiverDelegate(rxBus, rh, sp, receiverStatusStore) } - @Test fun testCalculateStatusChargingState() { - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(false) - var ev = EventChargingState(true, 0) - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev = EventChargingState(false, 0) - Assert.assertTrue(sut!!.calculateStatus(ev)) - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(true) - ev = EventChargingState(true, 0) - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev = EventChargingState(false, 0) - Assert.assertTrue(!sut!!.calculateStatus(ev)) + @Test + fun testCalculateStatusChargingState() { + `when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(false) + Assert.assertTrue(sut.calculateStatus(EventChargingState(false, 0))) + Assert.assertFalse(sut.calculateStatus(EventChargingState(true, 0))) + `when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(false) + `when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(true) + Assert.assertTrue(sut.calculateStatus(EventChargingState(true, 0))) + Assert.assertFalse(sut.calculateStatus(EventChargingState(false, 0))) } - @Test fun testCalculateStatusNetworkState() { - // wifiOnly = false - // allowRoaming = false as well - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(false) - `when`(sp.getString(anyInt(), anyString())).thenReturn("") - val ev = EventNetworkChange() - ev.ssid = "" - ev.mobileConnected = true - ev.wifiConnected = true - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev.ssid = "test" - `when`(sp.getString(anyInt(), anyString())).thenReturn("test") - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev.ssid = "test" - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev.wifiConnected = false - Assert.assertTrue(sut!!.calculateStatus(ev)) + @Test + fun testCalculateStatusNetworkState() { + `when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true) + `when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("") + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "", mobileConnected = true, wifiConnected = true))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "", mobileConnected = false, wifiConnected = true))) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange())) - // wifiOnly = true - // allowRoaming = true as well - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(true) - ev.wifiConnected = true - Assert.assertTrue(sut!!.calculateStatus(ev)) - ev.wifiConnected = false - Assert.assertTrue(!sut!!.calculateStatus(ev)) + `when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("test") + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "", mobileConnected = true, wifiConnected = true))) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange(ssid = "", mobileConnected = false, wifiConnected = true))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = true, wifiConnected = true))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = false, wifiConnected = true))) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange())) - // wifiOnly = false - // allowRoaming = false as well - `when`(sp.getBoolean(anyInt(), anyBoolean())).thenReturn(false) - ev.wifiConnected = false - ev.roaming = true - Assert.assertTrue(!sut!!.calculateStatus(ev)) + `when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(false) + `when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true) + `when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("") + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(wifiConnected = true))) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange())) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true))) - // wifiOnly = false - // allowRoaming = true - `when`(sp.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(false) - `when`(sp.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true) - ev.wifiConnected = false - ev.roaming = true - Assert.assertTrue(sut!!.calculateStatus(ev)) + `when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(false) + `when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("") + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false))) + Assert.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true))) - // wifiOnly = true - // allowRoaming = true - `when`(sp.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(true) - `when`(sp.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true) - ev.wifiConnected = false - ev.roaming = true - Assert.assertTrue(!sut!!.calculateStatus(ev)) - - // wifiOnly = true - // allowRoaming = true - `when`(sp.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(true) - `when`(sp.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true) - ev.wifiConnected = true - ev.roaming = true - Assert.assertTrue(sut!!.calculateStatus(ev)) - - // wifiOnly = false - // allowRoaming = false - `when`(sp.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(false) - `when`(sp.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(false) - ev.wifiConnected = true - ev.roaming = true - Assert.assertTrue(sut!!.calculateStatus(ev)) + `when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true) + `when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true) + `when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("") + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false))) + Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true))) } } \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt b/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt index be0eb00790..907f739127 100644 --- a/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/queue/CommandQueueImplementationTest.kt @@ -25,7 +25,7 @@ import info.nightscout.androidaps.queue.commands.* import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers diff --git a/automation/build.gradle b/automation/build.gradle index 79564845d5..e1107c676f 100644 --- a/automation/build.gradle +++ b/automation/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.automation' +} dependencies { diff --git a/automation/src/main/AndroidManifest.xml b/automation/src/main/AndroidManifest.xml index 3396187ca4..94da5bcfde 100644 --- a/automation/src/main/AndroidManifest.xml +++ b/automation/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index 22abb1b54e..aaa0bf3363 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -261,6 +261,7 @@ class AutomationPlugin @Inject constructor( @Synchronized fun add(event: AutomationEvent) { automationEvents.add(event) + event.position = automationEvents.size - 1 rxBus.send(EventAutomationDataChanged()) } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt index 1918291268..4767d287a9 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt @@ -13,7 +13,6 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuil import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper -import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.TimerUtil import org.json.JSONObject import javax.inject.Inject @@ -40,7 +39,7 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) { override fun doAction(callback: Callback) { timerUtil.scheduleReminder(10, text.value.takeIf { it.isNotBlank() } ?: rh.gs(R.string.app_name)) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } override fun toJSON(): String { diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopEnable.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopEnable.kt index fef97824bd..e1ce21ccee 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopEnable.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopEnable.kt @@ -33,9 +33,9 @@ class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) { configBuilder.storeSettings("ActionLoopEnable") rxBus.send(EventRefreshOverview("ActionLoopEnable")) uel.log(UserEntry.Action.LOOP_ENABLED, Sources.Automation, title) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } else { - callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadyenabled))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadyenabled)).run() } } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.kt index 131e4fd707..c60c861d06 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopResume.kt @@ -45,9 +45,9 @@ class ActionLoopResume(injector: HasAndroidInjector) : Action(injector) { }) rxBus.send(EventRefreshOverview("ActionLoopResume")) uel.log(UserEntry.Action.RESUME, Sources.Automation, title) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } else { - callback.result(PumpEnactResult(injector).success(true).comment(R.string.notsuspended))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.notsuspended)).run() } } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt index ea3f2aa978..1c490b4bde 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt @@ -40,9 +40,9 @@ class ActionLoopSuspend(injector: HasAndroidInjector) : Action(injector) { UserEntry.Action.SUSPEND, Sources.Automation, title + ": " + rh.gs(R.string.suspendloopforXmin, minutes.getMinutes()), ValueWithUnit.Minute(minutes.getMinutes()) ) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } else { - callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadysuspended))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadysuspended)).run() } } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt index aaa7ef263d..63622eca2c 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt @@ -39,7 +39,7 @@ class ActionNotification(injector: HasAndroidInjector) : Action(injector) { rxBus.send(EventNewNotification(notification)) disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(text.value)).subscribe() rxBus.send(EventRefreshOverview("ActionNotification")) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } override fun toJSON(): String { diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt index fcb11a0814..52e1048b42 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt @@ -10,7 +10,6 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.general.automation.elements.InputProfileName import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement @@ -18,6 +17,7 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuil import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper +import info.nightscout.shared.logging.LTag import org.json.JSONObject import javax.inject.Inject @@ -39,23 +39,23 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) { //Check for uninitialized profileName if (inputProfileName.value == "") { aapsLogger.error(LTag.AUTOMATION, "Selected profile not initialized") - callback.result(PumpEnactResult(injector).success(false).comment(R.string.error_field_must_not_be_empty))?.run() + callback.result(PumpEnactResult(injector).success(false).comment(R.string.error_field_must_not_be_empty)).run() return } if (profileFunction.getProfile() == null) { aapsLogger.error(LTag.AUTOMATION, "ProfileFunctions not initialized") - callback.result(PumpEnactResult(injector).success(false).comment(R.string.noprofile))?.run() + callback.result(PumpEnactResult(injector).success(false).comment(R.string.noprofile)).run() return } if (inputProfileName.value == activeProfileName) { aapsLogger.debug(LTag.AUTOMATION, "Profile is already switched") - callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadyset))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadyset)).run() return } val profileStore = activePlugin.activeProfileSource.profile ?: return if (profileStore.getSpecificProfile(inputProfileName.value) == null) { aapsLogger.error(LTag.AUTOMATION, "Selected profile does not exist! - ${inputProfileName.value}") - callback.result(PumpEnactResult(injector).success(false).comment(R.string.notexists))?.run() + callback.result(PumpEnactResult(injector).success(false).comment(R.string.notexists)).run() return } uel.log( @@ -64,7 +64,7 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) { ValueWithUnit.Percent(100) ) val result = profileFunction.createProfileSwitch(profileStore, inputProfileName.value, 0, 100, 0, dateUtil.now()) - callback.result(PumpEnactResult(injector).success(result).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(result).comment(R.string.ok)).run() } override fun generateDialog(root: LinearLayout) { diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt index 0e7ad534b7..e6863d4c1c 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt @@ -9,7 +9,6 @@ import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration @@ -19,6 +18,7 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuil import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.JsonHelper +import info.nightscout.shared.logging.LTag import org.json.JSONObject import javax.inject.Inject @@ -50,10 +50,10 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector ValueWithUnit.Percent(pct.value.toInt()), ValueWithUnit.Minute(duration.value) ) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } else { aapsLogger.error(LTag.AUTOMATION, "Final profile not valid") - callback.result(PumpEnactResult(injector).success(false).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(false).comment(R.string.ok)).run() } } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionRunAutotune.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionRunAutotune.kt index 2fc8026157..c2687fffed 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionRunAutotune.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionRunAutotune.kt @@ -22,12 +22,12 @@ import org.json.JSONObject import javax.inject.Inject class ActionRunAutotune(injector: HasAndroidInjector) : Action(injector) { + @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var autotunePlugin: Autotune @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var sp: SP - @Inject lateinit var uel: UserEntryLogger var defaultValue = 0 private var inputProfileName = InputProfileName(rh, activePlugin, "", true) @@ -48,7 +48,7 @@ class ActionRunAutotune(injector: HasAndroidInjector) : Action(injector) { message = R.string.autotune_run_with_error aapsLogger.error(LTag.AUTOMATION, "Error during Autotune Run") } - callback.result(PumpEnactResult(injector).success(autotunePlugin.lastRunSuccess).comment(message))?.run() + callback.result(PumpEnactResult(injector).success(autotunePlugin.lastRunSuccess).comment(message)).run() }.start() return } diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt index 4c96e33784..47d87e619b 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt @@ -25,7 +25,7 @@ class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) { override fun doAction(callback: Callback) { val result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.value) - callback.result(PumpEnactResult(injector).success(result).comment(if (result) R.string.ok else R.string.error))?.run() + callback.result(PumpEnactResult(injector).success(result).comment(if (result) R.string.ok else R.string.error)).run() } override fun isValid(): Boolean = text.value.isNotEmpty() diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt index 7647ecd11b..6e45d702d2 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt @@ -17,7 +17,6 @@ import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration @@ -29,6 +28,7 @@ import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import org.json.JSONObject @@ -59,18 +59,20 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) { override fun doAction(callback: Callback) { disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction(tt())) .subscribe({ result -> - result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") } - result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") } - uel.log(UserEntry.Action.TT, Sources.Automation, title, - ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.AUTOMATION), - ValueWithUnit.Mgdl(tt().lowTarget), - ValueWithUnit.Mgdl(tt().highTarget).takeIf { tt().lowTarget != tt().highTarget }, - ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt().duration).toInt())) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() - }, { - aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) - callback.result(PumpEnactResult(injector).success(false).comment(R.string.error))?.run() - }) + result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") } + result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") } + uel.log( + UserEntry.Action.TT, Sources.Automation, title, + ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.AUTOMATION), + ValueWithUnit.Mgdl(tt().lowTarget), + ValueWithUnit.Mgdl(tt().highTarget).takeIf { tt().lowTarget != tt().highTarget }, + ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt().duration).toInt()) + ) + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() + }, { + aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) + callback.result(PumpEnactResult(injector).success(false).comment(R.string.error)).run() + }) } override fun generateDialog(root: LinearLayout) { diff --git a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStopTempTarget.kt b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStopTempTarget.kt index 1f8c77c95b..53075b11e7 100644 --- a/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStopTempTarget.kt +++ b/automation/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStopTempTarget.kt @@ -7,10 +7,10 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction -import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import javax.inject.Inject @@ -35,7 +35,7 @@ class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) { }, { aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) }) - callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() + callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok)).run() } override fun isValid(): Boolean = true diff --git a/automation/src/main/res/values-de-rDE/strings.xml b/automation/src/main/res/values-de-rDE/strings.xml index 3cb46b8eaa..4fdf548bc7 100644 --- a/automation/src/main/res/values-de-rDE/strings.xml +++ b/automation/src/main/res/values-de-rDE/strings.xml @@ -113,4 +113,5 @@ Automatisierungs-Ereignis Umsortieren Benutzeraktion + Sind Sie sicher, dass Sie diese(s) %1$d Element(e) löschen möchten? diff --git a/automation/src/main/res/values-ru-rRU/strings.xml b/automation/src/main/res/values-ru-rRU/strings.xml index 2caaa73c95..181d25930f 100644 --- a/automation/src/main/res/values-ru-rRU/strings.xml +++ b/automation/src/main/res/values-ru-rRU/strings.xml @@ -120,4 +120,7 @@ Вы уверены, что хотите удалить %1$d элемент Сортировать Автоматизация системы + Запустить автоматизацию + Добавить правило + Удаление/сортировка diff --git a/automation/src/main/res/values-zh-rCN/strings.xml b/automation/src/main/res/values-zh-rCN/strings.xml index 5ec6797b3a..5e02878c3d 100644 --- a/automation/src/main/res/values-zh-rCN/strings.xml +++ b/automation/src/main/res/values-zh-rCN/strings.xml @@ -120,4 +120,7 @@ 你确定要删除 %1$d 吗? 排序 系统自动化 + 运行自动化 + 添加规则 + 移除/排序 diff --git a/build.gradle b/build.gradle index 8a5dbef20b..f7aeaacda4 100644 --- a/build.gradle +++ b/build.gradle @@ -2,9 +2,9 @@ buildscript { ext { - kotlin_version = '1.6.21' - core_version = '1.7.0' - rxjava_version = '3.1.4' + kotlin_version = '1.7.0' + core_version = '1.8.0' + rxjava_version = '3.1.5' rxandroid_version = '3.0.0' rxkotlin_version = '3.0.1' room_version = '2.4.2' @@ -16,8 +16,8 @@ buildscript { ormLite_version = '4.46' gson_version = '2.9.0' nav_version = '2.4.2' - appcompat_version = '1.4.1' - material_version = '1.6.0' + appcompat_version = '1.4.2' + material_version = '1.6.1' constraintlayout_version = '2.1.4' preferencektx_version = '1.2.0' commonslang3_version = '3.12.0' @@ -40,7 +40,7 @@ buildscript { wearable_version = '2.9.0' play_services_wearable_version = '17.1.0' - play_services_location_version = '19.0.1' + play_services_location_version = '20.0.0' } repositories { google() @@ -66,7 +66,7 @@ plugins { id "io.gitlab.arturbosch.detekt" version "1.20.0" id "org.jlleitschuh.gradle.ktlint" version "10.3.0" id 'org.barfuin.gradle.jacocolog' version '2.0.0' - id 'org.jetbrains.kotlin.android' version '1.6.21' apply false + id 'org.jetbrains.kotlin.android' version '1.7.0' apply false } allprojects { diff --git a/combo/build.gradle b/combo/build.gradle index 7605e4667d..a3faa431e6 100644 --- a/combo/build.gradle +++ b/combo/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.combo' +} dependencies { implementation project(':core') diff --git a/combo/src/main/AndroidManifest.xml b/combo/src/main/AndroidManifest.xml index a5aa9f0e8e..11b940a009 100644 --- a/combo/src/main/AndroidManifest.xml +++ b/combo/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/core/build.gradle b/core/build.gradle index b3fef255db..f1b51650c2 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -15,3 +15,7 @@ dependencies { implementation project(':shared') implementation project(':database') } + +android { + namespace 'info.nightscout.androidaps.core' +} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 9f170d4340..0f37944ddb 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + @@ -9,14 +8,17 @@ - - + + diff --git a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt index 709b7d71c4..eb5f46428d 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt @@ -4,6 +4,7 @@ import android.content.Context import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.Round import org.json.JSONException import org.json.JSONObject @@ -50,15 +51,15 @@ class IobTotal(val time: Long) : DataPointWithLabelInterface { return this } - fun round(): IobTotal { - iob = Round.roundTo(iob, 0.001) - activity = Round.roundTo(activity, 0.0001) - bolussnooze = Round.roundTo(bolussnooze, 0.0001) - basaliob = Round.roundTo(basaliob, 0.001) - netbasalinsulin = Round.roundTo(netbasalinsulin, 0.001) - hightempinsulin = Round.roundTo(hightempinsulin, 0.001) - netInsulin = Round.roundTo(netInsulin, 0.001) - extendedBolusInsulin = Round.roundTo(extendedBolusInsulin, 0.001) + fun round(fabricPrivacy: FabricPrivacy? = null): IobTotal { + iob = Round.roundTo(iob, 0.001, fabricPrivacy) + activity = Round.roundTo(activity, 0.0001, fabricPrivacy) + bolussnooze = Round.roundTo(bolussnooze, 0.0001, fabricPrivacy) + basaliob = Round.roundTo(basaliob, 0.001, fabricPrivacy) + netbasalinsulin = Round.roundTo(netbasalinsulin, 0.001, fabricPrivacy) + hightempinsulin = Round.roundTo(hightempinsulin, 0.001, fabricPrivacy) + netInsulin = Round.roundTo(netInsulin, 0.001, fabricPrivacy) + extendedBolusInsulin = Round.roundTo(extendedBolusInsulin, 0.001, fabricPrivacy) return this } diff --git a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt index 1b9229e4e3..e30a92c223 100644 --- a/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt +++ b/core/src/main/java/info/nightscout/androidaps/di/CoreFragmentsModule.kt @@ -10,6 +10,7 @@ import info.nightscout.androidaps.dialogs.ErrorDialog import info.nightscout.androidaps.dialogs.NtpProgressDialog import info.nightscout.androidaps.dialogs.ProfileViewerDialog import info.nightscout.androidaps.plugins.general.maintenance.activities.PrefImportListActivity +import info.nightscout.androidaps.utils.ui.SingleClickButton @Module @Suppress("unused") @@ -25,4 +26,6 @@ abstract class CoreFragmentsModule { @ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): NtpProgressDialog @ContributesAndroidInjector abstract fun contributesProfileViewerDialog(): ProfileViewerDialog + @ContributesAndroidInjector abstract fun contributesSingleClickButton(): SingleClickButton + } diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt b/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt index bf36db39d0..12e9b48b5b 100644 --- a/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/dialogs/ErrorDialog.kt @@ -74,11 +74,11 @@ class ErrorDialog : DaggerDialogFragment() { } binding.mute.setOnClickListener { uel.log(Action.ERROR_DIALOG_MUTE, Sources.Unknown) - stopAlarm() + stopAlarm("Mute") } binding.mute5min.setOnClickListener { uel.log(Action.ERROR_DIALOG_MUTE_5MIN, Sources.Unknown) - stopAlarm() + stopAlarm("Mute 5 min") handler.postDelayed(this::startAlarm, T.mins(5).msecs()) } startAlarm() @@ -110,14 +110,14 @@ class ErrorDialog : DaggerDialogFragment() { super.dismissAllowingStateLoss() helperActivity?.finish() handler.removeCallbacksAndMessages(null) - stopAlarm() + stopAlarm("Dismiss") } private fun startAlarm() { if (sound != 0) - alarmSoundServiceHelper.startAlarm(ctx, sound) + alarmSoundServiceHelper.startAlarm(ctx, sound, "$title:$status") } - private fun stopAlarm() = - alarmSoundServiceHelper.stopService(ctx) + private fun stopAlarm(reason: String) = + alarmSoundServiceHelper.stopService(ctx, reason) } diff --git a/core/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.kt b/core/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.kt index 36650f1838..0f19800f22 100644 --- a/core/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.kt +++ b/core/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.kt @@ -1,12 +1,10 @@ package info.nightscout.androidaps.events -class EventNetworkChange : Event() { - - var mobileConnected = false - var wifiConnected = false - var vpnConnected = false - - var ssid = "" - var roaming = false - var metered = false -} +class EventNetworkChange( + var mobileConnected: Boolean = false, + var wifiConnected: Boolean = false, + var vpnConnected: Boolean = false, + var ssid: String = "", + var roaming: Boolean = false, + var metered: Boolean = false +) : Event() diff --git a/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt b/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt index a07e789856..5affb67f08 100644 --- a/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt +++ b/core/src/main/java/info/nightscout/androidaps/extensions/BolusCalculatorResultExtension.kt @@ -2,22 +2,23 @@ package info.nightscout.androidaps.extensions import com.google.gson.Gson import com.google.gson.JsonSyntaxException -import info.nightscout.androidaps.Constants import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper import org.json.JSONObject -fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject = +fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil, profileFunction: ProfileFunction): JSONObject = JSONObject() .put("eventType", TherapyEvent.Type.BOLUS_WIZARD.text) .put("created_at", dateUtil.toISOString(timestamp)) .put("isValid", isValid) .put("bolusCalculatorResult", Gson().toJson(this)) .put("date", timestamp) - .put("glucose", glucoseValue) - .put("units", Constants.MGDL) + .put("glucose", Profile.fromMgdlToUnits(glucoseValue, profileFunction.getUnits())) + .put("units", profileFunction.getUnits().asText) .put("notes", note) .also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelper.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/BuildHelper.kt similarity index 71% rename from core/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelper.kt rename to core/src/main/java/info/nightscout/androidaps/interfaces/BuildHelper.kt index ca6a251f65..5f47316282 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/buildHelper/BuildHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/BuildHelper.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.utils.buildHelper +package info.nightscout.androidaps.interfaces interface BuildHelper { diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/CommandQueue.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/CommandQueue.kt index 7218b06df2..5ba0055402 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/CommandQueue.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/CommandQueue.kt @@ -2,10 +2,9 @@ package info.nightscout.androidaps.interfaces import android.text.Spanned import info.nightscout.androidaps.data.DetailedBolusInfo -import info.nightscout.androidaps.interfaces.Profile -import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.androidaps.queue.commands.CustomCommand interface CommandQueue { diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/ImportExportPrefs.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/ImportExportPrefs.kt index 15ee7030b4..efed509a3a 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/ImportExportPrefs.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/ImportExportPrefs.kt @@ -2,9 +2,7 @@ package info.nightscout.androidaps.interfaces import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity -import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.plugins.general.maintenance.PrefsFile -import io.reactivex.rxjava3.core.Single interface ImportExportPrefs { diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt index c62af2c988..7061c01540 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/Profile.kt @@ -8,7 +8,6 @@ import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.Round -import info.nightscout.androidaps.interfaces.ResourceHelper import org.joda.time.DateTime import org.json.JSONObject @@ -62,6 +61,7 @@ interface Profile { * ISF value according to "now"" in MGDL */ fun getIsfMgdl(): Double + /** * ISF value according to timestamp in MGDL */ diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt index 6d6c1e945a..9cf779cfe2 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/constraints/versionChecker/AllowedVersions.kt @@ -4,43 +4,9 @@ import org.joda.time.LocalDate import org.json.JSONArray import org.json.JSONException import org.json.JSONObject -import java.lang.Exception class AllowedVersions { - fun generateSupportedVersions(): String = - JSONArray() - // Android API versions - .put(JSONObject().apply { - put("minAndroid", 1) // 1.0 - put("maxAndroid", 23) // 6.0.1 - }) - .put(JSONObject().apply { - put("minAndroid", 24) // 7.0 - put("maxAndroid", 25) // 7.1.2 - put("supported", "2.6.2") - }) - .put(JSONObject().apply { - put("minAndroid", 26) // 8.0 - put("maxAndroid", 27) // 8.1 - put("supported", "2.8.2") - }) - .put(JSONObject().apply { - put("minAndroid", 28) // 9.0 - put("maxAndroid", 99) - put("supported", "2.8.2") - }) - // Version time limitation - .put(JSONObject().apply { - put("endDate", "2021-11-07") - put("version", "2.9.0-beta1") - }) - .put(JSONObject().apply { - put("endDate", "2021-11-07") - put("version", "3.0-beta1") - }) - .toString() - fun findByApi(definition: String?, api: Int): JSONObject? { if (definition == null) return null try { diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java index d66585d173..1edec982f5 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -96,6 +96,7 @@ public class PointsWithLabelGraphSeries e * @param isSecondScale whether it is the second scale */ @Override + @SuppressWarnings({"deprecation"}) public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { // Convert the sp to pixels float scaledTextSize = spSize * graphView.getContext().getResources().getDisplayMetrics().scaledDensity; diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/Scale.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/Scale.kt index 0c11b7e285..748f327eaf 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/Scale.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/Scale.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions -class Scale(var shift: Double = 0.0, var multiplier: Double = 0.0) { +class Scale(var shift: Double = 0.0, var multiplier: Double = 1.0) { fun transform(original: Double): Double { return original * multiplier + shift diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt index fc0d025e80..11843accfb 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.kt @@ -8,7 +8,7 @@ open class Notification { var id = 0 var date: Long = 0 - var text: String? = null + var text: String = "" var level = 0 var validTo: Long = 0 @RawRes var soundId: Int? = null diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt index 9344476a61..0a9d28d76c 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt @@ -11,7 +11,8 @@ import kotlin.math.min @Suppress("unused") enum class PumpType { - GENERIC_AAPS(description = "Generic AAPS", + GENERIC_AAPS( + description = "Generic AAPS", manufacturer = ManufacturerType.AndroidAPS, model = "VirtualPump", bolusSize = 0.1, @@ -23,9 +24,11 @@ enum class PumpType { baseBasalMinValue = 0.01, baseBasalStep = 0.01, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.VirtualPumpCapabilities), + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), - CELLNOVO(description = "Cellnovo", + CELLNOVO( + description = "Cellnovo", manufacturer = ManufacturerType.Cellnovo, model = "Cellnovo", bolusSize = 0.05, @@ -37,9 +40,11 @@ enum class PumpType { baseBasalMinValue = 0.05, baseBasalStep = 0.05, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.VirtualPumpCapabilities), + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), - ACCU_CHEK_COMBO(description = "Accu-Chek Combo", + ACCU_CHEK_COMBO( + description = "Accu-Chek Combo", manufacturer = ManufacturerType.Roche, model = "Combo", bolusSize = 0.1, @@ -53,8 +58,10 @@ enum class PumpType { baseBasalSpecialSteps = DoseStepSize.ComboBasal, pumpCapability = PumpCapability.ComboCapabilities, source = Sources.Combo, - supportBatteryLevel = false), - ACCU_CHEK_SPIRIT(description = "Accu-Chek Spirit", + supportBatteryLevel = false + ), + ACCU_CHEK_SPIRIT( + description = "Accu-Chek Spirit", manufacturer = ManufacturerType.Roche, model = "Spirit", bolusSize = 0.1, @@ -66,8 +73,10 @@ enum class PumpType { baseBasalMinValue = 0.01, baseBasalStep = 0.1, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.VirtualPumpCapabilities), - ACCU_CHEK_INSIGHT_VIRTUAL(description = "Accu-Chek Insight", + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), + ACCU_CHEK_INSIGHT_VIRTUAL( + description = "Accu-Chek Insight", manufacturer = ManufacturerType.Roche, model = "Insight", bolusSize = 0.05, @@ -79,8 +88,10 @@ enum class PumpType { baseBasalMinValue = 0.02, baseBasalStep = 0.01, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.InsightCapabilities), - ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight", + pumpCapability = PumpCapability.InsightCapabilities + ), + ACCU_CHEK_INSIGHT( + description = "Accu-Chek Insight", manufacturer = ManufacturerType.Roche, model = "Insight", bolusSize = 0.01, @@ -94,8 +105,10 @@ enum class PumpType { baseBasalStep = 0.01, baseBasalSpecialSteps = DoseStepSize.InsightBasal, pumpCapability = PumpCapability.InsightCapabilities, - source = Sources.Insight), - ACCU_CHEK_SOLO(description = "Accu-Chek Solo", + source = Sources.Insight + ), + ACCU_CHEK_SOLO( + description = "Accu-Chek Solo", manufacturer = ManufacturerType.Roche, model = "Solo", bolusSize = 0.01, @@ -108,9 +121,11 @@ enum class PumpType { baseBasalMaxValue = null, baseBasalStep = 0.01, baseBasalSpecialSteps = DoseStepSize.InsightBolus, - pumpCapability = PumpCapability.InsightCapabilities), + pumpCapability = PumpCapability.InsightCapabilities + ), - ANIMAS_VIBE(description = "Animas Vibe", + ANIMAS_VIBE( + description = "Animas Vibe", manufacturer = ManufacturerType.Animas, model = "Vibe", bolusSize = 0.05, @@ -123,9 +138,11 @@ enum class PumpType { baseBasalMaxValue = 5.0, baseBasalStep = 0.0, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.VirtualPumpCapabilities), + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE), - DANA_R(description = "DanaR", + DANA_R( + description = "DanaR", manufacturer = ManufacturerType.Sooil, model = "DanaR", bolusSize = 0.05, @@ -138,8 +155,10 @@ enum class PumpType { baseBasalStep = 0.01, baseBasalSpecialSteps = null, pumpCapability = PumpCapability.DanaCapabilities, - source = Sources.DanaR), - DANA_R_KOREAN(description = "DanaR Korean", + source = Sources.DanaR + ), + DANA_R_KOREAN( + description = "DanaR Korean", manufacturer = ManufacturerType.Sooil, model = "DanaRKorean", bolusSize = 0.05, @@ -152,8 +171,10 @@ enum class PumpType { baseBasalStep = 0.01, baseBasalSpecialSteps = null, pumpCapability = PumpCapability.DanaCapabilities, - source = Sources.DanaRC), - DANA_RS(description = "DanaRS", + source = Sources.DanaRC + ), + DANA_RS( + description = "DanaRS", manufacturer = ManufacturerType.Sooil, model = "DanaRS", bolusSize = 0.05, @@ -166,11 +187,13 @@ enum class PumpType { baseBasalStep = 0.01, baseBasalSpecialSteps = null, pumpCapability = PumpCapability.DanaWithHistoryCapabilities, - source = Sources.DanaRS), + source = Sources.DanaRS + ), DANA_RS_KOREAN(description = "DanaRSKorean", model = "DanaRSKorean", parent = DANA_RS), DANA_I(description = "DanaI", model = "DanaI", parent = DANA_RS, source = Sources.DanaI), DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS, source = Sources.DanaRv2), - OMNIPOD_EROS(description = "Omnipod Eros", + OMNIPOD_EROS( + description = "Omnipod Eros", manufacturer = ManufacturerType.Insulet, model = "Eros", bolusSize = 0.05, @@ -188,8 +211,10 @@ enum class PumpType { isPatchPump = true, useHardwareLink = true, supportBatteryLevel = false, - source = Sources.OmnipodEros), - OMNIPOD_DASH(description = "Omnipod Dash", + source = Sources.OmnipodEros + ), + OMNIPOD_DASH( + description = "Omnipod Dash", manufacturer = ManufacturerType.Insulet, model = "Dash", bolusSize = 0.05, @@ -205,8 +230,10 @@ enum class PumpType { isPatchPump = true, pumpCapability = PumpCapability.OmnipodCapabilities, hasCustomUnreachableAlertCheck = false, - supportBatteryLevel = false), - MEDTRONIC_512_712(description = "Medtronic 512/712", + supportBatteryLevel = false + ), + MEDTRONIC_512_712( + description = "Medtronic 512/712", manufacturer = ManufacturerType.Medtronic, model = "512/712", bolusSize = 0.1, @@ -219,14 +246,20 @@ enum class PumpType { baseBasalStep = 0.05, baseBasalSpecialSteps = null, pumpCapability = PumpCapability.MedtronicCapabilities, - source = Sources.Medtronic), - MEDTRONIC_515_715(description = "Medtronic 515/715", + source = Sources.Medtronic + ), + MEDTRONIC_515_715( + description = "Medtronic 515/715", model = "515/715", - parent = MEDTRONIC_512_712), - MEDTRONIC_522_722(description = "Medtronic 522/722", + parent = MEDTRONIC_512_712 + ), + MEDTRONIC_522_722( + description = "Medtronic 522/722", model = "522/722", - parent = MEDTRONIC_512_712), - MEDTRONIC_523_723_REVEL(description = "Medtronic 523/723 (Revel)", + parent = MEDTRONIC_512_712 + ), + MEDTRONIC_523_723_REVEL( + description = "Medtronic 523/723 (Revel)", manufacturer = ManufacturerType.Medtronic, model = "523/723 (Revel)", bolusSize = 0.05, @@ -239,9 +272,11 @@ enum class PumpType { baseBasalStep = 0.025, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, pumpCapability = PumpCapability.MedtronicCapabilities, - source = Sources.Medtronic), + source = Sources.Medtronic + ), MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL), - MEDTRONIC_640G(description = "Medtronic 640G", + MEDTRONIC_640G( + description = "Medtronic 640G", manufacturer = ManufacturerType.Medtronic, model = "640G", bolusSize = 0.025, @@ -253,9 +288,11 @@ enum class PumpType { baseBasalMinValue = 0.025, baseBasalStep = 0.025, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, - pumpCapability = PumpCapability.VirtualPumpCapabilities), + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), - TANDEM_T_SLIM(description = "Tandem t:slim", + TANDEM_T_SLIM( + description = "Tandem t:slim", manufacturer = ManufacturerType.Tandem, model = "t:slim", bolusSize = 0.01, @@ -267,12 +304,14 @@ enum class PumpType { baseBasalMinValue = 0.1, baseBasalStep = 0.001, baseBasalSpecialSteps = null, - pumpCapability = PumpCapability.VirtualPumpCapabilities), + pumpCapability = PumpCapability.VirtualPumpCapabilities + ), TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM), - YPSOPUMP(description = "YpsoPump", + YPSOPUMP( + description = "YpsoPump", manufacturer = ManufacturerType.Ypsomed, model = "Ypsopump", bolusSize = 0.1, @@ -285,26 +324,39 @@ enum class PumpType { baseBasalMaxValue = 40.0, baseBasalStep = 0.01, baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal, - pumpCapability = PumpCapability.YpsomedCapabilities), - MDI(description = "MDI", + pumpCapability = PumpCapability.YpsomedCapabilities + ), + MDI( + description = "MDI", manufacturer = ManufacturerType.AndroidAPS, bolusSize = 0.5, model = "MDI", tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), - pumpCapability = PumpCapability.MDI), + pumpCapability = PumpCapability.MDI + ), // Not real pump. Used for User as a source - USER(description = "USER", + USER( + description = "USER", manufacturer = ManufacturerType.AndroidAPS, model = "USER", tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), pumpCapability = PumpCapability.MDI, - source = Sources.MDI), + source = Sources.MDI + ), + + // Not real, cached value + CACHE( + description = "CACHE", + model = "CACHE", + parent = USER + ), //Diaconn Pump - DIACONN_G8(description = "Diaconn G8", + DIACONN_G8( + description = "Diaconn G8", manufacturer = ManufacturerType.G2e, model = "DiaconnG8", bolusSize = 0.01, @@ -319,7 +371,8 @@ enum class PumpType { baseBasalSpecialSteps = null, pumpCapability = PumpCapability.DiaconnCapabilities, source = Sources.DiaconnG8, - useHardwareLink = true); + useHardwareLink = true + ); val description: String var manufacturer: ManufacturerType? = null @@ -407,6 +460,7 @@ enum class PumpType { InterfaceIDs.PumpType.MDI -> MDI InterfaceIDs.PumpType.USER -> USER InterfaceIDs.PumpType.DIACONN_G8 -> DIACONN_G8 + InterfaceIDs.PumpType.CACHE -> TODO() } } @@ -418,25 +472,27 @@ enum class PumpType { parent.model = model } - constructor(description: String, - manufacturer: ManufacturerType, - model: String, - bolusSize: Double = 0.0, - specialBolusSize: DoseStepSize? = null, - extendedBolusSettings: DoseSettings, - pumpTempBasalType: PumpTempBasalType? = null, - tbrSettings: DoseSettings, - specialBasalDurations: PumpCapability? = null, - baseBasalMinValue: Double = 0.01, - baseBasalMaxValue: Double? = null, - baseBasalStep: Double = 1.0, - baseBasalSpecialSteps: DoseStepSize? = null, - pumpCapability: PumpCapability, - hasCustomUnreachableAlertCheck: Boolean = false, - isPatchPump: Boolean = false, - supportBatteryLevel: Boolean = true, - useHardwareLink: Boolean = false, - source: Sources = Sources.VirtualPump) { + constructor( + description: String, + manufacturer: ManufacturerType, + model: String, + bolusSize: Double = 0.0, + specialBolusSize: DoseStepSize? = null, + extendedBolusSettings: DoseSettings, + pumpTempBasalType: PumpTempBasalType? = null, + tbrSettings: DoseSettings, + specialBasalDurations: PumpCapability? = null, + baseBasalMinValue: Double = 0.01, + baseBasalMaxValue: Double? = null, + baseBasalStep: Double = 1.0, + baseBasalSpecialSteps: DoseStepSize? = null, + pumpCapability: PumpCapability, + hasCustomUnreachableAlertCheck: Boolean = false, + isPatchPump: Boolean = false, + supportBatteryLevel: Boolean = true, + useHardwareLink: Boolean = false, + source: Sources = Sources.VirtualPump + ) { this.description = description this.manufacturer = manufacturer this.model = model @@ -463,12 +519,14 @@ enum class PumpType { val eb = extendedBolusSettings ?: return "INVALID" val tbr = tbrSettings ?: return "INVALID" val extendedNote = if (hasExtendedBasals) rh.gs(R.string.def_extended_note) else "" - return String.format(i18nTemplate, + return String.format( + i18nTemplate, getStep("" + bolusSize, specialBolusSize), eb.step, eb.durationStep, eb.maxDuration / 60, getStep(baseBasalRange(), baseBasalSpecialSteps), tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit, - tbr.durationStep, tbr.maxDuration / 60, extendedNote) + tbr.durationStep, tbr.maxDuration / 60, extendedNote + ) } private fun baseBasalRange(): String = @@ -494,42 +552,45 @@ enum class PumpType { fun determineCorrectBasalSize(basalAmount: Double): Double { val tSettings = tbrSettings ?: throw IllegalStateException() - return Round.roundTo(min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount) - ?: baseBasalStep) + return Round.roundTo( + min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount) + ?: baseBasalStep + ) } fun toDbPumpType(): InterfaceIDs.PumpType = when (this) { - GENERIC_AAPS -> InterfaceIDs.PumpType.GENERIC_AAPS - CELLNOVO -> InterfaceIDs.PumpType.CELLNOVO - ACCU_CHEK_COMBO -> InterfaceIDs.PumpType.ACCU_CHEK_COMBO - ACCU_CHEK_SPIRIT -> InterfaceIDs.PumpType.ACCU_CHEK_SPIRIT + GENERIC_AAPS -> InterfaceIDs.PumpType.GENERIC_AAPS + CELLNOVO -> InterfaceIDs.PumpType.CELLNOVO + ACCU_CHEK_COMBO -> InterfaceIDs.PumpType.ACCU_CHEK_COMBO + ACCU_CHEK_SPIRIT -> InterfaceIDs.PumpType.ACCU_CHEK_SPIRIT ACCU_CHEK_INSIGHT_VIRTUAL -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT ACCU_CHEK_INSIGHT -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH ACCU_CHEK_SOLO -> InterfaceIDs.PumpType.ACCU_CHEK_SOLO - ANIMAS_VIBE -> InterfaceIDs.PumpType.ANIMAS_VIBE - ANIMAS_PING -> InterfaceIDs.PumpType.ANIMAS_PING - DANA_R -> InterfaceIDs.PumpType.DANA_R - DANA_R_KOREAN -> InterfaceIDs.PumpType.DANA_R_KOREAN - DANA_RS -> InterfaceIDs.PumpType.DANA_RS - DANA_RS_KOREAN -> InterfaceIDs.PumpType.DANA_RS_KOREAN - DANA_RV2 -> InterfaceIDs.PumpType.DANA_RV2 - DANA_I -> InterfaceIDs.PumpType.DANA_I - OMNIPOD_EROS -> InterfaceIDs.PumpType.OMNIPOD_EROS - OMNIPOD_DASH -> InterfaceIDs.PumpType.OMNIPOD_DASH - MEDTRONIC_512_712 -> InterfaceIDs.PumpType.MEDTRONIC_512_517 - MEDTRONIC_515_715 -> InterfaceIDs.PumpType.MEDTRONIC_515_715 - MEDTRONIC_522_722 -> InterfaceIDs.PumpType.MEDTRONIC_522_722 - MEDTRONIC_523_723_REVEL -> InterfaceIDs.PumpType.MEDTRONIC_523_723_REVEL - MEDTRONIC_554_754_VEO -> InterfaceIDs.PumpType.MEDTRONIC_554_754_VEO - MEDTRONIC_640G -> InterfaceIDs.PumpType.MEDTRONIC_640G - TANDEM_T_SLIM -> InterfaceIDs.PumpType.TANDEM_T_SLIM - TANDEM_T_SLIM_G4 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_G4 - TANDEM_T_FLEX -> InterfaceIDs.PumpType.TANDEM_T_FLEX - TANDEM_T_SLIM_X2 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_X2 - YPSOPUMP -> InterfaceIDs.PumpType.YPSOPUMP - MDI -> InterfaceIDs.PumpType.MDI - USER -> InterfaceIDs.PumpType.USER - DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8 + ANIMAS_VIBE -> InterfaceIDs.PumpType.ANIMAS_VIBE + ANIMAS_PING -> InterfaceIDs.PumpType.ANIMAS_PING + DANA_R -> InterfaceIDs.PumpType.DANA_R + DANA_R_KOREAN -> InterfaceIDs.PumpType.DANA_R_KOREAN + DANA_RS -> InterfaceIDs.PumpType.DANA_RS + DANA_RS_KOREAN -> InterfaceIDs.PumpType.DANA_RS_KOREAN + DANA_RV2 -> InterfaceIDs.PumpType.DANA_RV2 + DANA_I -> InterfaceIDs.PumpType.DANA_I + OMNIPOD_EROS -> InterfaceIDs.PumpType.OMNIPOD_EROS + OMNIPOD_DASH -> InterfaceIDs.PumpType.OMNIPOD_DASH + MEDTRONIC_512_712 -> InterfaceIDs.PumpType.MEDTRONIC_512_517 + MEDTRONIC_515_715 -> InterfaceIDs.PumpType.MEDTRONIC_515_715 + MEDTRONIC_522_722 -> InterfaceIDs.PumpType.MEDTRONIC_522_722 + MEDTRONIC_523_723_REVEL -> InterfaceIDs.PumpType.MEDTRONIC_523_723_REVEL + MEDTRONIC_554_754_VEO -> InterfaceIDs.PumpType.MEDTRONIC_554_754_VEO + MEDTRONIC_640G -> InterfaceIDs.PumpType.MEDTRONIC_640G + TANDEM_T_SLIM -> InterfaceIDs.PumpType.TANDEM_T_SLIM + TANDEM_T_SLIM_G4 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_G4 + TANDEM_T_FLEX -> InterfaceIDs.PumpType.TANDEM_T_FLEX + TANDEM_T_SLIM_X2 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_X2 + YPSOPUMP -> InterfaceIDs.PumpType.YPSOPUMP + MDI -> InterfaceIDs.PumpType.MDI + USER -> InterfaceIDs.PumpType.USER + DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8 + CACHE -> InterfaceIDs.PumpType.CACHE } } diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtil.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtil.java index eee40443e2..c96e99b89b 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtil.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtil.java @@ -273,6 +273,13 @@ public class DateTimeUtil { } + public static long getATDWithAddedMinutes(Long atd, int minutesDiff) { + GregorianCalendar oldestEntryTime = DateTimeUtil.toGregorianCalendar(atd); + oldestEntryTime.add(Calendar.MINUTE, minutesDiff); + + return toATechDate(oldestEntryTime); + } + public static long getATDWithAddedMinutes(GregorianCalendar oldestEntryTime, int minutesDiff) { oldestEntryTime.add(Calendar.MINUTE, minutesDiff); diff --git a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt index 1fde2cdbb7..9f5e32a9b6 100644 --- a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundServiceHelper.kt @@ -28,8 +28,8 @@ class AlarmSoundServiceHelper @Inject constructor( private val notificationHolder: NotificationHolder ) { - fun startAlarm(context: Context, sound: Int) { - aapsLogger.debug(LTag.CORE, "Starting alarm") + fun startAlarm(context: Context, sound: Int, reason: String) { + aapsLogger.debug(LTag.CORE, "Starting alarm from $reason") val connection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { // The binder of the service that returns the instance that is created. @@ -62,8 +62,8 @@ class AlarmSoundServiceHelper @Inject constructor( } } - fun stopService(context: Context) { - aapsLogger.debug(LTag.CORE, "Stopping alarm") + fun stopService(context: Context, reason: String) { + aapsLogger.debug(LTag.CORE, "Stopping alarm from $reason") val alarm = Intent(context, AlarmSoundService::class.java) context.stopService(alarm) } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/Round.kt b/core/src/main/java/info/nightscout/androidaps/utils/Round.kt index 4d9f542775..3f854d4979 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/Round.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/Round.kt @@ -1,32 +1,37 @@ package info.nightscout.androidaps.utils +import android.os.Bundle import java.math.BigDecimal import kotlin.math.abs import kotlin.math.ceil import kotlin.math.floor -import kotlin.math.round +import kotlin.math.roundToLong /** * Created by mike on 20.06.2016. */ object Round { - @JvmStatic - fun roundTo(x: Double, step: Double): Double = + fun roundTo(x: Double, step: Double, fabricPrivacy: FabricPrivacy? = null): Double = try { if (x == 0.0) 0.0 - else BigDecimal.valueOf(round(x / step) * step).toDouble() + else BigDecimal.valueOf((x / step).roundToLong()).multiply(BigDecimal.valueOf(step)).toDouble() + } catch (e: Exception) { + fabricPrivacy?.logCustom("Error_roundTo", Bundle().apply { + putDouble("x", x) + putDouble("step", step) + putString("stacktrace", e.stackTraceToString()) + }) + 0.0 + } - @JvmStatic fun floorTo(x: Double, step: Double): Double = if (x != 0.0) floor(x / step) * step else 0.0 - @JvmStatic fun ceilTo(x: Double, step: Double): Double = if (x != 0.0) ceil(x / step) * step else 0.0 - @JvmStatic fun isSame(d1: Double, d2: Double): Boolean = abs(d1 - d2) <= 0.000001 } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/SingleClickButton.kt b/core/src/main/java/info/nightscout/androidaps/utils/ui/SingleClickButton.kt index ef336c2a52..185b97f89f 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/ui/SingleClickButton.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/SingleClickButton.kt @@ -2,25 +2,32 @@ package info.nightscout.androidaps.utils.ui import android.content.Context import android.util.AttributeSet +import dagger.android.HasAndroidInjector import info.nightscout.androidaps.core.R -import info.nightscout.shared.logging.StacktraceLoggerWrapper -import org.slf4j.Logger +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import javax.inject.Inject -class SingleClickButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.style.Widget_MaterialComponents_Button) : com.google.android.material.button.MaterialButton(context, attrs, defStyleAttr) { +class SingleClickButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.style.Widget_MaterialComponents_Button) : + com.google.android.material.button.MaterialButton(context, attrs, defStyleAttr) { + + init { + (context.applicationContext as HasAndroidInjector).androidInjector().inject(this) + } + + @Inject lateinit var aapsLogger: AAPSLogger override fun performClick(): Boolean = guardClick { super.performClick() } override fun callOnClick(): Boolean = guardClick { super.callOnClick() } private fun guardClick(block: () -> Boolean): Boolean { isEnabled = false - postDelayed({ isEnabled = true; log.debug("Button enabled") }, BUTTON_REFRACTION_PERIOD) + postDelayed({ isEnabled = true; aapsLogger.debug(LTag.UI, "Button enabled") }, BUTTON_REFRACTION_PERIOD) return block() } - @Suppress("DEPRECATION") - private val log: Logger = StacktraceLoggerWrapper.getLogger(SingleClickButton::class.java) - companion object { + const val BUTTON_REFRACTION_PERIOD = 3000L } } \ No newline at end of file diff --git a/core/src/main/res/values-af-rZA/strings.xml b/core/src/main/res/values-af-rZA/strings.xml index e16a8775f0..0b6a6abc84 100644 --- a/core/src/main/res/values-af-rZA/strings.xml +++ b/core/src/main/res/values-af-rZA/strings.xml @@ -2,7 +2,9 @@ + Stoor %1$.2f U/h + ]]> Ja Nee LOOP UIT AKSIE GESTEL DEUR BEPERKINGS @@ -60,5 +62,6 @@ %1$.2f beperk tot %2$.2f + Basale diff --git a/core/src/main/res/values-bg-rBG/strings.xml b/core/src/main/res/values-bg-rBG/strings.xml index 9eada62db6..183980600d 100644 --- a/core/src/main/res/values-bg-rBG/strings.xml +++ b/core/src/main/res/values-bg-rBG/strings.xml @@ -4,6 +4,7 @@ Обнови Грешка + Съхрани Не е зададен Неуспешно обновяване на базалния профил Профила на помпата е обновен @@ -41,6 +42,7 @@ въглехидрати Грешен профил !!! НЕ Е АКТИВИРАН ПРОФИЛ + ]]> Дата Единици DIA (Време на действие на инсулина): @@ -285,6 +287,7 @@ %1$.2f ограничен до %2$.2f SMS + Базал %1$d дeн diff --git a/core/src/main/res/values-ca-rES/strings.xml b/core/src/main/res/values-ca-rES/strings.xml index 16ce76713d..1eb5f978ea 100644 --- a/core/src/main/res/values-ca-rES/strings.xml +++ b/core/src/main/res/values-ca-rES/strings.xml @@ -2,6 +2,8 @@ + Desar + ]]> @@ -66,5 +68,6 @@ %1$.2f limitat a %2$.2f »%1$s« supera els límits + Basal diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index 7867c85bf7..8f03f86ea7 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -464,8 +464,8 @@ Poslední spuštění : Varování : Vyberte profil pro ladění - Autotune funguje pouze s jedinou hodnotou IC, váš profil má %1$d hodnot. Průměrná hodnota je %2$.2fg/U - Autotune funguje pouze s jedinou hodnotou ISF, váš profil má %1$d hodnot. Průměrná hodnota je %2$.1f%3$s/U + Vybraný profil má %1$d hodnot IC. Autotune bude používat %2$.2f g/U + Vybraný profil má %1$d hodnot ISF. Autotune bude používat %2$.1f %3$s/U Chyba vstupních dat, zkuste autotune spustit znovu nebo snížit počet dní Autotune spuštěno, prosím buďte trpěliví Před použitím výsledky pečlivě zkontrolujte! diff --git a/core/src/main/res/values-da-rDK/strings.xml b/core/src/main/res/values-da-rDK/strings.xml index 8f64c75dee..d446162c2f 100644 --- a/core/src/main/res/values-da-rDK/strings.xml +++ b/core/src/main/res/values-da-rDK/strings.xml @@ -461,8 +461,6 @@ Sidst kørt : Advarsel : Vælg profil, der skal justeres - Autotune fungerer med kun én IC-værdi, din profil har %1$d værdier. Gennemsnitsværdi er %2$.2fg/E - Autotune virker med kun én ISF-værdi, din profil har %1$d værdier. Gennemsnitlig værdi er %2$.1f%3$s/E Automatisk beregning startet, vær venligst tålmodig Kontrollér resultaterne omhyggeligt, før du bruger dem! Delvis resultat dag %1$d / %2$d justeret diff --git a/core/src/main/res/values-de-rDE/strings.xml b/core/src/main/res/values-de-rDE/strings.xml index 0c2664a530..5b12029067 100644 --- a/core/src/main/res/values-de-rDE/strings.xml +++ b/core/src/main/res/values-de-rDE/strings.xml @@ -42,6 +42,7 @@ Kohlenhydrate Ungültiges oder defektes Profil! KEIN PROFIL GESETZT + ]]> Datum Einheiten DIA @@ -428,6 +429,9 @@ Insight Refresh Button abnehmend %1$s mit %2$s zunehmend %1$s mit %2$s + Basal + %1$d ausgewählt + Sortieren %1$d Tag diff --git a/core/src/main/res/values-el-rGR/strings.xml b/core/src/main/res/values-el-rGR/strings.xml index 730d941711..68de2b7014 100644 --- a/core/src/main/res/values-el-rGR/strings.xml +++ b/core/src/main/res/values-el-rGR/strings.xml @@ -2,7 +2,9 @@ + Αποθήκευση %1$.2f U/h + ]]> Ναι Όχι ΤΟ ΚΥΚΛΩΜΑ ΑΠΕΝΕΡΓΟΠΟΙΗΘΗΚΕ ΑΠΟ ΠΕΡΙΟΡΙΣΜΟΥΣ @@ -60,5 +62,6 @@ Το %1$.2f περιορίζεται σε %2$.2f + Βασικός Ρυθμός diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml index 936daa643a..19f888b736 100644 --- a/core/src/main/res/values-es-rES/strings.xml +++ b/core/src/main/res/values-es-rES/strings.xml @@ -464,8 +464,6 @@ Última ejecución : Advertencia : Selecciona el perfil para a ajustar - Autotune sólo funciona con un valor de IC. Tu perfil tiene %1$d valores. El valor promedio es %2$.2fg/U - Autotune sólo funciona con un valor de ISF. Tu perfil tiene %1$d valores. El valor promedio es %2$.1f%3$s/U Error en los datos de entrada, intenta ejecutar de nuevo autotune o reducir el número de días Cálculo de autototune iniciado, por favor ten paciencia ¡Comprueba los resultados cuidadosamente antes de usarlos! diff --git a/core/src/main/res/values-fr-rFR/strings.xml b/core/src/main/res/values-fr-rFR/strings.xml index 16f153ac86..2170468b20 100644 --- a/core/src/main/res/values-fr-rFR/strings.xml +++ b/core/src/main/res/values-fr-rFR/strings.xml @@ -446,7 +446,7 @@ Aide pour ajuster le profil (SI, rapport G/I et débits de basal) AT Paramètres Autotune - Changement de profil avec l\'Automatisation + Changr le profil avec l\'automatisation Si activé, Autotune mettra à jour automatiquement à jour le profil sélectionné et activera le profil calculé effectué à partir d\'une règle d\'automatisation. Catégoriser UAM en tant que Basal Activer uniquement si vous avez correctement saisi tous les glucides consommés, avec cette option, des hausses soudaines vues par Autotune seront utilisées pour modifier les débits de basal. @@ -464,8 +464,8 @@ Dernier run : Avertissement : Sélectionnez le profil à optimiser - Autotune ne fonctionne qu\'avec une seule valeur G/I, votre profil a %1$d valeurs. La valeur moyenne est de %2$.2f g/U - Autotune ne calcule qu\'une seule valeur de SI, votre profil a %1$d valeurs. La valeur moyenne est de %2$.1f %3$s/U + Le profil sélectionné %1$d valeurs de G/I. Autotune va utiliser la moyenne %2$.2f g/U + Le profil sélectionné a %1$d valeurs de SI. Autotune va utiliser la moyenne %2$.1f %3$s/U Erreur dans les données d\'entrée, essayez de relancer le calcul ou réduire le nombre de jours Le calcul Autotune a commencé, veuillez patienter Vérifiez attentivement les résultats avant de les utiliser! diff --git a/core/src/main/res/values-ga-rIE/strings.xml b/core/src/main/res/values-ga-rIE/strings.xml index 57edab2df3..0ab0b703fd 100644 --- a/core/src/main/res/values-ga-rIE/strings.xml +++ b/core/src/main/res/values-ga-rIE/strings.xml @@ -3,6 +3,7 @@ Earráid + Sábháil Ag fanacht do caidéil Ag nascadh le %1$d s Ag seachadadh %1$.2f A @@ -114,5 +115,6 @@ + Bunaidh diff --git a/core/src/main/res/values-hr-rHR/strings.xml b/core/src/main/res/values-hr-rHR/strings.xml index 6f676893c7..57579e20e0 100644 --- a/core/src/main/res/values-hr-rHR/strings.xml +++ b/core/src/main/res/values-hr-rHR/strings.xml @@ -2,8 +2,10 @@ + Zatvori + Otkaži diff --git a/core/src/main/res/values-hu-rHU/strings.xml b/core/src/main/res/values-hu-rHU/strings.xml index cb08528112..8d7d288e7b 100644 --- a/core/src/main/res/values-hu-rHU/strings.xml +++ b/core/src/main/res/values-hu-rHU/strings.xml @@ -26,5 +26,6 @@ + Bázis diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml index bf525d5731..700387ef45 100644 --- a/core/src/main/res/values-iw-rIL/strings.xml +++ b/core/src/main/res/values-iw-rIL/strings.xml @@ -464,8 +464,8 @@ הפעלה אחרונה : אזהרה : בחרו פרופיל לכוונון - כוונון אוטומטי עובד עם ערך IC אחד בלבד, לפרופיל שלכם יש %1$d ערכים. הערך הממוצע הוא %2$.2f גר\'\\יח\' - כוונון אוטומטי עובד עם ערך ISF אחד בלבד, לפרופיל שלכם יש %1$d ערכים. הערך הממוצע הוא %2$.1f %3$s\\יח\' + בפרופיל הנבחר יש %1$d ערכי יחס פחמימות. הכיוונון האוטומטי ישתמש ב-%2$.2f גר\'\\יח\' + בפרופיל הנבחר יש %1$d ערכי יחס תיקון. הכיוונון האוטומטי ישתמש ב-%2$.1f %3$s\\יח\' שגיאה בנתוני הקלט, נסו להפעיל בשנית או שנסו לצמצם את מספר הימים חישוב הכוונון האוטומטי התחיל, אנא התאזרו בסבלנות בדקו היטב את התוצאות לפני השימוש בהן! diff --git a/core/src/main/res/values-ko-rKR/strings.xml b/core/src/main/res/values-ko-rKR/strings.xml index 59b3617bea..c04e9ec5b3 100644 --- a/core/src/main/res/values-ko-rKR/strings.xml +++ b/core/src/main/res/values-ko-rKR/strings.xml @@ -4,6 +4,7 @@ 새로고침 에러 + 저장 설정되지 않음 Basal 프로파일 갱신 실패 Basal 프로파일이 펌프에 업데이트 되었습니다 @@ -40,6 +41,7 @@ 탄수화물 프로파일이 유효하지 않습니다!!! 프로파일이 설정되지 않았습니다. + ]]> 날짜 단위 인슐린활동시간(DIA): @@ -376,6 +378,7 @@ »%1$s« %2$.2f이 \'고정된 한계값\'을 벗어났습니다. Basal 값 + Basal %1$d 일 diff --git a/core/src/main/res/values-lt-rLT/strings.xml b/core/src/main/res/values-lt-rLT/strings.xml index 976c5a496f..c834cbf768 100644 --- a/core/src/main/res/values-lt-rLT/strings.xml +++ b/core/src/main/res/values-lt-rLT/strings.xml @@ -4,6 +4,7 @@ Atnaujinti Klaida + Išsaugoti Nenustatyta Nepavyko atnaujinti bazės profilio Bazės profilis pompoje atnaujintas @@ -41,6 +42,7 @@ AV Netinkamas profilis!!! Nenustatytas profilis + ]]> Data Vienetai IVT @@ -418,6 +420,7 @@ Bolusas OK Pompa suporuota Insight Mygtukas Naujinti + Valandinė bazė %1$d d. diff --git a/core/src/main/res/values-no-rNO/strings.xml b/core/src/main/res/values-no-rNO/strings.xml index dfbe711045..d8b19182c7 100644 --- a/core/src/main/res/values-no-rNO/strings.xml +++ b/core/src/main/res/values-no-rNO/strings.xml @@ -464,8 +464,8 @@ Siste beregning : Varsel: Velg profil du vil justere - Autotune fungerer bare med én IC-verdi, og din profil har %1$d verdier. Gjennomsnittlig verdi er %2$.2fg/E - Autotune fungerer med bare én ISF verdi, og din profil har %1$d verdier. Gjennomsnittsverdi er %2$.1f%3$s/E + Valgt profil har %1$d IK verdier. Autotune vil bruke %2$.2f g/E + Valgte profil har %1$d ISF-verdier. Autotune vil bruke %2$.1f %3$s/E Feil i innleste datasett, prøv å kjør Autotune en gang til eller reduser antall dager Har startet Autotune beregning, vennligst vent Kontroller resultatene nøye før du bruker dem! diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml index 76332f8fbf..eba2bf6385 100644 --- a/core/src/main/res/values-pl-rPL/strings.xml +++ b/core/src/main/res/values-pl-rPL/strings.xml @@ -4,6 +4,7 @@ Odśwież Błąd + ZACHOWAJ Nie ustawiono Nieudane uaktualnienie profilu bazy Profil bazowy w pompie uaktualniony @@ -41,6 +42,7 @@ Węglowodany Nieprawidłowy profil !!! NIE USTAWIONO PROFILU + ]]> Data Jednostki DIA @@ -418,6 +420,9 @@ Bolus OK Pompa sparowana Przycisk Odświeżania Insight + Baza + Wybrany %1$d + Sortuj %1$d dzień diff --git a/core/src/main/res/values-pt-rPT/strings.xml b/core/src/main/res/values-pt-rPT/strings.xml index ffbe00bc75..29c658270c 100644 --- a/core/src/main/res/values-pt-rPT/strings.xml +++ b/core/src/main/res/values-pt-rPT/strings.xml @@ -4,6 +4,7 @@ Actualizar Erro + Guardar Não definido Falha a actualizar perfil da basal Perfil Basal actualizado na bomba @@ -40,6 +41,7 @@ Hidratos Perfil inválido !!! SEM PERFIL DEFINIDO + ]]> Data Unidades DIA @@ -337,6 +339,7 @@ %1$.2f limitado a %2$.2f »%1$s« está fora dos limites máximos + Basal %1$d dia diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml index 1ef70c3e8f..dc4b4b01f3 100644 --- a/core/src/main/res/values-ro-rRO/strings.xml +++ b/core/src/main/res/values-ro-rRO/strings.xml @@ -4,6 +4,7 @@ Actualizează Eroare + Salvează Nesetată Actualizarea profilului bazalei a eșuat Profilul bazalei a fost modificat în pompă @@ -41,6 +42,7 @@ Carbohidrați Profil invalid!!! NICIUN PROFIL SETAT + ]]> Data Unități DIA @@ -419,6 +421,8 @@ Bolus OK Pompă împerecheată Buton Reîmprospătare Insight + Rate bazale + Sortează %1$d zi diff --git a/core/src/main/res/values-ru-rRU/strings.xml b/core/src/main/res/values-ru-rRU/strings.xml index 20f5a3db8f..86d074832f 100644 --- a/core/src/main/res/values-ru-rRU/strings.xml +++ b/core/src/main/res/values-ru-rRU/strings.xml @@ -42,6 +42,7 @@ Углеводы Неверный профиль !!! ПРОФИЛЬ НЕ ЗАДАН + дата единицы DIA (время действия инсулина) @@ -438,7 +439,53 @@ Удалить элементы Сортировать элементы Удалить выбранные элементы + файл + пользователь + Автонастройка + Помощь в возможной корректировке профиля (ISF, IC, базал) + АвтТюн + Настройки Autotune + Профили Автонастройки + При активации происходит обновление автонастройки и смена профиля на основе правила автоматизации + Классифицировать UAM как базал + Включите, если только вы точно ввели все съеденные углеводы. С этой опцией внезапные подъемы, зафиксированные Autotune, будут использованы для рекомендаций изменения базальной скорости. + Настройка кривой инсулина + Включите, если используете беспиковый. Настроит пики и DIA + Количество дней с данными + Применить усредненный суточный IC/ISF + Autotune не настраивает суточные вариации, эта опция только применяет усредненные коэффициенты IC и ISF к суточному профилю + Включить больше информации логов для отладки + Включите только если разработчик просит отправить больше информации о логах для отладки плагина Autotune + Количество дней обработки данных Autotune по умолчанию (до 30) + Настроено + Профиль: + Настроено дней: + Последнее выполнение: + Внимание: + Выберите профиль для изменения + Ошибка ввода данных, попробуйте запустить снова autotune или уменьшить количество дней + Идет настройка автоматизации, ждите + Перед использованием внимательно проверьте результаты! + Частичный результат дня %1$d / %2$d с отладкой + Результат: %1$s + Парам + % + Отсутствует + Профиль авто тюн + Выполнить Autotune + Проверьте профиль ввода + Сравнить профили + Копировать в локальный профиль + Обновить профиль ввода + Вернуть профиль ввода + Создать новый локальный профиль из этого профиля Autotune? + Обновить профиль %1$s профилем Autotune? + Восстановить профиль %1$s с помощью входного профиля? + Неверный профиль + Autotune выполнен без переключения профиля + Autotune выполнен и профиль переключён автоматически + Ошибка во время последнего выполнения Autotune %1$d день %1$d дня diff --git a/core/src/main/res/values-sk-rSK/strings.xml b/core/src/main/res/values-sk-rSK/strings.xml index 780625bd0a..cbd101e11e 100644 --- a/core/src/main/res/values-sk-rSK/strings.xml +++ b/core/src/main/res/values-sk-rSK/strings.xml @@ -464,8 +464,6 @@ Posledné spustenie : Upozornenie : Vyberte profil pre ladenie - Autotune funguje iba s jedinou hodnotou IC, váš profil má %1$d hodnôt. Priemerná hodnota je %2$.2fg/JI - Autotune funguje iba s jedinou hodnotou IC, váš profil má %1$d hodnôt. Priemerná hodnota je %2$.1fg/JI Chyba vstupných dát, skúste znova spustiť Autotune, alebo znížte počet dní Autotune spustený, prosím buďte trpezliví Pred použitím výsledky starostlivo skontrolujte! diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml index eb3759fb8d..86d9f25d0c 100644 --- a/core/src/main/res/values-sv-rSE/strings.xml +++ b/core/src/main/res/values-sv-rSE/strings.xml @@ -4,6 +4,7 @@ Uppdatera Fel + Spara Ej vald Lyckades inte uppdatera basalprofilen Basalprofilen uppdaterad i pumpen @@ -41,6 +42,7 @@ Kolhydrater Ogiltig profil! INGEN PROFIL VALD + ]]> Datum Enheter DIA @@ -426,6 +428,7 @@ Uppdat. knapp för Insight minska %1$s med %2$s öka %1$s med %2$s + Basal %1$d dag diff --git a/core/src/main/res/values-tr-rTR/strings.xml b/core/src/main/res/values-tr-rTR/strings.xml index db7b65151d..07bb349882 100644 --- a/core/src/main/res/values-tr-rTR/strings.xml +++ b/core/src/main/res/values-tr-rTR/strings.xml @@ -464,8 +464,8 @@ Son Çalıştırma : Uyarı : Ayarlanacak profili seçin - OtoAyar yalnızca bir IC değeriyle çalışır, profilinizde %1$d değer mevcut. Ortalama değer: %2$.2fg/Ü - OtoAyar yalnızca bir İDF değeriyle çalışır, profilinizde %1$d değer mevcut. Ortalama değer: %2$.1f%3$s/Ü + Seçilen profilde %1$d KİO değeri var. OtoAyar %2$.2f g/Ü kullanacak + Seçilen profilde %1$d İDF değeri var. OtoAyar %2$.1f %3$s/Ü kullanacak Giriş verilerinde hata, otoayarı tekrar çalıştırmayı deneyin veya gün sayısını azaltın OtoAyar hesaplaması başladı, lütfen sabırlı olun Kullanmadan önce sonuçları dikkatlice kontrol edin! diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml index d0f3e1844a..d64d0e7d41 100644 --- a/core/src/main/res/values-zh-rCN/strings.xml +++ b/core/src/main/res/values-zh-rCN/strings.xml @@ -42,6 +42,7 @@ 碳水化合物 无效的配置文件!!! 没有设置配置文件 + ]]> 日期 单位 DIA diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 28411ab493..30974f7512 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -569,8 +569,8 @@ Last run : Warning : Select profile to tune - Autotune works with only one IC value, your profile has %1$d values. Average value is %2$.2fg/U - Autotune works with only one ISF value, your profile has %1$d values. Average value is %2$.1f%3$s/U + Selected profile has %1$d IC values. Autotune will use %2$.2f g/U + Selected profile has %1$d ISF values. Autotune will use %2$.1f %3$s/U Error in input data, try to run again autotune or reduce the number of days Autotune calculation started, please be patient Check the results carefully before using it! diff --git a/crowdin.yml b/crowdin.yml index ec9551d875..61f98bf0b8 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -19,6 +19,8 @@ files: translation: /combo/src/main/res/values-%android_code%/strings.xml - source: /dana/src/main/res/values/strings.xml translation: /dana/src/main/res/values-%android_code%/strings.xml + - source: /danar/src/main/res/values/strings.xml + translation: /danar/src/main/res/values-%android_code%/strings.xml - source: /medtronic/src/main/res/values/strings.xml translation: /medtronic/src/main/res/values-%android_code%/strings.xml - source: /omnipod-common/src/main/res/values/strings.xml @@ -43,6 +45,8 @@ files: translation: /automation/src/main/res/values-%android_code%/strings.xml - source: /diaconn/src/main/res/values/strings.xml translation: /diaconn/src/main/res/values-%android_code%/strings.xml + - source: /pump-common/src/main/res/values/strings.xml + translation: /pump-common/src/main/res/values-%android_code%/strings.xml - source: /openhumans/src/main/res/values/strings.xml translation: /openhumans/src/main/res/values-%android_code%/strings.xml translate_attributes: 0 diff --git a/dana/build.gradle b/dana/build.gradle index 64bc021517..f03521d269 100644 --- a/dana/build.gradle +++ b/dana/build.gradle @@ -10,6 +10,8 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" android { + + namespace 'info.nightscout.androidaps.dana' defaultConfig { kapt { arguments { diff --git a/dana/src/main/AndroidManifest.xml b/dana/src/main/AndroidManifest.xml index dda39a96f5..3960154ebf 100644 --- a/dana/src/main/AndroidManifest.xml +++ b/dana/src/main/AndroidManifest.xml @@ -1,13 +1,13 @@ - + - + diff --git a/danar/build.gradle b/danar/build.gradle index 6a273260c5..7fe1ba8c55 100644 --- a/danar/build.gradle +++ b/danar/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.danar' +} dependencies { implementation project(':core') diff --git a/danar/src/main/AndroidManifest.xml b/danar/src/main/AndroidManifest.xml index afa0e2ef98..df2a5d9b43 100644 --- a/danar/src/main/AndroidManifest.xml +++ b/danar/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java b/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java index fe56e12d89..5594689077 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java @@ -232,8 +232,8 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { int percentRate = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); // Any basal less than 0.10u/h will be dumped once per hour, not every 4 minutes. So if it's less than .10u/h, set a zero temp. if (absoluteRate < 0.10d) percentRate = 0; - if (percentRate < 100) percentRate = (int) Round.ceilTo((double) percentRate, 10d); - else percentRate = (int) Round.floorTo((double) percentRate, 10d); + if (percentRate < 100) percentRate = (int) Round.INSTANCE.ceilTo((double) percentRate, 10d); + else percentRate = (int) Round.INSTANCE.floorTo((double) percentRate, 10d); if (percentRate > 500) // Special high temp 500/15min percentRate = 500; aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Calculated percent rate: " + percentRate); @@ -353,7 +353,8 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); - insulin = Round.roundTo(insulin, getPumpDescription().getExtendedBolusStep()); + insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep(), + null); PumpEnactResult result = new PumpEnactResult(getInjector()); if (danaPump.isExtendedInProgress() && Math.abs(danaPump.getExtendedBolusAmount() - insulin) < pumpDescription.getExtendedBolusStep()) { diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java b/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java index a290c4e520..f2dbf782a6 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java @@ -267,7 +267,8 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); - insulin = Round.roundTo(insulin, getPumpDescription().getExtendedBolusStep()); + insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep(), + null); PumpEnactResult result = new PumpEnactResult(getInjector()); if (danaPump.isExtendedInProgress() && Math.abs(danaPump.getExtendedBolusAmount() - insulin) < getPumpDescription().getExtendedBolusStep()) { diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java b/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java index 90fd97ed88..9640c86b00 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java @@ -217,8 +217,8 @@ public class DanaRPlugin extends AbstractDanaRPlugin { int percentRate = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); // Any basal less than 0.10u/h will be dumped once per hour, not every 4 minutes. So if it's less than .10u/h, set a zero temp. if (absoluteRate < 0.10d) percentRate = 0; - if (percentRate < 100) percentRate = (int) Round.ceilTo((double) percentRate, 10d); - else percentRate = (int) Round.floorTo((double) percentRate, 10d); + if (percentRate < 100) percentRate = (int) Round.INSTANCE.ceilTo((double) percentRate, 10d); + else percentRate = (int) Round.INSTANCE.floorTo((double) percentRate, 10d); if (percentRate > getPumpDescription().getMaxTempPercent()) { percentRate = getPumpDescription().getMaxTempPercent(); } @@ -288,7 +288,8 @@ public class DanaRPlugin extends AbstractDanaRPlugin { double extendedRateToSet = absoluteRate - getBaseBasalRate(); extendedRateToSet = constraintChecker.applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value(); // needs to be rounded to 0.1 - extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours + extendedRateToSet = Round.INSTANCE.roundTo(extendedRateToSet, + pumpDescription.getExtendedBolusStep() * 2, null); // *2 because of half hours // What is current rate of extended bolusing in u/h? aapsLogger.debug(LTag.PUMP, "setTempBasalAbsolute: Extended bolus in progress: " + (danaPump.isExtendedInProgress()) + " rate: " + danaPump.getExtendedBolusAbsoluteRate() + "U/h duration remaining: " + danaPump.getExtendedBolusRemainingMinutes() + "min"); diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt index b2c5c0924b..fbbc7600f8 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgError.kt @@ -29,6 +29,8 @@ class MsgError( danaPump.bolusStopped = true bolusingEvent.status = errorString rxBus.send(bolusingEvent) + // at least on Occlusion pump stops communication. Try to force reconnecting + activePlugin.activePump.disconnect("Error from pump received") failed = true } else { failed = false diff --git a/danars/build.gradle b/danars/build.gradle index 96b60d2931..2f0b2a46a4 100644 --- a/danars/build.gradle +++ b/danars/build.gradle @@ -11,6 +11,7 @@ apply from: "${project.rootDir}/core/jacoco_global.gradle" android { ndkVersion "21.1.6352462" + namespace 'info.nightscout.androidaps.danars' defaultConfig { diff --git a/danars/src/main/AndroidManifest.xml b/danars/src/main/AndroidManifest.xml index 9588230a7d..c3ef8bc727 100644 --- a/danars/src/main/AndroidManifest.xml +++ b/danars/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + @@ -7,7 +6,9 @@ - + @@ -15,9 +16,11 @@ + diff --git a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt index ad6be79def..2ce6796e66 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt @@ -2,6 +2,7 @@ package info.nightscout.androidaps.database import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.database.data.NewEntries +import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.interfaces.DBEntry import info.nightscout.androidaps.database.transactions.Transaction @@ -59,6 +60,10 @@ import kotlin.math.roundToInt fun clearDatabases() = database.clearAllTables() + fun clearCachedData(from: Long) { + database.totalDailyDoseDao.deleteNewerThan(from, InterfaceIDs.PumpType.CACHE) + } + //BG READINGS -- only valid records fun compatGetBgReadingsDataFromTime(timestamp: Long, ascending: Boolean): Single> = database.glucoseValueDao.compatGetBgReadingsDataFromTime(timestamp) @@ -775,22 +780,26 @@ import kotlin.math.roundToInt fun getOldestExtendedBolusRecord(): ExtendedBolus? = database.extendedBolusDao.getOldestRecord() - // TotalDailyDose - fun getAllTotalDailyDoses(ascending: Boolean): Single> = - database.totalDailyDoseDao.getAllTotalDailyDoses() - .map { if (!ascending) it.reversed() else it } + fun getLastExtendedBolusIdWrapped(): Single> = + database.extendedBolusDao.getLastId() .subscribeOn(Schedulers.io()) + .toWrappedSingle() + // TotalDailyDose fun getLastTotalDailyDoses(count: Int, ascending: Boolean): Single> = database.totalDailyDoseDao.getLastTotalDailyDoses(count) .map { if (!ascending) it.reversed() else it } .subscribeOn(Schedulers.io()) - fun getLastExtendedBolusIdWrapped(): Single> = - database.extendedBolusDao.getLastId() + fun getCalculatedTotalDailyDose(timestamp: Long): Single> = + database.totalDailyDoseDao.findByTimestamp(timestamp, InterfaceIDs.PumpType.CACHE) .subscribeOn(Schedulers.io()) .toWrappedSingle() + fun createTotalDailyDose(tdd: TotalDailyDose) { + database.totalDailyDoseDao.insert(tdd) + } + // OFFLINE EVENT /* * returns a Pair of the next entity to sync and the ID of the "update". diff --git a/database/src/main/java/info/nightscout/androidaps/database/daos/TotalDailyDoseDao.kt b/database/src/main/java/info/nightscout/androidaps/database/daos/TotalDailyDoseDao.kt index d14d8b9bc0..5cb71c265a 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/daos/TotalDailyDoseDao.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/daos/TotalDailyDoseDao.kt @@ -2,11 +2,10 @@ package info.nightscout.androidaps.database.daos import androidx.room.Dao import androidx.room.Query -import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS import info.nightscout.androidaps.database.TABLE_TOTAL_DAILY_DOSES import info.nightscout.androidaps.database.embedments.InterfaceIDs -import info.nightscout.androidaps.database.entities.TemporaryTarget import info.nightscout.androidaps.database.entities.TotalDailyDose +import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.core.Single @Suppress("FunctionName") @@ -25,13 +24,16 @@ internal interface TotalDailyDoseDao : TraceableDao { @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp = :timestamp AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL") fun findByPumpTimestamp(timestamp: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): TotalDailyDose? - @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL ORDER BY timestamp ASC") - fun getAllTotalDailyDoses(): Single> + @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp = :timestamp AND pumpType = :pumpType AND referenceId IS NULL") + fun findByTimestamp(timestamp: Long, pumpType: InterfaceIDs.PumpType): Maybe - @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL ORDER BY timestamp DESC LIMIT :count") - fun getLastTotalDailyDoses(count: Int): Single> + @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE isValid = 1 AND referenceId IS NULL AND pumpType <> :exclude ORDER BY timestamp DESC LIMIT :count") + fun getLastTotalDailyDoses(count: Int, exclude: InterfaceIDs.PumpType = InterfaceIDs.PumpType.CACHE): Single> @Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset") suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List + @Query("DELETE FROM $TABLE_TOTAL_DAILY_DOSES WHERE dateCreated >= :since AND pumpType = :pumpType") + fun deleteNewerThan(since: Long, pumpType: InterfaceIDs.PumpType) + } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt b/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt index 0477dc1c8d..7306c89d1f 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt @@ -42,7 +42,8 @@ data class InterfaceIDs( YPSOPUMP, MDI, DIACONN_G8, - USER; + USER, + CACHE; companion object { diff --git a/diaconn/build.gradle b/diaconn/build.gradle index 64bc021517..84034c07ae 100644 --- a/diaconn/build.gradle +++ b/diaconn/build.gradle @@ -10,6 +10,8 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" android { + + namespace 'info.nightscout.androidaps.diaconn' defaultConfig { kapt { arguments { diff --git a/diaconn/src/main/AndroidManifest.xml b/diaconn/src/main/AndroidManifest.xml index 290eecf25f..837b1eae29 100644 --- a/diaconn/src/main/AndroidManifest.xml +++ b/diaconn/src/main/AndroidManifest.xml @@ -1,24 +1,24 @@ - + - + + android:exported="false" + android:theme="@style/AppTheme"> diff --git a/diaconn/src/main/res/values-ru-rRU/strings.xml b/diaconn/src/main/res/values-ru-rRU/strings.xml index f3fd8c04f3..126ce64c5c 100644 --- a/diaconn/src/main/res/values-ru-rRU/strings.xml +++ b/diaconn/src/main/res/values-ru-rRU/strings.xml @@ -152,4 +152,6 @@ Приостановка на низких отключена, команда ВЫКЛ отклонена. Запуск временного базала отклоняется при работе tempbasal Остановка временного базала отклоняется при неработающем tempbasal + Отправить лог помпы в Diaconn Cloud. + Синхронизация с Diaconn Cloud diff --git a/gradle.properties b/gradle.properties index 489d41472f..bc239ab4ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,3 +21,5 @@ org.gradle.jvmargs=-Xmx2g android.enableJetifier=true android.useAndroidX=true +# Cache is causeing issues with CircleCI nad maybe Studio 2021 +# org.gradle.unsafe.configuration-cache=true diff --git a/insight/build.gradle b/insight/build.gradle index 64bc021517..623c52532a 100644 --- a/insight/build.gradle +++ b/insight/build.gradle @@ -10,6 +10,8 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" android { + + namespace 'info.nightscout.androidaps.insight' defaultConfig { kapt { arguments { diff --git a/insight/src/main/AndroidManifest.xml b/insight/src/main/AndroidManifest.xml index 7e05839276..d125d192f6 100644 --- a/insight/src/main/AndroidManifest.xml +++ b/insight/src/main/AndroidManifest.xml @@ -1,25 +1,28 @@ - + + diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java index 864fb9e3c0..1ac0d12f7f 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/history/history_events/HistoryEvent.java @@ -8,7 +8,7 @@ import org.slf4j.Logger; public class HistoryEvent implements Comparable { @SuppressWarnings("deprecation") - private static final Logger log = StacktraceLoggerWrapper.getLogger(HistoryEvent.class); + private static final Logger log = StacktraceLoggerWrapper.Companion.getLogger(HistoryEvent.class); private int eventYear; private int eventMonth; diff --git a/medtronic/Changelog.txt b/medtronic/Changelog.txt index fc0b934b1c..ddea9b2ba0 100644 --- a/medtronic/Changelog.txt +++ b/medtronic/Changelog.txt @@ -8,4 +8,5 @@ V2 - Rewrite into kotlin, new database (for v3.0) 0002 - some fixes 0003 - SMB fix (798) 0004 - Zero TBR Duration fix (798), refactoring of TempBasalProcessDTO -0005 - fixes to MedtronicHistoryEntry lateinit problem \ No newline at end of file +0005 - fixes to MedtronicHistoryEntry lateinit problem +0006 - when bolus is placed, we adjust detailedBolusInfo with current timestamp \ No newline at end of file diff --git a/medtronic/build.gradle b/medtronic/build.gradle index 7b00d238c8..89b2f37c51 100644 --- a/medtronic/build.gradle +++ b/medtronic/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.plugins.pump.medtronic' +} dependencies { implementation project(':core') diff --git a/medtronic/src/main/AndroidManifest.xml b/medtronic/src/main/AndroidManifest.xml index 9738faa19c..935c304195 100644 --- a/medtronic/src/main/AndroidManifest.xml +++ b/medtronic/src/main/AndroidManifest.xml @@ -1,16 +1,19 @@ - + - + - + - + diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index a4e660fe4c..9752d1ef42 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -116,7 +116,7 @@ class MedtronicPumpPlugin @Inject constructor( private var isBusy = false override fun onStart() { - aapsLogger.debug(LTag.PUMP, deviceID() + " started. (V2.0005)") + aapsLogger.debug(LTag.PUMP, deviceID() + " started. (V2.0006)") serviceConnection = object : ServiceConnection { override fun onServiceDisconnected(name: ComponentName) { aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is disconnected") @@ -640,6 +640,8 @@ class MedtronicPumpPlugin @Inject constructor( } val now = System.currentTimeMillis() + detailedBolusInfo.timestamp = now + pumpSyncStorage.addBolusWithTempId(detailedBolusInfo, true, this) // we subtract insulin, exact amount will be visible with next remainingInsulin update. diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt index 39ab042651..7a70667d51 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/MedtronicHistoryEntry.kt @@ -140,6 +140,8 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface { val bodyLength: Int get() = sizes[2] + abstract fun toEntryString(): String + override fun toString(): String { val sb = StringBuilder() // if (DT == null) { @@ -156,6 +158,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface { sb.append("(") sb.append(headLength + dateTimeLength + bodyLength) sb.append(")") + val hasData = hasData() if (hasData) { sb.append(", data=$decodedDataAsString") diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt index 26e9cea75a..82beed1655 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/cgms/CGMSHistoryEntry.kt @@ -60,4 +60,9 @@ class CGMSHistoryEntry : MedtronicHistoryEntry() { fun setDateTime(timeStamp: LocalDateTime, getIndex: Int) { atechDateTime = (DateTimeUtil.toATechDate(timeStamp.plusMinutes(getIndex * 5))) } + + override fun toEntryString(): String { + // TODO fixme if needed + return toString() + } } \ No newline at end of file diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt index c16bf5c362..2c7481fd73 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/PumpHistoryEntry.kt @@ -84,6 +84,45 @@ class PumpHistoryEntry : MedtronicHistoryEntry() { return atechDateTime < this.atechDateTime } + override fun toEntryString(): String { + val sb = StringBuilder() + // if (DT == null) { + // Log.e("", "DT is null. RawData=" + ByteUtil.getHex(rawData)) + // } + sb.append("PumpHistoryEntry [type=" + StringUtil.getStringInLength(entryType.name, 20)) + sb.append(" " + if (DT == null) "null" else StringUtil.getStringInLength(DT, 19)) + + val hasData = (decodedData.size > 0) + if (hasData) { + if (hasDecodedDataEntry("Object")) { + val oo = getDecodedDataEntry("Object") + sb.append(", $oo") + } else { + sb.append(", data=$decodedDataAsString") + } + } else { + if (head.isNotEmpty()) { + sb.append(", head=") + sb.append(ByteUtil.shortHexString(head)) + } + if (datetime.size != 0) { + sb.append(", datetime=") + sb.append(ByteUtil.shortHexString(datetime)) + } + if (body.size != 0) { + sb.append(", body=") + sb.append(ByteUtil.shortHexString(body)) + } + sb.append(", rawData=") + sb.append(ByteUtil.shortHexString(rawData)) + sb.append("]") + } + + // sb.append(" Ext: "); + return sb.toString() + + } + class Comparator : java.util.Comparator { override fun compare(o1: PumpHistoryEntry, o2: PumpHistoryEntry): Int { diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt index 2f9b264971..752d7e187b 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.kt @@ -357,7 +357,7 @@ class MedtronicHistoryData @Inject constructor( aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "ProcessHistoryData: TBRs Processed [count=%d, items=%s]", tbrs.size, gson.toJson(tbrs))) if (tbrs.isNotEmpty()) { try { - processTBREntries(tbrs) + processTBREntries(tbrs, rewindRecords) } catch (ex: Exception) { aapsLogger.error(LTag.PUMP, "ProcessHistoryData: Error processing TBR entries: " + ex.message, ex) throw ex @@ -582,7 +582,7 @@ class MedtronicHistoryData @Inject constructor( } } - private fun processTBREntries(entryList: MutableList) { + private fun processTBREntries(entryList: MutableList, rewindList: MutableList) { entryList.reverse() val tbr = entryList[0].getDecodedDataEntry("Object") as TempBasalPair // var readOldItem = false @@ -606,7 +606,7 @@ class MedtronicHistoryData @Inject constructor( val tbrRecords = pumpSyncStorage.getTBRs() - val processList: MutableList = createTBRProcessList(entryList) + val processList: MutableList = createTBRProcessList(entryList, rewindList) if (processList.isNotEmpty()) { for (tempBasalProcessDTO in processList) { @@ -729,7 +729,8 @@ class MedtronicHistoryData @Inject constructor( } // collection } - fun createTBRProcessList(entryList: MutableList) : MutableList { + + fun createTBRProcessList(entryList: MutableList, rewindList: MutableList) : MutableList { aapsLogger.debug(LTag.PUMP, "${ProcessHistoryRecord.TBR.description} List (before filter): ${gson.toJson(entryList)}") @@ -795,6 +796,23 @@ class MedtronicHistoryData @Inject constructor( } } + // see if rewind items, need to fix any of current tempBasalProcessDTO items (bug 1724) + if (rewindList.isNotEmpty()) { + for (rewindEntry in rewindList) { + for (tempBasalProcessDTO in processList) { + if (tempBasalProcessDTO.itemTwo==null) { + val endTime: Long = DateTimeUtil.getATDWithAddedMinutes(tempBasalProcessDTO.itemOne.atechDateTime, tempBasalProcessDTO.itemOneTbr!!.durationMinutes) + + if ((rewindEntry.atechDateTime > tempBasalProcessDTO.itemOne.atechDateTime) && + (rewindEntry.atechDateTime < endTime)) { + tempBasalProcessDTO.itemTwo = rewindEntry + continue + } + } + } + } + } + return processList } @@ -1174,7 +1192,7 @@ class MedtronicHistoryData @Inject constructor( return getFilteredItems(newHistory, entryTypes) } - private fun getFilteredItems(entryType: PumpHistoryEntryType): MutableList { + fun getFilteredItems(entryType: PumpHistoryEntryType): MutableList { return getFilteredItems(newHistory, setOf(entryType)) } @@ -1188,7 +1206,7 @@ class MedtronicHistoryData @Inject constructor( } } - private fun getFilteredItems(inList: MutableList?, entryType: PumpHistoryEntryType): MutableList { + fun getFilteredItems(inList: MutableList?, entryType: PumpHistoryEntryType): MutableList { return getFilteredItems(inList, setOf(entryType)) } diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt index b784699bfa..29645b477b 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalProcessDTO.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.medtronic.data.dto import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry, var aapsLogger: AAPSLogger, @@ -13,7 +14,11 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry, field = value if (objectType == ObjectType.TemporaryBasal) { if (value!=null) { - itemTwoTbr = value.getDecodedDataEntry("Object") as TempBasalPair + if (value.entryType == PumpHistoryEntryType.TempBasalCombined) { + itemTwoTbr = value.getDecodedDataEntry("Object") as TempBasalPair + } else { + itemTwoRewind = value + } } else { itemTwoTbr = null } @@ -22,6 +27,7 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry, var itemOneTbr: TempBasalPair? = null var itemTwoTbr: TempBasalPair? = null + var itemTwoRewind: PumpHistoryEntry? = null val atechDateTime: Long get() = itemOne.atechDateTime @@ -41,6 +47,9 @@ class TempBasalProcessDTO constructor(var itemOne: PumpHistoryEntry, //aapsLogger.error("Couldn't find TempBasalPair in entry: $itemOne") return 0 } + } else if (itemTwoRewind!=null) { + val secondsDiff = DateTimeUtil.getATechDateDiferenceAsSeconds(itemOne.atechDateTime, DateTimeUtil.getATDWithAddedSeconds(itemTwo!!.atechDateTime, -2)) + return secondsDiff } else { //aapsLogger.debug(LTag.PUMP, "Found 2 items for duration: itemOne=$itemOne, itemTwo=$itemTwo") val secondsDiff = DateTimeUtil.getATechDateDiferenceAsSeconds(itemOne.atechDateTime, itemTwo!!.atechDateTime) diff --git a/medtronic/src/main/res/values-ru-rRU/strings.xml b/medtronic/src/main/res/values-ru-rRU/strings.xml index 30c3a6af52..71e7be8ba3 100644 --- a/medtronic/src/main/res/values-ru-rRU/strings.xml +++ b/medtronic/src/main/res/values-ru-rRU/strings.xml @@ -91,4 +91,6 @@ Если эта опция включена, то она отменяет временный базал до конца каждого часа. Такой метод помогает прекратить почасовую вибрацию некоторых помп. %1$.1fед/ч(%2$d мин осталось) Обнаружены недопустимые данные истории помпы. Создайте запись о новой проблеме и предоставьте журналы. + Статистика RL + Тип: diff --git a/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt b/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt index 3d78d1b4f6..fd598dcb63 100644 --- a/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt +++ b/medtronic/src/test/java/info/nightscout/androidaps/TestBase.kt @@ -1,10 +1,26 @@ package info.nightscout.androidaps +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.PumpSync +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil +import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType +import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil import info.nightscout.shared.logging.AAPSLoggerTest import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.TestAapsSchedulers +import info.nightscout.shared.sharedPreferences.SP import org.junit.Before import org.junit.Rule +import org.mockito.Answers +import org.mockito.Mock import org.mockito.Mockito import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoRule @@ -14,6 +30,28 @@ open class TestBase { val aapsLogger = AAPSLoggerTest() val aapsSchedulers: AapsSchedulers = TestAapsSchedulers() + var rxBus: RxBus = RxBus(TestAapsSchedulers(), aapsLogger) + var byteUtil = ByteUtil() + var rileyLinkUtil = RileyLinkUtil() + + @Mock lateinit var pumpSync: PumpSync + @Mock lateinit var pumpSyncStorage: PumpSyncStorage + @Mock(answer = Answers.RETURNS_DEEP_STUBS) lateinit var activePlugin: ActivePlugin + @Mock lateinit var sp: SP + @Mock lateinit var rh: ResourceHelper + + lateinit var medtronicUtil : MedtronicUtil + lateinit var decoder : MedtronicPumpHistoryDecoder + + + val packetInjector = HasAndroidInjector { + AndroidInjector { + + } + } + + + // Add a JUnit rule that will setup the @Mock annotated vars and log. // Another possibility would be to add `MockitoAnnotations.initMocks(this) to the setup method. @@ -34,6 +72,52 @@ open class TestBase { return uninitialized() } + fun preProcessListTBR(inputList: MutableList) { + + var tbrs: MutableList = mutableListOf() + + for (pumpHistoryEntry in inputList) { + if (pumpHistoryEntry.entryType === PumpHistoryEntryType.TempBasalRate || + pumpHistoryEntry.entryType === PumpHistoryEntryType.TempBasalDuration) { + tbrs.add(pumpHistoryEntry) + } + } + + inputList.removeAll(tbrs) + + inputList.addAll(preProcessTBRs(tbrs)) + + sort(inputList) + + //return inputList + + } + + + private fun preProcessTBRs(TBRs_Input: MutableList): MutableList { + val tbrs: MutableList = mutableListOf() + val map: MutableMap = HashMap() + for (pumpHistoryEntry in TBRs_Input) { + if (map.containsKey(pumpHistoryEntry.DT)) { + decoder.decodeTempBasal(map[pumpHistoryEntry.DT]!!, pumpHistoryEntry) + pumpHistoryEntry.setEntryType(medtronicUtil.medtronicPumpModel, PumpHistoryEntryType.TempBasalCombined) + tbrs.add(pumpHistoryEntry) + map.remove(pumpHistoryEntry.DT) + } else { + map[pumpHistoryEntry.DT] = pumpHistoryEntry + } + } + return tbrs + } + + private fun sort(list: MutableList) { + // if (list != null && !list.isEmpty()) { + // Collections.sort(list, PumpHistoryEntry.Comparator()) + // } + list.sortWith(PumpHistoryEntry.Comparator()) + } + + @Suppress("Unchecked_Cast") fun uninitialized(): T = null as T } \ No newline at end of file diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.java b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.java deleted file mode 100644 index e02c4bab20..0000000000 --- a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.medtronic.comm; - -//import uk.org.lidalia.slf4jtest.TestLogger; -//import uk.org.lidalia.slf4jtest.TestLoggerFactory; - -/** - * Created by andy on 3/10/19. - */ -public class MedtronicHistoryDataUTest { -/* - //TestLogger LOGGER = TestLoggerFactory.getTestLogger(MedtronicHistoryDataUTest.class); - - byte[] historyPageData = ByteUtil - .createByteArrayFromString("16 00 12 EC 14 47 13 33 00 14 F2 14 47 13 00 16 01 14 F2 14 47 13 33 00 1C C9 15 47 13 00 16 00 1C C9 15 47 13 33 4E 31 D3 15 47 13 00 16 01 31 D3 15 47 13 33 00 1A F1 15 47 13 00 16 00 1A F1 15 47 13 33 50 1D F1 15 47 13 00 16 01 1D F1 15 47 13 33 50 11 D8 16 47 13 00 16 01 11 D8 16 47 13 33 50 31 FB 16 47 13 00 16 01 31 FB 16 47 13 33 50 12 E3 17 47 13 00 16 01 12 E3 17 47 13 33 00 1E FB 17 47 13 00 16 00 1E FB 17 47 13 33 D8 21 FB 17 47 13 00 16 01 21 FB 17 47 13 07 00 00 05 CC 27 93 6D 27 93 05 0C 00 E8 00 00 00 00 05 CC 05 CC 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 33 00 36 C4 00 48 13 00 16 00 36 C4 00 48 13 33 D8 29 C9 00 48 13 00 16 01 29 C9 00 48 13 33 00 12 E7 00 48 13 00 16 00 12 E7 00 48 13 33 BC 19 C9 01 48 13 00 16 01 19 C9 01 48 13 33 00 26 CE 01 48 13 00 16 00 26 CE 01 48 13 33 44 29 CE 01 48 13 00 16 01 29 CE 01 48 13 33 00 13 D3 01 48 13 00 16 00 13 D3 01 48 13 33 64 31 F1 01 48 13 00 16 01 31 F1 01 48 13 33 00 0B F7 01 48 13 00 16 00 0B F7 01 48 13 33 00 12 D8 02 48 13 00 16 01 12 D8 02 48 13 33 00 10 F1 02 48 13 00 16 00 10 F1 02 48 13 33 00 30 C4 03 48 13 00 16 01 30 C4 03 48 13 33 00 04 CA 03 48 13 00 16 00 04 CA 03 48 13 33 00 2F D3 03 48 13 00 16 01 2F D3 03 48 13 33 00 30 D8 03 48 13 00 16 00 30 D8 03 48 13 33 00 13 E7 03 48 13 00 16 01 13 E7 03 48 13 33 00 2E FB 03 48 13 00 16 00 2E FB 03 48 13 19 00 00 C1 04 08 13 07 00 00 04 0C 28 93 6D 28 93 05 0C 00 E8 00 00 00 00 04 0C 04 0C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 06 3E 03 7A 19 DC 48 49 13 0C 3E 0C E6 08 09 13 07 00 00 01 E4 29 93 6D 29 93 05 0C 00 E8 00 00 00 00 01 E4 01 E4 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 1A 00 13 D2 0D 0A 13 1A 01 28 D2 0D 0A 13 21 00 2A D8 0D 0A 13 03 00 00 00 0E 2D D9 2D 0A 13 33 98 26 DE 0D 4A 13 00 16 01 26 DE 0D 4A 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5D 70"); - - MedtronicPumpHistoryDecoder decoder = new MedtronicPumpHistoryDecoder(); - - - // Logger LOGGER = StacktraceLoggerWrapper.getLogger(MedtronicHistoryDataUTest.class); - - //@Before - public void setup() { - - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "trace"); - - // final TestAppender appender = new TestAppender(); - // final Logger logger = Logger.getRootLogger(); - // logger.addAppender(appender); - // try { - // Logger.getLogger(MyTest.class).info("Test"); - // } finally { - // logger.removeAppender(appender); - // } - - - } - - - @Before - public void prepareMocks() throws Exception { - - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "trace"); - - when(SP.getString(R.string.key_danars_address, "")).thenReturn(""); - - //danaRPlugin = DanaRPlugin.getPlugin(); - } - - - //@Test - public void testTBR() throws Exception { - - RawHistoryPage historyPage = new RawHistoryPage(); - historyPage.appendData(historyPageData); - - List pumpHistoryEntries = decoder.processPageAndCreateRecords(historyPage); - - System.out.println("PumpHistoryEntries: " + pumpHistoryEntries.size()); - - Log.d("Test", "Log.d"); - //LOGGER.debug("Logger.debug"); - - for (PumpHistoryEntry pumpHistoryEntry : pumpHistoryEntries) { - Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()); - } - - } - - - public void testRussel() throws Exception { - byte[] historyPageData = ByteUtil - .createByteArrayFromString("06 15 04 F6 00 40 60 01 05 06 36 04 FE 00 40 60 01 05 06 2F 18 1A 00 40 20 C1 05 06 2F 0C 45 00 40 20 C1 05 06 2F 0C 56 00 40 20 C1 05 06 2F 0C 78 00 40 20 C1 05 06 2F 0C AD 00 40 20 C1 05 06 15 04 BA 00 40 40 A1 05 0C 15 0E 40 00 01 05 64 00 0D 44 00 01 05 17 00 14 44 00 01 05 18 00 00 44 00 01 05 21 00 07 44 00 01 05 21 00 0C 4E 00 01 05 07 00 00 00 00 01 85 6D 01 85 06 08 00 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 03 00 00 00 15 00 67 35 02 05 03 00 03 00 03 1C 67 15 02 05 07 00 00 00 40 02 85 6D 02 85 06 08 00 2B 00 00 00 00 00 40 00 40 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 2C 78 39 5F 17 03 05 07 00 00 02 6C 03 85 6D 03 85 06 08 00 2B 00 00 00 00 02 6C 02 6C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 26 01 33 44 01 04 05 27 03 74 41 01 B2 07 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 74"); - - RawHistoryPage historyPage = new RawHistoryPage(); - historyPage.appendData(historyPageData); - - List pumpHistoryEntries = decoder.processPageAndCreateRecords(historyPage); - - System.out.println("PumpHistoryEntries: " + pumpHistoryEntries.size()); - - Log.d("Test", "Log.d"); - //LOGGER.debug("Logger.debug"); - - for (PumpHistoryEntry pumpHistoryEntry : pumpHistoryEntries) { - Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()); - } - - } - - - // @Test - public void testJRoth_2111() throws Exception { - - byte[] historyPageData = ByteUtil - .createByteArrayFromString("01 03 03 00 8E 85 52 48 13 33 00 AB 89 12 48 13 00 16 00 AB 89 12 48 13 33 34 AD 89 12 48 13 00 16 01 AD 89 12 48 13 01 01 01 00 B8 8A 52 48 13 01 08 08 00 9F 8C 52 48 13 33 00 91 8F 12 48 13 00 16 00 91 8F 12 48 13 33 00 92 8F 12 48 13 00 16 03 92 8F 12 48 13 33 00 BA A7 12 48 13 00 16 04 BA A7 12 48 13 01 19 19 00 AF B0 52 48 13 33 00 8C 8A 13 48 13 00 16 04 8C 8A 13 48 13 33 00 9D A8 13 48 13 00 16 04 9D A8 13 48 13 33 00 AA 85 14 48 13 00 16 04 AA 85 14 48 13 33 00 8D A1 14 48 13 00 16 04 8D A1 14 48 13 33 10 89 BA 14 48 13 00 16 01 89 BA 14 48 13 33 00 AD 88 15 48 13 00 16 00 AD 88 15 48 13 33 00 AF 88 15 48 13 00 16 01 AF 88 15 48 13 01 1D 1D 00 95 8D 55 48 13 33 00 95 92 15 48 13 00 16 04 95 92 15 48 13 33 1E B7 9C 15 48 13 00 16 01 B7 9C 15 48 13 33 00 AA A6 15 48 13 00 16 00 AA A6 15 48 13 33 00 AC A6 15 48 13 00 16 04 AC A6 15 48 13 01 02 02 00 B7 A6 55 48 13 01 01 01 00 A6 AC 55 48 13 33 00 B3 8D 16 48 13 00 16 04 B3 8D 16 48 13 33 00 B7 97 16 48 13 00 16 04 B7 97 16 48 13 33 18 A7 B2 16 48 13 00 16 01 A7 B2 16 48 13 33 00 8B B8 16 48 13 00 16 00 8B B8 16 48 13 33 00 8D B8 16 48 13 00 16 03 8D B8 16 48 13 33 18 AE 85 17 48 13 00 16 01 AE 85 17 48 13 33 00 92 8A 17 48 13 00 16 00 92 8A 17 48 13 33 00 94 8A 17 48 13 00 16 01 94 8A 17 48 13 01 02 02 00 9F 8A 57 48 13 33 06 AC 8F 17 48 13 00 16 01 AC 8F 17 48 13 01 02 02 00 B8 8F 57 48 13 33 00 98 94 17 48 13 00 16 00 98 94 17 48 13 33 0C 9A 94 17 48 13 00 16 01 9A 94 17 48 13 01 02 02 00 A5 94 57 48 13 33 00 9C 99 17 48 13 00 16 00 9C 99 17 48 13 33 00 9E 99 17 48 13 00 16 01 9E 99 17 48 13 01 02 02 00 A9 99 57 48 13 01 02 02 00 84 9F 57 48 13 01 02 02 00 A7 A6 57 48 13 33 00 A4 AB 17 48 13 00 16 00 A4 AB 17 48 13 01 02 02 00 B0 AB 57 48 13 33 00 A7 B0 17 48 13 00 16 02 A7 B0 17 48 13 01 01 01 00 B2 B0 57 48 13 33 00 AD BA 17 48 13 00 16 04 AD BA 17 48 13 07 00 00 05 3A A8 13 6D A8 13 05 0C 00 E8 00 00 00 00 05 3A 00 F6 12 04 44 52 00 00 04 44 52 00 00 00 00 00 00 04 44 64 35 00 00 00 35 0C 00 E8 00 00 00 06 0A 1D 66 80 81 60 09 13 0C 0A 8D 82 00 09 13 1A 00 9A 82 00 09 13 1A 01 AF 82 00 09 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 28"); - - RawHistoryPage historyPage = new RawHistoryPage(); - historyPage.appendData(historyPageData); - - List pumpHistoryEntries = decoder.processPageAndCreateRecords(historyPage); - - System.out.println("PumpHistoryEntries: " + pumpHistoryEntries.size()); - - Log.d("Test", "Log.d"); - //LOGGER.debug("Logger.debug"); - - for (PumpHistoryEntry pumpHistoryEntry : pumpHistoryEntries) { - Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()); - } - } - -*/ -} diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt new file mode 100644 index 0000000000..adb0844ef0 --- /dev/null +++ b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt @@ -0,0 +1,186 @@ +package info.nightscout.androidaps.plugins.pump.medtronic.comm + +import android.util.Log +import info.nightscout.androidaps.TestBase +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil +import org.mockito.Mock +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.AAPSLoggerTest +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil +import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus +import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.MedtronicPumpHistoryDecoder +import kotlin.Throws +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RawHistoryPage +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry +import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType +import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData +import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalProcessDTO +import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType +import info.nightscout.androidaps.utils.rx.TestAapsSchedulers +import info.nightscout.androidaps.utils.serialisation.SealedClassHelper.gson +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import java.lang.Exception + +//import uk.org.lidalia.slf4jtest.TestLogger; +//import uk.org.lidalia.slf4jtest.TestLoggerFactory; +/** + * Created by andy on 3/10/19. + */ +class MedtronicHistoryDataUTest : TestBase() { + + //TestLogger LOGGER = TestLoggerFactory.getTestLogger(MedtronicHistoryDataUTest.class); + // var historyPageData = ByteUtil + // .createByteArrayFromString( + // "16 00 12 EC 14 47 13 33 00 14 F2 14 47 13 00 16 01 14 F2 14 47 13 33 00 1C C9 15 47 13 00 16 00 1C C9 15 47 13 33 4E 31 D3 15 47 13 00 16 01 31 D3 15 47 13 33 00 1A F1 15 47 13 00 16 00 1A F1 15 47 13 33 50 1D F1 15 47 13 00 16 01 1D F1 15 47 13 33 50 11 D8 16 47 13 00 16 01 11 D8 16 47 13 33 50 31 FB 16 47 13 00 16 01 31 FB 16 47 13 33 50 12 E3 17 47 13 00 16 01 12 E3 17 47 13 33 00 1E FB 17 47 13 00 16 00 1E FB 17 47 13 33 D8 21 FB 17 47 13 00 16 01 21 FB 17 47 13 07 00 00 05 CC 27 93 6D 27 93 05 0C 00 E8 00 00 00 00 05 CC 05 CC 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 33 00 36 C4 00 48 13 00 16 00 36 C4 00 48 13 33 D8 29 C9 00 48 13 00 16 01 29 C9 00 48 13 33 00 12 E7 00 48 13 00 16 00 12 E7 00 48 13 33 BC 19 C9 01 48 13 00 16 01 19 C9 01 48 13 33 00 26 CE 01 48 13 00 16 00 26 CE 01 48 13 33 44 29 CE 01 48 13 00 16 01 29 CE 01 48 13 33 00 13 D3 01 48 13 00 16 00 13 D3 01 48 13 33 64 31 F1 01 48 13 00 16 01 31 F1 01 48 13 33 00 0B F7 01 48 13 00 16 00 0B F7 01 48 13 33 00 12 D8 02 48 13 00 16 01 12 D8 02 48 13 33 00 10 F1 02 48 13 00 16 00 10 F1 02 48 13 33 00 30 C4 03 48 13 00 16 01 30 C4 03 48 13 33 00 04 CA 03 48 13 00 16 00 04 CA 03 48 13 33 00 2F D3 03 48 13 00 16 01 2F D3 03 48 13 33 00 30 D8 03 48 13 00 16 00 30 D8 03 48 13 33 00 13 E7 03 48 13 00 16 01 13 E7 03 48 13 33 00 2E FB 03 48 13 00 16 00 2E FB 03 48 13 19 00 00 C1 04 08 13 07 00 00 04 0C 28 93 6D 28 93 05 0C 00 E8 00 00 00 00 04 0C 04 0C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 06 3E 03 7A 19 DC 48 49 13 0C 3E 0C E6 08 09 13 07 00 00 01 E4 29 93 6D 29 93 05 0C 00 E8 00 00 00 00 01 E4 01 E4 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 1A 00 13 D2 0D 0A 13 1A 01 28 D2 0D 0A 13 21 00 2A D8 0D 0A 13 03 00 00 00 0E 2D D9 2D 0A 13 33 98 26 DE 0D 4A 13 00 16 01 26 DE 0D 4A 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5D 70" + // ) + + + + + //lateinit var rxBus: RxBus + lateinit var medtronicHistoryData: MedtronicHistoryData + lateinit var medtronicPumpStatus : MedtronicPumpStatus + + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + rxBus = RxBus(TestAapsSchedulers(), aapsLogger) + + medtronicPumpStatus = MedtronicPumpStatus( + rh, sp, rxBus, + rileyLinkUtil + ) + + medtronicUtil = MedtronicUtil( + aapsLogger, rxBus, rileyLinkUtil, + medtronicPumpStatus + ) + + decoder = MedtronicPumpHistoryDecoder( + aapsLogger, + medtronicUtil, byteUtil + ) + + medtronicHistoryData = MedtronicHistoryData(packetInjector, aapsLogger, sp, rh, rxBus, activePlugin, + medtronicUtil, decoder, + medtronicPumpStatus, + pumpSync, + pumpSyncStorage) + + + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "trace") + + } + + + //@Test + @Throws(Exception::class) fun testTBR() { + var historyPageData = ByteUtil + .createByteArrayFromString( + "16 00 12 EC 14 47 13 33 00 14 F2 14 47 13 00 16 01 14 F2 14 47 13 33 00 1C C9 15 47 13 00 16 00 1C C9 15 47 13 33 4E 31 D3 15 47 13 00 16 01 31 D3 15 47 13 33 00 1A F1 15 47 13 00 16 00 1A F1 15 47 13 33 50 1D F1 15 47 13 00 16 01 1D F1 15 47 13 33 50 11 D8 16 47 13 00 16 01 11 D8 16 47 13 33 50 31 FB 16 47 13 00 16 01 31 FB 16 47 13 33 50 12 E3 17 47 13 00 16 01 12 E3 17 47 13 33 00 1E FB 17 47 13 00 16 00 1E FB 17 47 13 33 D8 21 FB 17 47 13 00 16 01 21 FB 17 47 13 07 00 00 05 CC 27 93 6D 27 93 05 0C 00 E8 00 00 00 00 05 CC 05 CC 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 33 00 36 C4 00 48 13 00 16 00 36 C4 00 48 13 33 D8 29 C9 00 48 13 00 16 01 29 C9 00 48 13 33 00 12 E7 00 48 13 00 16 00 12 E7 00 48 13 33 BC 19 C9 01 48 13 00 16 01 19 C9 01 48 13 33 00 26 CE 01 48 13 00 16 00 26 CE 01 48 13 33 44 29 CE 01 48 13 00 16 01 29 CE 01 48 13 33 00 13 D3 01 48 13 00 16 00 13 D3 01 48 13 33 64 31 F1 01 48 13 00 16 01 31 F1 01 48 13 33 00 0B F7 01 48 13 00 16 00 0B F7 01 48 13 33 00 12 D8 02 48 13 00 16 01 12 D8 02 48 13 33 00 10 F1 02 48 13 00 16 00 10 F1 02 48 13 33 00 30 C4 03 48 13 00 16 01 30 C4 03 48 13 33 00 04 CA 03 48 13 00 16 00 04 CA 03 48 13 33 00 2F D3 03 48 13 00 16 01 2F D3 03 48 13 33 00 30 D8 03 48 13 00 16 00 30 D8 03 48 13 33 00 13 E7 03 48 13 00 16 01 13 E7 03 48 13 33 00 2E FB 03 48 13 00 16 00 2E FB 03 48 13 19 00 00 C1 04 08 13 07 00 00 04 0C 28 93 6D 28 93 05 0C 00 E8 00 00 00 00 04 0C 04 0C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 06 3E 03 7A 19 DC 48 49 13 0C 3E 0C E6 08 09 13 07 00 00 01 E4 29 93 6D 29 93 05 0C 00 E8 00 00 00 00 01 E4 01 E4 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 E8 00 00 00 1A 00 13 D2 0D 0A 13 1A 01 28 D2 0D 0A 13 21 00 2A D8 0D 0A 13 03 00 00 00 0E 2D D9 2D 0A 13 33 98 26 DE 0D 4A 13 00 16 01 26 DE 0D 4A 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5D 70" + ) + + val historyPage = RawHistoryPage(aapsLogger) + historyPage.appendData(historyPageData) + val pumpHistoryEntries: List = decoder.processPageAndCreateRecords(historyPage) + println("PumpHistoryEntries: " + pumpHistoryEntries.size) + Log.d("Test", "Log.d") + //LOGGER.debug("Logger.debug"); + for (pumpHistoryEntry in pumpHistoryEntries) { + Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()) + } + } + + @Throws(Exception::class) fun testRussel() { + val historyPageData = ByteUtil + .createByteArrayFromString( + "06 15 04 F6 00 40 60 01 05 06 36 04 FE 00 40 60 01 05 06 2F 18 1A 00 40 20 C1 05 06 2F 0C 45 00 40 20 C1 05 06 2F 0C 56 00 40 20 C1 05 06 2F 0C 78 00 40 20 C1 05 06 2F 0C AD 00 40 20 C1 05 06 15 04 BA 00 40 40 A1 05 0C 15 0E 40 00 01 05 64 00 0D 44 00 01 05 17 00 14 44 00 01 05 18 00 00 44 00 01 05 21 00 07 44 00 01 05 21 00 0C 4E 00 01 05 07 00 00 00 00 01 85 6D 01 85 06 08 00 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 03 00 00 00 15 00 67 35 02 05 03 00 03 00 03 1C 67 15 02 05 07 00 00 00 40 02 85 6D 02 85 06 08 00 2B 00 00 00 00 00 40 00 40 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 2C 78 39 5F 17 03 05 07 00 00 02 6C 03 85 6D 03 85 06 08 00 2B 00 00 00 00 02 6C 02 6C 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 2B 00 00 00 26 01 33 44 01 04 05 27 03 74 41 01 B2 07 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 74" + ) + val historyPage = RawHistoryPage(aapsLogger) + historyPage.appendData(historyPageData) + val pumpHistoryEntries: List = decoder.processPageAndCreateRecords(historyPage) + println("PumpHistoryEntries: " + pumpHistoryEntries.size) + Log.d("Test", "Log.d") + //LOGGER.debug("Logger.debug"); + for (pumpHistoryEntry in pumpHistoryEntries) { + Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()) + } + } + + // @Test + @Throws(Exception::class) fun testJRoth_2111() { + val historyPageData = ByteUtil + .createByteArrayFromString( + "01 03 03 00 8E 85 52 48 13 33 00 AB 89 12 48 13 00 16 00 AB 89 12 48 13 33 34 AD 89 12 48 13 00 16 01 AD 89 12 48 13 01 01 01 00 B8 8A 52 48 13 01 08 08 00 9F 8C 52 48 13 33 00 91 8F 12 48 13 00 16 00 91 8F 12 48 13 33 00 92 8F 12 48 13 00 16 03 92 8F 12 48 13 33 00 BA A7 12 48 13 00 16 04 BA A7 12 48 13 01 19 19 00 AF B0 52 48 13 33 00 8C 8A 13 48 13 00 16 04 8C 8A 13 48 13 33 00 9D A8 13 48 13 00 16 04 9D A8 13 48 13 33 00 AA 85 14 48 13 00 16 04 AA 85 14 48 13 33 00 8D A1 14 48 13 00 16 04 8D A1 14 48 13 33 10 89 BA 14 48 13 00 16 01 89 BA 14 48 13 33 00 AD 88 15 48 13 00 16 00 AD 88 15 48 13 33 00 AF 88 15 48 13 00 16 01 AF 88 15 48 13 01 1D 1D 00 95 8D 55 48 13 33 00 95 92 15 48 13 00 16 04 95 92 15 48 13 33 1E B7 9C 15 48 13 00 16 01 B7 9C 15 48 13 33 00 AA A6 15 48 13 00 16 00 AA A6 15 48 13 33 00 AC A6 15 48 13 00 16 04 AC A6 15 48 13 01 02 02 00 B7 A6 55 48 13 01 01 01 00 A6 AC 55 48 13 33 00 B3 8D 16 48 13 00 16 04 B3 8D 16 48 13 33 00 B7 97 16 48 13 00 16 04 B7 97 16 48 13 33 18 A7 B2 16 48 13 00 16 01 A7 B2 16 48 13 33 00 8B B8 16 48 13 00 16 00 8B B8 16 48 13 33 00 8D B8 16 48 13 00 16 03 8D B8 16 48 13 33 18 AE 85 17 48 13 00 16 01 AE 85 17 48 13 33 00 92 8A 17 48 13 00 16 00 92 8A 17 48 13 33 00 94 8A 17 48 13 00 16 01 94 8A 17 48 13 01 02 02 00 9F 8A 57 48 13 33 06 AC 8F 17 48 13 00 16 01 AC 8F 17 48 13 01 02 02 00 B8 8F 57 48 13 33 00 98 94 17 48 13 00 16 00 98 94 17 48 13 33 0C 9A 94 17 48 13 00 16 01 9A 94 17 48 13 01 02 02 00 A5 94 57 48 13 33 00 9C 99 17 48 13 00 16 00 9C 99 17 48 13 33 00 9E 99 17 48 13 00 16 01 9E 99 17 48 13 01 02 02 00 A9 99 57 48 13 01 02 02 00 84 9F 57 48 13 01 02 02 00 A7 A6 57 48 13 33 00 A4 AB 17 48 13 00 16 00 A4 AB 17 48 13 01 02 02 00 B0 AB 57 48 13 33 00 A7 B0 17 48 13 00 16 02 A7 B0 17 48 13 01 01 01 00 B2 B0 57 48 13 33 00 AD BA 17 48 13 00 16 04 AD BA 17 48 13 07 00 00 05 3A A8 13 6D A8 13 05 0C 00 E8 00 00 00 00 05 3A 00 F6 12 04 44 52 00 00 04 44 52 00 00 00 00 00 00 04 44 64 35 00 00 00 35 0C 00 E8 00 00 00 06 0A 1D 66 80 81 60 09 13 0C 0A 8D 82 00 09 13 1A 00 9A 82 00 09 13 1A 01 AF 82 00 09 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 28" + ) + val historyPage = RawHistoryPage(aapsLogger) + historyPage.appendData(historyPageData) + val pumpHistoryEntries: List = decoder.processPageAndCreateRecords(historyPage) + println("PumpHistoryEntries: " + pumpHistoryEntries.size) + Log.d("Test", "Log.d") + //LOGGER.debug("Logger.debug"); + for (pumpHistoryEntry in pumpHistoryEntries) { + Log.d("MedtronicHistoryDataUTest", pumpHistoryEntry.toString()) + } + } + + @Test @Throws(Exception::class) fun test_1724() { + val historyPageData = ByteUtil + .createByteArrayFromString( + "33 20 53 78 15 51 16 00 16 01 53 78 15 51 16 33 00 6F 40 16 51 16 00 16 00 6F 40 16 51 16 7B 16 6F 40 16 11 16 2C 1E 00 33 30 71 40 16 51 16 00 16 01 71 40 16 51 16 33 00 6E 45 16 51 16 00 16 00 6E 45 16 51 16 7B 16 6E 45 16 11 16 2C 1E 00 33 3A 70 45 16 51 16 00 16 01 70 45 16 51 16 33 00 71 5E 16 51 16 00 16 00 71 5E 16 51 16 7B 16 71 5E 16 11 16 2C 1E 00 33 40 73 5E 16 51 16 00 16 01 73 5E 16 51 16 33 00 74 6D 16 51 16 00 16 00 74 6D 16 51 16 7B 16 74 6D 16 11 16 2C 1E 00 33 14 76 6D 16 51 16 00 16 01 76 6D 16 51 16 33 00 77 72 16 51 16 00 16 00 77 72 16 51 16 7B 16 77 72 16 11 16 2C 1E 00 7B 17 40 40 17 11 16 2E 1E 00 33 28 51 41 17 51 16 00 16 01 51 41 17 51 16 33 00 56 46 17 51 16 00 16 00 56 46 17 51 16 7B 17 56 46 17 11 16 2E 1E 00 33 34 59 46 17 51 16 00 16 01 59 46 17 51 16 33 00 70 4A 17 51 16 00 16 00 70 4A 17 51 16 7B 17 70 4A 17 11 16 2E 1E 00 33 58 72 4A 17 51 16 00 16 01 72 4A 17 51 16 33 00 6E 59 17 51 16 00 16 00 6E 59 17 51 16 7B 17 6E 59 17 11 16 2E 1E 00 33 18 70 59 17 51 16 00 16 01 70 59 17 51 16 33 00 70 5E 17 51 16 00 16 00 70 5E 17 51 16 7B 17 70 5E 17 11 16 2E 1E 00 33 0C 72 5E 17 51 16 00 16 01 72 5E 17 51 16 33 00 72 63 17 51 16 00 16 00 72 63 17 51 16 7B 17 72 63 17 11 16 2E 1E 00 33 1C 70 72 17 51 16 00 16 01 70 72 17 51 16 33 00 51 78 17 51 16 00 16 00 51 78 17 51 16 7B 17 52 78 17 11 16 2E 1E 00 33 12 54 78 17 51 16 00 16 01 54 78 17 51 16 07 00 00 04 4E 51 96 00 00 00 6E 51 96 05 00 00 00 00 00 00 00 04 4E 03 A2 54 00 AC 10 00 00 00 00 00 00 00 00 00 AC 00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 33 00 46 46 00 52 16 00 16 00 46 46 00 52 16 7B 00 47 46 00 12 16 00 1E 00 33 20 47 64 00 52 16 00 16 01 47 64 00 52 16 33 00 6D 77 00 52 16 00 16 00 6D 77 00 52 16 7B 00 6D 77 00 12 16 00 1E 00 33 12 70 77 00 52 16 00 16 01 70 77 00 52 16 33 00 58 78 00 52 16 00 16 00 58 78 00 52 16 7B 00 59 78 00 12 16 00 1E 00 33 00 5C 78 00 52 16 00 16 02 5C 78 00 52 16 21 00 66 79 00 12 16 03 00 00 00 9C 74 42 21 12 16 03 00 03 00 03 6E 4D 01 12 16 33 00 79 4E 01 52 16 00 16 00 79 4E 01 52 16 7B 01 79 4E 01 12 16 02 1E 00 33 2A 6B 4F 01 52 16 00 16 01 6B 4F 01 52 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2E D1" + //"33 20 53 78 15 51 16 00 16 01 53 78 15 51 16 33 00 6F 40 16 51 16 00 16 00 6F 40 16 51 16 7B 16 6F 40 16 11 16 2C 1E 00 33 30 71 40 16 51 16 00 16 01 71 40 16 51 16 33 00 6E 45 + // 16 51 16 00 16 00 6E 45 16 51 16 7B 16 6E 45 16 11 16 2C 1E 00 33 3A 70 45 16 51 16 00 16 01 70 45 16 51 16 33 00 71 5E 16 51 16 00 16 00 71 5E 16 51 16 7B 16 71 5E 16 11 16 2C 1E 00 33 40 73 5E 16 51 16 00 16 01 73 5E 16 51 16 33 00 74 6D 16 51 16 00 16 00 74 6D 16 51 16 7B 16 74 6D 16 11 16 2C 1E 00 33 14 76 6D 16 51 16 00 16 01 76 6D 16 51 16 33 00 77 72 16 51 16 00 16 00 77 72 16 51 16 7B 16 77 72 16 11 16 2C 1E 00 7B 17 40 40 17 11 16 2E 1E 00 33 28 51 41 17 51 16 00 16 01 51 41 17 51 16 33 00 56 46 17 51 16 00 16 00 56 46 17 51 16 7B 17 56 46 17 11 16 2E 1E 00 33 34 59 46 17 51 16 00 16 01 59 46 17 51 16 33 00 70 4A 17 51 16 00 16 00 70 4A 17 51 16 7B 17 70 4A 17 11 16 2E 1E 00 33 58 72 4A 17 51 16 00 16 01 72 4A 17 51 16 33 00 6E 59 17 51 16 00 16 00 6E 59 17 51 16 7B 17 6E 59 17 11 16 2E 1E 00 33 18 70 59 17 51 16 00 16 01 70 59 17 51 16 33 00 70 5E 17 51 16 00 16 00 70 5E 17 51 16 7B 17 70 5E 17 11 16 2E 1E 00 33 0C 72 5E 17 51 16 00 16 01 72 5E 17 51 16 33 00 72 63 17 51 16 00 16 00 72 63 17 51 16 7B 17 72 63 17 11 16 2E 1E 00 33 1C 70 72 17 51 16 00 16 01 70 72 17 51 16 33 00 51 78 17 51 16 00 16 00 51 78 17 51 16 7B 17 52 78 17 11 16 2E 1E 00 33 12 54 78 17 51 16 00 16 01 54 78 17 51 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4D 6D" + ) + + medtronicUtil.medtronicPumpModel =MedtronicDeviceType.Medtronic_723_Revel + medtronicUtil.isModelSet = true + + val historyPage = RawHistoryPage(aapsLogger) + historyPage.appendData(historyPageData) + val pumpHistoryEntries: MutableList = decoder.processPageAndCreateRecords(historyPage) + println("PumpHistoryEntries: " + pumpHistoryEntries.size) + + val rewindRecords: MutableList = medtronicHistoryData.getFilteredItems(pumpHistoryEntries, PumpHistoryEntryType.Rewind) + + preProcessListTBR(pumpHistoryEntries) + + println("PumpHistoryEntries: after: " + pumpHistoryEntries.size) + + Log.d("Test", "Log.d") + //LOGGER.debug("Logger.debug"); + for (pumpHistoryEntry in pumpHistoryEntries) { + println(pumpHistoryEntry.toEntryString()) + } + + println("PumpHistoryEntries: after: " + pumpHistoryEntries.size) + + val tbrs: MutableList = medtronicHistoryData.getFilteredItems(pumpHistoryEntries, PumpHistoryEntryType.TempBasalCombined) + + tbrs.reverse() + + println("PumpHistoryEntries: getFilteredItems: " + tbrs.size) + + println("PumpHistoryEntries: getRewindItems: $rewindRecords.size : " + gson.toJson(rewindRecords) ) + + val processList: MutableList = medtronicHistoryData.createTBRProcessList(tbrs, rewindRecords) + + println("PumpHistoryEntries: processList: " + processList.size) + + for (tempBasalProcessDTO in processList) { + println(tempBasalProcessDTO.toTreatmentString()) + } + + } +} \ No newline at end of file diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt index 14d3a7e1b2..9b0a05ebf9 100644 --- a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt +++ b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoderUTest.kt @@ -1,8 +1,7 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump -import dagger.android.HasAndroidInjector +//import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBase -import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil @@ -10,13 +9,11 @@ import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RawHistory import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.TestAapsSchedulers -import info.nightscout.shared.sharedPreferences.SP import org.junit.Assert import org.junit.Before +import org.junit.Ignore import org.junit.Test -import org.mockito.Answers import org.mockito.Mock /** @@ -25,16 +22,17 @@ import org.mockito.Mock @Suppress("SpellCheckingInspection") class MedtronicPumpHistoryDecoderUTest : TestBase() { - @Mock lateinit var injector: HasAndroidInjector - @Mock lateinit var rh: ResourceHelper - @Mock(answer = Answers.RETURNS_DEEP_STUBS) lateinit var activePlugin: ActivePlugin - @Mock lateinit var rileyLinkUtil: RileyLinkUtil - @Mock lateinit var sp: SP + //@Mock lateinit var injector: HasAndroidInjector + //@Mock lateinit var rh: ResourceHelper +// @Mock(answer = Answers.RETURNS_DEEP_STUBS) lateinit var activePlugin: ActivePlugin + //@Mock lateinit var rileyLinkUtil: RileyLinkUtil + //@Mock lateinit var sp: SP private var medtronicPumpStatus: MedtronicPumpStatus? = null - private var medtronicUtil: MedtronicUtil? = null - private var decoder: MedtronicPumpHistoryDecoder? = null + //private var medtronicUtil: MedtronicUtil? = null + //private var decoder: MedtronicPumpHistoryDecoder? = null var rxBusWrapper = RxBus(TestAapsSchedulers(), aapsLogger) + @Before fun setup() { medtronicPumpStatus = MedtronicPumpStatus(rh, sp, rxBusWrapper, rileyLinkUtil) diff --git a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt index fb14af8230..a985f6d615 100644 --- a/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt +++ b/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryDataUTest.kt @@ -4,8 +4,8 @@ import java.lang.reflect.Type import com.google.gson.reflect.TypeToken import com.google.gson.Gson import com.google.gson.internal.LinkedTreeMap -import dagger.android.AndroidInjector -import dagger.android.HasAndroidInjector +// import dagger.android.AndroidInjector +// import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.PumpSync @@ -18,34 +18,50 @@ import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpSta import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP +import org.junit.Before +import org.junit.Ignore import org.junit.Test import org.mockito.Mock +@Suppress("UNCHECKED_CAST") class MedtronicHistoryDataUTest : TestBase() { - @Mock lateinit var activePlugin: ActivePlugin - @Mock lateinit var medtronicUtil: MedtronicUtil - @Mock lateinit var medtronicPumpHistoryDecoder: MedtronicPumpHistoryDecoder + //@Mock lateinit var activePlugin: ActivePlugin + //@Mock lateinit var medtronicUtil: MedtronicUtil + //@Mock lateinit var medtronicPumpHistoryDecoder: MedtronicPumpHistoryDecoder @Mock lateinit var medtronicPumpStatus: MedtronicPumpStatus - @Mock lateinit var pumpSync: PumpSync - @Mock lateinit var pumpSyncStorage: PumpSyncStorage - @Mock lateinit var sp: SP - @Mock lateinit var rh: ResourceHelper - @Mock lateinit var rxBus: RxBus + // @Mock lateinit var pumpSync: PumpSync + // @Mock lateinit var pumpSyncStorage: PumpSyncStorage - private val packetInjector = HasAndroidInjector { - AndroidInjector { + //@Mock lateinit var rxBus: RxBus - } + // val packetInjector = HasAndroidInjector { + // AndroidInjector { + // + // } + // } + + @Before + fun setUp() { + medtronicUtil = MedtronicUtil( + aapsLogger, rxBus, rileyLinkUtil, + medtronicPumpStatus + ) + + decoder = MedtronicPumpHistoryDecoder( + aapsLogger, + medtronicUtil, byteUtil + ) } + @Test fun createTBRProcessList() { var unitToTest = MedtronicHistoryData(packetInjector, aapsLogger, sp, rh, rxBus, activePlugin, - medtronicUtil, medtronicPumpHistoryDecoder, + medtronicUtil, decoder, medtronicPumpStatus, pumpSync, pumpSyncStorage) @@ -72,7 +88,7 @@ class MedtronicHistoryDataUTest : TestBase() { System.out.println("TBR Pre-Process List: " + gson.toJson(yourClassList)) - val createTBRProcessList = unitToTest.createTBRProcessList(yourClassList) + val createTBRProcessList = unitToTest.createTBRProcessList(yourClassList, mutableListOf()) System.out.println("TBR Process List: " + createTBRProcessList.size) @@ -86,7 +102,7 @@ class MedtronicHistoryDataUTest : TestBase() { fun createTBRProcessList_SpecialCase() { var unitToTest = MedtronicHistoryData(packetInjector, aapsLogger, sp, rh, rxBus, activePlugin, - medtronicUtil, medtronicPumpHistoryDecoder, + medtronicUtil, decoder, medtronicPumpStatus, pumpSync, pumpSyncStorage) @@ -113,7 +129,7 @@ class MedtronicHistoryDataUTest : TestBase() { System.out.println("TBR Pre-Process List (Special): " + gson.toJson(yourClassList)) - val createTBRProcessList = unitToTest.createTBRProcessList(yourClassList) + val createTBRProcessList = unitToTest.createTBRProcessList(yourClassList, mutableListOf()) System.out.println("TBR Process List (Special): " + createTBRProcessList.size) diff --git a/medtronic/src/test/resources/tbr_1724.json b/medtronic/src/test/resources/tbr_1724.json new file mode 100644 index 0000000000..79c6bc320c --- /dev/null +++ b/medtronic/src/test/resources/tbr_1724.json @@ -0,0 +1 @@ +33 20 53 78 15 51 16 00 16 01 53 78 15 51 16 33 00 6F 40 16 51 16 00 16 00 6F 40 16 51 16 7B 16 6F 40 16 11 16 2C 1E 00 33 30 71 40 16 51 16 00 16 01 71 40 16 51 16 33 00 6E 45 16 51 16 00 16 00 6E 45 16 51 16 7B 16 6E 45 16 11 16 2C 1E 00 33 3A 70 45 16 51 16 00 16 01 70 45 16 51 16 33 00 71 5E 16 51 16 00 16 00 71 5E 16 51 16 7B 16 71 5E 16 11 16 2C 1E 00 33 40 73 5E 16 51 16 00 16 01 73 5E 16 51 16 33 00 74 6D 16 51 16 00 16 00 74 6D 16 51 16 7B 16 74 6D 16 11 16 2C 1E 00 33 14 76 6D 16 51 16 00 16 01 76 6D 16 51 16 33 00 77 72 16 51 16 00 16 00 77 72 16 51 16 7B 16 77 72 16 11 16 2C 1E 00 7B 17 40 40 17 11 16 2E 1E 00 33 28 51 41 17 51 16 00 16 01 51 41 17 51 16 33 00 56 46 17 51 16 00 16 00 56 46 17 51 16 7B 17 56 46 17 11 16 2E 1E 00 33 34 59 46 17 51 16 00 16 01 59 46 17 51 16 33 00 70 4A 17 51 16 00 16 00 70 4A 17 51 16 7B 17 70 4A 17 11 16 2E 1E 00 33 58 72 4A 17 51 16 00 16 01 72 4A 17 51 16 33 00 6E 59 17 51 16 00 16 00 6E 59 17 51 16 7B 17 6E 59 17 11 16 2E 1E 00 33 18 70 59 17 51 16 00 16 01 70 59 17 51 16 33 00 70 5E 17 51 16 00 16 00 70 5E 17 51 16 7B 17 70 5E 17 11 16 2E 1E 00 33 0C 72 5E 17 51 16 00 16 01 72 5E 17 51 16 33 00 72 63 17 51 16 00 16 00 72 63 17 51 16 7B 17 72 63 17 11 16 2E 1E 00 33 1C 70 72 17 51 16 00 16 01 70 72 17 51 16 33 00 51 78 17 51 16 00 16 00 51 78 17 51 16 7B 17 52 78 17 11 16 2E 1E 00 33 12 54 78 17 51 16 00 16 01 54 78 17 51 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4D 6D \ No newline at end of file diff --git a/omnipod-common/build.gradle b/omnipod-common/build.gradle index 5a2e5bfac4..3d4aab407b 100644 --- a/omnipod-common/build.gradle +++ b/omnipod-common/build.gradle @@ -9,6 +9,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.plugins.pump.omnipod.common' +} dependencies { implementation project(':core') diff --git a/omnipod-common/src/main/AndroidManifest.xml b/omnipod-common/src/main/AndroidManifest.xml index 5f59d2c48f..9d6e11f691 100644 --- a/omnipod-common/src/main/AndroidManifest.xml +++ b/omnipod-common/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + diff --git a/omnipod-dash/build.gradle b/omnipod-dash/build.gradle index c6c5734f70..631dec2207 100644 --- a/omnipod-dash/build.gradle +++ b/omnipod-dash/build.gradle @@ -17,6 +17,8 @@ detekt { // TODO move to `subprojects` section in global build.gradle } android { + + namespace 'info.nightscout.androidaps.plugins.pump.omnipod.dash' defaultConfig { kapt { arguments { diff --git a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt b/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt index fdb073b3c4..e5b309d398 100644 --- a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt +++ b/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt @@ -10,7 +10,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.Das import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordDao import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper.HistoryMapper import info.nightscout.shared.logging.AAPSLoggerTest -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxjava3.schedulers.Schedulers import org.junit.After import org.junit.Before import org.junit.Rule @@ -44,9 +44,9 @@ class DashHistoryTest { assertValue { it.isEmpty() } } - dashHistory.createRecord(commandType = OmnipodCommandType.CANCEL_BOLUS, 0L).test().apply { - assertValue { ULID.isValid(it) } - } + // dashHistory.createRecord(commandType = OmnipodCommandType.CANCEL_BOLUS, 0L).test().apply { + // assertValue { ULID.isValid(it) } + // } dashHistory.getRecords().test().apply { assertValue { it.size == 1 } diff --git a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt b/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt index a649da837d..4ac697c88e 100644 --- a/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt +++ b/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/RxSchedulerRule.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.history -import io.reactivex.Scheduler -import io.reactivex.android.plugins.RxAndroidPlugins -import io.reactivex.plugins.RxJavaPlugins +import io.reactivex.rxjava3.android.plugins.RxAndroidPlugins +import io.reactivex.rxjava3.core.Scheduler +import io.reactivex.rxjava3.plugins.RxJavaPlugins import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement diff --git a/omnipod-dash/src/main/AndroidManifest.xml b/omnipod-dash/src/main/AndroidManifest.xml index 68a2f71c0b..0408c54440 100644 --- a/omnipod-dash/src/main/AndroidManifest.xml +++ b/omnipod-dash/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + @@ -8,11 +7,18 @@ - - - - - + + + + + \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt index 3b8f32c426..49e03984fe 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt @@ -39,7 +39,7 @@ import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.interfaces.BuildHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.ui.UIRunnable diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt index d51e841cd8..0a9862d027 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt @@ -16,7 +16,6 @@ class MessagePacketTest { ) @Test fun testParseMessagePacket() { - val aapsLogger = AAPSLoggerTest() val msg = MessagePacket.parse(Hex.decode(payload)) assertEquals(msg.type, MessageType.ENCRYPTED) assertEquals(msg.source, Id.fromLong(136326824)) diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt index 74ed773246..92daeed0b4 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommandTest.kt @@ -8,6 +8,7 @@ import org.junit.Assert import org.junit.Test import java.util.* +@Suppress("DEPRECATION") class ProgramBasalCommandTest { @Test @Throws(DecoderException::class) fun testProgramBasalCommand() { diff --git a/omnipod-eros/build.gradle b/omnipod-eros/build.gradle index 9bc119cef9..a748715b9d 100644 --- a/omnipod-eros/build.gradle +++ b/omnipod-eros/build.gradle @@ -10,6 +10,8 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" android { + + namespace 'info.nightscout.androidaps.plugins.pump.omnipod.eros' defaultConfig { kapt { arguments { diff --git a/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt b/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt index 29a44e961d..864050ecc7 100644 --- a/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt +++ b/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt @@ -44,11 +44,11 @@ class ErosHistoryTest { history = erosHistory.getAllErosHistoryRecordsFromTimestamp(0L) assert(history.size == 2) - assert(type.equals(history.first().podEntryTypeCode)) + assert(type == history.first().podEntryTypeCode) val returnedEntity = erosHistory.findErosHistoryRecordByPumpId(entity.pumpId) assertNotNull(returnedEntity) - assert(type.equals(returnedEntity.podEntryTypeCode)) + assert(type == returnedEntity?.podEntryTypeCode) } @After diff --git a/omnipod-eros/src/main/AndroidManifest.xml b/omnipod-eros/src/main/AndroidManifest.xml index 68957b8696..b036e15038 100644 --- a/omnipod-eros/src/main/AndroidManifest.xml +++ b/omnipod-eros/src/main/AndroidManifest.xml @@ -1,16 +1,22 @@ - + - + - - - - + + + + \ No newline at end of file diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java index 4483eab747..402d836bb3 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java @@ -705,7 +705,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley } if (tbrCurrent != null && !enforceNew) { - if (Round.isSame(tbrCurrent.getRate(), absoluteRate)) { + if (Round.INSTANCE.isSame(tbrCurrent.getRate(), absoluteRate)) { aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - No enforceNew and same rate. Exiting."); return new PumpEnactResult(getInjector()).success(true).enacted(false); } diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java index 5fda76dbd8..96569f6ffc 100644 --- a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java +++ b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/defs/schedule/BasalTableEntryTest.java @@ -1,11 +1,11 @@ package info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.communication.message.defs.schedule; +import static org.junit.Assert.assertEquals; + import org.junit.Test; import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.schedule.BasalTableEntry; -import static junit.framework.Assert.assertEquals; - public class BasalTableEntryTest { @Test public void testChecksum() { diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java index 388deb09a8..df85b00d83 100644 --- a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java +++ b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/driver/communication/message/response/podinfo/PodInfoResponseTest.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.communication.message.response.podinfo; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -12,9 +13,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; public class PodInfoResponseTest { - @Rule - public ExpectedException thrown = ExpectedException.none(); - @Test public void testRawData() { byte[] encodedData = ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d"); @@ -51,7 +49,8 @@ public class PodInfoResponseTest { assertEquals(PodInfoType.DETAILED_STATUS, podInfoResponse.getSubType()); - thrown.expect(ClassCastException.class); - PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo(); + Assert.assertThrows("Expect throw", ClassCastException.class, () -> { + PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo(); + }); } } diff --git a/openhumans/build.gradle b/openhumans/build.gradle index 79564845d5..ead419045a 100644 --- a/openhumans/build.gradle +++ b/openhumans/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.plugin.general.openhumans' +} dependencies { diff --git a/openhumans/src/main/AndroidManifest.xml b/openhumans/src/main/AndroidManifest.xml index ed6ea8dc06..11cb7d1764 100644 --- a/openhumans/src/main/AndroidManifest.xml +++ b/openhumans/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + - + + Kanselleer + Maak toe + diff --git a/openhumans/src/main/res/values-bg-rBG/strings.xml b/openhumans/src/main/res/values-bg-rBG/strings.xml index 80e2ef9000..6aee856ee4 100644 --- a/openhumans/src/main/res/values-bg-rBG/strings.xml +++ b/openhumans/src/main/res/values-bg-rBG/strings.xml @@ -16,4 +16,7 @@ Излязохте от \"Open Humans\". Натиснете тук за да влезете отново, ако това не е било нарочно. Качи сега + Условия за ползване + Откажи + Затвори diff --git a/openhumans/src/main/res/values-ca-rES/strings.xml b/openhumans/src/main/res/values-ca-rES/strings.xml index 9868d0e25d..7eac6702e2 100644 --- a/openhumans/src/main/res/values-ca-rES/strings.xml +++ b/openhumans/src/main/res/values-ca-rES/strings.xml @@ -7,4 +7,7 @@ Enviar només si carregant Heu tancat la sessió amb Open Humans Cliqueu aquí si no era la intenció. + Condicions d\'ús + Cancel·lar + Tancar diff --git a/openhumans/src/main/res/values-da-rDK/strings.xml b/openhumans/src/main/res/values-da-rDK/strings.xml index e58df734fe..dd505c8935 100644 --- a/openhumans/src/main/res/values-da-rDK/strings.xml +++ b/openhumans/src/main/res/values-da-rDK/strings.xml @@ -16,4 +16,6 @@ Du er blevet logget ud af Open Humans Klik her for at logge ind igen, hvis dette ikke var meningen. Upload nu + Annuller + Luk diff --git a/openhumans/src/main/res/values-de-rDE/strings.xml b/openhumans/src/main/res/values-de-rDE/strings.xml index f31bb0cf22..19a6178baa 100644 --- a/openhumans/src/main/res/values-de-rDE/strings.xml +++ b/openhumans/src/main/res/values-de-rDE/strings.xml @@ -16,4 +16,7 @@ Du wurdest von Open Humans abgemeldet. Klicke hier, um Dich erneut anzumelden, falls dies versehentlich passiert ist. Jetzt hochladen + Nutzungsbedingungen + Abbrechen + Schließen diff --git a/openhumans/src/main/res/values-el-rGR/strings.xml b/openhumans/src/main/res/values-el-rGR/strings.xml index 3ea04e700d..e963aa86ba 100644 --- a/openhumans/src/main/res/values-el-rGR/strings.xml +++ b/openhumans/src/main/res/values-el-rGR/strings.xml @@ -1,2 +1,5 @@ - + + Ακύρωση + Κλείσιμο + diff --git a/openhumans/src/main/res/values-fr-rFR/strings.xml b/openhumans/src/main/res/values-fr-rFR/strings.xml index a2945acfc4..b200c1e685 100644 --- a/openhumans/src/main/res/values-fr-rFR/strings.xml +++ b/openhumans/src/main/res/values-fr-rFR/strings.xml @@ -45,4 +45,13 @@ Champs de texte libre Je comprends et je suis d\'accord. Téléchargement vers Open Humans + Touche finale + Vous n\'êtes qu\'à une étape du téléchargement de vos données vers Open Humans. Voulez-vous continuer? + Annuler + Procéder + Finalisation... + Cela peut prendre quelques secondes. + Nous avons terminé ! + Désormais, votre téléphone téléversera les données en arrière-plan de temps en temps. + Fermer diff --git a/openhumans/src/main/res/values-ga-rIE/strings.xml b/openhumans/src/main/res/values-ga-rIE/strings.xml index 3ea04e700d..d1e993eb08 100644 --- a/openhumans/src/main/res/values-ga-rIE/strings.xml +++ b/openhumans/src/main/res/values-ga-rIE/strings.xml @@ -1,2 +1,5 @@ - + + Cuir ar ceal + Dún + diff --git a/openhumans/src/main/res/values-ko-rKR/strings.xml b/openhumans/src/main/res/values-ko-rKR/strings.xml index 969971395d..5be117d4e8 100644 --- a/openhumans/src/main/res/values-ko-rKR/strings.xml +++ b/openhumans/src/main/res/values-ko-rKR/strings.xml @@ -16,4 +16,7 @@ Open Humans에 접속 종료되었습니다. 의도한 것이 아닌 경우 \"여기\"를 클릭하여 다시 접속하십시오. 지금 업로드하기 + 이용 약관 + 취소 + 닫기 diff --git a/openhumans/src/main/res/values-lt-rLT/strings.xml b/openhumans/src/main/res/values-lt-rLT/strings.xml index 202491c0c3..59d9291c26 100644 --- a/openhumans/src/main/res/values-lt-rLT/strings.xml +++ b/openhumans/src/main/res/values-lt-rLT/strings.xml @@ -16,4 +16,7 @@ Jūs buvote atjungtas iš Open Humans Spustelėkite čia, kad prisijungtumėte dar kartą, jei tai atsitiko netyčia. Įkelti dabar + Naudojimosi sąlygos + Atšaukti + Uždaryti diff --git a/openhumans/src/main/res/values-pl-rPL/strings.xml b/openhumans/src/main/res/values-pl-rPL/strings.xml index 0138f625ca..09615b828e 100644 --- a/openhumans/src/main/res/values-pl-rPL/strings.xml +++ b/openhumans/src/main/res/values-pl-rPL/strings.xml @@ -16,4 +16,7 @@ Zostałeś wylogowany z Open Humans Kliknij tutaj, aby zalogować się ponownie, jeśli wylogowanie nie było celowe. Prześlij teraz + Warunki użytkowania + Anuluj + Zamknij diff --git a/openhumans/src/main/res/values-pt-rBR/strings.xml b/openhumans/src/main/res/values-pt-rBR/strings.xml index 3ea04e700d..604c5d915b 100644 --- a/openhumans/src/main/res/values-pt-rBR/strings.xml +++ b/openhumans/src/main/res/values-pt-rBR/strings.xml @@ -1,2 +1,5 @@ - + + Cancelar + Fechar + diff --git a/openhumans/src/main/res/values-pt-rPT/strings.xml b/openhumans/src/main/res/values-pt-rPT/strings.xml index 778e45ca27..03076d75a5 100644 --- a/openhumans/src/main/res/values-pt-rPT/strings.xml +++ b/openhumans/src/main/res/values-pt-rPT/strings.xml @@ -16,4 +16,7 @@ Sessão do Open Humans foi encerrada Clique aqui para entrar novamente, se não foi de propósito. Fazer o upload agora + Termos de Utilização + Cancelar + Fechar diff --git a/openhumans/src/main/res/values-ro-rRO/strings.xml b/openhumans/src/main/res/values-ro-rRO/strings.xml index 0f1261b783..47f2c88863 100644 --- a/openhumans/src/main/res/values-ro-rRO/strings.xml +++ b/openhumans/src/main/res/values-ro-rRO/strings.xml @@ -16,4 +16,7 @@ Ai fost deconectat de la Open Humans Dați click aici pentru a vă conecta din nou, dacă a fost din greșeală. Încarcă acum + Condiții de utilizare + Renunță + Închide diff --git a/openhumans/src/main/res/values-ru-rRU/strings.xml b/openhumans/src/main/res/values-ru-rRU/strings.xml index 8827371bc6..2d277cae07 100644 --- a/openhumans/src/main/res/values-ru-rRU/strings.xml +++ b/openhumans/src/main/res/values-ru-rRU/strings.xml @@ -16,4 +16,42 @@ Вы вышли из Open Humans Нажмите здесь, чтобы снова войти в систему, если выход произошел случайно. Начать передачу данных + Далее + Добро пожаловать в Open Humans + Для настройки загрузки данных нажмите \'Далее\'. + Согласие + Условия пользования + Внимательно ознакомьтесь со следующей информацией и примите условия использования. + Это проект с открытым исходным кодом, который будет копировать ваши данные на Open Humans. Мы не будем обмениваться вашими данными с третьими лицами без вашего явного разрешения. Данные, отправляемые на проект и приложение, идентифицируются с помощью случайного идентификатора и будут безопасно передаваться на учетную запись Open Humans при вашем одобрении этого процесса. Вы можете остановить загрузку и удалить загруженные данные в любое время здесь: www.openhumans.org. + Данные загружены + Гликемия + Болюсы + Пролонгированные болюсы + Углеводы + События портала терапии (кроме примечаний) + Переключения профиля + Суммарные суточные дозы + Временные базальные скорости + Временные целевые значения + Настройки + Версия приложения + Модель устройства + Размеры экрана + Данные отладки алгоритма + Данные НЕ загружены + Пароли + URL-адрес Nightscout + Секретный ключ Nightscout API + Поля свободного текста + Я понимаю и соглашаюсь. + Войти в Open Humans + Финальные настройки + Вы в одном шаге от передачи данных в Open Humans. Продолжить? + Отменить + Продолжить + Завершение... + Может занять несколько секунд. + Готово! + С этого момента ваш телефон будет иногда загружать данные в фоновом режиме. + Закрыть diff --git a/openhumans/src/main/res/values-sv-rSE/strings.xml b/openhumans/src/main/res/values-sv-rSE/strings.xml index 039bd031f8..0323a8edd8 100644 --- a/openhumans/src/main/res/values-sv-rSE/strings.xml +++ b/openhumans/src/main/res/values-sv-rSE/strings.xml @@ -16,4 +16,7 @@ Du har loggats ut från Open Humans Klicka här om du vill logga in igen. Ladda upp nu + Användarvillkor + Avbryt + Stäng diff --git a/openhumans/src/main/res/values-zh-rCN/strings.xml b/openhumans/src/main/res/values-zh-rCN/strings.xml index 18a0cfd7e9..ad03708d8d 100644 --- a/openhumans/src/main/res/values-zh-rCN/strings.xml +++ b/openhumans/src/main/res/values-zh-rCN/strings.xml @@ -16,4 +16,36 @@ 你已经从开源人类项目中退出 如果不是故意的,请单击此处再次登录。 现在上传 + 下一个 + 欢迎使用 Open Humans + 要设置数据上传,请单击“下一步” + 同意 + 使用条款 + 请仔细阅读以下信息并接受使用条款以继续 + 上传数据 + 血糖值 + 大剂量 + 扩展大剂量(方波) + 碳水化合物 + 切换配置文件 + 每日总剂量 + 临时基础率 + 临时目标 + 设置 + 应用程序版本 + 设备型号 + 屏幕尺寸 + 算法调试数据 + 数据未上传 + 密码 + Nightscout URL(NS网址) + Nightscout API密钥 + 空闲文本字段 + 我理解并同意 + 登陆到Open Humans + 取消 + 继续 + 正在完成... + 成功完成! + 关闭 diff --git a/pump-common/build.gradle b/pump-common/build.gradle index 7f0a8b7757..b1802ccb8b 100644 --- a/pump-common/build.gradle +++ b/pump-common/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.plugins.pump.common' +} dependencies { implementation project(':core') diff --git a/pump-common/src/main/AndroidManifest.xml b/pump-common/src/main/AndroidManifest.xml index d4055a4210..b935efb489 100644 --- a/pump-common/src/main/AndroidManifest.xml +++ b/pump-common/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - + diff --git a/rileylink/build.gradle b/rileylink/build.gradle index 0647e1d938..24ac3125e8 100644 --- a/rileylink/build.gradle +++ b/rileylink/build.gradle @@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" +android { + namespace 'info.nightscout.androidaps.plugins.pump.common.hw.rileylink' +} dependencies { implementation project(':core') diff --git a/rileylink/src/main/AndroidManifest.xml b/rileylink/src/main/AndroidManifest.xml index 2efb9aa635..684a90fcf6 100644 --- a/rileylink/src/main/AndroidManifest.xml +++ b/rileylink/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + @@ -13,9 +12,10 @@ - + @@ -24,8 +24,9 @@ + android:exported="false" + android:label="@string/title_activity_rileylink_settings" + android:theme="@style/AppTheme" /> diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java index 5ca477f8e2..1837bfce2e 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkCommunicationManager.java @@ -200,7 +200,7 @@ public abstract class RileyLinkCommunicationManager { double[] scanFrequencies = rileyLinkServiceData.rileyLinkTargetFrequency.getScanFrequencies(); if (scanFrequencies.length == 1) { - return Round.isSame(scanFrequencies[0], frequency); + return Round.INSTANCE.isSame(scanFrequencies[0], frequency); } else { return (scanFrequencies[0] <= frequency && scanFrequencies[scanFrequencies.length - 1] >= frequency); } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.java index 3d25089463..703cd1c211 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.java @@ -103,7 +103,8 @@ public class InitializePumpManagerTask extends ServiceTask { } } else { - if (!Round.isSame(lastGoodFrequency, RileyLinkTargetFrequency.Omnipod.getScanFrequencies()[0])) { + if (!Round.INSTANCE.isSame(lastGoodFrequency, + RileyLinkTargetFrequency.Omnipod.getScanFrequencies()[0])) { lastGoodFrequency = RileyLinkTargetFrequency.Omnipod.getScanFrequencies()[0]; lastGoodFrequency = Math.round(lastGoodFrequency * 1000d) / 1000d; diff --git a/shared/build.gradle b/shared/build.gradle index 381cfdc40e..3a6a62902e 100644 --- a/shared/build.gradle +++ b/shared/build.gradle @@ -11,6 +11,8 @@ apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle" android { + + namespace 'info.nightscout.shared' defaultConfig { minSdkVersion 23 // for wear } diff --git a/shared/src/main/AndroidManifest.xml b/shared/src/main/AndroidManifest.xml index c299e9eece..a5918e68ab 100644 --- a/shared/src/main/AndroidManifest.xml +++ b/shared/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + \ No newline at end of file diff --git a/shared/src/main/java/info/nightscout/shared/SafeParse.kt b/shared/src/main/java/info/nightscout/shared/SafeParse.kt index 1c415b858b..badcc231d6 100644 --- a/shared/src/main/java/info/nightscout/shared/SafeParse.kt +++ b/shared/src/main/java/info/nightscout/shared/SafeParse.kt @@ -1,12 +1,9 @@ package info.nightscout.shared -import java.lang.Exception - object SafeParse { - // TODO return logging with dagger // private static Logger log = StacktraceLoggerWrapper.getLogger(SafeParse.class); - @JvmStatic fun stringToDouble(inputString: String?): Double { + fun stringToDouble(inputString: String?): Double { var input = inputString ?: return 0.0 var result = 0.0 input = input.replace(",", ".") @@ -20,7 +17,7 @@ object SafeParse { return result } - @JvmStatic fun stringToFloat(inputString: String?): Float { + fun stringToFloat(inputString: String?): Float { var input = inputString ?: return 0f var result = 0f input = input.replace(",", ".") @@ -34,7 +31,7 @@ object SafeParse { return result } - @JvmStatic fun stringToInt(inputString: String?): Int { + fun stringToInt(inputString: String?): Int { var input = inputString ?: return 0 var result = 0 input = input.replace(",", ".") diff --git a/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt b/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt index fb65329df6..2301a3f008 100644 --- a/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt +++ b/shared/src/main/java/info/nightscout/shared/logging/StacktraceLoggerWrapper.kt @@ -32,7 +32,7 @@ class StacktraceLoggerWrapper(private val delegate: Logger) : Logger by delegate // all other methods will be implemented by delegate companion object { - @JvmStatic + @Deprecated("please inject AAPSLogger") fun getLogger(clazz: Class<*>) = StacktraceLoggerWrapper(LoggerFactory.getLogger(clazz)) } diff --git a/shared/src/main/res/values-af-rZA/strings.xml b/shared/src/main/res/values-af-rZA/strings.xml new file mode 100644 index 0000000000..875daa124a --- /dev/null +++ b/shared/src/main/res/values-af-rZA/strings.xml @@ -0,0 +1,19 @@ + + + + h + dae + ure + sekonde + minuut + uur + dag + week + sekondes + minute + ure + dae + weke + m + d + diff --git a/shared/src/main/res/values-bg-rBG/strings.xml b/shared/src/main/res/values-bg-rBG/strings.xml new file mode 100644 index 0000000000..56da387b4b --- /dev/null +++ b/shared/src/main/res/values-bg-rBG/strings.xml @@ -0,0 +1,21 @@ + + + + преди %1$d мин + преди %1$.1fч + ч. + дни + часа + секунда + минута + час + ден + седмица + секунди + минути + часове + дни + седмици + мин. + д + diff --git a/shared/src/main/res/values-ca-rES/strings.xml b/shared/src/main/res/values-ca-rES/strings.xml new file mode 100644 index 0000000000..9735814c77 --- /dev/null +++ b/shared/src/main/res/values-ca-rES/strings.xml @@ -0,0 +1,21 @@ + + + + Fa %1$d m + Fa %1$.1f h + h + dies + hores + segon + minut + hora + dia + setmana + segons + minuts + hores + dies + setmanes + m + d + diff --git a/shared/src/main/res/values-cs-rCZ/strings.xml b/shared/src/main/res/values-cs-rCZ/strings.xml new file mode 100644 index 0000000000..a05fa45757 --- /dev/null +++ b/shared/src/main/res/values-cs-rCZ/strings.xml @@ -0,0 +1,30 @@ + + + + před %1$d min + před %1$d minutamí + před %1$.1f h + Před %1$.1f dny + Před %1$.0f dny + za %1$.0f dní + za %1$.0f dní + h + dnů + hodin + sekund + minut + hodina + den + týden + sekund + minut + hodin + dní + týdnů + m + d + Později během dneška + Zítra + Dnes + Včera + diff --git a/shared/src/main/res/values-da-rDK/strings.xml b/shared/src/main/res/values-da-rDK/strings.xml new file mode 100644 index 0000000000..d46c0c97a2 --- /dev/null +++ b/shared/src/main/res/values-da-rDK/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d min. siden + %1$d minutter siden + %1$.1f t siden + %1$.1f dage siden + %1$.0f dage siden + om %1$.0f dage + om %1$.0f dage + t + dage + timer + sekund + minut + time + dag + uge + sekunder + minutter + timer + dage + uger + min + d + Senere i dag + I morgen + I dag + I går + diff --git a/shared/src/main/res/values-de-rDE/strings.xml b/shared/src/main/res/values-de-rDE/strings.xml new file mode 100644 index 0000000000..8c95db789a --- /dev/null +++ b/shared/src/main/res/values-de-rDE/strings.xml @@ -0,0 +1,22 @@ + + + + vor %1$d Min. + vor %1$d Minuten + vor %1$.1f Stunde + Std + Tage + Stunden + Sekunde + Minute + Stunde + Tag + Woche + Sekunden + Minuten + Stunden + Tage + Wochen + min + d + diff --git a/shared/src/main/res/values-el-rGR/strings.xml b/shared/src/main/res/values-el-rGR/strings.xml new file mode 100644 index 0000000000..960d69de0d --- /dev/null +++ b/shared/src/main/res/values-el-rGR/strings.xml @@ -0,0 +1,18 @@ + + + + h + ημέρες + ώρες + δευτερόλεπτο + λεπτό + ώρα + ημέρα + εβδομάδα + δευτερόλεπτα + λεπτά + ώρες + ημέρες + εβδομάδες + m + diff --git a/shared/src/main/res/values-es-rES/strings.xml b/shared/src/main/res/values-es-rES/strings.xml new file mode 100644 index 0000000000..a0f0767587 --- /dev/null +++ b/shared/src/main/res/values-es-rES/strings.xml @@ -0,0 +1,30 @@ + + + + hace %1$d m + Hace %1$d minutos + hace %1$.1f h + Hace %1$.1f día + Hace %1$.0f días + en %1$.0f días + en %1$.0f días + h + días + horas + segundo + minuto + hora + día + semana + segundos + minutos + horas + días + semanas + m + d + Más tarde hoy + Mañana + Hoy + Ayer + diff --git a/shared/src/main/res/values-fr-rFR/strings.xml b/shared/src/main/res/values-fr-rFR/strings.xml new file mode 100644 index 0000000000..67db8a5129 --- /dev/null +++ b/shared/src/main/res/values-fr-rFR/strings.xml @@ -0,0 +1,30 @@ + + + + il y a %1$d m + Il y a %1$d minutes + il y a %1$.1f h + Il y a %1$.1f jours + Il y a %1$.0f jours + en %1$.0f jours + en %1$.0f jours + h + jours + heures + seconde + minute + heure + jour + semaine + secondes + minutes + heures + jours + semaines + m + j + Plus tard aujourd\'hui + Demain + Aujourd’hui + Hier + diff --git a/shared/src/main/res/values-ga-rIE/strings.xml b/shared/src/main/res/values-ga-rIE/strings.xml new file mode 100644 index 0000000000..8d4df752e5 --- /dev/null +++ b/shared/src/main/res/values-ga-rIE/strings.xml @@ -0,0 +1,21 @@ + + + + %1$d nóim ó shin + %1$.1f u ó shin + u + + uair + soicind + nóiméad + uair + + seachtain + soicind + nóiméad + uair + + seachtaine + n + + diff --git a/shared/src/main/res/values-hr-rHR/strings.xml b/shared/src/main/res/values-hr-rHR/strings.xml new file mode 100644 index 0000000000..554d7a16e3 --- /dev/null +++ b/shared/src/main/res/values-hr-rHR/strings.xml @@ -0,0 +1,4 @@ + + + + diff --git a/shared/src/main/res/values-hu-rHU/strings.xml b/shared/src/main/res/values-hu-rHU/strings.xml new file mode 100644 index 0000000000..875ac03d58 --- /dev/null +++ b/shared/src/main/res/values-hu-rHU/strings.xml @@ -0,0 +1,6 @@ + + + + p + n + diff --git a/shared/src/main/res/values-it-rIT/strings.xml b/shared/src/main/res/values-it-rIT/strings.xml new file mode 100644 index 0000000000..28f5292504 --- /dev/null +++ b/shared/src/main/res/values-it-rIT/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d m fa + %1$d minuti fa + %1$.1f h fa + %1$.1f giorni fa + %1$.0f giorni fa + in %1$.0f giorni + in %1$.0f giorni + h + giorni + ore + secondi + minuti + ora + giorno + settimana + secondi + minuti + ore + giorni + settimane + m + d + Più tardì oggi + Domani + Oggi + Ieri + diff --git a/shared/src/main/res/values-iw-rIL/strings.xml b/shared/src/main/res/values-iw-rIL/strings.xml new file mode 100644 index 0000000000..554d7a16e3 --- /dev/null +++ b/shared/src/main/res/values-iw-rIL/strings.xml @@ -0,0 +1,4 @@ + + + + diff --git a/shared/src/main/res/values-ko-rKR/strings.xml b/shared/src/main/res/values-ko-rKR/strings.xml new file mode 100644 index 0000000000..be3ce93a16 --- /dev/null +++ b/shared/src/main/res/values-ko-rKR/strings.xml @@ -0,0 +1,21 @@ + + + + %1$d 분 전 + %1$.1f 시간 전 + 시간 + + 시간 + + + + + + + + + + + + + diff --git a/shared/src/main/res/values-lt-rLT/strings.xml b/shared/src/main/res/values-lt-rLT/strings.xml new file mode 100644 index 0000000000..bb053b1723 --- /dev/null +++ b/shared/src/main/res/values-lt-rLT/strings.xml @@ -0,0 +1,21 @@ + + + + prieš %1$d min + Prieš %1$.1f val. + val + d. + val. + sek. + min. + val. + d. + savaitė + sekundės + min. + val. + d. + savaičių + min. + d + diff --git a/shared/src/main/res/values-nl-rNL/strings.xml b/shared/src/main/res/values-nl-rNL/strings.xml new file mode 100644 index 0000000000..554d7a16e3 --- /dev/null +++ b/shared/src/main/res/values-nl-rNL/strings.xml @@ -0,0 +1,4 @@ + + + + diff --git a/shared/src/main/res/values-no-rNO/strings.xml b/shared/src/main/res/values-no-rNO/strings.xml new file mode 100644 index 0000000000..6cdad44084 --- /dev/null +++ b/shared/src/main/res/values-no-rNO/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d min siden + %1$d minutter siden + %1$.1f timer siden + %1$.1f dager siden + %1$.0f dager siden + om %1$.0f dager + om %1$.0f dager + t + dager + timer + sekund + minutt + time + dag + uke + sekunder + minutter + timer + dager + uker + m + d + Senere i dag + I morgen + Idag + I går + diff --git a/shared/src/main/res/values-pl-rPL/strings.xml b/shared/src/main/res/values-pl-rPL/strings.xml new file mode 100644 index 0000000000..52ab7af39b --- /dev/null +++ b/shared/src/main/res/values-pl-rPL/strings.xml @@ -0,0 +1,29 @@ + + + + %1$d min temu + %1$.1f godz. temu + %1$.1f dni temu + %1$.0f dni temu + za %1$.0f dni + za %1$.0f dni + h + dni + godzin + sekunda + minuta + godzina + dzień + tydzień + sekund + minut + godzin + dni + tygodni + m + d + Dzisiaj, później + Jutro + Dziś + Wczoraj + diff --git a/shared/src/main/res/values-pt-rBR/strings.xml b/shared/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..91d8dc0119 --- /dev/null +++ b/shared/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,22 @@ + + + + %1$d min atrás + %1$d minutos atrás + %1$.1fh atrás + %1$d dias atrás + h + dias + horas + segundo + minuto + hora + dia + semana + segundos + minutos + horas + dias + semanas + m + diff --git a/shared/src/main/res/values-pt-rPT/strings.xml b/shared/src/main/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000..b6194783ad --- /dev/null +++ b/shared/src/main/res/values-pt-rPT/strings.xml @@ -0,0 +1,21 @@ + + + + %1$d m atrás + %1$.1f h atrás + h + dias + horas + segundo + minuto + hora + dia + semana + segundos + minutos + horas + dias + semanas + m + d + diff --git a/shared/src/main/res/values-ro-rRO/strings.xml b/shared/src/main/res/values-ro-rRO/strings.xml new file mode 100644 index 0000000000..025c5d22c6 --- /dev/null +++ b/shared/src/main/res/values-ro-rRO/strings.xml @@ -0,0 +1,21 @@ + + + + %1$d min în urmă + %1$.1f ore în urmă + h + zile + ore + secundă + minut + oră + zi + săptămână + secunde + minute + ore + zile + săptămâni + min + z + diff --git a/shared/src/main/res/values-ru-rRU/strings.xml b/shared/src/main/res/values-ru-rRU/strings.xml new file mode 100644 index 0000000000..823285bb86 --- /dev/null +++ b/shared/src/main/res/values-ru-rRU/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d мин. назад + %1$d минут назад + %1$.1fч. назад + %1$s дн назад + %1$s дн назад + через %1$.0f дн + через %1$.0f дн + ч + дн + час + сек + мин + час + дн + нед + сек + мин + час + дн + нед + мин + дн + Позднее сегодня + Завтра + Cегодня + Вчера + diff --git a/shared/src/main/res/values-sk-rSK/strings.xml b/shared/src/main/res/values-sk-rSK/strings.xml new file mode 100644 index 0000000000..3371a5e805 --- /dev/null +++ b/shared/src/main/res/values-sk-rSK/strings.xml @@ -0,0 +1,30 @@ + + + + pred %1$d min + pred %1$d minútami + pred %1$.1f h + Pred %1$.1f dňami + Pred %1$.0f dňami + za %1$.0f dní + za %1$.0f dní + h + dní + hodín + sekunda + minúta + hodina + deň + týždeň + sekúnd + minút + hodín + dní + týždňov + m + d + Neskôr počas dňa + Zajtra + Dnes + včera + diff --git a/shared/src/main/res/values-sv-rSE/strings.xml b/shared/src/main/res/values-sv-rSE/strings.xml new file mode 100644 index 0000000000..df1d98aae8 --- /dev/null +++ b/shared/src/main/res/values-sv-rSE/strings.xml @@ -0,0 +1,22 @@ + + + + %1$dm sedan + %1$d minuter sedan + %1$.1f tim sedan + h + dagar + timmar + sekund + minut + timme + dag + vecka + sekunder + minuter + timmar + dagar + veckor + m + d + diff --git a/shared/src/main/res/values-tr-rTR/strings.xml b/shared/src/main/res/values-tr-rTR/strings.xml new file mode 100644 index 0000000000..b457090d83 --- /dev/null +++ b/shared/src/main/res/values-tr-rTR/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d dak önce + %1$d dakika önce + %1$.1f s önce + %1$.1f gün önce + %1$.0f gün önce + %1$.0f gün içinde + %1$.0f gün içinde + s + gün + saat + saniye + dakika + saat + gün + hafta + saniye + dakika + saat + gün + hafta + dk + g + Bugünden sonra + Yarın + Bugün + Dün + diff --git a/shared/src/main/res/values-zh-rCN/strings.xml b/shared/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000..2619d4b612 --- /dev/null +++ b/shared/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,30 @@ + + + + %1$d 分钟前 + %1$d 分钟前 + %1$.1f 小时前 + %1$.1f 天前 + %1$.0f 天前 + 在 %1$.0f 天内 + 在 %1$.0f 天内 + h + + 小时 + + 分钟 + 小时 + + + + 分钟 + 小时 + + + m + d + 今天稍后 + 明天 + 今天 + 昨天 + diff --git a/wear/build.gradle b/wear/build.gradle index 9bfdcf3e1f..ddcfcbfa2f 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -76,6 +76,7 @@ android { versionName version + "-nsclient" } } + namespace 'info.nightscout.androidaps' } allprojects { diff --git a/wear/google-services.json b/wear/google-services.json new file mode 100644 index 0000000000..ad84142eea --- /dev/null +++ b/wear/google-services.json @@ -0,0 +1,127 @@ +{ + "project_info": { + "project_number": "477603612366", + "firebase_url": "https://androidaps-c34f8.firebaseio.com", + "project_id": "androidaps-c34f8", + "storage_bucket": "androidaps-c34f8.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:477603612366:android:aef229914e3e5448", + "android_client_info": { + "package_name": "info.nightscout.aapspumpcontrol" + } + }, + "oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyD9HRtJJsnk_SbAMAuvudSua2vEm3j3430" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:477603612366:android:efc956f55b281623", + "android_client_info": { + "package_name": "info.nightscout.androidaps" + } + }, + "oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyD9HRtJJsnk_SbAMAuvudSua2vEm3j3430" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:477603612366:android:b38d6e7351f73cc0", + "android_client_info": { + "package_name": "info.nightscout.nsclient" + } + }, + "oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyD9HRtJJsnk_SbAMAuvudSua2vEm3j3430" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:477603612366:android:2dc8cf3acd3332e7", + "android_client_info": { + "package_name": "info.nightscout.nsclient2" + } + }, + "oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyD9HRtJJsnk_SbAMAuvudSua2vEm3j3430" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index 1b75866fe8..88b52fc779 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> diff --git a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt index f816358b71..cac52e5439 100644 --- a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt +++ b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt @@ -200,6 +200,7 @@ class DataHandlerWear @Inject constructor( .setContentIntent(cancelPendingIntent) .setPriority(NotificationCompat.PRIORITY_MAX) .setVibrate(vibratePattern) + .setOnlyAlertOnce(true) .addAction(R.drawable.ic_cancel, context.getString(R.string.cancel_bolus), cancelPendingIntent) val notificationManager = NotificationManagerCompat.from(context) notificationManager.notify(DataLayerListenerServiceWear.BOLUS_PROGRESS_NOTIF_ID, notificationBuilder.build()) @@ -214,18 +215,20 @@ class DataHandlerWear @Inject constructor( longArrayOf(0, 50, 1000), DataLayerListenerServiceWear.AAPS_NOTIFY_CHANNEL_ID_BOLUS_PROGRESS, context.getString(R.string.bolus_progress_channel_name), - context.getString(R.string.bolus_progress_channel_description) + context.getString(R.string.bolus_progress_channel_description), + NotificationManager.IMPORTANCE_HIGH ) createNotificationChannel( - longArrayOf(0, 1, 1000), + longArrayOf(0), DataLayerListenerServiceWear.AAPS_NOTIFY_CHANNEL_ID_BOLUS_PROGRESS_SILENT, context.getString(R.string.bolus_progress_silent_channel_name), - context.getString(R.string.bolus_progress_silent_channel_description) + context.getString(R.string.bolus_progress_silent_channel_description), + NotificationManager.IMPORTANCE_LOW ) } - @TargetApi(value = 26) private fun createNotificationChannel(vibratePattern: LongArray, channelID: String, name: CharSequence, description: String) { - val channel = NotificationChannel(channelID, name, NotificationManager.IMPORTANCE_HIGH) + @TargetApi(value = 26) private fun createNotificationChannel(vibratePattern: LongArray, channelID: String, name: CharSequence, description: String, importance: Int) { + val channel = NotificationChannel(channelID, name, importance) channel.description = description channel.enableVibration(true) channel.vibrationPattern = vibratePattern diff --git a/wear/src/main/java/info/nightscout/androidaps/complications/BrCobIobComplication.kt b/wear/src/main/java/info/nightscout/androidaps/complications/BrCobIobComplication.kt index 308aaf2d73..3a6ee0716f 100644 --- a/wear/src/main/java/info/nightscout/androidaps/complications/BrCobIobComplication.kt +++ b/wear/src/main/java/info/nightscout/androidaps/complications/BrCobIobComplication.kt @@ -7,6 +7,7 @@ import android.support.wearable.complications.ComplicationData import android.support.wearable.complications.ComplicationText import dagger.android.AndroidInjection import info.nightscout.androidaps.data.RawDisplayData +import info.nightscout.androidaps.interaction.utils.DisplayFormat import info.nightscout.androidaps.interaction.utils.SmallestDoubleString import info.nightscout.shared.logging.LTag import kotlin.math.max @@ -25,8 +26,8 @@ class BrCobIobComplication : BaseComplicationProviderService() { override fun buildComplicationData(dataType: Int, raw: RawDisplayData, complicationPendingIntent: PendingIntent): ComplicationData? { var complicationData: ComplicationData? = null if (dataType == ComplicationData.TYPE_SHORT_TEXT) { - val cob = SmallestDoubleString(raw.status.cob, SmallestDoubleString.Units.USE).minimise(displayFormat.MIN_FIELD_LEN_COB) - val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(max(displayFormat.MIN_FIELD_LEN_IOB, displayFormat.MAX_FIELD_LEN_SHORT - 1 - cob.length)) + val cob = SmallestDoubleString(raw.status.cob, SmallestDoubleString.Units.USE).minimise(DisplayFormat.MIN_FIELD_LEN_COB) + val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(max(DisplayFormat.MIN_FIELD_LEN_IOB, DisplayFormat.MAX_FIELD_LEN_SHORT - 1 - cob.length)) val builder = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(displayFormat.basalRateSymbol() + raw.status.currentBasal)) .setShortTitle(ComplicationText.plainText("$cob $iob")) @@ -39,4 +40,4 @@ class BrCobIobComplication : BaseComplicationProviderService() { } override fun getProviderCanonicalName(): String = BrCobIobComplication::class.java.canonicalName!! -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/complications/CobIobComplication.kt b/wear/src/main/java/info/nightscout/androidaps/complications/CobIobComplication.kt index 339f2fae85..f4bf3ed413 100644 --- a/wear/src/main/java/info/nightscout/androidaps/complications/CobIobComplication.kt +++ b/wear/src/main/java/info/nightscout/androidaps/complications/CobIobComplication.kt @@ -6,6 +6,7 @@ import android.app.PendingIntent import android.support.wearable.complications.ComplicationData import android.support.wearable.complications.ComplicationText import info.nightscout.androidaps.data.RawDisplayData +import info.nightscout.androidaps.interaction.utils.DisplayFormat import info.nightscout.androidaps.interaction.utils.SmallestDoubleString import info.nightscout.shared.logging.LTag @@ -18,7 +19,7 @@ class CobIobComplication : BaseComplicationProviderService() { var complicationData: ComplicationData? = null if (dataType == ComplicationData.TYPE_SHORT_TEXT) { val cob = raw.status.cob - val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(displayFormat.MAX_FIELD_LEN_SHORT) + val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(DisplayFormat.MAX_FIELD_LEN_SHORT) val builder = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(cob)) .setShortTitle(ComplicationText.plainText(iob)) @@ -31,4 +32,4 @@ class CobIobComplication : BaseComplicationProviderService() { } override fun getProviderCanonicalName(): String = CobIobComplication::class.java.canonicalName!! -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/complications/IobIconComplication.kt b/wear/src/main/java/info/nightscout/androidaps/complications/IobIconComplication.kt index 7befcd9858..50742e22d0 100644 --- a/wear/src/main/java/info/nightscout/androidaps/complications/IobIconComplication.kt +++ b/wear/src/main/java/info/nightscout/androidaps/complications/IobIconComplication.kt @@ -8,6 +8,7 @@ import android.support.wearable.complications.ComplicationData import android.support.wearable.complications.ComplicationText import info.nightscout.androidaps.R import info.nightscout.androidaps.data.RawDisplayData +import info.nightscout.androidaps.interaction.utils.DisplayFormat import info.nightscout.androidaps.interaction.utils.SmallestDoubleString import info.nightscout.shared.logging.LTag @@ -19,7 +20,7 @@ class IobIconComplication : BaseComplicationProviderService() { override fun buildComplicationData(dataType: Int, raw: RawDisplayData, complicationPendingIntent: PendingIntent): ComplicationData? { var complicationData: ComplicationData? = null if (dataType == ComplicationData.TYPE_SHORT_TEXT) { - val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(displayFormat.MAX_FIELD_LEN_SHORT) + val iob = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(DisplayFormat.MAX_FIELD_LEN_SHORT) val builder = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(iob)) .setIcon(Icon.createWithResource(this, R.drawable.ic_ins)) @@ -34,4 +35,4 @@ class IobIconComplication : BaseComplicationProviderService() { override fun getProviderCanonicalName(): String = IobIconComplication::class.java.canonicalName!! override fun getComplicationAction(): ComplicationAction = ComplicationAction.BOLUS -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.kt index 56889fca22..552f26f391 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.kt @@ -15,7 +15,7 @@ class FillMenuActivity : MenuListActivity() { super.onCreate(savedInstanceState) } - override fun getElements(): List = + override fun provideElements(): List = ArrayList().apply { add(MenuItem(R.drawable.ic_canula, getString(R.string.action_preset_1))) add(MenuItem(R.drawable.ic_canula, getString(R.string.action_preset_2))) @@ -23,12 +23,12 @@ class FillMenuActivity : MenuListActivity() { add(MenuItem(R.drawable.ic_canula, getString(R.string.action_free_amount))) } - override fun doAction(action: String) { - when (action) { + override fun doAction(position: String) { + when (position) { getString(R.string.action_preset_1) -> rxBus.send(EventWearToMobile(EventData.ActionFillPresetPreCheck(1))) getString(R.string.action_preset_2) -> rxBus.send(EventWearToMobile(EventData.ActionFillPresetPreCheck(2))) getString(R.string.action_preset_3) -> rxBus.send(EventWearToMobile(EventData.ActionFillPresetPreCheck(3))) getString(R.string.action_free_amount) -> startActivity(Intent(this, FillActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }) } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.kt index 9cc84c832c..68ea46c780 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.kt @@ -21,7 +21,7 @@ class MainMenuActivity : MenuListActivity() { rxBus.send(EventWearToMobile(ActionResendData("MainMenuListActivity"))) } - override fun getElements(): List = + override fun provideElements(): List = ArrayList().apply { if (!sp.getBoolean(R.string.key_wear_control, false)) { add(MenuItem(R.drawable.ic_settings, getString(R.string.menu_settings))) @@ -40,8 +40,8 @@ class MainMenuActivity : MenuListActivity() { } } - override fun doAction(action: String) { - when (action) { + override fun doAction(position: String) { + when (position) { getString(R.string.menu_settings) -> startActivity(Intent(this, WatchfaceConfigurationActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }) getString(R.string.menu_resync) -> rxBus.send(EventWearToMobile(ActionResendData("Re-Sync"))) getString(R.string.status_profile_switch) -> rxBus.send(EventWearToMobile(EventData.ActionProfileSwitchSendInitialData(System.currentTimeMillis()))) @@ -53,4 +53,4 @@ class MainMenuActivity : MenuListActivity() { getString(R.string.menu_ecarb) -> startActivity(Intent(this, ECarbActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }) } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.kt index 38ffeef840..c6705cedf3 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.kt @@ -15,18 +15,18 @@ class StatusMenuActivity : MenuListActivity() { super.onCreate(savedInstanceState) } - override fun getElements(): List = + override fun provideElements(): List = ArrayList().apply { add(MenuItem(R.drawable.ic_status, getString(R.string.status_pump))) add(MenuItem(R.drawable.ic_loop_closed, getString(R.string.status_loop))) add(MenuItem(R.drawable.ic_tdd, getString(R.string.status_tdd))) } - override fun doAction(action: String) { - when (action) { + override fun doAction(position: String) { + when (position) { getString(R.string.status_pump) -> rxBus.send(EventWearToMobile(ActionPumpStatus(System.currentTimeMillis()))) getString(R.string.status_loop) -> rxBus.send(EventWearToMobile(ActionLoopStatus(System.currentTimeMillis()))) getString(R.string.status_tdd) -> rxBus.send(EventWearToMobile(ActionTddStatus(System.currentTimeMillis()))) } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.java deleted file mode 100644 index 18f2f3ca81..0000000000 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.java +++ /dev/null @@ -1,158 +0,0 @@ -package info.nightscout.androidaps.interaction.utils; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import info.nightscout.androidaps.data.RawDisplayData; -import info.nightscout.shared.sharedPreferences.SP; - -@Singleton -public class DisplayFormat { - - @Inject SP sp; - @Inject WearUtil wearUtil; - - @Inject DisplayFormat() { - } - - /** - * Maximal and minimal lengths of fields/labels shown in complications, in characters - * For MAX values - above that WearOS and watch faces may start ellipsize (...) contents - * For MIN values - this is minimal length that can hold legible data - */ - public final int MAX_FIELD_LEN_LONG = 22; // this is found out empirical, for TYPE_LONG_TEXT - public final int MAX_FIELD_LEN_SHORT = 7; // according to Wear OS docs for TYPE_SHORT_TEXT - public final int MIN_FIELD_LEN_COB = 3; // since carbs are usually 0..99g - public final int MIN_FIELD_LEN_IOB = 3; // IoB can range from like .1U to 99U - - private boolean areComplicationsUnicode() { - return sp.getBoolean("complication_unicode", true); - } - - public String deltaSymbol() { - return areComplicationsUnicode() ? "\u0394" : ""; - } - - public String verticalSeparatorSymbol() { - return areComplicationsUnicode() ? "\u205E" : "|"; - } - - public String basalRateSymbol() { - return areComplicationsUnicode() ? "\u238D\u2006" : ""; - } - - public String shortTimeSince(final long refTime) { - - long deltaTimeMs = wearUtil.msSince(refTime); - - if (deltaTimeMs < Constants.MINUTE_IN_MS) { - return "0'"; - } else if (deltaTimeMs < Constants.HOUR_IN_MS) { - int minutes = (int) (deltaTimeMs / Constants.MINUTE_IN_MS); - return minutes + "'"; - } else if (deltaTimeMs < Constants.DAY_IN_MS) { - int hours = (int) (deltaTimeMs / Constants.HOUR_IN_MS); - return hours + "h"; - } else { - int days = (int) (deltaTimeMs / Constants.DAY_IN_MS); - if (days < 7) { - return days + "d"; - } else { - int weeks = days / 7; - return weeks + "w"; - } - } - } - - public String shortTrend(final RawDisplayData raw) { - String minutes = "--"; - if (raw.getSingleBg().getTimeStamp() > 0) { - minutes = shortTimeSince(raw.getSingleBg().getTimeStamp()); - } - - if (minutes.length() + raw.getSingleBg().getDelta().length() + deltaSymbol().length() + 1 <= MAX_FIELD_LEN_SHORT) { - return minutes + " " + deltaSymbol() + raw.getSingleBg().getDelta(); - } - - // that only optimizes obvious things like 0 before . or at end, + at beginning - String delta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT - 1); - if (minutes.length() + delta.length() + deltaSymbol().length() + 1 <= MAX_FIELD_LEN_SHORT) { - return minutes + " " + deltaSymbol() + delta; - } - - String shortDelta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT - (1 + minutes.length())); - - return minutes + " " + shortDelta; - } - - public String longGlucoseLine(final RawDisplayData raw) { - return raw.getSingleBg().getSgvString() + raw.getSingleBg().getSlopeArrow() + " " + deltaSymbol() + (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(8) + " (" + shortTimeSince(raw.getSingleBg().getTimeStamp()) + ")"; - } - - public String longDetailsLine(final RawDisplayData raw) { - - final String SEP_LONG = " " + verticalSeparatorSymbol() + " "; - final String SEP_SHORT = " " + verticalSeparatorSymbol() + " "; - final int SEP_SHORT_LEN = SEP_SHORT.length(); - final String SEP_MIN = " "; - - String line = - raw.getStatus().getCob() + SEP_LONG + raw.getStatus().getIobSum() + SEP_LONG + basalRateSymbol() + raw.getStatus().getCurrentBasal(); - if (line.length() <= MAX_FIELD_LEN_LONG) { - return line; - } - line = raw.getStatus().getCob() + SEP_SHORT + raw.getStatus().getIobSum() + SEP_SHORT + raw.getStatus().getCurrentBasal(); - if (line.length() <= MAX_FIELD_LEN_LONG) { - return line; - } - - int remainingMax = MAX_FIELD_LEN_LONG - (raw.getStatus().getCob().length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN * 2); - final String smallestIoB = new SmallestDoubleString(raw.getStatus().getIobSum(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_IOB, remainingMax)); - line = raw.getStatus().getCob() + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal(); - if (line.length() <= MAX_FIELD_LEN_LONG) { - return line; - } - - remainingMax = MAX_FIELD_LEN_LONG - (smallestIoB.length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN * 2); - final String simplifiedCob = new SmallestDoubleString(raw.getStatus().getCob(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_COB, remainingMax)); - - line = simplifiedCob + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal(); - if (line.length() <= MAX_FIELD_LEN_LONG) { - return line; - } - - line = simplifiedCob + SEP_MIN + smallestIoB + SEP_MIN + raw.getStatus().getCurrentBasal(); - - return line; - } - - public Pair detailedIob(RawDisplayData raw) { - final String iob1 = new SmallestDoubleString(raw.getStatus().getIobSum(), SmallestDoubleString.Units.USE).minimise(MAX_FIELD_LEN_SHORT); - String iob2 = ""; - if (raw.getStatus().getIobDetail().contains("|")) { - String[] iobs = raw.getStatus().getIobDetail().replace("(", "").replace(")", "").split("\\|"); - - String iobBolus = new SmallestDoubleString(iobs[0]).minimise(MIN_FIELD_LEN_IOB); - if (iobBolus.trim().length() == 0) { - iobBolus = "--"; - } - String iobBasal = new SmallestDoubleString(iobs[1]).minimise((MAX_FIELD_LEN_SHORT - 1) - Math.max(MIN_FIELD_LEN_IOB, iobBolus.length())); - if (iobBasal.trim().length() == 0) { - iobBasal = "--"; - } - iob2 = iobBolus + " " + iobBasal; - } - return Pair.Companion.create(iob1, iob2); - } - - public Pair detailedCob(final RawDisplayData raw) { - SmallestDoubleString cobMini = new SmallestDoubleString(raw.getStatus().getCob(), SmallestDoubleString.Units.USE); - - String cob2 = ""; - if (cobMini.getExtra().length() > 0) { - cob2 = cobMini.getExtra() + cobMini.getUnits(); - } - final String cob1 = cobMini.minimise(MAX_FIELD_LEN_SHORT); - return Pair.Companion.create(cob1, cob2); - } -} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.kt new file mode 100644 index 0000000000..45acd71b94 --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/DisplayFormat.kt @@ -0,0 +1,137 @@ +package info.nightscout.androidaps.interaction.utils + +import info.nightscout.androidaps.interaction.utils.Pair.Companion.create +import javax.inject.Singleton +import javax.inject.Inject +import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.androidaps.data.RawDisplayData +import kotlin.math.max + +@Singleton +class DisplayFormat @Inject internal constructor() { + + companion object { + + const val MAX_FIELD_LEN_LONG = 22 // this is found out empirical, for TYPE_LONG_TEXT + const val MAX_FIELD_LEN_SHORT = 7 // according to Wear OS docs for TYPE_SHORT_TEXT + const val MIN_FIELD_LEN_COB = 3 // since carbs are usually 0..99g + const val MIN_FIELD_LEN_IOB = 3 // IoB can range from like .1U to 99U + } + + @Inject lateinit var sp: SP + @Inject lateinit var wearUtil: WearUtil + + /** + * Maximal and minimal lengths of fields/labels shown in complications, in characters + * For MAX values - above that WearOS and watch faces may start ellipsize (...) contents + * For MIN values - this is minimal length that can hold legible data + */ + + private fun areComplicationsUnicode() = sp.getBoolean("complication_unicode", true) + + private fun deltaSymbol() = if (areComplicationsUnicode()) "\u0394" else "" + + private fun verticalSeparatorSymbol() = if (areComplicationsUnicode()) "\u205E" else "|" + + fun basalRateSymbol() = if (areComplicationsUnicode()) "\u238D\u2006" else "" + + fun shortTimeSince(refTime: Long): String { + val deltaTimeMs = wearUtil.msSince(refTime) + return if (deltaTimeMs < Constants.MINUTE_IN_MS) { + "0'" + } else if (deltaTimeMs < Constants.HOUR_IN_MS) { + val minutes = (deltaTimeMs / Constants.MINUTE_IN_MS).toInt() + "$minutes'" + } else if (deltaTimeMs < Constants.DAY_IN_MS) { + val hours = (deltaTimeMs / Constants.HOUR_IN_MS).toInt() + hours.toString() + "h" + } else { + val days = (deltaTimeMs / Constants.DAY_IN_MS).toInt() + if (days < 7) { + days.toString() + "d" + } else { + val weeks = days / 7 + weeks.toString() + "w" + } + } + } + + fun shortTrend(raw: RawDisplayData): String { + var minutes = "--" + if (raw.singleBg.timeStamp > 0) { + minutes = shortTimeSince(raw.singleBg.timeStamp) + } + if (minutes.length + raw.singleBg.delta.length + deltaSymbol().length + 1 <= MAX_FIELD_LEN_SHORT) { + return minutes + " " + deltaSymbol() + raw.singleBg.delta + } + + // that only optimizes obvious things like 0 before . or at end, + at beginning + val delta = SmallestDoubleString(raw.singleBg.delta).minimise(MAX_FIELD_LEN_SHORT - 1) + if (minutes.length + delta.length + deltaSymbol().length + 1 <= MAX_FIELD_LEN_SHORT) { + return minutes + " " + deltaSymbol() + delta + } + val shortDelta = SmallestDoubleString(raw.singleBg.delta).minimise(MAX_FIELD_LEN_SHORT - (1 + minutes.length)) + return "$minutes $shortDelta" + } + + fun longGlucoseLine(raw: RawDisplayData): String { + return raw.singleBg.sgvString + raw.singleBg.slopeArrow + " " + deltaSymbol() + SmallestDoubleString(raw.singleBg.delta).minimise(8) + " (" + shortTimeSince(raw.singleBg.timeStamp) + ")" + } + + fun longDetailsLine(raw: RawDisplayData): String { + val sepLong = " " + verticalSeparatorSymbol() + " " + val sepShort = " " + verticalSeparatorSymbol() + " " + val sepShortLen = sepShort.length + val sepMin = " " + var line = raw.status.cob + sepLong + raw.status.iobSum + sepLong + basalRateSymbol() + raw.status.currentBasal + if (line.length <= MAX_FIELD_LEN_LONG) { + return line + } + line = raw.status.cob + sepShort + raw.status.iobSum + sepShort + raw.status.currentBasal + if (line.length <= MAX_FIELD_LEN_LONG) { + return line + } + var remainingMax = MAX_FIELD_LEN_LONG - (raw.status.cob.length + raw.status.currentBasal.length + sepShortLen * 2) + val smallestIoB = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(max(MIN_FIELD_LEN_IOB, remainingMax)) + line = raw.status.cob + sepShort + smallestIoB + sepShort + raw.status.currentBasal + if (line.length <= MAX_FIELD_LEN_LONG) { + return line + } + remainingMax = MAX_FIELD_LEN_LONG - (smallestIoB.length + raw.status.currentBasal.length + sepShortLen * 2) + val simplifiedCob = SmallestDoubleString(raw.status.cob, SmallestDoubleString.Units.USE).minimise(max(MIN_FIELD_LEN_COB, remainingMax)) + line = simplifiedCob + sepShort + smallestIoB + sepShort + raw.status.currentBasal + if (line.length <= MAX_FIELD_LEN_LONG) { + return line + } + line = simplifiedCob + sepMin + smallestIoB + sepMin + raw.status.currentBasal + return line + } + + fun detailedIob(raw: RawDisplayData): Pair { + val iob1 = SmallestDoubleString(raw.status.iobSum, SmallestDoubleString.Units.USE).minimise(MAX_FIELD_LEN_SHORT) + var iob2 = "" + if (raw.status.iobDetail.contains("|")) { + val iobs = raw.status.iobDetail.replace("(", "").replace(")", "").split("|").toTypedArray() + var iobBolus = SmallestDoubleString(iobs[0]).minimise(MIN_FIELD_LEN_IOB) + if (iobBolus.trim().isEmpty()) { + iobBolus = "--" + } + var iobBasal = SmallestDoubleString(iobs[1]).minimise(MAX_FIELD_LEN_SHORT - 1 - max(MIN_FIELD_LEN_IOB, iobBolus.length)) + if (iobBasal.trim().isEmpty()) { + iobBasal = "--" + } + iob2 = "$iobBolus $iobBasal" + } + return create(iob1, iob2) + } + + fun detailedCob(raw: RawDisplayData): Pair { + val cobMini = SmallestDoubleString(raw.status.cob, SmallestDoubleString.Units.USE) + var cob2 = "" + if (cobMini.extra.isNotEmpty()) { + cob2 = cobMini.extra + cobMini.units + } + val cob1 = cobMini.minimise(MAX_FIELD_LEN_SHORT) + return create(cob1, cob2) + } +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java deleted file mode 100644 index 3f55afebd2..0000000000 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java +++ /dev/null @@ -1,160 +0,0 @@ -package info.nightscout.androidaps.interaction.utils; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; -import androidx.wear.widget.CurvedTextView; -import androidx.wear.widget.WearableLinearLayoutManager; -import androidx.wear.widget.WearableRecyclerView; - -import java.util.List; - -import javax.inject.Inject; - -import dagger.android.DaggerActivity; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.shared.sharedPreferences.SP; - -/** - * Created by adrian on 08/02/17. - */ - -public abstract class MenuListActivity extends DaggerActivity { - - @Inject public RxBus rxBus; - @Inject public SP sp; - - List elements; - - protected abstract List getElements(); - - protected abstract void doAction(String position); - - public interface AdapterCallback { - void onItemClicked(MenuAdapter.ItemViewHolder v); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.actions_list_activity); - setTitleBasedOnScreenShape(String.valueOf(getTitle())); - - elements = getElements(); - CustomScrollingLayoutCallback customScrollingLayoutCallback = new CustomScrollingLayoutCallback(); - WearableLinearLayoutManager layoutManager = new WearableLinearLayoutManager(this); - WearableRecyclerView listView = findViewById(R.id.action_list); - boolean isScreenRound = this.getResources().getConfiguration().isScreenRound(); - if (isScreenRound) { - layoutManager.setLayoutCallback(customScrollingLayoutCallback); - listView.setEdgeItemsCenteringEnabled(true); - } else { - // Bug in androidx.wear:wear:1.2.0 - // WearableRecyclerView setEdgeItemsCenteringEnabled requires fix for square screen - listView.setPadding(0, 50, 0, 0); - } - listView.setHasFixedSize(true); - listView.setLayoutManager(layoutManager); - listView.setAdapter(new MenuAdapter(elements, v -> { - String tag = (String) v.itemView.getTag(); - doAction(tag); - })); - } - - private void setTitleBasedOnScreenShape(String title) { - CurvedTextView titleViewCurved = findViewById(R.id.title_curved); - TextView titleView = findViewById(R.id.title); - if (this.getResources().getConfiguration().isScreenRound()) { - titleViewCurved.setText(title); - titleViewCurved.setVisibility(View.VISIBLE); - titleView.setVisibility((View.GONE)); - } else { - titleView.setText(title); - titleView.setVisibility(View.VISIBLE); - titleViewCurved.setVisibility((View.GONE)); - } - } - - private static class MenuAdapter extends RecyclerView.Adapter { - private final List mDataset; - private final AdapterCallback callback; - - public MenuAdapter(List dataset, AdapterCallback callback) { - mDataset = dataset; - this.callback = callback; - } - - public static class ItemViewHolder extends RecyclerView.ViewHolder { - protected final RelativeLayout menuContainer; - protected final TextView actionItem; - protected final ImageView actionIcon; - - public ItemViewHolder(View itemView) { - super(itemView); - menuContainer = itemView.findViewById(R.id.menu_container); - actionItem = itemView.findViewById(R.id.menuItemText); - actionIcon = itemView.findViewById(R.id.menuItemIcon); - } - } - - @NonNull @Override - public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false); - - return new ItemViewHolder(view); - } - - @Override - public void onBindViewHolder(ItemViewHolder holder, final int position) { - MenuItem item = mDataset.get(position); - holder.actionItem.setText(item.actionItem); - holder.actionIcon.setImageResource(item.actionIcon); - holder.itemView.setTag(item.actionItem); - holder.menuContainer.setOnClickListener(v -> callback.onItemClicked(holder)); - } - - @Override - public int getItemCount() { - return mDataset.size(); - } - } - - protected static class MenuItem { - public MenuItem(int actionIcon, String actionItem) { - this.actionIcon = actionIcon; - this.actionItem = actionItem; - } - - public int actionIcon; - public String actionItem; - } - - public static class CustomScrollingLayoutCallback extends WearableLinearLayoutManager.LayoutCallback { - // How much should we scale the icon at most. - private static final float MAX_ICON_PROGRESS = 0.65f; - - @Override - public void onLayoutFinished(View child, RecyclerView parent) { - // Figure out % progress from top to bottom - float centerOffset = ((float) child.getHeight() / 2.0f) / (float) parent.getHeight(); - float yRelativeToCenterOffset = (child.getY() / parent.getHeight()) + centerOffset; - - // Normalize for center - float progressToCenter = Math.abs(0.5f - yRelativeToCenterOffset); - // Adjust to the maximum scale - progressToCenter = Math.min(progressToCenter, MAX_ICON_PROGRESS); - - child.setScaleX(1 - progressToCenter); - child.setScaleY(1 - progressToCenter); - } - } - -} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.kt new file mode 100644 index 0000000000..b299e4f96e --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.kt @@ -0,0 +1,129 @@ +package info.nightscout.androidaps.interaction.utils + +import dagger.android.DaggerActivity +import javax.inject.Inject +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.androidaps.interaction.utils.MenuListActivity.MenuAdapter.ItemViewHolder +import android.os.Bundle +import info.nightscout.androidaps.R +import androidx.wear.widget.WearableLinearLayoutManager +import androidx.wear.widget.CurvedTextView +import android.widget.TextView +import android.widget.RelativeLayout +import android.view.ViewGroup +import android.view.LayoutInflater +import android.view.View +import android.widget.ImageView +import androidx.recyclerview.widget.RecyclerView +import androidx.wear.widget.WearableLinearLayoutManager.LayoutCallback +import androidx.wear.widget.WearableRecyclerView +import kotlin.math.abs +import kotlin.math.min + +/** + * Created by adrian on 08/02/17. + */ +abstract class MenuListActivity : DaggerActivity() { + + @Inject lateinit var sp: SP + @Inject lateinit var rxBus: RxBus + + private var elements: List = listOf() + protected abstract fun provideElements(): List + protected abstract fun doAction(position: String) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.actions_list_activity) + setTitleBasedOnScreenShape(title.toString()) + elements = provideElements() + val customScrollingLayoutCallback = CustomScrollingLayoutCallback() + val layoutManager = WearableLinearLayoutManager(this) + val listView = findViewById(R.id.action_list) + val isScreenRound = this.resources.configuration.isScreenRound + if (isScreenRound) { + layoutManager.layoutCallback = customScrollingLayoutCallback + listView.isEdgeItemsCenteringEnabled = true + } else { + // Bug in androidx.wear:wear:1.2.0 + // WearableRecyclerView setEdgeItemsCenteringEnabled requires fix for square screen + listView.setPadding(0, 50, 0, 0) + } + listView.setHasFixedSize(true) + listView.layoutManager = layoutManager + listView.adapter = MenuAdapter(elements) { v: ItemViewHolder -> + val tag = v.itemView.tag as String + doAction(tag) + } + } + + private fun setTitleBasedOnScreenShape(title: String) { + val titleViewCurved = findViewById(R.id.title_curved) + val titleView = findViewById(R.id.title) + if (this.resources.configuration.isScreenRound) { + titleViewCurved.text = title + titleViewCurved.visibility = View.VISIBLE + titleView.visibility = View.GONE + } else { + titleView.text = title + titleView.visibility = View.VISIBLE + titleViewCurved.visibility = View.GONE + } + } + + class MenuAdapter(private val mDataset: List, private val callback: (ItemViewHolder) -> Unit) : RecyclerView.Adapter() { + class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + val menuContainer: RelativeLayout + val actionItem: TextView + val actionIcon: ImageView + + init { + menuContainer = itemView.findViewById(R.id.menu_container) + actionItem = itemView.findViewById(R.id.menuItemText) + actionIcon = itemView.findViewById(R.id.menuItemIcon) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) + return ItemViewHolder(view) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val item = mDataset[position] + holder.actionItem.text = item.actionItem + holder.actionIcon.setImageResource(item.actionIcon) + holder.itemView.tag = item.actionItem + holder.menuContainer.setOnClickListener { callback(holder) } + } + + override fun getItemCount(): Int { + return mDataset.size + } + } + + class MenuItem(var actionIcon: Int, var actionItem: String) + class CustomScrollingLayoutCallback : LayoutCallback() { + + override fun onLayoutFinished(child: View, parent: RecyclerView) { + // Figure out % progress from top to bottom + val centerOffset = child.height.toFloat() / 2.0f / parent.height.toFloat() + val yRelativeToCenterOffset = child.y / parent.height + centerOffset + + // Normalize for center + var progressToCenter = abs(0.5f - yRelativeToCenterOffset) + // Adjust to the maximum scale + progressToCenter = min(progressToCenter, MAX_ICON_PROGRESS) + child.scaleX = 1 - progressToCenter + child.scaleY = 1 - progressToCenter + } + + companion object { + + // How much should we scale the icon at most. + private const val MAX_ICON_PROGRESS = 0.65f + } + } +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/Persistence.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/Persistence.kt index bfad5b3571..96de0db6d9 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/Persistence.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/Persistence.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps.interaction.utils -import android.util.Base64 import info.nightscout.androidaps.utils.DateUtil import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -182,4 +181,4 @@ class Persistence @Inject constructor( aapsLogger.debug(LTag.WEAR, "TURNING OFF all active complications") putString(KEY_COMPLICATIONS, "") } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.java deleted file mode 100644 index 64503f089e..0000000000 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.java +++ /dev/null @@ -1,236 +0,0 @@ -package info.nightscout.androidaps.interaction.utils; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.core.view.InputDeviceCompat; -import androidx.core.view.MotionEventCompat; - -import java.text.NumberFormat; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * Created by mike on 28.06.2016. - */ -public class PlusMinusEditText implements View.OnKeyListener, - View.OnTouchListener, View.OnClickListener, View.OnGenericMotionListener { - - public TextView editText; - ImageView minusImage; - ImageView plusImage; - - Double value; - Double minValue; - Double maxValue; - Double step; - NumberFormat formatter; - boolean allowZero; - boolean roundRobin; - - private int mChangeCounter = 0; - private long mLastChange = 0; - private final static int THRESHOLD_COUNTER = 5; - private final static int THRESHOLD_COUNTER_LONG = 10; - private final static int THRESHOLD_TIME = 100; - - private final Handler mHandler; - private ScheduledExecutorService mUpdater; - - private class UpdateCounterTask implements Runnable { - private final boolean mInc; - private int repeated = 0; - private int multiplier = 1; - - public UpdateCounterTask(boolean inc) { - mInc = inc; - } - - public void run() { - Message msg = new Message(); - int doubleLimit = 5; - if (repeated % doubleLimit == 0) multiplier *= 2; - repeated++; - msg.arg1 = multiplier; - msg.arg2 = repeated; - if (mInc) { - msg.what = MSG_INC; - } else { - msg.what = MSG_DEC; - } - mHandler.sendMessage(msg); - } - } - - private static final int MSG_INC = 0; - private static final int MSG_DEC = 1; - - public PlusMinusEditText(View view, int editTextID, int plusID, int minusID, Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero) { - this(view, editTextID, plusID, minusID, initValue, minValue, maxValue, step, formatter, allowZero, false); - } - - public PlusMinusEditText(View view, int editTextID, int plusID, int minusID, Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero, boolean roundRobin) { - editText = view.findViewById(editTextID); - minusImage = view.findViewById(minusID); - plusImage = view.findViewById(plusID); - - this.value = initValue; - this.minValue = minValue; - this.maxValue = maxValue; - this.step = step; - this.formatter = formatter; - this.allowZero = allowZero; - this.roundRobin = roundRobin; - - mHandler = new Handler(Looper.getMainLooper()) { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_INC: - inc(msg.arg1); - return; - case MSG_DEC: - dec(msg.arg1); - return; - } - super.handleMessage(msg); - } - }; - - minusImage.setOnTouchListener(this); - minusImage.setOnKeyListener(this); - minusImage.setOnClickListener(this); - plusImage.setOnTouchListener(this); - plusImage.setOnKeyListener(this); - plusImage.setOnClickListener(this); - editText.setOnGenericMotionListener(this); - updateEditText(); - } - - public void setValue(Double value) { - this.value = value; - updateEditText(); - } - - public Double getValue() { - return value; - } - - private void inc(int multiplier) { - value += step * multiplier; - if (value > maxValue) { - if (roundRobin) { - value = minValue; - } else { - value = maxValue; - stopUpdating(); - } - } - updateEditText(); - } - - private void dec(int multiplier) { - value -= step * multiplier; - if (value < minValue) { - if (roundRobin) { - value = maxValue; - } else { - value = minValue; - stopUpdating(); - } - } - updateEditText(); - } - - private void updateEditText() { - if (value == 0d && !allowZero) - editText.setText(""); - else - editText.setText(formatter.format(value)); - } - - private void startUpdating(boolean inc) { - if (mUpdater != null) { - return; - } - mUpdater = Executors.newSingleThreadScheduledExecutor(); - mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200, - TimeUnit.MILLISECONDS); - } - - private void stopUpdating() { - if (mUpdater != null) { - mUpdater.shutdownNow(); - mUpdater = null; - } - } - - @Override - public void onClick(View v) { - if (mUpdater == null) { - if (v == plusImage) { - inc(1); - } else { - dec(1); - } - } - } - - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER; - boolean isReleased = event.getAction() == KeyEvent.ACTION_UP; - boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN - && event.getAction() != KeyEvent.ACTION_MULTIPLE; - - if (isKeyOfInterest && isReleased) { - stopUpdating(); - } else if (isKeyOfInterest && isPressed) { - startUpdating(v == plusImage); - } - return false; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL; - boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN; - - if (isReleased) { - stopUpdating(); - } else if (isPressed) { - startUpdating(v == plusImage); - } - return false; - } - - @Override - public boolean onGenericMotion(View v, MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_SCROLL && ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)) { - long now = System.currentTimeMillis(); - if (now - mLastChange > THRESHOLD_TIME) mChangeCounter = 0; - - int dynamicMultiplier = mChangeCounter < THRESHOLD_COUNTER ? 1 : - mChangeCounter < THRESHOLD_COUNTER_LONG ? 2 : 4; - - float delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL); - if (delta > 0) { - inc(dynamicMultiplier); - } else { - dec(dynamicMultiplier); - } - mLastChange = System.currentTimeMillis(); - mChangeCounter++; - return true; - } - return false; - } - -} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt new file mode 100644 index 0000000000..1ee994c9d3 --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -0,0 +1,217 @@ +package info.nightscout.androidaps.interaction.utils + +import android.os.Handler +import kotlin.jvm.JvmOverloads +import android.view.View.OnTouchListener +import android.view.View.OnGenericMotionListener +import android.widget.TextView +import android.view.MotionEvent +import android.os.Looper +import android.os.Message +import android.view.KeyEvent +import android.view.View +import android.widget.ImageView +import androidx.core.view.InputDeviceCompat +import androidx.core.view.MotionEventCompat +import java.text.NumberFormat +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.TimeUnit + +/** + * Created by mike on 28.06.2016. + */ +class PlusMinusEditText @JvmOverloads constructor( + view: View, + editTextID: Int, + plusID: Int, + minusID: Int, + initValue: Double, + minValue: Double, + maxValue: Double, + step: Double, + formatter: NumberFormat, + allowZero: Boolean, + roundRobin: Boolean = false +) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener { + + var editText: TextView + private set + private var minusImage: ImageView + private var plusImage: ImageView + private var value: Double + private var minValue: Double + private var maxValue: Double + private var step: Double + private var formatter: NumberFormat + private var allowZero: Boolean + private var roundRobin: Boolean + private var mChangeCounter = 0 + private var mLastChange: Long = 0 + private val mHandler: Handler + private var mUpdater: ScheduledExecutorService? = null + + private inner class UpdateCounterTask(private val mInc: Boolean) : Runnable { + + private var repeated = 0 + private var multiplier = 1 + override fun run() { + val msg = Message() + val doubleLimit = 5 + if (repeated % doubleLimit == 0) multiplier *= 2 + repeated++ + msg.arg1 = multiplier + msg.arg2 = repeated + if (mInc) { + msg.what = MSG_INC + } else { + msg.what = MSG_DEC + } + mHandler.sendMessage(msg) + } + } + + private fun inc(multiplier: Int) { + value += step * multiplier + if (value > maxValue) { + if (roundRobin) { + value = minValue + } else { + value = maxValue + stopUpdating() + } + } + updateEditText() + } + + private fun dec(multiplier: Int) { + value -= step * multiplier + if (value < minValue) { + if (roundRobin) { + value = maxValue + } else { + value = minValue + stopUpdating() + } + } + updateEditText() + } + + private fun updateEditText() { + if (value == 0.0 && !allowZero) editText.text = "" else editText.text = formatter.format(value) + } + + private fun startUpdating(inc: Boolean) { + if (mUpdater != null) { + return + } + + mUpdater = Executors.newSingleThreadScheduledExecutor() + mUpdater?.scheduleAtFixedRate( + UpdateCounterTask(inc), 200, 200, + TimeUnit.MILLISECONDS + ) + } + + private fun stopUpdating() { + mUpdater?.shutdownNow() + mUpdater = null + } + + override fun onClick(v: View) { + if (mUpdater == null) { + if (v === plusImage) { + inc(1) + } else { + dec(1) + } + } + } + + override fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean { + val isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER + val isReleased = event.action == KeyEvent.ACTION_UP + val isPressed = event.action == KeyEvent.ACTION_DOWN + if (isKeyOfInterest && isReleased) { + stopUpdating() + } else if (isKeyOfInterest && isPressed) { + startUpdating(v === plusImage) + } + return false + } + + override fun onTouch(v: View, event: MotionEvent): Boolean { + val isReleased = event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL + val isPressed = event.action == MotionEvent.ACTION_DOWN + if (isReleased) { + stopUpdating() + } else if (isPressed) { + startUpdating(v === plusImage) + } + return false + } + + override fun onGenericMotion(v: View, ev: MotionEvent): Boolean { + if (ev.action == MotionEvent.ACTION_SCROLL && ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)) { + val now = System.currentTimeMillis() + if (now - mLastChange > THRESHOLD_TIME) mChangeCounter = 0 + val dynamicMultiplier = if (mChangeCounter < THRESHOLD_COUNTER) 1 else if (mChangeCounter < THRESHOLD_COUNTER_LONG) 2 else 4 + val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) + if (delta > 0) { + inc(dynamicMultiplier) + } else { + dec(dynamicMultiplier) + } + mLastChange = System.currentTimeMillis() + mChangeCounter++ + return true + } + return false + } + + companion object { + + private const val THRESHOLD_COUNTER = 5 + private const val THRESHOLD_COUNTER_LONG = 10 + private const val THRESHOLD_TIME = 100 + private const val MSG_INC = 0 + private const val MSG_DEC = 1 + } + + init { + editText = view.findViewById(editTextID) + minusImage = view.findViewById(minusID) + plusImage = view.findViewById(plusID) + value = initValue + this.minValue = minValue + this.maxValue = maxValue + this.step = step + this.formatter = formatter + this.allowZero = allowZero + this.roundRobin = roundRobin + mHandler = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + when (msg.what) { + MSG_INC -> { + inc(msg.arg1) + return + } + + MSG_DEC -> { + dec(msg.arg1) + return + } + } + super.handleMessage(msg) + } + } + minusImage.setOnTouchListener(this) + minusImage.setOnKeyListener(this) + minusImage.setOnClickListener(this) + plusImage.setOnTouchListener(this) + plusImage.setOnKeyListener(this) + plusImage.setOnClickListener(this) + editText.setOnGenericMotionListener(this) + updateEditText() + } +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.java deleted file mode 100644 index be59dbc127..0000000000 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.java +++ /dev/null @@ -1,135 +0,0 @@ -package info.nightscout.androidaps.interaction.utils; - -import java.math.RoundingMode; -import java.text.DecimalFormat; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Helper to minimise various floating point values, with or without unit, to fit into specified - * and limited size, scarifying precision (rounding up) and extra characters like leading zero, - * following zero(s) in fractional part, extra plus sign etc. - * - * Created by dlvoy on 2019-11-12 - */ -public class SmallestDoubleString { - - private String sign = ""; - private String decimal = ""; - private String separator = ""; - private String fractional = ""; - private String extra = ""; - private String units = ""; - - private final Units withUnits; - - public enum Units { - SKIP, - USE - } - - private static final Pattern pattern = Pattern.compile("^([+-]?)([0-9]*)([,.]?)([0-9]*)(\\([^)]*\\))?(.*?)$", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE ); - - public SmallestDoubleString(String inputString) { - this(inputString, Units.SKIP); - } - - public SmallestDoubleString(String inputString, Units withUnits) { - Matcher matcher = pattern.matcher(inputString); - matcher.matches(); - - sign = matcher.group(1); - decimal = matcher.group(2); - separator = matcher.group(3); - fractional = matcher.group(4); - units = matcher.group(6); - - if (fractional == null || fractional.length() == 0) { - separator = ""; - fractional = ""; - } - if (decimal == null || decimal.length() == 0) { - decimal = ""; - } - if (separator == null || separator.length() == 0) { - separator = ""; - } - if (sign == null || sign.length() == 0) { - sign = ""; - } - - final String extraCandidate = matcher.group(5); - if (extraCandidate != null && extraCandidate.length() > 2) { - extra = extraCandidate.substring(1, extraCandidate.length()-1); - } - - if (units != null) { - units = units.trim(); - } - - this.withUnits = withUnits; - } - - public String minimise(int maxSize) { - final String originalSeparator = separator; - - if (Integer.parseInt("0"+fractional) == 0) { - separator = ""; - fractional = ""; - } - if (Integer.parseInt("0"+decimal) == 0 && (fractional.length() >0)) { - decimal = ""; - } - if (currentLen() <= maxSize) - return toString(); - - if (sign.equals("+")) { - sign = ""; - } - if (currentLen() <= maxSize) { - return toString(); - } - - while ((fractional.length() > 1)&&(fractional.charAt(fractional.length()-1) == '0')) { - fractional = fractional.substring(0, fractional.length()-1); - } - if (currentLen() <= maxSize) { - return toString(); - } - - if (fractional.length() > 0) { - int remainingForFraction = maxSize-currentLen()+fractional.length(); - String formatCandidate = "#"; - if (remainingForFraction>=1) { - formatCandidate = "#."+("#######".substring(0, remainingForFraction)); - } - DecimalFormat df = new DecimalFormat(formatCandidate); - df.setRoundingMode(RoundingMode.HALF_UP); - - final String decimalSup = (decimal.length() > 0) ? decimal : "0"; - String result = sign + df.format(Double.parseDouble(decimalSup+"."+fractional)).replace(",", originalSeparator).replace(".", originalSeparator) + - ((withUnits == Units.USE) ? units : ""); - return (decimal.length() > 0) ? result : result.substring(1); - } - return toString(); - } - - private int currentLen() { - return sign.length() + decimal.length() + separator.length() + fractional.length() + - ((withUnits == Units.USE) ? units.length() : 0); - } - - @Override - public String toString() { - return sign+decimal+separator+fractional + - ((withUnits == Units.USE) ? units : ""); - } - - public String getExtra() { - return extra; - } - - public String getUnits() { return units; } - - -} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.kt new file mode 100644 index 0000000000..5eb6b8946a --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/SmallestDoubleString.kt @@ -0,0 +1,102 @@ +package info.nightscout.androidaps.interaction.utils + +import kotlin.jvm.JvmOverloads +import java.math.RoundingMode +import java.text.DecimalFormat +import java.util.regex.Pattern + +/** + * Helper to minimise various floating point values, with or without unit, to fit into specified + * and limited size, scarifying precision (rounding up) and extra characters like leading zero, + * following zero(s) in fractional part, extra plus sign etc. + * + * Created by dlvoy on 2019-11-12 + */ +class SmallestDoubleString @JvmOverloads constructor(inputString: String, withUnits: Units = Units.SKIP) { + + private var sign: String + private var decimal: String + private var separator: String + private var fractional: String + var extra = "" + var units: String + private val withUnits: Units + + enum class Units { + SKIP, USE + } + + fun minimise(maxSize: Int): String { + val originalSeparator = separator + if ("0$fractional".toInt() == 0) { + separator = "" + fractional = "" + } + if ("0$decimal".toInt() == 0 && fractional.isNotEmpty()) { + decimal = "" + } + if (currentLen() <= maxSize) return toString() + if (sign == "+") { + sign = "" + } + if (currentLen() <= maxSize) { + return toString() + } + while (fractional.length > 1 && fractional[fractional.length - 1] == '0') { + fractional = fractional.substring(0, fractional.length - 1) + } + if (currentLen() <= maxSize) { + return toString() + } + if (fractional.isNotEmpty()) { + val remainingForFraction = maxSize - currentLen() + fractional.length + var formatCandidate = "#" + if (remainingForFraction >= 1) { + formatCandidate = "#." + "#######".substring(0, remainingForFraction) + } + val df = DecimalFormat(formatCandidate) + df.roundingMode = RoundingMode.HALF_UP + val decimalSup = decimal.ifEmpty { "0" } + val result = sign + df.format("$decimalSup.$fractional".toDouble()).replace(",", originalSeparator).replace(".", originalSeparator) + + if (withUnits == Units.USE) units else "" + return if (decimal.isNotEmpty()) result else result.substring(1) + } + return toString() + } + + private fun currentLen(): Int { + return sign.length + decimal.length + separator.length + fractional.length + + if (withUnits == Units.USE) units.length else 0 + } + + override fun toString(): String { + return sign + decimal + separator + fractional + + if (withUnits == Units.USE) units else "" + } + + companion object { + + private val pattern = Pattern.compile("^([+-]?)([0-9]*)([,.]?)([0-9]*)(\\([^)]*\\))?(.*?)$", Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE) + } + + init { + val matcher = pattern.matcher(inputString) + matcher.matches() + sign = matcher.group(1) ?: "" + decimal = matcher.group(2) ?: "" + separator = matcher.group(3) ?: "" + fractional = matcher.group(4) ?: "" + units = matcher.group(6) ?: "" + if (fractional.isEmpty()) { + separator = "" + fractional = "" + } + val extraCandidate = matcher.group(5) ?: "" + if (extraCandidate.length > 2) { + extra = extraCandidate.substring(1, extraCandidate.length - 1) + } + units = units.trim() + + this.withUnits = withUnits + } +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt index 1311e2dce6..7509cfc0a5 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/WearUtil.kt @@ -1,9 +1,7 @@ package info.nightscout.androidaps.interaction.utils import android.content.Context -import android.os.Bundle import android.os.PowerManager -import com.google.android.gms.wearable.DataMap import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import javax.inject.Inject @@ -72,4 +70,4 @@ class WearUtil @Inject constructor() { // we simply ignore if sleep was interrupted } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/ActionsTileService.kt b/wear/src/main/java/info/nightscout/androidaps/tile/ActionsTileService.kt index 959948443a..18fdcace9c 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/ActionsTileService.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/ActionsTileService.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.tile import dagger.android.AndroidInjection +import info.nightscout.androidaps.tile.source.ActionSource import javax.inject.Inject class ActionsTileService : TileBase() { diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardTileService.kt b/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardTileService.kt index 7dfc32a540..23cd00ca27 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardTileService.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardTileService.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.tile import dagger.android.AndroidInjection +import info.nightscout.androidaps.tile.source.QuickWizardSource import javax.inject.Inject class QuickWizardTileService : TileBase() { diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetTileService.kt b/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetTileService.kt index 8b17893ac1..9526b3feba 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetTileService.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetTileService.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.tile import dagger.android.AndroidInjection +import info.nightscout.androidaps.tile.source.TempTargetSource import javax.inject.Inject class TempTargetTileService : TileBase() { diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/ActionSource.kt b/wear/src/main/java/info/nightscout/androidaps/tile/source/ActionSource.kt similarity index 95% rename from wear/src/main/java/info/nightscout/androidaps/tile/ActionSource.kt rename to wear/src/main/java/info/nightscout/androidaps/tile/source/ActionSource.kt index 492c10d9ec..49a8ac4199 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/ActionSource.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/source/ActionSource.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.tile +package info.nightscout.androidaps.tile.source import android.content.Context import android.content.res.Resources diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardSource.kt b/wear/src/main/java/info/nightscout/androidaps/tile/source/QuickWizardSource.kt similarity index 93% rename from wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardSource.kt rename to wear/src/main/java/info/nightscout/androidaps/tile/source/QuickWizardSource.kt index 00993b09bf..6982b2d0c2 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/QuickWizardSource.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/source/QuickWizardSource.kt @@ -1,9 +1,11 @@ -package info.nightscout.androidaps.tile +package info.nightscout.androidaps.tile.source import android.content.Context import android.content.res.Resources import info.nightscout.androidaps.R import info.nightscout.androidaps.interaction.actions.BackgroundActionActivity +import info.nightscout.androidaps.tile.Action +import info.nightscout.androidaps.tile.TileSource import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag import info.nightscout.shared.sharedPreferences.SP diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/StaticTileSource.kt b/wear/src/main/java/info/nightscout/androidaps/tile/source/StaticTileSource.kt similarity index 90% rename from wear/src/main/java/info/nightscout/androidaps/tile/StaticTileSource.kt rename to wear/src/main/java/info/nightscout/androidaps/tile/source/StaticTileSource.kt index 93d29d6927..893bcf4c48 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/StaticTileSource.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/source/StaticTileSource.kt @@ -1,9 +1,10 @@ -package info.nightscout.androidaps.tile +package info.nightscout.androidaps.tile.source import android.content.Context -import android.content.SharedPreferences import android.content.res.Resources import androidx.annotation.DrawableRes +import info.nightscout.androidaps.tile.Action +import info.nightscout.androidaps.tile.TileSource import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.weardata.EventData diff --git a/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetSource.kt b/wear/src/main/java/info/nightscout/androidaps/tile/source/TempTargetSource.kt similarity index 96% rename from wear/src/main/java/info/nightscout/androidaps/tile/TempTargetSource.kt rename to wear/src/main/java/info/nightscout/androidaps/tile/source/TempTargetSource.kt index 3ebbfdc7e2..ec9a64b50a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/tile/TempTargetSource.kt +++ b/wear/src/main/java/info/nightscout/androidaps/tile/source/TempTargetSource.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.tile +package info.nightscout.androidaps.tile.source import android.content.Context import android.content.res.Resources diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.kt b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.kt index a25d320dd4..23f304a8b5 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.kt +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.kt @@ -13,11 +13,11 @@ import android.os.Vibrator import android.support.wearable.watchface.WatchFaceStyle import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.WindowInsets import android.view.WindowManager import android.widget.ImageView import android.widget.LinearLayout -import android.widget.RelativeLayout import android.widget.TextView import androidx.annotation.LayoutRes import androidx.core.content.ContextCompat @@ -66,7 +66,6 @@ abstract class BaseWatchFace : WatchFace() { @Inject lateinit var dateUtil: DateUtil private var disposable = CompositeDisposable() - private val rawData = RawDisplayData() protected val singleBg get() = rawData.singleBg @@ -96,23 +95,23 @@ abstract class BaseWatchFace : WatchFace() { var mCOB2: TextView? = null var mBgi: TextView? = null var mLoop: TextView? = null - var mTimePeriod: TextView? = null + private var mTimePeriod: TextView? = null var mDay: TextView? = null - var mDayName: TextView? = null + private var mDayName: TextView? = null var mMonth: TextView? = null - var isAAPSv2: TextView? = null + private var isAAPSv2: View? = null var mHighLight: TextView? = null var mLowLight: TextView? = null var mGlucoseDial: ImageView? = null var mDeltaGauge: ImageView? = null var mHourHand: ImageView? = null var mMinuteHand: ImageView? = null - var mRelativeLayout: RelativeLayout? = null + var mRelativeLayout: ViewGroup? = null var mLinearLayout: LinearLayout? = null var mLinearLayout2: LinearLayout? = null - var mDate: LinearLayout? = null - var mChartTap: LinearLayout? = null // Steampunk only - var mMainMenuTap: LinearLayout? = null // Steampunk,Digital only + private var mDate: LinearLayout? = null + private var mChartTap: LinearLayout? = null // Steampunk only + private var mMainMenuTap: LinearLayout? = null // Steampunk,Digital only var chart: LineChartView? = null var ageLevel = 1 @@ -123,7 +122,7 @@ abstract class BaseWatchFace : WatchFace() { var gridColor = Color.WHITE var basalBackgroundColor = Color.BLUE var basalCenterColor = Color.BLUE - var bolusColor = Color.MAGENTA + private var bolusColor = Color.MAGENTA private var lowResMode = false private var layoutSet = false var bIsRound = false @@ -137,8 +136,8 @@ abstract class BaseWatchFace : WatchFace() { // related endTime manual layout var layoutView: View? = null - var specW = 0 - var specH = 0 + private var specW = 0 + private var specH = 0 var forceSquareCanvas = false // Set to true by the Steampunk watch face. private var batteryReceiver: BroadcastReceiver? = null private var colorDarkHigh = 0 @@ -338,7 +337,7 @@ abstract class BaseWatchFace : WatchFace() { return (System.currentTimeMillis() - singleBg.timeStamp).toDouble() } - protected fun readingAge(shortString: Boolean): String { + private fun readingAge(shortString: Boolean): String { if (singleBg.timeStamp == 0L) { return if (shortString) "--" else "-- Minute ago" } @@ -491,7 +490,7 @@ abstract class BaseWatchFace : WatchFace() { invalidate() } - protected fun setDateAndTime() { + private fun setDateAndTime() { mTime?.text = dateUtil.timeString() mHour?.text = dateUtil.hourString() mMinute?.text = dateUtil.minuteString() @@ -512,7 +511,7 @@ abstract class BaseWatchFace : WatchFace() { } } - protected fun strikeThroughSgvIfNeeded() { + private fun strikeThroughSgvIfNeeded() { mSgv?.let { mSgv -> if (ageLevel() <= 0 && singleBg.timeStamp > 0) mSgv.paintFlags = mSgv.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG else mSgv.paintFlags = mSgv.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() @@ -594,4 +593,4 @@ abstract class BaseWatchFace : WatchFace() { val BOLD_TYPEFACE: Typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD) const val SCREEN_SIZE_SMALL = 280 } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BigChartWatchface.kt b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BigChartWatchface.kt index 8fe6eaae33..698ce41142 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BigChartWatchface.kt +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BigChartWatchface.kt @@ -2,6 +2,7 @@ package info.nightscout.androidaps.watchfaces +import android.annotation.SuppressLint import androidx.annotation.LayoutRes import androidx.core.content.ContextCompat import com.ustwo.clockwise.common.WatchMode @@ -13,6 +14,7 @@ class BigChartWatchface : BaseWatchFace() { if (resources.displayMetrics.widthPixels < SCREEN_SIZE_SMALL || resources.displayMetrics.heightPixels < SCREEN_SIZE_SMALL) R.layout.activity_bigchart_small else R.layout.activity_bigchart + @SuppressLint("SetTextI18n") override fun setDataFields() { super.setDataFields() mStatus?.text = status.externalStatus + if (sp.getBoolean(R.string.key_show_cob, true)) (" " + this.status.cob) else "" @@ -118,4 +120,4 @@ class BigChartWatchface : BaseWatchFace() { setColorDark() } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/CircleWatchface.kt b/wear/src/main/java/info/nightscout/androidaps/watchfaces/CircleWatchface.kt index 0809275b7e..d24c1826a2 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/CircleWatchface.kt +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/CircleWatchface.kt @@ -197,7 +197,7 @@ class CircleWatchface : WatchFace() { myLayout?.layout(0, 0, myLayout?.measuredWidth ?: 0, myLayout?.measuredHeight ?: 0) } - val minutes: String + private val minutes: String get() { var minutes = "--'" if (singleBg.timeStamp != 0L) { @@ -421,4 +421,4 @@ class CircleWatchface : WatchFace() { override fun getWatchFaceStyle(): WatchFaceStyle { return WatchFaceStyle.Builder(this).setAcceptsTapEvents(true).build() } -} \ No newline at end of file +} diff --git a/wear/src/main/res/layout-notround/activity_bigchart.xml b/wear/src/main/res/layout-notround/activity_bigchart.xml index d610c6f38b..8c3a136e6a 100644 --- a/wear/src/main/res/layout-notround/activity_bigchart.xml +++ b/wear/src/main/res/layout-notround/activity_bigchart.xml @@ -1,108 +1,111 @@ - + android:gravity="center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-5dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="5dp" + android:textAlignment="center"> - - + android:layout_gravity="bottom" + android:layout_marginEnd="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="30sp" + tools:ignore="HardcodedText" /> - + - - + - + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_bigchart_small.xml b/wear/src/main/res/layout-notround/activity_bigchart_small.xml index 3a271e9ea0..9462a35612 100644 --- a/wear/src/main/res/layout-notround/activity_bigchart_small.xml +++ b/wear/src/main/res/layout-notround/activity_bigchart_small.xml @@ -1,111 +1,114 @@ - + android:gravity="center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-5dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="5dp" + android:textAlignment="center"> + + + android:gravity="center_horizontal" + android:text="---" + android:textColor="@color/white" + android:textSize="34sp" + tools:ignore="HardcodedText" /> - - - - - - - - + android:layout_gravity="center_vertical|center_horizontal|center" + android:layout_marginStart="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="24sp" + tools:ignore="HardcodedText" /> - + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_cockpit.xml b/wear/src/main/res/layout-notround/activity_cockpit.xml index 75290deb00..750cb2a80e 100644 --- a/wear/src/main/res/layout-notround/activity_cockpit.xml +++ b/wear/src/main/res/layout-notround/activity_cockpit.xml @@ -1,9 +1,13 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/airplane_cockpit_outside_clouds" + tools:context=".watchfaces.CockpitWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - + android:layout_weight="0.095" /> + android:layout_weight="0.2575" + android:orientation="horizontal"> + + + android:layout_weight="0.06" + android:baselineAligned="false" + android:orientation="vertical"> + + + android:id="@+id/highLight" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center" + android:layout_weight="1" + android:background="@drawable/airplane_led_grey_unlit" + android:gravity="center" + android:text="@string/first_char_high" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="8sp" + android:textStyle="bold" + tools:ignore="SmallSp" /> - - - - - - - - - - - - - + + android:id="@+id/lowLight" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center" + android:layout_weight="1" + android:background="@drawable/airplane_led_grey_unlit" + android:gravity="center" + android:text="@string/first_char_low" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="8sp" + android:textStyle="bold" + tools:ignore="SmallSp" /> + + + + + android:layout_weight="0.0775" + android:orientation="vertical"> @@ -120,369 +111,335 @@ android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="0.57" - android:orientation="vertical"> + android:orientation="horizontal"> + + + android:layout_weight="0.275" + android:orientation="vertical"> + + + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="0.5" + android:orientation="vertical" + android:weightSum="1"> + + + + + android:weightSum="1"> - + android:layout_weight="0.35" + tools:ignore="NestedWeights" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_gravity="center" + android:layout_weight="0.65" + android:gravity="center" + android:text="--'" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="14sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_digitalstyle.xml b/wear/src/main/res/layout-notround/activity_digitalstyle.xml index 87352b783a..d07e0bc616 100644 --- a/wear/src/main/res/layout-notround/activity_digitalstyle.xml +++ b/wear/src/main/res/layout-notround/activity_digitalstyle.xml @@ -1,12 +1,12 @@ - + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> + android:orientation="horizontal" + tools:ignore="HardcodedText" /> @@ -34,10 +36,11 @@ android:orientation="vertical" android:weightSum="100"> - + android:layout_weight="13.95" + tools:ignore="NestedWeights" /> - @@ -69,7 +72,8 @@ android:gravity="bottom|center_horizontal" android:text="@string/activity_carb" android:textColor="@color/light_grey" - android:textSize="10sp" /> + android:textSize="10sp" + tools:ignore="SmallSp, NestedWeights" /> + - - @@ -105,7 +110,7 @@ android:orientation="horizontal" android:weightSum="13"> - @@ -120,6 +125,7 @@ + android:weightSum="10" + tools:ignore="NestedWeights"> - @@ -146,7 +153,8 @@ android:textAlignment="center" android:textColor="@color/white" android:textSize="16sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:ignore="HardcodedText" /> + android:textSize="10sp" + tools:ignore="HardcodedText,SmallSp" /> - + @@ -186,21 +196,23 @@ android:gravity="top|center_horizontal" android:letterSpacing="-0.05" android:lines="1" - android:text="00,0" + android:text="@string/svg_00_0" android:textColor="@color/white" android:textSize="20sp" android:textStyle="bold" /> + + - - @@ -213,7 +225,7 @@ android:orientation="horizontal" android:weightSum="13"> - @@ -235,7 +247,8 @@ android:gravity="bottom|center_horizontal" android:text="@string/activity_IOB" android:textColor="@color/light_grey" - android:textSize="10sp" /> + android:textSize="10sp" + tools:ignore="SmallSp, NestedWeights" /> + - - + @@ -278,12 +293,14 @@ + android:orientation="vertical" + tools:ignore="NestedWeights"> - @@ -311,11 +328,11 @@ android:layout_height="match_parent" android:layout_weight="5" android:fontFamily="@font/roboto_condensed_regular" - android:text="DDD" android:textAllCaps="true" android:textColor="@color/white" android:textFontWeight="400" - android:textSize="18sp" /> + android:textSize="18sp" + tools:text="DDD" /> + android:visibility="gone" + tools:text="ww" /> - + @@ -354,10 +372,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/roboto_condensed_regular" + android:paddingStart="0dp" android:paddingEnd="4dp" - android:text="DD" android:textColor="@color/light_grey" - android:textSize="18sp" /> + android:textSize="18sp" + tools:text="DD" /> + + android:textSize="18sp" + tools:text="MMM" /> + + + @@ -383,7 +406,8 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" - android:gravity="left|center_vertical" + android:baselineAligned="false" + android:gravity="start|center_vertical" android:orientation="horizontal"> + android:textStyle="bold" + tools:text="HH" /> + @@ -416,29 +441,33 @@ android:id="@+id/minute" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="left" - android:layout_marginLeft="6sp" + android:layout_gravity="start" + android:layout_marginStart="6sp" android:layout_marginBottom="-8sp" android:fontFamily="@font/roboto_condensed_bold" - android:text="MI" android:textColor="@color/light_grey" android:textSize="26sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:text="MI" /> - + + android:textStyle="bold" + tools:ignore="SmallSp" + tools:text="AM" /> + + + @@ -449,7 +478,7 @@ android:layout_marginRight="7dp" android:layout_weight="1" android:baselineAligned="false" - android:gravity="left|top" + android:gravity="start|top" android:orientation="vertical" android:weightSum="10"> @@ -472,7 +501,8 @@ android:text="+/-" android:textColor="@color/light_grey" android:textSize="10sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:ignore="HardcodedText, SmallSp, NestedWeights" /> + android:textStyle="bold" + tools:ignore="SmallSp" /> + android:textStyle="bold" + tools:ignore="HardcodedText,SmallSp" /> + android:visibility="gone" + tools:ignore="HardcodedText,SmallSp" /> + android:textStyle="bold" + tools:ignore="SmallSp" /> + android:visibility="gone" + tools:ignore="SmallSp" + tools:text="bgi" /> + @@ -547,26 +583,28 @@ android:layout_height="0dp" android:layout_gravity="bottom" android:layout_weight="1" - android:gravity="center_horizontal|top" /> + android:gravity="center_horizontal|top" + tools:ignore="NestedWeights" /> - + + + - diff --git a/wear/src/main/res/layout-notround/activity_home.xml b/wear/src/main/res/layout-notround/activity_home.xml index dd700fcf5c..b20301ae4a 100644 --- a/wear/src/main/res/layout-notround/activity_home.xml +++ b/wear/src/main/res/layout-notround/activity_home.xml @@ -1,156 +1,158 @@ - + android:gravity="center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + android:weightSum="1" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - + + + android:baselineAligned="false" + android:gravity="center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + android:weightSum="1"> + + - - - - - - - - + android:gravity="center_horizontal|bottom" + android:text="@string/delta_na" + android:textColor="@color/white" + android:textSize="10sp" + android:textStyle="bold" + tools:ignore="SmallSp" /> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_home_2.xml b/wear/src/main/res/layout-notround/activity_home_2.xml index 60ae6c3cf6..faaaca080e 100644 --- a/wear/src/main/res/layout-notround/activity_home_2.xml +++ b/wear/src/main/res/layout-notround/activity_home_2.xml @@ -1,372 +1,351 @@ - + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> + android:id="@+id/primary_layout" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center_horizontal" + android:layout_weight="0.27" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:textAlignment="center"> + + + + + android:orientation="vertical"> - - + android:gravity="center_horizontal|bottom" + android:text="--" + android:textAlignment="center" + android:textColor="@color/white" + android:textSize="22sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:text="--'" + android:textColor="@color/white" + android:textSize="14sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_home_large.xml b/wear/src/main/res/layout-notround/activity_home_large.xml index a3ffe072f3..9595976def 100644 --- a/wear/src/main/res/layout-notround/activity_home_large.xml +++ b/wear/src/main/res/layout-notround/activity_home_large.xml @@ -1,138 +1,136 @@ - + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_width="147dp" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="15dp" + android:textAlignment="center" + android:weightSum="1"> + + + android:weightSum="1"> + + + + + + - + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_nochart.xml b/wear/src/main/res/layout-notround/activity_nochart.xml index 41f44e4404..6f4da2c1b5 100644 --- a/wear/src/main/res/layout-notround/activity_nochart.xml +++ b/wear/src/main/res/layout-notround/activity_nochart.xml @@ -1,100 +1,103 @@ - + android:gravity="center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-5dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="5dp" + android:textAlignment="center"> - - + android:layout_gravity="bottom" + android:layout_marginEnd="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="40sp" + tools:ignore="HardcodedText" /> - + - - + - + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_nochart_small.xml b/wear/src/main/res/layout-notround/activity_nochart_small.xml index c8f82fad03..a02a672216 100644 --- a/wear/src/main/res/layout-notround/activity_nochart_small.xml +++ b/wear/src/main/res/layout-notround/activity_nochart_small.xml @@ -1,116 +1,112 @@ - + android:gravity="center_vertical|center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.NoChartWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - + + - - - - - - - - - - + android:text="---" + android:textColor="@color/white" + android:textSize="45sp" + tools:ignore="HardcodedText" /> - - - - - - - - - + android:layout_height="match_parent" + android:layout_gravity="center_horizontal" + android:layout_marginStart="5dp" + android:gravity="center_vertical|center_horizontal|center" + android:text=" ---" + android:textColor="@color/white" + android:textSize="26sp" + tools:ignore="HardcodedText" /> - \ No newline at end of file + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-notround/activity_steampunk.xml b/wear/src/main/res/layout-notround/activity_steampunk.xml index e56d515d1b..fc414e9c39 100644 --- a/wear/src/main/res/layout-notround/activity_steampunk.xml +++ b/wear/src/main/res/layout-notround/activity_steampunk.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".watchfaces.SteampunkWatchface" - tools:deviceIds="wear_square"> + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> @@ -57,13 +59,11 @@ android:orientation="vertical" android:weightSum="1"> - + tools:ignore="NestedWeights" /> @@ -108,7 +108,7 @@ @@ -130,7 +130,7 @@ @@ -170,11 +170,11 @@ android:orientation="horizontal" android:weightSum="1"> - + tools:ignore="NestedWeights" /> - - + android:layout_weight="0.03" /> @@ -207,26 +206,26 @@ android:orientation="vertical" android:weightSum="1"> - + android:layout_weight="0.15" /> - + tools:ignore="NestedWeights" /> + android:textSize="12sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> @@ -268,9 +269,10 @@ android:text="--%" android:textAlignment="center" android:textColor="@color/black_86p" - android:textSize="10sp" + android:textSize="12sp" android:textStyle="bold" - android:visibility="gone" /> + android:visibility="gone" + tools:ignore="HardcodedText" /> + android:textSize="12sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> @@ -300,28 +303,28 @@ android:gravity="center" android:paddingStart="10dp" android:paddingTop="8dp" + android:paddingEnd="0dp" android:rotation="24" android:text="-'" android:textAlignment="center" android:textColor="@color/black_86p" - android:textSize="10sp" - android:textStyle="bold" /> + android:textSize="12sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - + android:layout_weight="0.32" /> - + android:layout_weight="0.64" /> @@ -330,8 +333,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/steampunk_cover_plate" - android:orientation="vertical"> - + android:orientation="vertical" /> - + android:visibility="gone" /> diff --git a/wear/src/main/res/layout-round/activity_bigchart.xml b/wear/src/main/res/layout-round/activity_bigchart.xml index d610c6f38b..58c7a609a7 100644 --- a/wear/src/main/res/layout-round/activity_bigchart.xml +++ b/wear/src/main/res/layout-round/activity_bigchart.xml @@ -1,108 +1,107 @@ - + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-2dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="5dp" + android:textAlignment="center"> - - + android:layout_gravity="bottom" + android:layout_marginEnd="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="30sp" + tools:ignore="HardcodedText" /> - + - - + - + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_bigchart_small.xml b/wear/src/main/res/layout-round/activity_bigchart_small.xml index 3a271e9ea0..c705f913dd 100644 --- a/wear/src/main/res/layout-round/activity_bigchart_small.xml +++ b/wear/src/main/res/layout-round/activity_bigchart_small.xml @@ -1,111 +1,113 @@ - + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-5dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingTop="5dp" + android:textAlignment="center"> + + + android:gravity="center_horizontal" + android:text="---" + android:textColor="@color/white" + android:textSize="34sp" + tools:ignore="HardcodedText" /> - - - - - - - - + android:layout_gravity="center_vertical|center_horizontal|center" + android:layout_marginStart="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="24sp" + tools:ignore="HardcodedText" /> - + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_cockpit.xml b/wear/src/main/res/layout-round/activity_cockpit.xml index 8486b4d211..4f967c714f 100644 --- a/wear/src/main/res/layout-round/activity_cockpit.xml +++ b/wear/src/main/res/layout-round/activity_cockpit.xml @@ -1,9 +1,13 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/airplane_cockpit_outside_clouds" + tools:context=".watchfaces.CockpitWatchface" + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> - - - + android:layout_weight="0.095" /> + android:layout_weight="0.2575" + android:orientation="horizontal"> + + + android:layout_weight="0.06" + android:baselineAligned="false" + android:orientation="vertical"> + + + android:id="@+id/highLight" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center" + android:layout_weight="1" + android:background="@drawable/airplane_led_grey_unlit" + android:gravity="center" + android:text="@string/first_char_high" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="8sp" + android:textStyle="bold" + tools:ignore="SmallSp" /> - - - - - - - - - - - - - + + android:id="@+id/lowLight" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center" + android:layout_weight="1" + android:background="@drawable/airplane_led_grey_unlit" + android:gravity="center" + android:text="@string/first_char_low" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="8sp" + android:textStyle="bold" + tools:ignore="SmallSp" /> + + + + + android:layout_weight="0.0775" + android:orientation="vertical"> @@ -120,369 +111,334 @@ android:layout_width="match_parent" android:layout_height="0px" android:layout_weight="0.57" - android:orientation="vertical"> + android:orientation="horizontal"> + + + android:layout_weight="0.275" + android:orientation="vertical"> + + + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="0.5" + android:orientation="vertical" + android:weightSum="1"> + + + + + android:weightSum="1"> - + android:layout_weight="0.35" + tools:ignore="NestedWeights" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_gravity="center" + android:layout_weight="0.65" + android:gravity="center" + android:text="--'" + android:textAlignment="center" + android:textColor="@color/primary_text_dark" + android:textSize="14sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_digitalstyle.xml b/wear/src/main/res/layout-round/activity_digitalstyle.xml index bc21b8d326..feeedc2455 100644 --- a/wear/src/main/res/layout-round/activity_digitalstyle.xml +++ b/wear/src/main/res/layout-round/activity_digitalstyle.xml @@ -1,12 +1,12 @@ - + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> + android:orientation="horizontal" + tools:ignore="HardcodedText" /> @@ -34,7 +36,7 @@ android:orientation="vertical" android:weightSum="100"> - @@ -47,7 +49,7 @@ android:orientation="horizontal" android:weightSum="13"> - @@ -69,7 +71,8 @@ android:gravity="bottom|center_horizontal" android:text="@string/activity_carb" android:textColor="@color/light_grey" - android:textSize="10sp" /> + android:textSize="10sp" + tools:ignore="SmallSp" /> + - - @@ -105,7 +109,7 @@ android:orientation="horizontal" android:weightSum="13"> - @@ -130,7 +134,7 @@ android:orientation="horizontal" android:weightSum="10"> - @@ -147,7 +151,8 @@ android:textAlignment="center" android:textColor="@color/white" android:textSize="16sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:ignore="HardcodedText" /> + android:textSize="10sp" + tools:ignore="HardcodedText,SmallSp" /> - + @@ -187,21 +194,23 @@ android:gravity="top|center_horizontal" android:letterSpacing="-0.05" android:lines="1" - android:text="00,0" + android:text="@string/svg_00_0" android:textColor="@color/white" android:textSize="20sp" android:textStyle="bold" /> + + - - @@ -214,7 +223,7 @@ android:orientation="horizontal" android:weightSum="13"> - @@ -236,7 +245,8 @@ android:gravity="bottom|center_horizontal" android:text="@string/activity_IOB" android:textColor="@color/light_grey" - android:textSize="10sp" /> + android:textSize="10sp" + tools:ignore="SmallSp" /> + - - + @@ -279,12 +291,13 @@ - @@ -312,11 +325,11 @@ android:layout_height="match_parent" android:layout_weight="5" android:fontFamily="@font/roboto_condensed_regular" - android:text="DDD" android:textAllCaps="true" android:textColor="@color/white" android:textFontWeight="400" - android:textSize="18sp" /> + android:textSize="18sp" + tools:text="DDD" /> + android:visibility="gone" + tools:text="ww" /> - + @@ -355,10 +369,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/roboto_condensed_regular" + android:paddingStart="0dp" android:paddingEnd="4dp" - android:text="DD" android:textColor="@color/light_grey" - android:textSize="18sp" /> + android:textSize="18sp" + tools:text="DD" /> + + android:textSize="18sp" + tools:text="MMM" /> + + + @@ -384,29 +403,32 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="4" - android:gravity="left|center_vertical" + android:baselineAligned="false" + android:gravity="start|center_vertical" android:orientation="horizontal"> + + android:textStyle="bold" + tools:text="HH" /> + @@ -416,29 +438,33 @@ android:id="@+id/minute" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="left" - android:layout_marginLeft="6sp" + android:layout_gravity="start" + android:layout_marginStart="6sp" android:layout_marginBottom="-8sp" android:fontFamily="@font/roboto_condensed_bold" - android:text="MI" android:textColor="@color/light_grey" android:textSize="26sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:text="MI" /> + android:textStyle="bold" + tools:ignore="SmallSp" + tools:text="AM" /> + + + @@ -449,7 +475,7 @@ android:layout_marginRight="7dp" android:layout_weight="1" android:baselineAligned="false" - android:gravity="left|top" + android:gravity="start|top" android:orientation="vertical" android:weightSum="10"> @@ -472,7 +498,8 @@ android:text="+/-" android:textColor="@color/light_grey" android:textSize="10sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:ignore="HardcodedText,SmallSp" /> + android:textStyle="bold" + tools:ignore="SmallSp" /> + android:textStyle="bold" + tools:ignore="HardcodedText,SmallSp" /> + android:visibility="gone" + tools:ignore="HardcodedText,SmallSp" /> + android:textStyle="bold" + tools:ignore="SmallSp" /> + android:visibility="gone" + tools:ignore="SmallSp" + tools:text="bgi" /> + @@ -552,22 +585,22 @@ - + + - diff --git a/wear/src/main/res/layout-round/activity_home.xml b/wear/src/main/res/layout-round/activity_home.xml index 008ed7d129..e886eada50 100644 --- a/wear/src/main/res/layout-round/activity_home.xml +++ b/wear/src/main/res/layout-round/activity_home.xml @@ -1,155 +1,164 @@ - + android:orientation="vertical" + android:textAlignment="center" + android:weightSum="1" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_gravity="center_horizontal|bottom" + android:layout_marginBottom="-2dp" + android:gravity="bottom|end" + android:paddingStart="0dp" + android:paddingTop="-2dp" + android:paddingEnd="5dp" + android:text="---" + android:textColor="@color/white" + android:textSize="41sp" + tools:ignore="HardcodedText" /> - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_home_2.xml b/wear/src/main/res/layout-round/activity_home_2.xml index 64e6a411f0..2a16cfb66a 100644 --- a/wear/src/main/res/layout-round/activity_home_2.xml +++ b/wear/src/main/res/layout-round/activity_home_2.xml @@ -1,385 +1,367 @@ - + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> + + + android:id="@+id/primary_layout" + android:layout_width="fill_parent" + android:layout_height="0px" + android:layout_gravity="center_horizontal" + android:layout_weight="0.27" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:textAlignment="center"> + + + + - - + android:baselineAligned="false" + android:gravity="center_vertical" + android:orientation="vertical" + android:paddingStart="0dp" + android:paddingEnd="4dp"> - - + android:gravity="center_horizontal|bottom" + android:text="--" + android:textAlignment="center" + android:textColor="@color/white" + android:textSize="22sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:text="--'" + android:textColor="@color/white" + android:textSize="14sp" + android:textStyle="bold" + tools:ignore="HardcodedText" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_home_large.xml b/wear/src/main/res/layout-round/activity_home_large.xml index 40f26dc17c..35bb86cdf1 100644 --- a/wear/src/main/res/layout-round/activity_home_large.xml +++ b/wear/src/main/res/layout-round/activity_home_large.xml @@ -1,138 +1,138 @@ - + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + android:weightSum="1"> + + + + + + - + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_nochart.xml b/wear/src/main/res/layout-round/activity_nochart.xml index 41f44e4404..0ae2e794e0 100644 --- a/wear/src/main/res/layout-round/activity_nochart.xml +++ b/wear/src/main/res/layout-round/activity_nochart.xml @@ -1,100 +1,101 @@ - + android:gravity="center_vertical|center_horizontal" + android:orientation="vertical" + android:textAlignment="center" + tools:context=".watchfaces.NoChartWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - - - - - - - - - - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="-15dp" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:textAlignment="center"> - - + android:layout_gravity="bottom" + android:layout_marginEnd="5dp" + android:gravity="center_horizontal|bottom" + android:text="---" + android:textColor="@color/white" + android:textSize="40sp" + tools:ignore="HardcodedText" /> - + - - + - + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_nochart_small.xml b/wear/src/main/res/layout-round/activity_nochart_small.xml index c8f82fad03..070d9baf38 100644 --- a/wear/src/main/res/layout-round/activity_nochart_small.xml +++ b/wear/src/main/res/layout-round/activity_nochart_small.xml @@ -1,116 +1,114 @@ - + android:gravity="center_vertical|center_horizontal" + android:orientation="vertical" + tools:context=".watchfaces.AapsWatchface" + tools:deviceIds="wear_square" + tools:ignore="MissingDefaultResource"> - + + - - - - - - - - - - + android:text="---" + android:textColor="@color/white" + android:textSize="42sp" + tools:ignore="HardcodedText" /> - - - - - - - - - + android:layout_height="match_parent" + android:layout_gravity="center_horizontal" + android:layout_marginStart="5dp" + android:layout_marginBottom="-15dp" + android:gravity="center_vertical|center_horizontal|center" + android:text=" ---" + android:textColor="@color/white" + android:textSize="22sp" + tools:ignore="HardcodedText" /> - \ No newline at end of file + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout-round/activity_steampunk.xml b/wear/src/main/res/layout-round/activity_steampunk.xml index 78f9c52383..fc414e9c39 100644 --- a/wear/src/main/res/layout-round/activity_steampunk.xml +++ b/wear/src/main/res/layout-round/activity_steampunk.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".watchfaces.SteampunkWatchface" - tools:deviceIds="wear_round"> + tools:deviceIds="wear_round" + tools:ignore="MissingDefaultResource"> @@ -57,13 +59,11 @@ android:orientation="vertical" android:weightSum="1"> - + tools:ignore="NestedWeights" /> - + tools:ignore="NestedWeights" /> - - + android:layout_weight="0.03" /> @@ -207,26 +206,26 @@ android:orientation="vertical" android:weightSum="1"> - + android:layout_weight="0.15" /> - + tools:ignore="NestedWeights" /> + android:textStyle="bold" + tools:ignore="HardcodedText" /> @@ -270,7 +271,8 @@ android:textColor="@color/black_86p" android:textSize="12sp" android:textStyle="bold" - android:visibility="gone" /> + android:visibility="gone" + tools:ignore="HardcodedText" /> + android:textStyle="bold" + tools:ignore="HardcodedText" /> @@ -300,28 +303,28 @@ android:gravity="center" android:paddingStart="10dp" android:paddingTop="8dp" + android:paddingEnd="0dp" android:rotation="24" android:text="-'" android:textAlignment="center" android:textColor="@color/black_86p" android:textSize="12sp" - android:textStyle="bold" /> + android:textStyle="bold" + tools:ignore="HardcodedText" /> - + android:layout_weight="0.32" /> - + android:layout_weight="0.64" /> @@ -330,8 +333,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/steampunk_cover_plate" - android:orientation="vertical"> - + android:orientation="vertical" /> - + android:visibility="gone" /> diff --git a/wear/src/main/res/layout-v26/list_item.xml b/wear/src/main/res/layout-v26/list_item.xml index 7e5efb671f..2616da7efb 100644 --- a/wear/src/main/res/layout-v26/list_item.xml +++ b/wear/src/main/res/layout-v26/list_item.xml @@ -12,9 +12,9 @@ android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentStart="true" - android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginStart="10dp" + android:importantForAccessibility="no" android:src="@drawable/circle" /> + android:textStyle="bold" + tools:text="action item" /> diff --git a/wear/src/main/res/layout/action_confirm_ok.xml b/wear/src/main/res/layout/action_confirm_ok.xml index fd0d4c89b9..097dc75adb 100644 --- a/wear/src/main/res/layout/action_confirm_ok.xml +++ b/wear/src/main/res/layout/action_confirm_ok.xml @@ -1,26 +1,22 @@ - + - + android:layout_margin="10sp" + android:background="@drawable/circle" + android:backgroundTint="@color/white" + android:contentDescription="@string/action_confirm" + android:padding="25sp" + android:src="@drawable/ic_confirm" + app:tint="@color/white" /> - - - - + diff --git a/wear/src/main/res/layout/action_confirm_text.xml b/wear/src/main/res/layout/action_confirm_text.xml index 031d98d1e2..9fde2356c6 100644 --- a/wear/src/main/res/layout/action_confirm_text.xml +++ b/wear/src/main/res/layout/action_confirm_text.xml @@ -1,5 +1,6 @@ @@ -11,18 +12,21 @@ + android:layout_height="match_parent" + android:focusable="true" + android:focusableInTouchMode="true"> + + android:textColor="@color/white" + tools:text="message" /> + - \ No newline at end of file + + diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusminus_item.xml index be5b622dbe..c3cbe263ba 100644 --- a/wear/src/main/res/layout/action_editplusminus_item.xml +++ b/wear/src/main/res/layout/action_editplusminus_item.xml @@ -1,66 +1,68 @@ - + + + + android:orientation="vertical"> - + android:cursorVisible="false" + android:gravity="center_horizontal" + android:inputType="numberDecimal" + android:minWidth="50dp" + android:padding="10dp" + android:textColor="@color/white" + android:textSize="45sp" + tools:text="112" /> - - - - - - - + android:gravity="center" + android:labelFor="@+id/amountfield" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/white" + android:textSize="25sp" + tools:ignore="LabelFor" + tools:text="label" /> - + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml index 980677522c..bf3418ca2c 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml @@ -1,69 +1,68 @@ - + + + + android:gravity="center" + android:orientation="vertical"> + + + + - - - - - - - - - - + android:backgroundTint="@color/white" + android:contentDescription="@string/decrement" + android:src="@drawable/ic_action_minus" + android:tint="@color/white" /> - + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml index a1b2107768..78c5d7e817 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml @@ -1,69 +1,68 @@ - + + android:gravity="center" + android:orientation="vertical"> - + android:cursorVisible="false" + android:gravity="center_horizontal" + android:inputType="numberDecimal" + android:minWidth="100dp" + android:paddingTop="10dp" + android:textColor="@color/white" + android:textSize="45sp" + tools:text="112" /> - - - - - - - + + android:backgroundTint="@color/white" + android:contentDescription="@string/decrement" + android:src="@drawable/ic_action_minus" + android:tint="@color/white" /> - + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml index 357fa7c4f2..0b396d8b7f 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml @@ -1,71 +1,67 @@ - + android:orientation="horizontal"> + + - + + + android:layout_gravity="center_vertical|center_horizontal" + android:background="@android:color/transparent" + android:cursorVisible="false" + android:gravity="center_vertical|center_horizontal" + android:inputType="numberDecimal" + android:minWidth="50dp" + android:padding="10dp" + android:textColor="@color/white" + android:textSize="45sp" + tools:text="112" /> - + - - - - - - - - - - + + + + diff --git a/wear/src/main/res/layout/actions_list_activity.xml b/wear/src/main/res/layout/actions_list_activity.xml index 45037c8337..4acdee7c25 100644 --- a/wear/src/main/res/layout/actions_list_activity.xml +++ b/wear/src/main/res/layout/actions_list_activity.xml @@ -1,9 +1,9 @@ - + android:textSize="18sp" + tools:text="Title" /> + + android:visibility="gone" + tools:text="Title" /> diff --git a/wear/src/main/res/layout/activity_circle.xml b/wear/src/main/res/layout/activity_circle.xml index 9837a8a2aa..57a9c6325a 100644 --- a/wear/src/main/res/layout/activity_circle.xml +++ b/wear/src/main/res/layout/activity_circle.xml @@ -1,53 +1,46 @@ - - + - - - + + + tools:text="999" /> - + - + - - - + diff --git a/wear/src/main/res/layout/grid_layout.xml b/wear/src/main/res/layout/grid_layout.xml index 26f1e92a6a..51091b08c4 100644 --- a/wear/src/main/res/layout/grid_layout.xml +++ b/wear/src/main/res/layout/grid_layout.xml @@ -1,16 +1,17 @@ + android:layout_height="match_parent"> + android:visibility="gone" + tools:text="Title" /> + android:textSize="18sp" + tools:text="Title" /> + app:dotFadeOutDelay="100000" /> diff --git a/wear/src/main/res/layout/list_item.xml b/wear/src/main/res/layout/list_item.xml index c5fd3b2433..2c5fbb2653 100644 --- a/wear/src/main/res/layout/list_item.xml +++ b/wear/src/main/res/layout/list_item.xml @@ -11,10 +11,9 @@ android:id="@+id/menuItemIcon" android:layout_width="35dp" android:layout_height="35dp" - android:layout_alignParentStart="true" - android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginStart="10dp" + android:importantForAccessibility="no" android:src="@drawable/circle" /> + android:textStyle="bold" + tools:text="action item" /> diff --git a/wear/src/main/res/values-cs-rCZ/strings.xml b/wear/src/main/res/values-cs-rCZ/strings.xml index f792859d43..84ebb1a0ae 100644 --- a/wear/src/main/res/values-cs-rCZ/strings.xml +++ b/wear/src/main/res/values-cs-rCZ/strings.xml @@ -168,4 +168,20 @@ Není dostupná žádná konfigurace Ovládání hodinkami vypnuto Žádná data k dispozici + zvýšení + snížení + V + N + prům + --U + --g + -.--U/h + Uploader: ---% + S: žádný status + Před -- minutamí + --- mg/dl + Žádný stav smyčky + 000g + 00,0 + 0,00U diff --git a/wear/src/main/res/values-es-rES/strings.xml b/wear/src/main/res/values-es-rES/strings.xml index bbd8afaa5b..680c610a92 100644 --- a/wear/src/main/res/values-es-rES/strings.xml +++ b/wear/src/main/res/values-es-rES/strings.xml @@ -168,4 +168,20 @@ No hay configuración disponible Controles Wear desactivados No hay datos disponibles + incremento + decremento + A + B + media + --U + --g + -.--U/h + Subido: ---% + S: sin estado + -- minutos atrás + --- mg/dl + Sin estado del lazo + 000g + 00,0 + 0,00U diff --git a/wear/src/main/res/values-fr-rFR/strings.xml b/wear/src/main/res/values-fr-rFR/strings.xml index b4501502bf..645f5d699b 100644 --- a/wear/src/main/res/values-fr-rFR/strings.xml +++ b/wear/src/main/res/values-fr-rFR/strings.xml @@ -168,4 +168,20 @@ Aucune configuration disponible Contrôles Wear désactivés Aucune donnée disponible + augmenter + diminuer + H + B + moy + --U + --g + -.-- U/h + Téléchargement : ---% + aucun statut + Il y a -- minutes + --- mg/dl + Aucun statut de la boucle + 000 g + 00,0 + 0,00 U diff --git a/wear/src/main/res/values-no-rNO/strings.xml b/wear/src/main/res/values-no-rNO/strings.xml index 91483daf3a..94fe4309d0 100644 --- a/wear/src/main/res/values-no-rNO/strings.xml +++ b/wear/src/main/res/values-no-rNO/strings.xml @@ -168,4 +168,20 @@ Ingen konfigurasjon tilgjengelig Wear kontroller deaktivert Ingen data tilgjengelig + økning + reduksjon + H + L + snitt + --E + --g + -.--E/t + Opplaster: ---% + S: ingen status + -- Minutter siden + --- mg/dl + Ingen loop status + 000g + 00,0 + 0,00E diff --git a/wear/src/main/res/values-ru-rRU/strings.xml b/wear/src/main/res/values-ru-rRU/strings.xml index cf45f1a812..4f320cac43 100644 --- a/wear/src/main/res/values-ru-rRU/strings.xml +++ b/wear/src/main/res/values-ru-rRU/strings.xml @@ -2,6 +2,15 @@ AAPS AAPS + AAPS + AAPS (Большой) + AAPS (Крупный график) + AAPS (Без графика) + AAPS (круглый) + AAPS(v2) + AAPS (кабина пилота) + AAPS (Стимпанк) + AAPS (ЦифровойСтиль) AAPS (Действия) AAPS(ВремЦель) AAPS(Мастер) @@ -55,11 +64,13 @@ Действия при нажатии кнопки расширений Юникод в репликации Версия: + Еще настройки циферблатов Смотрите конфигурацию циферблата. ВремЦ Калькулятор Кальк Терапия + Терап Болюс Углеводы растянутые углеводы eCarbs @@ -70,18 +81,38 @@ Не показывать По умолчанию Menu + XL + Длительность + Запрошена временная цель + Запрошен мастер настройки + Запрошена терапия + Запрошен Болюс + Расчет запрошен + Заполнение запрошено + Углеводы запрошены + Запрос на смену профиля + Цель + Низкое значение + Высокое значение + Углеводы растянутые углеводы eCarbs + Процент + Начало [min] + Продолжительность [h] + Инсулин Предустановка 1 Предустановка 2 Предустановка 3 Произвольное количество ПОДТВЕРДИТЬ сдвиг по времени + Болюс Подается болюс нажмите для отмены ОТМЕНИТЬ БОЛЮС Помпа Замкнутый цикл + Смена профиля TDD/общая суточная доза Углеводы IOB @@ -128,4 +159,29 @@ Во время зарядки Режим: всегда вкл Режим: всегда вкл при зарядке + Прием пищи + Гипо + Нагрузка + Вручную + Отмена + Отсутствует + Нет доступной конфигурации + Функция управления Wear выключена + Нет данных + приращение + декремент + В + Н + сред + --ед + --г + -.--ед/ч + Загрузчик: --% + S: статус отсутствует + -- Минут назад + --- мг/дл + Нет статуса + 000г + 00,0 + 0,00 ед diff --git a/wear/src/main/res/values-sk-rSK/strings.xml b/wear/src/main/res/values-sk-rSK/strings.xml index 8093367939..08dde6af7b 100644 --- a/wear/src/main/res/values-sk-rSK/strings.xml +++ b/wear/src/main/res/values-sk-rSK/strings.xml @@ -168,4 +168,19 @@ Nie je dostupná žiadna konfigurácia Ovládanie hodinkami vypnuté Žiadne údaje nie sú k dispozícii + prírastok + zníženie + H + L + priemer + --JI + --g + -.--JI/h + S: žiadny stav + Pred -- minútami + --- mg/dl + Žiadny stav uzavretého okruhu + 000g + 00,0 + 0,00JI diff --git a/wear/src/main/res/values-tr-rTR/strings.xml b/wear/src/main/res/values-tr-rTR/strings.xml index 872f9cde00..5754310521 100644 --- a/wear/src/main/res/values-tr-rTR/strings.xml +++ b/wear/src/main/res/values-tr-rTR/strings.xml @@ -168,4 +168,20 @@ Mevcut yapılandırma yok Saat kontrolleri devre dışı Veri yok + artış + azalma + Y + D + ort + --Ü + --g + -.--Ü/sa + Yükleyici: ---% + S: durum yok + -- Dakika önce + --- mg/dl + Döngü Durumu Yok + 000g + 00,0 + 0,00Ü diff --git a/wear/src/main/res/values-zh-rCN/strings.xml b/wear/src/main/res/values-zh-rCN/strings.xml index a7b0cdfd1f..0dd214aefa 100644 --- a/wear/src/main/res/values-zh-rCN/strings.xml +++ b/wear/src/main/res/values-zh-rCN/strings.xml @@ -2,6 +2,15 @@ AAPS AAPS + AAPS + AAPS(大) + AAPS(大图) + AAPS(无图) + AAPS(圆形) + AAPS(v2) + AAPS(驾驶) + AAPS(机械) + AAPS(数字风格) AAPS(操作) AAPS(临时目标) AAPS(快速向导) @@ -55,6 +64,7 @@ 折叠Tap操作 折叠中的代码 版本 + 更多手表表盘设置 请查看手表表盘配置。 临时目标 计算器 @@ -80,6 +90,7 @@ 计算请求 Fill 充盈请求 碳水化合物请求 + 请求配置文件切换 目标 @@ -101,6 +112,7 @@ 取消大剂量 胰岛素泵 闭环 + 切换配置文件 日总量 碳水化合物 活性胰岛素 diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index 1869913e37..d5331aa883 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -222,5 +222,21 @@ dark input_design complication_tap_action + increment + decrement + H + L + avg + --U + --g + -.--U/h + Uploader: ---% + S: no status + -- Minutes ago + --- mg/dl + No Loop Status + 000g + 00,0 + 0,00U diff --git a/wear/src/main/res/xml/tile_configuration_activity.xml b/wear/src/main/res/xml/tile_configuration_activity.xml index 19abf54a05..e1287e1d9f 100644 --- a/wear/src/main/res/xml/tile_configuration_activity.xml +++ b/wear/src/main/res/xml/tile_configuration_activity.xml @@ -1,33 +1,32 @@ - + + android:entryValues="@array/tile_action_values" + android:key="tile_action_1" + android:title="Action 1" /> + android:entryValues="@array/tile_action_values" + android:key="tile_action_2" + android:title="Action 2" /> + android:entryValues="@array/tile_action_values" + android:key="tile_action_3" + android:title="Action 3" /> + android:entryValues="@array/tile_action_values" + android:key="tile_action_4" + android:title="Action 4" /> diff --git a/wear/src/main/res/xml/tile_configuration_tempt.xml b/wear/src/main/res/xml/tile_configuration_tempt.xml index 44ba856ef0..de687d8f96 100644 --- a/wear/src/main/res/xml/tile_configuration_tempt.xml +++ b/wear/src/main/res/xml/tile_configuration_tempt.xml @@ -1,33 +1,32 @@ - + + android:entryValues="@array/tile_tempt_values" + android:key="tile_tempt_1" + android:title="Target 1" /> + android:entryValues="@array/tile_tempt_values" + android:key="tile_tempt_2" + android:title="Target 2" /> + android:entryValues="@array/tile_tempt_values" + android:key="tile_tempt_3" + android:title="Target 3" /> + android:entryValues="@array/tile_tempt_values" + android:key="tile_tempt_4" + android:title="Target 4" /> diff --git a/wear/src/test/java/info/nightscout/androidaps/testing/mockers/WearUtilMocker.kt b/wear/src/test/java/info/nightscout/androidaps/testing/mockers/WearUtilMocker.kt index 5453200be2..e59164aee0 100644 --- a/wear/src/test/java/info/nightscout/androidaps/testing/mockers/WearUtilMocker.kt +++ b/wear/src/test/java/info/nightscout/androidaps/testing/mockers/WearUtilMocker.kt @@ -1,14 +1,9 @@ package info.nightscout.androidaps.testing.mockers -import android.os.Bundle -import com.google.android.gms.wearable.Asset -import com.google.android.gms.wearable.DataMap import info.nightscout.androidaps.interaction.utils.Constants import info.nightscout.androidaps.interaction.utils.WearUtil import org.mockito.ArgumentMatchers import org.mockito.Mockito -import org.mockito.invocation.InvocationOnMock -import org.mockito.stubbing.Answer class WearUtilMocker(private val wearUtil: WearUtil) { @@ -23,11 +18,11 @@ class WearUtilMocker(private val wearUtil: WearUtil) { fun prepareMockNoReal() { resetClock() - Mockito.doAnswer { invocation: InvocationOnMock? -> REF_NOW + clockMsDiff }.`when`(wearUtil).timestamp() + Mockito.doAnswer { REF_NOW + clockMsDiff }.`when`(wearUtil).timestamp() Mockito.doReturn(null).`when`(wearUtil).getWakeLock(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt()) } - fun resetClock() { + private fun resetClock() { clockMsDiff = 0L } @@ -35,50 +30,10 @@ class WearUtilMocker(private val wearUtil: WearUtil) { clockMsDiff += byMilliseconds } - fun setClock(atMillisecondsSinceEpoch: Long) { - clockMsDiff = atMillisecondsSinceEpoch - REF_NOW - } - fun backInTime(d: Int, h: Int, m: Int, s: Int): Long { return REF_NOW - (Constants.DAY_IN_MS * d + Constants.HOUR_IN_MS * h + Constants.MINUTE_IN_MS * m + Constants.SECOND_IN_MS * s) } - @Suppress("UNCHECKED_CAST") - private val bundleToDataMapMock: Answer<*> = Answer { invocation: InvocationOnMock -> - val map = DataMap() - val bundle = invocation.getArgument(0) - for (key in bundle.keySet()) { - val v = bundle[key] - if (v is Asset) map.putAsset(key, v) - if (v is Boolean) map.putBoolean(key, v) - if (v is Byte) map.putByte(key, (v as Byte?)!!) - if (v is ByteArray) map.putByteArray(key, v) - if (v is DataMap) map.putDataMap(key, v) - if (v is Double) map.putDouble(key, v) - if (v is Float) map.putFloat(key, (v as Float)) - if (v is FloatArray) map.putFloatArray(key, v) - if (v is Int) map.putInt(key, v) - if (v is Long) map.putLong(key, v) - if (v is LongArray) map.putLongArray(key, v) - if (v is String) map.putString(key, v) - if (v is Array<*>) map.putStringArray(key, v as Array) - if (v is ArrayList<*>) { - if (v.isNotEmpty()) { - if (v[0] is Int) { - map.putIntegerArrayList(key, v as ArrayList) - } - if (v[0] is String) { - map.putStringArrayList(key, v as ArrayList) - } - if (v[0] is DataMap) { - map.putDataMapArrayList(key, v as ArrayList) - } - } - } - } - map - } - companion object { const val REF_NOW = 1572610530000L