diff --git a/app/build.gradle b/app/build.gradle index ddd3aae0cc..5bda0b7b45 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,13 +1,10 @@ buildscript { repositories { - maven { url 'https://maven.fabric.io/public' } jcenter() } dependencies { - classpath 'io.fabric.tools:gradle:1.+' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4' - classpath 'de.undercouch:gradle-download-task:3.4.3' } } apply plugin: 'com.android.application' @@ -15,10 +12,8 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.gms.google-services' -apply plugin: 'io.fabric' apply plugin: 'jacoco-android' -apply plugin: 'de.undercouch.download' - +apply plugin: 'com.google.firebase.crashlytics' jacoco { toolVersion = "0.8.3" @@ -27,13 +22,12 @@ jacoco { ext { powermockVersion = "1.7.3" dexmakerVersion = "1.2" - retrofit2Version = '2.8.1' - okhttp3Version = '4.6.0' + retrofit2Version = '2.9.0' + okhttp3Version = '4.7.2' } repositories { - maven { url 'https://maven.fabric.io/public' } jcenter { url "https://jcenter.bintray.com/" } mavenCentral() } @@ -249,12 +243,9 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.google.android.gms:play-services-wearable:17.0.0' implementation "com.google.android.gms:play-services-location:17.0.0" - implementation 'com.google.firebase:firebase-core:17.4.0' + implementation 'com.google.firebase:firebase-core:17.4.2' implementation 'com.google.firebase:firebase-auth:19.3.1' implementation 'com.google.firebase:firebase-database:19.3.0' - implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') { - transitive = true; - } implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.legacy:legacy-support-v13:1.0.0' @@ -265,12 +256,11 @@ dependencies { implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.percentlayout:percentlayout:1.0.0' implementation "androidx.preference:preference-ktx:1.1.1" - implementation "androidx.activity:activity:${activityVersion}" implementation "androidx.activity:activity-ktx:${activityVersion}" implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.1.0' - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" + implementation "io.reactivex.rxjava2:rxandroid:${rxandroid_version}" implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}" implementation "com.j256.ormlite:ormlite-android:${ormLiteVersion}" @@ -283,6 +273,7 @@ dependencies { implementation "com.jjoe64:graphview:4.0.1" implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.2.2" implementation 'com.madgag.spongycastle:core:1.58.0.0' + // Omnipod wizard implementation(name: "com.atech-software.android.library.wizardpager-1.1.1", ext: "aar") implementation("com.google.android:flexbox:0.3.0") { @@ -308,7 +299,7 @@ dependencies { implementation 'com.eatthepath:java-otp:0.2.0' testImplementation "junit:junit:4.13" - testImplementation "org.json:json:20190722" + testImplementation 'org.json:json:20200518' testImplementation "org.mockito:mockito-core:2.8.47" testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}" testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}" diff --git a/app/src/main/assets/OpenAPSSMB/determine-basal.js b/app/src/main/assets/OpenAPSSMB/determine-basal.js index 00a9c1d0a2..fbc0a4de9f 100644 --- a/app/src/main/assets/OpenAPSSMB/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMB/determine-basal.js @@ -407,6 +407,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ , 'bg': bg , 'tick': tick , 'eventualBG': eventualBG + , 'targetBG': target_bg , 'insulinReq': 0 , 'reservoir' : reservoir_data // The expected reservoir volume at which to deliver the microbolus (the reservoir volume from right before the last pumphistory run) , 'deliverAt' : deliverAt // The time at which the microbolus should be delivered diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index c78aaedaf5..7881fea604 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -49,7 +49,7 @@ import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicato import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.LocaleHelper +import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest @@ -174,6 +174,7 @@ class MainActivity : NoSplashAppCompatActivity() { private fun processPreferenceChange(ev: EventPreferenceChange) { if (ev.isChanged(resourceHelper, R.string.key_keep_screen_on)) setWakeLock() + if (ev.isChanged(resourceHelper, R.string.key_skin)) recreate() } private fun setupViews() { diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 126ba47d22..85bfd24f44 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -37,7 +37,7 @@ import info.nightscout.androidaps.receivers.NetworkChangeReceiver; import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver; import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.utils.ActivityMonitor; -import info.nightscout.androidaps.utils.LocaleHelper; +import info.nightscout.androidaps.utils.locale.LocaleHelper; import info.nightscout.androidaps.utils.sharedPreferences.SP; public class MainApp extends DaggerApplication { @@ -69,7 +69,7 @@ public class MainApp extends DaggerApplication { sResources = getResources(); LocaleHelper.INSTANCE.update(this); sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class); - +/* Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> { if (ex instanceof InternalError) { // usually the app trying to spawn a thread while being killed @@ -77,7 +77,7 @@ public class MainApp extends DaggerApplication { } aapsLogger.error("Uncaught exception crashing app", ex); }); - +*/ registerActivityLifecycleCallbacks(activityMonitor); JodaTimeAndroid.init(this); diff --git a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.kt index ad3961c883..ea90f4b250 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.kt @@ -5,7 +5,7 @@ import android.os.Bundle import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceScreen import info.nightscout.androidaps.R -import info.nightscout.androidaps.utils.LocaleHelper +import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.resources.ResourceHelper import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.kt index 9e62f16c97..0193b690a6 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.kt @@ -9,7 +9,7 @@ import dagger.android.support.DaggerAppCompatActivity import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.plugins.configBuilder.PluginStore -import info.nightscout.androidaps.utils.LocaleHelper +import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.protection.ProtectionCheck import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 50a7d3ed47..4d4c52df43 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -52,6 +52,7 @@ import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID; import info.nightscout.androidaps.plugins.pump.insight.database.InsightHistoryOffset; @@ -386,7 +387,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { old.copyFrom(bgReading); getDaoBgReadings().update(old); aapsLogger.debug(LTag.DATABASE, "BG: Updating record from: " + from + " New data: " + old.toString()); - scheduleBgChange(bgReading); + rxBus.send(new EventNewHistoryBgData(old.date)); // trigger cache invalidation + scheduleBgChange(bgReading); // trigger new calculation return false; } } catch (SQLException e) { @@ -1531,7 +1533,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { //add last one without duration ProfileSwitch last = getLastProfileSwitchWithoutDuration(); if (last != null) { - if (!profileSwitches.contains(last)) + if (!isInList(profileSwitches, last)) profileSwitches.add(last); } return profileSwitches; @@ -1541,6 +1543,13 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList<>(); } + boolean isInList(List profileSwitches, ProfileSwitch last) { + for (ProfileSwitch ps : profileSwitches) { + if (ps.isEqual(last)) return true; + } + return false; + } + @Nullable private ProfileSwitch getLastProfileSwitchWithoutDuration() { try { diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/SkinsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/SkinsModule.kt index ebd4691f38..cd71cc8fd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/SkinsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/SkinsModule.kt @@ -8,6 +8,7 @@ import dagger.multibindings.IntoMap import info.nightscout.androidaps.skins.SkinButtonsOn import info.nightscout.androidaps.skins.SkinClassic import info.nightscout.androidaps.skins.SkinInterface +import info.nightscout.androidaps.skins.SkinLargeDisplay import javax.inject.Qualifier @Module @@ -25,6 +26,12 @@ open class SkinsModule { @IntKey(10) fun bindsSkinButtonsOn(skinButtonsOn: SkinButtonsOn): SkinInterface = skinButtonsOn + @Provides + @Skin + @IntoMap + @IntKey(20) + fun bindsSkinLargeDisplay(skinLargeDisplay: SkinLargeDisplay): SkinInterface = skinLargeDisplay + @Qualifier annotation class Skin } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt b/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt index f59a38d770..df22cabde6 100644 --- a/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/historyBrowser/HistoryBrowseActivity.kt @@ -3,10 +3,10 @@ package info.nightscout.androidaps.historyBrowser import android.app.DatePickerDialog import android.graphics.Color import android.os.Bundle -import android.os.SystemClock import android.util.DisplayMetrics import android.view.ViewGroup import android.widget.LinearLayout +import android.widget.RelativeLayout import android.widget.TextView import com.jjoe64.graphview.GraphView import dagger.android.HasAndroidInjector @@ -15,12 +15,13 @@ import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.events.EventCustomCalculationFinished import info.nightscout.androidaps.events.EventRefreshOverview import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.plugins.general.overview.OverviewMenus import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress import info.nightscout.androidaps.utils.DateUtil @@ -33,6 +34,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.activity_historybrowse.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -49,7 +51,8 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var defaultValueHelper: DefaultValueHelper - @Inject lateinit var iobCobStaticCalculatorPlugin: IobCobStaticCalculatorPlugin + @Inject lateinit var iobCobCalculatorPluginHistory: IobCobCalculatorPluginHistory + @Inject lateinit var treatmentsPluginHistory: TreatmentsPluginHistory @Inject lateinit var activePlugin: ActivePluginProvider @Inject lateinit var buildHelper: BuildHelper @Inject lateinit var fabricPrivacy: FabricPrivacy @@ -73,12 +76,10 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { historybrowse_left.setOnClickListener { start -= T.hours(rangeToDisplay.toLong()).msecs() - updateGUI("onClickLeft") runCalculation("onClickLeft") } historybrowse_right.setOnClickListener { start += T.hours(rangeToDisplay.toLong()).msecs() - updateGUI("onClickRight") runCalculation("onClickRight") } historybrowse_end.setOnClickListener { @@ -89,13 +90,12 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { calendar[Calendar.MINUTE] = 0 calendar[Calendar.HOUR_OF_DAY] = 0 start = calendar.timeInMillis - updateGUI("onClickEnd") runCalculation("onClickEnd") } historybrowse_zoom.setOnClickListener { rangeToDisplay += 6 rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay - updateGUI("rangeChange") + updateGUI("rangeChange", false) } historybrowse_zoom.setOnLongClickListener { val calendar = Calendar.getInstance() @@ -105,7 +105,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { calendar[Calendar.MINUTE] = 0 calendar[Calendar.HOUR_OF_DAY] = 0 start = calendar.timeInMillis - updateGUI("resetToMidnight") runCalculation("onLongClickZoom") true } @@ -114,12 +113,15 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth -> val cal = Calendar.getInstance() cal.timeInMillis = start - cal.set(Calendar.YEAR, year) - cal.set(Calendar.MONTH, monthOfYear) - cal.set(Calendar.DAY_OF_MONTH, dayOfMonth) + cal[Calendar.YEAR] = year + cal[Calendar.MONTH] = monthOfYear + cal[Calendar.DAY_OF_MONTH] = dayOfMonth + cal[Calendar.MILLISECOND] = 0 + cal[Calendar.SECOND] = 0 + cal[Calendar.MINUTE] = 0 + cal[Calendar.HOUR_OF_DAY] = 0 start = cal.timeInMillis historybrowse_date?.text = dateUtil.dateAndTimeString(start) - updateGUI("onClickDate") runCalculation("onClickDate") } @@ -143,24 +145,38 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { overviewMenus.setupChartMenu(overview_chartMenuButton) prepareGraphs() + savedInstanceState?.let { bundle -> + rangeToDisplay = bundle.getInt("rangeToDisplay", 0) + start = bundle.getLong("start", 0) + } + } public override fun onPause() { super.onPause() disposable.clear() - iobCobStaticCalculatorPlugin.stopCalculation("onPause") + iobCobCalculatorPluginHistory.stopCalculation("onPause") } public override fun onResume() { super.onResume() disposable.add(rxBus .toObservable(EventAutosensCalculationFinished::class.java) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ event: EventAutosensCalculationFinished -> - // catch only events from iobCobStaticCalculatorPlugin - if (event.cause === eventCustomCalculationFinished) { - aapsLogger.debug(LTag.AUTOSENS, "EventAutosensCalculationFinished") - updateGUI("EventAutosensCalculationFinished") + .observeOn(Schedulers.io()) + .subscribe({ + // catch only events from iobCobCalculatorPluginHistory + if (it.cause is EventCustomCalculationFinished) { + updateGUI("EventAutosensCalculationFinished", bgOnly = false) + } + }) { fabricPrivacy::logException } + ) + disposable.add(rxBus + .toObservable(EventAutosensBgLoaded::class.java) + .observeOn(Schedulers.io()) + .subscribe({ + // catch only events from iobCobCalculatorPluginHistory + if (it.cause is EventCustomCalculationFinished) { + updateGUI("EventAutosensCalculationFinished", bgOnly = true) } }) { fabricPrivacy::logException } ) @@ -173,21 +189,32 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { .toObservable(EventRefreshOverview::class.java) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ - prepareGraphs() - updateGUI("EventRefreshOverview") + if (it.now) { + prepareGraphs() + updateGUI("EventRefreshOverview", bgOnly = false) + } }) { fabricPrivacy::logException } ) - // set start of current day - val calendar = Calendar.getInstance() - calendar.timeInMillis = System.currentTimeMillis() - calendar[Calendar.MILLISECOND] = 0 - calendar[Calendar.SECOND] = 0 - calendar[Calendar.MINUTE] = 0 - calendar[Calendar.HOUR_OF_DAY] = 0 - start = calendar.timeInMillis - runCalculation("onResume") - SystemClock.sleep(1000) - updateGUI("onResume") + if (start == 0L) { + // set start of current day + val calendar = Calendar.getInstance() + calendar.timeInMillis = System.currentTimeMillis() + calendar[Calendar.MILLISECOND] = 0 + calendar[Calendar.SECOND] = 0 + calendar[Calendar.MINUTE] = 0 + calendar[Calendar.HOUR_OF_DAY] = 0 + start = calendar.timeInMillis + runCalculation("onResume") + } else { + updateGUI("onResume", bgOnly = false) + } + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putInt("rangeToDisplay", rangeToDisplay) + outState.putLong("start", start) + } private fun prepareGraphs() { @@ -200,19 +227,28 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { secondaryGraphsLabel.clear() history_iobgraph.removeAllViews() for (i in 1 until numOfGraphs) { - val label = TextView(this) - label.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(100, 0, 0, -50) } - history_iobgraph.addView(label) - secondaryGraphsLabel.add(label) + val relativeLayout = RelativeLayout(this) + relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + val graph = GraphView(this) - graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, 0, 0, resourceHelper.dpToPx(10)) } + graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(10)) } graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) graph.gridLabelRenderer?.reloadStyles() graph.gridLabelRenderer?.isHorizontalLabelsVisible = false graph.gridLabelRenderer?.labelVerticalWidth = axisWidth graph.gridLabelRenderer?.numVerticalLabels = 3 graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray - history_iobgraph.addView(graph) + relativeLayout.addView(graph) + + val label = TextView(this) + val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(resourceHelper.dpToPx(30), resourceHelper.dpToPx(25), 0, 0) } + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP) + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT) + label.layoutParams = layoutParams + relativeLayout.addView(label) + secondaryGraphsLabel.add(label) + + history_iobgraph.addView(relativeLayout) secondaryGraphs.add(graph) } } @@ -220,35 +256,37 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { } private fun runCalculation(from: String) { - val end = start + T.hours(rangeToDisplay.toLong()).msecs() - iobCobStaticCalculatorPlugin.stopCalculation(from) - iobCobStaticCalculatorPlugin.clearCache() - iobCobStaticCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished) + GlobalScope.launch(Dispatchers.Default) { + treatmentsPluginHistory.initializeData(start - T.hours(8).msecs()) + val end = start + T.hours(rangeToDisplay.toLong()).msecs() + iobCobCalculatorPluginHistory.stopCalculation(from) + iobCobCalculatorPluginHistory.clearCache() + iobCobCalculatorPluginHistory.runCalculation(from, end, true, false, eventCustomCalculationFinished) + } } - @Synchronized - fun updateGUI(from: String) { + fun updateGUI(from: String, bgOnly: Boolean) { aapsLogger.debug(LTag.UI, "updateGUI from: $from") val pump = activePlugin.activePump val profile = profileFunction.getProfile() - historybrowse_noprofile?.visibility = (profile == null).toVisibility() - profile ?: return - val lowLine = defaultValueHelper.determineLowLine() val highLine = defaultValueHelper.determineHighLine() - historybrowse_date?.text = dateUtil.dateAndTimeString(start) - historybrowse_zoom?.text = rangeToDisplay.toString() GlobalScope.launch(Dispatchers.Main) { + historybrowse_noprofile?.visibility = (profile == null).toVisibility() + profile ?: return@launch + historybrowse_bggraph ?: return@launch - val graphData = GraphData(injector, historybrowse_bggraph, iobCobStaticCalculatorPlugin) + historybrowse_date?.text = dateUtil.dateAndTimeString(start) + historybrowse_zoom?.text = rangeToDisplay.toString() + val graphData = GraphData(injector, historybrowse_bggraph, iobCobCalculatorPluginHistory, treatmentsPluginHistory) val secondaryGraphsData: ArrayList = ArrayList() // do preparation in different thread withContext(Dispatchers.Default) { val fromTime: Long = start + T.secs(100).msecs() - val toTime: Long = start + T.hours(rangeToDisplay.toLong()).msecs() + val toTime: Long = start + T.hours(rangeToDisplay.toLong()).msecs() + T.secs(100).msecs() aapsLogger.debug(LTag.UI, "Period: " + dateUtil.dateAndTimeString(fromTime) + " - " + dateUtil.dateAndTimeString(toTime)) val pointer = System.currentTimeMillis() @@ -261,71 +299,73 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { // set manual x bounds to have nice steps graphData.formatAxis(fromTime, toTime) - // Treatments - graphData.addTreatments(fromTime, toTime) - if (overviewMenus.setting[0][OverviewMenus.CharType.ACT.ordinal]) - graphData.addActivity(fromTime, toTime, false, 0.8) - - // add basal data - if (pump.pumpDescription.isTempBasalCapable && overviewMenus.setting[0][OverviewMenus.CharType.BAS.ordinal]) { - graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2) - } - // add target line graphData.addTargetLine(fromTime, toTime, profile, null) // **** NOW line **** graphData.addNowLine(pointer) - // ------------------ 2nd graph - for (g in 0 until secondaryGraphs.size) { - val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobStaticCalculatorPlugin) - var useIobForScale = false - var useCobForScale = false - var useDevForScale = false - var useRatioForScale = false - var useDSForScale = false - var useIAForScale = false - var useABSForScale = false - when { - overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true + if (!bgOnly) { + // Treatments + graphData.addTreatments(fromTime, toTime) + if (overviewMenus.setting[0][OverviewMenus.CharType.ACT.ordinal]) + graphData.addActivity(fromTime, toTime, false, 0.8) + + // add basal data + if (pump.pumpDescription.isTempBasalCapable && overviewMenus.setting[0][OverviewMenus.CharType.BAS.ordinal]) { + graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2) } + // ------------------ 2nd graph + for (g in 0 until secondaryGraphs.size) { + val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPluginHistory, treatmentsPluginHistory) + var useIobForScale = false + var useCobForScale = false + var useDevForScale = false + var useRatioForScale = false + var useDSForScale = false + var useIAForScale = false + var useABSForScale = false + when { + overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true + } - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, toTime, useIobForScale, 1.0, overviewMenus.setting[g + 1][OverviewMenus.CharType.PRE.ordinal]) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, toTime, useCobForScale, if (useCobForScale) 1.0 else 0.5) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1.0) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1.0) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, toTime, useIAForScale, 0.8) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, toTime, useABSForScale, 1.0) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, toTime, useIobForScale, 1.0, overviewMenus.setting[g + 1][OverviewMenus.CharType.PRE.ordinal]) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, toTime, useCobForScale, if (useCobForScale) 1.0 else 0.5) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, toTime, useIAForScale, 0.8) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, toTime, useABSForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1.0) - // set manual x bounds to have nice steps - secondGraphData.formatAxis(fromTime, toTime) - secondGraphData.addNowLine(pointer) - secondaryGraphsData.add(secondGraphData) + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, toTime) + secondGraphData.addNowLine(pointer) + secondaryGraphsData.add(secondGraphData) + } } } // finally enforce drawing of graphs in UI thread graphData.performUpdate() - for (g in 0 until secondaryGraphs.size) { - secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1) - secondaryGraphs[g].visibility = ( - overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] - ).toVisibility() - secondaryGraphsData[g].performUpdate() - } + if (!bgOnly) + for (g in 0 until secondaryGraphs.size) { + secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1) + secondaryGraphs[g].visibility = (!bgOnly && ( + overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] + )).toVisibility() + secondaryGraphsData[g].performUpdate() + } } } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobStaticCalculatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt similarity index 83% rename from app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobStaticCalculatorPlugin.kt rename to app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt index 03214175d2..bf7401036a 100644 --- a/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobStaticCalculatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/historyBrowser/IobCobCalculatorPluginHistory.kt @@ -9,7 +9,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.resources.ResourceHelper @@ -18,7 +17,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class IobCobStaticCalculatorPlugin @Inject constructor( +class IobCobCalculatorPluginHistory @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, rxBus: RxBusWrapper, @@ -26,14 +25,14 @@ class IobCobStaticCalculatorPlugin @Inject constructor( resourceHelper: ResourceHelper, profileFunction: ProfileFunction, activePlugin: ActivePluginProvider, - treatmentsPlugin: TreatmentsPlugin, + treatmentsPluginHistory: TreatmentsPluginHistory, sensitivityOref1Plugin: SensitivityOref1Plugin, sensitivityAAPSPlugin: SensitivityAAPSPlugin, sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin, fabricPrivacy: FabricPrivacy, dateUtil: DateUtil ) : IobCobCalculatorPlugin(injector, aapsLogger, rxBus, sp, resourceHelper, profileFunction, - activePlugin, treatmentsPlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil) { + activePlugin, treatmentsPluginHistory, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil) { override fun onStart() { // do not attach to rxbus } diff --git a/app/src/main/java/info/nightscout/androidaps/historyBrowser/TreatmentsPluginHistory.kt b/app/src/main/java/info/nightscout/androidaps/historyBrowser/TreatmentsPluginHistory.kt new file mode 100644 index 0000000000..caa0fb1b1a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/historyBrowser/TreatmentsPluginHistory.kt @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.historyBrowser + +import android.content.Context +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.plugins.bus.RxBusWrapper +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload +import info.nightscout.androidaps.plugins.treatments.TreatmentService +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TreatmentsPluginHistory @Inject constructor( + injector: HasAndroidInjector, + aapsLogger: AAPSLogger, + rxBus: RxBusWrapper, + resourceHelper: ResourceHelper, + context: Context, + sp: SP, + profileFunction: ProfileFunction, + activePlugin: ActivePluginProvider, + nsUpload: NSUpload, + fabricPrivacy: FabricPrivacy, dateUtil: DateUtil +) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil) { + + init { + onStart() + } + + override fun onStart() { + service = TreatmentService(injector) + initializeData(range()) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java index 6b5f5363b0..35ba0d3abe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java @@ -26,16 +26,16 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.interfaces.ActivePluginProvider; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.aps.loop.ScriptReader; import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback; +import info.nightscout.androidaps.plugins.aps.loop.ScriptReader; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.interfaces.ActivePluginProvider; - import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.resources.ResourceHelper; @@ -237,7 +237,8 @@ public class DetermineBasalAdapterSMBJS { ) throws JSONException { String units = profile.getUnits(); - Double pumpbolusstep = activePluginProvider.getActivePump().getPumpDescription().bolusStep; + PumpInterface pump = activePluginProvider.getActivePump(); + Double pumpbolusstep = pump.getPumpDescription().bolusStep; mProfile = new JSONObject(); mProfile.put("max_iob", maxIob); @@ -259,13 +260,13 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("low_temptarget_lowers_sensitivity", false); - mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target); - mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target); + mProfile.put("sensitivity_raises_target", sp.getBoolean(resourceHelper.gs(R.string.key_sensitivity_raises_target),SMBDefaults.sensitivity_raises_target)); + mProfile.put("resistance_lowers_target", sp.getBoolean(resourceHelper.gs(R.string.key_resistance_lowers_target),SMBDefaults.resistance_lowers_target)); mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments); mProfile.put("exercise_mode", SMBDefaults.exercise_mode); mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target); mProfile.put("maxCOB", SMBDefaults.maxCOB); - mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps); + mProfile.put("skip_neutral_temps", pump.setNeutralTempAtFullHour()); // min_5m_carbimpact is not used within SMB determinebasal //if (mealData.usedMinCarbsImpact > 0) { // mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.java index dae170d5d9..f8f72c6c87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalResultSMB.java @@ -51,6 +51,9 @@ public class DetermineBasalResultSMB extends APSResult { } else { smb = 0d; } + if (result.has("targetBG")) { + targetBG = result.getDouble("targetBG"); + } if (result.has("deliverAt")) { String date = result.getString("deliverAt"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt index 5166248e7d..3958f17d78 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/PluginStore.kt @@ -108,7 +108,7 @@ class PluginStore @Inject constructor( (activeProfile as PluginBase).setPluginEnabled(PluginType.PROFILE, true) aapsLogger.debug(LTag.CONFIGBUILDER, "Defaulting ProfileInterface") } - setFragmentVisiblities((activeSensitivity as PluginBase).name, pluginsInCategory, PluginType.PROFILE) + setFragmentVisiblities((activeProfile as PluginBase).name, pluginsInCategory, PluginType.PROFILE) // PluginType.BGSOURCE pluginsInCategory = getSpecificPluginsList(PluginType.BGSOURCE) 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 47651ef9ac..22973b3caf 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 @@ -18,9 +18,9 @@ import info.nightscout.androidaps.events.* import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider +import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.overview.StatusLightHandler import info.nightscout.androidaps.queue.Callback @@ -192,17 +192,15 @@ class ActionsFragment : DaggerFragment() { @Synchronized fun updateGui() { - actions_profileswitch?.visibility = (activePlugin.activeProfileInterface.profile != null).toVisibility() val profile = profileFunction.getProfile() val pump = activePlugin.activePump - actions_temptarget?.visibility = (profile != null).toVisibility() - actions_historybrowser.visibility = (profile != null).toVisibility() - - val basalProfileEnabled = buildHelper.isEngineeringModeOrRelease() && pump.pumpDescription.isSetBasalProfileCapable - - actions_profileswitch?.visibility = if (!basalProfileEnabled || !pump.isInitialized || pump.isSuspended) View.GONE else View.VISIBLE + actions_profileswitch?.visibility = ( + activePlugin.activeProfileInterface.profile != null && + pump.pumpDescription.isSetBasalProfileCapable && + pump.isInitialized && + !pump.isSuspended).toVisibility() if (!pump.pumpDescription.isExtendedBolusCapable || !pump.isInitialized || pump.isSuspended || pump.isFakingTempsByExtendedBoluses) { actions_extendedbolus?.visibility = View.GONE @@ -236,12 +234,11 @@ class ActionsFragment : DaggerFragment() { } } - actions_fill?.visibility = - if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE - else View.VISIBLE - - actions_temptarget?.visibility = config.APS.toVisibility() + actions_historybrowser.visibility = (profile != null).toVisibility() + actions_fill?.visibility = (pump.pumpDescription.isRefillingCapable && pump.isInitialized && !pump.isSuspended).toVisibility() + actions_temptarget?.visibility = (profile != null && config.APS).toVisibility() actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility() + statusLightHandler.updateStatusLights(careportal_canulaage, careportal_insulinage, null, careportal_sensorage, careportal_pbage, null) checkPumpCustomActions() } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index b4f9ec425e..bde4182aef 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -177,10 +177,9 @@ class AutomationPlugin @Inject constructor( @Synchronized private fun processActions() { - if (!isEnabled(PluginType.GENERAL)) - return - if (loopPlugin.isSuspended || !loopPlugin.isEnabled(PluginType.LOOP)) { + if (loopPlugin.isSuspended || !loopPlugin.isEnabled()) { aapsLogger.debug(LTag.AUTOMATION, "Loop deactivated") + executionLog.add(resourceHelper.gs(R.string.smscommunicator_loopisdisabled)) return } val enabled = constraintChecker.isAutomationEnabled() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt index db57bb159a..4b7a56771a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt @@ -35,7 +35,7 @@ class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) { } override fun shouldRun(): Boolean { - val lastBolusTime = treatmentsPlugin.getLastBolusTime(false) + val lastBolusTime = treatmentsPlugin.getLastBolusTime(true) if (lastBolusTime == 0L) return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) { aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt index 08343a3c94..ffc79e39e1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt @@ -34,12 +34,11 @@ class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) { return this } - override fun shouldRun(): Boolean { - val currentMinSinceMidnight = getMinSinceMidnight(DateUtil.now()) + override fun shouldRun() : Boolean { + val currentMinSinceMidnight = getMinSinceMidnight(dateUtil._now()) val scheduledDayOfWeek = Calendar.getInstance()[Calendar.DAY_OF_WEEK] - val scheduled = getMinSinceMidnight(time.value.toLong()) if (days.isSet(Objects.requireNonNull(InputWeekDay.DayOfWeek.fromCalendarInt(scheduledDayOfWeek)))) { - if (currentMinSinceMidnight >= scheduled && currentMinSinceMidnight - scheduled < 5) { + if (currentMinSinceMidnight >= time.value && currentMinSinceMidnight - time.value < 5) { aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) return true } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.kt index 4fa6c43fce..565b33b77b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.provider.Settings -import androidx.activity.invoke import androidx.annotation.StringRes import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -221,7 +220,7 @@ class ImportExportPrefs @Inject constructor( importSharedPreferences(fragmentAct, it) } } - callForPrefFile.invoke() + callForPrefFile.launch(null) } } @@ -231,7 +230,7 @@ class ImportExportPrefs @Inject constructor( importSharedPreferences(activity, it) } } - callForPrefFile.invoke() + callForPrefFile.launch(null) } private fun importSharedPreferences(activity: Activity, importFile: PrefsFile) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/PrefImportListActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/PrefImportListActivity.kt index 7703166d04..6be8b5e020 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/PrefImportListActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/PrefImportListActivity.kt @@ -19,7 +19,7 @@ import info.nightscout.androidaps.plugins.general.maintenance.PrefsFileContract import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsFormatsHandler import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsStatus -import info.nightscout.androidaps.utils.LocaleHelper +import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.resources.ResourceHelper import kotlinx.android.synthetic.main.maintenance_importlist_activity.* import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/data/NSDeviceStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/data/NSDeviceStatus.java index 7195435515..757692e655 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/data/NSDeviceStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/data/NSDeviceStatus.java @@ -331,7 +331,7 @@ public class NSDeviceStatus { // test warning level int level = Levels.INFO; long now = System.currentTimeMillis(); - if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + sp.getInt(R.string.key_nsalarm_urgent_staledatavalue, 16) * 60 * 1000L < now) + if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + sp.getInt(R.string.key_nsalarm_urgent_staledatavalue, 31) * 60 * 1000L < now) level = Levels.URGENT; else if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + sp.getInt(R.string.key_nsalarm_staledatavalue, 16) * 60 * 1000L < now) level = Levels.WARN; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java index cc5057f7eb..7c4d41ca86 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.java @@ -842,33 +842,42 @@ public class NSClientService extends DaggerService { } private void handleAnnouncement(JSONObject announcement) { - NSAlarm nsAlarm = new NSAlarm(announcement); - Notification notification = new NotificationWithAction(injector, nsAlarm); - rxBus.send(new EventNewNotification(notification)); - rxBus.send(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(announcement, "message", "received"))); - aapsLogger.debug(LTag.NSCLIENT, announcement.toString()); + boolean defaultVal = config.getNSCLIENT(); + if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) { + NSAlarm nsAlarm = new NSAlarm(announcement); + Notification notification = new NotificationWithAction(injector, nsAlarm); + rxBus.send(new EventNewNotification(notification)); + rxBus.send(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(announcement, "message", "received"))); + aapsLogger.debug(LTag.NSCLIENT, announcement.toString()); + } } private void handleAlarm(JSONObject alarm) { - long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L); - if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) { - NSAlarm nsAlarm = new NSAlarm(alarm); - Notification notification = new NotificationWithAction(injector, nsAlarm); - rxBus.send(new EventNewNotification(notification)); + boolean defaultVal = config.getNSCLIENT(); + if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) { + long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L); + if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) { + NSAlarm nsAlarm = new NSAlarm(alarm); + Notification notification = new NotificationWithAction(injector, nsAlarm); + rxBus.send(new EventNewNotification(notification)); + } + rxBus.send(new EventNSClientNewLog("ALARM", JsonHelper.safeGetString(alarm, "message", "received"))); + aapsLogger.debug(LTag.NSCLIENT, alarm.toString()); } - rxBus.send(new EventNSClientNewLog("ALARM", JsonHelper.safeGetString(alarm, "message", "received"))); - aapsLogger.debug(LTag.NSCLIENT, alarm.toString()); } private void handleUrgentAlarm(JSONObject alarm) { - long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L); - if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) { - NSAlarm nsAlarm = new NSAlarm(alarm); - Notification notification = new NotificationWithAction(injector, nsAlarm); - rxBus.send(new EventNewNotification(notification)); + boolean defaultVal = config.getNSCLIENT(); + if (sp.getBoolean(R.string.key_ns_alarms, defaultVal)) { + long snoozedTo = sp.getLong(R.string.key_snoozedTo, 0L); + if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) { + NSAlarm nsAlarm = new NSAlarm(alarm); + Notification notification = new NotificationWithAction(injector, nsAlarm); + rxBus.send(new EventNewNotification(notification)); + } + rxBus.send(new EventNSClientNewLog("URGENTALARM", JsonHelper.safeGetString(alarm, "message", "received"))); + aapsLogger.debug(LTag.NSCLIENT, alarm.toString()); } - rxBus.send(new EventNSClientNewLog("URGENTALARM", JsonHelper.safeGetString(alarm, "message", "received"))); - aapsLogger.debug(LTag.NSCLIENT, alarm.toString()); } public void handleNewCal(JSONArray cals, boolean isDelta) { 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 a7c2517aa2..2488a5e2ec 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 @@ -19,6 +19,7 @@ import android.view.View import android.view.View.OnLongClickListener import android.view.ViewGroup import android.widget.LinearLayout +import android.widget.RelativeLayout import android.widget.TextView import androidx.core.text.toSpanned import androidx.recyclerview.widget.LinearLayoutManager @@ -184,6 +185,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList overview_bggraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) overview_bggraph?.gridLabelRenderer?.reloadStyles() overview_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth + overview_bggraph?.layoutParams?.height = resourceHelper.dpToPx(skinProvider.activeSkin().mainGraphHeight) rangeToDisplay = sp.getInt(R.string.key_rangetodisplay, 6) @@ -477,19 +479,28 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList secondaryGraphsLabel.clear() overview_iobgraph.removeAllViews() for (i in 1 until numOfGraphs) { - val label = TextView(context) - label.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(100, 0, 0, -120) } - overview_iobgraph.addView(label) - secondaryGraphsLabel.add(label) + val relativeLayout = RelativeLayout(context) + relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + val graph = GraphView(context) - graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, resourceHelper.dpToPx(35), 0, resourceHelper.dpToPx(15)) } + graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(skinProvider.activeSkin().secondaryGraphHeight)).also { it.setMargins(0, resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(10)) } graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) graph.gridLabelRenderer?.reloadStyles() graph.gridLabelRenderer?.isHorizontalLabelsVisible = false graph.gridLabelRenderer?.labelVerticalWidth = axisWidth graph.gridLabelRenderer?.numVerticalLabels = 3 graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray - overview_iobgraph.addView(graph) + relativeLayout.addView(graph) + + val label = TextView(context) + val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(resourceHelper.dpToPx(30), resourceHelper.dpToPx(25), 0, 0) } + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP) + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT) + label.layoutParams = layoutParams + relativeLayout.addView(label) + secondaryGraphsLabel.add(label) + + overview_iobgraph.addView(relativeLayout) secondaryGraphs.add(graph) } } @@ -582,70 +593,47 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList loopPlugin.isEnabled() && loopPlugin.isSuperBolus -> { overview_apsmode.setImageResource(R.drawable.loop_superbolus) overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper) - //overview_apsmode_text?.text = String.format(resourceHelper.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend()) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning)) } loopPlugin.isDisconnected -> { overview_apsmode.setImageResource(R.drawable.loop_disconnected) overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper) -// overview_apsmode_text?.text = String.format(resourceHelper.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend()) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonCritical)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextCritical)) } loopPlugin.isEnabled() && loopPlugin.isSuspended -> { overview_apsmode.setImageResource(R.drawable.loop_paused) overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper) -// overview_apsmode_text?.text = String.format(resourceHelper.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning)) } pump.isSuspended -> { overview_apsmode.setImageResource(R.drawable.loop_paused) overview_apsmode_text?.text = "" -// overview_apsmode_text?.text = resourceHelper.gs(R.string.pumpsuspended) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning)) } loopPlugin.isEnabled() && closedLoopEnabled.value() && loopPlugin.isLGS -> { overview_apsmode.setImageResource(R.drawable.loop_lgs) overview_apsmode_text?.text = "" -// overview_apsmode_text?.text = resourceHelper.gs(R.string.closedloop) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault)) } loopPlugin.isEnabled() && closedLoopEnabled.value() -> { overview_apsmode.setImageResource(R.drawable.loop_closed) overview_apsmode_text?.text = "" -// overview_apsmode_text?.text = resourceHelper.gs(R.string.closedloop) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault)) } loopPlugin.isEnabled() && !closedLoopEnabled.value() -> { overview_apsmode.setImageResource(R.drawable.loop_open) overview_apsmode_text?.text = "" -// overview_apsmode_text?.text = resourceHelper.gs(R.string.openloop) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault)) } else -> { overview_apsmode.setImageResource(R.drawable.loop_disabled) overview_apsmode_text?.text = "" -// overview_apsmode_text?.text = resourceHelper.gs(R.string.disabledloop) -// overview_apsmode_text?.setBackgroundColor(resourceHelper.gc(R.color.ribbonCritical)) -// overview_apsmode_text?.setTextColor(resourceHelper.gc(R.color.ribbonTextCritical)) } } } else { overview_apsmode_text?.visibility = View.GONE } + val lastRun = loopPlugin.lastRun // temp target val tempTarget = treatmentsPlugin.tempTargetFromHistory @@ -654,9 +642,18 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList overview_temptarget?.setBackgroundColor(resourceHelper.gc(R.color.ribbonWarning)) overview_temptarget?.text = Profile.toTargetRangeString(tempTarget.low, tempTarget.high, Constants.MGDL, units) + " " + DateUtil.untilString(tempTarget.end(), resourceHelper) } else { - overview_temptarget?.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault)) - overview_temptarget?.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault)) - overview_temptarget?.text = Profile.toTargetRangeString(profile.targetLowMgdl, profile.targetHighMgdl, Constants.MGDL, units) + // If the target is not the same as set in the profile then oref has overridden it + val targetUsed = lastRun?.constraintsProcessed?.targetBG ?: 0.0 + + if (targetUsed != 0.0 && profile.targetMgdl != targetUsed) { + overview_temptarget?.text = Profile.toTargetRangeString(targetUsed, targetUsed, Constants.MGDL, units) + overview_temptarget?.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning)) + overview_temptarget?.setBackgroundColor(resourceHelper.gc(R.color.tempTargetBackground)) + } else { + overview_temptarget?.setTextColor(resourceHelper.gc(R.color.ribbonTextDefault)) + overview_temptarget?.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault)) + overview_temptarget?.text = Profile.toTargetRangeString(profile.targetLowMgdl, profile.targetHighMgdl, Constants.MGDL, units) + } } // Basal, TBR @@ -677,7 +674,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList if (activeTemp != null) overview_basebasal_icon.setImageResource(if (activeTemp.tempBasalConvertedToPercent(System.currentTimeMillis(), profile) > 100) R.drawable.icon_cp_basal_tbr_high else R.drawable.icon_cp_basal_tbr_low) else - overview_basebasal_icon.setImageResource( R.drawable.icon_cp_basal_no_tbr ) + overview_basebasal_icon.setImageResource(R.drawable.icon_cp_basal_no_tbr) // Extended bolus val extendedBolus = treatmentsPlugin.getExtendedBolusFromHistory(System.currentTimeMillis()) @@ -741,7 +738,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList } overview_cob?.text = cobText - val lastRun = loopPlugin.lastRun val predictionsAvailable = if (config.APS) lastRun?.request?.hasPredictions == true else config.NSCLIENT // pump status from ns @@ -757,9 +753,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList overview_uploader?.setOnClickListener { activity?.let { OKDialog.show(it, resourceHelper.gs(R.string.uploader), nsDeviceStatus.extendedUploaderStatus) } } // Sensitivity - if (sp.getBoolean(R.string.key_openapsama_useautosens, false)) { + if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value()) { overview_sensitivity_icon.setImageResource(R.drawable.ic_swap_vert_black_48dp_green) - }else { + } else { overview_sensitivity_icon.setImageResource(R.drawable.ic_x_swap_vert_48px_green) } @@ -771,7 +767,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList // ****** GRAPH ******* GlobalScope.launch(Dispatchers.Main) { overview_bggraph ?: return@launch - val graphData = GraphData(injector, overview_bggraph, iobCobCalculatorPlugin) + val graphData = GraphData(injector, overview_bggraph, iobCobCalculatorPlugin, treatmentsPlugin) val secondaryGraphsData: ArrayList = ArrayList() // do preparation in different thread @@ -834,30 +830,30 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList // ------------------ 2nd graph for (g in 0 until secondaryGraphs.size) { - val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPlugin) + val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPlugin, treatmentsPlugin) + var useABSForScale = false var useIobForScale = false var useCobForScale = false var useDevForScale = false var useRatioForScale = false var useDSForScale = false var useIAForScale = false - var useABSForScale = false when { + overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true - overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true } + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, now, useABSForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, now, useIobForScale, 1.0, overviewMenus.setting[g + 1][OverviewMenus.CharType.PRE.ordinal]) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, now, useCobForScale, if (useCobForScale) 1.0 else 0.5) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, now, useDevForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, endTime, useIAForScale, 0.8) - if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, now, useABSForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0) // set manual x bounds to have nice steps @@ -871,16 +867,16 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList for (g in 0 until secondaryGraphs.size) { secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1) secondaryGraphs[g].visibility = ( - overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] || + overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] || overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] || overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] || overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] || overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] || - overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] || overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] ).toVisibility() secondaryGraphsData[g].performUpdate() } } } -} \ No newline at end of file +} 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 1cc60f0400..f5e3c656dc 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 @@ -61,16 +61,16 @@ class OverviewMenus @Inject constructor( private val config: Config ) { - enum class CharType(@StringRes val nameId: Int, @ColorRes val colorId: Int, val primary: Boolean, val secondary: Boolean) { - PRE(R.string.overview_show_predictions, R.color.prediction, primary = true, secondary = false), - BAS(R.string.overview_show_basals, R.color.basal, primary = true, secondary = false), - IOB(R.string.overview_show_iob, R.color.iob, primary = false, secondary = true), - COB(R.string.overview_show_cob, R.color.cob, primary = false, secondary = true), - DEV(R.string.overview_show_deviations, R.color.deviations, primary = false, secondary = true), - SEN(R.string.overview_show_sensitivity, R.color.ratio, primary = false, secondary = true), - ACT(R.string.overview_show_activity, R.color.activity, primary = true, secondary = true), - ABS(R.string.overview_show_absinsulin, R.color.iob, primary = false, secondary = true), - DEVSLOPE(R.string.overview_show_deviationslope, R.color.devslopepos, primary = false, secondary = true) + enum class CharType(@StringRes val nameId: Int, @ColorRes val colorId: Int, val primary: Boolean, val secondary: Boolean, @StringRes val shortnameId: Int) { + PRE(R.string.overview_show_predictions, R.color.prediction, primary = true, secondary = false, shortnameId = R.string.prediction_shortname), + BAS(R.string.overview_show_basals, R.color.basal, primary = true, secondary = false,shortnameId = R.string.basal_shortname), + ABS(R.string.overview_show_absinsulin, R.color.iob, primary = false, secondary = true,shortnameId = R.string.abs_insulin_shortname), + IOB(R.string.overview_show_iob, R.color.iob, primary = false, secondary = true,shortnameId = R.string.iob), + COB(R.string.overview_show_cob, R.color.cob, primary = false, secondary = true,shortnameId = R.string.cob), + DEV(R.string.overview_show_deviations, R.color.deviations, primary = false, secondary = true,shortnameId = R.string.deviation_shortname), + SEN(R.string.overview_show_sensitivity, R.color.ratio, primary = false, secondary = true,shortnameId = R.string.sensitivity_shortname), + ACT(R.string.overview_show_activity, R.color.activity, primary = true, secondary = true,shortnameId = R.string.activity_shortname), + DEVSLOPE(R.string.overview_show_deviationslope, R.color.devslopepos, primary = false, secondary = true,shortnameId = R.string.devslope_shortname) } companion object { @@ -80,7 +80,7 @@ class OverviewMenus @Inject constructor( fun enabledTypes(graph: Int): String { val r = StringBuilder() for (type in CharType.values()) if (setting[graph][type.ordinal]) { - r.append(type.name) + r.append(resourceHelper.gs(type.shortnameId)) r.append(" ") } return r.toString() 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 70e4f9f8fc..f3a779af22 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 @@ -34,7 +34,13 @@ import kotlin.math.abs import kotlin.math.max import kotlin.math.min -class GraphData(injector: HasAndroidInjector, private val graph: GraphView, private val iobCobCalculatorPlugin: IobCobCalculatorPlugin) { +class GraphData( + injector: HasAndroidInjector, + private val graph: GraphView, + private val iobCobCalculatorPlugin: IobCobCalculatorPlugin, + private val treatmentsPlugin: TreatmentsInterface + +) { // IobCobCalculatorPlugin Cannot be injected: HistoryBrowser @Inject lateinit var aapsLogger: AAPSLogger @@ -42,8 +48,6 @@ class GraphData(injector: HasAndroidInjector, private val graph: GraphView, priv @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var activePlugin: ActivePluginProvider - private val treatmentsPlugin: TreatmentsInterface - var maxY = Double.MIN_VALUE private var minY = Double.MAX_VALUE private var bgReadingsArray: List? = null @@ -53,7 +57,6 @@ class GraphData(injector: HasAndroidInjector, private val graph: GraphView, priv init { injector.androidInjector().inject(this) units = profileFunction.getUnits() - treatmentsPlugin = activePlugin.activeTreatments } @Suppress("UNUSED_PARAMETER") diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationWithAction.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationWithAction.kt index f492196b29..4e85b03b5c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationWithAction.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/NotificationWithAction.kt @@ -22,8 +22,6 @@ class NotificationWithAction constructor( @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var nsClientPlugin: NSClientPlugin - private var nsAlarm: NSAlarm? = null - init { injector.androidInjector().inject(this) } @@ -36,7 +34,6 @@ class NotificationWithAction constructor( } constructor (injector: HasAndroidInjector, nsAlarm: NSAlarm) : this(injector) { - this.nsAlarm = nsAlarm date = System.currentTimeMillis() when (nsAlarm.level()) { 0 -> { @@ -50,14 +47,14 @@ class NotificationWithAction constructor( id = NSALARM level = NORMAL text = nsAlarm.title() - if (nsAlarm.low() && sp.getBoolean(R.string.key_nsalarm_low, false) || nsAlarm.high() && sp.getBoolean(R.string.key_nsalarm_high, false) || nsAlarm.timeago() && sp.getBoolean(R.string.key_nsalarm_staledata, false)) soundId = R.raw.alarm + soundId = R.raw.alarm } 2 -> { id = NSURGENTALARM level = URGENT text = nsAlarm.title() - if (nsAlarm.low() && sp.getBoolean(R.string.key_nsalarm_urgent_low, false) || nsAlarm.high() && sp.getBoolean(R.string.key_nsalarm_urgent_high, false) || nsAlarm.timeago() && sp.getBoolean(R.string.key_nsalarm_staledata, false)) soundId = R.raw.urgentalarm + soundId = R.raw.urgentalarm } } buttonText = R.string.snooze 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 7aa94f1dcc..60bba0fd13 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 @@ -85,7 +85,7 @@ class SmsCommunicatorPlugin @Inject constructor( "LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20", "TREATMENTS" to "TREATMENTS REFRESH", "NSCLIENT" to "NSCLIENT RESTART", - "PUMP" to "PUMP", + "PUMP" to "PUMP\nPUMP CONNECT\nPUMP DISCONNECT 30\n", "BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n", "BOLUS" to "BOLUS 1.2\nBOLUS 1.2 MEAL", "EXTENDED" to "EXTENDED STOP/CANCEL\nEXTENDED 2 120", @@ -228,7 +228,8 @@ class SmsCommunicatorPlugin @Inject constructor( if (splitted.size == 2) processNSCLIENT(splitted, receivedSms) else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) "PUMP" -> - if (splitted.size == 1) processPUMP(receivedSms) + if (!remoteCommandsAllowed && splitted.size > 1) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed))) + else if (splitted.size <= 3) processPUMP(splitted, receivedSms) else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) "PROFILE" -> if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed))) @@ -308,13 +309,20 @@ class SmsCommunicatorPlugin @Inject constructor( when (splitted[1].toUpperCase(Locale.getDefault())) { "DISABLE", "STOP" -> { if (loopPlugin.isEnabled(PluginType.LOOP)) { - loopPlugin.setPluginEnabled(PluginType.LOOP, false) - commandQueue.cancelTempBasal(true, object : Callback() { + val passCode = generatePasscode() + val reply = String.format(resourceHelper.gs(R.string.smscommunicator_loopdisablereplywithcode), passCode) + receivedSms.processed = true + messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction() { override fun run() { - rxBus.send(EventRefreshOverview("SMS_LOOP_STOP")) - val replyText = resourceHelper.gs(R.string.smscommunicator_loophasbeendisabled) + " " + - resourceHelper.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed) - sendSMS(Sms(receivedSms.phoneNumber, replyText)) + loopPlugin.setPluginEnabled(PluginType.LOOP, false) + commandQueue.cancelTempBasal(true, object : Callback() { + override fun run() { + rxBus.send(EventRefreshOverview("SMS_LOOP_STOP")) + val replyText = resourceHelper.gs(R.string.smscommunicator_loophasbeendisabled) + " " + + resourceHelper.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed) + sendSMS(Sms(receivedSms.phoneNumber, replyText)) + } + }) } }) } else @@ -324,9 +332,16 @@ class SmsCommunicatorPlugin @Inject constructor( "ENABLE", "START" -> { if (!loopPlugin.isEnabled(PluginType.LOOP)) { - loopPlugin.setPluginEnabled(PluginType.LOOP, true) - sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_loophasbeenenabled))) - rxBus.send(EventRefreshOverview("SMS_LOOP_START")) + val passCode = generatePasscode() + val reply = String.format(resourceHelper.gs(R.string.smscommunicator_loopenablereplywithcode), passCode) + receivedSms.processed = true + messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction() { + override fun run() { + loopPlugin.setPluginEnabled(PluginType.LOOP, true) + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_loophasbeenenabled))) + rxBus.send(EventRefreshOverview("SMS_LOOP_START")) + } + }) } else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_loopisenabled))) receivedSms.processed = true @@ -343,9 +358,16 @@ class SmsCommunicatorPlugin @Inject constructor( } "RESUME" -> { - rxBus.send(EventRefreshOverview("SMS_LOOP_RESUME")) - loopPlugin.createOfflineEvent(0) - sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_loopresumed))) + val passCode = generatePasscode() + val reply = String.format(resourceHelper.gs(R.string.smscommunicator_loopresumereplywithcode), passCode) + receivedSms.processed = true + messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction() { + override fun run() { + rxBus.send(EventRefreshOverview("SMS_LOOP_RESUME")) + loopPlugin.createOfflineEvent(0) + sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_loopresumed))) + } + }) } "SUSPEND" -> { @@ -420,20 +442,66 @@ class SmsCommunicatorPlugin @Inject constructor( sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) } - private fun processPUMP(receivedSms: Sms) { - commandQueue.readStatus("SMS", object : Callback() { - override fun run() { - val pump = activePlugin.activePump - if (result.success) { - val reply = pump.shortStatus(true) - sendSMS(Sms(receivedSms.phoneNumber, reply)) - } else { - val reply = resourceHelper.gs(R.string.readstatusfailed) - sendSMS(Sms(receivedSms.phoneNumber, reply)) + private fun processPUMP(splitted: Array, receivedSms: Sms) { + if (splitted.size == 1) { + commandQueue.readStatus("SMS", object : Callback() { + override fun run() { + val pump = activePlugin.activePump + if (result.success) { + val reply = pump.shortStatus(true) + sendSMS(Sms(receivedSms.phoneNumber, reply)) + } else { + val reply = resourceHelper.gs(R.string.readstatusfailed) + sendSMS(Sms(receivedSms.phoneNumber, reply)) + } } + }) + receivedSms.processed = true + } else if ((splitted.size == 2) && (splitted[1].equals("CONNECT", ignoreCase = true))) { + val passCode = generatePasscode() + val reply = String.format(resourceHelper.gs(R.string.smscommunicator_pumpconnectwithcode), passCode) + receivedSms.processed = true + messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction() { + override fun run() { + commandQueue.cancelTempBasal(true, object : Callback() { + override fun run() { + if (!result.success) { + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_pumpconnectfail))) + } else { + loopPlugin.suspendTo(0L) + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_reconnect))) + rxBus.send(EventRefreshOverview("SMS_PUMP_START")) + loopPlugin.createOfflineEvent(0) + } + } + }) + } + }) + } else if ((splitted.size == 3) && (splitted[1].equals("DISCONNECT", ignoreCase = true))) { + var duration = SafeParse.stringToInt(splitted[2]) + duration = Math.max(0, duration) + duration = Math.min(120, duration) + if (duration == 0) { + receivedSms.processed = true + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_wrongduration))) + return + } else { + val passCode = generatePasscode() + val reply = String.format(resourceHelper.gs(R.string.smscommunicator_pumpdisconnectwithcode), duration, passCode) + receivedSms.processed = true + messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction() { + override fun run() { + val profile = profileFunction.getProfile() + loopPlugin.disconnectPump(duration, profile) + rxBus.send(EventRefreshOverview("SMS_PUMP_DISCONNECT")) + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_pumpdisconnected))) + } + }) } - }) - receivedSms.processed = true + } else { + sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) + return + } } private fun processPROFILE(splitted: Array, receivedSms: Sms) { // load profiles diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/InMemoryGlucoseValue.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/InMemoryGlucoseValue.kt new file mode 100644 index 0000000000..55acd27b40 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/InMemoryGlucoseValue.kt @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.iob.iobCobCalculator + +import info.nightscout.androidaps.db.BgReading + +class InMemoryGlucoseValue constructor(var timestamp: Long = 0L, var value: Double = 0.0) { + + constructor(gv: BgReading) : this(gv.date, gv.value) +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java index 01e8aa2ce2..9563519107 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java @@ -39,6 +39,7 @@ import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; @@ -79,7 +80,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat private LongSparseArray basalDataTable = new LongSparseArray<>(); // oldest at index 0 private volatile List bgReadings = null; // newest at index 0 - private volatile List bucketed_data = null; + private volatile List bucketed_data = null; private final Object dataLock = new Object(); @@ -159,7 +160,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat runCalculation("onNewProfile", System.currentTimeMillis(), false, true, event); }, fabricPrivacy::logException) ); - // EventNewBG + // EventNewBG .... cannot be used for invalidating because only event with last BG is fired disposable.add(rxBus .toObservable(EventNewBG.class) .observeOn(Schedulers.io()) @@ -203,7 +204,13 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat disposable.add(rxBus .toObservable(EventNewHistoryData.class) .observeOn(Schedulers.io()) - .subscribe(this::newHistoryData, fabricPrivacy::logException) + .subscribe(event -> newHistoryData(event, false), fabricPrivacy::logException) + ); + // EventNewHistoryBgData + disposable.add(rxBus + .toObservable(EventNewHistoryBgData.class) + .observeOn(Schedulers.io()) + .subscribe(event -> newHistoryData(new EventNewHistoryData(event.getTimestamp()), true), fabricPrivacy::logException) ); } @@ -225,7 +232,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat this.bgReadings = bgReadings; } - public List getBucketedData() { + public List getBucketedData() { return bucketed_data; } @@ -335,15 +342,15 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat break; if (older.date == newer.date) { // direct hit - bucketed_data.add(newer); + bucketed_data.add(new InMemoryGlucoseValue(newer)); } else { double bgDelta = newer.value - older.value; long timeDiffToNew = newer.date - currentTime; double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta; - BgReading newBgreading = new BgReading(injector); - newBgreading.date = currentTime; - newBgreading.value = Math.round(currentBg); + InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(); + newBgreading.setTimestamp(currentTime); + newBgreading.setValue(Math.round(currentBg)); bucketed_data.add(newBgreading); //log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")"); } @@ -360,7 +367,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat } bucketed_data = new ArrayList<>(); - bucketed_data.add(bgReadings.get(0)); + bucketed_data.add(new InMemoryGlucoseValue(bgReadings.get(0))); getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgReadings.get(0).date) + " lastbgTime: " + "none-first-value" + " " + bgReadings.get(0).toString()); int j = 0; for (int i = 1; i < bgReadings.size(); ++i) { @@ -381,12 +388,12 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat while (elapsed_minutes > 5) { nextbgTime = lastbgTime - 5 * 60 * 1000; j++; - BgReading newBgreading = new BgReading(injector); - newBgreading.date = nextbgTime; + InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(); + newBgreading.setTimestamp(nextbgTime); double gapDelta = bgReadings.get(i).value - lastbg; //console.error(gapDelta, lastbg, elapsed_minutes); double nextbg = lastbg + (5d / elapsed_minutes * gapDelta); - newBgreading.value = Math.round(nextbg); + newBgreading.setValue(Math.round(nextbg)); //console.error("Interpolated", bucketed_data[j]); bucketed_data.add(newBgreading); getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); @@ -396,38 +403,38 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat lastbgTime = nextbgTime; } j++; - BgReading newBgreading = new BgReading(injector); - newBgreading.value = bgReadings.get(i).value; - newBgreading.date = bgTime; + InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(); + newBgreading.setValue(bgReadings.get(i).value); + newBgreading.setTimestamp(bgTime); bucketed_data.add(newBgreading); getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); } else if (Math.abs(elapsed_minutes) > 2) { j++; - BgReading newBgreading = new BgReading(injector); - newBgreading.value = bgReadings.get(i).value; - newBgreading.date = bgTime; + InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(); + newBgreading.setValue(bgReadings.get(i).value); + newBgreading.setTimestamp(bgTime); bucketed_data.add(newBgreading); getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); } else { - bucketed_data.get(j).value = (bucketed_data.get(j).value + bgReadings.get(i).value) / 2; + bucketed_data.get(j).setValue((bucketed_data.get(j).getValue() + bgReadings.get(i).value) / 2); //log.error("***** Average"); } } // Normalize bucketed data for (int i = bucketed_data.size() - 2; i >= 0; i--) { - BgReading current = bucketed_data.get(i); - BgReading previous = bucketed_data.get(i + 1); - long msecDiff = current.date - previous.date; + InMemoryGlucoseValue current = bucketed_data.get(i); + InMemoryGlucoseValue previous = bucketed_data.get(i + 1); + long msecDiff = current.getTimestamp() - previous.getTimestamp(); long adjusted = (msecDiff - T.mins(5).msecs()) / 1000; - getAapsLogger().debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + DateUtil.toISOString(current.date) + " to: " + DateUtil.toISOString(previous.date + T.mins(5).msecs()) + " by " + adjusted + " sec"); + getAapsLogger().debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + DateUtil.toISOString(current.getTimestamp()) + " to: " + DateUtil.toISOString(previous.getTimestamp() + T.mins(5).msecs()) + " by " + adjusted + " sec"); if (Math.abs(adjusted) > 90) { // too big adjustment, fallback to non 5 min data getAapsLogger().debug(LTag.AUTOSENS, "Fallback to non 5 min data"); createBucketedDataRecalculated(); return; } - current.date = previous.date + T.mins(5).msecs(); + current.setTimestamp(previous.getTimestamp() + T.mins(5).msecs()); } getAapsLogger().debug(LTag.AUTOSENS, "Bucketed data created. Size: " + bucketed_data.size()); @@ -544,8 +551,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat if (bucketed_data == null) return null; for (int index = 0; index < bucketed_data.size(); index++) { - if (bucketed_data.get(index).date <= time) - return bucketed_data.get(index).date; + if (bucketed_data.get(index).getTimestamp() <= time) + return bucketed_data.get(index).getTimestamp(); } return null; } @@ -814,15 +821,15 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat getAapsLogger().debug(LTag.AUTOSENS, "Starting calculation thread: " + from + " to " + dateUtil.dateAndTimeString(end)); if (thread == null || thread.getState() == Thread.State.TERMINATED) { if (sensitivityOref1Plugin.isEnabled()) - thread = new IobCobOref1Thread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause); + thread = new IobCobOref1Thread(injector, this, treatmentsPlugin, from, end, bgDataReload, limitDataToOldestAvailable, cause); else - thread = new IobCobThread(injector, this, from, end, bgDataReload, limitDataToOldestAvailable, cause); + thread = new IobCobThread(injector, this, treatmentsPlugin, from, end, bgDataReload, limitDataToOldestAvailable, cause); thread.start(); } } // When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated - private void newHistoryData(EventNewHistoryData ev) { + private void newHistoryData(EventNewHistoryData ev, boolean bgDataReload) { //log.debug("Locking onNewHistoryData"); stopCalculation("onEventNewHistoryData"); synchronized (dataLock) { @@ -862,7 +869,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat } } } - runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, true, ev); + runCalculation("onEventNewHistoryData", System.currentTimeMillis(), bgDataReload, true, ev); //log.debug("Releasing onNewHistoryData"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java index ef891ff62c..431d27f63c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java @@ -30,11 +30,13 @@ import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; @@ -61,7 +63,6 @@ public class IobCobOref1Thread extends Thread { @Inject ResourceHelper resourceHelper; @Inject ProfileFunction profileFunction; @Inject Context context; - @Inject ActivePluginProvider activePluginProvider; @Inject SensitivityAAPSPlugin sensitivityAAPSPlugin; @Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin; @Inject BuildHelper buildHelper; @@ -71,6 +72,7 @@ public class IobCobOref1Thread extends Thread { private final HasAndroidInjector injector; private final IobCobCalculatorPlugin iobCobCalculatorPlugin; // cannot be injected : HistoryBrowser uses different instance + private final TreatmentsPlugin treatmentsPlugin; // cannot be injected : HistoryBrowser uses different instance private boolean bgDataReload; private boolean limitDataToOldestAvailable; private String from; @@ -78,11 +80,12 @@ public class IobCobOref1Thread extends Thread { private PowerManager.WakeLock mWakeLock; - IobCobOref1Thread(HasAndroidInjector injector, IobCobCalculatorPlugin iobCobCalculatorPlugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { + IobCobOref1Thread(HasAndroidInjector injector, IobCobCalculatorPlugin iobCobCalculatorPlugin, TreatmentsPlugin treatmentsPlugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { super(); injector.androidInjector().inject(this); this.injector = injector; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; + this.treatmentsPlugin = treatmentsPlugin; this.bgDataReload = bgDataReload; this.limitDataToOldestAvailable = limitDataToOldestAvailable; @@ -114,8 +117,9 @@ public class IobCobOref1Thread extends Thread { if (bgDataReload) { iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); + rxBus.send(new EventAutosensBgLoaded(cause)); } - List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); + List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { @@ -123,7 +127,7 @@ public class IobCobOref1Thread extends Thread { return; } - long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); + long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).getTimestamp()); aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime)); AutosensData previous = autosensDataTable.get(prevDataTime); // start from oldest to be able sub cob @@ -137,7 +141,7 @@ public class IobCobOref1Thread extends Thread { return; } // check if data already exists - long bgTime = bucketed_data.get(i).date; + long bgTime = bucketed_data.get(i).getTimestamp(); bgTime = IobCobCalculatorPlugin.roundUpTime(bgTime); if (bgTime > IobCobCalculatorPlugin.roundUpTime(now())) continue; @@ -169,14 +173,14 @@ public class IobCobOref1Thread extends Thread { double bg; double avgDelta; double delta; - bg = bucketed_data.get(i).value; - if (bg < 39 || bucketed_data.get(i + 3).value < 39) { + bg = bucketed_data.get(i).getValue(); + if (bg < 39 || bucketed_data.get(i + 3).getValue() < 39) { aapsLogger.error("! value < 39"); continue; } autosensData.bg = bg; - delta = (bg - bucketed_data.get(i + 1).value); - avgDelta = (bg - bucketed_data.get(i + 3).value) / 3; + delta = (bg - bucketed_data.get(i + 1).getValue()); + avgDelta = (bg - bucketed_data.get(i + 3).getValue()) / 3; IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile); @@ -240,7 +244,7 @@ public class IobCobOref1Thread extends Thread { } } - List recentCarbTreatments = activePluginProvider.getActiveTreatments().getCarbTreatments5MinBackFromHistory(bgTime); + List recentCarbTreatments = treatmentsPlugin.getCarbTreatments5MinBackFromHistory(bgTime); for (Treatment recentCarbTreatment : recentCarbTreatments) { autosensData.carbsFromBolus += recentCarbTreatment.carbs; boolean isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled(); @@ -363,7 +367,7 @@ public class IobCobOref1Thread extends Thread { // add an extra negative deviation if a high temptarget is running and exercise mode is set // TODO AS-FIX if (false && sp.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) { - TempTarget tempTarget = activePluginProvider.getActiveTreatments().getTempTargetFromHistory(bgTime); + TempTarget tempTarget = treatmentsPlugin.getTempTargetFromHistory(bgTime); if (tempTarget != null && tempTarget.target() >= 100) { autosensData.extraDeviation.add(-(tempTarget.target() - 100) / 20); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java index d5af67e3b8..d2d73c1ba9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java @@ -28,11 +28,13 @@ import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; @@ -58,7 +60,6 @@ public class IobCobThread extends Thread { @Inject ResourceHelper resourceHelper; @Inject ProfileFunction profileFunction; @Inject Context context; - @Inject ActivePluginProvider activePluginProvider; @Inject SensitivityAAPSPlugin sensitivityAAPSPlugin; @Inject SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin; @Inject BuildHelper buildHelper; @@ -68,6 +69,7 @@ public class IobCobThread extends Thread { private final HasAndroidInjector injector; private final IobCobCalculatorPlugin iobCobCalculatorPlugin; // cannot be injected : HistoryBrowser uses different instance + private final TreatmentsPlugin treatmentsPlugin; // cannot be injected : HistoryBrowser uses different instance private boolean bgDataReload; private boolean limitDataToOldestAvailable; private String from; @@ -75,11 +77,12 @@ public class IobCobThread extends Thread { private PowerManager.WakeLock mWakeLock; - @Inject IobCobThread(HasAndroidInjector injector, IobCobCalculatorPlugin iobCobCalculatorPlugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { + @Inject IobCobThread(HasAndroidInjector injector, IobCobCalculatorPlugin iobCobCalculatorPlugin, TreatmentsPlugin treatmentsPlugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { super(); injector.androidInjector().inject(this); this.injector = injector; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; + this.treatmentsPlugin = treatmentsPlugin; this.bgDataReload = bgDataReload; this.limitDataToOldestAvailable = limitDataToOldestAvailable; @@ -111,8 +114,9 @@ public class IobCobThread extends Thread { if (bgDataReload) { iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); + rxBus.send(new EventAutosensBgLoaded(cause)); } - List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); + List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { @@ -120,7 +124,7 @@ public class IobCobThread extends Thread { return; } - long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); + long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).getTimestamp()); aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime)); AutosensData previous = autosensDataTable.get(prevDataTime); // start from oldest to be able sub cob @@ -134,7 +138,7 @@ public class IobCobThread extends Thread { return; } // check if data already exists - long bgTime = bucketed_data.get(i).date; + long bgTime = bucketed_data.get(i).getTimestamp(); bgTime = IobCobCalculatorPlugin.roundUpTime(bgTime); if (bgTime > IobCobCalculatorPlugin.roundUpTime(now())) continue; @@ -166,14 +170,14 @@ public class IobCobThread extends Thread { double bg; double avgDelta; double delta; - bg = bucketed_data.get(i).value; - if (bg < 39 || bucketed_data.get(i + 3).value < 39) { + bg = bucketed_data.get(i).getValue(); + if (bg < 39 || bucketed_data.get(i + 3).getValue() < 39) { aapsLogger.error("! value < 39"); continue; } autosensData.bg = bg; - delta = (bg - bucketed_data.get(i + 1).value); - avgDelta = (bg - bucketed_data.get(i + 3).value) / 3; + delta = (bg - bucketed_data.get(i + 1).getValue()); + avgDelta = (bg - bucketed_data.get(i + 3).getValue()) / 3; IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile); @@ -237,7 +241,7 @@ public class IobCobThread extends Thread { } } - List recentCarbTreatments = activePluginProvider.getActiveTreatments().getCarbTreatments5MinBackFromHistory(bgTime); + List recentCarbTreatments = treatmentsPlugin.getCarbTreatments5MinBackFromHistory(bgTime); for (Treatment recentCarbTreatment : recentCarbTreatments) { autosensData.carbsFromBolus += recentCarbTreatment.carbs; boolean isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensBgLoaded.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensBgLoaded.kt new file mode 100644 index 0000000000..b02e96b67f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventAutosensBgLoaded.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events + +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.events.EventLoop + +class EventAutosensBgLoaded(var cause: Event) : EventLoop() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventNewHistoryBgData.kt b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventNewHistoryBgData.kt new file mode 100644 index 0000000000..5f546c2d9f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/events/EventNewHistoryBgData.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events + +import info.nightscout.androidaps.events.Event + +class EventNewHistoryBgData(val timestamp: Long) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index aebcb7eaf6..0da2b70209 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -597,6 +597,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, bolusMessage.setDuration(0); bolusMessage.setExtendedAmount(0); bolusMessage.setImmediateAmount(insulin); + bolusMessage.setVibration(sp.getBoolean(detailedBolusInfo.isSMB ? R.string.key_disable_vibration_auto : R.string.key_disable_vibration ,false)); bolusID = connectionService.requestMessage(bolusMessage).await().getBolusId(); bolusCancelled = false; } @@ -720,7 +721,8 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, PumpEnactResult cancelTBRResult = cancelTempBasalOnly(); if (cancelTBRResult.success) { PumpEnactResult ebResult = setExtendedBolusOnly((absoluteRate - getBaseBasalRate()) / 60D - * ((double) durationInMinutes), durationInMinutes); + * ((double) durationInMinutes), durationInMinutes, + sp.getBoolean(R.string.key_disable_vibration_auto,false)); if (ebResult.success) { result.success = true; result.enacted = true; @@ -798,7 +800,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, @NonNull @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { PumpEnactResult result = cancelExtendedBolusOnly(); - if (result.success) result = setExtendedBolusOnly(insulin, durationInMinutes); + if (result.success) result = setExtendedBolusOnly(insulin, durationInMinutes, sp.getBoolean(R.string.key_disable_vibration,false)); try { fetchStatus(); readHistory(); @@ -812,7 +814,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, return result; } - public PumpEnactResult setExtendedBolusOnly(Double insulin, Integer durationInMinutes) { + public PumpEnactResult setExtendedBolusOnly(Double insulin, Integer durationInMinutes, boolean disableVibration) { PumpEnactResult result = new PumpEnactResult(getInjector()); try { DeliverBolusMessage bolusMessage = new DeliverBolusMessage(); @@ -820,6 +822,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, bolusMessage.setDuration(durationInMinutes); bolusMessage.setExtendedAmount(insulin); bolusMessage.setImmediateAmount(0); + bolusMessage.setVibration(disableVibration); int bolusID = connectionService.requestMessage(bolusMessage).await().getBolusId(); InsightBolusID insightBolusID = new InsightBolusID(); insightBolusID.bolusID = bolusID; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/remote_control/DeliverBolusMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/remote_control/DeliverBolusMessage.java index e0d0f2461a..6a4973b42b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/remote_control/DeliverBolusMessage.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/app_layer/remote_control/DeliverBolusMessage.java @@ -14,6 +14,7 @@ public class DeliverBolusMessage extends AppLayerMessage { private double extendedAmount; private int duration; private int bolusId; + private boolean disableVibration = false; public DeliverBolusMessage() { super(MessagePriority.NORMAL, true, true, Service.REMOTE_CONTROL); @@ -22,7 +23,11 @@ public class DeliverBolusMessage extends AppLayerMessage { @Override protected ByteBuf getData() { ByteBuf byteBuf = new ByteBuf(22); - byteBuf.putUInt16LE(252); + // 805 => Old value with vibration (2.6.1 and earlier), 252 => new value without vibrations for firmware 3.x + if (disableVibration) + byteBuf.putUInt16LE(252); + else + byteBuf.putUInt16LE(805); byteBuf.putUInt16LE(BolusTypeIDs.IDS.getID(bolusType)); byteBuf.putUInt16LE(31); byteBuf.putUInt16LE(0); @@ -57,6 +62,8 @@ public class DeliverBolusMessage extends AppLayerMessage { this.duration = duration; } + public void setVibration(boolean disableVibration) { this.disableVibration = disableVibration;} + public int getBolusId() { return bolusId; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java index 77df3be676..89480fcdf3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java @@ -1571,6 +1571,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter this.hasTimeDateOrTimeZoneChanged = true; } + @Override public boolean setNeutralTempAtFullHour() { + return sp.getBoolean(R.string.key_set_neutral_temps, true); + } + private void setEnableCustomAction(MedtronicCustomActionType customAction, boolean isEnabled) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.java index a8405ea00d..3737dd0226 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicCommunicationManager.java @@ -61,14 +61,11 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil; */ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager { - @Inject AAPSLogger aapsLogger; @Inject MedtronicPumpStatus medtronicPumpStatus; @Inject MedtronicPumpPlugin medtronicPumpPlugin; @Inject MedtronicConverter medtronicConverter; @Inject MedtronicUtil medtronicUtil; @Inject MedtronicPumpHistoryDecoder medtronicPumpHistoryDecoder; - @Inject RileyLinkServiceData rileyLinkServiceData; - @Inject ServiceTaskExecutor serviceTaskExecutor; private final int MAX_COMMAND_TRIES = 3; private final int DEFAULT_TIMEOUT = 2000; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index 5a47672e8c..575fe385ec 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -95,13 +95,12 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface private final OmnipodManager delegate; - @Deprecated + //TODO: remove and use injection private static AapsOmnipodManager instance; private Date lastBolusTime; private Double lastBolusUnits; - @Deprecated public static AapsOmnipodManager getInstance() { return instance; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java index d206337384..7a6c025433 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java @@ -7,7 +7,6 @@ import java.util.Date; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPumpPluginInterface; @@ -103,7 +102,7 @@ public class OmnipodUIPostprocessor { private boolean isLogEnabled() { - return L.isEnabled(LTag.PUMP); + return true; //L.isEnabled(LTag.PUMP); } public RxBusWrapper getRxBus() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt index bb008b383b..12af6cfe04 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/RandomBgPlugin.kt @@ -12,12 +12,14 @@ import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -29,13 +31,14 @@ class RandomBgPlugin @Inject constructor( injector: HasAndroidInjector, resourceHelper: ResourceHelper, aapsLogger: AAPSLogger, - private val virtualPumpPlugin: VirtualPumpPlugin, - private val buildHelper: BuildHelper + private val sp: SP, + private val nsUpload: NSUpload ) : PluginBase(PluginDescription() .mainType(PluginType.BGSOURCE) .fragmentClass(BGSourceFragment::class.java.name) .pluginName(R.string.randombg) .shortName(R.string.randombg_short) + .preferencesId(R.xml.pref_bgsource) .description(R.string.description_source_randombg), aapsLogger, resourceHelper, injector ), BgSourceInterface { @@ -55,7 +58,7 @@ class RandomBgPlugin @Inject constructor( } override fun advancedFilteringSupported(): Boolean { - return false + return true } override fun onStart() { @@ -69,7 +72,7 @@ class RandomBgPlugin @Inject constructor( } override fun specialEnableCondition(): Boolean { - return isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode() + return true //isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode() } override fun handleNewData(intent: Intent) { @@ -85,7 +88,12 @@ class RandomBgPlugin @Inject constructor( bgReading.value = bgMgdl bgReading.date = DateUtil.now() bgReading.raw = bgMgdl - MainApp.getDbHelper().createIfNotExists(bgReading, "RandomBG") + if (MainApp.getDbHelper().createIfNotExists(bgReading, "RandomBG")) { + if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) + nsUpload.uploadBg(bgReading, "AndroidAPS-RandomBG") + if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) + nsUpload.sendToXdrip(bgReading) + } aapsLogger.debug(LTag.BGSOURCE, "Generated BG: $bgReading") } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java index 60bd9b9b8c..18d997178e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentService.java @@ -45,6 +45,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData; +import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.JsonHelper; import io.reactivex.disposables.CompositeDisposable; @@ -588,6 +589,30 @@ public class TreatmentService extends OrmLiteBaseService { } } + /** + * Returns the newest record with insulin > 0 + */ + @Nullable + public Treatment getLastBolus(boolean excludeSMB) { + try { + QueryBuilder queryBuilder = getDao().queryBuilder(); + Where where = queryBuilder.where(); + where.gt("insulin", 0); + where.and().le("date", DateUtil.now()); + where.and().eq("isValid", true); + if (excludeSMB) where.and().eq("isSMB", false); + queryBuilder.orderBy("date", false); + queryBuilder.limit(1L); + + List result = getDao().query(queryBuilder.prepare()); + if (result.isEmpty()) + return null; + return result.get(0); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + public void deleteNS(JSONObject json) { String _id = JsonHelper.safeGetString(json, "_id"); if (_id != null && !_id.isEmpty()) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java index f273015441..8d723cea71 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java @@ -178,7 +178,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface return this.service; } - private long range() { + protected long range() { double dia = Constants.defaultDIA; if (profileFunction.getProfile() != null) dia = profileFunction.getProfile().getDia(); @@ -335,33 +335,27 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface @Override public long getLastBolusTime() { - long now = System.currentTimeMillis(); - long last = 0; - synchronized (treatments) { - for (Treatment t : treatments) { - if (!t.isValid) - continue; - if (t.date > last && t.insulin > 0 && t.date <= now) - last = t.date; - } + Treatment last = getService().getLastBolus(false); + if (last == null) { + getAapsLogger().debug(LTag.DATATREATMENTS, "Last bolus time: NOTHING FOUND"); + return 0; + } + else { + getAapsLogger().debug(LTag.DATATREATMENTS, "Last bolus time: " + dateUtil.dateAndTimeString(last.date)); + return last.date; } - getAapsLogger().debug(LTag.DATATREATMENTS, "Last bolus time: " + dateUtil.dateAndTimeString(last)); - return last; } - public long getLastBolusTime(boolean isSMB) { - long now = System.currentTimeMillis(); - long last = 0; - synchronized (treatments) { - for (Treatment t : treatments) { - if (!t.isValid) - continue; - if (t.date > last && t.insulin > 0 && t.date <= now && isSMB == t.isSMB) - last = t.date; - } + public long getLastBolusTime(boolean excludeSMB) { + Treatment last = getService().getLastBolus(excludeSMB); + if (last == null) { + getAapsLogger().debug(LTag.DATATREATMENTS, "Last manual bolus time: NOTHING FOUND"); + return 0; + } + else { + getAapsLogger().debug(LTag.DATATREATMENTS, "Last manual bolus time: " + dateUtil.dateAndTimeString(last.date)); + return last.date; } - getAapsLogger().debug(LTag.DATATREATMENTS, "Last manual bolus time: " + dateUtil.dateAndTimeString(last)); - return last; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt index c8e406881b..d0f8c29138 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt @@ -34,7 +34,7 @@ import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.CryptoUtil -import info.nightscout.androidaps.utils.LocaleHelper.update +import info.nightscout.androidaps.utils.locale.LocaleHelper.update import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.kt index b265af0d4c..44af0e1312 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.kt @@ -20,7 +20,7 @@ import info.nightscout.androidaps.setupwizard.elements.SWItem import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.LocaleHelper.update +import info.nightscout.androidaps.utils.locale.LocaleHelper.update import info.nightscout.androidaps.utils.alertDialogs.OKDialog.show import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation import info.nightscout.androidaps.utils.resources.ResourceHelper diff --git a/app/src/main/java/info/nightscout/androidaps/skins/SkinButtonsOn.kt b/app/src/main/java/info/nightscout/androidaps/skins/SkinButtonsOn.kt index b2243d3336..9584ce2f4b 100644 --- a/app/src/main/java/info/nightscout/androidaps/skins/SkinButtonsOn.kt +++ b/app/src/main/java/info/nightscout/androidaps/skins/SkinButtonsOn.kt @@ -8,7 +8,9 @@ import javax.inject.Singleton @Singleton class SkinButtonsOn @Inject constructor(private val config: Config) : SkinInterface { - override val description: Int get() = R.string.buttonson_desrciption + override val description: Int get() = R.string.buttonson_description + override val mainGraphHeight: Int get() = 200 + override val secondaryGraphHeight: Int get() = 100 override fun overviewLayout(isLandscape: Boolean, isTablet: Boolean, isSmallHeight: Boolean): Int = when { diff --git a/app/src/main/java/info/nightscout/androidaps/skins/SkinClassic.kt b/app/src/main/java/info/nightscout/androidaps/skins/SkinClassic.kt index deef2440f3..9388843db8 100644 --- a/app/src/main/java/info/nightscout/androidaps/skins/SkinClassic.kt +++ b/app/src/main/java/info/nightscout/androidaps/skins/SkinClassic.kt @@ -8,7 +8,9 @@ import javax.inject.Singleton @Singleton class SkinClassic @Inject constructor(private val config: Config): SkinInterface { - override val description: Int get() = R.string.classic_desrciption + override val description: Int get() = R.string.classic_description + override val mainGraphHeight: Int get() = 200 + override val secondaryGraphHeight: Int get() = 100 override fun overviewLayout(isLandscape: Boolean, isTablet: Boolean, isSmallHeight: Boolean): Int = when { diff --git a/app/src/main/java/info/nightscout/androidaps/skins/SkinInterface.kt b/app/src/main/java/info/nightscout/androidaps/skins/SkinInterface.kt index 6a9d055a13..73c047d100 100644 --- a/app/src/main/java/info/nightscout/androidaps/skins/SkinInterface.kt +++ b/app/src/main/java/info/nightscout/androidaps/skins/SkinInterface.kt @@ -6,5 +6,7 @@ import androidx.annotation.StringRes interface SkinInterface { @get:StringRes val description : Int + val mainGraphHeight : Int // in dp + val secondaryGraphHeight : Int // in dp @LayoutRes fun overviewLayout(isLandscape : Boolean, isTablet : Boolean, isSmallHeight : Boolean): Int } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/skins/SkinLargeDisplay.kt b/app/src/main/java/info/nightscout/androidaps/skins/SkinLargeDisplay.kt new file mode 100644 index 0000000000..b28a0e3e0a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/skins/SkinLargeDisplay.kt @@ -0,0 +1,23 @@ +package info.nightscout.androidaps.skins + +import info.nightscout.androidaps.Config +import info.nightscout.androidaps.R +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SkinLargeDisplay @Inject constructor(private val config: Config): SkinInterface { + + override val description: Int get() = R.string.largedisplay_description + override val mainGraphHeight: Int get() = 400 + override val secondaryGraphHeight: Int get() = 150 + + override fun overviewLayout(isLandscape: Boolean, isTablet: Boolean, isSmallHeight: Boolean): Int = + when { + config.NSCLIENT && isTablet -> R.layout.overview_fragment_nsclient_tablet + config.NSCLIENT -> R.layout.overview_fragment_nsclient + isSmallHeight || isLandscape -> R.layout.overview_fragment_landscape + else -> R.layout.overview_fragment + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java b/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java index 9b754ac47a..db1f6af239 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java @@ -1,6 +1,5 @@ package info.nightscout.androidaps.utils; -import android.os.Build; import android.text.Html; import android.text.Spanned; @@ -8,7 +7,6 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.Iterator; @@ -24,33 +22,24 @@ public class JSONFormatter { final JsonVisitor visitor = new JsonVisitor(1, '\t'); try { if (jsonString.equals("undefined")) - return Html.fromHtml("undefined"); + return HtmlHelper.INSTANCE.fromHtml("undefined"); else if (jsonString.getBytes()[0] == '[') - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return Html.fromHtml(visitor.visit(new JSONArray(jsonString), 0), Html.FROM_HTML_MODE_COMPACT); - } else { - return Html.fromHtml(visitor.visit(new JSONArray(jsonString), 0)); - } - else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return Html.fromHtml(visitor.visit(new JSONObject(jsonString), 0), Html.FROM_HTML_MODE_COMPACT); - } else { - return Html.fromHtml(visitor.visit(new JSONObject(jsonString), 0)); - } - } + return HtmlHelper.INSTANCE.fromHtml(visitor.visit(new JSONArray(jsonString), 0)); + else + return HtmlHelper.INSTANCE.fromHtml(visitor.visit(new JSONObject(jsonString), 0)); } catch (JSONException e) { log.error("Unhandled exception", e); - return Html.fromHtml(""); + return HtmlHelper.INSTANCE.fromHtml(""); } } public static Spanned format(final JSONObject object) { final JsonVisitor visitor = new JsonVisitor(1, '\t'); try { - return Html.fromHtml(visitor.visit(object, 0)); + return HtmlHelper.INSTANCE.fromHtml(visitor.visit(object, 0)); } catch (JSONException e) { log.error("Unhandled exception", e); - return Html.fromHtml(""); + return HtmlHelper.INSTANCE.fromHtml(""); } } diff --git a/app/src/main/res/layout/overview_statuslights_layout.xml b/app/src/main/res/layout/overview_statuslights_layout.xml index 930f996736..13b9fd1815 100644 --- a/app/src/main/res/layout/overview_statuslights_layout.xml +++ b/app/src/main/res/layout/overview_statuslights_layout.xml @@ -16,6 +16,8 @@ android:layout_weight="1" android:gravity="center_vertical" android:scaleType="centerInside" + android:scaleX="2" + android:scaleY="2" android:src="@drawable/icon_cp_age_canula" /> Insulien ouderdom Pomp battery ouderdom Alarm Opsies - Nood hoog - Hoog - Laag - Nood laag - Ou data - Nood ou data Ou data drumpel [min] Nood ou data drumpel [min] Interval vir autosens [h] diff --git a/app/src/main/res/values-bg-rBG/objectives.xml b/app/src/main/res/values-bg-rBG/objectives.xml index 16339650fd..2d575aaaac 100644 --- a/app/src/main/res/values-bg-rBG/objectives.xml +++ b/app/src/main/res/values-bg-rBG/objectives.xml @@ -20,7 +20,9 @@ Една седмица успешно дневно използване с редовно въвеждане на въглехидрати Активиране на допълнителни функции за дневно използване, включително и advanced meal assist (АМА) Добавяне на допълнителни функции за използване през деня, като SMB + Разрешаване на автоматизация Трябва да прочетете wiki и увеличите maxIOB за да може SMB да работи добре! Добро начало е maxIOB = средния болус за хранене + 3 пъти най-големия базал от профила + Прочетете документацията как работи автоматизацията. Настройте първите си прости правила. Вместо да прави действия нека AAPS покаже само известие. Когато сте сигурни, автоматизацията се задейства в точното време, за да заменете известяването с реални действия. (https: //androidaps.readthedocs.io/en/latest/EN/Usage/Automation.html) КЗ да се вижда в NS Статуса на помпата да е достъпен в NS Ръчно приложени diff --git a/app/src/main/res/values-bg-rBG/protection.xml b/app/src/main/res/values-bg-rBG/protection.xml index 3ea04e700d..868fec0b53 100644 --- a/app/src/main/res/values-bg-rBG/protection.xml +++ b/app/src/main/res/values-bg-rBG/protection.xml @@ -1,2 +1,22 @@ - + + Изисква се удостоверяване + Поставете пръста си върху четеца на пръстови отпечатъци, за да потвърдите самоличността си + Защита на настройките + Защита на приложението + Защита от болус + Главна парола + Парола за настройки + Парола за приложението + Парола за болус + Биометрични данни + Допълнителна парола + Няма защита + Защита + Главната парола не е зададена!\n\nМоля, настройте Вашата главна парола в Предпочитания (%1$s → %2$s) + Паролата е зададена! + Паролата не е зададена + Паролата не е променена + Паролата е изчистена! + Въведете парола + diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 80bafc0b29..8360491ecf 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -130,6 +130,7 @@ APS режим Затворен кръг Отворен кръг + Спиране на базал при ниска КЗ Loop изключен Изключи Loop Включи Loop @@ -170,6 +171,52 @@ Макс. лимит на временен базал [Е/ч] Максимален IOB Този параметър се нарича максимален IOB в OpenAPS и подразбиране е 0. След няколко дни или седмици можете да го увеличите. + Главна парола, която ще бъде използвана за криптиране на експортирани настройки. + Парола, която е била използвана за криптиране на експортираните настройки. + Експорт неуспешен! Настройките не са експортирани! + Импорт неуспешен! Настройките не са импортирани! + Изберете файл + Моля, проверете насстройките преди импортирането: + Настройите не могат да бъдат импортирани! + Настройите не трябва да бъдат импортирани! (опасни) + Разясняване на проблеми с импорт… + Подробности за проблеми с импорта + Импорт + Импортирай все пак (ОПАСНО!) + Настройките са създадени с различен вариант на AAPS (%1$s) докато Вие сте с: %2$s.\n\nНякои настройки може да липсват или са невалидни!След импортиране, моля, проверете и актуализирайте своите настройки. + Настройките са създадени на друго устройство. Това е ОК, ако импортирате от по-стар/различен телефон, но се уверете, че тези настройки са правилни! + Използвате остарял формат от старите версии на AAPS, който не е защитен! Използвайте го само като крайна мярка, или експортирайте в JSON формат. + Импортираните настройки са стари %1$s дни! Може би имате по-актуални настройки или сте избрали грешен файл? Не забравяйте да експортирате настройки редовно! + Невалиден формат на датата! + Настройки от различна под-версия на приложението. Това е ОК, ако импортирате след надстройка, но проверете след вноса, ако настройки са все още правилни! + Настройки от различна главна версия на приложението. Основните версии се различават значително и могат да имат несъвместими настройки! Уверете се, че след импорт, че преференциите са все още правилни! + Формат на файла + Създаден на + Версия на AAPS + вариант + Име на пациента + Модел на телефона: + Криптиране + Стар формат + Нов формат + Нов формат (некриптирани) + Непознат формат + Файлът с настройки е преправян + Файлът с настройки е сигурен + Използване на нешифровани настройки е рисково + Грешка във формат JSON, липсва поле (формат, съдържание, метаданни или сигурност) + Грешка при декриптиране, грешна парола + Контролна сума (hash) липсва, не може да се провери автентичността на настройките! + Файлът е бил модифициран след експорт! + Грешка при декриптиране, възстановяването неуспешно! + Грешка при декриптиране, грешна парола или файлът с настройки е модифициран! Възможно е импортираният файл да е експортиран с различна парола. + Липсва конфигурация на шифроване, форматът на настройките е невалиден! + Неподдържан или непотвърден алгоритъм за криптиране! + експортирани днес + от преди %1$s + от %1$s + от преди по-малко от час + в директория: %1$s Лицензионно споразумение с краен потребител НЕ ТРЯБВА ДА СЕ ИЗПОЛЗВА ЗА ВЗЕМАНЕ НА МЕДИЦИНСКИ РЕШЕНИЯ. НЯМА ГАРАНЦИЯ ЗА ПРОГРАМАТА, ДО СТЕПЕНТА, ПОЗВОЛЕНА ОТ ПРИЛОЖИМОТО ПРАВО. ОСВЕН КОГАТО Е ПОСОЧЕНО ДРУГО В ПИСМЕН ВИД, ПРИТЕЖАТЕЛИТЕ НА АВТОРСКОТО ПРАВО И/ИЛИ ДРУГИ СТРАНИ ПРЕДОСТАВЯТ ПРОГРАМАТА \"КАКТО Е\", БЕЗ ГАРАНЦИИ ОТ ВСЯКАКЪВ ВИД, ИЗРАЗЕНИ ИЛИ ПОДРАЗБИРАЩИ СЕ, ВКЛЮЧИТЕЛНО, НО НЕ САМО, ПОДРАЗБИРАЩИ СЕ ГАРАНЦИИ ЗА ПРОДАВАЕМОСТ И ПРИГОДНОСТ ЗА КОНКРЕТНА ЦЕЛ. ЦЕЛИЯ РИСК ПО ОТНОШЕНИЕ НА КАЧЕСТВОТО И ЕФЕКТИВНОСТТА НА ПРОГРАМАТА Е САМО ВАШ. АКО ПРОГРАМАТА НЕ СРАБОТИ, ВИЕ ПОЕМАТЕ ВСИЧКИ НЕОБХОДИМИ РАЗХОДИ ЗА ОБСЛУЖВАНЕ, РЕМОНТ ИЛИ КОРЕКЦИЯ. Разбирам и приемам @@ -217,6 +264,9 @@ За да въведете %1$dг в %2$s отговорете с код %3$s За да стартирате базал от %1$d%%Е/ч за %2$d мин отговорете с код %3$s За да спрете APS за %1$d минути отговорете с код %2$s + За възстановяване на кръга отговорете с код %1$s + За активирнае на кръга отговорете с код %1$s + За изключване на кръга отговорете с код %1$s Временен базал от %1$.2fЕ/ч за %2$d мин стартиран успешно Удължен болус %1$.2fU за %2$d мин стартиран успешно Въглехидрати %1$dг въведени @@ -353,6 +403,9 @@ Възрастен Възрастни с голяма инсулинова резистентност Изберете възраст за определяне лимитите на безопасност + Име на пациента + Моля, посочете име на пациента или измислено име, за да се различават + Потребител Glimp %1$s се нуждае от изключване от списъка за оптимизиране на батерията за пълна функционалност Loop изключен @@ -387,12 +440,26 @@ Разреши използването на Суперболус Разреши функцията суперболус в съветника. Не я разрешавайте докато не научите какво наистина прави. ТОВА МОЖЕ ДА СЪЗДАДЕ ОПАСНОСТ ОТ ПРЕДОЗИРАНЕ С ИНСУЛИН. Покажи статус светлини на началния екран + Праг за възраст на канюла [часа] + Праг за критична възраст на канюла [часа] + Праг за инсулинова възраст [часа] + Праг за критична инсулинова възраст [часа] + Праг за възраст на сензор [часа] + Праг за критична възраст на сензор [часа] + Аларма при възраст на батерия над [часа] + Праг за критична възраст на батерията над [часа] Ниво за аларма за останал инсулин в резервоара [Е] Критично ниво на останал инсулин в резервоар [Е] Аларма при заряд на батерия под [%] Критично ниво на батерията под [%] + Предв IOB СОВ + БАЗА + Откл + АКТ + АБС + ОТК.НАКЛ За приложението SMS команда забранена Липсва разрешение до данни от телефона @@ -410,12 +477,8 @@ Смени профил Възраст на батерията на помпата Опции за аларми - Много висока - Висока - Ниска - Много ниска - Стари данни - Много стари данни + Известяване при NS аларми + Създаване на известия от NS съобщения Когато няма данни повече от [мин] Много стари данни при повече от [мин] Интервал за autosens [ч] @@ -503,8 +566,13 @@ Настройки при качване на КЗ към Nightscout Показвай подробна делта Показвай делта с още един десетичен знак + Интервал между SMB в минути Максимум минути СМБ Максимални минути за ограничаване на базала от SMB + Максимум минути за отчитане на необявени хранения UAM + Максимални минути за ограничаване на базала при SMB за UAM + Праг на предложение за въгл. + Когато се предлагат въгл., при колко да се покаже уведомление Изпращай данни за КЗ към xDrip+ В xDrip+ изберете 640g/Eversense за източник на данни КЗ от NS @@ -563,6 +631,8 @@ Грешка при доставяне на удължен болус Sight преди + Прилагане на неутрални временни базали + Ако е вкл, то ще анулира временен базал на всеки час. Това може да помогне за спиране на звук/вибрация от някой помпи на всеки час. Разреши SMB постоянно Разрешава SMB постоянно и независимо от болусите. Възможно само с източник на КЗ с добра филтрация като G5 Разреши SMB след въглехидрати @@ -734,6 +804,10 @@ Ниските цели да свалят ли чувствителността ? + Съпротивление намалява целта + Когато се установи резистентност, намалява целевата глюкоза. + Чувствителността увеличава целта + Когато се установи чувствителност, повишаване на целевата глюкоза Невалидни настройки на помпата, проверете wiki и се уверете че меню Quick Info се казва QUICK INFO, с помощта на 360 софтуера. По избор AndroidAPS стартира @@ -742,6 +816,7 @@ Данните за лечението не са пълни Настройки за поддръжка Имейл + Криптиране на експортирани настройки Брой логове за изпращане Поддръжка ПОДДР @@ -783,6 +858,10 @@ Записвай аларми Разреши емулация на временни базали Използвайте удължени болуси вместо временни базали да се заобиколи ограничението от 250%% + Изключи вибрациите при ръчен болус + За болус и разширен болус (само на разположение с Insight фърмуер 3.x) + Изключи вибрациите при автоматичен болус + За SMB и временни базали с емулация (достъпна само с Insight фърмуер 3.x) Забавяне при прекъсване на връзката [сек] Сериен номер Софтуер версия @@ -927,6 +1006,8 @@ съществува не съществува Временна цел %1$s + Bluetooth връзка към устройство %1$s %2$s + Връзка с Bluetooth устройство WiFi SSID %1$s %2$s Аутосенс %1$s %2$s %% Аутосенс % @@ -981,6 +1062,7 @@ Алкални Литиева NiZn батерия + NiMH (батерия) Болус/Корекция подробно СКАНИРАЙ @@ -1122,6 +1204,7 @@ Изчисти приключение Изчисти стартираните Искате ли да нулирате прогреса си? + Време и/или промяна на часовата зона на помпата Не е избрана помпа Изберете единиците, в които искате да работите Качване на локални промени в НС профила @@ -1171,19 +1254,148 @@ Макс. време за изпълнение за SMB Диапазон между временни базали Продължителност на временни базали + Информация за Insight Pump + от приложението AUTHENTICATOR за: %1$s + Активиране на удостоверител + Удостоверяване чрез еднократна парола, генерирана с Google Authenticator или подобна програма за 2-факторна оторизация. + Допълнителен PIN в края на токен + Допълнителни цифри, които следва да бъдат залепени в края на всяка генерирана еднократна парола + Настройка на удостоверителя + ОТР за проверка: + Нулиране на удостоверители + Нулиране на ключва + Сигурни ли сте, че ще анулирате ключа на Authenticator? Той ще направи всички конфигурирани в момента аудиентикатори невалидни, и вие ще трябва да ги настроите отново. + Генериран е нов ключ! Моля, използвайте актуализирания QRCode. + 1. Инсталиране на удостоверител + 2. Сканиране на кода за настройка на AndroidAPS OTP + 3. Тест на еднократна парола + Нулиране на удостоверители + На всеки следящ телефона инсталирайте приложение Аутентификатор, който поддържа RFC 6238 ТОТР токени. Популярни безплатни приложения:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator + Не давайте този код е онлайн!\nИзползвайте го само за сканиране на телефони последовател. + При нулиране на на удостоверителя, всички вече използвани удостоверения са невалидни. Ще трябва да ги настроите отново! + При свързване + При изключване Прогнозни КЗ + Наклон на отклонението + Удостоверяването неуспешно + Абсолютен инсулин + Главната парола се използва за архивиране на настройки и за подмяна на защитата в приложението. Запомни я или я пази на сигурно място. + Паролите не съвпадат + Сегашна главна парола + Индикатори + Копиране на настройки от NS + Копиране на профил от NS (ако има)? + Оригинален изглед + Бутоните винаги се показват на дъното на екрана. + Голям екран + Тема + Интеграция на помпата Omnipod, изисква RileyLink устройство (с фърмуер минимум 2.0 ) . + Звук при болус активен + Звук при базал активен + Звук при SMB активен + Звук при временен базал активен + Опции за отстраняване на грешки в под активирани + Разрешено е DST/Timezone + Под Mgmt + Статус на под + %1$.2f Е остават + Над 50 Е + Адрес на под + Срокът на пода изтича + Няма информация. + Няма активен под + Под не е инициализиран + Сигнали за активен под + Ack Предупреждения + Omnipod (433.91 MHz) + Забранено действие.\n\n Първо трябва да конфигурурате Omnipod , преди да използвате тази операция,. + Операцията не е възможна.\n\n Трябва да изчакате няколко минути, докато AAPS се опита да зададе профил за първи път. + Неправилен PodInitActionType: %1$s + Няма активен под. + Грешка при проверка на командата + Непредвидена грешка. Моля, докладвайте! (тип: %1$s). + Неуспешна комуникация: получени грешни входни параметри. + Връзката е неуспешна: таймаут. + Комуникацията е неуспешна: възникнала е неочаквана грешка. Моля, докладвайте! + Неуспешна комуникация: проверката на целостта на съобщението е неуспешна. + Неуспешна комуникация: получени грешни входни параметри. + Съобщението е неуспешно: Pod е в лошо състояние. + Неуспешна комуникация: получени грешни входни параметри. + Неуспешна комуникация: получи съобщение с невалиден номер на последователност от Pod. + Неуспешна комуникация: получи съобщение с невалиден номер на последователност от Pod. + Неуспешна комуникация: получени грешни входни параметри. + Комуникацията е неуспешна: nonce ресинхронизирането е неуспешно. + Комуникацията е неуспешна: nonce ресинхронизирането е неуспешно. + Комуникацията е неуспешна: няма достатъчно данни, получени от Pod. + Грешка на Pod (%1$03d %2$s). Моля, деактивирайте вашия Pod и стартирайте нов. + Комуникацията е неуспешна: Pod върна отговор с грешка. + Управление на Pod + Инициализация на Pod + Деактивирай под + Нулиране на под + История на под Стартирай болус + Отмяна на болус Приложи временен базал + Отказ на базал + Отказ на базал + Задаване на график за базал + Получу статус на под + Получи информация за Pod + Задаване на час + Конфигуриране на аларми + Потвърждение на аларми + Спиране на доставката на инсулин + Подновяване на доставката + Непознат запис + %1$.1fЕ + %1$.1f U, CH=%2$.1f g + Скорост: %1$.1f U, Продължителност: %2$d мин. + Ако натиснете OK, състоянието на Pod ще бъде нулирано и няма да можете да общувате с него повече. Правете това, само ако вече не можеш да се свързвате с него. Ако все още можете да общувате с Под, моля, използвайте опцията Деактивирай Pod. + Историята на Pod не е достъпна в момента. + Напълни Pod + \nНапълнете с достатъчно инсулин за 3 дни.\n\nИзчакайте два сигнала от Pod по време на процеса на зареждане. Те показват, че е вмъкнат минималният размер от 85U. Уверете се, че сте изпразнил напълно спринцовката, дори след като сте чули двата сигнала.\n\nСлед пълнене на Pod, моля натиснете Следващ.\n\nЗабележка: не вадете капачката на капсулата на Podв този момент. + Пълнене + Опитвам се да се сдвоя с Pod.\n\nКогато всички елементи са проверени, можете да натиснете Следващ.\n\nЗабележка: задръжте Pod много близо до RileyLink в този момент. + Прикрепете Pod + \nПодгответе мястото за инфузия. Отстранете капачката на Pod и лепенката и прикрепете капсулата към мястото за инфузия.\n\nАко канюла стърчи, моля натиснете Отказ и изхвърлете вашия Pod.\n\nПрес Следваща да се вмъкне канюлата и да започне базалната доставка. + Вмъкване на канюла + Опитвам се да определя първоначалния базален график и да вмъкна канюлата.\n\nКогато всички елементи са проверени, можете да натиснете Следващ. + Информация за Pod + \Podе активна.\n\nВашият базален график е програмиран и канюлата вмъкната.\n\nМоля, проверете дали канюлата е поставена правилно или заменете Pod, ако чувствате, че не е. + Деактивирай Pod + \nНатиснете Следващ , за да деактивирате Pod.\n\nЗабележка: Това ще спре всички доставки на инсулин и деактивира Pod. + Деактивиране на Pod + Деактивиране на Pod.\n\nКогато всички елементи са проверени, можете да натиснете Следващ.\n\nЗабележка: Ако деактивирането непрекъснато се проваля, моля натиснете Отказ и използвайте опция Нулирай Pod , за да възстановите състоянието на Pod. + Pod изключен.\n\nмоля, извадете Pod от тялото си и го хвърли. + Сдвояване на под + Пълнене на под + Напълни канула Приложи базалният профил + Отмяна + Деактивирай под + Интеграция на Omnipod Dash. + Край на напомняне за сдвояване + Край на напомнянето за настройка + Подът скоро ще изтече + Подът скоро ще изтече + Спирането е неизбежно Минимален инсулин в резервоара + Непозната аларма + Задаването на базален профил може да е неуспешно. Доставката на инсулин може да бъде спряна! Моля, опреснете статуса на под. + Стартиране на временен базал неуспешно. Ако е имало вече такъв, той може да е бил отменен! Моля, обновете статуса на пода. + Задаването на време може да е неуспешно. Доставката на инсулин може да бъде спряна! Моля, опреснете статуса на под. + Не може да се провери статус на болус. Моля, уверете се, че вашият под е стартирал болус или го отменете. + Статистика на RL + Pulse лог diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 9819565981..c395dac6e2 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -264,6 +264,9 @@ Pro zadání %1$dg na %2$s odpovězte pomocí SMS s kódem %3$s Pro spuštění bazálu %1$d%% na %2$d min odpovězte SMS s kódem %3$s K pozastavení smyčky na %1$d minut odpověz SMS s kódem %2$s + Chcete-li obnovit smyčku, odpovězte SMS s kódem %1$s + Chcete-li povolit smyčku, odpovězte SMS s kódem %1$s + Chcete-li zakázat smyčku, odpovězte SMS s kódem %1$s Dočasný bazál %1$.2fU/h na %2$d minut spuštěn Prodloužený bolus %1$.2fU na %2$d min úspěšně spuštěn Sacharidy %1$dg byly úspěšně zadány @@ -468,12 +471,8 @@ Proveďte přepnutí profilu Stáří baterie v pumpě Nastavení alarmů - Urgentně vysoká - Vysoká - Nízká - Urgentně nízká - Zastaralá data - Urgentně zastaralá data + Vytvořit oznámení z alarmů NS + Vytvořit oznámení z NS upozornění Mezní hodnota pro zastaralá data [min] Urgentní mezní hodnota pro zastaralá data [min] Interval pro detekci senzitivity [h] @@ -626,6 +625,8 @@ Chyba spuštění extended bolusu Insight zpět + Nastavit neutrální dočasný bazál + Je-li povoleno, zastaví dočasný bazál před koncem každé hodiny. To může u některých pump pomoci zastavit pípání/vibrace v celou hodinu. Vždy povolit SMB Povolit SMB nezávisle na bolusech. Možno pouze se zdroji glykémií s dobrým filtrováním dat, jako např. G5 Povolit SMB po jídle @@ -851,6 +852,10 @@ Zaznamenat výstrahy Povolit emulaci dočasných bazálů Používat prodloužené bolusy na obejití limitu dočasných bazálů 250%% + Zakázat vibrace při ručním podání bolusu + Pro bolus a prodloužený bolus (dostupné pouze s Insight firmware 3.x) + Zakázat vibrace při automatickém podání bolusu + Pro SMB a Dočasný bazál s emulací TBR (k dispozici pouze s Insight firmware 3.x) Limit pro odpojení [s] Sériové číslo Verze softwaru @@ -1275,8 +1280,6 @@ Stavové indikátory Zkopírovat nastavení z NS Zkopírovat nastavení NS (existuje-li)? - Původní vzhled - Tlačítka jsou vždy zobrazena v dolní části obrazovky Vzhled @@ -1347,9 +1350,43 @@ %1$.1f U %1$.1f U, Sach=%2$.1f g Rychlost: %1$.1f U, doba trvání: %2$d min + Pokud stisknete OK, stav Podu bude vynuceně resetován a již nebudete moci komunikovat s Podem. Udělejte to pouze v případě, že s Podem již nelze komunikovat. Pokud stále můžete komunikovat s Podem, použijte volbu Deaktivovat Pod. + Historie Podu není v daném okamžiku k dispozici. + Naplňte Pod + \nNaplňte nový Pod dostatkem inzulínu na 3 dny.\n\nSledujte dvě pípnutí z Podu během procesu plnění. Tyto ukazují, že minimální množství 85U bylo naplněno. Ujistěte se, že stříkačka je zcela vyprázdněná a to i po vyslechnutí dvou pípnutí.\n\nPo naplnění Podu, prosím, stiskněte Další.\n\nPoznámka: prozatím nesundavejte kryt jehly. + Plnění + Snažím se spárovat s novým Podem a naplnit ho.\n\nJakmile budou zaškrtnuty všechny položky, můžete stisknout Další.\n\nPoznámka: ponechte prosím Pod velmi blízko RileyLinku. + Nasaďte Pod + \nPřipravte infuzní místo. Odstraňte krytku jehly a náplasti a nalepte Pod.\n\nPokud se kanyla odlepí, stiskněte Zrušit a zahoďte Pod.\n\nStiskněte Další pro vložení kanyly a spuštění bazálů. + Vkládání kanyly + Snažím se nastavit počáteční základní bazální plán a vložit kanylu.\n\nPři zaškrtnutí všech položek můžete stisknout tlačítko Další. + Pod Info + \nPod je nyní aktivní.\n\nVáš bazál byl naprogramován a kanyla byla vložena.\n\nOvěřte, prosím, že kanyla byla vložena správně a případně vyměňte Pod. Deaktivovat Pod + \nStiskněte Další pro deaktivaci Podu.\n\nPoznámka: Zastavíte veškerý výdej inzulínu a deaktivujete Pod. + Deaktivace Podu + Deaktivace Podu.\n\nKdyž jsou zaškrtnuty všechny položky, můžete stisknout Další.\n\nPoznámka: Pokud deaktivace nepřetržitě selhává, prosím stiskněte Zrušit a použijte možnost Resetovat Pod pro resetování stavu Podu. + Pod deaktivován.\n\nOdstraňte Pod z těla a znehodnoťte jej. + Párování Podu + Plnění Podu + Plnění kanyly Nastavit bazální profil + Zrušit podávání Deaktivovat Pod + Integrace pumpy pro Omnipod Dash. + Upomínka dokončení párování + Upomínka dokončení nastavení + Životnost Podu brzy skončí + Pod brzy vyprší + Blíží se vypnutí + Nízký stav zásobníku + Neznámá výstraha + Nastavení bazálního profilu se možná nezdařilo. Výdej může být pozastaven! Obnovte prosím stav Podu. + Nastavení dočasného bazálu mohlo být neúspěšné. Pokud je dočasný bazál již spuštěn, mohl by být zrušen! Aktualizujte prosím stav Podu. + Nastavení času se možná nezdařilo. Výdej může být pozastaven! Obnovte prosím stav Podu. + Nelze ověřit, zda byl bolus úspěšný. Ověřte prosím, zda Váš Pod dodává bolus nebo ho zrušte. + Statistika RL + Pulse Log diff --git a/app/src/main/res/values-de-rDE/insight_exceptions.xml b/app/src/main/res/values-de-rDE/insight_exceptions.xml index 8f8f0015de..43eeeea573 100644 --- a/app/src/main/res/values-de-rDE/insight_exceptions.xml +++ b/app/src/main/res/values-de-rDE/insight_exceptions.xml @@ -2,7 +2,7 @@ Verbindung fehlgeschlagen Verbindung unterbrochen - Pairing abgelehnt + Kopplung abgelehnt Erstellen des Sockets fehlgeschlagen Zeitüberschreitung Maximale Anzahl an Boli dieses Typs bereits aktiv diff --git a/app/src/main/res/values-de-rDE/protection.xml b/app/src/main/res/values-de-rDE/protection.xml index 0c6f2dd337..83fce7bd9a 100644 --- a/app/src/main/res/values-de-rDE/protection.xml +++ b/app/src/main/res/values-de-rDE/protection.xml @@ -1,7 +1,7 @@ Authentifizierung erforderlich - Legen Deinen Finger auf den Fingerabdrucksensors, um Deine Identität zu bestätigen. + Lege Deinen Finger auf den Fingerabdrucksensor, um Deine Identität zu bestätigen. Schutz der Einstellungen Schutz der App Bolus-Schutz @@ -14,7 +14,7 @@ Benutzerdefiniertes Passwort Kein Schutz Schutz - Das Master-Passwort ist nicht festgelegt!\n\nLege Dein Master-Passwort bitte in en Einstellungen fest (%1$s → %2$s) + Das Master-Passwort ist nicht festgelegt!\n\nLege Dein Master-Passwort bitte in den Einstellungen fest (%1$s → %2$s) Passwort festgelegt! Passwort nicht festgelegt Passwort nicht geändert diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index f496669e05..4801ec3215 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -18,7 +18,7 @@ Einige Schaltflächen, um auf häufig verwendete Funktionen zugreifen zu können. Dient zum Konfigurieren der aktiven Plugins Das Programm kennenlernen - Zeigt die Essens-Vorlagen aus Nightscout an + Zeigt die Essensvorlagen aus Nightscout an Insulinprofil für Humalog und NovoRapid / NovoLog Insulinprofil für Fiasp Erlaubt dir, das Wirkmaximum der Insulinaktivität zu definieren, und sollte nur von erfahrenen Anwendern genutzt werden @@ -27,26 +27,26 @@ Stand des Algorithmus in 2016 Stand des Algorithmus in 2017 Der aktuellste Algorithmus für erfahrene Nutzer - Zeigt den aktuellen Status deines Loops und Knöpfe für die geläufigsten Aktionen an + Zeigt den aktuellen Status deines Loops und Schaltflächen für die geläufigsten Aktionen an Zeigt eine fortlaufende Benachrichtigung mit einer kurzen Übersicht darüber, was dein Loop derzeit tut Definiere ein Profil, was auch offline verfügbar ist. Stellt das Profil zur Verfügung, das in Nightscout definiert ist Definiere ein Profil mit nur einem Zeitblock. Pumpen-Integration für Accu-Chek Combo Pumpen; erfordert, dass ruffy installiert ist - Pumpen-Integration für Personen, die täglich mehrere Injektionen für ihre Diabetestherapie vornehmen - Pumpen-Integration für Pumpen, die noch nicht über einen Treiber verfügen (Open Loop) + Pumpenintegration für Personen, die täglich mehrere Injektionen für ihre Diabetestherapie vornehmen + Pumpenintegration für Pumpen, die noch nicht über einen Treiber verfügen (Open Loop) Die Sensitivität wird genauso wie bei Oref0 berechnet, aber Du kannst dafür ein Zeitfenster bestimmen. Die minimale Kohlenhydrat-Absorptionsrate wird aus der maximalen Absorptionsdauer aus den Einstellungen abgeleitet. Die Sensitivität wird aus den Daten der letzten 8 Stunden berechnet und Kohlenhydrate (falls nicht bereits absorbiert) werden nach der in den Einstellungen angegebenen Zeit als absorbiert betrachtet. Das Plugin bezieht Zeiträume, in denen UAM annimmt, dass Kohlenhydrate aktiv waren, nicht mit in die Berechnung ein. Die Sensitivität wird aus den Abweichungen errechnet. Dabei werden neuere Abweichungen stärker gewichtet als ältere. Die minimale Kohlenhydrat-Aufnahme wird aus der in den Präferenzen angegebenen maximalen Kohlenhydrat-Resorptionszeit abgeleitet. Dieser Algorithmus reagiert am schnellsten auf Änderungen der Empfindlichkeit. - Empfange BZ-Werte von der gepatchten Eversense App. - Empfange Blutzucker-Werte von Glimp. - Empfange Blutzucker-Werte vom 600SeriesAndroidUploader. - Lade Blutzucker-Daten von Nightscout - Empfange Blutzucker-Werte von xDrip. + Empfange BZ-Werte von der gepatchten Eversense-App. + Empfange Blutzuckerwerte von Glimp. + Empfange Blutzuckerwerte vom 600SeriesAndroidUploader. + Lade Blutzuckerdaten von Nightscout + Empfange Blutzuckerwerte von xDrip. Speichert alle eingegebenen Behandlungen Überwache und steuere AndroidAPS mit Deiner WearOS-Smartwatch. Zeige Loop-Informationen auf Deinem xDrip+-Watchface. - Steuere AndroiAPS fern mittels SMS-Anweisungen. + AndroidAPS mit SMS-Befehlen fernsteuern. Insulin: Kohlenhydrate: IOB: @@ -72,7 +72,7 @@ Aktuelle TBR IOB-Daten Profil - Mahlzeiten-Daten + Mahlzeitendaten Ergebnis Ergebnis: %1$s %2$s Keine BZ-Werte verfügbar @@ -94,7 +94,7 @@ Profil Welches Profil soll AndroidAPS nutzen? APS - Welcher APS-Algorithmus soll Therapie-Anpassungen vornehmen? + Welcher APS-Algorithmus soll Therapieanpassungen vornehmen? Allgemein Dies sind einige generelle Plugins, die Du vielleicht hilfreich findest. Welche Beschränkungen werden angewendet? @@ -117,7 +117,7 @@ Akzeptiere neue TBR: Bolus Rechner - Beschränkungen angewendet! + Beschränkung angewendet! Bestätigung Bolus Bolus: @@ -135,7 +135,7 @@ Deaktiviere Loop Aktiviere Loop Neue Empfehlung verfügbar - Nicht unterstütze Nightscout-Version + Nicht unterstützte Nightscout-Version LOOP DEAKTIVIERT DURCH BESCHRÄNKUNGEN Basal-IOB Bolus-Beschränkung angewendet @@ -151,10 +151,10 @@ Prozent Absolut Notiz - Ereignis-Zeit + Ereigniszeit Profil Eingegeben durch - Glukose-Art + Glukoseart Bisher noch kein Profil von Nightscout geladen TBR Verzögerter Bolus @@ -167,10 +167,10 @@ Datei nicht gefunden Einstellungen exportieren Einstellungen importieren - Max IE/h, die als TBR gesetzt werden können + Max. IE/h, die als TBR gesetzt werden können Dieser Wert wird \"max basal\" in OpenAPS genannt. Maximales Basal-IOB, das OpenAPS abgeben darf [IE] - Maximale Menge von nicht Bolus-IOB, die OpenAPs abgeben kann. + Maximale Menge von Nicht-Bolus-IOB, die OpenAPS abgeben kann. Du wirst nach dem Master-Passwort gefragt. Mit diesem werden die exportierten Einstellungen verschlüsselt. Du wirst nach dem Master-Passwort gefragt. Mit diesem werden die importierten Einstellungen entschlüsselt. Export abgebrochen! Einstellungen wurden NICHT exportiert! @@ -185,7 +185,7 @@ Trotzdem importieren (GEFÄHRLICH!) Einstellungen wurden mit einer anderen Variante von AAPS erstellt (%1$s). Du nutzt: %2$s.\n\nEinige Einstellungen können fehlen oder ungültig sein - überprüfe und aktualisiere Deine Einstellungen nach dem Import . Einstellungen wurden auf einem anderen Gerät erstellt. Das ist OK, wenn Du von einem älteren/anderen Handy importierst. Stelle aber sicher, dass die importierten Einstellungen korrekt sind! - Du verwendest das veraltete Format einer alten AAPS-Version das nicht sicher ist! Verwende dieses nur als letzte Möglichkeit, wenn Du keinen Export im aktuellen JSON-Format hast. + Du verwendest das veraltete Format einer alten AAPS-Version, das nicht sicher ist! Verwende dieses nur als letzte Möglichkeit, wenn Du keinen Export im aktuellen JSON-Format hast. Die importierten Einstellungen sind bereits %1$s Tage alt! Hast Du aktuellere Einstellungen oder evtl. die falsche Datei gewählt? Denke daran, die Einstellungen regelmäßig zu exportieren. Ungültiges Datums-/Zeitformat! Einstellungen stammen aus einer Vorgängerversion (Nebenversion). Du kannst diese importieren, prüfe aber unbedingt nach dem Import, ob diese noch korrekt sind! @@ -201,7 +201,7 @@ Neues verschlüsseltes Format Neues Debugformat (unverschlüsselt) Unbekanntes Export-Format - Einstellungen-Datei wurde manipuliert. + Konfigurationsdatei wurde manipuliert. Einstellungsdatei ist sicher. Nicht sicheres, unverschlüsseltes Einstellungsformat verwenden Fehler im JSON-Format, fehlendes erforderliches Feld (Format, Inhalt, Metadaten oder Sicherheit) @@ -218,23 +218,23 @@ vor weniger als einer Stunde exportiert in Verzeichnis: %1$s 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, ÜBERNEHMEN SIE ALLE NOTWENDIGEN KRANKHEITSKOSTEN, SERVICELEISTUNGEN, REPARATUREN ODER KORREKTUREN. + 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 +XXXXXXXXXX;+YYYYYYYYYY - Um einen Bolus von %1$.2f IE abzugeben, antworte mit dem Code %2$s. + Um einen Bolus von %1$.2f IE abzugeben, antworte mit dem Code %2$s. Um einen Mahlzeitenbolus von %1$.2f IE abzugeben, antworte mit dem Code %2$s. - Um ein Temp Target von %1$s zu setzen, antworte mit dem Code %2$s + Um ein temporäres Ziel von %1$s zu setzen, antworte mit dem Code %2$s Um das temporäre Ziel zu stoppen, antworte mit dem Code %1$s - Um den SMS Remote Service zu deaktivieren, antworte mit dem Code %1$s.\n\nBeachte, dass Du diesen nur am AAPS Master Smartphone wieder aktivieren kannst. - SMS Remote Service gestoppt. Verwende das AAPS Master, um ihn wieder zu aktivieren. + Um die SMS-Fernsteuerung zu deaktivieren, antworte mit dem Code %1$s\n\nBeachte, dass Du diesen nur am AAPS-Master-Smartphone wieder aktivieren kannst. + SMS-Fernsteuerung gestoppt. Verwende das AAPS-Master-Smartphone, um sie wieder zu aktivieren. Um die Kalibrierung %1$.2f zu senden, antworte mit dem Code %2$s. Bolus fehlgeschlagen - Minimale Dauer in Minuten, die nach einem Remote Bolus verstrichen sein muss, bevor ein neuer abgegeben werden kann. - Anzahl Minuten, die mindestens zwischen zwei Bolusgaben liegen müssen. + Minimale Dauer in Minuten, die nach einem Remote-Bolus verstrichen sein muss, bevor ein neuer abgegeben werden kann. + Anzahl der Minuten, die mindestens zwischen zwei Remote-Bolusabgaben liegen müssen. Aus Sicherheitsgründen musst Du mindestens zwei Telefonnummern eintragen, um diese Voreinstellung zu ändern. Bolus %1$.2fIE erfolgreich abgegeben Werde %1$.2fIE abgeben @@ -243,7 +243,7 @@ Ziel %1$s für %2$d Minuten Ziel %1$s für %2$d Minuten erfolgreich gesetzt. Temporäres Ziel wurde erfolgreich abgebrochen - Erlaube externe Befehle per SMS + Erlaube Fernsteuerung per SMS DanaR Profil-Einstellungen DIA [h] Dauer der Insulinwirkung @@ -251,7 +251,7 @@ Bolus gestoppt Bolus wird gestoppt Loop wurde deaktiviert. - Loop wurde aktiviert + Lopp wurde aktiviert. Loop ist deaktiviert. Loop ist aktiviert. %1$.2f limitiert auf %2$.2f @@ -264,19 +264,22 @@ Um %1$dg Kohlenhydrate um %2$s einzugeben, antworte mit dem Code %3$s Um die Basalrate von %1$d%% für %2$d Minuten zu setzen, antworte mit dem Code %3$s Um das Loopen für %1$d Minuten zu pausieren, antworte mit dem Code %2$s. + Um den Loop fortzusetzen, antworte mit dem Code %1$s + Um den Loop zu aktivieren, antworte mit dem Code %1$s + Um den Loop zu deaktivieren, antworte mit dem Code %1$s TBR mit %1$.2f IE/h für %2$d min wurde erfolgreich gestartet. Der erweiterte Bolus %1$.2f IE/h für %2$d Minuten wurde erfolgreich gestartet - %1$dg Kohlenhydrate erfolgreich erfasst + %1$dg Kohlenhydrate erfolgreich erfasst. Eingabe von %1$dg Kohlenhydraten ist fehlgeschlagen. - Die temporäre Basalrate wurde erfolgreich für %2$d Minuten auf %1$d%% gesetzt + Die temporäre Basalrate wurde erfolgreich für %2$d Minuten auf %1$d%% gesetzt. Das Starten der TBR ist fehlgeschlagen. - Die Abgabe des erweiterten Bolus ist fehlgeschlagen - Antworte mit dem Code %1$s, um die temporäre Basalrate zu beenden - Antworte mit dem Code %1$s, um den erweiterten Bolus zu beenden + Die Abgabe des erweiterten Bolus ist fehlgeschlagen. + Antworte mit dem Code %1$s, um die temporäre Basalrate zu beenden. + Antworte mit dem Code %1$s, um den erweiterten Bolus zu beenden. TBR abgebrochen - Die Abgabe des erweiterten Bolus wurde abgebrochen + Die Abgabe des erweiterten Bolus wurde abgebrochen. Das Abbrechen der TBR ist fehlgeschlagen. - Der Abbruch des erweiterten Bolus ist fehlgeschlagen + Der Abbruch des erweiterten Bolus ist fehlgeschlagen. Unbekannter Befehl oder falsche Antwort QuickWizard QuickWizard-Einstellungen @@ -326,7 +329,7 @@ Array mit %1$d Elementen.\nWert: Autosens-Daten Skript Debug - Nutze Autosense + Nutze Autosens Aktualisiere Einträge von Nightscout Lösche Behandlungen in der Zukunft Bald essen @@ -352,7 +355,7 @@ Profil Standardwert: 3\nDies ist eine wichtige Sicherheitseinstellung. Sie begrenzt das maximale Basal-IOB auf die dreifache Menge (im Standardfall) deiner größten Basalrate. In der Regel solltest Du diesen Wert nicht ändern. Aber Du solltest wissen, was \"3x max daily, 4x current\" als Sicherheitseinstellung bedeutet. Standardwert: 4\nDies ist die andere wichtige Sicherheitseinstellung, die zweite Hälfte von \"3x max daily, 4x current\". Diese Grenze beschränkt das Basal-IOB auf die (im Standardfall) vierfache Menge der aktuellen Basalrate. Dies ist wichtig, um Nutzer davor zu bewahren, zuviel Basal-Insulin zu verabreichen. Nochmals, der Standardwert ist 4x. Die meisten Nutzer werden niemals diese Einstellung verändern, sondern andere Einstellungen anpassen, um sich nicht dieser Sicherheitsgrenze zu nähern. - Standardwert: 1.2\nDies ist eine Sicherheitsgrenze für Autosens (und bald auch Autotune), die besagt, wie hoch Autosens Basalraten anpassen darf und wie niedrig der ISF (Insulin-Sensitivitäts-Faktor) und der BZ-Zielwert eingestellt werden können. 1.2 ist dabei der Multiplikationsfaktor und erlaubt eine Anpassung um 20%%. + Standardwert: 1.2\nDies ist eine Sicherheitsgrenze für Autosens (und bald auch Autotune), die besagt, wie stark Autosens Basalraten erhöhen darf und wie niedrig der ISF (Insulin-Sensitivitäts-Faktor) und der BZ-Zielwert eingestellt werden können. 1.2 ist dabei der Multiplikationsfaktor und erlaubt eine Anpassung um 20%%. Standardwert: 0.7\nDies ist die andere Sicherheitsgrenze für autosens. Sie beschränkt, wie weit Basalraten abgesenkt und wie sehr ISF und BZ-Zielwerte erhöht werden können. Autosens passt Zielwerte ebenfalls an Vorgabe: erlaubt.\nErlaubt Autosens den Ziel-BZ-Bereich in Verbindung mit ISF und Basal anzupassen. @@ -401,7 +404,7 @@ Insulinresistenter Erwachsener Bitte wähle das Patientenalter, um die Sicherheits-Limits festzulegen Name des Patienten - Gib den Namen des Patienten oder einen Spitznamen für die Unterscheidung zwischen mehreren Setups an. + Bitte gib den Namen des Patienten oder einen Spitznamen an, um mehrere Setups unterscheiden zu können. Nutzer Glimp %1$s benötigt eine deaktivierte Akku-Leistungsoptimierung, um korrekt arbeiten zu können. @@ -449,8 +452,14 @@ Warnschwelle kritischer Reservoirstand [IE] Warnschwelle Batteriestand [%] Warnschwelle kritischer Batteriestand [%] + PRED IOB COB + BAS + DEV + ACT + ABS + DEVSLOPE Über SMS-Steuerung nicht erlaubt Fehlende Berechtigung für den Zugriff auf den Telefonstatus @@ -468,12 +477,8 @@ Profilwechsel durchführen Batteriealter Alarm-Optionen - Sehr hoch - Hoch - Niedrig - Sehr niedrig - Veraltete Daten - Stark veraltete Daten + Benachrichtigungen über NS-Alarme + Benachrichtigungen über NS-Ankündigungen Veraltete Daten seit [min] Stark veraltete Daten seit [min] Intervall für Autosens [h] @@ -506,7 +511,7 @@ Abbrechen Es sind nicht alle Profile geladen! Werte nicht gespeichert! - Aktiviere die Datenübertragung zu anderen Apps (z.B. xDrip). Nicht aktivieren falls Du mehr als eine Instanz von AAPS oder NSClient installiert hast! + Aktiviere die Datenübertragung zu anderen Apps (z.B. xDrip). Nicht aktivieren, falls Du mehr als eine Instanz von AAPS oder NSClient installiert hast! Aktiviere lokale Broadcasts AKTIVITÄT & FEEDBACK CARBS & BOLUS @@ -561,10 +566,10 @@ BZ Upload Einstellungen Zeige detailliertes Delta Delta wird mit Dezimalstelle angezeigt. - Wie häufig SMBs angegeben werden (in Min.) + Wie häufig SMBs abgegeben werden (in Min.) SMB max. Minuten SMB Basal-Limit in Minuten - UAM SMB max minutes + UAM SMB max. Minuten SMB Basal-Limit in Minuten für UAM Schwellenwert für KH-Empfehlung Sende BZ-Werte zu xDrip+ @@ -625,6 +630,8 @@ Fehler bei der Abgabe eines verzögerten Bolus Sight her + Neutrale TBR setzen + Wenn diese Option aktiviert ist, wird die TBR vor Ende jeder Stunde abgebrochen. Dies kann dazu beitragen, einige Pumpen davon abzuhalten, zur vollen Stunde zu vibrieren / zu piepsen. SMB immer aktivieren Aktiviere SMB immer, unabhängig von Boli. Dies ist nur möglich, wenn eine BZ-Quelle genutzt wird, die die Daten besonders gut filtert wie z. B. G5. Aktiviere SMB nach Mahlzeiten. @@ -832,9 +839,9 @@ Unerwartetes Verhalten. Minimaler Wert zur Anfrage einer Änderung [%] Open Loop schlägt neue Änderungen nur dann vor, wenn die Änderung größer als dieser Wert ist. Der Standard-Wert ist 20%. Geräte werden gesucht… - Pairing abgeschlossen + Kopplung abgeschlossen Stimmen die Codes auf diesem Gerät und auf deiner Pumpe überein? - Insight Pairing + Insight Kopplung Accu-Chek Insight %1$.2f U / %2$.2f U abgegeben %1$s: %2$s @@ -851,6 +858,10 @@ Unerwartetes Verhalten. Alarme protokollieren TBR-Emulation aktivieren Verzögerte Boli an Stelle von TBRs verwenden, um die Beschränkung auf 250%% zu umgehen + Vibrationen bei manueller Bolus-Abgabe deaktivieren + Für Boli und verlängerte Boli (nur mit Insight Firmware 3.x verfügbar) + Vibrationen bei automatischer Bolus-Abgabe deaktivieren + Für SMB und Temporäre Basalraten mit TBR Emulation (nur mit Insight Firmware 3.x verfügbar) Verbindungsabbau-Verzögerung [s] Seriennummer Release-Softwareversion @@ -862,8 +873,8 @@ Unerwartetes Verhalten. Bluetooth-Adresse System-ID-Appendix Herstellungsdatum - Pairing löschen - Pairinginformationen + Kopplung aufheben + Kopplungsinformation Pumpe starten Pumpe stoppen Betriebsmodus @@ -1275,8 +1286,9 @@ Unerwartetes Verhalten. Statusanzeige Einstellung aus NS kopieren NS-Einstellungen kopieren (falls vorhanden)? - Ursprüngliches Erscheinungsbild - Schaltflächen werden immer am unteren Rand des Bildschirms angezeigt + Ursprüngliches Erscheinungsbild + Schaltflächen werden immer am unteren Rand des Bildschirms angezeigt + Großer Bildschirm Erscheinungsbild diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index b40f6e7b2e..f5184d6876 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -386,12 +386,6 @@ Χρόνος ζωής Ινσουλίνης Χρόνος ζωής μπαταρίας αντλίας Επιλογές συναγερμού - Επείγον υψηλό - Υψηλό - Χαμηλό - Επείγον χαμηλό - Παλιά δεδομένα - Επείγον παλιά δεδομένα Οριακή τιμή για παλιά δεδομένα [min] Επείγουσα οριακή τιμή για παλιά δεδομένα [min] Εσωτερικά διαστήματα για autosense [h] diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 2193c826d8..7afa8894ec 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -441,12 +441,6 @@ Cambio de perfil Edad batería bomba Opciones alarma - Urgente alto - Alto - Bajo - Urgente bajo - Datos anticuados - Datos antiguos urgentes Datos antiguos limite [min] Datos antiguos urgentes limite [min] Intervalo para autosens [h] diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index f9e0d10cc5..ecb04b75ca 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -469,12 +469,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Changer de profil Age batterie pompe Options d\'alarme - Haute urgent - Haute - Basse - Basse urgent - Données obsolètes - Urgent données obsolètes Seuil sans nouvelle donnée Glyc. [min] Seuil d\'urgence pour les données obsolètes [min] Plage pour Autosens [h] @@ -567,7 +561,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Max. minutes de basal pour limiter le SMB SMB RNS minutes max Minutes de basal max pour limiter les SMB des RNS - Seuil de suggestionde glucides + Seuil de suggestion de glucides Quantité de glucides à partir de laquelle une notification est envoyée Transmettre les Gly vers xDrip+ Dans xDrip+ veuillez séléctionner 640g/Eversense comme source de données @@ -852,6 +846,10 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Enreg. alertes Activer l’émulation de DBT Utilisez des Bolus étendus au lieu de DBTs pour contourner la limite de 250%% + Désactiver les vibrations des bolus manuels + Concerne les bolus et bolus étendus (disponible uniquement pour les firmwares 3.x) + Désactiver les vibrations des bolus automatiques + Concerne les SMB et les basal temp avec émulation DBT (disponible uniquement pour les firmwares 3.x) Délai de déconnexion [s] Numéro de série Version du logiciel @@ -1276,8 +1274,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Voyants d\'état Copier les paramètres depuis NS Copier les paramètres NS (s\'ils existent)? - Thème d\'origine - Les boutons sont toujours affichés en bas de l\'écran Thème @@ -1376,7 +1372,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Intégration de la pompe Omnipod Dash. Rappel fin d\'appairage Rappel fin de configuration - Le Pod expire bientôt Le Pod expire bientôt Arrêt imminent Réservoir bas diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index d1ef20a32e..b0b5939317 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -264,6 +264,9 @@ Per inserire %1$dg a %2$s rispondi col codice %3$s Per avviare la basale %1$d%% per %2$d min rispondi col codice %3$s Per sospendere il loop per %1$d minuti rispondi col codice %2$s + Per riprendere il loop rispondi col codice %1$s + Per abilitare il loop rispondi col codice %1$s + Per disabilitare il loop rispondi col codice %1$s Basale temporanea %1$.2fU/h per %2$d min avviata con successo Bolo esteso %1$.2fU/h per %2$d min avviato con successo CHO %1$dg inseriti con successo @@ -449,8 +452,14 @@ Soglia livello serbatoio critico [U] Soglia di avviso livello batteria [%] Soglia livello batteria critico [%] + PRED IOB COB + BAS + DEV + ATT + ASS + PENDEV Informazioni su Autorizzazione SMS mancante Autorizzazione stato telefono mancante @@ -468,12 +477,8 @@ Cambia profilo Età batteria micro Opzioni allarme - Molto alto - Alto - Basso - Molto basso - Dati non aggiornati - Dati non aggiornati da molto tempo + Crea notifiche da allarmi NS + Crea notifiche da avvisi NS Soglia dati non aggiornati [min] Soglia dati non aggiornati da molto tempo [min] Intervallo per autosens [h] @@ -626,6 +631,8 @@ Errore erogazione bolo esteso Sight fa + Imposta basali temporanee neutre + Se abilitato, cancellerà una basale temporanea prima della fine di ogni ora. Questo metodo può aiutare a fermare alcuni micro dall\'emettere un suono/vibrare allo scoccare dell\'ora. Abilita SMB sempre Abilita SMB sempre, indipendentemente dai boli. Possibile solo con sorgente glicemia con un buon filtraggio dei dati, come G5 Abilita SMB dopo i CHO @@ -851,6 +858,10 @@ Registra avvisi Abilita emulazione TBR Usa i bolli estesi invece dei TBR per aggirare il limite del 250%% + Erogazione bolo manuale: disabilita vibrazioni + Per bolo e bolo esteso (disponibile solo con firmware Insight 3.x) + Erogazione bolo automatica: disabilita vibrazioni + Per SMB e basale temporanea con emulazione TBR (disponibile solo con firmware Insight 3.x) Ritardo disconnessione [s] Numero seriale Versione Release software @@ -1275,8 +1286,9 @@ Indicatori di stato Copia impostazioni da NS Copiare impostazioni NS (se esiste)? - Tema originale - I tasti vengono sempre visualizzati nella parte inferiore dello schermo + Tema originale + I tasti vengono sempre visualizzati nella parte inferiore dello schermo + Visualizzazione ampia Tema diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 0c04ecd8ab..f89d6cb1ab 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -408,12 +408,6 @@ 프로파일 변경 실행 펌프배터리사용기간 알람 옵션 - 위험 고혈당 - 고혈당 - 저혈당 - 위험 저혈당 - 누락 데이터 - 위험 누락 데이터 누락 데이터 기준값 [min] 위험 누락 데이터 기준값 [min] autosens 시간 [h] diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 6445d65195..2be090e0be 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -450,12 +450,6 @@ Profilio keitimas Baterija Aliarmų nustatymai - Kritiškai aukštas - Aukštas - Žemas - Kritiškai žemas - Seni duomenys - Kritiškai seni duomenys Seni duomenys, riba [min] Kritiškai seni duomenys, riba [min] Autosens intervalas [h] diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index 3c4f8dbd28..0ba8a69c9d 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -408,12 +408,6 @@ Profiel wissel uitvoeren Ouderdom batterij Alarm opties - Zeer hoog - Hoog - Laag - Zeer laag - Oude gegevens - Dringend oude gegevens vernieuwen Oude gegevens sinds [min] Alarm oude gegevens sinds [min] Interval voor autosens [uur] @@ -895,6 +889,7 @@ Herhaal tijd Elke Nooit + %1$dmin Voorwaarde: Actie: IOB [E]: diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 14f82463e8..e9f466ba22 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -459,12 +459,6 @@ Zmień profil Czas baterii pompy Opcje alarmu - Uwaga wysoki - Wysoki - Niski - Uwaga niski - Nieaktualne dane - Uwaga, nieaktualne dane Próg nieaktualne dane [min] Próg uwaga nieaktualne dane [min] Przedział czasowy dla autosens [h] diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 59ef0d4a69..6ba8a86ce2 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -171,8 +171,8 @@ Este valor é chamado max basal no contexto do OpenAPS Basal Máxima IOB que OpenAPS pode dar [U] Este valor é denominado Max IOB em contexto OpenAPS \nEste é o valor máximo de insulina em [U] que APS pode dar de uma vez. - Será perguntado pela password mestre, que será usada para encriptar preferências exportadas. - Será perguntado pela password mestre, que será necessária para desencriptar preferências importadas. + Será perguntado pela senha mestre, que será usada para encriptar preferências exportadas. + Será perguntado pela senha mestre, que será necessária para desencriptar preferências importadas. Exportação cancelada! Preferências NÃO foram exportadas! Importação cancelada! Preferências NÃO foram importadas! Seleccione o ficheiro para importação @@ -205,11 +205,11 @@ Ficheiro de configurações é seguro A usar um formato de configurações não seguro e não encriptado Erro de formato JSON, campo necessário ausente (formato, conteúdo, metadados ou segurança) - Erro ao desencriptar, a password inserida não pode desencriptar o ficheiro + Erro ao desencriptar, a senha inserida não pode desencriptar o ficheiro Ficheiro de verificação (hash) em falta, não é possível verificar a autenticidade de configurações! Ficheiro foi modificado após exportação! Erro Desencriptação, a análise de preferências falhou! - Erro de Desencriptação, a password é inválida ou configurações de arquivo foram modificadas! Pode acontecer que o ficheiro importado foi exportado com uma Password Mestre diferente. + Erro de Desencriptação, a senha é inválida ou configurações de arquivo foram modificadas! Pode acontecer que o ficheiro importado foi exportado com uma Senha Mestre diferente. Configuração de encriptação ausente, formato de configurações é inválido! Algoritmo de encriptação não suportado ou não especificado! exportado hoje @@ -226,7 +226,7 @@ Números de telefone permitidos +XXXXXXXXXX;+YYYYYYYYYY Para dar bolus %1$.2fU responder com código %2$s - Para dar bólus %1$.2fU responder com código %2$s + Para administrar bólus %1$.2fU responder com código %2$s Para definir o Alvo Tempo %1$s responda com o código %2$s Para cancelar Alvo Temp responda com o código %1$s Para desactivar o Serviço Remoto SMS de responda com o código %1$s.\n\nTenha em mente que será capaz de o reactivar directamente apenas a partir do telemóvel mestre do AAPS. @@ -239,7 +239,7 @@ Bolus %1$.2fU entregue com sucesso Vão ser administradas %1$.2fU Bólus %1$.2fU enviado com êxito - Bólus de refeição %1$.2fU entregue com sucesso + Bólus de refeição %1$.2fU administrado com sucesso Alvo %1$s para %2$d minutos Alvo %1$s para %2$d minutos definido com sucesso Alvo Temp cancelado com êxito @@ -264,6 +264,9 @@ Para inserir %1$dg em %2$s responda com código %3$s Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s Para suspender o loop por %1$d minutos resposta com código %2$s + Para retomar o loop responda com o código %1$s + Para activar o loop responda com o código %1$s + Para desactivar o loop responda com o código %1$s Basal temporária %1$.2fU/h para %2$d min iniciada com êxito Bólus estendido %1$.2fU/h para %2$d min iniciado com êxito Hidratos %1$dg inseridos com sucesso @@ -449,8 +452,14 @@ Limite crítico de nível de reservatório [U] Limite de aviso de nível de bateria [%] Limite de crítico de nível de bateria [%] + PREV IOB COB + BAS + DESV + ACT + ABS + DESVINCLI Sobre Falta de permissão SMS Falta permissão do estado do telefone @@ -468,12 +477,8 @@ Fazer Mudança De Perfil Idade bateria bomba Opções Alarme - Urgência hiperglicemia - Alta - Baixa - Urgência hipoglicemia - Dados Obsoletos - Dados obsoletos urgentes + Criar notificações dos alarmes NS + Criar notificações a partir dos anúncios NS Tempo limite para dados obsoletos [min] Tempo limite para Urgência por dados obsoletos [min] Intervalo para autosens [h] @@ -626,6 +631,8 @@ Erro na entrega Bólus Estendido Visão atrás + Definir basais temporárias neutras + Se activado, ele irá cancelar basal temporária antes do final de cada hora. Este método pode ajudar a parar o sinal sonoro/vibração em algumas bombas, de hora em hora. SMB sempre activado SMB sempre activo independentemente dos bolus. Possível apenas quando o medidor tive um bom filtro de dados como o G5 Ativar SMB após carbos @@ -851,6 +858,10 @@ Alertas de registo Ativar a emulação TBR Usar bólus prolongados em vez de basais temporárias para contornar o limite de 250%% + Desactivar vibrações na entrega manual de bólus + Para bólus e bólus estendidos (só disponível com o firmware Insight 3.x) + Desactivar vibrações na entrega automática de bólus + Para SMB e Basal Temp com emulação DBT (só disponível com firmware Insight 3.x) Atraso de desconexão [s] Número de série Lançar versão de software @@ -1247,9 +1258,9 @@ a partir da app Autenticador para: %1$s Activar Autenticador - Autenticar comandos usando Uma-Password-Única que sejam geradas pelo Google Authenticator ou app 2FA similar. + Autenticar comandos usando Uma-Senha-Única que sejam geradas pelo Google Authenticator ou app 2FA similar. PIN adicional no token final - Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Password-Única que seja gerada + Dígitos adicionais que devem ser memorizados e colados no final de cada Uma-Senha-Única que seja gerada Configuração do Autenticador OTP para verificar: Repor Autenticadores @@ -1258,7 +1269,7 @@ Nova Chave do Autenticador foi gerada! Por favor, use o QRCode actualizado para os autenticadores. 1. Instalar Autenticador 2. Pesquise o código para configurar os códigos OTP do AndroidAPS - 3. Teste Uma-Password-Única + 3. Testar Uma-Senha-Única Repor Autenticadores Instalar uma app Autenticador que suporte Tokens RFC 6238 TOTP em cada telefone seguidor. Populares aplicativos gratuitos são:\n • Authy\n • o Google Authenticator\n • LastPass Autenticador\n • FreeOTP Autenticador NÃO PARTILHE este código online!\nUse-o apenas para a instalação da app Autenticador nos telefones seguidores. @@ -1269,22 +1280,22 @@ Desvio de inclinação Falha na autorização Insulina absoluta - Password Mestre é usada para encriptação da cópia de segurança e substituir segurança na aplicação. Lembre-se dela ou guarde-a em um lugar seguro. - As passwords não coincidem - Password Mestre actual + Senha Mestre é usada para encriptação da cópia de segurança e substituir segurança na aplicação. Lembre-se dela ou guarde-a em um lugar seguro. + As senhas não coincidem + Senha Mestre actual Luzes de Estado Copiar definições do NS Copiar definições do NS (se existir)? - Tema gráfico original - Os botões são sempre exibidos na parte inferior do ecrã Tema gráfico + Integração de bomba para Omnipod, requer RileyLink (com pelo menos firmware 2.0) dispositivo. - Beep Bólus Activado - Beep Basal Activado - Beep SMB Activado - Beep DBT Activado + Sinal Bólus Activado + Sinal Basal Activado + Sinal SMB Activado + Sinal DBT Activado + Opções de Depuração do Pod habilitadas Detecção de DST/Fuso Horário Activado Gestão Pod @@ -1301,8 +1312,27 @@ Omnipod (433.91 MHz) + A operação não é possível.\n\nPrecisa configurar o Omnipod primeiro, antes de pode usar esta operação. + A operação não é possível.\n\n Precisa de esperar alguns minutos, até que AAPS tente definir o perfil para a primeira vez. + PodInitActionType Ilegal: %1$s Nenhum Pod Activo. A verificação do comando falhou. + Ocorreu um erro inesperado. Por favor reporte! (digite: %1$s). + Falha na comunicação: foram recebidos parâmetros de entrada inválidos. + Falha na comunicação: tempo limite. + Falha na comunicação: ocorreu um erro inesperado. Por favor, reporte! + Falha na comunicação: mensagem de falha de verificação de integridade. + Falha na comunicação: recebeu um pacote inválido do Pod. + Falha na comunicação: o Pod está em um estado errado. + Falha na comunicação: recebeu uma resposta inválida do Pod. + Falha na comunicação: recebeu uma mensagem com número de sequência inválido do Pod. + Falha na comunicação: recebeu uma mensagem com um endereço inválido do Pod. + Falha na comunicação: falha ao descodificar a mensagem do Pod. + Falha na comunicação: nonce resync falhou. + Falha na comunicação: nonce fora de sincronização. + Falha na comunicação: não há dados suficientes recebidos do Pod. + Uma falha de Pod (%1$03d %2$s) foi detectada. Por favor, desactive o Pod e inicie um novo. + Falha na comunicação: o Pod devolveu uma resposta de erro. Gestão Pod Iniciar Pod @@ -1326,19 +1356,29 @@ %1$.1f U %1$.1f U, HC=%2$.1f g Taxa: %1$.1f U, Duração: %2$d min + Se pressionar OK, o estado do Pod vai ser forçado a redefinir e você não será capaz de comunicar mais com o Pod. Faça isso somente se você não pode comunicar mais com o Pod. Se ainda pode comunicar com o Pod, por favor, use o Desactivar Pod opção. + Histórico do Pod não disponível no momento. Encher o Pod + \nPreencher o novo Pod com insulina suficiente para 3 dias.\n\nOuvir dois sinais sonoros a partir do Pod durante o processo de enchimento. Isso indica que a quantidade mínima de 85U foi inserida. Certifique-se de esvaziar completamente a seringa, mesmo depois de ouvir dois sinais sonoros.\n\nDepois de preencher o Pod, por favor, pressione Próximo.\n\nNota: não remova a tampa da agulha do Pod neste momento. A Purgar + A tentar emparelhar com o novo Pod e purgá-lo.\n\nQuando todos os itens forem verificados, pode pressionar Próximo.\n\nNota: por favor, mantenha o Pod muito perto do RileyLink neste momento. Anexar o Pod + \nPrepare o local de infusão. Remova a tampa da agulha do Pod e o adesivo e fixe o Pod no local de infusão.\n\nSe a canula sair, por favor, pressione Cancelar e descarte o seu Pod.\n\nPressione Próximo para inserir a canula e começar a administração da basal. A inserir canula + A tentar definir um plano da basal inicial e inserir canula.\n\nQuando todos os itens estiverem verificados, pode pressionar Próximo. Info Pod + \nO Pod está agora activo.\n\nO seu plano de basal foi programado e a canula foi inserida.\n\nPor favor, verifique se a canula foi inserida correctamente e substitua o seu Pod se você se sente que não. Desactivar Pod + \nPressione Próximo para desactivar o Pod.\n\nNota: Isto irá suspender toda a administração de insulina e desactivar o Pod. A Desactivar Pod + A desactivar o Pod.\n\nQuando todos os itens forem verificados, pode pressionar Próximo.\n\nNota: Se desactivar falhar continuamente, por favor, pressione Cancelar e use o Repor Pod opção para forçar a repor o estado do Pod. + Pod desactivado.\n\nPor favor, remova o Pod do seu corpo e descarte-o. Emparelhar Pod Purgar Pod Enchimento de Canula Definir Perfil Basal Cancelar Administração - Desacitvar Pod + Desactivar Pod Integração da Bomba para Omnipod Dash. @@ -1349,6 +1389,10 @@ Encerramento iminente Reservatório baixo Alerta desconhecido + Pode ter falhado ao definir perfil da basal. A administração pode estar suspensa! Por favor, actualize o estado do Pod. + Pode ter falhado ao definir basal temporária. Se houve uma basal temporária já em execução, pode ter sido cancelada! Por favor, actualize o estado do Pod. + Pode ter falhado ao definir a hora. A administração pode estar suspensa! Por favor, actualize o estado do Pod. + Não é possível verificar se o bólus foi bem-sucedido. Por favor, verifique se o Pod está administrar ou cancelar o bólus. Estatísticas RL Registo de Pulse diff --git a/app/src/main/res/values-pt-rPT/exam.xml b/app/src/main/res/values-pt-rPT/exam.xml index cf9f53bcf4..737c4c23a9 100644 --- a/app/src/main/res/values-pt-rPT/exam.xml +++ b/app/src/main/res/values-pt-rPT/exam.xml @@ -115,7 +115,7 @@ https://androidaps.readthedocs.io/en/latest/EN/Usage/Extended-Carbs.html Tópico: Monitorização Remota Como pode monitorizar AAPS do seu filho remotamente? - A usar um site Nightscout. + Usando um site Nightscout. App Dex om Follow se estiver a usar a app original Dexcom (Glic apenas). Dexcom Follow se estiver a usar a app xDrip. xDrip a correr no modo seguidor. diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 1b8cc9057a..9705931fa8 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -143,7 +143,7 @@ Outro Medidor Sensor - Hidratos de Carbono + Hidratos Insulina Tempo Hidratos Dividir @@ -264,6 +264,9 @@ Para inserir %1$dg em %2$s responda com código %3$s Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s Para suspender o loop por %1$d minutos resposta com código %2$s + Para retomar o loop responda com o código %1$s + Para activar o loop responda com o código %1$s + Para desactivar o loop responda com o código %1$s Basal temporária %1$.2fU/h para %2$d min iniciada com êxito Bólus prolongado %1$.2fU/h para %2$d min iniciado com êxito Hidratos %1$dg inseridos com sucesso @@ -370,12 +373,12 @@ A Executar Definições da bomba virtual Enviar estado para NS - NSCliente - NSCI + ClienteNS + CLNS URL: Rolar automático Reiniciar - NSCliente + ClienteNS Nightscout URL Introduza o Nightscout URL NS API secret @@ -388,7 +391,7 @@ Estado: Em pausa Limpar Registo - NSCliente sem permissões para alterar dados. Tem a senha API correta? + ClienteNS sem permissões para alterar dados. Tem a senha API correta? Definições Wear Mostrar IOB detalhada Dividir IOB entre IOB de bolus e de basal na face do relógio @@ -449,8 +452,14 @@ Limite crítico de nível de reservatório [U] Limite de aviso de nível de bateria [%] Limite de crítico de nível de bateria [%] + PREV IOB COB + BAS + DESV + ACT + ABS + DESVINCLI Acerca Falta de permissão SMS Falta permissão do estado do telefone @@ -468,12 +477,8 @@ Fazer Mudança De Perfil Idade bateria bomba Opções Alarme - Urgência hiperglicemia - Alto - Baixo - Urgência hipoglicemia - Dados Obsoletos - Dados obsoletos urgentes + Criar notificações dos alarmes NS + Criar notificações a partir dos anúncios NS Tempo limite para dados obsoletos [min] Tempo limite para Urgência por dados obsoletos [min] Intervalo para autosens [h] @@ -506,7 +511,7 @@ Cancelar Nem todos perfis foram carregados! Valores não guardados! - Activar transmissões para outras aplicações (como xDrip). Não habilite se tiver mais de uma instância de AAPS ou NSClient instalado! + Activar transmissões para outras aplicações (como xDrip). Não habilite se tiver mais de uma instância de AAPS ou ClienteNS instalado! Activar partilha local. ACTIVIDADE & FEEDBACK HIDRATOS & BÓLUS @@ -570,7 +575,7 @@ Quando Hidratos são sugeridos, quantos hidratos irá solicitar uma notificação Enviar dados Glic. para xDrip+ Seleccionar 640g/Eversense como fonte no xDrip+ - Glic NSCliente + Glic ClienteNS Cálculos Glic Cálculo de Bólus IOB Cálculo de Basal IOB @@ -584,7 +589,7 @@ Cálculo alvo temporário Loop activado APS seleccionado - NSCLiente tem permissão de escrita + ClienteNS tem permissão de escrita Modo fechado ativado IOB máxima definida correctamente Glicemia disponivel desde a fonte selecionada @@ -626,6 +631,8 @@ Erro na administração Bólus Prolongado Visão atrás + Definir basais temporárias neutras + Se activado, ele irá cancelar basal temporária antes do final de cada hora. Este método pode ajudar a parar o sinal sonoro/vibração em algumas bombas, de hora em hora. SMB sempre activado SMB sempre activo independentemente dos bolus. Possível apenas quando o medidor tive um bom filtro de dados como o G5 Activar SMB após hidratos @@ -759,7 +766,7 @@ Resultado cálculos incluídos no Assistente: Configurações Ecrã Configurações Gerais - Activar NSCliente + Activar ClienteNS Bem-vindo ao assistente de configuração. Vai guiá-lo(a) através do processo de instalação\n Configurações da bomba Ler estado @@ -770,7 +777,7 @@ Configurar plugin Sensibilidade Plugin de Sensibilidade é usado para detecção de sensibilidade e cálculos COB. Para mais info visite: https://github.com/MilosKozak/AndroidAPS/wiki/Sensitivity-detection-and-COB - NSCliente gere a ligação ao Nightscout. Pode saltar esta parte mas não será possível passar os objectivos até que o configure. + ClienteNS gere a ligação ao Nightscout. Pode saltar esta parte mas não será possível passar os objectivos até que o configure. Lembre-se: novos perfis de insulina requerem diâmetro de pelo menos 5h. DIA 5–6h no novo perfil é igual ao diâmetro 3h nos antigos perfis de insulina. Configure a fonte das glicemias Por favor seleccione a fonte do perfil. Se o paciente é uma criança deverá utilizar perfil NS. Se ninguém o está a seguir no Nightscout provavelmente preferirá um perfil Local. Lembre-se que apenas está a escolher a fonte de perfil. Para o utilizar terá que o activar executando \"Troca Perfil\" @@ -821,7 +828,7 @@ Sem dados Autosens disponíveis Definições de registo Repor definições por defeito - Erro de funcionamento do NSCliente. Pondere reiniciar o NS e NSCliente. + Erro de funcionamento do ClienteNS. Pondere reiniciar o NS e ClienteNS. AS Disponível %1$s disponível Fuso horário @@ -851,6 +858,10 @@ Alertas de registo Activar a emulação DBT Usar bólus prolongados em vez de basais temporárias para contornar o limite de 250%% + Desactivar vibrações na entrega manual de bólus + Para bólus e bólus estendidos (só disponível com o firmware Insight 3.x) + Desactivar vibrações na entrega automática de bólus + Para SMB e Basal Temp com emulação DBT (só disponível com firmware Insight 3.x) Atraso de desconexão [s] Número de série Lançar versão de software @@ -1275,8 +1286,9 @@ Luzes de Estado Copiar definições do NS Copiar definições do NS (se existir)? - Tema gráfico original - Os botões são sempre exibidos na parte inferior do ecrã + Tema Gráfico Original + Os botões são sempre exibidos na parte inferior do ecrã + Mostrador Grande Tema gráfico diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index bd7dedb65d..9a71eb6ffd 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -383,12 +383,6 @@ Vechime insulină Vechime baterie pompă Opțiuni alarmare - Hiper urgent - Hiper - Hipo - Hipo urgent - Date învechite - Date mult prea vechi Prag vechime date [min] Prag date mult prea vechi [min] Interval pentru autosens [o] diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index 85fd15c298..ca8e62ca3d 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -264,6 +264,9 @@ Чтобы ввести %1$d г в %2$s ответьте кодом %3$s Для начала подачи базала %1$d%% на %2$d мин. ответьте кодом %3$s для приостановки цикла на %1$d мин ответьте кодом %2$s + Чтобы возобновить цикл ответьте кодом %1$s + Чтобы включить цикл ответьте кодом %1$s + Чтобы отключить цикл ответьте кодом %1$s врем базал %1$.2fU/h на %2$d мин начат успешно Пролонгированный болюс %1$.2fед. на %2$d мин. начат успешно Углеводы %1$d г введены успешно @@ -449,8 +452,14 @@ Порог критического уровня наполненности резервуара [U] Порог предупреждения о разрядке батареи [%] Порог предупреждения о критическом уровне разрядки батареи [%] + ОЖИД IOB акт инс акт углев + БАЗ + ОТКЛН + НАГР + НАДО + ЛИНОТКЛН о приложении отсутствует смс подтверждение Отсутствует разрешение телефона @@ -468,12 +477,8 @@ Переключить профиль Батарея помпы работает опции оповещения - Тревога выс - Высокий - Низкий - Тревога низкий - Устаревшие данные - Тревога! устаревшие данные + Создать уведомления из оповещений NS + Создать уведомления из оповещений NS Порог оповещения об устаревших данных [min] (мин) Порог тревоги об устаревших данных [min] (мин) Интервал для autosens [h] (ч) @@ -626,6 +631,8 @@ Подача пролонгированного болюса не состоялась Поле обзора тому назад + Установить нейтральные временные базалы + Если эта опция включена, то она отменяет временный базал до конца каждого часа. Такой метод помогает прекратить почасовую вибрацию некоторых помп. Всегда включать супер микро болюс SMB Всегда включать супер микро болюс SMB независимо от болюсов. Возможно только для источников СК с хорошей фильтрацией данных вроде G5 Активировать супер микро болюс SMB после углеводов @@ -853,6 +860,10 @@ Context | Edit Context Журнал оповещений Включить эмуляцию TBR Использовать пролонгированные болюсы вместо временных базалов TBR чтобы обойти лимит в 250%% + Отключение вибраций при ручном болюсе + Для болюса и пролонгированного болюса (доступно только для Insight прошивки 3.х) + Отключение вибрации при ручном болюсе + Для микроболюсов SMB и временных базалов с эмуляцией TBR (доступно только для Insight с прошивкой версии 3.x) Задержка разъединения [s] Серийный номер Версия ПО @@ -1277,8 +1288,6 @@ Context | Edit Context Индикаторы состояния Копировать параметры из NS Копировать настройки NS (если есть)? - Исходная тема оформления - Кнопки всегда отображаются в нижней части экрана Тема оформления @@ -1377,7 +1386,7 @@ Context | Edit Context Интеграция с помпой Omnompod Dash. Напоминание о завершении сопряжения Напоминание о завершении настройки - Срок Pod\'a истекает в ближайшее время + Срок работы Pod\'a истекает Срок Pod\'a истекает в ближайшее время Остановка неизбежна В резервуаре мало инсулина diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 4102738d1d..12f7de2d68 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -264,6 +264,9 @@ Pre zadanie %1$dg na %2$s odpovedz SMS kódom %3$s Pre spustenie bazálu %1$d%% na %2$d min odpovedzte SMS s kódom %3$s Pre pozastavenie uzavretého okruhu na %1$d minút odpovedaj SMS s kódom %2$s + Pre obnovenie uzavretého okruhu, odpovedzte SMS s kódom %1$s + Pre povolenie uzavretého okruhu, odpovedzte SMS s kódom %1$s + Pre zakázanie uzavretého okruhu, odpovedzte SMS s kódom %1$s Dočasný bazál %1$.2fJI/h spustený na %2$d minút Predĺžený bolus %1$.2fJI na %2$d min úspešne spustený Sacharidy %1$dg zadané úspešne @@ -468,12 +471,8 @@ Vykonajte zmenu profilu Vek batérie v pumpe Nastavenie alarmov - Veľmi vysoká - Vysoká - Nízka - Veľmi nízka - Zastaralé dáta - Veľmi zastaralé dáta + Vytvoriť oznámenia z alarmov NS + Vytvoriť oznámenia z upozornení NS Hraničná hodnota pre zastaralé dáta [min] Vysoká hraničná hodnota pre zastaralé dáta [min] Interval pre automatickú detekciu citlivosti [h] @@ -626,6 +625,8 @@ Chyba pri podávaní predĺženého bolusu Sight pred + Nastaviť neutrálny dočasný bazál + Ak je povolená táto možnosť, zastaví sa dočasný bazál pred koncom každej hodiny. To môže u niektorých púmp pomôcť zastaviť pípanie/vibrácie na celú hodinu. Vždy povoliť SMB Povoliť SMB nezávisle na bolusoch. Možno iba zo zdrojom glykémií s dobrým filtrovaním dát, ako napr. G5 Povoliť SMB po jedle @@ -851,6 +852,10 @@ Zaznamenať výstrahy Povoliť emuláciu dočasných bazálov Používať predĺžené bolusy namiesto dočasných bázalov, aby sme sa vyhli 250%% limitu + Zakázať vibrácie pri ručnom podaní bolusu + Pre bolus a predĺžený bolus (dostupné iba s Insight firmware 3.x) + Zakázať vibrácie pri automatickom podaní bolusu + Pre SMB a Dočasný bazál s emuláciou TBR (k dispozícii iba s Insight firmware 3.x) Oneskorenie odpojenia [s] Sériové číslo Verzia softwaru @@ -1275,8 +1280,6 @@ Indikátory stavu Kopírovať nastavenia z NS Skopírovať nastavenia NS (ak existujú)? - Pôvodný vzhľad - Tlačidlá sú vždy zobrazené v spodnej časti obrazovky Vzhľad diff --git a/app/src/main/res/values-sv-rSE/exam.xml b/app/src/main/res/values-sv-rSE/exam.xml index 507b63f02f..5a94009f00 100644 --- a/app/src/main/res/values-sv-rSE/exam.xml +++ b/app/src/main/res/values-sv-rSE/exam.xml @@ -130,7 +130,7 @@ Om du ändrar ISF-värdet i din profil är det tillräckligt för att tillämpa ändringen. https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#insulin-sensitivity-factor-isf-mmol-l-u-or-mg-dl-u https://androidaps.readthedocs.io/en/latest/EN/Usage/Profiles.html - Ämne: IC-kvoten + Ämne: KH-kvot Högre IC-kvot leder till mindre insulin som levereras för en given mängd kolhydrater. Lägre IC-kvot leder till mindre insulin som levereras för en given mängd kolhydrater. Om du har 0 COB, kommer en förändring av IC-kvoten leda till en annan mängd insulin för att korrigera din BG-nivå. diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 511f476671..fe88fd2393 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -132,12 +132,12 @@ Eversense-appen. Closed Loop Open Loop Stopp innan lågt - Loop avstängd + Loop inaktiverad Inaktivera loop Aktivera loop Ny rekommendation tillgänglig Versionen av Nightscout stöds inte - LOOP STOPPAD PGA BEGRÄNSNINGAR + LOOP INAKTIVERAD PGA BEGRÄNSNINGAR IOB från basal Bolusspärr aktiverad Kolhydratsspärr aktiverad @@ -251,9 +251,9 @@ Eversense-appen. Laddar upp Bolus avbruten Avbryter bolus - Loop stängdes av. - Loop aktiverades - Loop är avstängd + Loop inaktiverad. + Loop aktiverad + Loop är inaktiverad Loop är aktiverad %1$.2f begränsat till %2$.2f Värdet %1$s är utanför hård begränsning @@ -265,6 +265,9 @@ Eversense-appen. Om du vill ange %1$dg kl. %2$s, svara med kod %3$s För att starta temp basal %1$d%% i %2$d min, svara med kod %3$s För att pausa loop i %1$d minuter, svara med kod %2$s + För att återuppta loopen, svara med kod %1$s + För att aktivera loopen, svara med kod %1$s + För att inaktivera loopen, svara med kod %1$s Temp basal %1$.2f enheter/tim i %2$d min startad Förlängd bolus %1$.2f enheter över %2$d min har startats %1$dg kolhydrater registrerat @@ -279,8 +282,8 @@ Eversense-appen. Misslyckades med att avbryta temp basal Avbryter förlängd bolus Okänt kommando eller fel svar - Kalkylator - Kalkylatorinställningar + Snabbsteg + Inställningar för snabbsteg Knapptext: KH: Giltig: @@ -423,7 +426,7 @@ Eversense-appen. Återuppta Återanslut Pump Fel duration - Loop pausad. + Loop pausad Loop återupptagen 15 min trend COB @@ -450,8 +453,14 @@ Eversense-appen. Akut varningsnivå för reservoar [U] Varningsnivå för batteri [%] Akut varningsnivå för batteri [%] + Prog IOB COB + Bas + Dev + Akt + Abs + Devslope Om Saknar behörighet att skicka SMS Behörighet saknas @@ -469,12 +478,8 @@ Eversense-appen. Genomför profilbyte Pumpbatteri ålder Larminställningar - Akut hög - Hög - Låg - Akut låg - BG-data saknas - BG-data saknas (akut larm) + Skapa aviseringar från NS-larm + Skapa aviseringar från NS-meddelanden Första varning efter [min] Akut varning efter [min] Intervall för autosens [tim] @@ -627,6 +632,8 @@ Eversense-appen. Förlängd bolus misslyckad Sight sedan + Sätt neutrala temp basaler + Om aktiverad, kommer en eventuell temporär basal automatiskt avbrytas före utgången av varje timme. Denna metod kan förhindra att vissa pumpar piper/vibrerar. Använd alltid SMB Använd alltid SMB oberoende av bolus. Endast möjligt med en bra filtrerad BG-källa, t ex Dexcom G5. Använd SMB efter kolhydrater @@ -652,7 +659,7 @@ Eversense-appen. Skapa notiser vid fel Skapa notiser i Nightscout vid fel eller lokala meddelanden (även synliga i Careportal/Behandlingar) Visa BG-prognos på klockan. - Prognos + BG-prognos Dataval Uppladdning till Fabric Tillåt automatisk rapportering av appkrascher och användningsinformation till utvecklarna via fabric.io-tjänsten. @@ -675,7 +682,7 @@ Eversense-appen. Basaler Ingen åtgärd vald. Inget ändras. Starta \"Hypo\" - Du kör nu dev-versionen. Closed Loop inte tillåtet. + Du kör nu dev-versionen. Closed Loop inaktiverat. Engineering Mode aktiverat Engineering Mode inte aktiverat och appen körs inte som release Läser basalprofil @@ -852,6 +859,10 @@ Eversense-appen. Logga varningar Aktivera emulering av temp basal Använda förlängda bolusar istället för temp basaler för att kringgå 250%%-begränsningen + Inaktivera vibration för manuell bolus + För bolus och förlängd bolus (endast tillgängligt med Insight firmware 3.x) + Inaktivera vibration för automatisk bolus + För SMB och temp basal med TBR-emulering (endast tillgängligt med Insight firmware 3.x) Fördröjning av frånkoppling [s] Serienummer Mjukvaruversion Release @@ -1266,7 +1277,7 @@ Eversense-appen. Genom att återställa autentiseringsfunktionen kommer alla redan driftsatta autentiserare bli ogiltiga. Du kommer behöva sätta upp dem igen! Vid anslutning Vid frånkoppling - Beräknade resultat + BG-prognos Avvikelsekurva Behörighetskontroll misslyckades Absolut insulinmängd @@ -1276,8 +1287,9 @@ Eversense-appen. Statuslampor Kopiera inställningar från NS Kopiera NS-inställningar (om det finns)? - Ursprungligt tema - Knappar visas alltid längst ned på skärmen + Ursprungligt tema + Knappar visas alltid längst ned på skärmen + Stor skärm Tema @@ -1376,7 +1388,7 @@ Eversense-appen. Pumpintegration för Omnipod Dash. Påminnelse att slutföra parkoppling Påminnelse att slutföra installation - Pod kommer att gå ut inom kort + Pod löper snart ut Pod kommer att gå ut inom kort Pod kommer snart att stängas av Låg reservoar diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 3b916dda38..738a52ea2e 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -355,12 +355,6 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d İnsülin yaşı Pompa pil yaşı Alarm türleri - Aşırı yüksek - Yüksek - Düşük - Çok düşük - Eski veriler - Acil durum verileri Eski veri eşiği [min] Acil durum verileri eşiği [min] Autosens [h] için aralık diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b642819c55..295bc3b9f1 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -378,12 +378,6 @@ 胰岛素使用时间 泵电池使用时间 报警选项 - 紧急高 - - - 紧急低 - 陈旧数据 - 紧急陈旧数据 陈旧数据阈值 [min] 紧急陈旧数据阈值 [min] Autosens间隔的 [h] diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 7ca80a7af9..0d8f4134a1 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -22,6 +22,7 @@ + @string/default_lang @string/en_lang @string/af_lang @string/bg_lang @@ -45,6 +46,7 @@ @string/zh_lang + default en af bg diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4a4595fab4..1533fce625 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,5 @@ + System default English Czech Afrikaans @@ -299,6 +300,11 @@ Loop is enabled %1$.2f limited to %2$.2f Value %1$s is out of hard limits + To connect pump reply with code %1$s + Connection to pump failed + To disconnect pump for %1d minutes reply with code %2$s + Pump disconnected + Pump reconnected Remote command is not allowed Remote bolus not available. Try again later. To start basal %1$.2fU/h for %2$d min reply with code %3$s @@ -307,6 +313,9 @@ To enter %1$dg at %2$s reply with code %3$s To start basal %1$d%% for %2$d min reply with code %3$s To suspend loop for %1$d minutes reply with code %2$s + To resume loop reply with code %1$s + To enable loop reply with code %1$s + To disable loop reply with code %1$s Temp basal %1$.2fU/h for %2$d min started successfully Extended bolus %1$.2fU for %2$d min started successfully Carbs %1$dg entered successfully @@ -527,8 +536,14 @@ Threshold warning battery level [%] statuslights_bat_critical Threshold critical battery level [%] + PRED IOB COB + BAS + DEV + ACT + ABS + DEVSLOPE About Missing SMS permission Missing phone state permission @@ -548,20 +563,12 @@ Do Profile Switch Pump battery age Alarm options - nsalarm_urgent_high - nsalarm_high - nsalarm_low - nsalarm_urgent_low - nsalarm_staledata - nsalarm_urgent_staledata + ns_announcements + ns_alarms nsalarm_staledatavalue nsalarm_urgent_staledatavalue - Urgent high - High - Low - Urgent low - Stale data - Urgent stale data + Create notifications from NS alarms + Create notifications from NS announcements Stale data threshold [min] Urgent stale data threshold [min] Interval for autosens [h] @@ -740,6 +747,9 @@ enableSMB_with_temptarget enableSMB_after_carbs enableSMB_with_high_temptarget + set_neutral_temps + Set neutral temp basals + If enabled, it will cancel a temporary basal before the end of each hour. This method can help stop some pumps beeping/vibrating on the hour. Enable SMB always Enable SMB always independently to boluses. Possible only with BG source with nice filtering of data like G5 Enable SMB after carbs @@ -1016,6 +1026,12 @@ Log alerts Enable TBR emulation Use extended boluses instead of TBRs to bypass the 250%% limit + insight_disable_vibration + Disable vibrations on manual bolus delivery + For bolus and extended bolus (only available with Insight firmware 3.x) + insight_disable_vibration_auto + Disable vibrations on automated bolus delivery + For SMB and Temp Basal with TBR emulation (only available with Insight firmware 3.x) Disconnect delay [s] Serial number Release software version @@ -1537,8 +1553,9 @@ statuslights_copy_ns Copy NS settings (if exists)? statuslights_overview_advanced - Original skin - Buttons are always displayed on bottom of screen + Original skin + Buttons are always displayed on bottom of screen + Large display skin Skin @@ -1675,7 +1692,7 @@ Pump integration for Omnipod Dash. Finish pairing reminder Finish setup reminder - Pod wil expire soon + Pod will expire soon Pod will expire soon Shutdown is imminent Low reservoir diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 9ae1ff6b9a..8dd2f98b76 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -14,7 +14,7 @@ android:title="@string/unitsnosemicolon" /> + + + + + + + + \ 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 6f68d77a7b..a25aeebd2f 100644 --- a/app/src/main/res/xml/pref_nsclientinternal.xml +++ b/app/src/main/res/xml/pref_nsclientinternal.xml @@ -42,29 +42,12 @@ android:title="@string/ns_alarmoptions"> + android:key="@string/key_ns_alarms" + android:title="@string/ns_alarms" /> - - - - - - + android:key="@string/key_ns_announcements" + android:title="@string/ns_announcements" /> - - = ArrayList() - companion object { - @Deprecated("Use Dagger") - lateinit var instance: L - - @Deprecated("Use Dagger") - @JvmStatic - fun isEnabled(ltag: LTag): Boolean { - return instance.findByName(ltag.name).enabled - } - } - init { - instance= this LTag.values().forEach { logElements.add(LogElement(it, sp)) } } @@ -46,7 +34,7 @@ class L @Inject constructor( } class LogElement { - var sp : SP + var sp: SP var name: String var defaultValue: Boolean var enabled: Boolean diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.java b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.java index 84ab8e5661..359ed88560 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.java @@ -62,6 +62,7 @@ public class APSResult { public boolean hasPredictions = false; public double smb = 0d; // super micro bolus in units public long deliverAt = 0; + public double targetBG = 0d; public Constraint inputConstraints; @@ -184,6 +185,7 @@ public class APSResult { newResult.smbConstraint = smbConstraint; newResult.percent = percent; newResult.usePercent = usePercent; + newResult.targetBG = targetBG; } diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/SMBDefaults.java b/core/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/SMBDefaults.java index 5f2216b5ae..83ef09f89a 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/SMBDefaults.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/SMBDefaults.java @@ -37,7 +37,7 @@ public class SMBDefaults { // (If someone enters more carbs or stacks more; OpenAPS will just truncate dosing based on 120. // Essentially, this just limits AMA/SMB as a safety cap against excessive COB entry) public final static int maxCOB = 120; - public final static boolean skip_neutral_temps = true; // ***** default false in oref1 ***** if true, don't set neutral temps + //public final static boolean skip_neutral_temps = true; // ***** default false in oref1 ***** if true, don't set neutral temps // unsuspend_if_no_temp:false // if true, pump will un-suspend after a zero temp finishes // bolussnooze_dia_divisor:2 // bolus snooze decays after 1/2 of DIA public final static double min_5m_carbimpact = 8d; // mg/dL per 5m (8 mg/dL/5m corresponds to 24g/hr at a CSF of 4 mg/dL/g (x/5*60/4)) diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index f6cd44a84b..5aab6d18b6 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -232,8 +232,7 @@ public class NSUpload { deviceStatus.enacted.put("requested", requested); } } else { - if (L.isEnabled(LTag.NSCLIENT)) - aapsLogger.debug("OpenAPS data too old to upload, sending iob only"); + aapsLogger.debug(LTag.NSCLIENT, "OpenAPS data too old to upload, sending iob only"); IobTotal[] iob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile); if (iob.length > 0) { deviceStatus.iob = iob[0].json(); diff --git a/core/src/main/java/info/nightscout/androidaps/utils/DateUtil.java b/core/src/main/java/info/nightscout/androidaps/utils/DateUtil.java index 419729a126..c5c5b68335 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/DateUtil.java +++ b/core/src/main/java/info/nightscout/androidaps/utils/DateUtil.java @@ -261,6 +261,10 @@ public class DateUtil { return timeFrameString(timestamp - System.currentTimeMillis(), resourceHelper); } + public long _now() { + return System.currentTimeMillis(); + } + public static long now() { return System.currentTimeMillis(); } @@ -358,6 +362,7 @@ public class DateUtil { // singletons to avoid repeated allocation private static DecimalFormatSymbols dfs; private static DecimalFormat df; + public static String qs(double x, int digits) { if (digits == -1) { diff --git a/core/src/main/java/info/nightscout/androidaps/utils/FabricPrivacy.kt b/core/src/main/java/info/nightscout/androidaps/utils/FabricPrivacy.kt index 9468f21bd4..744c692541 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/FabricPrivacy.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/FabricPrivacy.kt @@ -2,13 +2,12 @@ package info.nightscout.androidaps.utils import android.content.Context import android.os.Bundle -import com.crashlytics.android.Crashlytics import com.google.firebase.analytics.FirebaseAnalytics +import com.google.firebase.crashlytics.FirebaseCrashlytics import info.nightscout.androidaps.core.R import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.utils.sharedPreferences.SP -import io.fabric.sdk.android.Fabric import javax.inject.Inject import javax.inject.Singleton @@ -27,21 +26,9 @@ class FabricPrivacy @Inject constructor( var firebaseAnalytics: FirebaseAnalytics init { - instance = this firebaseAnalytics = FirebaseAnalytics.getInstance(context) firebaseAnalytics.setAnalyticsCollectionEnabled(!java.lang.Boolean.getBoolean("disableFirebase") && fabricEnabled()) - - if (fabricEnabled()) { - Fabric.with(context, Crashlytics()) - } - } - - companion object { - private lateinit var instance: FabricPrivacy - - @JvmStatic - @Deprecated("Use Dagger") - fun getInstance(): FabricPrivacy = instance + FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!java.lang.Boolean.getBoolean("disableFirebase") && fabricEnabled()) } // Analytics logCustom @@ -76,38 +63,8 @@ class FabricPrivacy @Inject constructor( // Crashlytics logException fun logException(throwable: Throwable) { - try { - val crashlytics = Crashlytics.getInstance() - crashlytics.core.logException(throwable) - } catch (e: NullPointerException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $throwable") - } catch (e: IllegalStateException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $throwable") - } - } - - // Crashlytics log - fun log(msg: String) { - try { - val crashlytics = Crashlytics.getInstance() - crashlytics.core.log(msg) - } catch (e: NullPointerException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg") - } catch (e: IllegalStateException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg") - } - } - - // Crashlytics log - fun log(priority: Int, tag: String?, msg: String) { - try { - val crashlytics = Crashlytics.getInstance() - crashlytics.core.log(priority, tag, msg) - } catch (e: NullPointerException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg") - } catch (e: IllegalStateException) { - aapsLogger.debug(LTag.CORE, "Ignoring opted out non-initialized log: $msg") - } + FirebaseCrashlytics.getInstance().recordException(throwable) + aapsLogger.debug(LTag.CORE, "Exception: ", throwable) } fun fabricEnabled(): Boolean { diff --git a/core/src/main/java/info/nightscout/androidaps/utils/HtmlHelper.kt b/core/src/main/java/info/nightscout/androidaps/utils/HtmlHelper.kt index b79fe884b4..dd0da3b72f 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/HtmlHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/HtmlHelper.kt @@ -6,11 +6,6 @@ import android.text.Spanned object HtmlHelper { fun fromHtml(source: String): Spanned { - // API level 24 to replace call - @Suppress("DEPRECATION") - return when { - Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY) - else -> Html.fromHtml(source) - } + return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY) } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/OKDialog.kt b/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/OKDialog.kt index 2d45d2910d..c0fc646258 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/OKDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/OKDialog.kt @@ -12,6 +12,7 @@ import info.nightscout.androidaps.utils.extensions.runOnUiThread object OKDialog { @SuppressLint("InflateParams") fun show(context: Context, title: String, message: String, runnable: Runnable? = null) { + var okClicked = false var notEmptytitle = title if (notEmptytitle.isEmpty()) notEmptytitle = context.getString(R.string.message) @@ -19,18 +20,21 @@ object OKDialog { .setCustomTitle(AlertDialogHelper.buildCustomTitle(context, notEmptytitle)) .setMessage(message) .setPositiveButton(context.getString(R.string.ok)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runOnUiThread(runnable) + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runOnUiThread(runnable) + } } .show() .setCanceledOnTouchOutside(false) } @SuppressLint("InflateParams") - @JvmStatic - @JvmOverloads fun show(activity: Activity, title: String, message: Spanned, runnable: Runnable? = null) { + var okClicked = false var notEmptytitle = title if (notEmptytitle.isEmpty()) notEmptytitle = activity.getString(R.string.message) @@ -38,9 +42,13 @@ object OKDialog { .setCustomTitle(AlertDialogHelper.buildCustomTitle(activity, notEmptytitle)) .setMessage(message) .setPositiveButton(activity.getString(R.string.ok)) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runnable?.let { activity.runOnUiThread(it) } + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runnable?.let { activity.runOnUiThread(it) } + } } .show() .setCanceledOnTouchOutside(false) @@ -57,71 +65,89 @@ object OKDialog { } @SuppressLint("InflateParams") - @JvmStatic - @JvmOverloads fun showConfirmation(activity: Activity, title: String, message: Spanned, ok: Runnable?, cancel: Runnable? = null) { + var okClicked = false AlertDialogHelper.Builder(activity) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(activity, title)) .setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - ok?.let { activity.runOnUiThread(it) } + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + ok?.let { activity.runOnUiThread(it) } + } } .setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - cancel?.let { activity.runOnUiThread(it) } + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + cancel?.let { activity.runOnUiThread(it) } + } } - .setNegativeButton(android.R.string.cancel, null) .show() .setCanceledOnTouchOutside(false) } @SuppressLint("InflateParams") - @JvmStatic fun showConfirmation(activity: Activity, title: String, message: String, ok: Runnable?, cancel: Runnable? = null) { + var okClicked = false AlertDialogHelper.Builder(activity) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(activity, title)) .setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - ok?.let { activity.runOnUiThread(it) } + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + ok?.let { activity.runOnUiThread(it) } + } } .setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - cancel?.let { activity.runOnUiThread(it) } + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + cancel?.let { activity.runOnUiThread(it) } + } } .show() .setCanceledOnTouchOutside(false) } - @JvmStatic - @JvmOverloads fun showConfirmation(context: Context, message: Spanned, ok: Runnable?, cancel: Runnable? = null) { showConfirmation(context, context.getString(R.string.confirmation), message, ok, cancel) } @SuppressLint("InflateParams") - @JvmStatic - @JvmOverloads fun showConfirmation(context: Context, title: String, message: Spanned, ok: Runnable?, cancel: Runnable? = null) { + var okClicked = false AlertDialogHelper.Builder(context) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(context, title)) .setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runOnUiThread(ok) + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runOnUiThread(ok) + } } .setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runOnUiThread(cancel) + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runOnUiThread(cancel) + } } - .setNegativeButton(android.R.string.cancel, null) .show() .setCanceledOnTouchOutside(false) } @@ -136,18 +162,27 @@ object OKDialog { @JvmStatic @JvmOverloads fun showConfirmation(context: Context, title: String, message: String, ok: Runnable?, cancel: Runnable? = null) { + var okClicked = false AlertDialogHelper.Builder(context) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(context, title)) .setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runOnUiThread(ok) + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runOnUiThread(ok) + } } .setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - runOnUiThread(cancel) + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + runOnUiThread(cancel) + } } .show() .setCanceledOnTouchOutside(false) @@ -157,18 +192,27 @@ object OKDialog { @JvmStatic @JvmOverloads fun showConfirmation(context: Context, title: String, message: String, ok: DialogInterface.OnClickListener?, cancel: DialogInterface.OnClickListener? = null) { + var okClicked = false AlertDialogHelper.Builder(context) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(context, title)) .setPositiveButton(android.R.string.ok) { dialog: DialogInterface, which: Int -> - dialog.dismiss() - SystemClock.sleep(100) - ok?.onClick(dialog, which) + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + ok?.onClick(dialog, which) + } } .setNegativeButton(android.R.string.cancel) { dialog: DialogInterface, which: Int -> - dialog.dismiss() - SystemClock.sleep(100) - cancel?.onClick(dialog, which) + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + cancel?.onClick(dialog, which) + } } .show() .setCanceledOnTouchOutside(false) diff --git a/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/WarningDialog.kt b/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/WarningDialog.kt index 847287d57a..2894f1b8d4 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/WarningDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/alertDialogs/WarningDialog.kt @@ -13,31 +13,37 @@ import info.nightscout.androidaps.utils.extensions.runOnUiThread object WarningDialog { @SuppressLint("InflateParams") - @JvmStatic - @JvmOverloads fun showWarning(context: Context, title: String, message: String, @StringRes positiveButton: Int = -1, ok: (() -> Unit)? = null, cancel: (() -> Unit)? = null) { - + var okClicked = false val builder = AlertDialogHelper.Builder(context, R.style.AppThemeWarningDialog) .setMessage(message) .setCustomTitle(AlertDialogHelper.buildCustomTitle(context, title, R.drawable.ic_header_warning, R.style.AppThemeWarningDialog)) .setNegativeButton(R.string.dismiss) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - if (cancel != null) { - runOnUiThread(Runnable { - cancel() - }) + if (okClicked) return@setNegativeButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + if (cancel != null) { + runOnUiThread(Runnable { + cancel() + }) + } } } if (positiveButton != -1) { builder.setPositiveButton(positiveButton) { dialog: DialogInterface, _: Int -> - dialog.dismiss() - SystemClock.sleep(100) - if (ok != null) { - runOnUiThread(Runnable { - ok() - }) + if (okClicked) return@setPositiveButton + else { + okClicked = true + dialog.dismiss() + SystemClock.sleep(100) + if (ok != null) { + runOnUiThread(Runnable { + ok() + }) + } } } } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/locale/LocaleHelper.kt b/core/src/main/java/info/nightscout/androidaps/utils/locale/LocaleHelper.kt index 7180bf7927..29d53e1e53 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/locale/LocaleHelper.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/locale/LocaleHelper.kt @@ -1,22 +1,23 @@ -package info.nightscout.androidaps.utils +package info.nightscout.androidaps.utils.locale import android.content.Context import android.content.ContextWrapper -import android.os.Build import android.os.LocaleList import androidx.preference.PreferenceManager import info.nightscout.androidaps.core.R import java.util.* object LocaleHelper { - private fun currentLanguage(context: Context): String = - PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.key_language), "en") - ?: "en" + private fun selectedLanguage(context: Context): String = + PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.key_language), "default") + ?: "default" // injection not possible because of use in attachBaseContext //SP.getString(R.string.key_language, Locale.getDefault().language) private fun currentLocale(context: Context): Locale { - val language = currentLanguage(context) + val language = selectedLanguage(context) + if (language == "default") return Locale.getDefault() + var locale = Locale(language) if (language.contains("_")) { // language with country like pt_BR defined in arrays.xml @@ -27,32 +28,30 @@ object LocaleHelper { return locale } - @Suppress("DEPRECATION") fun update(context: Context) { + // no action for system default language + if (selectedLanguage(context) == "default") return + val locale = currentLocale(context) Locale.setDefault(locale) val resources = context.resources val configuration = resources.configuration context.createConfigurationContext(configuration) configuration.setLocale(locale) - configuration.locale = locale - resources.updateConfiguration(configuration, resources.displayMetrics) } - fun wrap(ctx: Context): ContextWrapper { + fun wrap(ctx: Context): Context { + // no action for system default language + if (selectedLanguage(ctx) == "default") return ctx + val res = ctx.resources val configuration = res.configuration val newLocale = currentLocale(ctx) - val context = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - configuration.setLocale(newLocale) - val localeList = LocaleList(newLocale) - LocaleList.setDefault(localeList) - configuration.locales = localeList - ctx.createConfigurationContext(configuration) - } else { - configuration.setLocale(newLocale) - ctx.createConfigurationContext(configuration) - } + configuration.setLocale(newLocale) + val localeList = LocaleList(newLocale) + LocaleList.setDefault(localeList) + configuration.locales = localeList + val context = ctx.createConfigurationContext(configuration) return ContextWrapper(context) } } \ No newline at end of file diff --git a/core/src/main/res/drawable-mdpi/icon_actions_refill.png b/core/src/main/res/drawable-mdpi/icon_actions_refill.png deleted file mode 100644 index 737cca8b00..0000000000 Binary files a/core/src/main/res/drawable-mdpi/icon_actions_refill.png and /dev/null differ diff --git a/core/src/main/res/drawable-mdpi/icon_danar_useropt.png b/core/src/main/res/drawable-mdpi/icon_danar_useropt.png deleted file mode 100644 index 1fadcd446b..0000000000 Binary files a/core/src/main/res/drawable-mdpi/icon_danar_useropt.png and /dev/null differ diff --git a/core/src/main/res/drawable-mdpi/icon_home_profile.png b/core/src/main/res/drawable-mdpi/icon_home_profile.png deleted file mode 100644 index f689df10c6..0000000000 Binary files a/core/src/main/res/drawable-mdpi/icon_home_profile.png and /dev/null differ diff --git a/core/src/main/res/drawable-xxxhdpi/icon_local_save.png b/core/src/main/res/drawable-xxxhdpi/icon_local_save.png deleted file mode 100644 index f2ecc45ac0..0000000000 Binary files a/core/src/main/res/drawable-xxxhdpi/icon_local_save.png and /dev/null differ diff --git a/core/src/main/res/values-bg-rBG/strings.xml b/core/src/main/res/values-bg-rBG/strings.xml index 4c45586f82..e0560d2206 100644 --- a/core/src/main/res/values-bg-rBG/strings.xml +++ b/core/src/main/res/values-bg-rBG/strings.xml @@ -1,20 +1,69 @@ + Грешка + Не е зададен + Неуспешно обновяване на базалния профил + Профила на помпата е обновен + Грешни данни + Грешка при подаване на временен базал + Ще стартира %1$.2fЕ болус + Чакаме помпата + Свързване %1$d сек + Пускам %1$.2fЕ + Сдвояване + Свързване + Свързана + Не е сврзана + Разкачане + Стартиран AndroidAPS + %1$.2fЕ + %1$.0f / %2$d Е + %1$.2f Е/ч + %1$.2f ч + %1$d мин + %1$dm + Помпата е заета + Грешка при връзка с помпата + Достигнахте лимита + Цели + Затвори + Моля изчакайте... + Заглушаване + Презареди + Натиснат е СТОП! + Стоп + въглехидрати + Грешен профил !!! + НЕ Е АКТИВИРАН ПРОФИЛ + Дата + Единици + DIA (Време на действие на инсулина): + IC (Инсулин/въглехидр.): + ISF (Инс.чувствителност): + Базал + Целeва КЗ: + Инициализация ... + Сериен номер + Батерия + Последна връзка + преди %1$d мин + %1$dмин + Статистика diff --git a/core/src/main/res/values-de-rDE/strings.xml b/core/src/main/res/values-de-rDE/strings.xml index dd1063e8c7..712b2c3534 100644 --- a/core/src/main/res/values-de-rDE/strings.xml +++ b/core/src/main/res/values-de-rDE/strings.xml @@ -124,25 +124,24 @@ %1$s: ∑: %2$.2f Bol: %3$.2f Bas: %4$.2f]]> - BZ Test + BZ-Test Ankündigung Notiz Frage Bewegung - Pumpenkatheter Wechsel + Pumpenkatheter-Wechsel CGM-Sensor gesetzt CGM-Sensor Start - Insulinreservoir Wechsel + Insulinreservoir-Wechsel Profilwechsel - Snack Bolus - Mahlzeiten Bolus - Korrektur Bolus - Combo Bolus - TBR Start + Snack-Bolus + Mahlzeiten-Bolus + Korrektur-Bolus + Combo-Bolus TBR Ende - Kohlenhydrat Korrektur + Kohlenhydrat-Korrektur OpenAPS offline - Pumpenbatterie Wechsel + Pumpenbatterie-Wechsel Temporäres Ziel Temporäres Ziel abbrechen Finger diff --git a/core/src/main/res/values-fr-rFR/strings.xml b/core/src/main/res/values-fr-rFR/strings.xml index 85f5ce3e2f..4f7e558f4d 100644 --- a/core/src/main/res/values-fr-rFR/strings.xml +++ b/core/src/main/res/values-fr-rFR/strings.xml @@ -10,7 +10,7 @@ Erreur injection basal temporaire %1$.2fU vont être injectées Attente connection pompe - Connexion à %1$s en cours + Connexion à %1$d en cours Injection en cours %1$.2fU Connexion Connection en cours diff --git a/core/src/main/res/values-pt-rPT/strings.xml b/core/src/main/res/values-pt-rPT/strings.xml index eae9d66156..eb03777b55 100644 --- a/core/src/main/res/values-pt-rPT/strings.xml +++ b/core/src/main/res/values-pt-rPT/strings.xml @@ -8,7 +8,7 @@ Perfil Basal actualizado na bomba Entrada Inválida Erro na administração da Basal Temp - A ser administrada %1$.2fU + A ser administrado %1$.2fU À espera da bomba A ligar durante %1$d s A administrar %1$.2fU @@ -130,7 +130,7 @@ Questão Exercício Mudança Local Bomba - Colocação do Sensor CGM + Colocação Sensor CGM Início do Sensor CGM Mudança de Cartucho de Insulina Troca de Perfil diff --git a/dana/build.gradle b/dana/build.gradle index 4450b57df6..09205a9337 100644 --- a/dana/build.gradle +++ b/dana/build.gradle @@ -51,10 +51,9 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' implementation "androidx.preference:preference-ktx:1.1.1" - implementation "androidx.activity:activity:${activityVersion}" implementation "androidx.activity:activity-ktx:${activityVersion}" - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" + implementation "io.reactivex.rxjava2:rxandroid:${rxandroid_version}" // Graphview cannot be upgraded implementation "com.jjoe64:graphview:4.0.1" diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt index 33f92910ac..e06f924215 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt @@ -3,10 +3,11 @@ package info.nightscout.androidaps.dana import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.interfaces.ProfileStore import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.db.Treatment +import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.sharedPreferences.SP import org.json.JSONArray import org.json.JSONException @@ -49,8 +50,32 @@ class DanaPump @Inject constructor( var bleModel = "" // RS v3: like BPN-1.0.1 var isNewPump = true // R only , providing model info var password = -1 // R, RSv1 - var pumpTime: Long = 0 + + // time + private var pumpTime: Long = 0 + var zoneOffset: Int = 0 // i (hw 7+) + + fun setPumpTime(value: Long) { + pumpTime = value + } + + fun setPumpTime(value: Long, zoneOffset: Int) { + pumpTime = value + T.hours(zoneOffset.toLong()).msecs() + this.zoneOffset = zoneOffset + } + + fun resetPumpTime() { + pumpTime = 0 + } + + fun getPumpTime() = pumpTime + var hwModel = 0 + val usingUTC + get() = hwModel >= 7 + val profile24 + get() = hwModel >= 7 + var protocol = 0 var productCode = 0 var errorState: ErrorState = ErrorState.NONE @@ -90,8 +115,9 @@ class DanaPump @Inject constructor( var extendedBolusRemainingMinutes = 0 var extendedBolusDeliveredSoFar = 0.0 //RS only = 0.0 - // Profile + // Profile R,RSv1 var units = 0 + var activeProfile = 0 var easyBasalMode = 0 var basal48Enable = false var currentCIR = 0 @@ -107,7 +133,10 @@ class DanaPump @Inject constructor( var eveningCF = 0.0 var nightCIR = 0 var nightCF = 0.0 - var activeProfile = 0 + + // Profile I + var cf24 = Array(24) { 0.0 } + var cir24 = Array(24) { 0.0 } //var pumpProfiles = arrayOf>() var pumpProfiles: Array>? = null @@ -151,6 +180,8 @@ class DanaPump @Inject constructor( var bolusDone = false // success end var lastEventTimeLoaded: Long = 0 // timestamp of last received event + val lastKnownHistoryId: Int = 0 // hwver 7+, 1-2000 + fun createConvertedProfile(): ProfileStore? { pumpProfiles?.let { val json = JSONObject() @@ -165,18 +196,30 @@ class DanaPump @Inject constructor( json.put("store", store) profile.put("dia", Constants.defaultDIA) val carbratios = JSONArray() - carbratios.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCIR)) - carbratios.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCIR)) - carbratios.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCIR)) - carbratios.put(JSONObject().put("time", "14:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCIR)) - carbratios.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCIR)) + if (!profile24) { + carbratios.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCIR)) + carbratios.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCIR)) + carbratios.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCIR)) + carbratios.put(JSONObject().put("time", "14:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCIR)) + carbratios.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCIR)) + } else { // 24 values + for (i in 0..23) { + carbratios.put(JSONObject().put("time", String.format("%02d", i) + ":00").put("timeAsSeconds", i * 3600).put("value", cir24[i])) + } + } profile.put("carbratio", carbratios) val sens = JSONArray() - sens.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCF)) - sens.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCF)) - sens.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCF)) - sens.put(JSONObject().put("time", "17:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCF)) - sens.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCF)) + if (!profile24) { + sens.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCF)) + sens.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCF)) + sens.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCF)) + sens.put(JSONObject().put("time", "17:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCF)) + sens.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCF)) + } else { // 24 values + for (i in 0..23) { + sens.put(JSONObject().put("time", String.format("%02d", i) + ":00").put("timeAsSeconds", i * 3600).put("value", cf24[i])) + } + } profile.put("sens", sens) val basals = JSONArray() val basalValues = if (basal48Enable) 48 else 24 @@ -270,6 +313,7 @@ class DanaPump @Inject constructor( const val PROFILECHANGE = 13 const val CARBS = 14 const val PRIMECANNULA = 15 + const val TIMECHANGE = 16 // Dana R btModel const val DOMESTIC_MODEL = 0x01 diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt index be38978236..fafebe603d 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt @@ -44,6 +44,8 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { private fun isDanaR() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaR private fun isDanaRv2() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRv2 + var minBacklight = 1 + @Synchronized override fun onResume() { super.onResume() @@ -65,6 +67,8 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { save_user_options.setOnClickListener { onSaveClick() } + minBacklight = if (danaPump.hwModel < 7) 1 else 0 // Dana-i allows zero + aapsLogger.debug(LTag.PUMP, "UserOptionsLoaded:" + (System.currentTimeMillis() - danaPump.lastConnection) / 1000 + " s ago" + "\ntimeDisplayType:" + danaPump.timeDisplayType @@ -76,9 +80,9 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { + "\nlowReservoir:" + danaPump.lowReservoirRate) danar_screentimeout.setParams(danaPump.lcdOnTimeSec.toDouble(), 5.0, 240.0, 5.0, DecimalFormat("1"), false, save_user_options) - danar_backlight.setParams(danaPump.backlightOnTimeSec.toDouble(), 1.0, 60.0, 1.0, DecimalFormat("1"), false, save_user_options) + danar_backlight.setParams(danaPump.backlightOnTimeSec.toDouble(), minBacklight.toDouble(), 60.0, 1.0, DecimalFormat("1"), false, save_user_options) danar_shutdown.setParams(danaPump.shutdownHour.toDouble(), 0.0, 24.0, 1.0, DecimalFormat("1"), true, save_user_options) - danar_lowreservoir.setParams(danaPump.lowReservoirRate.toDouble(), 10.0, 60.0, 10.0, DecimalFormat("10"), false, save_user_options) + danar_lowreservoir.setParams(danaPump.lowReservoirRate.toDouble(), 10.0, 50.0, 10.0, DecimalFormat("10"), false, save_user_options) when (danaPump.beepAndAlarm) { 0x01 -> danar_pumpalarm_sound.isChecked = true 0x02 -> danar_pumpalarm_vibrate.isChecked = true @@ -136,7 +140,7 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { // step is 5 seconds, 5 to 240 danaPump.lcdOnTimeSec = min(max(danar_screentimeout.value.toInt() / 5 * 5, 5), 240) // 1 to 60 - danaPump.backlightOnTimeSec = min(max(danar_backlight.value.toInt(), 1), 60) + danaPump.backlightOnTimeSec = min(max(danar_backlight.value.toInt(), minBacklight), 60) danaPump.units = if (danar_units.isChecked) 1 else 0 diff --git a/dana/src/main/res/values-cs-rCZ/strings.xml b/dana/src/main/res/values-cs-rCZ/strings.xml index 54cb889cc2..695e20aefe 100644 --- a/dana/src/main/res/values-cs-rCZ/strings.xml +++ b/dana/src/main/res/values-cs-rCZ/strings.xml @@ -29,6 +29,9 @@ Baterie v pumpě vybitá Okluze Prázdný zásobník + Zkontrolovat hřídel + Max. bazál + Max. denní Výstraha měření glykémie Zbývající inzulín Chybějící bolus diff --git a/dana/src/main/res/values-de-rDE/strings.xml b/dana/src/main/res/values-de-rDE/strings.xml index 4d7efc4638..56f9391d6e 100644 --- a/dana/src/main/res/values-de-rDE/strings.xml +++ b/dana/src/main/res/values-de-rDE/strings.xml @@ -29,6 +29,9 @@ Pumpenbatterie entladen Verstopfung Reservoir leer + Gewindestange prüfen + max. Basal + Tagesmaximum Alarm BZ-Messung Restinsulin Versäumter Bolus diff --git a/dana/src/main/res/values-fr-rFR/strings.xml b/dana/src/main/res/values-fr-rFR/strings.xml index 7da5f10834..2c45d91871 100644 --- a/dana/src/main/res/values-fr-rFR/strings.xml +++ b/dana/src/main/res/values-fr-rFR/strings.xml @@ -29,6 +29,8 @@ Batterie Pompe Déchargée Occlusion Réservoir vide + Basal max + Quotidien max Alerte de mesure de glycémie Niveau d\'insuline restant Bolus manqués diff --git a/dana/src/main/res/values-it-rIT/strings.xml b/dana/src/main/res/values-it-rIT/strings.xml index 3ffadabd3b..11329423d5 100644 --- a/dana/src/main/res/values-it-rIT/strings.xml +++ b/dana/src/main/res/values-it-rIT/strings.xml @@ -29,6 +29,9 @@ Batteria del micro scarica Occlusione Serbatoio vuoto + Controlla asta meccanica (shaft) + Max basale + Max giornaliero Avviso misurazione glicemia Livello insulina rimanente Bolo perso diff --git a/dana/src/main/res/values-pt-rBR/strings.xml b/dana/src/main/res/values-pt-rBR/strings.xml index 445b5cfe64..d641178465 100644 --- a/dana/src/main/res/values-pt-rBR/strings.xml +++ b/dana/src/main/res/values-pt-rBR/strings.xml @@ -12,9 +12,11 @@ Erro no comando Erro velocidade Transgressão limite insulina - Pedido: %1$.2fU Entregue: %2$.2fU Código Erro: %3$s + Pedido: %1$.2fU Administrado: %2$.2fU Código Erro: %3$s Valor não definido corretamente Coloque o incremento da basal em 0.01 U/h + Repor as informações de emparelhamento? + %1$s\nModelo: %2$02X\nProtocolo: %3$02X\nCódigo: %4$02X A processar acção Habilitar bólus prolongado na bomba Administrado @@ -22,6 +24,7 @@ Firmware bomba não suportado Erro Bomba Bateria fraca + A administrar menos que a taxa de base predefinida Encerrar Bomba Bateria da Bomba Descarregada Oclusão @@ -29,6 +32,7 @@ Alerta medição da glicemia Nível de insulina restante Bólus não administrado + Informações de emparelhamento inválidas. A solicitar novo emparelhamento A obter estado bomba A procurar o estado do bólus prolongado A obter estado bólus @@ -39,7 +43,7 @@ Grande diferença horária:\n A diferença de hora para a bomba é superior a 1.5h.\nPor favor ajuste manualmente a hora na bomba e certifique-se que a leitura do histórico da bomba não provoca problemas.\nSe possível apague o histórico da bomba antes de modificar a hora ou desabilite o loop durante toda a duração de acção da insulina (DIA) depois da ultima entrada no histórico da bomba ou mais um DIA desde o momento da correcção, qual delas seja a que mantenha o loop aberto durante mais tempo. Emparelhe a sua bomba com o seu telefone! Aproximação do limite diário de insulina - A iniciar administração de bolus + A iniciar administração de bólus A aguardar o final do bolus. Restam %1$d seg. A parar basal temp A configurar bólus prolongado @@ -61,6 +65,55 @@ Purgar Opções do utilizador Formato hora + Botão rolamento + Sinal ao pressionar botão + Alarme + Som + Vibrar + Ambos + LCD na hora [segundos] + Luz de fundo na hora [segundos] + Unidades de Glicose + Desligar [horas] + Reservatório baixo [Unidades] + Gravar opções para a bomba + Integração para bombas DANA Diabecare R + Integração para bombas DANA Diabecare R Coreanas + Integração para as bombas DANA Diabecare R com firmware actualizado + DANA + Nenhum dispositivo bluetooth encontrado + Dispositivo seleccionado não foi encontrado + Mudar de modo U/d para U/h na bomba + DanaR Coreana + DanaR + Controlador bomba corrigido + DanaRv2 + Desactivar modo EasyUI na bomba + Não foi possível configurar o perfil de basal + Estado Bluetooth + IOB Bomba + Incremento Basal + Incremento Bólus + Firmware + Configurações da bomba Dana + 12h + 24h + Ligado + Desligado + Dispositivo Bluetooth DanaR + Senha da bomba (apenas v1) + Senha da bomba Usar bólus prolongado por >200%% Visualizar bólus prolongado como %% + Velocidade Bólus + Bomba seleccionada + Registar mudança de reservatório + Adicionar evento \"Mudança de Insulina\" ao careportal quando detectado no histórico + Registar mudança de canula + Adicionar evento \"Mudança Local Bomba\" ao careportal, quando detectado no histórico + PIN1 + PIN2 + Pressione OK na bomba\ne digite os 2 números mostrados\nManter o visor da bomba ligado, pressionando o botão menos até que você termine a digitação do código. + 1: (12 dígitos) + 2: (8 dígitos) diff --git a/dana/src/main/res/values-pt-rPT/strings.xml b/dana/src/main/res/values-pt-rPT/strings.xml index d641178465..2a9b392910 100644 --- a/dana/src/main/res/values-pt-rPT/strings.xml +++ b/dana/src/main/res/values-pt-rPT/strings.xml @@ -29,6 +29,9 @@ Bateria da Bomba Descarregada Oclusão Reservatório vazio + Verificar Eixo + Máx Basal + Máx Diário Alerta medição da glicemia Nível de insulina restante Bólus não administrado diff --git a/dana/src/main/res/values-ru-rRU/strings.xml b/dana/src/main/res/values-ru-rRU/strings.xml index 964feb4428..b62cc03edd 100644 --- a/dana/src/main/res/values-ru-rRU/strings.xml +++ b/dana/src/main/res/values-ru-rRU/strings.xml @@ -29,6 +29,9 @@ батарея помпы разряжена закупорка Резервуар пуст + Проверьте шток помпы + Макс. шаг базала + Максимум в день Предупреждение при измерении уровня СК Уровень оставшегося инсулина Недоставленный болюс diff --git a/dana/src/main/res/values-sk-rSK/strings.xml b/dana/src/main/res/values-sk-rSK/strings.xml index c7cd8251bb..9e6e2cfd8e 100644 --- a/dana/src/main/res/values-sk-rSK/strings.xml +++ b/dana/src/main/res/values-sk-rSK/strings.xml @@ -29,6 +29,9 @@ Batéria v pumpe vybitá Oklúzia Prázdny zásobník + Skontrolovať hriadeľ + Max. bazál + Max. denný Výstraha merania glykémie Zostávajúci inzulín Chýbajúci bolus diff --git a/dana/src/main/res/values-sv-rSE/strings.xml b/dana/src/main/res/values-sv-rSE/strings.xml index 0edf825c1d..94bc25e158 100644 --- a/dana/src/main/res/values-sv-rSE/strings.xml +++ b/dana/src/main/res/values-sv-rSE/strings.xml @@ -29,6 +29,9 @@ Pumpbatteri urladdat Ocklusion Tom reservoar + Kontrollera axel + Max basal + Max daglig Varning om blodsockermätning Återstående mängd insulin Missad bolus diff --git a/dana/src/main/res/values/strings.xml b/dana/src/main/res/values/strings.xml index b0fe53ee25..bf26707ffc 100644 --- a/dana/src/main/res/values/strings.xml +++ b/dana/src/main/res/values/strings.xml @@ -42,6 +42,9 @@ Pump Battery Discharged Occlusion Empty reservoir + Check shaft + Basal max + Daily max Blood sugar measurement alert Remaining insulin level Missed bolus diff --git a/danar/build.gradle b/danar/build.gradle index 83399cc43a..878641c87a 100644 --- a/danar/build.gradle +++ b/danar/build.gradle @@ -53,14 +53,8 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' implementation "androidx.preference:preference-ktx:1.1.1" - implementation "androidx.activity:activity:${activityVersion}" implementation "androidx.activity:activity-ktx:${activityVersion}" - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" - - // remove after conversion to aapslogger - implementation 'org.slf4j:slf4j-api:1.7.30' - // Graphview cannot be upgraded implementation "com.jjoe64:graphview:4.0.1" @@ -74,7 +68,7 @@ dependencies { kapt "com.google.dagger:dagger-compiler:$dagger_version" //RxBus - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" + implementation "io.reactivex.rxjava2:rxandroid:${rxandroid_version}" testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt index 5fffb9cf71..d8d216c16e 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt @@ -1,10 +1,7 @@ package info.nightscout.androidaps.danar.comm import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.dana.DanaPump -import info.nightscout.androidaps.utils.DateUtil import org.joda.time.DateTime import java.util.* @@ -27,10 +24,10 @@ class MsgSettingPumpTime( intFromBuff(bytes, 0, 1) ).millis aapsLogger.debug(LTag.PUMPCOMM, "Pump time: " + dateUtil.dateAndTimeString(time) + " Phone time: " + Date()) - danaPump.pumpTime = time + danaPump.setPumpTime(time) } override fun handleMessageNotReceived() { - danaPump.pumpTime = 0 + danaPump.resetPumpTime() } } \ No newline at end of file diff --git a/danars/build.gradle b/danars/build.gradle index 80a5623e04..4e991b502d 100644 --- a/danars/build.gradle +++ b/danars/build.gradle @@ -52,11 +52,8 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' implementation "androidx.preference:preference-ktx:1.1.1" - implementation "androidx.activity:activity:${activityVersion}" implementation "androidx.activity:activity-ktx:${activityVersion}" - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" - // Graphview cannot be upgraded implementation "com.jjoe64:graphview:4.0.1" @@ -70,7 +67,7 @@ dependencies { kapt "com.google.dagger:dagger-compiler:$dagger_version" //RxBus - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" + implementation "io.reactivex.rxjava2:rxandroid:${rxandroid_version}" testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt index 9280187622..84e0dffa09 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.Profile import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -37,6 +38,7 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) put(DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information(injector)) put(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) + put(DanaRS_Packet_Bolus_Get_24_CIR_CF_Array(injector)) put(DanaRS_Packet_Bolus_Get_Dual_Bolus(injector)) put(DanaRS_Packet_Bolus_Get_Extended_Bolus(injector)) put(DanaRS_Packet_Bolus_Get_Extended_Bolus_State(injector)) @@ -45,6 +47,7 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Bolus_Set_Bolus_Option(injector)) put(DanaRS_Packet_Bolus_Set_Initial_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_CIR_CF_Array(injector)) + put(DanaRS_Packet_Bolus_Set_24_CIR_CF_Array(injector, Profile(injector, null))) put(DanaRS_Packet_Bolus_Set_Dual_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_Extended_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel(injector)) @@ -60,8 +63,10 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Notify_Delivery_Rate_Display(injector)) put(DanaRS_Packet_Notify_Missed_Bolus_Alarm(injector)) put(DanaRS_Packet_Option_Get_Pump_Time(injector)) + put(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) put(DanaRS_Packet_Option_Get_User_Option(injector)) put(DanaRS_Packet_Option_Set_Pump_Time(injector)) + put(DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(injector)) put(DanaRS_Packet_Option_Set_User_Option(injector)) //put(new DanaRS_Packet_History_(injector)); put(DanaRS_Packet_History_Alarm(injector)) diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java index cf10a2d95c..87ff77d0e6 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java @@ -151,6 +151,29 @@ public class DanaRS_Packet { return ret; } + protected static int intFromBuffMsbLsb(byte[] b, int srcStart, int srcLength) { + int ret; + + switch (srcLength) { + case 1: + ret = b[DATA_START + srcStart] & 0x000000FF; + break; + case 2: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 1] & 0x000000FF); + break; + case 3: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 2] & 0x000000FF); + break; + case 4: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 24) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 2] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 3] & 0x000000FF); + break; + default: + ret = -1; + break; + } + return ret; + } + @TargetApi(Build.VERSION_CODES.KITKAT) public static String stringFromBuff(byte[] buff, int offset, int length) { byte[] strbuff = new byte[length]; diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt index d2e8bbc3dd..6c351210be 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt @@ -18,6 +18,8 @@ import info.nightscout.androidaps.danars.encryption.BleEncryption import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import org.joda.time.DateTime +import org.joda.time.DateTimeZone import java.util.* import javax.inject.Inject @@ -34,59 +36,67 @@ open class DanaRS_Packet_APS_History_Events( @Inject lateinit var sp: SP @Inject lateinit var nsUpload: NSUpload - private var year = 0 - private var month = 0 - private var day = 0 - private var hour = 0 - private var min = 0 - private var sec = 0 - init { opCode = BleEncryption.DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS - val cal = GregorianCalendar() if (from > DateUtil.now()) { aapsLogger.debug(LTag.PUMPCOMM, "Asked to load from the future") from = 0 } - if (from != 0L) cal.timeInMillis = from else cal[2000, 0, 1, 0, 0] = 0 - year = cal[Calendar.YEAR] - 1900 - 100 - month = cal[Calendar.MONTH] + 1 - day = cal[Calendar.DAY_OF_MONTH] - hour = cal[Calendar.HOUR_OF_DAY] - min = cal[Calendar.MINUTE] - sec = cal[Calendar.SECOND] - aapsLogger.debug(LTag.PUMPCOMM, "Loading event history from: " + dateUtil.dateAndTimeString(cal.timeInMillis)) + aapsLogger.debug(LTag.PUMPCOMM, "Loading event history from: " + dateUtil.dateAndTimeString(from)) danaPump.historyDoneReceived = false } override fun getRequestParams(): ByteArray { + val date = + if (danaPump.usingUTC) DateTime(from).withZone(DateTimeZone.UTC) + else DateTime(from) val request = ByteArray(6) - request[0] = (year and 0xff).toByte() - request[1] = (month and 0xff).toByte() - request[2] = (day and 0xff).toByte() - request[3] = (hour and 0xff).toByte() - request[4] = (min and 0xff).toByte() - request[5] = (sec and 0xff).toByte() + if (from == 0L) { + request[0] = 0 + request[1] = 1 + request[2] = 1 + request[3] = 0 + request[4] = 0 + request[5] = 0 + } else { + request[0] = (date.year - 2000 and 0xff).toByte() + request[1] = (date.monthOfYear and 0xff).toByte() + request[2] = (date.dayOfMonth and 0xff).toByte() + request[3] = (date.hourOfDay and 0xff).toByte() + request[4] = (date.minuteOfHour and 0xff).toByte() + request[5] = (date.secondOfMinute and 0xff).toByte() + } return request } override fun handleMessage(data: ByteArray) { - val recordCode = intFromBuff(data, 0, 1).toByte() + var recordCode = intFromBuff(data, 0, 1).toByte() // Last record if (recordCode == 0xFF.toByte()) { danaPump.historyDoneReceived = true aapsLogger.debug(LTag.PUMPCOMM, "Last record received") return } - val datetime = dateTimeSecFromBuff(data, 1) // 6 bytes - val param1 = (intFromBuff(data, 7, 1) shl 8 and 0xFF00) + (intFromBuff(data, 8, 1) and 0xFF) - val param2 = (intFromBuff(data, 9, 1) shl 8 and 0xFF00) + (intFromBuff(data, 10, 1) and 0xFF) - val temporaryBasal = TemporaryBasal(injector).date(datetime).source(Source.PUMP).pumpId(datetime) - val extendedBolus = ExtendedBolus(injector).date(datetime).source(Source.PUMP).pumpId(datetime) + val datetime: Long + val param1 = intFromBuffMsbLsb(data, 7, 2) + val param2 = intFromBuffMsbLsb(data, 9, 2) + val pumpId: Long + var id = 0 + if (!danaPump.usingUTC) { + datetime = dateTimeSecFromBuff(data, 1) // 6 bytes + pumpId = datetime + } else { + datetime = intFromBuffMsbLsb(data, 3, 4) * 1000L + recordCode = intFromBuff(data, 2, 1).toByte() + id = intFromBuffMsbLsb(data, 0, 2) // range only 1-2000 + pumpId = datetime shl 16 + id + } + val temporaryBasal = TemporaryBasal(injector).date(datetime).source(Source.PUMP).pumpId(pumpId) + val extendedBolus = ExtendedBolus(injector).date(datetime).source(Source.PUMP).pumpId(pumpId) val status: String when (recordCode.toInt()) { DanaPump.TEMPSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT TEMPSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TEMPSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min") temporaryBasal.percentRate = param1 temporaryBasal.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryTempBasal(temporaryBasal) @@ -94,13 +104,13 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.TEMPSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT TEMPSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime)) + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TEMPSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime)) activePlugin.activeTreatments.addToHistoryTempBasal(temporaryBasal) status = "TEMPSTOP " + dateUtil.timeString(datetime) } DanaPump.EXTENDEDSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT EXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT EXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") extendedBolus.insulin = param1 / 100.0 extendedBolus.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) @@ -108,7 +118,7 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.EXTENDEDSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT EXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT EXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) status = "EXTENDEDSTOP " + dateUtil.timeString(datetime) } @@ -121,7 +131,7 @@ open class DanaRS_Packet_APS_History_Events( detailedBolusInfo.pumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") status = "BOLUS " + dateUtil.timeString(datetime) } @@ -133,12 +143,12 @@ open class DanaRS_Packet_APS_History_Events( detailedBolusInfo.pumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") status = "DUALBOLUS " + dateUtil.timeString(datetime) } DanaPump.DUALEXTENDEDSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT DUALEXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT DUALEXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") extendedBolus.insulin = param1 / 100.0 extendedBolus.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) @@ -146,37 +156,37 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.DUALEXTENDEDSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) status = "DUALEXTENDEDSTOP " + dateUtil.timeString(datetime) } DanaPump.SUSPENDON -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT SUSPENDON (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT SUSPENDON (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") status = "SUSPENDON " + dateUtil.timeString(datetime) } DanaPump.SUSPENDOFF -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT SUSPENDOFF (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT SUSPENDOFF (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") status = "SUSPENDOFF " + dateUtil.timeString(datetime) } DanaPump.REFILL -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT REFILL (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT REFILL (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") if (sp.getBoolean(R.string.key_rs_loginsulinchange, true)) nsUpload.generateCareportalEvent(CareportalEvent.INSULINCHANGE, datetime, resourceHelper.gs(R.string.danarspump)) status = "REFILL " + dateUtil.timeString(datetime) } DanaPump.PRIME -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PRIME (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PRIME (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") if (sp.getBoolean(R.string.key_rs_logcanulachange, true)) nsUpload.generateCareportalEvent(CareportalEvent.SITECHANGE, datetime, resourceHelper.gs(R.string.danarspump)) status = "PRIME " + dateUtil.timeString(datetime) } DanaPump.PROFILECHANGE -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PROFILECHANGE (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + param2 / 100.0 + "U/h") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PROFILECHANGE (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + param2 / 100.0 + "U/h") status = "PROFILECHANGE " + dateUtil.timeString(datetime) } @@ -187,17 +197,23 @@ open class DanaRS_Packet_APS_History_Events( emptyCarbsInfo.source = Source.PUMP emptyCarbsInfo.pumpId = datetime val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g") status = "CARBS " + dateUtil.timeString(datetime) } DanaPump.PRIMECANNULA -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PRIMECANNULA(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PRIMECANNULA(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") status = "PRIMECANNULA " + dateUtil.timeString(datetime) } - else -> { - aapsLogger.debug(LTag.PUMPCOMM, "Event: " + recordCode + " " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2) + DanaPump.TIMECHANGE -> { + val oldDateTime = intFromBuffMsbLsb(data, 7, 4) * 1000L + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TIMECHANGE(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Previous: " + dateUtil.dateAndTimeString(oldDateTime)) + status = "TIMECHANGE " + dateUtil.timeString(datetime) + } + + else -> { + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "Event: " + recordCode + " " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2) status = "UNKNOWN " + dateUtil.timeString(datetime) } } diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt index 67d4643064..802eb09b56 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt @@ -1,9 +1,12 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danars.encryption.BleEncryption -import java.util.* +import info.nightscout.androidaps.logging.LTag +import org.joda.time.DateTime +import org.joda.time.DateTimeZone +import javax.inject.Inject class DanaRS_Packet_APS_Set_Event_History( injector: HasAndroidInjector, @@ -13,29 +16,26 @@ class DanaRS_Packet_APS_Set_Event_History( private var param2: Int ) : DanaRS_Packet(injector) { + @Inject lateinit var danaPump: DanaPump + init { opCode = BleEncryption.DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY - if ((packetType == info.nightscout.androidaps.dana.DanaPump.CARBS || packetType == info.nightscout.androidaps.dana.DanaPump.BOLUS) && param1 <= 0) this.param1 = 0 + if ((packetType == DanaPump.CARBS || packetType == DanaPump.BOLUS) && param1 <= 0) this.param1 = 0 aapsLogger.debug(LTag.PUMPCOMM, "Set history entry: " + dateUtil.dateAndTimeString(time) + " type: " + packetType + " param1: " + param1 + " param2: " + param2) } override fun getRequestParams(): ByteArray { - val cal = GregorianCalendar() - cal.timeInMillis = time - val year = cal[Calendar.YEAR] - 1900 - 100 - val month = cal[Calendar.MONTH] + 1 - val day = cal[Calendar.DAY_OF_MONTH] - val hour = cal[Calendar.HOUR_OF_DAY] - val min = cal[Calendar.MINUTE] - val sec = cal[Calendar.SECOND] + val date = + if (danaPump.usingUTC) DateTime(time).withZone(DateTimeZone.UTC) + else DateTime(time) val request = ByteArray(11) request[0] = (packetType and 0xff).toByte() - request[1] = (year and 0xff).toByte() - request[2] = (month and 0xff).toByte() - request[3] = (day and 0xff).toByte() - request[4] = (hour and 0xff).toByte() - request[5] = (min and 0xff).toByte() - request[6] = (sec and 0xff).toByte() + request[1] = (date.year - 2000 and 0xff).toByte() + request[2] = (date.monthOfYear and 0xff).toByte() + request[3] = (date.dayOfMonth and 0xff).toByte() + request[4] = (date.hourOfDay and 0xff).toByte() + request[5] = (date.minuteOfHour and 0xff).toByte() + request[6] = (date.secondOfMinute and 0xff).toByte() request[7] = (param1 ushr 8 and 0xff).toByte() request[8] = (param1 and 0xff).toByte() request[9] = (param2 ushr 8 and 0xff).toByte() diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt new file mode 100644 index 0000000000..5f8be76b2e --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import javax.inject.Inject + +class DanaRS_Packet_Bolus_Get_24_CIR_CF_Array( + injector: HasAndroidInjector +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__GET_24_CIR_CF_ARRAY + aapsLogger.debug(LTag.PUMPCOMM, "New message") + } + + override fun handleMessage(data: ByteArray) { + danaPump.units = byteArrayToInt(getBytes(data, DATA_START, 1)) + for (i in 0 .. 23) { + val cf = byteArrayToInt(getBytes(data, DATA_START + 1 + 2 * i, 2)).toDouble() + val cir = if (danaPump.units == DanaPump.UNITS_MGDL) + byteArrayToInt(getBytes(data, DATA_START + 1 + 48 + 2 * i, 2)).toDouble() + else + byteArrayToInt(getBytes(data, DATA_START + 1 + 48 + 2 * i, 2)) / 100.0 + danaPump.cir24[i] = cir + danaPump.cf24[i] = cf + aapsLogger.debug(LTag.PUMPCOMM, "$i: CIR: $cir CF: $cf") + } + if (danaPump.units < 0 || danaPump.units > 1) failed = true + aapsLogger.debug(LTag.PUMPCOMM, "Pump units: " + if (danaPump.units == DanaPump.UNITS_MGDL) "MGDL" else "MMOL") + } + + override fun getFriendlyName(): String { + return "BOLUS__GET_24_ CIR_CF_ARRAY" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.kt index d6d7801acc..7cc2d3aa65 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.kt @@ -1,10 +1,11 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danars.encryption.BleEncryption +import info.nightscout.androidaps.logging.LTag import org.joda.time.DateTime +import org.joda.time.DateTimeZone import javax.inject.Inject class DanaRS_Packet_Bolus_Get_Step_Bolus_Information( @@ -24,7 +25,8 @@ class DanaRS_Packet_Bolus_Get_Step_Bolus_Information( danaPump.initialBolusAmount = intFromBuff(data, 2, 2) / 100.0 val hours = intFromBuff(data, 4, 1) val minutes = intFromBuff(data, 5, 1) - danaPump.lastBolusTime = DateTime.now().withHourOfDay(hours).withMinuteOfHour(minutes).millis + if (danaPump.usingUTC) danaPump.lastBolusTime = DateTime.now().withZone(DateTimeZone.UTC).withHourOfDay(hours).withMinuteOfHour(minutes).millis + else danaPump.lastBolusTime = DateTime.now().withHourOfDay(hours).withMinuteOfHour(minutes).millis danaPump.lastBolusAmount = intFromBuff(data, 6, 2) / 100.0 danaPump.maxBolus = intFromBuff(data, 8, 2) / 100.0 danaPump.bolusStep = intFromBuff(data, 10, 1) / 100.0 diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt new file mode 100644 index 0000000000..7a0e925ab6 --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt @@ -0,0 +1,52 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.logging.LTag +import javax.inject.Inject + +class DanaRS_Packet_Bolus_Set_24_CIR_CF_Array( + injector: HasAndroidInjector, + private val profile: Profile? +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_24_CIR_CF_ARRAY + aapsLogger.debug(LTag.PUMPCOMM, "New message") + } + + override fun getRequestParams(): ByteArray { + val request = ByteArray(96) + profile ?: return request // profile is null only in hash table + val cfStart = 24 * 2 + for (i in 0..23) { + var isf = profile.getIsfMgdlTimeFromMidnight(i * 3600) + if (danaPump.units == DanaPump.UNITS_MMOL) isf *= 10 + val ic = profile.getIcTimeFromMidnight(i * 3600) * 100 + request[2 * i] = (isf.toInt() and 0xff).toByte() + request[2 * i] = (isf.toInt() ushr 8 and 0xff).toByte() + request[cfStart + 2 * i] = (ic.toInt() and 0xff).toByte() + request[cfStart + 2 * i] = (ic.toInt() ushr 8 and 0xff).toByte() + } + return request + } + + override fun handleMessage(data: ByteArray) { + val result = intFromBuff(data, 0, 1) + if (result == 0) { + aapsLogger.debug(LTag.PUMPCOMM, "Result OK") + failed = false + } else { + aapsLogger.error("Result Error: $result") + failed = true + } + } + + override fun getFriendlyName(): String { + return "BOLUS__SET_24_CIR_CF_ARRAY" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_General_Get_More_Information.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_General_Get_More_Information.kt index 4f9d15410e..0d110deb71 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_General_Get_More_Information.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_General_Get_More_Information.kt @@ -5,6 +5,7 @@ import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danars.encryption.BleEncryption import org.joda.time.DateTime +import org.joda.time.DateTimeZone import javax.inject.Inject class DanaRS_Packet_General_Get_More_Information( @@ -30,7 +31,8 @@ class DanaRS_Packet_General_Get_More_Information( // val remainRate = intFromBuff(data, 7, 2) / 100.0 val hours = intFromBuff(data, 9, 1) val minutes = intFromBuff(data, 10, 1) - danaPump.lastBolusTime = DateTime.now().withHourOfDay(hours).withMinuteOfHour(minutes).millis + if (danaPump.usingUTC) danaPump.lastBolusTime = DateTime.now().withZone(DateTimeZone.UTC).withHourOfDay(hours).withMinuteOfHour(minutes).millis + else danaPump.lastBolusTime = DateTime.now().withHourOfDay(hours).withMinuteOfHour(minutes).millis danaPump.lastBolusAmount = intFromBuff(data, 11, 2) / 100.0 // On DanaRS DailyUnits can't be more than 160 if (danaPump.dailyTotalUnits > 160) failed = true diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt index c5a0b40ceb..538d9b0bf7 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt @@ -193,11 +193,15 @@ abstract class DanaRS_Packet_History_( val datetimewihtsec = DateTime(2000 + historyYear, historyMonth, historyDay, historyHour, historyMinute, historySecond) danaRHistoryRecord.recordDate = datetimewihtsec.millis var strAlarm = "None" - when (paramByte8.toInt()) { - 67 -> strAlarm = "Check" - 79 -> strAlarm = "Occlusion" - 66 -> strAlarm = "Low Battery" - 83 -> strAlarm = "Shutdown" + when (paramByte8) { + 'P'.toByte() -> strAlarm = "Basal Compare" + 'R'.toByte() -> strAlarm = "Empty Reservoir" + 'C'.toByte() -> strAlarm = "Check" + 'O'.toByte() -> strAlarm = "Occlusion" + 'M'.toByte() -> strAlarm = "Basal max" + 'D'.toByte() -> strAlarm = "Daily max" + 'B'.toByte() -> strAlarm = "Low Battery" + 'S'.toByte() -> strAlarm = "Shutdown" } danaRHistoryRecord.recordAlarm = strAlarm danaRHistoryRecord.recordValue = value * 0.01 diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt index fe94033ea8..f397179185 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt @@ -41,12 +41,18 @@ class DanaRS_Packet_Notify_Alarm( errorString = resourceHelper.gs(R.string.lowbattery) 0x06 -> // Basal Compare errorString = resourceHelper.gs(R.string.basalcompare) - 0x09 -> // Empty Reservoir - errorString = resourceHelper.gs(R.string.emptyreservoir) 0x07, 0xFF -> // Blood sugar measurement alert errorString = resourceHelper.gs(R.string.bloodsugarmeasurementalert) 0x08, 0xFE -> // Remaining insulin level errorString = resourceHelper.gs(R.string.remaininsulinalert) + 0x09 -> // Empty Reservoir + errorString = resourceHelper.gs(R.string.emptyreservoir) + 0x0A -> // Check shaft + errorString = resourceHelper.gs(R.string.checkshaft) + 0x0B -> // Basal MAX + errorString = resourceHelper.gs(R.string.basalmax) + 0x0C -> // Daily MAX + errorString = resourceHelper.gs(R.string.dailymax) 0xFD -> // Blood sugar check miss alarm errorString = resourceHelper.gs(R.string.missedbolus) } diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt index 1b1daf30b7..11659879e3 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt @@ -19,31 +19,19 @@ class DanaRS_Packet_Option_Get_Pump_Time( } override fun handleMessage(data: ByteArray) { - var dataIndex = DATA_START - var dataSize = 1 - val year = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val month = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val day = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val hour = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val min = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val sec = byteArrayToInt(getBytes(data, dataIndex, dataSize)) + val year = byteArrayToInt(getBytes(data, DATA_START, 1)) + val month = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) + val day = byteArrayToInt(getBytes(data, DATA_START + 2, 1)) + val hour = byteArrayToInt(getBytes(data, DATA_START + 3, 1)) + val min = byteArrayToInt(getBytes(data, DATA_START + 4, 1)) + val sec = byteArrayToInt(getBytes(data, DATA_START + 5, 1)) val time = DateTime(2000 + year, month, day, hour, min, sec) - danaPump.pumpTime = time.millis + danaPump.setPumpTime(time.millis) aapsLogger.debug(LTag.PUMPCOMM, "Pump time " + dateUtil.dateAndTimeString(time.millis)) } override fun handleMessageNotReceived() { - danaPump.pumpTime = 0 + danaPump.resetPumpTime() } override fun getFriendlyName(): String { diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt new file mode 100644 index 0000000000..9f35fcb82c --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import org.joda.time.DateTime +import javax.inject.Inject + +class DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone( + injector: HasAndroidInjector +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_OPTION__GET_PUMP_UTC_AND_TIME_ZONE + aapsLogger.debug(LTag.PUMPCOMM, "Requesting pump UTC time") + } + + override fun handleMessage(data: ByteArray) { + val year = byteArrayToInt(getBytes(data, DATA_START, 1)) + val month = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) + val day = byteArrayToInt(getBytes(data, DATA_START + 2, 1)) + val hour = byteArrayToInt(getBytes(data, DATA_START + 3, 1)) + val min = byteArrayToInt(getBytes(data, DATA_START + 4, 1)) + val sec = byteArrayToInt(getBytes(data, DATA_START + 5, 1)) + val zoneOffset = getBytes(data, DATA_START + 6, 1)[0].toInt() + val time = DateTime(2000 + year, month, day, hour, min, sec) + danaPump.setPumpTime(time.millis, zoneOffset) + aapsLogger.debug(LTag.PUMPCOMM, "Pump time ${dateUtil.dateAndTimeString(danaPump.getPumpTime())} ZoneOffset: $zoneOffset") + } + + override fun handleMessageNotReceived() { + danaPump.resetPumpTime() + } + + override fun getFriendlyName(): String { + return "OPTION__GET_PUMP_UTC_AND_TIMEZONE" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt new file mode 100644 index 0000000000..3fbf79a388 --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt @@ -0,0 +1,49 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.danars.encryption.BleEncryption +import org.joda.time.DateTime +import org.joda.time.DateTimeZone + +class DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone( + injector: HasAndroidInjector, + private var time: Long = 0, + private var zoneOffset: Int = 0 +) : DanaRS_Packet(injector) { + + var error = 0 + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_OPTION__SET_PUMP_UTC_AND_TIME_ZONE + aapsLogger.debug(LTag.PUMPCOMM, "Setting UTC pump time ${dateUtil.dateAndTimeString(time)} ZoneOffset: $zoneOffset") + } + + override fun getRequestParams(): ByteArray { + val date = DateTime(time).withZone(DateTimeZone.UTC) + val request = ByteArray(7) + request[0] = (date.year - 2000 and 0xff).toByte() + request[1] = (date.monthOfYear and 0xff).toByte() + request[2] = (date.dayOfMonth and 0xff).toByte() + request[3] = (date.hourOfDay and 0xff).toByte() + request[4] = (date.minuteOfHour and 0xff).toByte() + request[5] = (date.secondOfMinute and 0xff).toByte() + request[6] = zoneOffset.toByte() + return request + } + + override fun handleMessage(data: ByteArray) { + val result = intFromBuff(data, 0, 1) + if (result == 0) { + aapsLogger.debug(LTag.PUMPCOMM, "Result OK") + failed = false + } else { + aapsLogger.error("Result Error: $result") + failed = true + } + } + + override fun getFriendlyName(): String { + return "OPTION__SET_PUMP_UTC_AND_TIMEZONE" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt b/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt index cb7a0dcfcd..f239525f85 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt @@ -25,6 +25,7 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Calculation_Information(): DanaRS_Packet_Bolus_Get_Calculation_Information @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information(): DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_CIR_CF_Array(): DanaRS_Packet_Bolus_Get_CIR_CF_Array + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_24_CIR_CF_Array(): DanaRS_Packet_Bolus_Get_24_CIR_CF_Array @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Dual_Bolus(): DanaRS_Packet_Bolus_Get_Dual_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Extended_Bolus(): DanaRS_Packet_Bolus_Get_Extended_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Extended_Bolus_State(): DanaRS_Packet_Bolus_Get_Extended_Bolus_State @@ -33,6 +34,7 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Bolus_Option(): DanaRS_Packet_Bolus_Set_Bolus_Option @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Initial_Bolus(): DanaRS_Packet_Bolus_Set_Initial_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_CIR_CF_Array(): DanaRS_Packet_Bolus_Set_CIR_CF_Array + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_24_CIR_CF_Array(): DanaRS_Packet_Bolus_Set_24_CIR_CF_Array @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Dual_Bolus(): DanaRS_Packet_Bolus_Set_Dual_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Extended_Bolus(): DanaRS_Packet_Bolus_Set_Extended_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel(): DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel @@ -76,4 +78,6 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_APS_Set_Event_History(): DanaRS_Packet_APS_Set_Event_History @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_General_Get_Shipping_Version(): DanaRS_Packet_General_Get_Shipping_Version @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Review_Get_Pump_Dec_Ratio(): DanaRS_Packet_Review_Get_Pump_Dec_Ratio + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(): DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(): DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone } \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java b/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java index 418881d6df..fbb441e223 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java +++ b/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java @@ -75,6 +75,8 @@ public class BleEncryption { public static final int DANAR_PACKET__OPCODE_BOLUS__SET_CIR_CF_ARRAY = 0x4F; public static final int DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_OPTION = 0x50; public static final int DANAR_PACKET__OPCODE_BOLUS__SET_BOLUS_OPTION = 0x51; + public static final int DANAR_PACKET__OPCODE_BOLUS__GET_24_CIR_CF_ARRAY = 0x52; + public static final int DANAR_PACKET__OPCODE_BOLUS__SET_24_CIR_CF_ARRAY = 0x53; public static final int DANAR_PACKET__OPCODE_BASAL__SET_TEMPORARY_BASAL = 0x60; public static final int DANAR_PACKET__OPCODE_BASAL__TEMPORARY_BASAL_STATE = 0x61; @@ -104,6 +106,12 @@ public class BleEncryption { // Easy Mode public static final int DANAR_PACKET__OPCODE_OPTION__GET_EASY_MENU_OPTION = 0x74; public static final int DANAR_PACKET__OPCODE_OPTION__SET_EASY_MENU_OPTION = 0x75; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_EASY_MENU_STATUS = 0x76; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_EASY_MENU_STATUS = 0x77; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_PUMP_UTC_AND_TIME_ZONE = 0x78; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_PUMP_UTC_AND_TIME_ZONE = 0x79; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_PUMP_TIME_ZONE = 0x7A; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_PUMP_TIME_ZONE = 0x7B; public static final int DANAR_PACKET__OPCODE_ETC__SET_HISTORY_SAVE = 0xE0; public static final int DANAR_PACKET__OPCODE_ETC__KEEP_CONNECTION = 0xFF; diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt b/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt index ad5023a849..469eb2188d 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt @@ -43,6 +43,9 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers +import org.joda.time.DateTime +import org.joda.time.DateTimeZone +import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.abs import kotlin.math.min @@ -110,6 +113,21 @@ class DanaRSService : DaggerService() { fun readPumpStatus() { try { + val now = System.currentTimeMillis() + val pump = activePlugin.activePump + if (danaPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized) { + rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) + sendMessage(DanaRS_Packet_General_Get_Shipping_Information(injector)) // serial no + sendMessage(DanaRS_Packet_General_Get_Pump_Check(injector)) // firmware + sendMessage(DanaRS_Packet_Basal_Get_Profile_Number(injector)) + sendMessage(DanaRS_Packet_Bolus_Get_Bolus_Option(injector)) // isExtendedEnabled + sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal + sendMessage(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) // target + if (danaPump.profile24) sendMessage(DanaRS_Packet_Bolus_Get_24_CIR_CF_Array(injector)) + else sendMessage(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) + sendMessage(DanaRS_Packet_Option_Get_User_Option(injector)) // Getting user options + danaPump.lastSettingsRead = now + } rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpstatus))) sendMessage(DanaRS_Packet_General_Initial_Screen_Information(injector)) rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingextendedbolusstatus))) @@ -120,7 +138,6 @@ class DanaRSService : DaggerService() { sendMessage(DanaRS_Packet_Basal_Get_Temporary_Basal_State(injector)) danaPump.lastConnection = System.currentTimeMillis() val profile = profileFunction.getProfile() - val pump = activePlugin.activePump if (profile != null && abs(danaPump.currentBasal - profile.basal) >= pump.pumpDescription.basalStep) { rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal @@ -129,9 +146,10 @@ class DanaRSService : DaggerService() { } } rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumptime))) - sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) - var timeDiff = (danaPump.pumpTime - System.currentTimeMillis()) / 1000L - if (danaPump.pumpTime == 0L) { + if (danaPump.usingUTC) sendMessage(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) + else sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) + var timeDiff = (danaPump.getPumpTime() - System.currentTimeMillis()) / 1000L + if (danaPump.getPumpTime() == 0L) { // initial handshake was not successful // de-initialize pump danaPump.reset() @@ -139,19 +157,6 @@ class DanaRSService : DaggerService() { rxBus.send(EventInitializationChanged()) return } - val now = System.currentTimeMillis() - if (danaPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized) { - rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) - sendMessage(DanaRS_Packet_General_Get_Shipping_Information(injector)) // serial no - sendMessage(DanaRS_Packet_General_Get_Pump_Check(injector)) // firmware - sendMessage(DanaRS_Packet_Basal_Get_Profile_Number(injector)) - sendMessage(DanaRS_Packet_Bolus_Get_Bolus_Option(injector)) // isExtendedEnabled - sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal - sendMessage(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) // target - sendMessage(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) - sendMessage(DanaRS_Packet_Option_Get_User_Option(injector)) // Getting user options - danaPump.lastSettingsRead = now - } aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds") if (abs(timeDiff) > 3) { if (abs(timeDiff) > 60 * 60 * 1.5) { @@ -170,15 +175,22 @@ class DanaRSService : DaggerService() { rxBus.send(EventInitializationChanged()) return } else { - if (danaPump.protocol >= 6) { + if (danaPump.usingUTC) { + val tz = DateTimeZone.getDefault() + val instant = DateTime.now().millis + val offsetInMilliseconds = tz.getOffset(instant).toLong() + val hours = TimeUnit.MILLISECONDS.toHours(offsetInMilliseconds).toInt() + sendMessage(DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(injector, DateUtil.now(), hours)) + } else if (danaPump.protocol >= 6) { // can set seconds sendMessage(DanaRS_Packet_Option_Set_Pump_Time(injector, DateUtil.now())) } else { waitForWholeMinute() // Dana can set only whole minute // add 10sec to be sure we are over minute (will be cut off anyway) sendMessage(DanaRS_Packet_Option_Set_Pump_Time(injector, DateUtil.now() + T.secs(10).msecs())) } - sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) - timeDiff = (danaPump.pumpTime - System.currentTimeMillis()) / 1000L + if (danaPump.usingUTC) sendMessage(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) + else sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) + timeDiff = (danaPump.getPumpTime() - System.currentTimeMillis()) / 1000L aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds") } } @@ -227,7 +239,7 @@ class DanaRSService : DaggerService() { } fun setUserSettings(): PumpEnactResult { - sendMessage(DanaRS_Packet_Option_Get_User_Option(injector)) + sendMessage(DanaRS_Packet_Option_Set_User_Option(injector)) return PumpEnactResult(injector).success(true) } diff --git a/wear/build.gradle b/wear/build.gradle index fbfeeccfbc..94441d025d 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -124,7 +124,7 @@ dependencies { implementation('com.github.lecho:hellocharts-library:1.5.8@aar') testImplementation 'junit:junit:4.13' - testImplementation 'org.json:json:20190722' + testImplementation 'org.json:json:20200518' testImplementation ("org.mockito:mockito-core:2.8.47") { exclude group: 'net.bytebuddy', module: 'byte-buddy' exclude group: 'net.bytebuddy', module: 'byte-buddy-android' diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index e8e48e3f51..3c114cb59c 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -1,5 +1,5 @@ - - +