diff --git a/app/build.gradle b/app/build.gradle index 3f7dac00a9..00c78fe077 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -57,7 +57,7 @@ android { targetSdkVersion 23 multiDexEnabled true versionCode 1500 - version "1.59-dev" + version "1.60-dev" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() @@ -238,6 +238,7 @@ dependencies { testCompile "org.powermock:powermock-module-junit4:${powermockVersion}" testCompile "joda-time:joda-time:2.9.4.2" testCompile "com.google.truth:truth:0.39" + testCompile "org.skyscreamer:jsonassert:1.5.0" androidTestCompile "org.mockito:mockito-core:2.7.22" androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}" diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java index 14465ccdc9..5faa288d77 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -96,7 +96,7 @@ public class DataService extends IntentService { dexcomG5Enabled = true; } - boolean isNSProfile = ConfigBuilderPlugin.getActiveProfileInterface().getClass().equals(NSProfilePlugin.class); + boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class); boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false); Bundle bundles = intent.getExtras(); @@ -368,9 +368,6 @@ public class DataService extends IntentService { ProfileStore profileStore = new ProfileStore(new JSONObject(profile)); NSProfilePlugin.getPlugin().storeNewProfile(profileStore); MainApp.bus().post(new EventNSProfileUpdateGUI()); - // if there are no profile switches this should lead to profile update - if (MainApp.getConfigBuilder().getProfileSwitchesFromHistory().size() == 0) - MainApp.bus().post(new EventNewBasalProfile()); if (Config.logIncommingData) log.debug("Received profileStore: " + activeProfile + " " + profile); } catch (JSONException e) { 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 5c6d4c9629..e966c4d11d 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -2,8 +2,6 @@ package info.nightscout.androidaps.data; import android.support.v4.util.LongSparseArray; - - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -19,41 +17,43 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.ToastUtils; public class Profile { private static Logger log = LoggerFactory.getLogger(Profile.class); private JSONObject json; - private String units = null; - private double dia = Constants.defaultDIA; - private TimeZone timeZone = TimeZone.getDefault(); + private String units; + private double dia; + private TimeZone timeZone; private JSONArray isf; - private LongSparseArray isf_v = null; // oldest at index 0 + private LongSparseArray isf_v; // oldest at index 0 private JSONArray ic; - private LongSparseArray ic_v = null; // oldest at index 0 + private LongSparseArray ic_v; // oldest at index 0 private JSONArray basal; - private LongSparseArray basal_v = null; // oldest at index 0 + private LongSparseArray basal_v; // oldest at index 0 private JSONArray targetLow; - private LongSparseArray targetLow_v = null; // oldest at index 0 + private LongSparseArray targetLow_v; // oldest at index 0 private JSONArray targetHigh; - private LongSparseArray targetHigh_v = null; // oldest at index 0 + private LongSparseArray targetHigh_v; // oldest at index 0 - private int percentage = 100; - private int timeshift = 0; + private int percentage; + private int timeshift; - private boolean isValid = true; - private boolean isValidated = false; + protected boolean isValid; + protected boolean isValidated; + // Default constructor for tests + protected Profile() { + } + + // Constructor from profileStore JSON public Profile(JSONObject json, String units) { - this(json, 100, 0); + init(json, 100, 0); if (this.units == null) { if (units != null) this.units = units; @@ -65,6 +65,22 @@ public class Profile { } public Profile(JSONObject json, int percentage, int timeshift) { + init(json, percentage, timeshift); + } + + protected void init(JSONObject json, int percentage, int timeshift) { + units = null; + dia = Constants.defaultDIA; + timeZone = TimeZone.getDefault(); + isf_v = null; + ic_v = null; + basal_v = null; + targetLow_v = null; + targetHigh_v = null; + + isValid = true; + isValidated = false; + this.percentage = percentage; this.timeshift = timeshift; this.json = json; @@ -78,53 +94,12 @@ public class Profile { if (json.has("timezone")) timeZone = TimeZone.getTimeZone(json.getString("timezone")); isf = json.getJSONArray("sens"); - if (getIsf(0) == null) { - int defaultISF = units.equals(Constants.MGDL) ? 400 : 20; - isf = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultISF + "\",\"timeAsSeconds\":\"0\"}]"); - Notification noisf = new Notification(Notification.ISF_MISSING, MainApp.sResources.getString(R.string.isfmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(noisf)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.ISF_MISSING)); - } ic = json.getJSONArray("carbratio"); - if (getIc(0) == null) { - int defaultIC = 25; - ic = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultIC + "\",\"timeAsSeconds\":\"0\"}]"); - Notification noic = new Notification(Notification.IC_MISSING, MainApp.sResources.getString(R.string.icmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(noic)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.IC_MISSING)); - } basal = json.getJSONArray("basal"); - if (getBasal(0) == null) { - double defaultBasal = 0.1d; - basal = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultBasal + "\",\"timeAsSeconds\":\"0\"}]"); - Notification nobasal = new Notification(Notification.BASAL_MISSING, MainApp.sResources.getString(R.string.basalmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(nobasal)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.BASAL_MISSING)); - } targetLow = json.getJSONArray("target_low"); - if (getTargetLow(0) == null) { - double defaultLow = units.equals(Constants.MGDL) ? 120 : 6; - targetLow = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultLow + "\",\"timeAsSeconds\":\"0\"}]"); - Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notarget)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING)); - } targetHigh = json.getJSONArray("target_high"); - if (getTargetHigh(0) == null) { - double defaultHigh = units.equals(Constants.MGDL) ? 160 : 8; - targetHigh = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultHigh + "\",\"timeAsSeconds\":\"0\"}]"); - Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notarget)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING)); - } } catch (JSONException e) { log.error("Unhandled exception", e); - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.invalidprofile)); isValid = false; isValidated = true; } @@ -133,7 +108,7 @@ public class Profile { public String log() { String ret = "\n"; for (Integer hour = 0; hour < 24; hour++) { - double value = getBasal((Integer) (hour * 60 * 60)); + double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60)); ret += "NS basal value for " + hour + ":00 is " + value + "\n"; } ret += "NS units: " + getUnits(); @@ -155,6 +130,10 @@ public class Profile { } // mmol or mg/dl + public void setUnits(String units) { + this.units = units; + } + public String getUnits() { return units; } @@ -164,6 +143,11 @@ public class Profile { } private LongSparseArray convertToSparseArray(JSONArray array) { + if (array == null) { + isValid = false; + return new LongSparseArray<>(); + } + double multiplier = getMultiplier(array); LongSparseArray sparse = new LongSparseArray<>(); @@ -235,7 +219,7 @@ public class Profile { for (int i = 0; i < basal_v.size(); i++) { if (basal_v.valueAt(i) < description.basalMinimumRate) { basal_v.setValueAt(i, description.basalMinimumRate); - MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL))); + sendBelowMinimumNotification(from); } } } else { @@ -249,6 +233,10 @@ public class Profile { return isValid; } + protected void sendBelowMinimumNotification(String from) { + MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL))); + } + private void validate(LongSparseArray array) { if (array.size() == 0) { isValid = false; @@ -262,6 +250,7 @@ public class Profile { } } + /* private Double getValueToTime(JSONArray array, Integer timeAsSeconds) { Double lastValue = null; @@ -281,6 +270,7 @@ public class Profile { } return lastValue; } + */ Integer getShitfTimeSecs(Integer originalTime) { Integer shiftedTime = originalTime + timeshift * 60 * 60; @@ -322,7 +312,7 @@ public class Profile { return multiplier; } - private Double getValueToTime(LongSparseArray array, Integer timeAsSeconds) { + private double getValueToTime(LongSparseArray array, Integer timeAsSeconds) { Double lastValue = null; for (Integer index = 0; index < array.size(); index++) { @@ -337,7 +327,7 @@ public class Profile { return lastValue; } - private String format_HH_MM(Integer timeAsSeconds) { + protected String format_HH_MM(Integer timeAsSeconds) { String time; int hour = timeAsSeconds / 60 / 60; int minutes = (timeAsSeconds - hour * 60 * 60) / 60; @@ -364,51 +354,55 @@ public class Profile { return retValue; } - public Double getIsf() { - return getIsf(secondsFromMidnight(System.currentTimeMillis())); + public double getIsf() { + return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); } - public Double getIsf(long time) { - return getIsf(secondsFromMidnight(time)); + public double getIsf(long time) { + return getIsfTimeFromMidnight(secondsFromMidnight(time)); } - public Double getIsf(Integer timeAsSeconds) { + double getIsfTimeFromMidnight(int timeAsSeconds) { if (isf_v == null) isf_v = convertToSparseArray(isf); return getValueToTime(isf_v, timeAsSeconds); } public String getIsfList() { + if (isf_v == null) + isf_v = convertToSparseArray(isf); return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U"); } - public Double getIc() { - return getIc(secondsFromMidnight(System.currentTimeMillis())); + public double getIc() { + return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); } - public Double getIc(long time) { - return getIc(secondsFromMidnight(time)); + public double getIc(long time) { + return getIcTimeFromMidnight(secondsFromMidnight(time)); } - public Double getIc(Integer timeAsSeconds) { + public double getIcTimeFromMidnight(int timeAsSeconds) { if (ic_v == null) ic_v = convertToSparseArray(ic); return getValueToTime(ic_v, timeAsSeconds); } public String getIcList() { - return getValuesList(ic_v, null, new DecimalFormat("0.0"), " g/U"); + if (ic_v == null) + ic_v = convertToSparseArray(ic); + return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U"); } - public Double getBasal() { - return getBasal(secondsFromMidnight(System.currentTimeMillis())); + public double getBasal() { + return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); } - public Double getBasal(long time) { - return getBasal(secondsFromMidnight(time)); + public double getBasal(long time) { + return getBasalTimeFromMidnight(secondsFromMidnight(time)); } - public synchronized Double getBasal(Integer timeAsSeconds) { + public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) { if (basal_v == null) { basal_v = convertToSparseArray(basal); } @@ -418,17 +412,17 @@ public class Profile { public String getBasalList() { if (basal_v == null) basal_v = convertToSparseArray(basal); - return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U"); + return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U/h"); } public class BasalValue { - public BasalValue(Integer timeAsSeconds, Double value) { + public BasalValue(int timeAsSeconds, double value) { this.timeAsSeconds = timeAsSeconds; this.value = value; } - public Integer timeAsSeconds; - public Double value; + public int timeAsSeconds; + public double value; } public synchronized BasalValue[] getBasalValues() { @@ -438,7 +432,7 @@ public class Profile { for (Integer index = 0; index < basal_v.size(); index++) { Integer tas = (int) basal_v.keyAt(index); - Double value = basal_v.valueAt(index); + double value = basal_v.valueAt(index); ret[index] = new BasalValue(tas, value); } return ret; @@ -448,52 +442,56 @@ public class Profile { return getTarget(secondsFromMidnight(System.currentTimeMillis())); } - private double getTarget(Integer time) { - return (getTargetLow(time) + getTargetHigh(time))/2; + protected double getTarget(int timeAsSeconds) { + return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2; } - public Double getTargetLow() { - return getTargetLow(secondsFromMidnight(System.currentTimeMillis())); + public double getTargetLow() { + return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); } - public Double getTargetLow(long time) { - return getTargetLow(secondsFromMidnight(time)); + public double getTargetLow(long time) { + return getTargetLowTimeFromMidnight(secondsFromMidnight(time)); } - public Double getTargetLow(Integer timeAsSeconds) { + public double getTargetLowTimeFromMidnight(int timeAsSeconds) { if (targetLow_v == null) targetLow_v = convertToSparseArray(targetLow); return getValueToTime(targetLow_v, timeAsSeconds); } - public Double getTargetHigh() { - return getTargetHigh(secondsFromMidnight(System.currentTimeMillis())); + public double getTargetHigh() { + return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); } - public Double getTargetHigh(long time) { - return getTargetHigh(secondsFromMidnight(time)); + public double getTargetHigh(long time) { + return getTargetHighTimeFromMidnight(secondsFromMidnight(time)); } - public Double getTargetHigh(Integer timeAsSeconds) { + public double getTargetHighTimeFromMidnight(int timeAsSeconds) { if (targetHigh_v == null) targetHigh_v = convertToSparseArray(targetHigh); return getValueToTime(targetHigh_v, timeAsSeconds); } public String getTargetList() { + if (targetLow_v == null) + targetLow_v = convertToSparseArray(targetLow); + if (targetHigh_v == null) + targetHigh_v = convertToSparseArray(targetHigh); return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits()); } public double getMaxDailyBasal() { - Double max = 0d; - for (Integer hour = 0; hour < 24; hour++) { - double value = getBasal((Integer) (hour * 60 * 60)); + double max = 0d; + for (int hour = 0; hour < 24; hour++) { + double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60)); if (value > max) max = value; } return max; } - public static Integer secondsFromMidnight() { + public static int secondsFromMidnight() { Calendar c = Calendar.getInstance(); long now = c.getTimeInMillis(); c.set(Calendar.HOUR_OF_DAY, 0); @@ -504,7 +502,7 @@ public class Profile { return (int) (passed / 1000); } - public static Integer secondsFromMidnight(long date) { + public static int secondsFromMidnight(long date) { Calendar c = Calendar.getInstance(); c.setTimeInMillis(date); c.set(Calendar.HOUR_OF_DAY, 0); @@ -515,22 +513,22 @@ public class Profile { return (int) (passed / 1000); } - public static Double toMgdl(Double value, String units) { + public static double toMgdl(double value, String units) { if (units.equals(Constants.MGDL)) return value; else return value * Constants.MMOLL_TO_MGDL; } - public static Double toMmol(Double value, String units) { + public static double toMmol(double value, String units) { if (units.equals(Constants.MGDL)) return value * Constants.MGDL_TO_MMOLL; else return value; } - public static Double fromMgdlToUnits(Double value, String units) { + public static double fromMgdlToUnits(double value, String units) { if (units.equals(Constants.MGDL)) return value; else return value * Constants.MGDL_TO_MMOLL; } - public static Double toUnits(Double valueInMgdl, Double valueInMmol, String units) { + public static double toUnits(Double valueInMgdl, Double valueInMmol, String units) { if (units.equals(Constants.MGDL)) return valueInMgdl; else return valueInMmol; } @@ -556,7 +554,7 @@ public class Profile { public double percentageBasalSum() { double result = 0d; for (int i = 0; i < 24; i++) { - result += getBasal((Integer) (i * 60 * 60)); + result += getBasalTimeFromMidnight(i * 60 * 60); } return result; } @@ -565,7 +563,7 @@ public class Profile { public double baseBasalSum() { double result = 0d; for (int i = 0; i < 24; i++) { - result += getBasal((Integer) (i * 60 * 60)) / getMultiplier(basal_v); + result += getBasalTimeFromMidnight(i * 60 * 60) / getMultiplier(basal_v); } return result; } diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java index 0ea76ffb15..8ea89e2a5b 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -3,10 +3,14 @@ package info.nightscout.androidaps.data; import android.support.annotation.Nullable; import android.support.v4.util.LongSparseArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.utils.DateUtil; /** * Created by mike on 09.05.2017. @@ -16,6 +20,7 @@ import info.nightscout.androidaps.interfaces.Interval; // When no interval match the lastest record without duration is used public class ProfileIntervals { + private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class); private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 @@ -51,6 +56,11 @@ public class ProfileIntervals { public synchronized Interval getValueToTime(long time) { int index = binarySearch(time); if (index >= 0) return rawData.valueAt(index); + // if we request data older than first record, use oldest instead + if (rawData.size() > 0) { + log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); + return rawData.valueAt(0); + } return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 06e411d856..72d45c9950 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -1709,7 +1709,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (trJson.has("profileJson")) profileSwitch.profileJson = trJson.getString("profileJson"); else { - ProfileStore store = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); + ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); Profile profile = store.getSpecificProfile(profileSwitch.profileName); if (profile != null) { profileSwitch.profileJson = profile.getData().toString(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java index 701d050cee..2656e43a26 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java @@ -96,7 +96,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli noProfileView = view.findViewById(R.id.profileview_noprofile); butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons); - ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); + ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); if (profileStore == null) { noProfileView.setVisibility(View.VISIBLE); butonsLayout.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 6e2728c95b..99fc44341b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -59,6 +59,7 @@ import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.DateUtil; import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; +import info.nightscout.utils.OKDialog; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.Translator; @@ -73,7 +74,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick Profile profile; ProfileStore profileStore; - String units; + String units = Constants.MGDL; TextView eventTypeText; LinearLayout layoutPercent; @@ -168,19 +169,24 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick // profile profile = MainApp.getConfigBuilder().getProfile(); - profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); - ArrayList profileList; - units = profile != null ? profile.getUnits() : Constants.MGDL; - profileList = profileStore.getProfileList(); - ArrayAdapter adapter = new ArrayAdapter(getContext(), - R.layout.spinner_centered, profileList); - profileSpinner.setAdapter(adapter); - // set selected to actual profile - for (int p = 0; p < profileList.size(); p++) { - if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false))) - profileSpinner.setSelection(p); + profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + if (profileStore == null) { + if (options.eventType == R.id.careportal_profileswitch) { + log.error("Profile switch called but plugin doesn't contain valid profile"); + } + } else { + ArrayList profileList; + units = profile != null ? profile.getUnits() : Constants.MGDL; + profileList = profileStore.getProfileList(); + ArrayAdapter adapter = new ArrayAdapter<>(getContext(), + R.layout.spinner_centered, profileList); + profileSpinner.setAdapter(adapter); + // set selected to actual profile + for (int p = 0; p < profileList.size(); p++) { + if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false))) + profileSpinner.setSelection(p); + } } - final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); // temp target @@ -720,7 +726,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSwitch.source = Source.USER; profileSwitch.profileName = profileName; profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); - profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName(); + profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName(); profileSwitch.durationInMinutes = duration; profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.timeshift = timeshift; @@ -752,7 +758,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSwitch.source = Source.USER; profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false); profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString(); - profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName(); + profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName(); profileSwitch.durationInMinutes = duration; profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.timeshift = timeshift; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index 1b411b3c40..45e4ddffc6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -200,7 +200,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr return activeBgSource; } - public static ProfileInterface getActiveProfileInterface() { + public ProfileInterface getActiveProfileInterface() { return activeProfile; } @@ -760,33 +760,21 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr } public String getProfileName(long time, boolean customized) { - boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false); - if (!ignoreProfileSwitchEvents) { - ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; - } else { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profileSwitch.profileName; - } + ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; + } else { + Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profileSwitch.profileName; } } - // Unable to determine profile, failover to default - String defaultProfile = activeProfile.getProfile().getDefaultProfileName(); - if (defaultProfile != null) - return defaultProfile; - // If default from plugin fails .... create empty - return "Default"; + return MainApp.gs(R.string.noprofileselected); } public boolean isProfileValid(String from) { - return getProfile() != null && getProfile().isValid(from) && - activeProfile != null && - activeProfile.getProfile() != null && - activeProfile.getProfile().getDefaultProfile() != null && - activeProfile.getProfile().getDefaultProfile().isValid(from); + return getProfile() != null && getProfile().isValid(from); } @Nullable @@ -806,41 +794,16 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr return null; //app not initialized } //log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); - boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false); - if (!ignoreProfileSwitchEvents) { - ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - return profileSwitch.getProfileObject(); - } else if (activeProfile.getProfile() != null) { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profile; - } + ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return profileSwitch.getProfileObject(); + } else if (activeProfile.getProfile() != null) { + Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profile; } } - // Unable to determine profile, failover to default - if (activeProfile.getProfile() == null) { - log.debug("getProfile activeProfile.getProfile() == null: returning null (activeProfile=" + activeProfile.getClass().getSimpleName() + ")"); - return null; //app not initialized - } - Profile defaultProfile = activeProfile.getProfile().getDefaultProfile(); - if (defaultProfile != null) - return defaultProfile; - // If default from plugin fails .... create empty - try { - Notification noisf = new Notification(Notification.ISF_MISSING, MainApp.sResources.getString(R.string.isfmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(noisf)); - Notification noic = new Notification(Notification.IC_MISSING, MainApp.sResources.getString(R.string.icmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(noic)); - Notification nobasal = new Notification(Notification.BASAL_MISSING, MainApp.sResources.getString(R.string.basalmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(nobasal)); - Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notarget)); - return new Profile(new JSONObject("{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"6\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"8\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}}"), 100, 0); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } log.debug("getProfile at the end: returning null"); return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index c492aae400..1a4c499c59 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -110,11 +110,6 @@ public class IobCobThread extends Thread { return; // profile not set yet } - if (profile.getIsf(bgTime) == null) { - log.debug("Aborting calculation thread (no ISF): " + from); - return; // profile not set yet - } - if (Config.logAutosensData) log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java index 5372f66b03..5fc7809f4e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java @@ -204,7 +204,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().doubleValue(), units)); + mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); mProfile.put("skip_neutral_temps", true); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index 6ac207ab80..dfab195125 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -212,9 +212,9 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!HardLimits.checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java index e7bd0c86fd..1ffa682fc5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java @@ -172,7 +172,7 @@ 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().doubleValue(), units)); + mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); mProfile.put("current_basal", basalRate); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java index 7f8b56f021..76df63e752 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java @@ -212,9 +212,9 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java index 64f8a155fd..9df54b34d3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java @@ -228,7 +228,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().doubleValue(), units)); + mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index 91aa4ef515..f10e6cb0be 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java @@ -216,9 +216,9 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return; if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index e99248c966..56f2276327 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -400,7 +400,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com private void initDialog() { Profile profile = MainApp.getConfigBuilder().getProfile(); - ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); + ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); if (profile == null) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile)); @@ -444,7 +444,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } private void calculateInsulin() { - ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); + ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) return; // not initialized yet String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 3dd6b04f40..5d9a652816 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -187,7 +187,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final Object updateSync = new Object(); - public enum CHARTTYPE {PRE,BAS, IOB, COB, DEV, SEN}; + public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN}; + private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private static ScheduledFuture scheduledUpdate = null; @@ -344,7 +345,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, SpannableString s; PopupMenu popup = new PopupMenu(v.getContext(), v); - if(predictionsAvailable) { + if (predictionsAvailable) { item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions"); title = item.getTitle(); s = new SpannableString(title); @@ -464,7 +465,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else if (v == activeProfileView) { menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile)); menu.add(MainApp.sResources.getString(R.string.danar_viewprofile)); - menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch)); + if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) { + menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch)); + } } } @@ -966,7 +969,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (timeView != null) { //must not exists timeView.setText(DateUtil.timeString(new Date())); } - if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {// app not initialized yet + if (!MainApp.getConfigBuilder().isProfileValid("Overview")) { pumpStatusView.setText(R.string.noprofileset); pumpStatusLayout.setVisibility(View.VISIBLE); loopStatusLayout.setVisibility(View.GONE); @@ -983,12 +986,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) { - pumpStatusView.setText(R.string.noprofileset); - pumpStatusLayout.setVisibility(View.VISIBLE); - loopStatusLayout.setVisibility(View.GONE); - return; - } final String units = profile.getUnits(); final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java index 38d54bc6fd..5868ed316a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java @@ -42,10 +42,7 @@ public class Notification { public static final int APPROACHING_DAILY_LIMIT = 11; public static final int NSCLIENT_NO_WRITE_PERMISSION = 12; public static final int MISSING_SMS_PERMISSION = 13; - public static final int ISF_MISSING = 14; - public static final int IC_MISSING = 15; - public static final int BASAL_MISSING = 16; - public static final int TARGET_MISSING = 17; + public static final int NSANNOUNCEMENT = 18; public static final int NSALARM = 19; public static final int NSURGENTALARM = 20; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java index 84a1dd3a87..b99a9f0799 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java @@ -14,47 +14,55 @@ import com.squareup.otto.Subscribe; import java.util.ArrayList; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnItemSelected; 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.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; +import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED; -public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener { - private Spinner profileSpinner; - private TextView noProfile; - private TextView units; - private TextView dia; - private TextView activeProfile; - private TextView ic; - private TextView isf; - private TextView basal; - private TextView target; + +public class NSProfileFragment extends SubscriberFragment { + @BindView(R.id.nsprofile_spinner) + Spinner profileSpinner; + @BindView(R.id.profileview_noprofile) + TextView noProfile; + @BindView(R.id.profileview_invalidprofile) + TextView invalidProfile; + @BindView(R.id.profileview_units) + TextView units; + @BindView(R.id.profileview_dia) + TextView dia; + @BindView(R.id.profileview_activeprofile) + TextView activeProfile; + @BindView(R.id.profileview_ic) + TextView ic; + @BindView(R.id.profileview_isf) + TextView isf; + @BindView(R.id.profileview_basal) + TextView basal; + @BindView(R.id.profileview_target) + TextView target; + @BindView(R.id.basal_graph) + ProfileGraph basalGraph; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { try { - View layout = inflater.inflate(R.layout.nsprofile_fragment, container, false); - - profileSpinner = (Spinner) layout.findViewById(R.id.nsprofile_spinner); - noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile); - units = (TextView) layout.findViewById(R.id.profileview_units); - dia = (TextView) layout.findViewById(R.id.profileview_dia); - activeProfile = (TextView) layout.findViewById(R.id.profileview_activeprofile); - ic = (TextView) layout.findViewById(R.id.profileview_ic); - isf = (TextView) layout.findViewById(R.id.profileview_isf); - basal = (TextView) layout.findViewById(R.id.profileview_basal); - target = (TextView) layout.findViewById(R.id.profileview_target); - - profileSpinner.setOnItemSelectedListener(this); + View view = inflater.inflate(R.layout.nsprofile_fragment, container, false); + unbinder = ButterKnife.bind(this, view); updateGUI(); - return layout; + return view; } catch (Exception e) { FabricPrivacy.logException(e); } @@ -66,12 +74,7 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView public void onStatusEvent(final EventNSProfileUpdateGUI ev) { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - updateGUI(); - } - }); + activity.runOnUiThread(() -> updateGUI()); } @Override @@ -97,9 +100,9 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView } } - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - String name = parent.getItemAtPosition(position).toString(); + @OnItemSelected(R.id.nsprofile_spinner) + public void onItemSelected(Spinner spinner, int position) { + String name = spinner.getItemAtPosition(position).toString(); ProfileStore store = NSProfilePlugin.getPlugin().getProfile(); if (store != null) { @@ -112,12 +115,18 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView isf.setText(profile.getIsfList()); basal.setText(profile.getBasalList()); target.setText(profile.getTargetList()); + basalGraph.show(profile); } + if (profile.isValid("NSProfileFragment")) + invalidProfile.setVisibility(View.GONE); + else + invalidProfile.setVisibility(View.VISIBLE); } } - @Override - public void onNothingSelected(AdapterView parent) { + @OnItemSelected(value = R.id.nsprofile_spinner, callback = NOTHING_SELECTED) + public void onNothingSelected() { + invalidProfile.setVisibility(View.VISIBLE); noProfile.setVisibility(View.VISIBLE); units.setText(""); dia.setText(""); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java index 4911187db4..c2d7cfabfc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java @@ -120,19 +120,6 @@ public class NSProfilePlugin implements PluginBase, ProfileInterface { profile = new ProfileStore(newProfile.getData()); storeNSProfile(); MainApp.bus().post(new EventNSProfileUpdateGUI()); - if (MainApp.getConfigBuilder().isProfileValid("storeNewProfile")) { - ConfigBuilderPlugin.getCommandQueue().setProfile(MainApp.getConfigBuilder().getProfile(), new Callback() { - @Override - public void run() { - if (result.enacted) { - SmsCommunicatorPlugin smsCommunicatorPlugin = MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class); - if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginBase.GENERAL)) { - smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.sResources.getString(R.string.profile_set_ok)); - } - } - } - }); - } } private void storeNSProfile() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java index 758f872ffe..b57b8543f4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -184,7 +184,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; for (int h = 0; h < basalValues; h++) { Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); + Double profileValue = profile.getBasalTimeFromMidnight((Integer) (h * basalIncrement)); if (profileValue == null) return true; if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java index 520e12d454..1e346695e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java @@ -241,7 +241,7 @@ public class DanaRPump { for (Integer hour = 0; hour < 24; hour++) { //Some values get truncated to the next lower one. // -> round them to two decimals and make sure we are a small delta larger (that will get truncated) - double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001; + double value = Math.round(100d * nsProfile.getBasalTimeFromMidnight((Integer) (hour * 60 * 60)))/100d + 0.00001; if (Config.logDanaMessageDetail) log.debug("NS basal value for " + hour + ":00 is " + value); record[hour] = value; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index 437e528441..48838117c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -428,7 +428,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; for (int h = 0; h < basalValues; h++) { Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal((Integer) (h * basalIncrement)); + Double profileValue = profile.getBasalTimeFromMidnight((Integer) (h * basalIncrement)); if (profileValue == null) return true; if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 46e90184fc..0a38477808 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -52,12 +52,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { private PumpDescription pumpDescription = new PumpDescription(); private static void loadFakingStatus() { - fromNSAreCommingFakedExtendedBoluses = SP.getBoolean("fromNSAreCommingFakedExtendedBoluses", false); + fromNSAreCommingFakedExtendedBoluses = SP.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false); } public static void setFakingStatus(boolean newStatus) { fromNSAreCommingFakedExtendedBoluses = newStatus; - SP.putBoolean("fromNSAreCommingFakedExtendedBoluses", fromNSAreCommingFakedExtendedBoluses); + SP.putBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, fromNSAreCommingFakedExtendedBoluses); } public static boolean getFakingStatus() { @@ -73,7 +73,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { return plugin; } - private VirtualPumpPlugin() { + public VirtualPumpPlugin() { pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.1d; @@ -245,7 +245,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { public double getBaseBasalRate() { Profile profile = MainApp.getConfigBuilder().getProfile(); if (profile != null) - return profile.getBasal() != null ? profile.getBasal() : 0d; + return profile.getBasal(); else return 0d; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java index 4b3208a2bf..ef5c4bce5b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java @@ -59,7 +59,7 @@ public class BGSourceFragment extends SubscriberFragment { RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)); recyclerView.setAdapter(adapter); - profile = ConfigBuilderPlugin.getActiveProfileInterface().getProfile().getDefaultProfile(); + profile = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile().getDefaultProfile(); return view; } catch (Exception e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java index b38fe4001e..61f4877ccc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java @@ -33,8 +33,8 @@ public class ProfileGraph extends GraphView { List basalArray = new ArrayList<>(); for (int hour = 0; hour < 24; hour++) { - basalArray.add(new DataPoint(hour, profile.getBasal(new Integer(hour*60*60)))); - basalArray.add(new DataPoint(hour+1, profile.getBasal(new Integer(hour*60*60)))); + basalArray.add(new DataPoint(hour, profile.getBasalTimeFromMidnight(new Integer(hour*60*60)))); + basalArray.add(new DataPoint(hour+1, profile.getBasalTimeFromMidnight(new Integer(hour*60*60)))); } DataPoint[] basalDataPoints = new DataPoint[basalArray.size()]; basalDataPoints = basalArray.toArray(basalDataPoints); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java index fa1105faac..3286f91a62 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java @@ -12,6 +12,9 @@ import android.widget.TextView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.Unbinder; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; @@ -30,19 +33,36 @@ public class ProfileViewerDialog extends DialogFragment { private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class); - private TextView noProfile; - private TextView units; - private TextView dia; - private TextView activeProfile; - private TextView ic; - private TextView isf; - private TextView basal; - private TextView target; - private View dateDelimiter; - private LinearLayout dateLayout; - private TextView dateTextView; - private Button refreshButton; - private ProfileGraph basalGraph; + @BindView(R.id.profileview_noprofile) + TextView noProfile; + @BindView(R.id.profileview_invalidprofile) + TextView invalidProfile; + @BindView(R.id.profileview_units) + TextView units; + @BindView(R.id.profileview_dia) + TextView dia; + @BindView(R.id.profileview_activeprofile) + TextView activeProfile; + @BindView(R.id.profileview_ic) + TextView ic; + @BindView(R.id.profileview_isf) + TextView isf; + @BindView(R.id.profileview_basal) + TextView basal; + @BindView(R.id.profileview_target) + TextView target; + @BindView(R.id.profileview_datedelimiter) + View dateDelimiter; + @BindView(R.id.profileview_datelayout) + LinearLayout dateLayout; + @BindView(R.id.profileview_date) + TextView dateTextView; + @BindView(R.id.profileview_reload) + Button refreshButton; + @BindView(R.id.basal_graph) + ProfileGraph basalGraph; + + private Unbinder unbinder; public static ProfileViewerDialog newInstance(long time) { ProfileViewerDialog dialog = new ProfileViewerDialog(); @@ -61,31 +81,26 @@ public class ProfileViewerDialog extends DialogFragment { time = getArguments().getLong("time"); } + @Override + public void onDestroyView() { + super.onDestroyView(); + if (unbinder != null) + unbinder.unbind(); + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View layout = inflater.inflate(R.layout.profileviewer_fragment, container, false); + View view = inflater.inflate(R.layout.profileviewer_fragment, container, false); + unbinder = ButterKnife.bind(this, view); - noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile); - units = (TextView) layout.findViewById(R.id.profileview_units); - dia = (TextView) layout.findViewById(R.id.profileview_dia); - activeProfile = (TextView) layout.findViewById(R.id.profileview_activeprofile); - ic = (TextView) layout.findViewById(R.id.profileview_ic); - isf = (TextView) layout.findViewById(R.id.profileview_isf); - basal = (TextView) layout.findViewById(R.id.profileview_basal); - target = (TextView) layout.findViewById(R.id.profileview_target); - refreshButton = (Button) layout.findViewById(R.id.profileview_reload); refreshButton.setVisibility(View.GONE); - dateDelimiter = layout.findViewById(R.id.profileview_datedelimiter); dateDelimiter.setVisibility(View.VISIBLE); - dateLayout = (LinearLayout) layout.findViewById(R.id.profileview_datelayout); dateLayout.setVisibility(View.VISIBLE); - dateTextView = (TextView) layout.findViewById(R.id.profileview_date); - basalGraph = (ProfileGraph) layout.findViewById(R.id.basal_graph); setContent(); - return layout; + return view; } @Override @@ -114,6 +129,11 @@ public class ProfileViewerDialog extends DialogFragment { basal.setText(profile.getBasalList()); target.setText(profile.getTargetList()); basalGraph.show(profile); + + if (profile.isValid("ProfileViewDialog")) + invalidProfile.setVisibility(View.GONE); + else + invalidProfile.setVisibility(View.VISIBLE); } else { noProfile.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java index 30d0060682..b304490e22 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java @@ -586,7 +586,7 @@ public class ActionStringHandler { } final Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null || profile.getBasal() == null) { + if (profile == null) { msg += MainApp.sResources.getString(R.string.notloadedplugins) + "\n"; } if (!"".equals(msg)) { diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java index fe236fa55f..8b2437fdc3 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java @@ -1,9 +1,14 @@ package info.nightscout.androidaps.queue.commands; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.db.ProfileSwitch; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.queue.Callback; /** @@ -11,7 +16,7 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandSetProfile extends Command { - Profile profile; + private Profile profile; public CommandSetProfile(Profile profile, Callback callback) { commandType = CommandType.BASALPROFILE; @@ -24,6 +29,15 @@ public class CommandSetProfile extends Command { PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile); if (callback != null) callback.result(r).run(); + + // Send SMS notification if ProfileSwitch is comming from NS + ProfileSwitch profileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis()); + if (r.enacted && profileSwitch.source == Source.NIGHTSCOUT) { + SmsCommunicatorPlugin smsCommunicatorPlugin = MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class); + if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginBase.GENERAL)) { + smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.sResources.getString(R.string.profile_set_ok)); + } + } } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java index 3d3258c614..810bf124c9 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java @@ -52,7 +52,7 @@ public class KeepAliveReceiver extends BroadcastReceiver { private void checkPump() { final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final Profile profile = MainApp.getConfigBuilder().getProfile(); - if (pump != null && profile != null && profile.getBasal() != null) { + if (pump != null && profile != null) { Date lastConnection = pump.lastDataTime(); boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep; diff --git a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java index 915d8bfb27..66cabd9db6 100644 --- a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java +++ b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java @@ -76,7 +76,7 @@ public class LocalAlertUtils { final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final Profile profile = MainApp.getConfigBuilder().getProfile(); - if (pump != null && profile != null && profile.getBasal() != null) { + if (pump != null && profile != null) { Date lastConnection = pump.lastDataTime(); long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold(); if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) { diff --git a/app/src/main/res/layout/nsprofile_fragment.xml b/app/src/main/res/layout/nsprofile_fragment.xml index b1c88c41c1..e8a38195cb 100644 --- a/app/src/main/res/layout/nsprofile_fragment.xml +++ b/app/src/main/res/layout/nsprofile_fragment.xml @@ -12,7 +12,6 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/profileviewer_fragment.xml b/app/src/main/res/layout/profileviewer_fragment.xml index 9f6da2acfb..7019c306ea 100644 --- a/app/src/main/res/layout/profileviewer_fragment.xml +++ b/app/src/main/res/layout/profileviewer_fragment.xml @@ -13,6 +13,17 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + android:visibility="gone" /> + + android:layout_height="100dip" + android:layout_margin="20dp" /> +