diff --git a/app/build.gradle b/app/build.gradle index 858fe354fc..783561a599 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -225,8 +225,8 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.google.android.gms:play-services-wearable:17.0.0' - implementation 'com.google.firebase:firebase-core:17.2.0' - implementation("com.crashlytics.sdk.android:crashlytics:2.9.9@aar") { + implementation 'com.google.firebase:firebase-core:17.2.1' + implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') { transitive = true; } @@ -234,11 +234,11 @@ dependencies { implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.percentlayout:percentlayout:1.0.0' - implementation "com.wdullaer:materialdatetimepicker:2.3.0" + implementation 'com.wdullaer:materialdatetimepicker:4.2.3' implementation "io.reactivex.rxjava2:rxandroid:2.1.1" @@ -247,11 +247,11 @@ dependencies { implementation("com.github.tony19:logback-android-classic:1.1.1-6") { exclude group: "com.google.android", module: "android" } - implementation "org.apache.commons:commons-lang3:3.7" - implementation "org.slf4j:slf4j-api:1.7.21" + implementation "org.apache.commons:commons-lang3:3.9" + implementation "org.slf4j:slf4j-api:1.7.29" // Graphview cannot be upgraded implementation "com.jjoe64:graphview:4.0.1" - implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1" + implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.2.2" implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar") implementation 'com.madgag.spongycastle:core:1.58.0.0' @@ -263,24 +263,23 @@ dependencies { // excluding org.json which is provided by Android exclude group: "org.json", module: "json" } - implementation "com.google.code.gson:gson:2.8.5" + implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.guava:guava:24.1-jre" - implementation "net.danlew:android.joda:2.9.9.1" - implementation "uk.com.robust-it:cloning:1.9.9" + implementation "net.danlew:android.joda:2.10.3" - implementation 'org.mozilla:rhino:1.7.7.2' + implementation 'org.mozilla:rhino:1.7.11' implementation 'com.github.DavidProdinger:weekdays-selector:1.1.0' testImplementation "junit:junit:4.12" - testImplementation "org.json:json:20140107" + testImplementation "org.json:json:20190722" testImplementation "org.mockito:mockito-core:2.8.47" testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}" testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}" testImplementation "org.powermock:powermock-module-junit4-rule:${powermockVersion}" testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}" - testImplementation "joda-time:joda-time:2.9.9" + testImplementation "joda-time:joda-time:2.10.5" testImplementation("com.google.truth:truth:0.39") { exclude group: "com.google.guava", module: "guava" } @@ -300,11 +299,11 @@ dependencies { // new for tidepool - implementation 'com.squareup.okhttp3:okhttp:3.10.0' - implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' - implementation "com.squareup.retrofit2:retrofit:2.4.0" - implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0" - implementation "com.squareup.retrofit2:converter-gson:2.4.0" + implementation 'com.squareup.okhttp3:okhttp:4.2.2' + implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2' + implementation "com.squareup.retrofit2:retrofit:2.6.2" + implementation "com.squareup.retrofit2:adapter-rxjava2:2.6.2" + implementation "com.squareup.retrofit2:converter-gson:2.6.2" } diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 64c2656086..c383d039ed 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -37,12 +37,10 @@ import com.joanzapata.iconify.fonts.FontAwesomeModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.activities.AgreementActivity; import info.nightscout.androidaps.activities.HistoryBrowseActivity; import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.activities.PreferencesActivity; import info.nightscout.androidaps.activities.SingleFragmentActivity; -import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRebuildTabs; @@ -51,7 +49,6 @@ import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.setupwizard.SetupWizardActivity; @@ -59,7 +56,6 @@ import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.androidaps.utils.AndroidPermission; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.LocaleHelper; -import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.SP; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -141,11 +137,9 @@ public class MainActivity extends NoSplashAppCompatActivity { .subscribe(this::processPreferenceChange, FabricPrivacy::logException) ); - if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) { + if (!SP.getBoolean(R.string.key_setupwizard_processed, false) || !SP.contains(R.string.key_units)) { Intent intent = new Intent(this, SetupWizardActivity.class); startActivity(intent); - } else { - checkEula(); } AndroidPermission.notifyForStoragePermission(this); @@ -237,20 +231,8 @@ public class MainActivity extends NoSplashAppCompatActivity { } } - private void checkEula() { - //SP.removeBoolean(R.string.key_i_understand); - boolean IUnderstand = SP.getBoolean(R.string.key_i_understand, false); - if (!IUnderstand) { - Intent intent = new Intent(getApplicationContext(), AgreementActivity.class); - startActivity(intent); - finish(); - } - } - private void doMigrations() { - checkUpgradeToProfileTarget(); - // guarantee that the unreachable threshold is at least 30 and of type String // Added in 1.57 at 21.01.2018 int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30); @@ -260,26 +242,6 @@ public class MainActivity extends NoSplashAppCompatActivity { } - private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future - boolean oldKeyExists = SP.contains("openapsma_min_bg"); - if (oldKeyExists) { - Profile profile = ProfileFunctions.getInstance().getProfile(); - String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d); - String newRange = ""; - if (profile != null) { - newRange = profile.getTargetLow() + " - " + profile.getTargetHigh(); - } - String message = "Target range is changed in current version.\n\nIt's not taken from preferences but from profile.\n\n!!! REVIEW YOUR SETTINGS !!!"; - message += "\n\nOld settings: " + oldRange; - message += "\nProfile settings: " + newRange; - OKDialog.show(this, "Target range change", message, () -> { - SP.remove("openapsma_min_bg"); - SP.remove("openapsma_max_bg"); - SP.remove("openapsma_target_bg"); - }); - } - } - @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 785aa84c38..11d8351b9b 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -59,7 +59,6 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlu import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin; import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin; -import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin; import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin; import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; @@ -195,8 +194,7 @@ public class MainApp extends Application { if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin()); if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin()); pluginsList.add(NSProfilePlugin.getPlugin()); - if (!Config.NSCLIENT) pluginsList.add(SimpleProfilePlugin.getPlugin()); - if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.getPlugin()); + if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.INSTANCE); pluginsList.add(TreatmentsPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(SafetyPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(VersionCheckerPlugin.INSTANCE); diff --git a/app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java deleted file mode 100644 index d3792bbad5..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java +++ /dev/null @@ -1,44 +0,0 @@ -package info.nightscout.androidaps.activities; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; - -import info.nightscout.androidaps.MainActivity; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.utils.SP; - -public class AgreementActivity extends NoSplashActivity { - boolean IUnderstand; - CheckBox agreeCheckBox; - Button saveButton; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_agreement); - IUnderstand = SP.getBoolean(R.string.key_i_understand, false); - setContentView(R.layout.activity_agreement); - agreeCheckBox = (CheckBox)findViewById(R.id.agreementCheckBox); - agreeCheckBox.setChecked(IUnderstand); - saveButton = (Button)findViewById(R.id.agreementSaveButton); - addListenerOnButton(); - } - - public void addListenerOnButton() { - saveButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - - SP.putBoolean(R.string.key_i_understand, agreeCheckBox.isChecked()); - - Intent intent = new Intent(getApplicationContext(), MainActivity.class); - startActivity(intent); - finish(); - } - - }); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java index 79f3fbf4d4..c0f654bbbb 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java @@ -45,7 +45,7 @@ import info.nightscout.androidaps.utils.T; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; -public class HistoryBrowseActivity extends NoSplashActivity { +public class HistoryBrowseActivity extends NoSplashAppCompatActivity { private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class); private CompositeDisposable disposable = new CompositeDisposable(); @@ -150,7 +150,7 @@ public class HistoryBrowseActivity extends NoSplashActivity { ); dpd.setThemeDark(true); dpd.dismissOnPause(true); - dpd.show(getFragmentManager(), "Datepickerdialog"); + dpd.show(getSupportFragmentManager(), "Datepickerdialog"); }); bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); @@ -231,9 +231,8 @@ public class HistoryBrowseActivity extends NoSplashActivity { noProfile.setVisibility(View.GONE); } - final String units = profile.getUnits(); - final double lowLine = OverviewPlugin.INSTANCE.determineLowLine(units); - final double highLine = OverviewPlugin.INSTANCE.determineHighLine(units); + final double lowLine = OverviewPlugin.INSTANCE.determineLowLine(); + final double highLine = OverviewPlugin.INSTANCE.determineHighLine(); buttonDate.setText(DateUtil.dateAndTimeString(start)); buttonZoom.setText(String.valueOf(rangeToDisplay)); diff --git a/app/src/main/java/info/nightscout/androidaps/activities/NoSplashActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/NoSplashActivity.kt deleted file mode 100644 index 0b7af2bd1d..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/activities/NoSplashActivity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package info.nightscout.androidaps.activities - -import android.app.Activity -import android.os.Bundle - -import info.nightscout.androidaps.R - -open class NoSplashActivity : Activity() { - public override fun onCreate(savedInstanceState: Bundle?) { - setTheme(R.style.AppTheme_NoActionBar) - super.onCreate(savedInstanceState) - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/activities/NoSplashAppCompatActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/NoSplashAppCompatActivity.kt index e4c8027cd5..3f59cd56ef 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/NoSplashAppCompatActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/NoSplashAppCompatActivity.kt @@ -1,12 +1,18 @@ package info.nightscout.androidaps.activities +import android.content.Context import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import info.nightscout.androidaps.R +import info.nightscout.androidaps.utils.LocaleHelper open class NoSplashAppCompatActivity : AppCompatActivity() { public override fun onCreate(savedInstanceState: Bundle?) { setTheme(R.style.AppTheme_NoActionBar) super.onCreate(savedInstanceState) } + + public override fun attachBaseContext(newBase: Context) { + super.attachBaseContext(LocaleHelper.wrap(newBase)) + } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java index 0e93a47151..c0dbf43527 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.activities; +import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.EditTextPreference; @@ -10,9 +11,12 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.preference.PreferenceManager; +import java.util.Arrays; + import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRebuildTabs; import info.nightscout.androidaps.interfaces.PluginBase; @@ -44,8 +48,10 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin; +import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.SafeParse; public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { MyPreferenceFragment myPreferenceFragment; @@ -62,23 +68,49 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); } + @Override + public void attachBaseContext(Context newBase) { + super.attachBaseContext(LocaleHelper.INSTANCE.wrap(newBase)); + } + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { RxBus.INSTANCE.send(new EventPreferenceChange(key)); - if (key.equals("language")) { + if (key.equals(MainApp.gs(R.string.key_language))) { RxBus.INSTANCE.send(new EventRebuildTabs(true)); //recreate() does not update language so better close settings finish(); } - if (key.equals("short_tabtitles")) { + if (key.equals(MainApp.gs(R.string.key_short_tabtitles))) { RxBus.INSTANCE.send(new EventRebuildTabs()); } + if (key.equals(MainApp.gs(R.string.key_units))) { + recreate(); + return; + } if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) { OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null); } updatePrefSummary(myPreferenceFragment.findPreference(key)); } + private static void adjustUnitDependentPrefs(Preference pref) { + // convert preferences values to current units + String[] unitDependent = new String[]{ + MainApp.gs(R.string.key_hypo_target), + MainApp.gs(R.string.key_activity_target), + MainApp.gs(R.string.key_eatingsoon_target), + MainApp.gs(R.string.key_high_mark), + MainApp.gs(R.string.key_low_mark) + }; + if (Arrays.asList(unitDependent).contains(pref.getKey())) { + EditTextPreference editTextPref = (EditTextPreference) pref; + String converted = Profile.toCurrentUnitsString(SafeParse.stringToDouble(editTextPref.getText())); + editTextPref.setSummary(converted); + editTextPref.setText(converted); + } + } + private static void updatePrefSummary(Preference pref) { if (pref instanceof ListPreference) { ListPreference listPref = (ListPreference) pref; @@ -97,6 +129,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre } } } + if (pref != null) + adjustUnitDependentPrefs(pref); } public static void initSummary(Preference p) { @@ -139,8 +173,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre if (!Config.NSCLIENT) { addPreferencesFromResource(R.xml.pref_password); } + addPreferencesFromResource(R.xml.pref_general); addPreferencesFromResource(R.xml.pref_age); - addPreferencesFromResource(R.xml.pref_language); addPreferencesFromResource(R.xml.pref_overview); diff --git a/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java index 24cdceada6..03fb034c5c 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java @@ -54,7 +54,7 @@ import info.nightscout.androidaps.utils.SafeParse; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; -public class TDDStatsActivity extends NoSplashActivity { +public class TDDStatsActivity extends NoSplashAppCompatActivity { private static Logger log = LoggerFactory.getLogger(TDDStatsActivity.class); private CompositeDisposable disposable = new CompositeDisposable(); diff --git a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java index 79885e297f..60e1b21048 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java +++ b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java @@ -1,7 +1,5 @@ package info.nightscout.androidaps.data; -import com.rits.cloning.Cloner; - import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -37,8 +35,19 @@ public class IobTotal implements DataPointWithLabelInterface { public IobTotal copy() { - Cloner cloner = new Cloner(); - return cloner.deepClone(this); + IobTotal i = new IobTotal(time); + i.iob = iob; + i.activity = activity; + i.bolussnooze = bolussnooze; + i.basaliob = basaliob; + i.netbasalinsulin = netbasalinsulin; + i.hightempinsulin = hightempinsulin; + i.lastBolusTime = lastBolusTime; + if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp.copy(); + i.netInsulin = netInsulin; + i.netRatio = netRatio; + i.extendedBolusInsulin = extendedBolusInsulin; + return i; } public IobTotal(long time) { @@ -137,7 +146,7 @@ public class IobTotal implements DataPointWithLabelInterface { // DataPoint interface - int color; + private int color; @Override public double getX() { diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java index 6f18ba7af5..93c95dda51 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -19,6 +19,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.utils.DateUtil; @@ -75,6 +76,11 @@ public class Profile { } } + // Constructor from profileStore JSON + public Profile(JSONObject json) { + init(json, 100, 0); + } + public Profile(JSONObject json, int percentage, int timeshift) { init(json, percentage, timeshift); } @@ -100,8 +106,6 @@ public class Profile { units = json.getString("units").toLowerCase(); if (json.has("dia")) dia = json.getDouble("dia"); - if (json.has("dia")) - dia = json.getDouble("dia"); if (json.has("timezone")) timeZone = TimeZone.getTimeZone(json.getString("timezone")); isf = json.getJSONArray("sens"); @@ -149,7 +153,7 @@ public class Profile { return units; } - public TimeZone getTimeZone() { + TimeZone getTimeZone() { return timeZone; } @@ -162,7 +166,7 @@ public class Profile { double multiplier = getMultiplier(array); LongSparseArray sparse = new LongSparseArray<>(); - for (Integer index = 0; index < array.length(); index++) { + for (int index = 0; index < array.length(); index++) { try { final JSONObject o = array.getJSONObject(index); long tas = 0; @@ -385,12 +389,12 @@ public class Profile { return retValue; } - public double getIsf() { - return getIsfTimeFromMidnight(secondsFromMidnight()); + public double getIsfMgdl() { + return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight()), units); } - public double getIsf(long time) { - return getIsfTimeFromMidnight(secondsFromMidnight(time)); + public double getIsfMgdl(long time) { + return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units); } double getIsfTimeFromMidnight(int timeAsSeconds) { @@ -405,15 +409,15 @@ public class Profile { return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit)); } - public ProfileValue[] getIsfs() { + public ProfileValue[] getIsfsMgdl() { if (isf_v == null) isf_v = convertToSparseArray(ic); ProfileValue[] ret = new ProfileValue[isf_v.size()]; - for (Integer index = 0; index < isf_v.size(); index++) { - Integer tas = (int) isf_v.keyAt(index); + for (int index = 0; index < isf_v.size(); index++) { + int tas = (int) isf_v.keyAt(index); double value = isf_v.valueAt(index); - ret[index] = new ProfileValue(tas, value); + ret[index] = new ProfileValue(tas, toMgdl(value, units)); } return ret; } @@ -495,44 +499,44 @@ public class Profile { return ret; } - public double getTarget() { - return getTarget(secondsFromMidnight()); + public double getTargetMgdl() { + return getTargetMgdl(secondsFromMidnight()); } - protected double getTarget(int timeAsSeconds) { - return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2; + public double getTargetMgdl(int timeAsSeconds) { + return toMgdl((getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2, units); } - public double getTargetLow() { - return getTargetLowTimeFromMidnight(secondsFromMidnight()); + public double getTargetLowMgdl() { + return toMgdl(getTargetLowTimeFromMidnight(secondsFromMidnight()), units); } - public double getTargetLow(long time) { - return getTargetLowTimeFromMidnight(secondsFromMidnight(time)); + public double getTargetLowMgdl(long time) { + return toMgdl(getTargetLowTimeFromMidnight(secondsFromMidnight(time)), units); } - public double getTargetLowTimeFromMidnight(int timeAsSeconds) { + double getTargetLowTimeFromMidnight(int timeAsSeconds) { if (targetLow_v == null) targetLow_v = convertToSparseArray(targetLow); return getValueToTime(targetLow_v, timeAsSeconds); } - public double getTargetHigh() { - return getTargetHighTimeFromMidnight(secondsFromMidnight()); + public double getTargetHighMgdl() { + return toMgdl(getTargetHighTimeFromMidnight(secondsFromMidnight()), units); } - public double getTargetHigh(long time) { - return getTargetHighTimeFromMidnight(secondsFromMidnight(time)); + public double getTargetHighMgdl(long time) { + return toMgdl(getTargetHighTimeFromMidnight(secondsFromMidnight(time)), units); } - public double getTargetHighTimeFromMidnight(int timeAsSeconds) { + double getTargetHighTimeFromMidnight(int timeAsSeconds) { if (targetHigh_v == null) targetHigh_v = convertToSparseArray(targetHigh); return getValueToTime(targetHigh_v, timeAsSeconds); } public class TargetValue { - public TargetValue(int timeAsSeconds, double low, double high) { + TargetValue(int timeAsSeconds, double low, double high) { this.timeAsSeconds = timeAsSeconds; this.low = low; this.high = high; @@ -559,17 +563,17 @@ public class Profile { return ret; } - public ProfileValue[] getSingleTargets() { + public ProfileValue[] getSingleTargetsMgdl() { if (targetLow_v == null) targetLow_v = convertToSparseArray(targetLow); if (targetHigh_v == null) targetHigh_v = convertToSparseArray(targetHigh); ProfileValue[] ret = new ProfileValue[targetLow_v.size()]; - for (Integer index = 0; index < targetLow_v.size(); index++) { - Integer tas = (int) targetLow_v.keyAt(index); + for (int index = 0; index < targetLow_v.size(); index++) { + int tas = (int) targetLow_v.keyAt(index); double target = (targetLow_v.valueAt(index) + targetHigh_v.valueAt(index)) / 2; - ret[index] = new ProfileValue(tas, target); + ret[index] = new ProfileValue(tas, toMgdl(target, units)); } return ret; } @@ -617,22 +621,39 @@ public class Profile { else return value * Constants.MGDL_TO_MMOLL; } - public static double toUnits(Double valueInMgdl, Double valueInMmol, String units) { + public static double fromMmolToUnits(double value, String units) { + if (units.equals(Constants.MMOL)) return value; + else return value * Constants.MMOLL_TO_MGDL; + } + + public static double toUnits(double valueInMgdl, double valueInMmol, String units) { if (units.equals(Constants.MGDL)) return valueInMgdl; else return valueInMmol; } - public static String toUnitsString(Double valueInMgdl, Double valueInMmol, String units) { + public static String toUnitsString(double valueInMgdl, double valueInMmol, String units) { if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(valueInMgdl); else return DecimalFormatter.to1Decimal(valueInMmol); } - public static String toSignedUnitsString(Double valueInMgdl, Double valueInMmol, String units) { + public static String toSignedUnitsString(double valueInMgdl, double valueInMmol, String units) { if (units.equals(Constants.MGDL)) return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl); else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol); } + public static double toCurrentUnits(double anyBg) { + if (anyBg < 32) return fromMmolToUnits(anyBg, ProfileFunctions.getSystemUnits()); + else return fromMgdlToUnits(anyBg, ProfileFunctions.getSystemUnits()); + } + + public static String toCurrentUnitsString(double anyBg) { + if (anyBg < 32) + return toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, ProfileFunctions.getSystemUnits()); + else + return toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, ProfileFunctions.getSystemUnits()); + } + // targets are stored in mg/dl but profile vary public static String toTargetRangeString(double low, double high, String sourceUnits, String units) { double lowMgdl = toMgdl(low, sourceUnits); @@ -670,4 +691,112 @@ public class Profile { public int getTimeshift() { return timeshift; } + + public Profile convertToNonCustomizedProfile() { + JSONObject o = new JSONObject(); + try { + o.put("units", units); + o.put("dia", dia); + o.put("timezone", timeZone.getID()); + // SENS + JSONArray sens = new JSONArray(); + double lastValue = -1d; + for (int i = 0; i < 24; i++) { + int timeAsSeconds = i * 60 * 60; + double value = getIsfTimeFromMidnight(timeAsSeconds); + if (value != lastValue) { + JSONObject item = new JSONObject(); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + item.put("time", time); + item.put("timeAsSeconds", timeAsSeconds); + item.put("value", value); + lastValue = value; + sens.put(item); + } + } + o.put("sens", sens); + // CARBRATIO + JSONArray carbratio = new JSONArray(); + lastValue = -1d; + for (int i = 0; i < 24; i++) { + int timeAsSeconds = i * 60 * 60; + double value = getIcTimeFromMidnight(timeAsSeconds); + if (value != lastValue) { + JSONObject item = new JSONObject(); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + item.put("time", time); + item.put("timeAsSeconds", timeAsSeconds); + item.put("value", value); + lastValue = value; + carbratio.put(item); + } + } + o.put("carbratio", carbratio); + // BASAL + JSONArray basal = new JSONArray(); + lastValue = -1d; + for (int i = 0; i < 24; i++) { + int timeAsSeconds = i * 60 * 60; + double value = getBasalTimeFromMidnight(timeAsSeconds); + if (value != lastValue) { + JSONObject item = new JSONObject(); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + item.put("time", time); + item.put("timeAsSeconds", timeAsSeconds); + item.put("value", value); + lastValue = value; + basal.put(item); + } + } + o.put("basal", basal); + // TARGET_LOW + JSONArray target_low = new JSONArray(); + lastValue = -1d; + for (int i = 0; i < 24; i++) { + int timeAsSeconds = i * 60 * 60; + double value = getTargetLowTimeFromMidnight(timeAsSeconds); + if (value != lastValue) { + JSONObject item = new JSONObject(); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + item.put("time", time); + item.put("timeAsSeconds", timeAsSeconds); + item.put("value", value); + lastValue = value; + target_low.put(item); + } + } + o.put("target_low", target_low); + // TARGET_HIGH + JSONArray target_high = new JSONArray(); + lastValue = -1d; + for (int i = 0; i < 24; i++) { + int timeAsSeconds = i * 60 * 60; + double value = getTargetHighTimeFromMidnight(timeAsSeconds); + if (value != lastValue) { + JSONObject item = new JSONObject(); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + item.put("time", time); + item.put("timeAsSeconds", timeAsSeconds); + item.put("value", value); + lastValue = value; + target_high.put(item); + } + } + o.put("target_high", target_high); + + } catch (JSONException e) { + log.error("Unhandled exception" + e); + } + return new Profile(o); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java deleted file mode 100644 index a0b54ec0bb..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java +++ /dev/null @@ -1,118 +0,0 @@ -package info.nightscout.androidaps.data; - -import androidx.annotation.Nullable; -import androidx.collection.ArrayMap; - -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.Iterator; - -import info.nightscout.androidaps.Constants; - -/** - * Created by mike on 01.06.2017. - */ - -public class ProfileStore { - private static Logger log = LoggerFactory.getLogger(ProfileStore.class); - private JSONObject json = null; - private String units = Constants.MGDL; - - ArrayMap cachedObjects = new ArrayMap<>(); - - public ProfileStore(JSONObject json) { - this.json = json; - getDefaultProfile(); // initialize units - } - - public JSONObject getData() { - return json; - } - - @Nullable - public Profile getDefaultProfile() { - Profile profile = null; - try { - String defaultProfileName = json.getString("defaultProfile"); - JSONObject store = json.getJSONObject("store"); - if (store.has(defaultProfileName)) { - profile = cachedObjects.get(defaultProfileName); - if (profile == null) { - if (store.has("units")) - units = store.getString("units"); - profile = new Profile(store.getJSONObject(defaultProfileName), units); - units = profile.getUnits(); - cachedObjects.put(defaultProfileName, profile); - } - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return profile; - } - - @Nullable - public String getDefaultProfileName() { - String defaultProfileName = null; - try { - defaultProfileName = json.getString("defaultProfile"); - JSONObject store = json.getJSONObject("store"); - if (store.has(defaultProfileName)) { - return defaultProfileName; - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return defaultProfileName; - } - - public String getUnits() { - return units; - } - - @Nullable - public Profile getSpecificProfile(String profileName) { - Profile profile = null; - try { - JSONObject store = json.getJSONObject("store"); - if (store.has(profileName)) { - profile = cachedObjects.get(profileName); - if (profile == null) { - if (store.has("units")) - units = store.getString("units"); - profile = new Profile(store.getJSONObject(profileName), units); - units = profile.getUnits(); - cachedObjects.put(profileName, profile); - } - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return profile; - } - - public ArrayList getProfileList() { - ArrayList ret = new ArrayList(); - - JSONObject store; - try { - store = json.getJSONObject("store"); - Iterator keys = store.keys(); - - while (keys.hasNext()) { - String profileName = (String) keys.next(); - ret.add(profileName); - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - - return ret; - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.kt b/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.kt new file mode 100644 index 0000000000..0fa0bf277f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.kt @@ -0,0 +1,61 @@ +package info.nightscout.androidaps.data + +import androidx.collection.ArrayMap +import org.json.JSONException +import org.json.JSONObject +import org.slf4j.LoggerFactory +import java.util.* + +class ProfileStore(val data: JSONObject) { + private val log = LoggerFactory.getLogger(ProfileStore::class.java) + + private val cachedObjects = ArrayMap() + + private fun getStore(): JSONObject? { + try { + if (data.has("store")) return data.getJSONObject("store") + } catch (e: JSONException) { + log.error("Unhandled exception", e) + } + return null + } + + fun getDefaultProfile(): Profile? = getDefaultProfileName()?.let { getSpecificProfile(it) } + + fun getDefaultProfileName(): String? { + val defaultProfileName = data.getString("defaultProfile") + return getStore()?.has(defaultProfileName)?.let { defaultProfileName } + } + + fun getProfileList(): ArrayList { + val ret = ArrayList() + getStore()?.keys()?.let { keys -> + while (keys.hasNext()) { + val profileName = keys.next() as String + ret.add(profileName) + } + } + return ret + } + + fun getSpecificProfile(profileName: String): Profile? { + var profile: Profile? = null + try { + getStore()?.let { store -> + if (store.has(profileName)) { + profile = cachedObjects[profileName] + if (profile == null) { + val profileObject = store.getJSONObject(profileName) + if (profileObject != null && profileObject.has("units")) { + profile = Profile(profileObject, profileObject.getString("units")) + cachedObjects[profileName] = profile + } + } + } + } + } catch (e: JSONException) { + log.error("Unhandled exception", e) + } + return profile + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java index 062f6ae391..af8451477d 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java @@ -11,6 +11,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; @@ -74,7 +75,7 @@ public class QuickWizardEntry { //BG double bg = 0; if (lastBG != null && useBG() == YES) { - bg = lastBG.valueToUnits(profile.getUnits()); + bg = lastBG.valueToUnits(ProfileFunctions.getSystemUnits()); } // COB diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index 8b206e2c78..abac9e08c0 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; +import java.util.List; import java.util.Objects; import info.nightscout.androidaps.Constants; @@ -19,10 +20,11 @@ import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.androidaps.utils.DecimalFormatter; +import info.nightscout.androidaps.utils.T; @DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS) public class BgReading implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(L.DATABASE); + private static Logger log = LoggerFactory.getLogger(L.GLUCOSE); @DatabaseField(id = true) public long date; @@ -73,9 +75,10 @@ public class BgReading implements DataPointWithLabelInterface { public String directionToSymbol() { String symbol = ""; - if (direction == null) { - symbol = "??"; - } else if (direction.compareTo("DoubleDown") == 0) { + if (direction == null) + direction = calculateDirection(); + + if (direction.compareTo("DoubleDown") == 0) { symbol = "\u21ca"; } else if (direction.compareTo("SingleDown") == 0) { symbol = "\u2193"; @@ -95,18 +98,13 @@ public class BgReading implements DataPointWithLabelInterface { return symbol; } - public static boolean isSlopeNameInvalid(String direction) { - if (direction.compareTo("NOT_COMPUTABLE") == 0 || + private static boolean isSlopeNameInvalid(String direction) { + return direction.compareTo("NOT_COMPUTABLE") == 0 || direction.compareTo("NOT COMPUTABLE") == 0 || direction.compareTo("OUT_OF_RANGE") == 0 || direction.compareTo("OUT OF RANGE") == 0 || direction.compareTo("NONE") == 0 || - direction.compareTo("NotComputable") == 0 - ) { - return true; - } else { - return false; - } + direction.compareTo("NotComputable") == 0; } @@ -123,7 +121,8 @@ public class BgReading implements DataPointWithLabelInterface { public boolean isDataChanging(BgReading other) { if (date != other.date) { - log.error("Comparing different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Comparing different"); return false; } if (value != other.value) @@ -133,7 +132,8 @@ public class BgReading implements DataPointWithLabelInterface { public boolean isEqual(BgReading other) { if (date != other.date) { - log.error("Comparing different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Comparing different"); return false; } if (value != other.value) @@ -149,7 +149,8 @@ public class BgReading implements DataPointWithLabelInterface { public void copyFrom(BgReading other) { if (date != other.date) { - log.error("Copying different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Copying different"); return; } value = other.value; @@ -181,8 +182,7 @@ public class BgReading implements DataPointWithLabelInterface { @Override public double getY() { - String units = ProfileFunctions.getInstance().getProfileUnits(); - return valueToUnits(units); + return valueToUnits(ProfileFunctions.getSystemUnits()); } @Override @@ -215,9 +215,9 @@ public class BgReading implements DataPointWithLabelInterface { @Override public int getColor() { - String units = ProfileFunctions.getInstance().getProfileUnits(); - Double lowLine = OverviewPlugin.INSTANCE.determineLowLine(units); - Double highLine = OverviewPlugin.INSTANCE.determineHighLine(units); + String units = ProfileFunctions.getSystemUnits(); + Double lowLine = OverviewPlugin.INSTANCE.determineLowLine(); + Double highLine = OverviewPlugin.INSTANCE.determineHighLine(); int color = MainApp.gc(R.color.inrange); if (isPrediction()) return getPredectionColor(); @@ -246,4 +246,53 @@ public class BgReading implements DataPointWithLabelInterface { return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction; } + + // Copied from xDrip+ + String calculateDirection() { + // Rework to get bgreaings from internal DB and calculate on that base + + List bgReadingsList = MainApp.getDbHelper().getAllBgreadingsDataFromTime(this.date - T.mins(10).msecs(), false); + if (bgReadingsList == null || bgReadingsList.size() < 2) + return "NONE"; + BgReading current = bgReadingsList.get(1); + BgReading previous = bgReadingsList.get(0); + + if (bgReadingsList.get(1).date < bgReadingsList.get(0).date) { + current = bgReadingsList.get(0); + previous = bgReadingsList.get(1); + } + + double slope; + + // Avoid division by 0 + if (current.date == previous.date) + slope = 0; + else + slope = (previous.value - current.value) / (previous.date - current.date); + + if (L.isEnabled(L.GLUCOSE)) + log.debug("Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date)); + + double slope_by_minute = slope * 60000; + String arrow = "NONE"; + + if (slope_by_minute <= (-3.5)) { + arrow = "DoubleDown"; + } else if (slope_by_minute <= (-2)) { + arrow = "SingleDown"; + } else if (slope_by_minute <= (-1)) { + arrow = "FortyFiveDown"; + } else if (slope_by_minute <= (1)) { + arrow = "Flat"; + } else if (slope_by_minute <= (2)) { + arrow = "FortyFiveUp"; + } else if (slope_by_minute <= (3.5)) { + arrow = "SingleUp"; + } else if (slope_by_minute <= (40)) { + arrow = "DoubleUp"; + } + if (L.isEnabled(L.GLUCOSE)) + log.debug("Direction set to: " + arrow); + return arrow; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java index 1c33e8f1be..c2dc6f737e 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -167,7 +167,7 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval { @Override public double getY() { - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); if (eventType.equals(MBG)) { double mbg = 0d; try { diff --git a/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java b/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java index 25d2c308c1..5c865a331c 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java @@ -259,11 +259,11 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { double sensitivityRatio = lastAutosensResult.ratio; double normalTarget = 100; - if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) { + if (exercise_mode && isTempTarget && profile.getTargetMgdl() >= normalTarget + 5) { // w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44 // e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6 double c = half_basal_exercise_target - normalTarget; - sensitivityRatio = c / (c + profile.getTarget() - normalTarget); + sensitivityRatio = c / (c + profile.getTargetMgdl() - normalTarget); } if (realDuration > 0) { diff --git a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java index f2a10cf4a4..cf0eeab462 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -299,11 +299,11 @@ public class TemporaryBasal implements Interval, DbObjectBase { double sensitivityRatio = lastAutosensResult.ratio; double normalTarget = 100; - if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) { + if (exercise_mode && isTempTarget && profile.getTargetMgdl() >= normalTarget + 5) { // w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44 // e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6 double c = half_basal_exercise_target - normalTarget; - sensitivityRatio = c / (c + profile.getTarget() - normalTarget); + sensitivityRatio = c / (c + profile.getTargetMgdl() - normalTarget); } if (realDuration > 0) { diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java index 482278e437..5fb3b459b6 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java @@ -10,6 +10,5 @@ import info.nightscout.androidaps.data.ProfileStore; public interface ProfileInterface { @Nullable ProfileStore getProfile(); - String getUnits(); String getProfileName(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java index 703dc4255b..9ea2d39567 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; @@ -194,8 +195,6 @@ public class DetermineBasalAdapterAMAJS { double autosensDataRatio, boolean tempTargetSet) throws JSONException { - String units = profile.getUnits(); - mProfile = new JSONObject(); mProfile.put("max_iob", maxIob); mProfile.put("dia", Math.min(profile.getDia(), 3d)); @@ -206,7 +205,7 @@ public class DetermineBasalAdapterAMAJS { mProfile.put("max_bg", maxBg); mProfile.put("target_bg", targetBg); mProfile.put("carb_ratio", profile.getIc()); - mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); + mProfile.put("sens", profile.getIsfMgdl()); mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)); mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)); mProfile.put("skip_neutral_temps", true); @@ -220,7 +219,7 @@ public class DetermineBasalAdapterAMAJS { mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact)); } - if (units.equals(Constants.MMOL)) { + if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) { mProfile.put("out_units", "mmol/L"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java index 65db6e440c..49881c5158 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java @@ -107,6 +107,13 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { return; } + if (pump == null) { + RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected))); + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.nopumpselected)); + return; + } + if (!isEnabled(PluginType.APS)) { RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); if (L.isEnabled(L.APS)) @@ -121,12 +128,10 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { return; } - String units = profile.getUnits(); - double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); - double minBg = Profile.toMgdl(profile.getTargetLow(), units); - double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); - double targetBg = Profile.toMgdl(profile.getTarget(), units); + double minBg = profile.getTargetLowMgdl(); + double maxBg = profile.getTargetHighMgdl(); + double targetBg = profile.getTargetMgdl(); minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); @@ -162,7 +167,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { return; if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!HardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal())) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java index 1ded34b7cb..dbc7782ab3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java @@ -20,6 +20,7 @@ import javax.annotation.Nullable; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; @@ -160,8 +161,6 @@ public class DetermineBasalAdapterMAJS { GlucoseStatus glucoseStatus, MealData mealData) throws JSONException { - String units = profile.getUnits(); - mProfile = new JSONObject(); mProfile.put("max_iob", maxIob); mProfile.put("dia", Math.min(profile.getDia(), 3d)); @@ -172,11 +171,11 @@ public class DetermineBasalAdapterMAJS { mProfile.put("max_bg", maxBg); mProfile.put("target_bg", targetBg); mProfile.put("carb_ratio", profile.getIc()); - mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); + mProfile.put("sens", profile.getIsfMgdl()); mProfile.put("current_basal", basalRate); - if (units.equals(Constants.MMOL)) { + if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) { mProfile.put("out_units", "mmol/L"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java index 8cac8b87cc..0380156c74 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java @@ -106,6 +106,13 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { return; } + if (pump == null) { + RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected))); + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.nopumpselected)); + return; + } + if (!isEnabled(PluginType.APS)) { RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); if (L.isEnabled(L.APS)) @@ -120,13 +127,11 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { return; } - String units = profile.getUnits(); - double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); - double minBg = Profile.toMgdl(profile.getTargetLow(), units); - double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); - double targetBg = Profile.toMgdl(profile.getTarget(), units); + double minBg = profile.getTargetLowMgdl(); + double maxBg = profile.getTargetHighMgdl(); + double targetBg = profile.getTargetMgdl(); minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); @@ -160,7 +165,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { return; if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal())) return; 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 5769196bb7..6b0f44f451 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 @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; @@ -240,7 +241,7 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("max_bg", maxBg); mProfile.put("target_bg", targetBg); mProfile.put("carb_ratio", profile.getIc()); - mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); + mProfile.put("sens", profile.getIsfMgdl()); mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)); mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)); @@ -284,7 +285,7 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("temptargetSet", tempTargetSet); mProfile.put("autosens_max", SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2"))); - if (units.equals(Constants.MMOL)) { + if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) { mProfile.put("out_units", "mmol/L"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java index c27a3f2059..426c04090b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java @@ -111,6 +111,13 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr return; } + if (pump == null) { + RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected))); + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.nopumpselected)); + return; + } + if (!isEnabled(PluginType.APS)) { RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); if (L.isEnabled(L.APS)) @@ -125,16 +132,14 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr return; } - String units = profile.getUnits(); - Constraint inputConstraints = new Constraint<>(0d); // fake. only for collecting all results Constraint maxBasalConstraint = MainApp.getConstraintChecker().getMaxBasalAllowed(profile); inputConstraints.copyReasons(maxBasalConstraint); double maxBasal = maxBasalConstraint.value(); - double minBg = Profile.toMgdl(profile.getTargetLow(), units); - double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); - double targetBg = Profile.toMgdl(profile.getTarget(), units); + double minBg = profile.getTargetLowMgdl(); + double maxBg = profile.getTargetHighMgdl(); + double targetBg = profile.getTargetMgdl(); minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); @@ -168,7 +173,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr return; if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal())) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java index 91c20b095a..63da02e2bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java @@ -124,9 +124,8 @@ public class ProfileFunctions { return getProfile(System.currentTimeMillis()); } - public String getProfileUnits() { - Profile profile = getProfile(); - return profile != null ? profile.getUnits() : Constants.MGDL; + public static String getSystemUnits() { + return SP.getString(R.string.key_units, Constants.MGDL); } @Nullable diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesFragment.kt index 5edb199c9a..34aadf84c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesFragment.kt @@ -4,6 +4,7 @@ import android.graphics.Color import android.os.Bundle import android.os.Handler import android.os.Looper +import android.os.SystemClock import android.view.Gravity import android.view.LayoutInflater import android.view.View @@ -12,6 +13,7 @@ import android.widget.Button import android.widget.EditText import android.widget.LinearLayout import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller @@ -21,6 +23,8 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.constraints.objectives.activities.ObjectivesExamDialog +import info.nightscout.androidaps.plugins.constraints.objectives.dialogs.NtpProgressDialog +import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtpStatus import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObjectivesUpdateGui import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask import info.nightscout.androidaps.receivers.NetworkChangeReceiver @@ -101,18 +105,20 @@ class ObjectivesFragment : Fragment() { } private fun scrollToCurrentObjective() { - for (i in 0 until ObjectivesPlugin.objectives.size) { - val objective = ObjectivesPlugin.objectives[i] - if (!objective.isStarted || !objective.isAccomplished) { - context?.let { - val smoothScroller = object : LinearSmoothScroller(it) { - override fun getVerticalSnapPreference(): Int = SNAP_TO_START - override fun calculateTimeForScrolling(dx: Int): Int = super.calculateTimeForScrolling(dx) * 4 + activity?.runOnUiThread { + for (i in 0 until ObjectivesPlugin.objectives.size) { + val objective = ObjectivesPlugin.objectives[i] + if (!objective.isStarted || !objective.isAccomplished) { + context?.let { + val smoothScroller = object : LinearSmoothScroller(it) { + override fun getVerticalSnapPreference(): Int = SNAP_TO_START + override fun calculateTimeForScrolling(dx: Int): Int = super.calculateTimeForScrolling(dx) * 4 + } + smoothScroller.targetPosition = i + objectives_recyclerview.layoutManager?.startSmoothScroll(smoothScroller) } - smoothScroller.targetPosition = i - objectives_recyclerview.layoutManager?.startSmoothScroll(smoothScroller) + break } - break } } } @@ -126,7 +132,6 @@ class ObjectivesFragment : Fragment() { override fun onBindViewHolder(holder: ViewHolder, position: Int) { val objective = ObjectivesPlugin.objectives[position] holder.title.text = MainApp.gs(R.string.nth_objective, position + 1) - holder.revert.visibility = View.GONE if (objective.objective != 0) { holder.objective.visibility = View.VISIBLE holder.objective.text = MainApp.gs(objective.objective) @@ -142,6 +147,8 @@ class ObjectivesFragment : Fragment() { holder.verify.visibility = View.GONE holder.progress.visibility = View.GONE holder.accomplished.visibility = View.GONE + holder.unFinish.visibility = View.GONE + holder.unStart.visibility = View.GONE if (position == 0 || ObjectivesPlugin.objectives[position - 1].isAccomplished) holder.start.visibility = View.VISIBLE else @@ -152,15 +159,16 @@ class ObjectivesFragment : Fragment() { holder.progress.visibility = View.GONE holder.start.visibility = View.GONE holder.accomplished.visibility = View.VISIBLE + holder.unFinish.visibility = View.VISIBLE + holder.unStart.visibility = View.GONE } else if (objective.isStarted) { holder.gate.setTextColor(-0x1) holder.verify.visibility = View.VISIBLE holder.verify.isEnabled = objective.isCompleted || objectives_fake.isChecked holder.start.visibility = View.GONE holder.accomplished.visibility = View.GONE - if (objective.isRevertable) { - holder.revert.visibility = View.VISIBLE - } + holder.unFinish.visibility = View.GONE + holder.unStart.visibility = View.VISIBLE holder.progress.visibility = View.VISIBLE holder.progress.removeAllViews() for (task in objective.tasks) { @@ -203,39 +211,43 @@ class ObjectivesFragment : Fragment() { holder.accomplished.text = MainApp.gs(R.string.accomplished, DateUtil.dateAndTimeString(objective.accomplishedOn)) holder.accomplished.setTextColor(-0x3e3e3f) holder.verify.setOnClickListener { - holder.verify.visibility = View.INVISIBLE NetworkChangeReceiver.grabNetworkStatus(context) if (objectives_fake.isChecked) { objective.accomplishedOn = DateUtil.now() scrollToCurrentObjective() startUpdateTimer() RxBus.send(EventObjectivesUpdateGui()) - } else - SntpClient.ntpTime(object : SntpClient.Callback() { - override fun run() { - activity?.runOnUiThread { - holder.verify.visibility = View.VISIBLE + } else { + // move out of UI thread + Thread { + NtpProgressDialog().show((context as AppCompatActivity).supportFragmentManager, "NtpCheck") + RxBus.send(EventNtpStatus(MainApp.gs(R.string.timedetection), 0)) + SntpClient.ntpTime(object : SntpClient.Callback() { + override fun run() { log.debug("NTP time: $time System time: ${DateUtil.now()}") + SystemClock.sleep(300) if (!networkConnected) { - ToastUtils.showToastInUiThread(context, R.string.notconnected) + RxBus.send(EventNtpStatus(MainApp.gs(R.string.notconnected), 99)) } else if (success) { if (objective.isCompleted(time)) { objective.accomplishedOn = time - scrollToCurrentObjective() - startUpdateTimer() + RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100)) + SystemClock.sleep(1000) RxBus.send(EventObjectivesUpdateGui()) + SystemClock.sleep(100) + scrollToCurrentObjective() } else { - ToastUtils.showToastInUiThread(context, R.string.requirementnotmet) + RxBus.send(EventNtpStatus(MainApp.gs(R.string.requirementnotmet), 99)) } } else { - ToastUtils.showToastInUiThread(context, R.string.failedretrievetime) + RxBus.send(EventNtpStatus(MainApp.gs(R.string.failedretrievetime), 99)) } } - } - }, NetworkChangeReceiver.isConnected()) + }, NetworkChangeReceiver.isConnected()) + }.start() + } } holder.start.setOnClickListener { - holder.start.visibility = View.INVISIBLE NetworkChangeReceiver.grabNetworkStatus(context) if (objectives_fake.isChecked) { objective.startedOn = DateUtil.now() @@ -243,36 +255,43 @@ class ObjectivesFragment : Fragment() { startUpdateTimer() RxBus.send(EventObjectivesUpdateGui()) } else - SntpClient.ntpTime(object : SntpClient.Callback() { - override fun run() { - activity?.runOnUiThread { - holder.start.visibility = View.VISIBLE + // move out of UI thread + Thread { + NtpProgressDialog().show((context as AppCompatActivity).supportFragmentManager, "NtpCheck") + RxBus.send(EventNtpStatus(MainApp.gs(R.string.timedetection), 0)) + SntpClient.ntpTime(object : SntpClient.Callback() { + override fun run() { log.debug("NTP time: $time System time: ${DateUtil.now()}") + SystemClock.sleep(300) if (!networkConnected) { - ToastUtils.showToastInUiThread(context, R.string.notconnected) + RxBus.send(EventNtpStatus(MainApp.gs(R.string.notconnected), 99)) } else if (success) { objective.startedOn = time - scrollToCurrentObjective() - startUpdateTimer() + RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100)) + SystemClock.sleep(1000) RxBus.send(EventObjectivesUpdateGui()) + SystemClock.sleep(100) + scrollToCurrentObjective() } else { - ToastUtils.showToastInUiThread(context, R.string.failedretrievetime) + RxBus.send(EventNtpStatus(MainApp.gs(R.string.failedretrievetime), 99)) } } - } - }, NetworkChangeReceiver.isConnected()) + }, NetworkChangeReceiver.isConnected()) + }.start() } - holder.revert.setOnClickListener { - objective.accomplishedOn = 0 - objective.startedOn = 0 - if (position > 0) { - val prevObj = ObjectivesPlugin.objectives[position - 1] - prevObj.accomplishedOn = 0 + holder.unStart.setOnClickListener { + OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantresetstart)) { + objective.startedOn = 0 + scrollToCurrentObjective() + RxBus.send(EventObjectivesUpdateGui()) } + } + holder.unFinish.setOnClickListener { + objective.accomplishedOn = 0 scrollToCurrentObjective() RxBus.send(EventObjectivesUpdateGui()) } - if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted) { + if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) { // generate random request code if none exists val request = SP.getString(R.string.key_objectives_request_code, String.format("%1$05d", (Math.random() * 99999).toInt())) SP.putString(R.string.key_objectives_request_code, request) @@ -307,7 +326,8 @@ class ObjectivesFragment : Fragment() { val progress: LinearLayout = itemView.findViewById(R.id.objective_progress) val verify: Button = itemView.findViewById(R.id.objective_verify) val start: Button = itemView.findViewById(R.id.objective_start) - val revert: Button = itemView.findViewById(R.id.objective_back) + val unFinish: Button = itemView.findViewById(R.id.objective_unfinish) + val unStart: Button = itemView.findViewById(R.id.objective_unstart) val inputHint: TextView = itemView.findViewById(R.id.objective_inputhint) val input: EditText = itemView.findViewById(R.id.objective_input) val enterButton: Button = itemView.findViewById(R.id.objective_enterbutton) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt index 5882f84d61..f8b0ca26ec 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt @@ -104,7 +104,7 @@ object ObjectivesPlugin : PluginBase(PluginDescription() fun completeObjectives(activity: Activity, request: String) { val requestCode = SP.getString(R.string.key_objectives_request_code, "") var url = SP.getString(R.string.key_nsclientinternal_url, "").toLowerCase() - if (!url.endsWith("\"")) url = "$url/" + if (!url.endsWith("/")) url = "$url/" @Suppress("DEPRECATION") val hashNS = Hashing.sha1().hashString(url + BuildConfig.APPLICATION_ID + "/" + requestCode, Charsets.UTF_8).toString() if (request.equals(hashNS.substring(0, 10), ignoreCase = true)) { SP.putLong("Objectives_" + "openloop" + "_started", DateUtil.now()) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/dialogs/NtpProgressDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/dialogs/NtpProgressDialog.kt new file mode 100644 index 0000000000..cef9bc232a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/dialogs/NtpProgressDialog.kt @@ -0,0 +1,84 @@ +package info.nightscout.androidaps.plugins.constraints.objectives.dialogs + +import android.os.Bundle +import android.os.SystemClock +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.bus.RxBus.toObservable +import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtpStatus +import info.nightscout.androidaps.utils.FabricPrivacy +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import kotlinx.android.synthetic.main.overview_bolusprogress_dialog.* +import org.slf4j.LoggerFactory + +class NtpProgressDialog : DialogFragment() { + private val log = LoggerFactory.getLogger(L.UI) + private val disposable = CompositeDisposable() + + private val DEFAULT_STATE = MainApp.gs(R.string.timedetection) + private var state: String = DEFAULT_STATE + private var percent = 0 + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + dialog?.setTitle(String.format(MainApp.gs(R.string.objectives))) + isCancelable = false + + state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE + percent = savedInstanceState?.getInt("percent", 0) ?: 0 + + return inflater.inflate(R.layout.overview_bolusprogress_dialog, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + overview_bolusprogress_stop.setOnClickListener { dismiss() } + overview_bolusprogress_status.setText(state) + overview_bolusprogress_progressbar.setMax(100) + overview_bolusprogress_progressbar.setProgress(percent) + overview_bolusprogress_stop.text = MainApp.gs(R.string.close) + } + + override fun onResume() { + super.onResume() + if (L.isEnabled(L.UI)) log.debug("onResume") + if (percent == 100) { + dismiss() + return + } else + dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + + disposable.add(toObservable(EventNtpStatus::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ event: EventNtpStatus -> + if (L.isEnabled(L.UI)) log.debug("Status: " + event.status + " Percent: " + event.percent) + overview_bolusprogress_status?.text = event.status + overview_bolusprogress_progressbar?.progress = event.percent + if (event.percent == 100) { + SystemClock.sleep(100) + dismiss() + } + state = event.status + percent = event.percent + }) { FabricPrivacy.logException(it) } + ) + } + + override fun onPause() { + if (L.isEnabled(L.UI)) log.debug("onPause") + super.onPause() + disposable.clear() + } + + override fun onSaveInstanceState(outState: Bundle) { + outState.putString("state", state) + outState.putInt("percent", percent) + super.onSaveInstanceState(outState) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/events/EventNtpStatus.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/events/EventNtpStatus.kt new file mode 100644 index 0000000000..fc4e5cb8e9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/events/EventNtpStatus.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.constraints.objectives.events + +import info.nightscout.androidaps.events.Event + +class EventNtpStatus(val status: String, val percent: Int) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective.java b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective.java index c882a921f5..7082c7e7bc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective.java @@ -61,10 +61,6 @@ public abstract class Objective { return true; } - public boolean isRevertable() { - return false; - } - public boolean isAccomplished() { return accomplishedOn != 0 && accomplishedOn < DateUtil.now(); } @@ -107,6 +103,8 @@ public abstract class Objective { return tasks; } + public boolean specialActionEnabled() { return true; } + public void specialAction(Activity activity, String input) {} public abstract class Task { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.java b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.java index c9ac7d8935..f8eb45bb2a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.java @@ -7,6 +7,7 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.T; @@ -38,6 +39,11 @@ public class Objective3 extends Objective { }); } + @Override + public boolean specialActionEnabled() { + return NSClientPlugin.getPlugin().nsClientService.isConnected && NSClientPlugin.getPlugin().nsClientService.hasWriteAuth; + } + @Override public void specialAction(Activity activity, String input) { ObjectivesPlugin.INSTANCE.completeObjectives(activity, input); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective5.java b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective5.java index 2407594069..bd3e69c751 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective5.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective5.java @@ -25,9 +25,4 @@ public class Objective5 extends Objective { } }); } - - @Override - public boolean isRevertable() { - return true; - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt index d1135c21ed..5266c0781c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt @@ -5,10 +5,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import info.nightscout.androidaps.R import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog +import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener +import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleItemTouchHelperCallback import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui import info.nightscout.androidaps.utils.FabricPrivacy @@ -17,11 +21,14 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.automation_fragment.* -class AutomationFragment : Fragment() { + +class AutomationFragment : Fragment(), OnStartDragListener { private var disposable: CompositeDisposable = CompositeDisposable() private var eventListAdapter: EventListAdapter? = null + private var itemTouchHelper: ItemTouchHelper? = null + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.automation_fragment, container, false) } @@ -29,7 +36,7 @@ class AutomationFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - eventListAdapter = EventListAdapter(AutomationPlugin.automationEvents, fragmentManager, activity) + eventListAdapter = EventListAdapter(AutomationPlugin.automationEvents, fragmentManager, activity, this) automation_eventListView.layoutManager = LinearLayoutManager(context) automation_eventListView.adapter = eventListAdapter @@ -42,6 +49,10 @@ class AutomationFragment : Fragment() { fragmentManager?.let { dialog.show(it, "EditEventDialog") } } + val callback: ItemTouchHelper.Callback = SimpleItemTouchHelperCallback(eventListAdapter!!) + itemTouchHelper = ItemTouchHelper(callback) + itemTouchHelper?.attachToRecyclerView(automation_eventListView) + } @Synchronized @@ -81,4 +92,8 @@ class AutomationFragment : Fragment() { automation_logView?.text = sb.toString() } + override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) { + itemTouchHelper?.startDrag(viewHolder); + } + } 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 8b78ae6458..b559311f9d 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 @@ -161,7 +161,7 @@ object AutomationPlugin : PluginBase(PluginDescription() private fun processActions() { if (!isEnabled(PluginType.GENERAL)) return - if (LoopPlugin.getPlugin().isSuspended) { + if (LoopPlugin.getPlugin().isSuspended || !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) { if (L.isEnabled(L.AUTOMATION)) log.debug("Loop deactivated") return diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java index 08079a9110..87c78d02eb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/EventListAdapter.java @@ -1,9 +1,12 @@ package info.nightscout.androidaps.plugins.general.automation; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; @@ -17,6 +20,7 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.RecyclerView; +import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -25,19 +29,26 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.general.automation.actions.Action; import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog; +import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter; +import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperViewHolder; +import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener; import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged; +import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui; import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector; import info.nightscout.androidaps.utils.OKDialog; -class EventListAdapter extends RecyclerView.Adapter { +class EventListAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter { private final List eventList; private final FragmentManager fragmentManager; private final Activity activity; - EventListAdapter(List events, FragmentManager fragmentManager, Activity activity) { + private final OnStartDragListener mDragStartListener; + + EventListAdapter(List events, FragmentManager fragmentManager, Activity activity, OnStartDragListener dragStartListener) { this.eventList = events; this.fragmentManager = fragmentManager; this.activity = activity; + mDragStartListener = dragStartListener; } @NonNull @@ -54,6 +65,7 @@ class EventListAdapter extends RecyclerView.Adapter layout.addView(iv); } + @SuppressLint("ClickableViewAccessibility") @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { final AutomationEvent event = eventList.get(position); @@ -91,16 +103,10 @@ class EventListAdapter extends RecyclerView.Adapter RxBus.INSTANCE.send(new EventAutomationDataChanged()); }); - // remove event - holder.iconTrash.setOnClickListener(v -> - OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + " " + event.getTitle(), () -> { - eventList.remove(event); - RxBus.INSTANCE.send(new EventAutomationDataChanged()); - }) - ); - // edit event - holder.rootLayout.setOnClickListener(v -> { + holder.rootLayout.setOnClickListener(v -> + + { //EditEventDialog dialog = EditEventDialog.Companion.newInstance(event, false); EditEventDialog dialog = new EditEventDialog(); Bundle args = new Bundle(); @@ -110,6 +116,17 @@ class EventListAdapter extends RecyclerView.Adapter if (fragmentManager != null) dialog.show(fragmentManager, "EditEventDialog"); }); + + // Start a drag whenever the handle view it touched + holder.iconSort.setOnTouchListener((v, motionEvent) -> + + { + if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { + mDragStartListener.onStartDrag(holder); + return true; + } + return v.onTouchEvent(motionEvent); + }); } @Override @@ -117,12 +134,33 @@ class EventListAdapter extends RecyclerView.Adapter return eventList.size(); } - static class ViewHolder extends RecyclerView.ViewHolder { + @Override + public boolean onItemMove(int fromPosition, int toPosition) { + Collections.swap(eventList, fromPosition, toPosition); + notifyItemMoved(fromPosition, toPosition); + RxBus.INSTANCE.send(new EventAutomationDataChanged()); + return true; + } + + @Override + public void onItemDismiss(int position) { + OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + " " + eventList.get(position).getTitle(), + () -> { + eventList.remove(position); + notifyItemRemoved(position); + RxBus.INSTANCE.send(new EventAutomationDataChanged()); + RxBus.INSTANCE.send(new EventAutomationUpdateGui()); + }, () -> { + RxBus.INSTANCE.send(new EventAutomationUpdateGui()); + }); + } + + static class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder { final RelativeLayout rootLayout; final LinearLayout iconLayout; final TextView eventTitle; final Context context; - final ImageView iconTrash; + final ImageView iconSort; final CheckBox enabled; ViewHolder(View view, Context context) { @@ -131,8 +169,18 @@ class EventListAdapter extends RecyclerView.Adapter eventTitle = view.findViewById(R.id.viewEventTitle); rootLayout = view.findViewById(R.id.rootLayout); iconLayout = view.findViewById(R.id.iconLayout); - iconTrash = view.findViewById(R.id.iconTrash); + iconSort = view.findViewById(R.id.iconSort); enabled = view.findViewById(R.id.automation_enabled); } + + @Override + public void onItemSelected() { + itemView.setBackgroundColor(Color.LTGRAY); + } + + @Override + public void onItemClear() { + itemView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault)); + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperAdapter.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperAdapter.kt new file mode 100644 index 0000000000..bdd68080ef --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperAdapter.kt @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.plugins.general.automation.dragHelpers + + +interface ItemTouchHelperAdapter { + /** + * Called when an item has been dragged far enough to trigger a move. This is called every time + * an item is shifted, and **not** at the end of a "drop" event.

+ *

+ * Implementations should call [RecyclerView.Adapter.notifyItemMoved] after + * adjusting the underlying data to reflect this move. + * + * @param fromPosition The start position of the moved item. + * @param toPosition Then resolved position of the moved item. + * @return True if the item was moved to the new adapter position. + * + * @see RecyclerView.getAdapterPositionFor + * @see RecyclerView.ViewHolder.getAdapterPosition + */ + fun onItemMove(fromPosition: Int, toPosition: Int): Boolean + + /** + * Called when an item has been dismissed by a swipe.

+ *

+ * Implementations should call [RecyclerView.Adapter.notifyItemRemoved] after + * adjusting the underlying data to reflect this removal. + * + * @param position The position of the item dismissed. + * + * @see RecyclerView.getAdapterPositionFor + * @see RecyclerView.ViewHolder.getAdapterPosition + */ + fun onItemDismiss(position: Int) +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperViewHolder.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperViewHolder.kt new file mode 100644 index 0000000000..a873e5253d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/ItemTouchHelperViewHolder.kt @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.general.automation.dragHelpers + +/** + * Interface to notify an item ViewHolder of relevant callbacks from [ ]. + * + * @author Paul Burke (ipaulpro) + */ +interface ItemTouchHelperViewHolder { + /** + * Called when the [ItemTouchHelper] first registers an item as being moved or swiped. + * Implementations should update the item view to indicate it's active state. + */ + fun onItemSelected() + + /** + * Called when the [ItemTouchHelper] has completed the move or swipe, and the active item + * state should be cleared. + */ + fun onItemClear() +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/OnStartDragListener.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/OnStartDragListener.kt new file mode 100644 index 0000000000..9a90a360de --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/OnStartDragListener.kt @@ -0,0 +1,12 @@ +package info.nightscout.androidaps.plugins.general.automation.dragHelpers + +import androidx.recyclerview.widget.RecyclerView + +interface OnStartDragListener { + /** + * Called when a view is requesting a start of a drag. + * + * @param viewHolder The holder of the view to drag. + */ + fun onStartDrag(viewHolder: RecyclerView.ViewHolder) +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/SimpleItemTouchHelperCallback.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/SimpleItemTouchHelperCallback.kt new file mode 100644 index 0000000000..7e66046e73 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dragHelpers/SimpleItemTouchHelperCallback.kt @@ -0,0 +1,85 @@ +package info.nightscout.androidaps.plugins.general.automation.dragHelpers + +import android.graphics.Canvas +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import kotlin.math.abs + + +/** + * An implementation of [ItemTouchHelper.Callback] that enables basic drag & drop and + * swipe-to-dismiss. Drag events are automatically started by an item long-press.

+ * + * Expects the `RecyclerView.Adapter` to listen for [ ] callbacks and the `RecyclerView.ViewHolder` to implement + * [ItemTouchHelperViewHolder]. + * + */ +class SimpleItemTouchHelperCallback(private val mAdapter: ItemTouchHelperAdapter) : ItemTouchHelper.Callback() { + override fun isLongPressDragEnabled(): Boolean { + return true + } + + override fun isItemViewSwipeEnabled(): Boolean { + return true + } + + override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { // Set movement flags based on the layout manager + return if (recyclerView.layoutManager is GridLayoutManager) { + val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + val swipeFlags = 0 + makeMovementFlags(dragFlags, swipeFlags) + } else { + val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN + val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END + makeMovementFlags(dragFlags, swipeFlags) + } + } + + override fun onMove(recyclerView: RecyclerView, source: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + if (source.itemViewType != target.itemViewType) { + return false + } + // Notify the adapter of the move + mAdapter.onItemMove(source.adapterPosition, target.adapterPosition) + return true + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) { // Notify the adapter of the dismissal + mAdapter.onItemDismiss(viewHolder.adapterPosition) + } + + override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { // Fade out the view as it is swiped out of the parent's bounds + val alpha = ALPHA_FULL - abs(dX) / viewHolder.itemView.width.toFloat() + viewHolder.itemView.alpha = alpha + viewHolder.itemView.translationX = dX + } else { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) + } + } + + override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { // We only want the active item to change + if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { + if (viewHolder is ItemTouchHelperViewHolder) { // Let the view holder know that this item is being moved or dragged + val itemViewHolder: ItemTouchHelperViewHolder = viewHolder + itemViewHolder.onItemSelected() + } + } + super.onSelectedChanged(viewHolder, actionState) + } + + override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { + super.clearView(recyclerView, viewHolder) + viewHolder.itemView.alpha = ALPHA_FULL + if (viewHolder is ItemTouchHelperViewHolder) { // Tell the view holder it's time to restore the idle state + val itemViewHolder: ItemTouchHelperViewHolder = viewHolder + itemViewHolder.onItemClear() + } + } + + companion object { + const val ALPHA_FULL = 1.0f + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java index 0809ed96d8..ff4781552a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java @@ -25,7 +25,7 @@ public class InputBg extends Element { public InputBg() { super(); - setUnits(ProfileFunctions.getInstance().getProfileUnits()); + setUnits(ProfileFunctions.getSystemUnits()); if (getUnits().equals(Constants.MMOL)) value = MMOL_MIN; else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java index 7e9207c0e1..e0fabcf0dd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java @@ -37,7 +37,7 @@ public class InputTempTarget extends Element { public InputTempTarget() { super(); - setUnits(ProfileFunctions.getInstance().getProfileUnits()); + setUnits(ProfileFunctions.getSystemUnits()); if (getUnits().equals(Constants.MMOL)) value = 6; else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java index 69ac67bf07..c1bca15028 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java @@ -1,12 +1,12 @@ package info.nightscout.androidaps.plugins.general.automation.triggers; -import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import com.google.common.base.Optional; @@ -84,11 +84,11 @@ public abstract class Trigger { } @Nullable - Activity scanForActivity(Context cont) { + AppCompatActivity scanForActivity(Context cont) { if (cont == null) return null; - else if (cont instanceof Activity) - return (Activity) cont; + else if (cont instanceof AppCompatActivity) + return (AppCompatActivity) cont; else if (cont instanceof ContextWrapper) return scanForActivity(((ContextWrapper) cont).getBaseContext()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java index eee649307b..6fb2053fbc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java @@ -45,7 +45,7 @@ public class TriggerDelta extends Trigger { public TriggerDelta() { super(); - this.units = ProfileFunctions.getInstance().getProfileUnits(); + this.units = ProfileFunctions.getSystemUnits(); initializer(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java index 89c8d17085..2031dbc74c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.general.automation.triggers; -import android.app.Activity; import android.graphics.Typeface; import android.text.format.DateFormat; import android.view.ViewGroup; @@ -9,6 +8,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import com.dpro.widgets.WeekdaysPicker; @@ -269,6 +269,8 @@ public class TriggerRecurringTime extends Trigger { weekdaysPicker.setSelectedDays(getSelectedDays()); weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> set(DayOfWeek.fromCalendarInt(i), list.contains(i))); weekdaysPicker.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + weekdaysPicker.setSundayFirstDay(Calendar.getInstance().getFirstDayOfWeek() == Calendar.SUNDAY); + weekdaysPicker.redrawDays(); root.addView(weekdaysPicker); @@ -294,9 +296,9 @@ public class TriggerRecurringTime extends Trigger { ); tpd.setThemeDark(true); tpd.dismissOnPause(true); - Activity a = scanForActivity(root.getContext()); + AppCompatActivity a = scanForActivity(root.getContext()); if (a != null) - tpd.show(a.getFragmentManager(), "TimePickerDialog"); + tpd.show(a.getSupportFragmentManager(), "TimePickerDialog"); }); int px = MainApp.dpToPx(10); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java index 08f9a65aa7..91e739ca45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java @@ -1,12 +1,12 @@ package info.nightscout.androidaps.plugins.general.automation.triggers; -import android.app.Activity; import android.graphics.Typeface; import android.text.format.DateFormat; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import com.google.common.base.Optional; @@ -142,9 +142,9 @@ public class TriggerTime extends Trigger { ); dpd.setThemeDark(true); dpd.dismissOnPause(true); - Activity a = scanForActivity(root.getContext()); + AppCompatActivity a = scanForActivity(root.getContext()); if (a != null) - dpd.show(a.getFragmentManager(), "DatePickerDialog"); + dpd.show(a.getSupportFragmentManager(), "DatePickerDialog"); }); timeButton.setOnClickListener(view -> { GregorianCalendar calendar = new GregorianCalendar(); @@ -162,9 +162,9 @@ public class TriggerTime extends Trigger { ); tpd.setThemeDark(true); tpd.dismissOnPause(true); - Activity a = scanForActivity(root.getContext()); + AppCompatActivity a = scanForActivity(root.getContext()); if (a != null) - tpd.show(a.getFragmentManager(), "TimePickerDialog"); + tpd.show(a.getSupportFragmentManager(), "TimePickerDialog"); }); int px = MainApp.dpToPx(10); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java index 1d03871620..082c5af75c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java @@ -1,12 +1,12 @@ package info.nightscout.androidaps.plugins.general.automation.triggers; -import android.app.Activity; import android.graphics.Typeface; import android.text.format.DateFormat; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import com.google.common.base.Optional; @@ -18,7 +18,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Calendar; -import java.util.Date; import java.util.GregorianCalendar; import info.nightscout.androidaps.MainApp; @@ -33,14 +32,14 @@ import info.nightscout.androidaps.utils.T; public class TriggerTimeRange extends Trigger { private static Logger log = LoggerFactory.getLogger(L.AUTOMATION); - + // in minutes since midnight 60 means 1AM private int start; private int end; long timeZoneOffset = DateUtil.getTimeZoneOffsetMs(); public TriggerTimeRange() { - + start = getMinSinceMidnight(DateUtil.now()); end = getMinSinceMidnight(DateUtil.now()); } @@ -60,11 +59,11 @@ public class TriggerTimeRange extends Trigger { return false; boolean doRun = false; - if ( start < end && start < currentMinSinceMidnight && currentMinSinceMidnight < end) + if (start < end && start < currentMinSinceMidnight && currentMinSinceMidnight < end) doRun = true; - // handle cases like 10PM to 6AM - else if ( start > end && (start < currentMinSinceMidnight || currentMinSinceMidnight < end)) + // handle cases like 10PM to 6AM + else if (start > end && (start < currentMinSinceMidnight || currentMinSinceMidnight < end)) doRun = true; if (doRun) { @@ -129,8 +128,8 @@ public class TriggerTimeRange extends Trigger { } TriggerTimeRange period(int start, int end) { - this.start = getMinSinceMidnight(start*60000); - this.end = getMinSinceMidnight(end*60000); + this.start = getMinSinceMidnight(start * 60000); + this.end = getMinSinceMidnight(end * 60000); return this; } @@ -145,7 +144,7 @@ public class TriggerTimeRange extends Trigger { } long toMilis(long minutesSinceMidnight) { - return minutesSinceMidnight*60*1000; + return minutesSinceMidnight * 60 * 1000; } public int getMinSinceMidnight(long time) { @@ -157,11 +156,11 @@ public class TriggerTimeRange extends Trigger { return (calendar.get(Calendar.HOUR_OF_DAY) * 60) + calendar.get(Calendar.MINUTE); } - int getStart(){ + int getStart() { return start; } - int getEnd(){ + int getEnd() { return end; } @@ -170,8 +169,8 @@ public class TriggerTimeRange extends Trigger { TextView label = new TextView(root.getContext()); TextView startButton = new TextView(root.getContext()); TextView endButton = new TextView(root.getContext()); - log.debug("Start is: " + start ); - log.debug("End is: " + end ); + log.debug("Start is: " + start); + log.debug("End is: " + end); startButton.setText(DateUtil.timeString(toMilis(start) - timeZoneOffset)); endButton.setText(MainApp.gs(R.string.and) + " " + DateUtil.timeString(toMilis(end) - timeZoneOffset)); @@ -193,9 +192,9 @@ public class TriggerTimeRange extends Trigger { ); tpd.setThemeDark(true); tpd.dismissOnPause(true); - Activity a = scanForActivity(root.getContext()); + AppCompatActivity a = scanForActivity(root.getContext()); if (a != null) - tpd.show(a.getFragmentManager(), "TimePickerDialog"); + tpd.show(a.getSupportFragmentManager(), "TimePickerDialog"); }); endButton.setOnClickListener(view -> { GregorianCalendar calendar = new GregorianCalendar(); @@ -213,9 +212,9 @@ public class TriggerTimeRange extends Trigger { ); tpd.setThemeDark(true); tpd.dismissOnPause(true); - Activity a = scanForActivity(root.getContext()); + AppCompatActivity a = scanForActivity(root.getContext()); if (a != null) - tpd.show(a.getFragmentManager(), "TimePickerDialog"); + tpd.show(a.getSupportFragmentManager(), "TimePickerDialog"); }); int px = MainApp.dpToPx(10); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java index 8818638201..64b7b05987 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java @@ -1,10 +1,8 @@ package info.nightscout.androidaps.plugins.general.careportal.Dialogs; -import android.app.Activity; +import android.content.Context; import android.os.Bundle; -import androidx.fragment.app.DialogFragment; -import androidx.appcompat.app.AlertDialog; import android.text.Editable; import android.text.TextWatcher; import android.text.format.DateFormat; @@ -20,9 +18,12 @@ import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.DialogFragment; + import com.google.common.collect.Lists; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; -import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout; import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; import org.json.JSONException; @@ -39,7 +40,6 @@ import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.BgReading; @@ -51,6 +51,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DefaultValueHelper; @@ -61,17 +62,14 @@ import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.Translator; -public class NewNSTreatmentDialog extends DialogFragment implements View.OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener { +public class NewNSTreatmentDialog extends AppCompatDialogFragment implements View.OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener { private static Logger log = LoggerFactory.getLogger(NewNSTreatmentDialog.class); - private Activity context; - private static OptionsToShow options; private static String event; Profile profile; public ProfileStore profileStore; - String units = Constants.MGDL; TextView eventTypeText; LinearLayout layoutPercent; @@ -120,18 +118,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } - @Override - public void onAttach(Activity activity) { - context = activity; - super.onAttach(activity); - } - - @Override - public void onDetach() { - super.onDetach(); - this.context = null; - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -179,7 +165,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } else { ArrayList profileList; - units = profile != null ? profile.getUnits() : Constants.MGDL; profileList = profileStore.getProfileList(); ArrayAdapter adapter = new ArrayAdapter<>(getContext(), R.layout.spinner_centered, profileList); @@ -190,7 +175,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSpinner.setSelection(p); } } - final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); + final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, ProfileFunctions.getSystemUnits()); // temp target final List reasonList = Lists.newArrayList( @@ -205,8 +190,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { double defaultDuration; - double defaultTarget = 0; - if (profile != null && editTemptarget.getValue() == bg) { + double defaultTarget; + if (profile != null && editTemptarget.getValue().equals(bg)) { defaultTarget = bg; } else { //prevent changes on screen rotate @@ -214,17 +199,17 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } boolean erase = false; - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); DefaultValueHelper helper = new DefaultValueHelper(); if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) { defaultDuration = helper.determineEatingSoonTTDuration(); - defaultTarget = helper.determineEatingSoonTT(units); + defaultTarget = helper.determineEatingSoonTT(); } else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) { defaultDuration = helper.determineActivityTTDuration(); - defaultTarget = helper.determineActivityTT(units); + defaultTarget = helper.determineActivityTT(); } else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) { defaultDuration = helper.determineHypoTTDuration(); - defaultTarget = helper.determineHypoTT(units); + defaultTarget = helper.determineHypoTT(); } else if (editDuration.getValue() != 0) { defaultDuration = editDuration.getValue(); } else { @@ -249,7 +234,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick }); // bg - bgUnitsView.setText(units); + bgUnitsView.setText(ProfileFunctions.getSystemUnits()); TextWatcher bgTextWatcher = new TextWatcher() { @@ -268,7 +253,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (profile == null) { editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), bgTextWatcher); editTemptarget.setParams(Constants.MIN_TT_MGDL, Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok)); - } else if (units.equals(Constants.MMOL)) { + } else if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) { editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), bgTextWatcher); editTemptarget.setParams(Constants.MIN_TT_MMOL, Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok)); } else { @@ -277,7 +262,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { - Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); + Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, ProfileFunctions.getSystemUnits()); if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) { editBg.setValue(savedInstanceState.getDouble("editBg")); } else { @@ -286,16 +271,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick }); Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); - editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput); + editCarbs = view.findViewById(R.id.careportal_newnstreatment_carbsinput); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok)); Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); - editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput); + editInsulin = view.findViewById(R.id.careportal_newnstreatment_insulininput); editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false, view.findViewById(R.id.ok)); - editSplit = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_splitinput); + editSplit = view.findViewById(R.id.careportal_newnstreatment_splitinput); editSplit.setParams(100d, 0d, 100d, 5d, new DecimalFormat("0"), true, view.findViewById(R.id.ok)); - editDuration = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_durationinput); + editDuration = view.findViewById(R.id.careportal_newnstreatment_durationinput); editDuration.setParams(0d, 0d, Constants.MAX_PROFILE_SWITCH_DURATION, 10d, new DecimalFormat("0"), false, view.findViewById(R.id.ok)); TextWatcher percentTextWatcher = new TextWatcher() { @@ -319,7 +304,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick Integer maxPercent = 200; if (profile != null) maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value(); - editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput); + editPercent = view.findViewById(R.id.careportal_newnstreatment_percentinput); editPercent.setParams(0d, -100d, (double) maxPercent, 5d, new DecimalFormat("0"), true, view.findViewById(R.id.ok), percentTextWatcher); TextWatcher absoluteTextWatcher = new TextWatcher() { @@ -343,16 +328,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick Double maxAbsolute = HardLimits.maxBasal(); if (profile != null) maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); - editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput); + editAbsolute = view.findViewById(R.id.careportal_newnstreatment_absoluteinput); editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, view.findViewById(R.id.ok), absoluteTextWatcher); - editCarbTime = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbtimeinput); + editCarbTime = view.findViewById(R.id.careportal_newnstreatment_carbtimeinput); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false, view.findViewById(R.id.ok)); - editPercentage = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentage); + editPercentage = view.findViewById(R.id.careportal_newnstreatment_percentage); editPercentage.setParams(100d, (double) Constants.CPP_MIN_PERCENTAGE, (double) Constants.CPP_MAX_PERCENTAGE, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok)); - editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift); + editTimeshift = view.findViewById(R.id.careportal_newnstreatment_timeshift); editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok)); ProfileSwitch ps = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()); @@ -369,21 +354,21 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick options.duration = false; } - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bgsource_layout), options.bg); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_insulin_layout), options.insulin); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_carbs_layout), options.carbs); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_split_layout), options.split); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_duration_layout), options.duration); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_bgsource_layout), options.bg); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_insulin_layout), options.insulin); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_carbs_layout), options.carbs); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_split_layout), options.split); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_duration_layout), options.duration); showOrHide(layoutPercent, options.percent); showOrHide(layoutAbsolute, options.absolute); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_carbtime_layout), options.prebolus); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_profile_layout), options.profile); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_percentage_layout), options.profile); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_timeshift_layout), options.profile); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_reuse_layout), options.profile && ps != null && ps.isCPP); - showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_temptarget_layout), options.tempTarget); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_carbtime_layout), options.prebolus); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_profile_layout), options.profile); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_percentage_layout), options.profile); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_timeshift_layout), options.profile); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_reuse_layout), options.profile && ps != null && ps.isCPP); + showOrHide(view.findViewById(R.id.careportal_newnstreatment_temptarget_layout), options.tempTarget); setCancelable(true); getDialog().setCanceledOnTouchOutside(false); @@ -423,18 +408,18 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick ); dpd.setThemeDark(true); dpd.dismissOnPause(true); - dpd.show(context.getFragmentManager(), "Datepickerdialog"); + dpd.show(getActivity().getSupportFragmentManager(), "Datepickerdialog"); break; case R.id.careportal_newnstreatment_eventtime: TimePickerDialog tpd = TimePickerDialog.newInstance( this, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), - DateFormat.is24HourFormat(context) + DateFormat.is24HourFormat(getContext()) ); tpd.setThemeDark(true); tpd.dismissOnPause(true); - tpd.show(context.getFragmentManager(), "Timepickerdialog"); + tpd.show(getActivity().getSupportFragmentManager(), "Timepickerdialog"); break; case R.id.ok: confirmNSTreatmentCreation(); @@ -457,7 +442,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if ((data.size() > 0) && (data.get(0).date > millis - 7 * 60 * 1000L) && (data.get(0).date < millis + 7 * 60 * 1000L)) { - editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, units)); + editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, ProfileFunctions.getSystemUnits())); } } @@ -471,7 +456,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } @Override - public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { + public void onTimeSet(TimePickerDialog view, int hourOfDay, int minute, int second) { eventTime.setHours(hourOfDay); eventTime.setMinutes(minute); eventTime.setSeconds(this.seconds++); // randomize seconds to prevent creating record of the same time, if user choose time manually @@ -479,7 +464,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick updateBGforDateTime(); } - JSONObject gatherData() { String enteredBy = SP.getString("careportal_enteredby", ""); JSONObject data = new JSONObject(); @@ -585,7 +569,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick data.put("preBolus", SafeParse.stringToDouble(editCarbTime.getText())); if (!notesEdit.getText().toString().equals("")) data.put("notes", notesEdit.getText().toString()); - data.put("units", units); + data.put("units", ProfileFunctions.getSystemUnits()); if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); if (options.eventType == R.id.careportal_combobolus) { Double enteredInsulin = SafeParse.stringToDouble(editInsulin.getText()); @@ -611,7 +595,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick ret += MainApp.gs(R.string.treatments_wizard_bg_label); ret += ": "; ret += JsonHelper.safeGetObject(data, "glucose", ""); - ret += " " + units + "\n"; + ret += " " + ProfileFunctions.getSystemUnits() + "\n"; } if (data.has("glucoseType")) { ret += MainApp.gs(R.string.careportal_newnstreatment_glucosetype); @@ -704,6 +688,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } void confirmNSTreatmentCreation() { + Context context = getContext(); if (context != null) { final JSONObject data = gatherData(); final String confirmText = buildConfirmText(data); @@ -717,7 +702,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } - public void createNSTreatment(JSONObject data) { + void createNSTreatment(JSONObject data) { if (options.executeProfileSwitch) { if (data.has("profile")) { ProfileFunctions.doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift")); @@ -734,8 +719,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick .reason(reason) .source(Source.USER); if (tempTarget.durationInMinutes != 0) { - tempTarget.low(Profile.toMgdl(targetBottom, units)) - .high(Profile.toMgdl(targetTop, units)); + tempTarget.low(Profile.toMgdl(targetBottom, ProfileFunctions.getSystemUnits())) + .high(Profile.toMgdl(targetTop, ProfileFunctions.getSystemUnits())); } else { tempTarget.low(0).high(0); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java index 7a801a44c0..ae9867b0a2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/ImportExportPrefs.java @@ -30,6 +30,7 @@ import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.utils.OKDialog; +import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.ToastUtils; /** @@ -113,27 +114,24 @@ public class ImportExportPrefs { .setMessage(MainApp.gs(R.string.import_from) + " " + file + " ?") .setPositiveButton(android.R.string.yes, (dialog, which) -> { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); String line; String[] lineParts; try { - editor.clear(); - editor.commit(); + SP.clear(); BufferedReader reader = new BufferedReader(new FileReader(file)); while ((line = reader.readLine()) != null) { lineParts = line.split("::"); if (lineParts.length == 2) { if (lineParts[1].equals("true") || lineParts[1].equals("false")) { - editor.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1])); + SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1])); } else { - editor.putString(lineParts[0], lineParts[1]); + SP.putString(lineParts[0], lineParts[1]); } } } reader.close(); - editor.commit(); + SP.putBoolean(R.string.key_setupwizard_processed, true); OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> { log.debug("Exiting"); MainApp.instance().stopKeepAliveService(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/LogSettingActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/LogSettingActivity.kt index f47bb03513..d9ed0c590c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/LogSettingActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/activities/LogSettingActivity.kt @@ -6,11 +6,11 @@ import android.widget.CheckBox import android.widget.LinearLayout import android.widget.TextView import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.NoSplashActivity +import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.logging.L import kotlinx.android.synthetic.main.activity_logsetting.* -class LogSettingActivity : NoSplashActivity() { +class LogSettingActivity : NoSplashAppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index f5582b71a2..582eedb0e7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -312,21 +312,14 @@ public class NSUpload { public static void uploadTempTarget(TempTarget tempTarget) { try { - Profile profile = ProfileFunctions.getInstance().getProfile(); - - if (profile == null) { - log.error("Profile is null. Skipping upload"); - return; - } - JSONObject data = new JSONObject(); data.put("eventType", CareportalEvent.TEMPORARYTARGET); data.put("duration", tempTarget.durationInMinutes); data.put("reason", tempTarget.reason); - data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits())); - data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, profile.getUnits())); + data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, ProfileFunctions.getSystemUnits())); + data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, ProfileFunctions.getSystemUnits())); data.put("created_at", DateUtil.toISOString(tempTarget.date)); - data.put("units", profile.getUnits()); + data.put("units", ProfileFunctions.getSystemUnits()); data.put("enteredBy", MainApp.gs(R.string.app_name)); uploadCareportalEntryToNS(data); } catch (JSONException e) { @@ -517,6 +510,21 @@ public class NSUpload { } } + public static void uploadProfileStore(JSONObject profileStore) { + if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) { + Context context = MainApp.instance().getApplicationContext(); + Bundle bundle = new Bundle(); + bundle.putString("action", "dbAdd"); + bundle.putString("collection", "profile"); + bundle.putString("data", String.valueOf(profileStore)); + Intent intent = new Intent(Intents.ACTION_DATABASE); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + DbLogger.dbAdd(intent, String.valueOf(profileStore)); + } + } + public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) { Context context = MainApp.instance().getApplicationContext(); Bundle bundle = new Bundle(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 046290500d..f3b718743e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -760,36 +760,36 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, pvd.show(manager, "ProfileViewDialog"); } else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) { DefaultValueHelper defHelper = new DefaultValueHelper(); - double target = defHelper.determineEatingSoonTT(profile.getUnits()); + double target = Profile.toMgdl(defHelper.determineEatingSoonTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(System.currentTimeMillis()) .duration(defHelper.determineEatingSoonTTDuration()) .reason(MainApp.gs(R.string.eatingsoon)) .source(Source.USER) - .low(Profile.toMgdl(target, profile.getUnits())) - .high(Profile.toMgdl(target, profile.getUnits())); + .low(target) + .high(target); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (item.getTitle().equals(MainApp.gs(R.string.activity))) { DefaultValueHelper defHelper = new DefaultValueHelper(); - double target = defHelper.determineActivityTT(profile.getUnits()); + double target = Profile.toMgdl(defHelper.determineActivityTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(now()) .duration(defHelper.determineActivityTTDuration()) .reason(MainApp.gs(R.string.activity)) .source(Source.USER) - .low(Profile.toMgdl(target, profile.getUnits())) - .high(Profile.toMgdl(target, profile.getUnits())); + .low(target) + .high(target); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) { DefaultValueHelper defHelper = new DefaultValueHelper(); - double target = defHelper.determineHypoTT(profile.getUnits()); + double target = Profile.toMgdl(defHelper.determineHypoTT(), ProfileFunctions.getSystemUnits()); TempTarget tempTarget = new TempTarget() .date(now()) .duration(defHelper.determineHypoTTDuration()) .reason(MainApp.gs(R.string.hypo)) .source(Source.USER) - .low(Profile.toMgdl(target, profile.getUnits())) - .high(Profile.toMgdl(target, profile.getUnits())); + .low(target) + .high(target); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (item.getTitle().equals(MainApp.gs(R.string.custom))) { NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); @@ -814,7 +814,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, public void onClick(View v) { boolean xdrip = SourceXdripPlugin.getPlugin().isEnabled(PluginType.BGSOURCE); boolean dexcom = SourceDexcomPlugin.INSTANCE.isEnabled(PluginType.BGSOURCE); - String units = ProfileFunctions.getInstance().getProfileUnits(); FragmentManager manager = getFragmentManager(); // try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days @@ -1041,9 +1040,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final Profile profile = ProfileFunctions.getInstance().getProfile(); final String profileName = ProfileFunctions.getInstance().getProfileName(); - final String units = profile.getUnits(); - final double lowLine = OverviewPlugin.INSTANCE.determineLowLine(units); - final double highLine = OverviewPlugin.INSTANCE.determineHighLine(units); + final String units = ProfileFunctions.getSystemUnits(); + final double lowLine = OverviewPlugin.INSTANCE.determineLowLine(); + final double highLine = OverviewPlugin.INSTANCE.determineHighLine(); //Start with updating the BG as it is unaffected by loop. // **** BG value **** @@ -1126,7 +1125,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else { tempTargetView.setTextColor(MainApp.gc(R.color.ribbonTextDefault)); tempTargetView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault)); - tempTargetView.setText(Profile.toTargetRangeString(profile.getTargetLow(), profile.getTargetHigh(), units, units)); + tempTargetView.setText(Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), Constants.MGDL, units)); tempTargetView.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt index cece359f22..96d6396f87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewPlugin.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.general.overview -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.events.EventRefreshOverview @@ -9,7 +8,6 @@ import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.plugins.bus.RxBus -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore @@ -65,22 +63,17 @@ object OverviewPlugin : PluginBase(PluginDescription() super.onStop() } - fun determineHighLine(units: String): Double { - var highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(bgTargetHigh, units))!! - if (highLineSetting < 1) - highLineSetting = Profile.fromMgdlToUnits(180.0, units) + fun determineHighLine(): Double { + var highLineSetting = SP.getDouble(R.string.key_high_mark, bgTargetHigh) + if (highLineSetting < 1) highLineSetting = 180.0 + highLineSetting = Profile.toCurrentUnits(highLineSetting) return highLineSetting } fun determineLowLine(): Double { - val profile = ProfileFunctions.getInstance().profile ?: return bgTargetLow - return determineLowLine(profile.units) - } - - fun determineLowLine(units: String): Double { - var lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(bgTargetLow, units))!! - if (lowLineSetting < 1) - lowLineSetting = Profile.fromMgdlToUnits(76.0, units) + var lowLineSetting = SP.getDouble(R.string.key_low_mark, bgTargetLow) + if (lowLineSetting < 1) lowLineSetting = 76.0 + lowLineSetting = Profile.toCurrentUnits(lowLineSetting) return lowLineSetting } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java index 23c3fd2cec..15d9f11a2b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java @@ -12,6 +12,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SetWarnColor; @@ -34,10 +35,14 @@ class StatuslightHandler { applyStatuslight("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN", 164, 166); - double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1; - applyStatuslightLevel(R.string.key_statuslights_bat_critical, 5.0, - R.string.key_statuslights_bat_warning, 22.0, - batteryView, "BAT", batteryLevel); + if (pump.model() != PumpType.AccuChekCombo) { + double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1; + applyStatuslightLevel(R.string.key_statuslights_bat_critical, 5.0, + R.string.key_statuslights_bat_warning, 22.0, + batteryView, "BAT", batteryLevel); + } else { + applyStatuslight("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT", 504, 240); + } } @@ -105,9 +110,14 @@ class StatuslightHandler { handleAge("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN ", 164, 166); - handleLevel(R.string.key_statuslights_bat_critical, 26.0, - R.string.key_statuslights_bat_warning, 51.0, - batteryView, "BAT ", pump.getBatteryLevel()); + if (pump.model() != PumpType.AccuChekCombo) { + handleLevel(R.string.key_statuslights_bat_critical, 26.0, + R.string.key_statuslights_bat_warning, 51.0, + batteryView, "BAT ", pump.getBatteryLevel()); + } else { + handleAge("bage", CareportalEvent.PUMPBATTERYCHANGE, batteryView, "BAT ", + 336, 240); + } } void handleAge(String nsSettingPlugin, String eventName, TextView view, String text, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java index a82f94d2ff..4c5d5b5d80 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java @@ -60,7 +60,7 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this); - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); bgNumber = (NumberPicker) view.findViewById(R.id.overview_calibration_bg); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewCarbsDialog.java index 23352f3d5b..36cfd07be9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewCarbsDialog.java @@ -1,7 +1,6 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs; import android.os.Bundle; -import android.os.HandlerThread; import androidx.fragment.app.DialogFragment; import androidx.appcompat.app.AlertDialog; import android.text.Editable; @@ -316,36 +315,36 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C int carbs = editCarbs.getValue().intValue(); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value(); - final String units = currentProfile.getUnits(); + final String units = ProfileFunctions.getSystemUnits(); DefaultValueHelper helper = new DefaultValueHelper(); int activityTTDuration = helper.determineActivityTTDuration(); - double activityTT = helper.determineActivityTT(units); + double activityTT = helper.determineActivityTT(); int eatingSoonTTDuration = helper.determineEatingSoonTTDuration(); - double eatingSoonTT = helper.determineEatingSoonTT(units); + double eatingSoonTT = helper.determineEatingSoonTT(); int hypoTTDuration = helper.determineHypoTTDuration(); - double hypoTT = helper.determineHypoTT(units); + double hypoTT = helper.determineHypoTT(); List actions = new LinkedList<>(); if (startActivityTTCheckbox.isChecked()) { String unitLabel = "mg/dl"; - if (currentProfile.getUnits().equals(Constants.MMOL)) { + if (units.equals(Constants.MMOL)) { unitLabel = "mmol/l"; } actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)"); } if (startEatingSoonTTCheckbox.isChecked()) { - if (currentProfile.getUnits().equals(Constants.MMOL)) { + if (units.equals(Constants.MMOL)) { actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)"); } else { actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)"); } } if (startHypoTTCheckbox.isChecked()) { - if (currentProfile.getUnits().equals(Constants.MMOL)) { + if (units.equals(Constants.MMOL)) { actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)"); } else { actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)"); @@ -398,8 +397,8 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C .duration(finalActivityTTDuration) .reason(MainApp.gs(R.string.activity)) .source(Source.USER) - .low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits())) - .high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits())); + .low(Profile.toMgdl(finalActivityTT, ProfileFunctions.getSystemUnits())) + .high(Profile.toMgdl(finalActivityTT, ProfileFunctions.getSystemUnits())); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (startEatingSoonTTCheckbox.isChecked()) { TempTarget tempTarget = new TempTarget() @@ -407,8 +406,8 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C .duration(finalEatingSoonTTDuration) .reason(MainApp.gs(R.string.eatingsoon)) .source(Source.USER) - .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())) - .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())); + .low(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits())) + .high(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits())); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } else if (startHypoTTCheckbox.isChecked()) { TempTarget tempTarget = new TempTarget() @@ -416,8 +415,8 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C .duration(finalHypoTTDuration) .reason(MainApp.gs(R.string.hypo)) .source(Source.USER) - .low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits())) - .high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits())); + .low(Profile.toMgdl(finalHypoTT, ProfileFunctions.getSystemUnits())) + .high(Profile.toMgdl(finalHypoTT, ProfileFunctions.getSystemUnits())); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewInsulinDialog.java index d5d4308f63..b708296776 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewInsulinDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/NewInsulinDialog.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.os.HandlerThread; import androidx.fragment.app.DialogFragment; import androidx.appcompat.app.AlertDialog; import android.text.Editable; @@ -56,9 +55,9 @@ import static info.nightscout.androidaps.utils.DateUtil.now; public class NewInsulinDialog extends DialogFragment implements OnClickListener { private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class); - public static final double PLUS1_DEFAULT = 0.5d; - public static final double PLUS2_DEFAULT = 1d; - public static final double PLUS3_DEFAULT = 2d; + private static final double PLUS1_DEFAULT = 0.5d; + private static final double PLUS2_DEFAULT = 1d; + private static final double PLUS3_DEFAULT = 2d; private CheckBox startEatingSoonTTCheckbox; private CheckBox recordOnlyCheckbox; @@ -207,9 +206,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener okClicked = true; try { - Profile currentProfile = ProfileFunctions.getInstance().getProfile(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - if (currentProfile == null || pump == null) + if (pump == null) return; Double insulin = SafeParse.stringToDouble(editInsulin.getText()); @@ -228,11 +226,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration); eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration; - double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl); - eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl; + double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, ProfileFunctions.getSystemUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl); + eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : ProfileFunctions.getSystemUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl; if (startEatingSoonTTCheckbox.isChecked()) { - if (currentProfile.getUnits().equals(Constants.MMOL)) { + if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) { actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)"); } else actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)"); @@ -272,8 +270,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener .duration(finalEatingSoonTTDuration) .reason(MainApp.gs(R.string.eatingsoon)) .source(Source.USER) - .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())) - .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())); + .low(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits())) + .high(Profile.toMgdl(finalEatigSoonTT, ProfileFunctions.getSystemUnits())); TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt index efe800bef0..46462b0dfc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt @@ -214,7 +214,7 @@ class WizardDialog : DialogFragment() { } val profileList: ArrayList - profileList = profileStore.profileList + profileList = profileStore.getProfileList() profileList.add(0, MainApp.gs(R.string.active)) context?.let { context -> val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList) @@ -222,7 +222,7 @@ class WizardDialog : DialogFragment() { } ?: return - val units = profile.units + val units = ProfileFunctions.getSystemUnits() treatments_wizard_bgunits.text = units if (units == Constants.MGDL) treatments_wizard_bg_input.setStep(1.0) @@ -302,7 +302,7 @@ class WizardDialog : DialogFragment() { treatment_wizard_notes.text.toString(), carbTime) wizard?.let { wizard -> - treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, specificProfile.units)).valueToUnitsToString(specificProfile.units), wizard.sens) + treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, ProfileFunctions.getSystemUnits())).valueToUnitsToString(ProfileFunctions.getSystemUnits()), wizard.sens) treatments_wizard_bginsulin.text = StringUtils.formatInsulin(wizard.insulinFromBG) treatments_wizard_carbs.text = String.format(MainApp.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic) @@ -320,8 +320,8 @@ class WizardDialog : DialogFragment() { // Trend if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) { treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "") - + Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, specificProfile.units) - + " " + specificProfile.units) + + Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits()) + + " " + ProfileFunctions.getSystemUnits()) } else { treatments_wizard_bgtrend.text = "" } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.java index 6de3e2c335..a3dc3c4212 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphData/GraphData.java @@ -69,7 +69,7 @@ public class GraphData { private IobCobCalculatorPlugin iobCobCalculatorPlugin; public GraphData(GraphView graph, IobCobCalculatorPlugin iobCobCalculatorPlugin) { - units = ProfileFunctions.getInstance().getProfileUnits(); + units = ProfileFunctions.getSystemUnits(); this.graph = graph; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; } @@ -264,9 +264,9 @@ public class GraphData { TempTarget tt = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(time); double value; if (tt == null) { - value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2; + value = Profile.fromMgdlToUnits((profile.getTargetLowMgdl(time) + profile.getTargetHighMgdl(time)) / 2, ProfileFunctions.getSystemUnits()); } else { - value = Profile.fromMgdlToUnits(tt.target(), profile.getUnits()); + value = Profile.fromMgdlToUnits(tt.target(), ProfileFunctions.getSystemUnits()); } if (lastTarget != value) { if (lastTarget != -1) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java index fdee040682..1cc2b1426a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java @@ -181,7 +181,7 @@ public class PersistentNotificationPlugin extends PluginBase { line1 = MainApp.gs(R.string.loading); } else if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ProfileFunctions.getInstance().isProfileValid("Notification")) { String line1_aa; - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); BgReading lastBG = DatabaseHelper.lastBg(); 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 e40ed8b1df..1d449f2ba1 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 @@ -259,7 +259,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() val actualBG = DatabaseHelper.actualBg() val lastBG = DatabaseHelper.lastBg() var reply = "" - val units = ProfileFunctions.getInstance().profileUnits + val units = ProfileFunctions.getSystemUnits() if (actualBG != null) { reply = MainApp.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", " } else if (lastBG != null) { @@ -428,7 +428,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() receivedSms.processed = true return } - val list = store.profileList + val list = store.getProfileList() if (splitted[1].toUpperCase(Locale.getDefault()) == "STATUS") { sendSMS(Sms(receivedSms.phoneNumber, ProfileFunctions.getInstance().profileName)) } else if (splitted[1].toUpperCase(Locale.getDefault()) == "LIST") { @@ -735,50 +735,47 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() receivedSms.processed = true messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() { override fun run() { - val currentProfile = ProfileFunctions.getInstance().profile - if (currentProfile != null) { - var keyDuration = 0 - var defaultTargetDuration = 0 - var keyTarget = 0 - var defaultTargetMMOL = 0.0 - var defaultTargetMGDL = 0.0 - if (isMeal) { - keyDuration = R.string.key_eatingsoon_duration - defaultTargetDuration = Constants.defaultEatingSoonTTDuration - keyTarget = R.string.key_eatingsoon_target - defaultTargetMMOL = Constants.defaultEatingSoonTTmmol - defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl - } else if (isActivity) { - keyDuration = R.string.key_activity_duration - defaultTargetDuration = Constants.defaultActivityTTDuration - keyTarget = R.string.key_activity_target - defaultTargetMMOL = Constants.defaultActivityTTmmol - defaultTargetMGDL = Constants.defaultActivityTTmgdl - } else if (isHypo) { - keyDuration = R.string.key_hypo_duration - defaultTargetDuration = Constants.defaultHypoTTDuration - keyTarget = R.string.key_hypo_target - defaultTargetMMOL = Constants.defaultHypoTTmmol - defaultTargetMGDL = Constants.defaultHypoTTmgdl - } - var ttDuration = SP.getInt(keyDuration, defaultTargetDuration) - ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration - var tt = SP.getDouble(keyTarget, if (currentProfile.units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL) - tt = if (tt > 0) tt else if (currentProfile.units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL - val tempTarget = TempTarget() - .date(System.currentTimeMillis()) - .duration(ttDuration) - .reason(MainApp.gs(R.string.eatingsoon)) - .source(Source.USER) - .low(Profile.toMgdl(tt, currentProfile.units)) - .high(Profile.toMgdl(tt, currentProfile.units)) - TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) - val ttString = if (currentProfile.units == Constants.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt) - val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration) - sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) - } else { - sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)) + val units = ProfileFunctions.getSystemUnits() + var keyDuration = 0 + var defaultTargetDuration = 0 + var keyTarget = 0 + var defaultTargetMMOL = 0.0 + var defaultTargetMGDL = 0.0 + if (isMeal) { + keyDuration = R.string.key_eatingsoon_duration + defaultTargetDuration = Constants.defaultEatingSoonTTDuration + keyTarget = R.string.key_eatingsoon_target + defaultTargetMMOL = Constants.defaultEatingSoonTTmmol + defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl + } else if (isActivity) { + keyDuration = R.string.key_activity_duration + defaultTargetDuration = Constants.defaultActivityTTDuration + keyTarget = R.string.key_activity_target + defaultTargetMMOL = Constants.defaultActivityTTmmol + defaultTargetMGDL = Constants.defaultActivityTTmgdl + } else if (isHypo) { + keyDuration = R.string.key_hypo_duration + defaultTargetDuration = Constants.defaultHypoTTDuration + keyTarget = R.string.key_hypo_target + defaultTargetMMOL = Constants.defaultHypoTTmmol + defaultTargetMGDL = Constants.defaultHypoTTmgdl } + var ttDuration = SP.getInt(keyDuration, defaultTargetDuration) + ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration + var tt = SP.getDouble(keyTarget, if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL) + tt = Profile.toCurrentUnits(tt) + tt = if (tt > 0) tt else if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL + val tempTarget = TempTarget() + .date(System.currentTimeMillis()) + .duration(ttDuration) + .reason(MainApp.gs(R.string.eatingsoon)) + .source(Source.USER) + .low(Profile.toMgdl(tt, units)) + .high(Profile.toMgdl(tt, units)) + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) + val ttString = if (units == Constants.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt) + val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration) + sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) } }) } else if (isStop) { @@ -787,20 +784,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription() receivedSms.processed = true messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() { override fun run() { - val currentProfile = ProfileFunctions.getInstance().profile - if (currentProfile != null) { - val tempTarget = TempTarget() - .source(Source.USER) - .date(DateUtil.now()) - .duration(0) - .low(0.0) - .high(0.0) - TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) - val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_canceled)) - sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) - } else { - sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)) - } + val tempTarget = TempTarget() + .source(Source.USER) + .date(DateUtil.now()) + .duration(0) + .low(0.0) + .high(0.0) + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget) + val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_canceled)) + sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) } }) } else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/InfoInterceptor.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/InfoInterceptor.kt index ca3c3e0483..4acc0b5d67 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/InfoInterceptor.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/InfoInterceptor.kt @@ -19,7 +19,7 @@ class InfoInterceptor(tag: String) : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() - request?.body()?.let { + request.body?.let { if (L.isEnabled(L.TIDEPOOL)) { log.debug("Interceptor Body size: " + it.contentLength()) val requestBuffer = Buffer() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt index 40473c0d93..7ab263b8d7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt @@ -14,9 +14,9 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.OKDialog import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.T -import okhttp3.MediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient -import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.logging.HttpLoggingInterceptor import org.slf4j.LoggerFactory import retrofit2.Retrofit @@ -43,7 +43,7 @@ object TidepoolUploader { val PUMPTYPE = "Tandem" - var connectionStatus: ConnectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + var connectionStatus: ConnectionStatus = ConnectionStatus.DISCONNECTED fun getRetrofitInstance(): Retrofit? { if (retrofit == null) { @@ -75,7 +75,7 @@ object TidepoolUploader { retrofit = null if (L.isEnabled(L.TIDEPOOL)) log.debug("Instance reset") - connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + connectionStatus = ConnectionStatus.DISCONNECTED } @Synchronized @@ -197,7 +197,7 @@ object TidepoolUploader { } else -> { - val body = RequestBody.create(MediaType.parse("application/json"), chunk) + val body = chunk.toRequestBody("application/json".toMediaTypeOrNull()) RxBus.send(EventTidepoolStatus(("Uploading"))) if (session.service != null && session.token != null && session.datasetReply != null) { @@ -231,11 +231,11 @@ object TidepoolUploader { extendWakeLock(60000) val call = session!!.service?.deleteDataSet(session!!.token!!, session!!.datasetReply!!.id!!) call?.enqueue(TidepoolCallback(session!!, "Delete Dataset", { - connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + connectionStatus = ConnectionStatus.DISCONNECTED RxBus.send(EventTidepoolStatus(("Dataset removed OK"))) releaseWakeLock() }, { - connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + connectionStatus = ConnectionStatus.DISCONNECTED RxBus.send(EventTidepoolStatus(("Dataset remove FAILED"))) releaseWakeLock() })) @@ -255,11 +255,11 @@ object TidepoolUploader { extendWakeLock(60000) val call = session.service?.deleteAllData(token, userid) call?.enqueue(TidepoolCallback(session, "Delete all data", { - connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + connectionStatus = ConnectionStatus.DISCONNECTED RxBus.send(EventTidepoolStatus(("All data removed OK"))) releaseWakeLock() }, { - connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED + connectionStatus = ConnectionStatus.DISCONNECTED RxBus.send(EventTidepoolStatus(("All data remove FAILED"))) releaseWakeLock() })) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/elements/ProfileElement.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/elements/ProfileElement.kt index 93009ea7e1..82ae37cebc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/elements/ProfileElement.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/elements/ProfileElement.kt @@ -41,12 +41,12 @@ class ProfileElement private constructor(ps: ProfileSwitch) checkNotNull(profile) for (br in profile.basalValues) basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value)) - for (target in profile.singleTargets) - bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, Profile.toMgdl(target.value, profile.units))) + for (target in profile.singleTargetsMgdl) + bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, target.value)) for (ic in profile.ics) carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value)) - for (isf in profile.isfs) - insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, Profile.toMgdl(isf.value, profile.units))) + for (isf in profile.isfsMgdl) + insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, isf.value)) } inner class BasalProfile internal constructor( diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/events/EventTidepoolStatus.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/events/EventTidepoolStatus.kt index e7854f8ff2..f9e2b724cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/events/EventTidepoolStatus.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/events/EventTidepoolStatus.kt @@ -3,9 +3,9 @@ package info.nightscout.androidaps.plugins.general.tidepool.events import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.LocaleHelper import org.slf4j.LoggerFactory import java.text.SimpleDateFormat +import java.util.* class EventTidepoolStatus(val status: String) : Event() { private val log = LoggerFactory.getLogger(L.TIDEPOOL) @@ -17,7 +17,7 @@ class EventTidepoolStatus(val status: String) : Event() { log.debug("New status: $status") } - private var timeFormat = SimpleDateFormat("HH:mm:ss", LocaleHelper.currentLocale()) + private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) fun toPreparedHtml(): StringBuilder { val stringBuilder = StringBuilder() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/BaseMessage.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/BaseMessage.kt index d3cdffcf8c..d9dfc97b38 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/BaseMessage.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/BaseMessage.kt @@ -1,8 +1,9 @@ package info.nightscout.androidaps.plugins.general.tidepool.messages import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance -import okhttp3.MediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody open class BaseMessage { private fun toS(): String { @@ -10,7 +11,7 @@ open class BaseMessage { } fun getBody(): RequestBody { - return RequestBody.create(MediaType.parse("application/json"), this.toS()) + return this.toS().toRequestBody("application/json".toMediaTypeOrNull()) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java index 1cf4dd7539..cae9817a55 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java @@ -131,12 +131,7 @@ public class ActionStringHandler { ///////////////////////////////////////////////////////// TEMPTARGET boolean isMGDL = Boolean.parseBoolean(act[1]); - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile == null) { - sendError("No profile found!"); - return; - } - if (profile.getUnits().equals(Constants.MGDL) != isMGDL) { + if (ProfileFunctions.getSystemUnits().equals(Constants.MGDL) != isMGDL) { sendError("Different units used on watch and phone!"); return; } @@ -222,7 +217,7 @@ public class ActionStringHandler { DecimalFormat format = new DecimalFormat("0.00"); DecimalFormat formatInt = new DecimalFormat("0"); BolusWizard bolusWizard = new BolusWizard(profile, profileName, TreatmentsPlugin.getPlugin().getTempTargetFromHistory(), - carbsAfterConstraints, cobInfo.displayCob, bgReading.valueToUnits(profile.getUnits()), + carbsAfterConstraints, cobInfo.displayCob, bgReading.valueToUnits(ProfileFunctions.getSystemUnits()), 0d, percentage, useBG, useCOB, useBolusIOB, useBasalIOB, false, useTT, useTrend); if (Math.abs(bolusWizard.getInsulinAfterConstraints() - bolusWizard.getCalculatedTotalInsulin()) >= 0.01) { @@ -534,14 +529,14 @@ public class ActionStringHandler { //Check for Temp-Target: TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(); if (tempTarget != null) { - ret += "Temp Target: " + Profile.toTargetRangeString(tempTarget.low, tempTarget.low, Constants.MGDL, profile.getUnits()); + ret += "Temp Target: " + Profile.toTargetRangeString(tempTarget.low, tempTarget.low, Constants.MGDL, ProfileFunctions.getSystemUnits()); ret += "\nuntil: " + DateUtil.timeString(tempTarget.originalEnd()); ret += "\n\n"; } ret += "DEFAULT RANGE: "; - ret += profile.getTargetLow() + " - " + profile.getTargetHigh(); - ret += " target: " + profile.getTarget(); + ret += Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), ProfileFunctions.getSystemUnits()) + " - " + Profile.fromMgdlToUnits(profile.getTargetHighMgdl(), ProfileFunctions.getSystemUnits()); + ret += " target: " + Profile.fromMgdlToUnits(profile.getTargetMgdl(), ProfileFunctions.getSystemUnits()); return ret; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 7eebdc8d8e..39676f17b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -1,12 +1,5 @@ package info.nightscout.androidaps.plugins.general.wear.wearintegration; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -17,9 +10,10 @@ import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.preference.PreferenceManager; -import androidx.annotation.NonNull; import android.util.Log; +import androidx.annotation.NonNull; + import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.wearable.CapabilityApi; @@ -32,31 +26,37 @@ import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; import com.google.android.gms.wearable.WearableListenerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.WearPlugin; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.treatments.Treatment; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; -import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.ToastUtils; public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { @@ -88,7 +88,6 @@ public class WatchUpdaterService extends WearableListenerService implements Goog boolean wear_integration = false; - SharedPreferences mPrefs; private static boolean lastLoopStatus; private static Logger log = LoggerFactory.getLogger(WatchUpdaterService.class); @@ -108,7 +107,6 @@ public class WatchUpdaterService extends WearableListenerService implements Goog @Override public void onCreate() { - mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); listenForChangeInSettings(); setSettings(); if (wear_integration) { @@ -139,7 +137,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog googleApiClient.disconnect(); } googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this) - .addOnConnectionFailedListener(this).addApi(Wearable.API).build(); + .addOnConnectionFailedListener(this).addApi(Wearable.API).build(); Wearable.MessageApi.addListener(googleApiClient, this); if (googleApiClient.isConnected()) { log.debug(logPrefix + "API client is connected"); @@ -303,10 +301,10 @@ public class WatchUpdaterService extends WearableListenerService implements Goog private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) { - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); - Double lowLine = SafeParse.stringToDouble(mPrefs.getString("low_mark", "0")); - Double highLine = SafeParse.stringToDouble(mPrefs.getString("high_mark", "0")); + Double lowLine = OverviewPlugin.INSTANCE.determineLowLine(); + Double highLine = OverviewPlugin.INSTANCE.determineHighLine(); // convert to mg/dl if (!units.equals(Constants.MGDL)) { @@ -323,7 +321,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog highLine = OverviewPlugin.INSTANCE.getBgTargetHigh(); } - long sgvLevel = 0l; + long sgvLevel = 0L; if (lastBG.value > highLine) { sgvLevel = 1; } else if (lastBG.value < lowLine) { @@ -721,7 +719,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog //bgi - double bgi = -(bolusIob.activity + basalIob.activity) * 5 * profile.getIsf(); + double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), ProfileFunctions.getSystemUnits()); bgiString = "" + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to1Decimal(bgi); status = generateStatusString(profile, currentBasal, iobSum, iobDetail, bgiString); @@ -748,14 +746,14 @@ public class WatchUpdaterService extends WearableListenerService implements Goog dataMapRequest.getDataMap().putString("externalStatusString", status); dataMapRequest.getDataMap().putString("iobSum", iobSum); dataMapRequest.getDataMap().putString("iobDetail", iobDetail); - dataMapRequest.getDataMap().putBoolean("detailedIob", mPrefs.getBoolean("wear_detailediob", false)); + dataMapRequest.getDataMap().putBoolean("detailedIob", SP.getBoolean(R.string.key_wear_detailediob, false)); dataMapRequest.getDataMap().putString("cob", cobString); dataMapRequest.getDataMap().putString("currentBasal", currentBasal); dataMapRequest.getDataMap().putString("battery", "" + phoneBattery); dataMapRequest.getDataMap().putString("rigBattery", rigBattery); dataMapRequest.getDataMap().putLong("openApsStatus", openApsStatus); dataMapRequest.getDataMap().putString("bgi", bgiString); - dataMapRequest.getDataMap().putBoolean("showBgi", mPrefs.getBoolean("wear_showbgi", false)); + dataMapRequest.getDataMap().putBoolean("showBgi", SP.getBoolean(R.string.key_wear_showbgi, false)); dataMapRequest.getDataMap().putInt("batteryLevel", (phoneBattery >= 30) ? 1 : 0); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); debugData("sendStatus", putDataRequest); @@ -789,7 +787,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog private void executeTask(AsyncTask task, DataMap... parameters) { - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])parameters); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[]) parameters); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); // } else { @@ -818,7 +816,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog } String iobString = ""; - if (mPrefs.getBoolean("wear_detailediob", false)) { + if (SP.getBoolean(R.string.key_wear_detailediob, false)) { iobString = iobSum + " " + iobDetail; } else { iobString = iobSum + "U"; @@ -827,7 +825,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog status += currentBasal + " " + iobString; //add BGI if shown, otherwise return - if (mPrefs.getBoolean("wear_showbgi", false)) { + if (SP.getBoolean(R.string.key_wear_showbgi, false)) { status += " " + bgiString; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java index da61b83b98..b810624e87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/xdripStatusline/StatuslinePlugin.java @@ -206,7 +206,7 @@ public class StatuslinePlugin extends PluginBase { return status; } - double bgi = -(bolusIob.activity + basalIob.activity) * 5 * profile.getIsf(); + double bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), ProfileFunctions.getSystemUnits()); status += " " + ((bgi >= 0) ? "+" : "") + DecimalFormatter.to2Decimal(bgi); status += " " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "StatuslinePlugin").generateCOBString(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.java index 8954c81ce7..dec9239948 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.java @@ -52,7 +52,7 @@ public class InsulinFragment extends Fragment { private void updateGUI() { insulinName.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getFriendlyName()); insulinComment.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getComment()); - insulinDia.setText(MainApp.gs(R.string.dia) + " " + ConfigBuilderPlugin.getPlugin().getActiveInsulin().getDia() + "h"); + insulinDia.setText(MainApp.gs(R.string.dia) + ": " + ConfigBuilderPlugin.getPlugin().getActiveInsulin().getDia() + "h"); insulinGraph.show(ConfigBuilderPlugin.getPlugin().getActiveInsulin()); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensData.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensData.java index 4b47602f33..0c93e0266f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/AutosensData.java @@ -48,7 +48,7 @@ public class AutosensData implements DataPointWithLabelInterface { if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) { double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME); Profile profile = ProfileFunctions.getInstance().getProfile(t.date); - double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits()); + double sens = profile.getIsfMgdl(t.date); double ic = profile.getIc(t.date); min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic; if (L.isEnabled(L.AUTOSENS)) 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 07d1b52947..57a1bba9ed 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 @@ -149,7 +149,7 @@ public class IobCobOref1Thread extends Thread { if (L.isEnabled(L.AUTOSENS)) log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); - double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits()); + double sens = profile.getIsfMgdl(bgTime); AutosensData autosensData = new AutosensData(); autosensData.time = bgTime; 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 a8ecc2a06a..fba1555d4c 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 @@ -148,7 +148,7 @@ public class IobCobThread extends Thread { if (L.isEnabled(L.AUTOSENS)) log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); - double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits()); + double sens = profile.getIsfMgdl(bgTime); AutosensData autosensData = new AutosensData(); autosensData.time = bgTime; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java deleted file mode 100644 index f8969e9594..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java +++ /dev/null @@ -1,212 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.local; - - -import android.app.Activity; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.RadioButton; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import java.text.DecimalFormat; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; -import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.NumberPicker; -import info.nightscout.androidaps.utils.SafeParse; -import info.nightscout.androidaps.utils.TimeListEdit; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; - -import static info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA; - -public class LocalProfileFragment extends Fragment { - private CompositeDisposable disposable = new CompositeDisposable(); - - private NumberPicker diaView; - private RadioButton mgdlView; - private RadioButton mmolView; - private TimeListEdit basalView; - private Button profileswitchButton; - private Button resetButton; - private Button saveButton; - - private TextView invalidProfile; - - private Runnable save = () -> { - doEdit(); - if (basalView != null) { - basalView.updateLabel(MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel()); - } - }; - - private TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - doEdit(); - } - }; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription(); - View layout = inflater.inflate(R.layout.localprofile_fragment, container, false); - diaView = layout.findViewById(R.id.localprofile_dia); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12d, 0.1d, new DecimalFormat("0.0"), false, layout.findViewById(R.id.localprofile_save), textWatch); - mgdlView = layout.findViewById(R.id.localprofile_mgdl); - mmolView = layout.findViewById(R.id.localprofile_mmol); - new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); - basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - profileswitchButton = layout.findViewById(R.id.localprofile_profileswitch); - resetButton = layout.findViewById(R.id.localprofile_reset); - saveButton = layout.findViewById(R.id.localprofile_save); - - - invalidProfile = layout.findViewById(R.id.invalidprofile); - - if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE); - } - - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - - mgdlView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - doEdit(); - }); - mmolView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - doEdit(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - resetButton.setOnClickListener(view -> { - LocalProfilePlugin.getPlugin().loadSettings(); - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.localprofile_save), textWatch); - new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); - basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - updateGUI(); - }); - - saveButton.setOnClickListener(view -> { - if (!LocalProfilePlugin.getPlugin().isValidEditState()) { - return; //Should not happen as saveButton should not be visible if not valid - } - LocalProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - }); - - return layout; - } - - @Override - public synchronized void onResume() { - super.onResume(); - disposable.add(RxBus.INSTANCE - .toObservable(EventInitializationChanged.class) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(event -> updateGUI(), FabricPrivacy::logException) - ); - updateGUI(); - } - - @Override - public synchronized void onPause() { - super.onPause(); - disposable.clear(); - } - - public void doEdit() { - LocalProfilePlugin.getPlugin().setEdited(true); - updateGUI(); - } - - @NonNull - public String getSumLabel() { - ProfileStore profile = LocalProfilePlugin.getPlugin().createProfileStore(); - if (profile != null) - return " ∑" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + MainApp.gs(R.string.insulin_unit_shortname); - else - return MainApp.gs(R.string.localprofile); - } - - protected void updateGUI() { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(() -> { - boolean isValid = LocalProfilePlugin.getPlugin().isValidEditState(); - boolean isEdited = LocalProfilePlugin.getPlugin().isEdited(); - if (isValid) { - invalidProfile.setVisibility(View.GONE); //show invalid profile - - if (isEdited) { - //edited profile -> save first - profileswitchButton.setVisibility(View.GONE); - saveButton.setVisibility(View.VISIBLE); - } else { - profileswitchButton.setVisibility(View.VISIBLE); - saveButton.setVisibility(View.GONE); - } - } else { - invalidProfile.setVisibility(View.VISIBLE); - profileswitchButton.setVisibility(View.GONE); - saveButton.setVisibility(View.GONE); //don't save an invalid profile - } - - //Show reset button iff data was edited - if (isEdited) { - resetButton.setVisibility(View.VISIBLE); - } else { - resetButton.setVisibility(View.GONE); - } - }); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt new file mode 100644 index 0000000000..3b6dbe7315 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -0,0 +1,265 @@ +package info.nightscout.androidaps.plugins.profile.local + + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import androidx.fragment.app.Fragment +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment +import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog +import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA +import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged +import info.nightscout.androidaps.utils.* +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import kotlinx.android.synthetic.main.localprofile_fragment.* +import java.text.DecimalFormat + +class LocalProfileFragment : Fragment() { + private var disposable: CompositeDisposable = CompositeDisposable() + + private var basalView: TimeListEdit? = null + private var spinner: SpinnerHelper? = null + + private val save = Runnable { + doEdit() + basalView?.updateLabel(MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel()) + } + + private val textWatch = object : TextWatcher { + override fun afterTextChanged(s: Editable) {} + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + LocalProfilePlugin.currentProfile().dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) + LocalProfilePlugin.currentProfile().name = localprofile_name.text.toString() + doEdit() + } + } + + private fun sumLabel(): String { + val profile = LocalProfilePlugin.createProfileStore().getDefaultProfile() + val sum = profile?.baseBasalSum() ?: 0.0 + return " ∑" + DecimalFormatter.to2Decimal(sum) + MainApp.gs(R.string.insulin_unit_shortname) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.localprofile_fragment, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + // activate DIA tab + processVisibilityOnClick(dia_tab) + localprofile_dia_placeholder.visibility = View.VISIBLE + // setup listeners + dia_tab.setOnClickListener { + processVisibilityOnClick(it) + localprofile_dia_placeholder.visibility = View.VISIBLE + } + ic_tab.setOnClickListener { + processVisibilityOnClick(it) + localprofile_ic.visibility = View.VISIBLE + } + isf_tab.setOnClickListener { + processVisibilityOnClick(it) + localprofile_isf.visibility = View.VISIBLE + } + basal_tab.setOnClickListener { + processVisibilityOnClick(it) + localprofile_basal.visibility = View.VISIBLE + } + target_tab.setOnClickListener { + processVisibilityOnClick(it) + localprofile_target.visibility = View.VISIBLE + } + } + + fun build() { + val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return + val units = if (LocalProfilePlugin.currentProfile().mgdl) Constants.MGDL else Constants.MMOL + + localprofile_name.removeTextChangedListener(textWatch) + localprofile_name.setText(LocalProfilePlugin.currentProfile().name) + localprofile_name.addTextChangedListener(textWatch) + localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label), LocalProfilePlugin.currentProfile().ic, null, HardLimits.MINIC, HardLimits.MAXIC, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + if (units == Constants.MGDL) { + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label), LocalProfilePlugin.currentProfile().isf, null, HardLimits.MINISF, HardLimits.MAXISF, 1.0, DecimalFormat("0"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label), LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save) + } else { + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label), LocalProfilePlugin.currentProfile().isf, null, Profile.fromMgdlToUnits(HardLimits.MINISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAXISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label), LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save) + } + + // Spinner + spinner = SpinnerHelper(view?.findViewById(R.id.localprofile_spinner)) + val profileList: ArrayList = LocalProfilePlugin.profile?.getProfileList() + ?: ArrayList() + context?.let { context -> + val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList) + spinner?.adapter = adapter + spinner?.setSelection(LocalProfilePlugin.currentProfileIndex) + } ?: return + spinner?.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + if (LocalProfilePlugin.isEdited) { + activity?.let { activity -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantswitchprofile), { + LocalProfilePlugin.currentProfileIndex = position + build() + }, { + spinner?.setSelection(LocalProfilePlugin.currentProfileIndex) + }) + } + } else { + LocalProfilePlugin.currentProfileIndex = position + build() + } + } + }) + + localprofile_profile_add.setOnClickListener { + if (LocalProfilePlugin.isEdited) { + activity?.let { OKDialog.show(it, "", MainApp.gs(R.string.saveorresetchangesfirst), null) } + } else { + LocalProfilePlugin.addNewProfile() + build() + } + } + + localprofile_profile_clone.setOnClickListener { + if (LocalProfilePlugin.isEdited) { + activity?.let { OKDialog.show(it, "", MainApp.gs(R.string.saveorresetchangesfirst), null) } + } else { + LocalProfilePlugin.cloneProfile() + build() + } + } + + localprofile_profile_remove.setOnClickListener { + activity?.let { activity -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.deletecurrentprofile), { + LocalProfilePlugin.removeCurrentProfile() + build() + }, null) + } + } + + // this is probably not possible because it leads to invalid profile + // if (!pumpDescription.isTempBasalCapable) localprofile_basal.visibility = View.GONE + + @Suppress("SETTEXTL18N") + localprofile_units.text = MainApp.gs(R.string.units_colon) + " " + (if (LocalProfilePlugin.currentProfile().mgdl) MainApp.gs(R.string.mgdl) else MainApp.gs(R.string.mmol)) + + localprofile_profileswitch.setOnClickListener { + // TODO: select in dialog LocalProfilePlugin.currentProfileIndex + val newDialog = NewNSTreatmentDialog() + val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT + profileSwitch.executeProfileSwitch = true + newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch) + fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") } + } + + localprofile_reset.setOnClickListener { + LocalProfilePlugin.loadSettings() + @Suppress("SETTEXTL18N") + localprofile_units.text = MainApp.gs(R.string.units_colon) + " " + (if (LocalProfilePlugin.currentProfile().mgdl) MainApp.gs(R.string.mgdl) else MainApp.gs(R.string.mmol)) + localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + updateGUI() + } + + localprofile_save.setOnClickListener { + if (!LocalProfilePlugin.isValidEditState()) { + return@setOnClickListener //Should not happen as saveButton should not be visible if not valid + } + LocalProfilePlugin.storeSettings(activity) + build() + } + updateGUI() + } + + @Synchronized + override fun onResume() { + super.onResume() + disposable.add(RxBus + .toObservable(EventLocalProfileChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ build() }, { FabricPrivacy.logException(it) }) + ) + build() + } + + @Synchronized + override fun onPause() { + super.onPause() + disposable.clear() + } + + fun doEdit() { + LocalProfilePlugin.isEdited = true + updateGUI() + } + + fun updateGUI() { + if (localprofile_profileswitch == null) return + val isValid = LocalProfilePlugin.isValidEditState() + val isEdited = LocalProfilePlugin.isEdited + if (isValid) { + this.view?.setBackgroundColor(MainApp.gc(R.color.ok_background)) + + if (isEdited) { + //edited profile -> save first + localprofile_profileswitch.visibility = View.GONE + localprofile_save.visibility = View.VISIBLE + } else { + localprofile_profileswitch.visibility = View.VISIBLE + localprofile_save.visibility = View.GONE + } + } else { + this.view?.setBackgroundColor(MainApp.gc(R.color.error_background)) + localprofile_profileswitch.visibility = View.GONE + localprofile_save.visibility = View.GONE //don't save an invalid profile + } + + //Show reset button if data was edited + if (isEdited) { + localprofile_reset.visibility = View.VISIBLE + } else { + localprofile_reset.visibility = View.GONE + } + } + + private fun processVisibilityOnClick(selected: View) { + dia_tab.setBackgroundColor(MainApp.gc(R.color.defaultbackground)) + ic_tab.setBackgroundColor(MainApp.gc(R.color.defaultbackground)) + isf_tab.setBackgroundColor(MainApp.gc(R.color.defaultbackground)) + basal_tab.setBackgroundColor(MainApp.gc(R.color.defaultbackground)) + target_tab.setBackgroundColor(MainApp.gc(R.color.defaultbackground)) + selected.setBackgroundColor(MainApp.gc(R.color.tabBgColorSelected)) + localprofile_dia_placeholder.visibility = View.GONE + localprofile_ic.visibility = View.GONE + localprofile_isf.visibility = View.GONE + localprofile_basal.visibility = View.GONE + localprofile_target.visibility = View.GONE + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java deleted file mode 100644 index e3e068c1cb..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java +++ /dev/null @@ -1,231 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.local; - -import androidx.annotation.NonNull; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventProfileStoreChanged; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginDescription; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.SP; - -/** - * Created by mike on 05.08.2016. - */ -public class LocalProfilePlugin extends PluginBase implements ProfileInterface { - public static final String LOCAL_PROFILE = "LocalProfile"; - private static Logger log = LoggerFactory.getLogger(L.PROFILE); - - private static LocalProfilePlugin localProfilePlugin; - - public static LocalProfilePlugin getPlugin() { - if (localProfilePlugin == null) - localProfilePlugin = new LocalProfilePlugin(); - return localProfilePlugin; - } - - private ProfileStore convertedProfile = null; - - private static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]"; - - public boolean isEdited() { - return edited; - } - - public void setEdited(boolean edited) { - this.edited = edited; - } - - boolean edited; - boolean mgdl; - boolean mmol; - Double dia; - JSONArray ic; - JSONArray isf; - JSONArray basal; - JSONArray targetLow; - JSONArray targetHigh; - - public LocalProfilePlugin() { - super(new PluginDescription() - .mainType(PluginType.PROFILE) - .fragmentClass(LocalProfileFragment.class.getName()) - .pluginName(R.string.localprofile) - .shortName(R.string.localprofile_shortname) - .description(R.string.description_profile_local) - ); - loadSettings(); - } - - public synchronized void storeSettings() { - SP.putBoolean(LOCAL_PROFILE + "mmol", mmol); - SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl); - SP.putString(LOCAL_PROFILE + "dia", dia.toString()); - SP.putString(LOCAL_PROFILE + "ic", ic.toString()); - SP.putString(LOCAL_PROFILE + "isf", isf.toString()); - SP.putString(LOCAL_PROFILE + "basal", basal.toString()); - SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString()); - SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()); - - createAndStoreConvertedProfile(); - edited = false; - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings: " + getRawProfile().getData().toString()); - RxBus.INSTANCE.send(new EventProfileStoreChanged()); - } - - public synchronized void loadSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Loading stored settings"); - - mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false); - mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true); - dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA); - try { - ic = new JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - ic = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - isf = new JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - isf = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - basal = new JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - basal = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - targetLow = new JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - targetLow = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - targetHigh = new JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - targetHigh = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - edited = false; - createAndStoreConvertedProfile(); - } - - /* - { - "_id": "576264a12771b7500d7ad184", - "startDate": "2016-06-16T08:35:00.000Z", - "defaultProfile": "Default", - "store": { - "Default": { - "dia": "3", - "carbratio": [{ - "time": "00:00", - "value": "30" - }], - "carbs_hr": "20", - "delay": "20", - "sens": [{ - "time": "00:00", - "value": "100" - }], - "timezone": "UTC", - "basal": [{ - "time": "00:00", - "value": "0.1" - }], - "target_low": [{ - "time": "00:00", - "value": "0" - }], - "target_high": [{ - "time": "00:00", - "value": "0" - }], - "startDate": "1970-01-01T00:00:00.000Z", - "units": "mmol" - } - }, - "created_at": "2016-06-16T08:34:41.256Z" - } - */ - private void createAndStoreConvertedProfile() { - convertedProfile = createProfileStore(); - } - - public synchronized boolean isValidEditState() { - return createProfileStore().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile), false); - } - - @NonNull - public ProfileStore createProfileStore() { - JSONObject json = new JSONObject(); - JSONObject store = new JSONObject(); - JSONObject profile = new JSONObject(); - - try { - json.put("defaultProfile", LOCAL_PROFILE); - json.put("store", store); - profile.put("dia", dia); - profile.put("carbratio", ic); - profile.put("sens", isf); - profile.put("basal", basal); - profile.put("target_low", targetLow); - profile.put("target_high", targetHigh); - profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); - store.put(LOCAL_PROFILE, profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return new ProfileStore(json); - } - - @Override - public ProfileStore getProfile() { - if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.localprofile))) - return null; - return convertedProfile; - } - - public ProfileStore getRawProfile() { - return convertedProfile; - } - - @Override - public String getUnits() { - return mgdl ? Constants.MGDL : Constants.MMOL; - } - - @Override - public String getProfileName() { - return DecimalFormatter.to2Decimal(convertedProfile.getDefaultProfile().percentageBasalSum()) + "U "; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt new file mode 100644 index 0000000000..e2c8d051ac --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt @@ -0,0 +1,429 @@ +package info.nightscout.androidaps.plugins.profile.local + +import android.app.Activity +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.data.ProfileStore +import info.nightscout.androidaps.events.EventProfileStoreChanged +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ProfileInterface +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.OKDialog +import info.nightscout.androidaps.utils.SP +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject +import org.slf4j.LoggerFactory +import java.util.* +import kotlin.collections.ArrayList + +object LocalProfilePlugin : PluginBase(PluginDescription() + .mainType(PluginType.PROFILE) + .fragmentClass(LocalProfileFragment::class.java.name) + .pluginName(R.string.localprofile) + .shortName(R.string.localprofile_shortname) + .description(R.string.description_profile_local)), ProfileInterface { + + override fun onStart() { + super.onStart() + loadSettings() + } + + private val log = LoggerFactory.getLogger(L.PROFILE) + + private var rawProfile: ProfileStore? = null + + const val LOCAL_PROFILE = "LocalProfile" + + private const val DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]" + + class SingleProfile { + internal var name: String? = null + internal var mgdl: Boolean = false + internal var dia: Double = Constants.defaultDIA + internal var ic: JSONArray? = null + internal var isf: JSONArray? = null + internal var basal: JSONArray? = null + internal var targetLow: JSONArray? = null + internal var targetHigh: JSONArray? = null + + fun deepClone(): SingleProfile { + val sp = SingleProfile() + sp.name = name + sp.mgdl = mgdl + sp.dia = dia + sp.ic = JSONArray(ic.toString()) + sp.isf = JSONArray(isf.toString()) + sp.basal = JSONArray(basal.toString()) + sp.targetLow = JSONArray(targetLow.toString()) + sp.targetHigh = JSONArray(targetHigh.toString()) + return sp + } + + fun copyFrom(profile: Profile, newName: String): SingleProfile { + var verifiedName = newName + if (rawProfile?.getSpecificProfile(newName) != null) { + verifiedName += " " + DateUtil.now().toString() + } + val sp = SingleProfile() + sp.name = verifiedName + sp.mgdl = profile.units == Constants.MGDL + sp.dia = profile.dia + sp.ic = JSONArray(profile.data.getJSONArray("carbratio").toString()) + sp.isf = JSONArray(profile.data.getJSONArray("sens").toString()) + sp.basal = JSONArray(profile.data.getJSONArray("basal").toString()) + sp.targetLow = JSONArray(profile.data.getJSONArray("target_low").toString()) + sp.targetHigh = JSONArray(profile.data.getJSONArray("target_high").toString()) + return sp + } + } + + var isEdited: Boolean = false + var profiles: ArrayList = ArrayList() + + internal var numOfProfiles = 0 + internal var currentProfileIndex = 0 + + fun currentProfile() = profiles[currentProfileIndex] + + @Synchronized + fun isValidEditState(): Boolean { + return createProfileStore().getDefaultProfile()?.isValid(MainApp.gs(R.string.localprofile), false) + ?: false + } + + @Synchronized + fun storeSettings(activity: Activity? = null) { + for (i in 0 until numOfProfiles) { + profiles[i].run { + val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_" + SP.putString(LOCAL_PROFILE_NUMBERED + "name", name) + SP.putBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", mgdl) + SP.putDouble(LOCAL_PROFILE_NUMBERED + "dia", dia) + SP.putString(LOCAL_PROFILE_NUMBERED + "ic", ic.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "isf", isf.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "basal", basal.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "targetlow", targetLow.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "targethigh", targetHigh.toString()) + } + } + SP.putInt(LOCAL_PROFILE + "_profiles", numOfProfiles) + + createAndStoreConvertedProfile() + isEdited = false + if (L.isEnabled(L.PROFILE)) + log.debug("Storing settings: " + rawProfile?.data.toString()) + RxBus.send(EventProfileStoreChanged()) + var namesOK = true + profiles.forEach { + val name = it.name ?: "." + if (name.contains(".")) namesOK = false + } + if (namesOK) + rawProfile?.let { NSUpload.uploadProfileStore(it.data) } + else + activity?.let { + OKDialog.show(it,"", MainApp.gs(R.string.profilenamecontainsdot), null) + } + } + + @Synchronized + fun loadSettings() { + if (SP.contains(LOCAL_PROFILE + "mgdl")) { + doConversion() + return + } + + numOfProfiles = SP.getInt(LOCAL_PROFILE + "_profiles", 0) + profiles.clear() + numOfProfiles = Math.max(numOfProfiles, 1) // create at least one default profile if none exists + + for (i in 0 until numOfProfiles) { + val p = SingleProfile() + val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_" + + p.name = SP.getString(LOCAL_PROFILE_NUMBERED + "name", LOCAL_PROFILE + i) + if (isExistingName(p.name)) continue + p.mgdl = SP.getBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", false) + p.dia = SP.getDouble(LOCAL_PROFILE_NUMBERED + "dia", Constants.defaultDIA) + try { + p.ic = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "ic", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.ic = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.isf = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "isf", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.isf = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.basal = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "basal", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.basal = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targetlow", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetLow = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targethigh", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetHigh = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + profiles.add(p) + } + isEdited = false + numOfProfiles = profiles.size + createAndStoreConvertedProfile() + } + + private fun isExistingName(name: String?): Boolean { + for (p in profiles) { + if (p.name == name) return true + } + return false + } + + @Synchronized + private fun doConversion() { // conversion from 2.3 to 2.4 format + if (L.isEnabled(L.PROFILE)) + log.debug("Loading stored settings") + val p = SingleProfile() + + p.mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", ProfileFunctions.getSystemUnits() == Constants.MGDL) + p.dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA) + try { + p.ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.ic = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + } + + try { + p.isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.isf = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + } + + try { + p.basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.basal = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + } + + try { + p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetLow = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + } + + try { + p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetHigh = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + } + p.name = LOCAL_PROFILE + + SP.remove(LOCAL_PROFILE + "mgdl") + SP.remove(LOCAL_PROFILE + "mmol") + SP.remove(LOCAL_PROFILE + "dia") + SP.remove(LOCAL_PROFILE + "ic") + SP.remove(LOCAL_PROFILE + "isf") + SP.remove(LOCAL_PROFILE + "basal") + SP.remove(LOCAL_PROFILE + "targetlow") + SP.remove(LOCAL_PROFILE + "targethigh") + + currentProfileIndex = 0 + numOfProfiles = 1 + profiles.clear() + profiles.add(p) + storeSettings() + + isEdited = false + createAndStoreConvertedProfile() + } + + /* + { + "_id": "576264a12771b7500d7ad184", + "startDate": "2016-06-16T08:35:00.000Z", + "defaultProfile": "Default", + "store": { + "Default": { + "dia": "3", + "carbratio": [{ + "time": "00:00", + "value": "30" + }], + "carbs_hr": "20", + "delay": "20", + "sens": [{ + "time": "00:00", + "value": "100" + }], + "timezone": "UTC", + "basal": [{ + "time": "00:00", + "value": "0.1" + }], + "target_low": [{ + "time": "00:00", + "value": "0" + }], + "target_high": [{ + "time": "00:00", + "value": "0" + }], + "startDate": "1970-01-01T00:00:00.000Z", + "units": "mmol" + } + }, + "created_at": "2016-06-16T08:34:41.256Z" + } + */ + private fun createAndStoreConvertedProfile() { + rawProfile = createProfileStore() + } + + fun addNewProfile() { + var free = 0 + for (i in 1..10000) { + if (rawProfile?.getSpecificProfile(LOCAL_PROFILE + i) == null) { + free = i; + break + } + } + val p = SingleProfile() + p.name = LOCAL_PROFILE + free + p.mgdl = ProfileFunctions.getSystemUnits() == Constants.MGDL + p.dia = Constants.defaultDIA + p.ic = JSONArray(DEFAULTARRAY) + p.isf = JSONArray(DEFAULTARRAY) + p.basal = JSONArray(DEFAULTARRAY) + p.targetLow = JSONArray(DEFAULTARRAY) + p.targetHigh = JSONArray(DEFAULTARRAY) + profiles.add(p) + currentProfileIndex = profiles.size - 1 + numOfProfiles++ + createAndStoreConvertedProfile() + storeSettings() + } + + fun cloneProfile() { + val p = profiles[currentProfileIndex].deepClone() + p.name = p.name + " copy" + profiles.add(p) + currentProfileIndex = profiles.size - 1 + numOfProfiles++ + createAndStoreConvertedProfile() + storeSettings() + isEdited = false + } + + fun addProfile(p: SingleProfile) { + profiles.add(p) + currentProfileIndex = profiles.size - 1 + numOfProfiles++ + createAndStoreConvertedProfile() + storeSettings() + isEdited = false + } + + fun removeCurrentProfile() { + profiles.removeAt(currentProfileIndex) + numOfProfiles-- + if (profiles.size == 0) addNewProfile() + currentProfileIndex = 0 + createAndStoreConvertedProfile() + storeSettings() + isEdited = false + } + + fun createProfileStore(): ProfileStore { + val json = JSONObject() + val store = JSONObject() + + try { + for (i in 0 until numOfProfiles) { + profiles[i].run { + val profile = JSONObject() + profile.put("dia", dia) + profile.put("carbratio", ic) + profile.put("sens", isf) + profile.put("basal", basal) + profile.put("target_low", targetLow) + profile.put("target_high", targetHigh) + profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL) + profile.put("timezone", TimeZone.getDefault().id) + store.put(name, profile) + } + } + json.put("defaultProfile", currentProfile().name) + json.put("startDate", DateUtil.toISOAsUTC(DateUtil.now())) + json.put("store", store) + } catch (e: JSONException) { + log.error("Unhandled exception", e) + } + + return ProfileStore(json) + } + + override fun getProfile(): ProfileStore? { + return rawProfile + } + + override fun getProfileName(): String { + return DecimalFormatter.to2Decimal(rawProfile?.getDefaultProfile()?.percentageBasalSum() + ?: 0.0) + "U " + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt new file mode 100644 index 0000000000..c84eaecd7f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/events/EventLocalProfileChanged.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.profile.local.events + +import info.nightscout.androidaps.events.Event + +class EventLocalProfileChanged : Event() { +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt index 7a76283074..7b377c9078 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.kt @@ -119,7 +119,7 @@ class NSProfileFragment : Fragment() { profileview_noprofile.visibility = View.VISIBLE NSProfilePlugin.getPlugin().profile?.let { profileStore -> - val profileList = profileStore.profileList + val profileList = profileStore.getProfileList() val adapter = ArrayAdapter(context!!, R.layout.spinner_centered, profileList) nsprofile_spinner.adapter = adapter // set selected to actual profile diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java index 38afe62bdf..41711b47bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfilePlugin.java @@ -118,11 +118,6 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface { return profile; } - @Override - public String getUnits() { - return profile != null ? profile.getUnits() : Constants.MGDL; - } - @Override public String getProfileName() { return profile.getDefaultProfileName(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java deleted file mode 100644 index ecf4fc423b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java +++ /dev/null @@ -1,159 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.simple; - - -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.RadioButton; -import android.widget.TextView; - -import androidx.fragment.app.Fragment; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; -import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.SafeParse; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; - -public class SimpleProfileFragment extends Fragment { - private CompositeDisposable disposable = new CompositeDisposable(); - - EditText diaView; - RadioButton mgdlView; - RadioButton mmolView; - EditText icView; - EditText isfView; - EditText basalView; - EditText targetlowView; - EditText targethighView; - Button profileswitchButton; - TextView invalidProfile; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View layout = inflater.inflate(R.layout.simpleprofile_fragment, container, false); - diaView = (EditText) layout.findViewById(R.id.simpleprofile_dia); - mgdlView = (RadioButton) layout.findViewById(R.id.simpleprofile_mgdl); - mmolView = (RadioButton) layout.findViewById(R.id.simpleprofile_mmol); - icView = (EditText) layout.findViewById(R.id.simpleprofile_ic); - isfView = (EditText) layout.findViewById(R.id.simpleprofile_isf); - basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate); - targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow); - targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh); - profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch); - invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); - - if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.simpleprofile_basalrate).setVisibility(View.GONE); - layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE); - } - - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - diaView.setText(SimpleProfilePlugin.getPlugin().dia.toString()); - icView.setText(SimpleProfilePlugin.getPlugin().ic.toString()); - isfView.setText(SimpleProfilePlugin.getPlugin().isf.toString()); - basalView.setText(SimpleProfilePlugin.getPlugin().basal.toString()); - targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString()); - targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString()); - - mgdlView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - mmolView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - SimpleProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - SimpleProfilePlugin.getPlugin().ic = SafeParse.stringToDouble(icView.getText().toString()); - SimpleProfilePlugin.getPlugin().isf = SafeParse.stringToDouble(isfView.getText().toString()); - SimpleProfilePlugin.getPlugin().basal = SafeParse.stringToDouble(basalView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); - SimpleProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - } - }; - - diaView.addTextChangedListener(textWatch); - icView.addTextChangedListener(textWatch); - isfView.addTextChangedListener(textWatch); - basalView.addTextChangedListener(textWatch); - targetlowView.addTextChangedListener(textWatch); - targethighView.addTextChangedListener(textWatch); - - return layout; - } - - @Override - public synchronized void onResume() { - super.onResume(); - disposable.add(RxBus.INSTANCE - .toObservable(EventInitializationChanged.class) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(event -> updateGUI(), FabricPrivacy::logException) - ); - updateGUI(); - } - - @Override - public synchronized void onPause() { - super.onPause(); - disposable.clear(); - } - - protected void updateGUI() { - boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile)); - if (!ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized() || ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !isValid) { - profileswitchButton.setVisibility(View.GONE); - } else { - profileswitchButton.setVisibility(View.VISIBLE); - } - if (isValid) - invalidProfile.setVisibility(View.GONE); - else - invalidProfile.setVisibility(View.VISIBLE); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java deleted file mode 100644 index 61ca403f55..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java +++ /dev/null @@ -1,181 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.simple; - -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventProfileStoreChanged; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginDescription; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.utils.SP; - -/** - * Created by mike on 05.08.2016. - */ -public class SimpleProfilePlugin extends PluginBase implements ProfileInterface { - private static Logger log = LoggerFactory.getLogger(L.PROFILE); - - private static SimpleProfilePlugin simpleProfilePlugin; - - public static SimpleProfilePlugin getPlugin() { - if (simpleProfilePlugin == null) - simpleProfilePlugin = new SimpleProfilePlugin(); - return simpleProfilePlugin; - } - - private static ProfileStore convertedProfile = null; - - boolean mgdl; - boolean mmol; - Double dia; - Double ic; - Double isf; - Double basal; - Double targetLow; - Double targetHigh; - - private SimpleProfilePlugin() { - super(new PluginDescription() - .mainType(PluginType.PROFILE) - .fragmentClass(SimpleProfileFragment.class.getName()) - .pluginName(R.string.simpleprofile) - .shortName(R.string.simpleprofile_shortname) - .description(R.string.description_profile_simple) - ); - loadSettings(); - } - - public void storeSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings"); - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean("SimpleProfile" + "mmol", mmol); - editor.putBoolean("SimpleProfile" + "mgdl", mgdl); - editor.putString("SimpleProfile" + "dia", dia.toString()); - editor.putString("SimpleProfile" + "ic", ic.toString()); - editor.putString("SimpleProfile" + "isf", isf.toString()); - editor.putString("SimpleProfile" + "basal", basal.toString()); - editor.putString("SimpleProfile" + "targetlow", targetLow.toString()); - editor.putString("SimpleProfile" + "targethigh", targetHigh.toString()); - - editor.apply(); - createConvertedProfile(); - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings: " + getRawProfile().getData().toString()); - RxBus.INSTANCE.send(new EventProfileStoreChanged()); - } - - private void loadSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Loading stored settings"); - - mgdl = SP.getBoolean("SimpleProfile" + "mgdl", true); - mmol = SP.getBoolean("SimpleProfile" + "mmol", false); - dia = SP.getDouble("SimpleProfile" + "dia", Constants.defaultDIA); - ic = SP.getDouble("SimpleProfile" + "ic", 0d); - isf = SP.getDouble("SimpleProfile" + "isf", 0d); - basal = SP.getDouble("SimpleProfile" + "basal", 0d); - targetLow = SP.getDouble("SimpleProfile" + "targetlow", 0d); - targetHigh = SP.getDouble("SimpleProfile" + "targethigh", 0d); - } - - /* - { - "_id": "576264a12771b7500d7ad184", - "startDate": "2016-06-16T08:35:00.000Z", - "defaultProfile": "Default", - "store": { - "Default": { - "dia": "3", - "carbratio": [{ - "time": "00:00", - "value": "30" - }], - "carbs_hr": "20", - "delay": "20", - "sens": [{ - "time": "00:00", - "value": "100" - }], - "timezone": "UTC", - "basal": [{ - "time": "00:00", - "value": "0.1" - }], - "target_low": [{ - "time": "00:00", - "value": "0" - }], - "target_high": [{ - "time": "00:00", - "value": "0" - }], - "startDate": "1970-01-01T00:00:00.000Z", - "units": "mmol" - } - }, - "created_at": "2016-06-16T08:34:41.256Z" - } - */ - private void createConvertedProfile() { - JSONObject json = new JSONObject(); - JSONObject store = new JSONObject(); - JSONObject profile = new JSONObject(); - - try { - json.put("defaultProfile", "SimpleProfile"); - json.put("store", store); - profile.put("dia", dia); - profile.put("carbratio", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", ic))); - profile.put("sens", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", isf))); - profile.put("basal", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", basal))); - profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow))); - profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh))); - profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); - store.put("SimpleProfile", profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - convertedProfile = new ProfileStore(json); - } - - @Override - public ProfileStore getProfile() { - if (convertedProfile == null) - createConvertedProfile(); - if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile))) - return null; - return convertedProfile; - } - - public ProfileStore getRawProfile() { - if (convertedProfile == null) - createConvertedProfile(); - return convertedProfile; - } - - @Override - public String getUnits() { - return mgdl ? Constants.MGDL : Constants.MMOL; - } - - @Override - public String getProfileName() { - return "SimpleProfile"; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java index 1a40e449e5..d8b2873a50 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java @@ -444,11 +444,6 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte return DanaRPump.getInstance().createConvertedProfile(); } - @Override - public String getUnits() { - return DanaRPump.getInstance().getUnits(); - } - @Override public String getProfileName() { return DanaRPump.getInstance().createConvertedProfileName(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.java index f20a74b024..97f029bd8c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRHistoryActivity.java @@ -24,7 +24,7 @@ import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.activities.NoSplashActivity; +import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.DanaRHistoryRecord; import info.nightscout.androidaps.events.EventPumpStatusChanged; @@ -41,16 +41,13 @@ import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.ToastUtils; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; -public class DanaRHistoryActivity extends NoSplashActivity { +public class DanaRHistoryActivity extends NoSplashAppCompatActivity { private static Logger log = LoggerFactory.getLogger(L.PUMP); private CompositeDisposable disposable = new CompositeDisposable(); - static Profile profile = null; - Spinner historyTypeSpinner; TextView statusView; Button reloadButton; @@ -182,11 +179,6 @@ public class DanaRHistoryActivity extends NoSplashActivity { clearCardView(); } }); - profile = ProfileFunctions.getInstance().getProfile(); - if (profile == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile)); - finish(); - } } public static class RecyclerViewAdapter extends RecyclerView.Adapter { @@ -252,7 +244,7 @@ public class DanaRHistoryActivity extends NoSplashActivity { holder.alarm.setVisibility(View.GONE); break; case RecordTypes.RECORD_TYPE_GLUCOSE: - holder.value.setText(Profile.toUnitsString(record.recordValue, record.recordValue * Constants.MGDL_TO_MMOLL, profile.getUnits())); + holder.value.setText(Profile.toUnitsString(record.recordValue, record.recordValue * Constants.MGDL_TO_MMOLL, ProfileFunctions.getSystemUnits())); // rest is the same case RecordTypes.RECORD_TYPE_CARBO: case RecordTypes.RECORD_TYPE_BASALHOUR: diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRNSHistorySync.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRNSHistorySync.java index dcb182a0d6..bf6f80af0b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRNSHistorySync.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRNSHistorySync.java @@ -184,7 +184,7 @@ public class DanaRNSHistorySync { log.debug("Syncing glucose record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "BG Check"); - nsrec.put("glucose", Profile.fromMgdlToUnits(record.recordValue, ProfileFunctions.getInstance().getProfileUnits())); + nsrec.put("glucose", Profile.fromMgdlToUnits(record.recordValue, ProfileFunctions.getSystemUnits())); nsrec.put("glucoseType", "Finger"); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); nsrec.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRUserOptionsActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRUserOptionsActivity.java index f1181bb7cb..0346b5320e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRUserOptionsActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/activities/DanaRUserOptionsActivity.java @@ -12,9 +12,8 @@ import org.slf4j.LoggerFactory; import java.text.DecimalFormat; import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.activities.NoSplashActivity; +import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; @@ -33,7 +32,7 @@ import io.reactivex.disposables.CompositeDisposable; * Created by Rumen Georgiev on 5/31/2018. */ -public class DanaRUserOptionsActivity extends NoSplashActivity { +public class DanaRUserOptionsActivity extends NoSplashAppCompatActivity { private static Logger log = LoggerFactory.getLogger(L.PUMP); private CompositeDisposable disposable = new CompositeDisposable(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java index 55be88996b..0eedd374b2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java @@ -285,11 +285,6 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte return DanaRPump.getInstance().createConvertedProfile(); } - @Override - public String getUnits() { - return DanaRPump.getInstance().getUnits(); - } - @Override public String getProfileName() { return DanaRPump.getInstance().createConvertedProfileName(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.java index 2d1a3a871e..7641e5c4cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/dialog/MedtronicHistoryActivity.java @@ -20,13 +20,13 @@ import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.activities.NoSplashActivity; +import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry; import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryGroup; -public class MedtronicHistoryActivity extends NoSplashActivity { +public class MedtronicHistoryActivity extends NoSplashAppCompatActivity { private static Logger LOG = LoggerFactory.getLogger(L.PUMP); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java index dfc4bed25d..8cfa903fb8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java @@ -137,7 +137,7 @@ public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { Double[] deviations = new Double[deviationsArray.size()]; deviations = deviationsArray.toArray(deviations); - double sens = profile.getIsf(); + double sens = profile.getIsfMgdl(); String ratioLimit = ""; String sensResult = ""; @@ -148,7 +148,7 @@ public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { Arrays.sort(deviations); double percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50); - double basalOff = percentile * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + double basalOff = percentile * (60 / 5) / sens; double ratio = 1 + (basalOff / profile.getMaxDailyBasal()); if (percentile < 0) { // sensitive diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref0Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref0Plugin.java index cfcaf0eb22..6298724514 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref0Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref0Plugin.java @@ -131,7 +131,7 @@ public class SensitivityOref0Plugin extends AbstractSensitivityPlugin { Double[] deviations = new Double[deviationsArray.size()]; deviations = deviationsArray.toArray(deviations); - double sens = profile.getIsf(); + double sens = profile.getIsfMgdl(); double ratio = 1; String ratioLimit = ""; @@ -154,10 +154,10 @@ public class SensitivityOref0Plugin extends AbstractSensitivityPlugin { double basalOff = 0; if (pSensitive < 0) { // sensitive - basalOff = pSensitive * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + basalOff = pSensitive * (60 / 5.0) / sens; sensResult = "Excess insulin sensitivity detected"; } else if (pResistant > 0) { // resistant - basalOff = pResistant * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + basalOff = pResistant * (60 / 5.0) / sens; sensResult = "Excess insulin resistance detected"; } else { sensResult = "Sensitivity normal"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.java index 5e0f5d3d85..131cafe89c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityOref1Plugin.java @@ -146,7 +146,7 @@ public class SensitivityOref1Plugin extends AbstractSensitivityPlugin { Double[] deviations = new Double[deviationsArray.size()]; deviations = deviationsArray.toArray(deviations); - double sens = profile.getIsf(); + double sens = profile.getIsfMgdl(); double ratio = 1; String ratioLimit = ""; @@ -174,10 +174,10 @@ public class SensitivityOref1Plugin extends AbstractSensitivityPlugin { double basalOff = 0; if (pSensitive < 0) { // sensitive - basalOff = pSensitive * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + basalOff = pSensitive * (60 / 5.0) / sens; sensResult = "Excess insulin sensitivity detected"; } else if (pResistant > 0) { // resistant - basalOff = pResistant * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + basalOff = pResistant * (60 / 5.0) / sens; sensResult = "Excess insulin resistance detected"; } else { sensResult = "Sensitivity normal"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java index 91b69162bb..5d0aac4d4c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java @@ -164,7 +164,7 @@ public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin return new AutosensResult(); } - double sens = profile.getIsf(); + double sens = profile.getIsfMgdl(); String ratioLimit = ""; String sensResult; @@ -173,7 +173,7 @@ public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin log.debug("Records: " + index + " " + pastSensitivity); double average = weightedsum / weights; - double basalOff = average * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + double basalOff = average * (60 / 5.0) / sens; double ratio = 1 + (basalOff / profile.getMaxDailyBasal()); if (average < 0) { // sensitive diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.java index 6023d70d12..1d72ed2e72 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/source/BGSourceFragment.java @@ -16,12 +16,11 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.List; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.utils.DateUtil; @@ -38,8 +37,6 @@ public class BGSourceFragment extends Fragment { private CompositeDisposable disposable = new CompositeDisposable(); RecyclerView recyclerView; - String units = Constants.MGDL; - final long MILLS_TO_THE_PAST = T.hours(12).msecs(); @Override @@ -57,9 +54,6 @@ public class BGSourceFragment extends Fragment { RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)); recyclerView.setAdapter(adapter); - if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile().getDefaultProfile() != null) - units = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile().getDefaultProfile().getUnits(); - return view; } catch (Exception e) { FabricPrivacy.logException(e); @@ -109,7 +103,7 @@ public class BGSourceFragment extends Fragment { holder.ns.setVisibility(NSUpload.isIdValid(bgReading._id) ? View.VISIBLE : View.GONE); holder.invalid.setVisibility(!bgReading.isValid ? View.VISIBLE : View.GONE); holder.date.setText(DateUtil.dateAndTimeString(bgReading.date)); - holder.value.setText(bgReading.valueToUnitsToString(units)); + holder.value.setText(bgReading.valueToUnitsToString(ProfileFunctions.getSystemUnits())); holder.direction.setText(bgReading.directionToSymbol()); holder.remove.setTag(bgReading); } @@ -147,7 +141,7 @@ public class BGSourceFragment extends Fragment { case R.id.bgsource_remove: AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(MainApp.gs(R.string.confirmation)); - builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(bgReading.date) + "\n" + bgReading.valueToUnitsToString(units)); + builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(bgReading.date) + "\n" + bgReading.valueToUnitsToString(ProfileFunctions.getSystemUnits())); builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { /* final String _id = bgReading._id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileViewerDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileViewerDialog.kt index a27ebfb656..be9adece61 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileViewerDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/ProfileViewerDialog.kt @@ -58,7 +58,7 @@ class ProfileViewerDialog : DialogFragment() { profileview_datelayout.visibility = View.VISIBLE } Mode.PUMP_PROFILE -> { - profile = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profile?.defaultProfile + profile = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profile?.getDefaultProfile() profileName = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profileName date = "" profileview_reload.visibility = View.VISIBLE diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java deleted file mode 100644 index 2d06b2824f..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.java +++ /dev/null @@ -1,242 +0,0 @@ -package info.nightscout.androidaps.plugins.treatments.fragments; - -import android.content.Context; -import android.content.DialogInterface; -import android.graphics.Paint; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.cardview.widget.CardView; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.db.ProfileSwitch; -import info.nightscout.androidaps.db.Source; -import info.nightscout.androidaps.events.EventProfileNeedsUpdate; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; -import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; -import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue; -import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.SP; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; - -/** - * Created by mike on 13/01/17. - */ - -public class TreatmentsProfileSwitchFragment extends Fragment implements View.OnClickListener { - private Logger log = LoggerFactory.getLogger(L.UI); - private CompositeDisposable disposable = new CompositeDisposable(); - - RecyclerView recyclerView; - LinearLayoutManager llm; - Button refreshFromNS; - - Context context; - - public class RecyclerViewAdapter extends RecyclerView.Adapter { - - List profileSwitchList; - - RecyclerViewAdapter(List profileSwitchList) { - this.profileSwitchList = profileSwitchList; - } - - @Override - public ProfileSwitchViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.treatments_profileswitch_item, viewGroup, false); - return new ProfileSwitchViewHolder(v); - } - - @Override - public void onBindViewHolder(ProfileSwitchViewHolder holder, int position) { - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile == null) return; - ProfileSwitch profileSwitch = profileSwitchList.get(position); - holder.ph.setVisibility(profileSwitch.source == Source.PUMP ? View.VISIBLE : View.GONE); - holder.ns.setVisibility(NSUpload.isIdValid(profileSwitch._id) ? View.VISIBLE : View.GONE); - - holder.date.setText(DateUtil.dateAndTimeString(profileSwitch.date)); - if (!profileSwitch.isEndingEvent()) { - holder.duration.setText(DecimalFormatter.to0Decimal(profileSwitch.durationInMinutes) + " min"); - } else { - holder.duration.setText(""); - } - holder.name.setText(profileSwitch.getCustomizedName()); - if (profileSwitch.isInProgress()) - holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); - else - holder.date.setTextColor(holder.duration.getCurrentTextColor()); - holder.remove.setTag(profileSwitch); - holder.name.setTag(profileSwitch); - holder.date.setTag(profileSwitch); - holder.invalid.setVisibility(profileSwitch.isValid() ? View.GONE : View.VISIBLE); - - } - - @Override - public int getItemCount() { - return profileSwitchList.size(); - } - - @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { - super.onAttachedToRecyclerView(recyclerView); - } - - public class ProfileSwitchViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - CardView cv; - TextView date; - TextView duration; - TextView name; - TextView remove; - TextView ph; - TextView ns; - TextView invalid; - - ProfileSwitchViewHolder(View itemView) { - super(itemView); - cv = (CardView) itemView.findViewById(R.id.profileswitch_cardview); - date = (TextView) itemView.findViewById(R.id.profileswitch_date); - duration = (TextView) itemView.findViewById(R.id.profileswitch_duration); - name = (TextView) itemView.findViewById(R.id.profileswitch_name); - ph = (TextView) itemView.findViewById(R.id.pump_sign); - ns = (TextView) itemView.findViewById(R.id.ns_sign); - invalid = (TextView) itemView.findViewById(R.id.invalid_sign); - remove = (TextView) itemView.findViewById(R.id.profileswitch_remove); - remove.setOnClickListener(this); - remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - name.setOnClickListener(this); - date.setOnClickListener(this); - - } - - @Override - public void onClick(View v) { - final ProfileSwitch profileSwitch = (ProfileSwitch) v.getTag(); - if (profileSwitch == null) { - log.error("profileSwitch == null"); - return; - } - switch (v.getId()) { - case R.id.profileswitch_remove: - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(MainApp.gs(R.string.confirmation)); - builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(profileSwitch.date)); - builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - final String _id = profileSwitch._id; - if (NSUpload.isIdValid(_id)) { - NSUpload.removeCareportalEntryFromNS(_id); - } else { - UploadQueue.removeID("dbAdd", _id); - } - MainApp.getDbHelper().delete(profileSwitch); - } - }); - builder.setNegativeButton(MainApp.gs(R.string.cancel), null); - builder.show(); - break; - case R.id.profileswitch_date: - case R.id.profileswitch_name: - Bundle args = new Bundle(); - args.putLong("time", ((ProfileSwitch) v.getTag()).date); - args.putLong("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal()); - ProfileViewerDialog pvd = new ProfileViewerDialog(); - pvd.setArguments(args); - FragmentManager manager = getFragmentManager(); - if (manager != null) - pvd.show(manager, "ProfileViewDialog"); - break; - } - } - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.treatments_profileswitch_fragment, container, false); - - recyclerView = (RecyclerView) view.findViewById(R.id.profileswitch_recyclerview); - recyclerView.setHasFixedSize(true); - llm = new LinearLayoutManager(view.getContext()); - recyclerView.setLayoutManager(llm); - - RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)); - recyclerView.setAdapter(adapter); - - refreshFromNS = (Button) view.findViewById(R.id.profileswitch_refreshfromnightscout); - refreshFromNS.setOnClickListener(this); - - context = getContext(); - - boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); - if (nsUploadOnly) - refreshFromNS.setVisibility(View.GONE); - - return view; - } - - @Override - public synchronized void onResume() { - super.onResume(); - disposable.add(RxBus.INSTANCE - .toObservable(EventProfileNeedsUpdate.class) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(event -> updateGUI(), FabricPrivacy::logException) - ); - updateGUI(); - } - - @Override - public synchronized void onPause() { - super.onPause(); - disposable.clear(); - } - - @Override - public void onClick(View view) { - switch (view.getId()) { - case R.id.profileswitch_refreshfromnightscout: - AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext()); - builder.setTitle(MainApp.gs(R.string.confirmation)); - builder.setMessage(MainApp.gs(R.string.refresheventsfromnightscout) + "?"); - builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - MainApp.getDbHelper().resetProfileSwitch(); - RxBus.INSTANCE.send(new EventNSClientRestart()); - } - }); - builder.setNegativeButton(MainApp.gs(R.string.cancel), null); - builder.show(); - break; - } - } - - protected void updateGUI() { - recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)), false); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt new file mode 100644 index 0000000000..a125f7a8c3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsProfileSwitchFragment.kt @@ -0,0 +1,160 @@ +package info.nightscout.androidaps.plugins.treatments.fragments + +import android.content.DialogInterface +import android.graphics.Paint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import androidx.cardview.widget.CardView +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.db.ProfileSwitch +import info.nightscout.androidaps.db.Source +import info.nightscout.androidaps.events.EventProfileNeedsUpdate +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload +import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue +import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart +import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin +import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged +import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder +import info.nightscout.androidaps.utils.* +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import kotlinx.android.synthetic.main.treatments_profileswitch_fragment.* + +class TreatmentsProfileSwitchFragment : Fragment() { + private val disposable = CompositeDisposable() + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.treatments_profileswitch_fragment, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + profileswitch_recyclerview.setHasFixedSize(true) + profileswitch_recyclerview.layoutManager = LinearLayoutManager(view.context) + profileswitch_recyclerview.adapter = RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)) + + profileswitch_refreshfromnightscout.setOnClickListener { + val builder = AlertDialog.Builder(this.context!!) + builder.setTitle(MainApp.gs(R.string.confirmation)) + builder.setMessage(MainApp.gs(R.string.refresheventsfromnightscout) + "?") + builder.setPositiveButton(MainApp.gs(R.string.ok)) { _ , _-> + MainApp.getDbHelper().resetProfileSwitch() + RxBus.send(EventNSClientRestart()) + } + builder.setNegativeButton(MainApp.gs(R.string.cancel), null) + builder.show() + } + if (SP.getBoolean(R.string.key_ns_upload_only, false)) profileswitch_refreshfromnightscout.visibility = View.GONE + + } + + @Synchronized + override fun onResume() { + super.onResume() + disposable.add(RxBus + .toObservable(EventProfileNeedsUpdate::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ updateGUI() }) { FabricPrivacy.logException(it) } + ) + updateGUI() + } + + @Synchronized + override fun onPause() { + super.onPause() + disposable.clear() + } + + fun updateGUI() = + profileswitch_recyclerview?.swapAdapter(RecyclerProfileViewAdapter(MainApp.getDbHelper().getProfileSwitchData(false)), false) + + inner class RecyclerProfileViewAdapter(var profileSwitchList: List) : RecyclerView.Adapter() { + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProfileSwitchViewHolder { + return ProfileSwitchViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_profileswitch_item, viewGroup, false)) + } + + override fun onBindViewHolder(holder: ProfileSwitchViewHolder, position: Int) { + val profileSwitch = profileSwitchList[position] + holder.ph.visibility = if (profileSwitch.source == Source.PUMP) View.VISIBLE else View.GONE + holder.ns.visibility = if (NSUpload.isIdValid(profileSwitch._id)) View.VISIBLE else View.GONE + holder.date.text = DateUtil.dateAndTimeString(profileSwitch.date) + if (!profileSwitch.isEndingEvent) { + holder.duration.text = DecimalFormatter.to0Decimal(profileSwitch.durationInMinutes.toDouble()) + " " + MainApp.gs(R.string.unit_minute_short) + } else { + holder.duration.text = "" + } + holder.name.text = profileSwitch.customizedName + if (profileSwitch.isInProgress) holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)) else holder.date.setTextColor(holder.duration.currentTextColor) + holder.remove.tag = profileSwitch + holder.clone.tag = profileSwitch + holder.name.tag = profileSwitch + holder.date.tag = profileSwitch + holder.invalid.visibility = if (profileSwitch.isValid()) View.GONE else View.VISIBLE + } + + override fun getItemCount(): Int { + return profileSwitchList.size + } + + inner class ProfileSwitchViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + var cv: CardView = itemView.findViewById(R.id.profileswitch_cardview) as CardView + var date: TextView = itemView.findViewById(R.id.profileswitch_date) as TextView + var duration: TextView = itemView.findViewById(R.id.profileswitch_duration) as TextView + var name: TextView = itemView.findViewById(R.id.profileswitch_name) as TextView + var remove: TextView = itemView.findViewById(R.id.profileswitch_remove) as TextView + var clone: TextView = itemView.findViewById(R.id.profileswitch_clone) as TextView + var ph: TextView = itemView.findViewById(R.id.pump_sign) as TextView + var ns: TextView = itemView.findViewById(R.id.ns_sign) as TextView + var invalid: TextView = itemView.findViewById(R.id.invalid_sign) as TextView + + override fun onClick(v: View) { + val profileSwitch = v.tag as ProfileSwitch + when (v.id) { + R.id.profileswitch_remove -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + "\n" + profileSwitch.profileName + "\n" + DateUtil.dateAndTimeString(profileSwitch.date)) { + val id = profileSwitch._id + if (NSUpload.isIdValid(id)) NSUpload.removeCareportalEntryFromNS(id) + else UploadQueue.removeID("dbAdd", id) + MainApp.getDbHelper().delete(profileSwitch) + } + R.id.profileswitch_clone -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.customizedName + "\n" + DateUtil.dateAndTimeString(profileSwitch.date)) { + profileSwitch.profileObject?.let { + val nonCustomized = it.convertToNonCustomizedProfile() + LocalProfilePlugin.addProfile(LocalProfilePlugin.SingleProfile().copyFrom(nonCustomized, profileSwitch.customizedName + " " + DateUtil.dateAndTimeString(profileSwitch.date).replace(".", "_"))) + RxBus.send(EventLocalProfileChanged()) + } + } + R.id.profileswitch_date, R.id.profileswitch_name -> { + val args = Bundle() + args.putLong("time", (v.tag as ProfileSwitch).date) + args.putInt("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal) + val pvd = ProfileViewerDialog() + pvd.arguments = args + fragmentManager?.let { pvd.show(it, "ProfileViewDialog") } + } + } + } + + init { + remove.setOnClickListener(this) + clone.setOnClickListener(this) + remove.paintFlags = remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG + clone.paintFlags = clone.paintFlags or Paint.UNDERLINE_TEXT_FLAG + name.setOnClickListener(this) + date.setOnClickListener(this) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.java index ccd1b327c9..3ee36b87dd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsTempTargetFragment.java @@ -69,7 +69,7 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli @Override public void onBindViewHolder(TempTargetsViewHolder holder, int position) { - String units = ProfileFunctions.getInstance().getProfileUnits(); + String units = ProfileFunctions.getSystemUnits(); TempTarget tempTarget = tempTargetList.getReversed(position); holder.ph.setVisibility(tempTarget.source == Source.PUMP ? View.VISIBLE : View.GONE); holder.ns.setVisibility(NSUpload.isIdValid(tempTarget._id) ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java index 2c9e1ea51b..37cfe695b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java @@ -33,10 +33,9 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment; import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin; import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment; import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin; -import info.nightscout.androidaps.plugins.profile.simple.SimpleProfileFragment; -import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin; import info.nightscout.androidaps.setupwizard.elements.SWBreak; import info.nightscout.androidaps.setupwizard.elements.SWButton; +import info.nightscout.androidaps.setupwizard.elements.SWEditNumberWithUnits; import info.nightscout.androidaps.setupwizard.elements.SWEditString; import info.nightscout.androidaps.setupwizard.elements.SWEditUrl; import info.nightscout.androidaps.setupwizard.elements.SWFragment; @@ -110,6 +109,29 @@ public class SWDefinition { .visibility(() -> !SP.getBoolean(R.string.key_i_understand, false)) .validator(() -> SP.getBoolean(R.string.key_i_understand, false)); + private SWScreen screenUnits = new SWScreen(R.string.units) + .skippable(false) + .add(new SWRadioButton() + .option(R.array.unitsArray, R.array.unitsValues) + .preferenceId(R.string.key_units).label(R.string.units) + .comment(R.string.setupwizard_units_prompt)) + .validator(() -> SP.contains(R.string.key_units)); + + private SWScreen displaySettings = new SWScreen(R.string.wear_display_settings) + .skippable(false) + .add(new SWEditNumberWithUnits(4d, 3d, 8d) + .preferenceId(R.string.key_low_mark) + .updateDelay(5) + .label(R.string.low_mark) + .comment(R.string.low_mark_comment)) + .add(new SWBreak()) + .add(new SWEditNumberWithUnits(10d, 5d, 20d) + .preferenceId(R.string.key_high_mark) + .updateDelay(5) + .label(R.string.high_mark) + .comment(R.string.high_mark_comment)) + .validator(() -> SP.contains(R.string.key_low_mark) && SP.contains(R.string.key_high_mark)); + private SWScreen screenPermissionBattery = new SWScreen(R.string.permission) .skippable(false) .add(new SWInfotext() @@ -270,15 +292,8 @@ public class SWDefinition { .skippable(false) .add(new SWFragment(this) .add(new LocalProfileFragment())) - .validator(() -> LocalProfilePlugin.getPlugin().getProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid("StartupWizard")) - .visibility(() -> LocalProfilePlugin.getPlugin().isEnabled(PluginType.PROFILE)); - - private SWScreen screenSimpleProfile = new SWScreen(R.string.simpleprofile) - .skippable(false) - .add(new SWFragment(this) - .add(new SimpleProfileFragment())) - .validator(() -> SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid("StartupWizard")) - .visibility(() -> SimpleProfilePlugin.getPlugin().isEnabled(PluginType.PROFILE)); + .validator(() -> LocalProfilePlugin.INSTANCE.getProfile() != null && LocalProfilePlugin.INSTANCE.getProfile().getDefaultProfile() != null && LocalProfilePlugin.INSTANCE.getProfile().getDefaultProfile().isValid("StartupWizard")) + .visibility(() -> LocalProfilePlugin.INSTANCE.isEnabled(PluginType.PROFILE)); private SWScreen screenProfileSwitch = new SWScreen(R.string.profileswitch) .skippable(false) @@ -421,6 +436,8 @@ public class SWDefinition { .add(screenPermissionBt) .add(screenPermissionStore) .add(screenImport) + .add(screenUnits) + .add(displaySettings) .add(screenNsClient) .add(screenAge) .add(screenInsulin) @@ -428,7 +445,6 @@ public class SWDefinition { .add(screenProfile) .add(screenNsProfile) .add(screenLocalProfile) - .add(screenSimpleProfile) .add(screenProfileSwitch) .add(screenPump) .add(screenAps) @@ -448,6 +464,8 @@ public class SWDefinition { .add(screenPermissionBt) .add(screenPermissionStore) .add(screenImport) + .add(screenUnits) + .add(displaySettings) .add(screenNsClient) .add(screenAge) .add(screenInsulin) @@ -455,7 +473,6 @@ public class SWDefinition { .add(screenProfile) .add(screenNsProfile) .add(screenLocalProfile) - .add(screenSimpleProfile) .add(screenProfileSwitch) .add(screenPump) .add(screenSensitivity) @@ -470,6 +487,8 @@ public class SWDefinition { .add(screenPermissionBattery) .add(screenPermissionStore) .add(screenImport) + .add(screenUnits) + .add(displaySettings) .add(screenNsClient) .add(screenBgSource) .add(screenAge) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWNumberValidator.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWNumberValidator.java new file mode 100644 index 0000000000..a71da1dea7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWNumberValidator.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.setupwizard; + +public interface SWNumberValidator { + boolean isValid(double value); +} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java index e6a4831693..603292d3cc 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java @@ -72,18 +72,6 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { } } - @Override - public void onBackPressed() { - if (currentWizardPage == 0) - OKDialog.showConfirmation(this, MainApp.gs(R.string.exitwizard), this::finish); - else showPreviousPage(null); - } - - public void exitPressed(View view) { - SP.putBoolean(R.string.key_setupwizard_processed, true); - OKDialog.showConfirmation(this, MainApp.gs(R.string.exitwizard), this::finish); - } - @Override public void onPause() { super.onPause(); @@ -157,6 +145,18 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity { }); } + @Override + public void onBackPressed() { + if (currentWizardPage == 0) + OKDialog.showConfirmation(this, MainApp.gs(R.string.exitwizard), this::finish); + else showPreviousPage(null); + } + + public void exitPressed(View view) { + SP.putBoolean(R.string.key_setupwizard_processed, true); + OKDialog.showConfirmation(this, MainApp.gs(R.string.exitwizard), this::finish); + } + public void showNextPage(View view) { this.finish(); Intent intent = new Intent(this, SetupWizardActivity.class); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java new file mode 100644 index 0000000000..6816b6fa1f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditNumberWithUnits.java @@ -0,0 +1,98 @@ +package info.nightscout.androidaps.setupwizard.elements; + +import android.content.Context; +import android.graphics.Typeface; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.text.DecimalFormat; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; +import info.nightscout.androidaps.setupwizard.SWNumberValidator; +import info.nightscout.androidaps.utils.NumberPicker; +import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.SafeParse; + + +public class SWEditNumberWithUnits extends SWItem { + + private SWNumberValidator validator = new SWNumberValidator() { + @Override + public boolean isValid(double value) { + return value >= min && value <= max; + } + }; + private int updateDelay = 0; + private double init, min, max; + + public SWEditNumberWithUnits(double defaultMMOL, double minMMOL, double maxMMOL) { + super(Type.UNITNUMBER); + init = defaultMMOL; + min = minMMOL; + max = maxMMOL; + } + + @Override + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); + + TextWatcher watcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (validator != null && validator.isValid(SafeParse.stringToDouble(s.toString()))) + save(s.toString(), updateDelay); + } + + @Override + public void afterTextChanged(Editable s) { + } + }; + + TextView l = new TextView(context); + l.setId(View.generateViewId()); + l.setText(label); + l.setTypeface(l.getTypeface(), Typeface.BOLD); + layout.addView(l); + + double initValue = SP.getDouble(preferenceId, init); + initValue = Profile.toCurrentUnits(initValue); + + NumberPicker numberPicker = new NumberPicker(context); + if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) + numberPicker.setParams(initValue, min, max, 0.1d, new DecimalFormat("0.0"), false, null, watcher); + else + numberPicker.setParams(initValue, min * 18, max * 18, 1d, new DecimalFormat("0"), false, null, watcher); + +// LinearLayout.LayoutParams ll = (LinearLayout.LayoutParams) numberPicker.getLayoutParams(); +// ll.gravity = Gravity.CENTER; +// numberPicker.setLayoutParams(ll); + layout.addView(numberPicker); + + TextView c = new TextView(context); + c.setId(View.generateViewId()); + c.setText(comment); + c.setTypeface(c.getTypeface(), Typeface.ITALIC); + layout.addView(c); + + super.generateDialog(layout); + } + + public SWEditNumberWithUnits preferenceId(int preferenceId) { + this.preferenceId = preferenceId; + return this; + } + + public SWEditNumberWithUnits updateDelay(int updateDelay) { + this.updateDelay = updateDelay; + return this; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java index 50e851ed6b..b16164c064 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java @@ -5,6 +5,7 @@ import android.graphics.Typeface; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; +import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; @@ -31,19 +32,19 @@ public class SWEditString extends SWItem { Context context = layout.getContext(); TextView l = new TextView(context); - l.setId(layout.generateViewId()); + l.setId(View.generateViewId()); l.setText(label); l.setTypeface(l.getTypeface(), Typeface.BOLD); layout.addView(l); TextView c = new TextView(context); - c.setId(layout.generateViewId()); + c.setId(View.generateViewId()); c.setText(comment); c.setTypeface(c.getTypeface(), Typeface.ITALIC); layout.addView(c); EditText editText = new EditText(context); - editText.setId(layout.generateViewId()); + editText.setId(View.generateViewId()); editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setMaxLines(1); editText.setText(SP.getString(preferenceId, "")); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java index 6931344acf..734b204ff3 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java @@ -3,6 +3,8 @@ package info.nightscout.androidaps.setupwizard.elements; import android.view.View; import android.widget.LinearLayout; +import androidx.annotation.StringRes; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +40,8 @@ public class SWItem { RADIOBUTTON, PLUGIN, BUTTON, - FRAGMENT + FRAGMENT, + UNITNUMBER } Type type; @@ -66,12 +69,12 @@ public class SWItem { return type; } - public SWItem label(int label) { + public SWItem label(@StringRes int label) { this.label = label; return this; } - public SWItem comment(int comment) { + public SWItem comment(@StringRes int comment) { this.comment = comment; return this; } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt index ef4cae3f83..89e0751e60 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.kt @@ -117,12 +117,12 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile, private fun doCalc() { // Insulin from BG - sens = profile.isf - targetBGLow = profile.targetLow - targetBGHigh = profile.targetHigh + sens = Profile.fromMgdlToUnits(profile.isfMgdl, ProfileFunctions.getSystemUnits()) + targetBGLow = Profile.fromMgdlToUnits(profile.targetLowMgdl, ProfileFunctions.getSystemUnits()) + targetBGHigh = Profile.fromMgdlToUnits(profile.targetHighMgdl, ProfileFunctions.getSystemUnits()) if (useTT && tempTarget != null) { - targetBGLow = Profile.fromMgdlToUnits(tempTarget.low, profile.units) - targetBGHigh = Profile.fromMgdlToUnits(tempTarget.high, profile.units) + targetBGLow = Profile.fromMgdlToUnits(tempTarget.low, ProfileFunctions.getSystemUnits()) + targetBGHigh = Profile.fromMgdlToUnits(tempTarget.high, ProfileFunctions.getSystemUnits()) } if (useBg && bg > 0) { bgDiff = when { @@ -138,7 +138,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile, glucoseStatus?.let { if (useTrend) { trend = it.short_avgdelta - insulinFromTrend = Profile.fromMgdlToUnits(trend, profile.units) * 3 / sens + insulinFromTrend = Profile.fromMgdlToUnits(trend, ProfileFunctions.getSystemUnits()) * 3 / sens } } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/DefaultValueHelper.java b/app/src/main/java/info/nightscout/androidaps/utils/DefaultValueHelper.java index 40448d2680..7ea507e280 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/DefaultValueHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/DefaultValueHelper.java @@ -2,6 +2,8 @@ package info.nightscout.androidaps.utils; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; public class DefaultValueHelper { @@ -41,11 +43,12 @@ public class DefaultValueHelper { /** * returns the configured EatingSoon TempTarget, if this is set to 0, the Default-Value is returned. * - * @param units * @return */ - public double determineEatingSoonTT(String units) { + public double determineEatingSoonTT() { + String units = ProfileFunctions.getSystemUnits(); double value = SP.getDouble(R.string.key_eatingsoon_target, this.getDefaultEatingSoonTT(units)); + value = Profile.toCurrentUnits(value); return value > 0 ? value : this.getDefaultEatingSoonTT(units); } @@ -58,11 +61,12 @@ public class DefaultValueHelper { /** * returns the configured Activity TempTarget, if this is set to 0, the Default-Value is returned. * - * @param units * @return */ - public double determineActivityTT(String units) { + public double determineActivityTT() { + String units = ProfileFunctions.getSystemUnits(); double value = SP.getDouble(R.string.key_activity_target, this.getDefaultActivityTT(units)); + value = Profile.toCurrentUnits(value); return value > 0 ? value : this.getDefaultActivityTT(units); } @@ -74,11 +78,12 @@ public class DefaultValueHelper { /** * returns the configured Hypo TempTarget, if this is set to 0, the Default-Value is returned. * - * @param units * @return */ - public double determineHypoTT(String units) { + public double determineHypoTT() { + String units = ProfileFunctions.getSystemUnits(); double value = SP.getDouble(R.string.key_hypo_target, this.getDefaultHypoTT(units)); + value = Profile.toCurrentUnits(value); return value > 0 ? value : this.getDefaultHypoTT(units); } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/LocaleHelper.kt b/app/src/main/java/info/nightscout/androidaps/utils/LocaleHelper.kt index 6052c5699a..447d076d93 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/LocaleHelper.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/LocaleHelper.kt @@ -1,21 +1,19 @@ package info.nightscout.androidaps.utils import android.content.Context +import android.content.ContextWrapper +import android.os.Build +import android.os.LocaleList import info.nightscout.androidaps.R import java.util.* -object LocaleHelper { - fun update(context: Context) = - updateResources(context, currentLanguage()) +object LocaleHelper { fun currentLanguage(): String = SP.getString(R.string.key_language, Locale.getDefault().language) - fun currentLocale(): Locale = - Locale(SP.getString(R.string.key_language, Locale.getDefault().language)) - - @Suppress("DEPRECATION") - private fun updateResources(context: Context, language: String) { + private fun currentLocale(): Locale { + val language = currentLanguage() var locale = Locale(language) if (language.contains("_")) { // language with country like pt_BR defined in arrays.xml @@ -23,10 +21,35 @@ object LocaleHelper { val country = language.substring(3, 5) locale = Locale(lang, country) } + return locale + } + @Suppress("DEPRECATION") + fun update(context: Context) { + val locale = currentLocale() Locale.setDefault(locale) val resources = context.resources - resources.configuration.setLocale(locale) - resources.updateConfiguration(resources.configuration, resources.displayMetrics) + val configuration = resources.configuration + context.createConfigurationContext(configuration) + configuration.setLocale(locale) + configuration.locale = locale + resources.updateConfiguration(configuration, resources.displayMetrics) + } + + fun wrap(ctx: Context): ContextWrapper { + val res = ctx.resources + val configuration = res.configuration + val newLocale = currentLocale() + 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) + } + return ContextWrapper(context) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java b/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java index e2a7489fc2..54e676a52d 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/NumberPicker.java @@ -86,6 +86,7 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener, public NumberPicker(Context context) { super(context, null); + this.initialize(context); } public NumberPicker(Context context, AttributeSet attrs) { @@ -94,9 +95,13 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener, this.initialize(context); } + protected void inflate(Context context) { + LayoutInflater.from(context).inflate(R.layout.number_picker_layout, this, true); + } + private void initialize(Context context) { // set layout view - LayoutInflater.from(context).inflate(R.layout.number_picker_layout, this, true); + inflate(context); // init ui components minusButton = findViewById(R.id.decrement); diff --git a/app/src/main/java/info/nightscout/androidaps/utils/NumberPickerVertical.java b/app/src/main/java/info/nightscout/androidaps/utils/NumberPickerVertical.java new file mode 100644 index 0000000000..3265280c48 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/utils/NumberPickerVertical.java @@ -0,0 +1,46 @@ +package info.nightscout.androidaps.utils; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.NumberFormat; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; + +/** + * Created by mike on 28.06.2016. + */ +public class NumberPickerVertical extends NumberPicker { + private static Logger log = LoggerFactory.getLogger(NumberPickerVertical.class); + + public NumberPickerVertical(Context context) { + super(context); + } + + public NumberPickerVertical(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void inflate(Context context) { + LayoutInflater.from(context).inflate(R.layout.number_picker_layout_vertical, this, true); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java index a45d329d63..cee3b7ea08 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java @@ -83,4 +83,24 @@ public class OKDialog { .show(); } + public static void showConfirmation(final Activity activity, String message, final Runnable ok, final Runnable cancel) { + AlertDialog alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme)) + .setMessage(message) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + dialog.dismiss(); + if (ok != null) { + SystemClock.sleep(100); + activity.runOnUiThread(ok); + } + }) + .setNegativeButton(android.R.string.cancel, (dialog, which) -> { + dialog.dismiss(); + if (cancel != null) { + SystemClock.sleep(100); + activity.runOnUiThread(cancel); + } + }) + .show(); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/SP.java b/app/src/main/java/info/nightscout/androidaps/utils/SP.java index 1b46642751..e45e650ace 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/SP.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/SP.java @@ -10,7 +10,11 @@ import info.nightscout.androidaps.MainApp; */ public class SP { - static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); + private static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); + + static public void clear() { + sharedPreferences.edit().clear().apply(); + } static public boolean contains(String key) { return sharedPreferences.contains(key); @@ -85,75 +89,51 @@ public class SP { } static public void putBoolean(String key, boolean value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean(key, value); - editor.apply(); + sharedPreferences.edit().putBoolean(key, value).apply(); } static public void putBoolean(int resourceID, boolean value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putBoolean(MainApp.gs(resourceID), value); - editor.apply(); + sharedPreferences.edit().putBoolean(MainApp.gs(resourceID), value).apply(); } static public void putDouble(String key, double value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(key, Double.toString(value)); - editor.apply(); + sharedPreferences.edit().putString(key, Double.toString(value)).apply(); } static public void putLong(String key, long value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putLong(key, value); - editor.apply(); + sharedPreferences.edit().putLong(key, value).apply(); } static public void putLong(int resourceID, long value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putLong(MainApp.gs(resourceID), value); - editor.apply(); + sharedPreferences.edit().putLong(MainApp.gs(resourceID), value).apply(); } static public void putInt(String key, int value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putInt(key, value); - editor.apply(); + sharedPreferences.edit().putInt(key, value).apply(); } static public void putInt(int resourceID, int value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putInt(MainApp.gs(resourceID), value); - editor.apply(); + sharedPreferences.edit().putInt(MainApp.gs(resourceID), value).apply(); } static public void incInt(int resourceID) { - SharedPreferences.Editor editor = sharedPreferences.edit(); int value = SP.getInt(resourceID, 0) + 1; - editor.putInt(MainApp.gs(resourceID), value); - editor.apply(); + sharedPreferences.edit().putInt(MainApp.gs(resourceID), value).apply(); } static public void putString(int resourceID, String value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(MainApp.gs(resourceID), value); - editor.apply(); + sharedPreferences.edit().putString(MainApp.gs(resourceID), value).apply(); } static public void putString(String key, String value) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(key, value); - editor.apply(); + sharedPreferences.edit().putString(key, value).apply(); } static public void remove(int resourceID) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.remove(MainApp.gs(resourceID)); - editor.apply(); + sharedPreferences.edit().remove(MainApp.gs(resourceID)).apply(); } static public void remove(String key) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.remove(key); - editor.apply(); + sharedPreferences.edit().remove(key).apply(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/SntpClient.java b/app/src/main/java/info/nightscout/androidaps/utils/SntpClient.java index fcee3638b9..60de82a93c 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/SntpClient.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/SntpClient.java @@ -16,12 +16,16 @@ package info.nightscout.androidaps.utils; */ import android.os.SystemClock; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; +import info.nightscout.androidaps.logging.L; + /** * {@hide} *

@@ -35,7 +39,7 @@ import java.net.InetAddress; * */ public class SntpClient { - private static final String TAG = "SntpClient"; + private static Logger log = LoggerFactory.getLogger(L.CORE); //private static final int REFERENCE_TIME_OFFSET = 16; private static final int ORIGINATE_TIME_OFFSET = 24; @@ -76,8 +80,10 @@ public class SntpClient { } static void doNtpTime(final Callback callback) { + log.debug("Time detection started"); callback.success = requestTime("time.google.com", 5000); callback.time = getNtpTime() + SystemClock.elapsedRealtime() - getNtpTimeReference(); + log.debug("Time detection ended: " + callback.success + " " + DateUtil.dateAndTimeString(getNtpTime())); callback.run(); } @@ -138,7 +144,7 @@ public class SntpClient { mNtpTimeReference = responseTicks; mRoundTripTime = roundTripTime; } catch (Exception e) { - Log.d(TAG, "request time failed: " + e); + log.debug("request time failed: " + e); return false; } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java b/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java index be8b89dff4..d9ed263c98 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/TimeListEdit.java @@ -84,11 +84,11 @@ public class TimeListEdit { textlabel = new TextView(context); textlabel.setText(label); - textlabel.setGravity(Gravity.START); + textlabel.setGravity(Gravity.CENTER); LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); - llp.setMargins(10, 0, 0, 0); // llp.setMargins(left, top, right, bottom); + llp.setMargins(0, 5, 0, 5); textlabel.setLayoutParams(llp); - textlabel.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.linearBlockBackground)); + //textlabel.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.linearBlockBackground)); TextViewCompat.setTextAppearance(textlabel, android.R.style.TextAppearance_Medium); layout.addView(textlabel); @@ -119,7 +119,8 @@ public class TimeListEdit { private void inflateRow(final int position) { LayoutInflater inflater = LayoutInflater.from(context); - View childView = intervals[position] = inflater.inflate(R.layout.timelistedit_element, layout, false); + int resource = data2 == null ? R.layout.timelistedit_element : R.layout.timelistedit_element_vertical; + View childView = intervals[position] = inflater.inflate(resource, layout, false); spinners[position] = new SpinnerHelper(childView.findViewById(R.id.timelistedit_time)); numberPickers1[position] = childView.findViewById(R.id.timelistedit_edit1); numberPickers2[position] = childView.findViewById(R.id.timelistedit_edit2); diff --git a/app/src/main/java/info/nightscout/androidaps/utils/XdripCalibrations.java b/app/src/main/java/info/nightscout/androidaps/utils/XdripCalibrations.java index f7b8761823..404a082112 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/XdripCalibrations.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/XdripCalibrations.java @@ -46,7 +46,7 @@ public class XdripCalibrations { Context context = MainApp.instance().getApplicationContext(); Bundle bundle = new Bundle(); bundle.putDouble("glucose_number", bg); - bundle.putString("units", ProfileFunctions.getInstance().getProfileUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); + bundle.putString("units", ProfileFunctions.getSystemUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); bundle.putLong("timestamp", System.currentTimeMillis()); Intent intent = new Intent(Intents.ACTION_REMOTE_CALIBRATION); intent.putExtras(bundle); diff --git a/app/src/main/res/drawable/clone.png b/app/src/main/res/drawable/clone.png new file mode 100644 index 0000000000..82fd90cca8 Binary files /dev/null and b/app/src/main/res/drawable/clone.png differ diff --git a/app/src/main/res/drawable/ic_reorder_gray_24dp.xml b/app/src/main/res/drawable/ic_reorder_gray_24dp.xml new file mode 100644 index 0000000000..8c12d67379 --- /dev/null +++ b/app/src/main/res/drawable/ic_reorder_gray_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/actions_fill_dialog.xml b/app/src/main/res/layout/actions_fill_dialog.xml index 27fdb02ee7..ce52f25abb 100644 --- a/app/src/main/res/layout/actions_fill_dialog.xml +++ b/app/src/main/res/layout/actions_fill_dialog.xml @@ -142,7 +142,7 @@ - + diff --git a/app/src/main/res/layout/activity_agreement.xml b/app/src/main/res/layout/activity_agreement.xml deleted file mode 100644 index 5c98f937ed..0000000000 --- a/app/src/main/res/layout/activity_agreement.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - -