Merge branch 'dev' into dev-merge

This commit is contained in:
Johannes Mockenhaupt 2018-03-18 20:20:40 +01:00 committed by GitHub
commit 643f3aee6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 496 additions and 388 deletions

View file

@ -57,7 +57,7 @@ android {
targetSdkVersion 23 targetSdkVersion 23
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "1.59-dev" version "1.60-dev"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild() buildConfigField "String", "BUILDVERSION", generateGitBuild()
@ -238,6 +238,7 @@ dependencies {
testCompile "org.powermock:powermock-module-junit4:${powermockVersion}" testCompile "org.powermock:powermock-module-junit4:${powermockVersion}"
testCompile "joda-time:joda-time:2.9.4.2" testCompile "joda-time:joda-time:2.9.4.2"
testCompile "com.google.truth:truth:0.39" testCompile "com.google.truth:truth:0.39"
testCompile "org.skyscreamer:jsonassert:1.5.0"
androidTestCompile "org.mockito:mockito-core:2.7.22" androidTestCompile "org.mockito:mockito-core:2.7.22"
androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}" androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"

View file

@ -96,7 +96,7 @@ public class DataService extends IntentService {
dexcomG5Enabled = true; 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); boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
Bundle bundles = intent.getExtras(); Bundle bundles = intent.getExtras();
@ -368,9 +368,6 @@ public class DataService extends IntentService {
ProfileStore profileStore = new ProfileStore(new JSONObject(profile)); ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
NSProfilePlugin.getPlugin().storeNewProfile(profileStore); NSProfilePlugin.getPlugin().storeNewProfile(profileStore);
MainApp.bus().post(new EventNSProfileUpdateGUI()); 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) if (Config.logIncommingData)
log.debug("Received profileStore: " + activeProfile + " " + profile); log.debug("Received profileStore: " + activeProfile + " " + profile);
} catch (JSONException e) { } catch (JSONException e) {

View file

@ -2,8 +2,6 @@ package info.nightscout.androidaps.data;
import android.support.v4.util.LongSparseArray; import android.support.v4.util.LongSparseArray;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -19,41 +17,43 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; 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.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.ToastUtils;
public class Profile { public class Profile {
private static Logger log = LoggerFactory.getLogger(Profile.class); private static Logger log = LoggerFactory.getLogger(Profile.class);
private JSONObject json; private JSONObject json;
private String units = null; private String units;
private double dia = Constants.defaultDIA; private double dia;
private TimeZone timeZone = TimeZone.getDefault(); private TimeZone timeZone;
private JSONArray isf; private JSONArray isf;
private LongSparseArray<Double> isf_v = null; // oldest at index 0 private LongSparseArray<Double> isf_v; // oldest at index 0
private JSONArray ic; private JSONArray ic;
private LongSparseArray<Double> ic_v = null; // oldest at index 0 private LongSparseArray<Double> ic_v; // oldest at index 0
private JSONArray basal; private JSONArray basal;
private LongSparseArray<Double> basal_v = null; // oldest at index 0 private LongSparseArray<Double> basal_v; // oldest at index 0
private JSONArray targetLow; private JSONArray targetLow;
private LongSparseArray<Double> targetLow_v = null; // oldest at index 0 private LongSparseArray<Double> targetLow_v; // oldest at index 0
private JSONArray targetHigh; private JSONArray targetHigh;
private LongSparseArray<Double> targetHigh_v = null; // oldest at index 0 private LongSparseArray<Double> targetHigh_v; // oldest at index 0
private int percentage = 100; private int percentage;
private int timeshift = 0; private int timeshift;
private boolean isValid = true; protected boolean isValid;
private boolean isValidated = false; protected boolean isValidated;
// Default constructor for tests
protected Profile() {
}
// Constructor from profileStore JSON
public Profile(JSONObject json, String units) { public Profile(JSONObject json, String units) {
this(json, 100, 0); init(json, 100, 0);
if (this.units == null) { if (this.units == null) {
if (units != null) if (units != null)
this.units = units; this.units = units;
@ -65,6 +65,22 @@ public class Profile {
} }
public Profile(JSONObject json, int percentage, int timeshift) { 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.percentage = percentage;
this.timeshift = timeshift; this.timeshift = timeshift;
this.json = json; this.json = json;
@ -78,53 +94,12 @@ public class Profile {
if (json.has("timezone")) if (json.has("timezone"))
timeZone = TimeZone.getTimeZone(json.getString("timezone")); timeZone = TimeZone.getTimeZone(json.getString("timezone"));
isf = json.getJSONArray("sens"); 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"); 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"); 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"); 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"); 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) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.invalidprofile));
isValid = false; isValid = false;
isValidated = true; isValidated = true;
} }
@ -133,7 +108,7 @@ public class Profile {
public String log() { public String log() {
String ret = "\n"; String ret = "\n";
for (Integer hour = 0; hour < 24; hour++) { 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 basal value for " + hour + ":00 is " + value + "\n";
} }
ret += "NS units: " + getUnits(); ret += "NS units: " + getUnits();
@ -155,6 +130,10 @@ public class Profile {
} }
// mmol or mg/dl // mmol or mg/dl
public void setUnits(String units) {
this.units = units;
}
public String getUnits() { public String getUnits() {
return units; return units;
} }
@ -164,6 +143,11 @@ public class Profile {
} }
private LongSparseArray<Double> convertToSparseArray(JSONArray array) { private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
if (array == null) {
isValid = false;
return new LongSparseArray<>();
}
double multiplier = getMultiplier(array); double multiplier = getMultiplier(array);
LongSparseArray<Double> sparse = new LongSparseArray<>(); LongSparseArray<Double> sparse = new LongSparseArray<>();
@ -235,7 +219,7 @@ public class Profile {
for (int i = 0; i < basal_v.size(); i++) { for (int i = 0; i < basal_v.size(); i++) {
if (basal_v.valueAt(i) < description.basalMinimumRate) { if (basal_v.valueAt(i) < description.basalMinimumRate) {
basal_v.setValueAt(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 { } else {
@ -249,6 +233,10 @@ public class Profile {
return isValid; 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) { private void validate(LongSparseArray array) {
if (array.size() == 0) { if (array.size() == 0) {
isValid = false; isValid = false;
@ -262,6 +250,7 @@ public class Profile {
} }
} }
/*
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) { private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
Double lastValue = null; Double lastValue = null;
@ -281,6 +270,7 @@ public class Profile {
} }
return lastValue; return lastValue;
} }
*/
Integer getShitfTimeSecs(Integer originalTime) { Integer getShitfTimeSecs(Integer originalTime) {
Integer shiftedTime = originalTime + timeshift * 60 * 60; Integer shiftedTime = originalTime + timeshift * 60 * 60;
@ -322,7 +312,7 @@ public class Profile {
return multiplier; return multiplier;
} }
private Double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) { private double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
Double lastValue = null; Double lastValue = null;
for (Integer index = 0; index < array.size(); index++) { for (Integer index = 0; index < array.size(); index++) {
@ -337,7 +327,7 @@ public class Profile {
return lastValue; return lastValue;
} }
private String format_HH_MM(Integer timeAsSeconds) { protected String format_HH_MM(Integer timeAsSeconds) {
String time; String time;
int hour = timeAsSeconds / 60 / 60; int hour = timeAsSeconds / 60 / 60;
int minutes = (timeAsSeconds - hour * 60 * 60) / 60; int minutes = (timeAsSeconds - hour * 60 * 60) / 60;
@ -364,51 +354,55 @@ public class Profile {
return retValue; return retValue;
} }
public Double getIsf() { public double getIsf() {
return getIsf(secondsFromMidnight(System.currentTimeMillis())); return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
} }
public Double getIsf(long time) { public double getIsf(long time) {
return getIsf(secondsFromMidnight(time)); return getIsfTimeFromMidnight(secondsFromMidnight(time));
} }
public Double getIsf(Integer timeAsSeconds) { double getIsfTimeFromMidnight(int timeAsSeconds) {
if (isf_v == null) if (isf_v == null)
isf_v = convertToSparseArray(isf); isf_v = convertToSparseArray(isf);
return getValueToTime(isf_v, timeAsSeconds); return getValueToTime(isf_v, timeAsSeconds);
} }
public String getIsfList() { public String getIsfList() {
if (isf_v == null)
isf_v = convertToSparseArray(isf);
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U"); return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
} }
public Double getIc() { public double getIc() {
return getIc(secondsFromMidnight(System.currentTimeMillis())); return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
} }
public Double getIc(long time) { public double getIc(long time) {
return getIc(secondsFromMidnight(time)); return getIcTimeFromMidnight(secondsFromMidnight(time));
} }
public Double getIc(Integer timeAsSeconds) { public double getIcTimeFromMidnight(int timeAsSeconds) {
if (ic_v == null) if (ic_v == null)
ic_v = convertToSparseArray(ic); ic_v = convertToSparseArray(ic);
return getValueToTime(ic_v, timeAsSeconds); return getValueToTime(ic_v, timeAsSeconds);
} }
public String getIcList() { public String getIcList() {
if (ic_v == null)
ic_v = convertToSparseArray(ic);
return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U"); return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U");
} }
public Double getBasal() { public double getBasal() {
return getBasal(secondsFromMidnight(System.currentTimeMillis())); return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
} }
public Double getBasal(long time) { public double getBasal(long time) {
return getBasal(secondsFromMidnight(time)); return getBasalTimeFromMidnight(secondsFromMidnight(time));
} }
public synchronized Double getBasal(Integer timeAsSeconds) { public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) {
if (basal_v == null) { if (basal_v == null) {
basal_v = convertToSparseArray(basal); basal_v = convertToSparseArray(basal);
} }
@ -418,17 +412,17 @@ public class Profile {
public String getBasalList() { public String getBasalList() {
if (basal_v == null) if (basal_v == null)
basal_v = convertToSparseArray(basal); 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 class BasalValue {
public BasalValue(Integer timeAsSeconds, Double value) { public BasalValue(int timeAsSeconds, double value) {
this.timeAsSeconds = timeAsSeconds; this.timeAsSeconds = timeAsSeconds;
this.value = value; this.value = value;
} }
public Integer timeAsSeconds; public int timeAsSeconds;
public Double value; public double value;
} }
public synchronized BasalValue[] getBasalValues() { public synchronized BasalValue[] getBasalValues() {
@ -438,7 +432,7 @@ public class Profile {
for (Integer index = 0; index < basal_v.size(); index++) { for (Integer index = 0; index < basal_v.size(); index++) {
Integer tas = (int) basal_v.keyAt(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); ret[index] = new BasalValue(tas, value);
} }
return ret; return ret;
@ -448,52 +442,56 @@ public class Profile {
return getTarget(secondsFromMidnight(System.currentTimeMillis())); return getTarget(secondsFromMidnight(System.currentTimeMillis()));
} }
private double getTarget(Integer time) { protected double getTarget(int timeAsSeconds) {
return (getTargetLow(time) + getTargetHigh(time))/2; return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2;
} }
public Double getTargetLow() { public double getTargetLow() {
return getTargetLow(secondsFromMidnight(System.currentTimeMillis())); return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
} }
public Double getTargetLow(long time) { public double getTargetLow(long time) {
return getTargetLow(secondsFromMidnight(time)); return getTargetLowTimeFromMidnight(secondsFromMidnight(time));
} }
public Double getTargetLow(Integer timeAsSeconds) { public double getTargetLowTimeFromMidnight(int timeAsSeconds) {
if (targetLow_v == null) if (targetLow_v == null)
targetLow_v = convertToSparseArray(targetLow); targetLow_v = convertToSparseArray(targetLow);
return getValueToTime(targetLow_v, timeAsSeconds); return getValueToTime(targetLow_v, timeAsSeconds);
} }
public Double getTargetHigh() { public double getTargetHigh() {
return getTargetHigh(secondsFromMidnight(System.currentTimeMillis())); return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
} }
public Double getTargetHigh(long time) { public double getTargetHigh(long time) {
return getTargetHigh(secondsFromMidnight(time)); return getTargetHighTimeFromMidnight(secondsFromMidnight(time));
} }
public Double getTargetHigh(Integer timeAsSeconds) { public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
if (targetHigh_v == null) if (targetHigh_v == null)
targetHigh_v = convertToSparseArray(targetHigh); targetHigh_v = convertToSparseArray(targetHigh);
return getValueToTime(targetHigh_v, timeAsSeconds); return getValueToTime(targetHigh_v, timeAsSeconds);
} }
public String getTargetList() { 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()); return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits());
} }
public double getMaxDailyBasal() { public double getMaxDailyBasal() {
Double max = 0d; double max = 0d;
for (Integer hour = 0; hour < 24; hour++) { for (int hour = 0; hour < 24; hour++) {
double value = getBasal((Integer) (hour * 60 * 60)); double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
if (value > max) max = value; if (value > max) max = value;
} }
return max; return max;
} }
public static Integer secondsFromMidnight() { public static int secondsFromMidnight() {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
long now = c.getTimeInMillis(); long now = c.getTimeInMillis();
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
@ -504,7 +502,7 @@ public class Profile {
return (int) (passed / 1000); return (int) (passed / 1000);
} }
public static Integer secondsFromMidnight(long date) { public static int secondsFromMidnight(long date) {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
c.setTimeInMillis(date); c.setTimeInMillis(date);
c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.HOUR_OF_DAY, 0);
@ -515,22 +513,22 @@ public class Profile {
return (int) (passed / 1000); 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; if (units.equals(Constants.MGDL)) return value;
else return value * Constants.MMOLL_TO_MGDL; 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; if (units.equals(Constants.MGDL)) return value * Constants.MGDL_TO_MMOLL;
else return value; 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; if (units.equals(Constants.MGDL)) return value;
else return value * Constants.MGDL_TO_MMOLL; 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; if (units.equals(Constants.MGDL)) return valueInMgdl;
else return valueInMmol; else return valueInMmol;
} }
@ -556,7 +554,7 @@ public class Profile {
public double percentageBasalSum() { public double percentageBasalSum() {
double result = 0d; double result = 0d;
for (int i = 0; i < 24; i++) { for (int i = 0; i < 24; i++) {
result += getBasal((Integer) (i * 60 * 60)); result += getBasalTimeFromMidnight(i * 60 * 60);
} }
return result; return result;
} }
@ -565,7 +563,7 @@ public class Profile {
public double baseBasalSum() { public double baseBasalSum() {
double result = 0d; double result = 0d;
for (int i = 0; i < 24; i++) { 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; return result;
} }

View file

@ -3,10 +3,14 @@ package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray; import android.support.v4.util.LongSparseArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.utils.DateUtil;
/** /**
* Created by mike on 09.05.2017. * 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 // When no interval match the lastest record without duration is used
public class ProfileIntervals<T extends Interval> { public class ProfileIntervals<T extends Interval> {
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0 private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0
@ -51,6 +56,11 @@ public class ProfileIntervals<T extends Interval> {
public synchronized Interval getValueToTime(long time) { public synchronized Interval getValueToTime(long time) {
int index = binarySearch(time); int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index); 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; return null;
} }

View file

@ -1709,7 +1709,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (trJson.has("profileJson")) if (trJson.has("profileJson"))
profileSwitch.profileJson = trJson.getString("profileJson"); profileSwitch.profileJson = trJson.getString("profileJson");
else { else {
ProfileStore store = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
Profile profile = store.getSpecificProfile(profileSwitch.profileName); Profile profile = store.getSpecificProfile(profileSwitch.profileName);
if (profile != null) { if (profile != null) {
profileSwitch.profileJson = profile.getData().toString(); profileSwitch.profileJson = profile.getData().toString();

View file

@ -96,7 +96,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
noProfileView = view.findViewById(R.id.profileview_noprofile); noProfileView = view.findViewById(R.id.profileview_noprofile);
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons); butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
if (profileStore == null) { if (profileStore == null) {
noProfileView.setVisibility(View.VISIBLE); noProfileView.setVisibility(View.VISIBLE);
butonsLayout.setVisibility(View.GONE); butonsLayout.setVisibility(View.GONE);

View file

@ -59,6 +59,7 @@ import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload; import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker; import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.OKDialog;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
import info.nightscout.utils.Translator; import info.nightscout.utils.Translator;
@ -73,7 +74,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
Profile profile; Profile profile;
ProfileStore profileStore; ProfileStore profileStore;
String units; String units = Constants.MGDL;
TextView eventTypeText; TextView eventTypeText;
LinearLayout layoutPercent; LinearLayout layoutPercent;
@ -168,11 +169,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
// profile // profile
profile = MainApp.getConfigBuilder().getProfile(); profile = MainApp.getConfigBuilder().getProfile();
profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); 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<CharSequence> profileList; ArrayList<CharSequence> profileList;
units = profile != null ? profile.getUnits() : Constants.MGDL; units = profile != null ? profile.getUnits() : Constants.MGDL;
profileList = profileStore.getProfileList(); profileList = profileStore.getProfileList();
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(), ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(getContext(),
R.layout.spinner_centered, profileList); R.layout.spinner_centered, profileList);
profileSpinner.setAdapter(adapter); profileSpinner.setAdapter(adapter);
// set selected to actual profile // set selected to actual profile
@ -180,7 +186,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false))) if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false)))
profileSpinner.setSelection(p); 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, units);
// temp target // temp target
@ -720,7 +726,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
profileSwitch.profileName = profileName; profileSwitch.profileName = profileName;
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName(); profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration; profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift; profileSwitch.timeshift = timeshift;
@ -752,7 +758,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false); profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString(); profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName(); profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration; profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift; profileSwitch.timeshift = timeshift;

View file

@ -201,7 +201,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
return activeBgSource; return activeBgSource;
} }
public static ProfileInterface getActiveProfileInterface() { public ProfileInterface getActiveProfileInterface() {
return activeProfile; return activeProfile;
} }
@ -762,8 +762,6 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
} }
public String getProfileName(long time, boolean customized) { 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); ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
if (profileSwitch != null) { if (profileSwitch != null) {
if (profileSwitch.profileJson != null) { if (profileSwitch.profileJson != null) {
@ -774,21 +772,11 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
return profileSwitch.profileName; return profileSwitch.profileName;
} }
} }
} return MainApp.gs(R.string.noprofileselected);
// 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";
} }
public boolean isProfileValid(String from) { public boolean isProfileValid(String from) {
return getProfile() != null && getProfile().isValid(from) && return getProfile() != null && getProfile().isValid(from);
activeProfile != null &&
activeProfile.getProfile() != null &&
activeProfile.getProfile().getDefaultProfile() != null &&
activeProfile.getProfile().getDefaultProfile().isValid(from);
} }
@Nullable @Nullable
@ -808,8 +796,6 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
return null; //app not initialized return null; //app not initialized
} }
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); //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); ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
if (profileSwitch != null) { if (profileSwitch != null) {
if (profileSwitch.profileJson != null) { if (profileSwitch.profileJson != null) {
@ -820,29 +806,6 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
return profile; 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"); log.debug("getProfile at the end: returning null");
return null; return null;
} }

View file

@ -110,11 +110,6 @@ public class IobCobThread extends Thread {
return; // profile not set yet 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) if (Config.logAutosensData)
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");

View file

@ -204,7 +204,7 @@ public class DetermineBasalAdapterAMAJS {
mProfile.put("max_bg", maxBg); mProfile.put("max_bg", maxBg);
mProfile.put("target_bg", targetBg); mProfile.put("target_bg", targetBg);
mProfile.put("carb_ratio", profile.getIc()); 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("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("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
mProfile.put("skip_neutral_temps", true); mProfile.put("skip_neutral_temps", true);

View file

@ -212,9 +212,9 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
return; 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; 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; return;
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
return; return;

View file

@ -172,7 +172,7 @@ public class DetermineBasalAdapterMAJS {
mProfile.put("max_bg", maxBg); mProfile.put("max_bg", maxBg);
mProfile.put("target_bg", targetBg); mProfile.put("target_bg", targetBg);
mProfile.put("carb_ratio", profile.getIc()); 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); mProfile.put("current_basal", basalRate);

View file

@ -212,9 +212,9 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
return; return;
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
return; 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; return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
return; return;

View file

@ -228,7 +228,7 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("max_bg", maxBg); mProfile.put("max_bg", maxBg);
mProfile.put("target_bg", targetBg); mProfile.put("target_bg", targetBg);
mProfile.put("carb_ratio", profile.getIc()); 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("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("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));

View file

@ -216,9 +216,9 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; 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; 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; return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return; if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return;
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return;

View file

@ -400,7 +400,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
private void initDialog() { private void initDialog() {
Profile profile = MainApp.getConfigBuilder().getProfile(); Profile profile = MainApp.getConfigBuilder().getProfile();
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
if (profile == null) { if (profile == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile)); 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() { private void calculateInsulin() {
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
return; // not initialized yet return; // not initialized yet
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString(); String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();

View file

@ -188,6 +188,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final Object updateSync = new Object(); 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 final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledUpdate = null; private static ScheduledFuture<?> scheduledUpdate = null;
@ -464,9 +465,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
} else if (v == activeProfileView) { } else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile)); menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile)); menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch)); menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
} }
} }
}
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
@ -966,7 +969,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (timeView != null) { //must not exists if (timeView != null) { //must not exists
timeView.setText(DateUtil.timeString(new Date())); 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); pumpStatusView.setText(R.string.noprofileset);
pumpStatusLayout.setVisibility(View.VISIBLE); pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE); loopStatusLayout.setVisibility(View.GONE);
@ -983,12 +986,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final Profile profile = MainApp.getConfigBuilder().getProfile(); 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 String units = profile.getUnits();
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);

View file

@ -42,10 +42,7 @@ public class Notification {
public static final int APPROACHING_DAILY_LIMIT = 11; public static final int APPROACHING_DAILY_LIMIT = 11;
public static final int NSCLIENT_NO_WRITE_PERMISSION = 12; public static final int NSCLIENT_NO_WRITE_PERMISSION = 12;
public static final int MISSING_SMS_PERMISSION = 13; 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 NSANNOUNCEMENT = 18;
public static final int NSALARM = 19; public static final int NSALARM = 19;
public static final int NSURGENTALARM = 20; public static final int NSURGENTALARM = 20;

View file

@ -14,47 +14,55 @@ import com.squareup.otto.Subscribe;
import java.util.ArrayList; import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemSelected;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; 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.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;
public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener {
private Spinner profileSpinner; public class NSProfileFragment extends SubscriberFragment {
private TextView noProfile; @BindView(R.id.nsprofile_spinner)
private TextView units; Spinner profileSpinner;
private TextView dia; @BindView(R.id.profileview_noprofile)
private TextView activeProfile; TextView noProfile;
private TextView ic; @BindView(R.id.profileview_invalidprofile)
private TextView isf; TextView invalidProfile;
private TextView basal; @BindView(R.id.profileview_units)
private TextView target; 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 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
try { try {
View layout = inflater.inflate(R.layout.nsprofile_fragment, container, false); View view = 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);
unbinder = ButterKnife.bind(this, view);
updateGUI(); updateGUI();
return layout; return view;
} catch (Exception e) { } catch (Exception e) {
FabricPrivacy.logException(e); FabricPrivacy.logException(e);
} }
@ -66,12 +74,7 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
public void onStatusEvent(final EventNSProfileUpdateGUI ev) { public void onStatusEvent(final EventNSProfileUpdateGUI ev) {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity != null) if (activity != null)
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(() -> updateGUI());
@Override
public void run() {
updateGUI();
}
});
} }
@Override @Override
@ -97,9 +100,9 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
} }
} }
@Override @OnItemSelected(R.id.nsprofile_spinner)
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(Spinner spinner, int position) {
String name = parent.getItemAtPosition(position).toString(); String name = spinner.getItemAtPosition(position).toString();
ProfileStore store = NSProfilePlugin.getPlugin().getProfile(); ProfileStore store = NSProfilePlugin.getPlugin().getProfile();
if (store != null) { if (store != null) {
@ -112,12 +115,18 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
isf.setText(profile.getIsfList()); isf.setText(profile.getIsfList());
basal.setText(profile.getBasalList()); basal.setText(profile.getBasalList());
target.setText(profile.getTargetList()); target.setText(profile.getTargetList());
basalGraph.show(profile);
} }
if (profile.isValid("NSProfileFragment"))
invalidProfile.setVisibility(View.GONE);
else
invalidProfile.setVisibility(View.VISIBLE);
} }
} }
@Override @OnItemSelected(value = R.id.nsprofile_spinner, callback = NOTHING_SELECTED)
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected() {
invalidProfile.setVisibility(View.VISIBLE);
noProfile.setVisibility(View.VISIBLE); noProfile.setVisibility(View.VISIBLE);
units.setText(""); units.setText("");
dia.setText(""); dia.setText("");

View file

@ -120,19 +120,6 @@ public class NSProfilePlugin implements PluginBase, ProfileInterface {
profile = new ProfileStore(newProfile.getData()); profile = new ProfileStore(newProfile.getData());
storeNSProfile(); storeNSProfile();
MainApp.bus().post(new EventNSProfileUpdateGUI()); 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() { private void storeNSProfile() {

View file

@ -184,7 +184,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
for (int h = 0; h < basalValues; h++) { for (int h = 0; h < basalValues; h++) {
Double pumpValue = pump.pumpProfiles[pump.activeProfile][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 (profileValue == null) return true;
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);

View file

@ -241,7 +241,7 @@ public class DanaRPump {
for (Integer hour = 0; hour < 24; hour++) { for (Integer hour = 0; hour < 24; hour++) {
//Some values get truncated to the next lower one. //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) // -> 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) if (Config.logDanaMessageDetail)
log.debug("NS basal value for " + hour + ":00 is " + value); log.debug("NS basal value for " + hour + ":00 is " + value);
record[hour] = value; record[hour] = value;

View file

@ -428,7 +428,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
for (int h = 0; h < basalValues; h++) { for (int h = 0; h < basalValues; h++) {
Double pumpValue = pump.pumpProfiles[pump.activeProfile][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 (profileValue == null) return true;
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);

View file

@ -52,12 +52,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
private PumpDescription pumpDescription = new PumpDescription(); private PumpDescription pumpDescription = new PumpDescription();
private static void loadFakingStatus() { private static void loadFakingStatus() {
fromNSAreCommingFakedExtendedBoluses = SP.getBoolean("fromNSAreCommingFakedExtendedBoluses", false); fromNSAreCommingFakedExtendedBoluses = SP.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false);
} }
public static void setFakingStatus(boolean newStatus) { public static void setFakingStatus(boolean newStatus) {
fromNSAreCommingFakedExtendedBoluses = newStatus; fromNSAreCommingFakedExtendedBoluses = newStatus;
SP.putBoolean("fromNSAreCommingFakedExtendedBoluses", fromNSAreCommingFakedExtendedBoluses); SP.putBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, fromNSAreCommingFakedExtendedBoluses);
} }
public static boolean getFakingStatus() { public static boolean getFakingStatus() {
@ -73,7 +73,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
return plugin; return plugin;
} }
private VirtualPumpPlugin() { public VirtualPumpPlugin() {
pumpDescription.isBolusCapable = true; pumpDescription.isBolusCapable = true;
pumpDescription.bolusStep = 0.1d; pumpDescription.bolusStep = 0.1d;
@ -245,7 +245,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
public double getBaseBasalRate() { public double getBaseBasalRate() {
Profile profile = MainApp.getConfigBuilder().getProfile(); Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile != null) if (profile != null)
return profile.getBasal() != null ? profile.getBasal() : 0d; return profile.getBasal();
else else
return 0d; return 0d;
} }

View file

@ -59,7 +59,7 @@ public class BGSourceFragment extends SubscriberFragment {
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)); RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false));
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
profile = ConfigBuilderPlugin.getActiveProfileInterface().getProfile().getDefaultProfile(); profile = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile().getDefaultProfile();
return view; return view;
} catch (Exception e) { } catch (Exception e) {

View file

@ -33,8 +33,8 @@ public class ProfileGraph extends GraphView {
List<DataPoint> basalArray = new ArrayList<>(); List<DataPoint> basalArray = new ArrayList<>();
for (int hour = 0; hour < 24; hour++) { for (int hour = 0; hour < 24; hour++) {
basalArray.add(new DataPoint(hour, 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.getBasal(new Integer(hour*60*60)))); basalArray.add(new DataPoint(hour+1, profile.getBasalTimeFromMidnight(new Integer(hour*60*60))));
} }
DataPoint[] basalDataPoints = new DataPoint[basalArray.size()]; DataPoint[] basalDataPoints = new DataPoint[basalArray.size()];
basalDataPoints = basalArray.toArray(basalDataPoints); basalDataPoints = basalArray.toArray(basalDataPoints);

View file

@ -12,6 +12,9 @@ import android.widget.TextView;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
@ -30,19 +33,36 @@ public class ProfileViewerDialog extends DialogFragment {
private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class); private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class);
private TextView noProfile; @BindView(R.id.profileview_noprofile)
private TextView units; TextView noProfile;
private TextView dia; @BindView(R.id.profileview_invalidprofile)
private TextView activeProfile; TextView invalidProfile;
private TextView ic; @BindView(R.id.profileview_units)
private TextView isf; TextView units;
private TextView basal; @BindView(R.id.profileview_dia)
private TextView target; TextView dia;
private View dateDelimiter; @BindView(R.id.profileview_activeprofile)
private LinearLayout dateLayout; TextView activeProfile;
private TextView dateTextView; @BindView(R.id.profileview_ic)
private Button refreshButton; TextView ic;
private ProfileGraph basalGraph; @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) { public static ProfileViewerDialog newInstance(long time) {
ProfileViewerDialog dialog = new ProfileViewerDialog(); ProfileViewerDialog dialog = new ProfileViewerDialog();
@ -61,31 +81,26 @@ public class ProfileViewerDialog extends DialogFragment {
time = getArguments().getLong("time"); time = getArguments().getLong("time");
} }
@Override
public void onDestroyView() {
super.onDestroyView();
if (unbinder != null)
unbinder.unbind();
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { 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); refreshButton.setVisibility(View.GONE);
dateDelimiter = layout.findViewById(R.id.profileview_datedelimiter);
dateDelimiter.setVisibility(View.VISIBLE); dateDelimiter.setVisibility(View.VISIBLE);
dateLayout = (LinearLayout) layout.findViewById(R.id.profileview_datelayout);
dateLayout.setVisibility(View.VISIBLE); dateLayout.setVisibility(View.VISIBLE);
dateTextView = (TextView) layout.findViewById(R.id.profileview_date);
basalGraph = (ProfileGraph) layout.findViewById(R.id.basal_graph);
setContent(); setContent();
return layout; return view;
} }
@Override @Override
@ -114,6 +129,11 @@ public class ProfileViewerDialog extends DialogFragment {
basal.setText(profile.getBasalList()); basal.setText(profile.getBasalList());
target.setText(profile.getTargetList()); target.setText(profile.getTargetList());
basalGraph.show(profile); basalGraph.show(profile);
if (profile.isValid("ProfileViewDialog"))
invalidProfile.setVisibility(View.GONE);
else
invalidProfile.setVisibility(View.VISIBLE);
} else { } else {
noProfile.setVisibility(View.VISIBLE); noProfile.setVisibility(View.VISIBLE);
} }

View file

@ -586,7 +586,7 @@ public class ActionStringHandler {
} }
final Profile profile = MainApp.getConfigBuilder().getProfile(); final Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile == null || profile.getBasal() == null) { if (profile == null) {
msg += MainApp.sResources.getString(R.string.notloadedplugins) + "\n"; msg += MainApp.sResources.getString(R.string.notloadedplugins) + "\n";
} }
if (!"".equals(msg)) { if (!"".equals(msg)) {

View file

@ -1,9 +1,14 @@
package info.nightscout.androidaps.queue.commands; package info.nightscout.androidaps.queue.commands;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; 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.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
/** /**
@ -11,7 +16,7 @@ import info.nightscout.androidaps.queue.Callback;
*/ */
public class CommandSetProfile extends Command { public class CommandSetProfile extends Command {
Profile profile; private Profile profile;
public CommandSetProfile(Profile profile, Callback callback) { public CommandSetProfile(Profile profile, Callback callback) {
commandType = CommandType.BASALPROFILE; commandType = CommandType.BASALPROFILE;
@ -24,6 +29,15 @@ public class CommandSetProfile extends Command {
PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile); PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile);
if (callback != null) if (callback != null)
callback.result(r).run(); 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 @Override

View file

@ -52,7 +52,7 @@ public class KeepAliveReceiver extends BroadcastReceiver {
private void checkPump() { private void checkPump() {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final Profile profile = MainApp.getConfigBuilder().getProfile(); final Profile profile = MainApp.getConfigBuilder().getProfile();
if (pump != null && profile != null && profile.getBasal() != null) { if (pump != null && profile != null) {
Date lastConnection = pump.lastDataTime(); Date lastConnection = pump.lastDataTime();
boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis();
boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep; boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep;

View file

@ -78,7 +78,7 @@ public class LocalAlertUtils {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final Profile profile = MainApp.getConfigBuilder().getProfile(); final Profile profile = MainApp.getConfigBuilder().getProfile();
if (pump != null && profile != null && profile.getBasal() != null) { if (pump != null && profile != null) {
Date lastConnection = pump.lastDataTime(); Date lastConnection = pump.lastDataTime();
long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold(); long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold();
if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) { if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) {

View file

@ -12,7 +12,6 @@
<include <include
layout="@layout/profileviewer_fragment" layout="@layout/profileviewer_fragment"
layout_width="match_parent" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>

View file

@ -13,6 +13,17 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<TextView
android:id="@+id/profileview_invalidprofile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/invalidprofile"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@android:color/holo_red_light"
android:textStyle="bold"
android:visibility="gone" />
<TextView <TextView
android:id="@+id/profileview_noprofile" android:id="@+id/profileview_noprofile"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,6 +72,7 @@
</LinearLayout> </LinearLayout>
<View <View
android:id="@+id/profileview_datedelimiter"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp" android:layout_marginBottom="5dp"
@ -68,14 +80,13 @@
android:layout_marginRight="20dp" android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:background="@color/listdelimiter" android:background="@color/listdelimiter"
android:id="@+id/profileview_datedelimiter"
android:visibility="gone" /> android:visibility="gone" />
<LinearLayout <LinearLayout
android:id="@+id/profileview_datelayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:id="@+id/profileview_datelayout"
android:visibility="gone"> android:visibility="gone">
<TextView <TextView
@ -333,11 +344,13 @@
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph <info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph
android:id="@+id/basal_graph" android:id="@+id/basal_graph"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_margin="20dp" android:layout_height="100dip"
android:layout_height="100dip" /> android:layout_margin="20dp" />
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
@ -393,11 +406,11 @@
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<Button <Button
android:id="@+id/profileview_reload"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/reloadprofile"
android:id="@+id/profileview_reload"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:text="@string/reloadprofile"
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -561,10 +561,6 @@
<string name="careportal_insulinage_label">Възраст на инсулина</string> <string name="careportal_insulinage_label">Възраст на инсулина</string>
<string name="hours">часа</string> <string name="hours">часа</string>
<string name="overview_newtempbasal_basaltype_label">Тип базал</string> <string name="overview_newtempbasal_basaltype_label">Тип базал</string>
<string name="isfmissing">ISF липсва в профила. По подразбиране.</string>
<string name="icmissing">IC липсва в профила. По подразбиране.</string>
<string name="basalmissing">Базал липсва в профила. По подразбиране.</string>
<string name="targetmissing">Целева КЗ липсва в профила. По подразбиране.</string>
<string name="invalidprofile">Грешен профил !!!</string> <string name="invalidprofile">Грешен профил !!!</string>
<string name="profileswitch">Смяна на профил</string> <string name="profileswitch">Смяна на профил</string>
<string name="careportal_pbage_label">Възраст на батерията на помпата</string> <string name="careportal_pbage_label">Възраст на батерията на помпата</string>
@ -581,8 +577,6 @@
<string name="nsalarm_urgent_staledatavalue_label">Много стари данни при повече от [мин]</string> <string name="nsalarm_urgent_staledatavalue_label">Много стари данни при повече от [мин]</string>
<string name="openapsama_autosens_period">Интервал за autosens [ч]</string> <string name="openapsama_autosens_period">Интервал за autosens [ч]</string>
<string name="openapsama_autosens_period_summary">Брой часове назад за определяне на чувствителността (приемът на въглехидрати е изключен)</string> <string name="openapsama_autosens_period_summary">Брой часове назад за определяне на чувствителността (приемът на въглехидрати е изключен)</string>
<string name="do_not_track_profile_switch">Игнорирай събитията от тип Смяна на профил</string>
<string name="do_not_track_profile_switch_summary">Всички смени на профила се игнорират и винаги се използва текущия профил</string>
<string name="pump">Помпа</string> <string name="pump">Помпа</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Устройство</string> <string name="device">Устройство</string>

View file

@ -555,14 +555,10 @@
<string name="danarv2pump">DanaRv2</string> <string name="danarv2pump">DanaRv2</string>
<string name="dev">ODCH</string> <string name="dev">ODCH</string>
<string name="device">Zařízení</string> <string name="device">Zařízení</string>
<string name="do_not_track_profile_switch">Ignorovat přepnutí profilu</string>
<string name="do_not_track_profile_switch_summary">Všechny záznamy přepnutí profilu jsou ignorovány a vždy je použit aktivní profil</string>
<string name="extendedbolus">ProdlouženýBolus</string> <string name="extendedbolus">ProdlouženýBolus</string>
<string name="hours">hodin</string> <string name="hours">hodin</string>
<string name="icmissing">I:S chybí. Je použita výchozí hodnota.</string>
<string name="invalidprofile">Chybný profil !!!</string> <string name="invalidprofile">Chybný profil !!!</string>
<string name="iob">IOB</string> <string name="iob">IOB</string>
<string name="isfmissing">Senzitivita chybí. Je použita výchozí hodnota.</string>
<string name="lock_screen">Zámek obrazovky</string> <string name="lock_screen">Zámek obrazovky</string>
<string name="lock_screen_short">Zámek</string> <string name="lock_screen_short">Zámek</string>
<string name="mdtp_cancel">Zrušit</string> <string name="mdtp_cancel">Zrušit</string>
@ -592,7 +588,6 @@
<string name="xdripstatus_settings">Status z xDripu (hodinky)</string> <string name="xdripstatus_settings">Status z xDripu (hodinky)</string>
<string name="xdripstatus_shortname">xds</string> <string name="xdripstatus_shortname">xds</string>
<string name="virtualpump_extendedbolus_label_short">EXT</string> <string name="virtualpump_extendedbolus_label_short">EXT</string>
<string name="targetmissing">Chybí cílový rozsah. Použity výchozí hodnoty.</string>
<string name="tempbasal">DočasnýBazál</string> <string name="tempbasal">DočasnýBazál</string>
<string name="temptarget">DočasnýCíl</string> <string name="temptarget">DočasnýCíl</string>
<string name="wear_overviewnotifications">Oznámení na hodinkách</string> <string name="wear_overviewnotifications">Oznámení na hodinkách</string>
@ -609,7 +604,6 @@
<string name="openaps_short">OAPS</string> <string name="openaps_short">OAPS</string>
<string name="danar_bluetooth_status">Bluetooth status</string> <string name="danar_bluetooth_status">Bluetooth status</string>
<string name="careportal_activity_label">AKTIVITA &amp; ZPĚTNÁ VAZBA</string> <string name="careportal_activity_label">AKTIVITA &amp; ZPĚTNÁ VAZBA</string>
<string name="basalmissing">Chybějící bazál v profilu. Použita výchozí hodnota</string>
<string name="basal_step">Krok bazálu</string> <string name="basal_step">Krok bazálu</string>
<string name="basal_short">BAZ</string> <string name="basal_short">BAZ</string>
<string name="unsupportednsversion">Nepodporovaná verze Nightscoutu</string> <string name="unsupportednsversion">Nepodporovaná verze Nightscoutu</string>

View file

@ -353,7 +353,6 @@
<string name="app_name">AndroidAPS</string> <string name="app_name">AndroidAPS</string>
<string name="basal_short">BAS</string> <string name="basal_short">BAS</string>
<string name="basal_step">Basal-Schritt</string> <string name="basal_step">Basal-Schritt</string>
<string name="basalmissing">Basalraten fehlen im Profil. Verwende Standard-Werte.</string>
<string name="basalvaluebelowminimum">Wert der Basalrate unter Minimum. Profil nicht gesetzt!</string> <string name="basalvaluebelowminimum">Wert der Basalrate unter Minimum. Profil nicht gesetzt!</string>
<string name="batteryoptimalizationerror">Smartphone untertützt anscheinend das Deaktivieren der Akku-Leistungsoptimierung nicht!</string> <string name="batteryoptimalizationerror">Smartphone untertützt anscheinend das Deaktivieren der Akku-Leistungsoptimierung nicht!</string>
<string name="bolus_step">Bolus-Schritt</string> <string name="bolus_step">Bolus-Schritt</string>
@ -368,7 +367,6 @@
<string name="paused">Pausiert</string> <string name="paused">Pausiert</string>
<string name="patientage">Patientenalter</string> <string name="patientage">Patientenalter</string>
<string name="patientage_summary">Bitte wähle das Pateintenalter, um die Sicherheits-Limits festzulegen</string> <string name="patientage_summary">Bitte wähle das Pateintenalter, um die Sicherheits-Limits festzulegen</string>
<string name="targetmissing">BZ-Zielbereich fehlt im Profil. Verwende Standardwerte.</string>
<string name="teenage">Teenager</string> <string name="teenage">Teenager</string>
<string name="tempbasaldeliveryerror">TBR Abgabe-Fehler</string> <string name="tempbasaldeliveryerror">TBR Abgabe-Fehler</string>
<string name="temptarget">Temporäres Ziel</string> <string name="temptarget">Temporäres Ziel</string>
@ -414,8 +412,6 @@
<string name="disconnectpumpfor15m">Trenne Pumpe für 15 Min.</string> <string name="disconnectpumpfor15m">Trenne Pumpe für 15 Min.</string>
<string name="disconnectpumpfor30m">Trenne Pumpe für 30 Min.</string> <string name="disconnectpumpfor30m">Trenne Pumpe für 30 Min.</string>
<string name="disconnectpumpfor3h">Trenne Pumpe für 3 h</string> <string name="disconnectpumpfor3h">Trenne Pumpe für 3 h</string>
<string name="do_not_track_profile_switch">Ignoriere Profilwechsel</string>
<string name="do_not_track_profile_switch_summary">Alle Profilwechsel werden ignoriert und nur das aktive Profil verwendet</string>
<string name="dont_show_again">Nicht erneut anzeigen</string> <string name="dont_show_again">Nicht erneut anzeigen</string>
<string name="eatingsoon">Bald essen</string> <string name="eatingsoon">Bald essen</string>
<string name="edit_base_basal">Bearbeite Basis-Basal:</string> <string name="edit_base_basal">Bearbeite Basis-Basal:</string>
@ -530,9 +526,7 @@
<string name="danarprofile_dia_summary">Dauer der Insulinwirkung</string> <string name="danarprofile_dia_summary">Dauer der Insulinwirkung</string>
<string name="edit_base_ic">Bearbeite Basis-IC:</string> <string name="edit_base_ic">Bearbeite Basis-IC:</string>
<string name="edit_base_isf">Bearbeite Basis-ISF:</string> <string name="edit_base_isf">Bearbeite Basis-ISF:</string>
<string name="icmissing">IC-Angabe fehlt im Profil. Verwende Standard-Wert.</string>
<string name="insulin_shortname">INS</string> <string name="insulin_shortname">INS</string>
<string name="isfmissing">ISF fehlt im Profil. Verwende Standard-Wert.</string>
<string name="lock_screen_short">Sperr</string> <string name="lock_screen_short">Sperr</string>
<string name="needwhitelisting">%s benötigt Batterie-Optimierungs-Whitelisting, um korrekt arbeiten zu können</string> <string name="needwhitelisting">%s benötigt Batterie-Optimierungs-Whitelisting, um korrekt arbeiten zu können</string>
<string name="nsalarm_staledata">Veraltete Daten</string> <string name="nsalarm_staledata">Veraltete Daten</string>

View file

@ -559,10 +559,6 @@
<string name="careportal_insulinage_label">Χρόνος ζωής Ινσουλίνης</string> <string name="careportal_insulinage_label">Χρόνος ζωής Ινσουλίνης</string>
<string name="hours">ώρες</string> <string name="hours">ώρες</string>
<string name="overview_newtempbasal_basaltype_label">Τύπος Βασικού</string> <string name="overview_newtempbasal_basaltype_label">Τύπος Βασικού</string>
<string name="isfmissing">"Λείπει ο ISF στο προφίλ.Χρησιμοποιείται το προκαθορισμένο "</string>
<string name="icmissing">"Λείπει ο IC στο προφίλ.Χρησιμοποιείται το προκαθορισμένο "</string>
<string name="basalmissing">"Λείπει ο Βασικός στο προφίλ.Χρησιμοποιείται το προκαθορισμένο "</string>
<string name="targetmissing">"Λείπει ο στόχος στο προφίλ.Χρησιμοποιείται το προκαθορισμένο "</string>
<string name="invalidprofile">Μη έγκυρο προφίλ!!!</string> <string name="invalidprofile">Μη έγκυρο προφίλ!!!</string>
<string name="profileswitch">ΜΕταβείτε στο προφίλ</string> <string name="profileswitch">ΜΕταβείτε στο προφίλ</string>
<string name="careportal_pbage_label">Χρόνος ζωής μπαταρίας αντλίας</string> <string name="careportal_pbage_label">Χρόνος ζωής μπαταρίας αντλίας</string>
@ -580,8 +576,6 @@
<string name="openapsama_autosens_period">"Εσωτερικά διαστήματα για autosense [h] "</string> <string name="openapsama_autosens_period">"Εσωτερικά διαστήματα για autosense [h] "</string>
<string name="openapsama_autosens_period_summary">Ποσότητα ωρών κατά το παρελθόν για ανίχνευση ευαισθησίας (εξαιρείται ο χρόνος απορρόφησης υδατανθράκων)</string> <string name="openapsama_autosens_period_summary">Ποσότητα ωρών κατά το παρελθόν για ανίχνευση ευαισθησίας (εξαιρείται ο χρόνος απορρόφησης υδατανθράκων)</string>
<string name="ratio_short">SEN</string> <string name="ratio_short">SEN</string>
<string name="do_not_track_profile_switch">Αγνοήστε τα συμβάντα αλλαγής προφίλ</string>
<string name="do_not_track_profile_switch_summary">;Ola τα συμβάντα αλλαγής προφίλ αγνοήθηκαν και χρησιμοποιείτε πάντα το ενεργό προφίλ</string>
<string name="pump">Αντλία</string> <string name="pump">Αντλία</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Συσκευή</string> <string name="device">Συσκευή</string>

View file

@ -564,10 +564,6 @@
<string name="careportal_insulinage_label">Edad insulina</string> <string name="careportal_insulinage_label">Edad insulina</string>
<string name="hours">horas</string> <string name="hours">horas</string>
<string name="overview_newtempbasal_basaltype_label">Tipo base</string> <string name="overview_newtempbasal_basaltype_label">Tipo base</string>
<string name="isfmissing">Falta ISF en perfil. Usando ajuste por defecto.</string>
<string name="icmissing">Falta IC en perfil. Usando ajuste por defecto.</string>
<string name="basalmissing">Falta base en perfil. Usando ajuste por defecto.</string>
<string name="targetmissing">"Falta objectivo en perfil. Usando ajuste por defecto. "</string>
<string name="invalidprofile">Perfil invalido !!!</string> <string name="invalidprofile">Perfil invalido !!!</string>
<string name="profileswitch">CambioPerfil</string> <string name="profileswitch">CambioPerfil</string>
<string name="careportal_pbage_label">Edad bateria bomba</string> <string name="careportal_pbage_label">Edad bateria bomba</string>
@ -585,8 +581,6 @@
<string name="openapsama_autosens_period">Interval para autosens [h]</string> <string name="openapsama_autosens_period">Interval para autosens [h]</string>
<string name="openapsama_autosens_period_summary">Horas en el pasado para detectar sensividad (tiempo de absorcion de carbohidratos no incluidos)</string> <string name="openapsama_autosens_period_summary">Horas en el pasado para detectar sensividad (tiempo de absorcion de carbohidratos no incluidos)</string>
<string name="ratio_short">SEN</string> <string name="ratio_short">SEN</string>
<string name="do_not_track_profile_switch">"Ignora evenos de cambio de perfil "</string>
<string name="do_not_track_profile_switch_summary">"Totos los cambios de perfil son ignorados y se usa siempre el perfil actual "</string>
<string name="pump">Bomba</string> <string name="pump">Bomba</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Aparato</string> <string name="device">Aparato</string>

View file

@ -557,10 +557,6 @@
<string name="careportal_insulinage_label">Durée d\'insuline</string> <string name="careportal_insulinage_label">Durée d\'insuline</string>
<string name="hours">Heures</string> <string name="hours">Heures</string>
<string name="overview_newtempbasal_basaltype_label">Type du Basal</string> <string name="overview_newtempbasal_basaltype_label">Type du Basal</string>
<string name="isfmissing">"Facteur SI manquant dans le profile. Utilisez les valeurs par défaut. "</string>
<string name="icmissing">I:G manquant dans le profile. Utilisez les valeurs par défaut.</string>
<string name="basalmissing">Basal manquant dans le profile. Utilisez les valeurs par défaut</string>
<string name="targetmissing">Cible manquante dans le profile. Utilisez les valeurs par défaut</string>
<string name="invalidprofile">Profile incorrect!!!</string> <string name="invalidprofile">Profile incorrect!!!</string>
<string name="profileswitch">Changement de Profil</string> <string name="profileswitch">Changement de Profil</string>
<string name="careportal_pbage_label">Durée batterie pompe</string> <string name="careportal_pbage_label">Durée batterie pompe</string>
@ -578,8 +574,6 @@
<string name="openapsama_autosens_period">"lintervalle pour autosens [h] "</string> <string name="openapsama_autosens_period">"lintervalle pour autosens [h] "</string>
<string name="openapsama_autosens_period_summary">Le nombre dheures écoulées pour la détection de sensibilité (le temps dabsorption des glucides est exclu)</string> <string name="openapsama_autosens_period_summary">Le nombre dheures écoulées pour la détection de sensibilité (le temps dabsorption des glucides est exclu)</string>
<string name="ratio_short">SEN</string> <string name="ratio_short">SEN</string>
<string name="do_not_track_profile_switch">Ignorer les événements de changement de profil</string>
<string name="do_not_track_profile_switch_summary">Tout les événements de changement de profils sont ignorés et le profil actif reste le seul profil en activité continue</string>
<string name="pump">Pompe</string> <string name="pump">Pompe</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Dispositif</string> <string name="device">Dispositif</string>

View file

@ -570,10 +570,6 @@
<string name="careportal_insulinage_label">인슐린 사용기간</string> <string name="careportal_insulinage_label">인슐린 사용기간</string>
<string name="hours">시간</string> <string name="hours">시간</string>
<string name="overview_newtempbasal_basaltype_label">기초주입 종류</string> <string name="overview_newtempbasal_basaltype_label">기초주입 종류</string>
<string name="isfmissing">프로파일에서 ISF가 누락되었습니다. 가본값을 사용합니다.</string>
<string name="icmissing">프로파일에서 IC가 누락되었습니다. 가본값을 사용합니다.</string>
<string name="basalmissing">프로파일에서 기초주입량이 누락되었습니다. 가본값을 사용합니다.</string>
<string name="targetmissing">프로파일에서 목표범위가 누락되었습니다. 가본값을 사용합니다.</string>
<string name="invalidprofile">프로파일이 잘못되었습니다 !!!</string> <string name="invalidprofile">프로파일이 잘못되었습니다 !!!</string>
<string name="profileswitch">프로파일변경</string> <string name="profileswitch">프로파일변경</string>
<string name="careportal_pbage_label">펌프배터리사용기간</string> <string name="careportal_pbage_label">펌프배터리사용기간</string>
@ -591,8 +587,6 @@
<string name="openapsama_autosens_period">autosens 시간 [h]</string> <string name="openapsama_autosens_period">autosens 시간 [h]</string>
<string name="openapsama_autosens_period_summary">민감도를 감지하기 위해 계산될 총 시간 (탄수화물 흡수 시간은 제외됩니다.)</string> <string name="openapsama_autosens_period_summary">민감도를 감지하기 위해 계산될 총 시간 (탄수화물 흡수 시간은 제외됩니다.)</string>
<string name="ratio_short">SEN</string> <string name="ratio_short">SEN</string>
<string name="do_not_track_profile_switch">프로파일 변경 이벤트 무시하기</string>
<string name="do_not_track_profile_switch_summary">모든 프로파일 변경 이벤트는 무시되고, 항상 활성 프로파일이 사용됩니다.</string>
<string name="pump">Pump</string> <string name="pump">Pump</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Device</string> <string name="device">Device</string>

View file

@ -63,7 +63,6 @@
<string name="treatmentssafety_maxcarbs_title">Max toegestaane koolhydraten [g]</string> <string name="treatmentssafety_maxcarbs_title">Max toegestaane koolhydraten [g]</string>
<string name="basal">Basaal</string> <string name="basal">Basaal</string>
<string name="basal_short">BAS</string> <string name="basal_short">BAS</string>
<string name="basalmissing">Basaal ontbreekt in profiel. Standaard actief</string>
<string name="basalshortlabel">BAS</string> <string name="basalshortlabel">BAS</string>
<string name="base_profile_label">Basis Profiel</string> <string name="base_profile_label">Basis Profiel</string>
<string name="batterydischarged">Pomp Batterij Leeg</string> <string name="batterydischarged">Pomp Batterij Leeg</string>
@ -221,12 +220,10 @@
<string name="loop_shortname">LOOP</string> <string name="loop_shortname">LOOP</string>
<string name="it_lang">Italiano</string> <string name="it_lang">Italiano</string>
<string name="nl_lang">Nederlands</string> <string name="nl_lang">Nederlands</string>
<string name="isfmissing">ISF ontbreekt in profiel. Standaard waarden toegepast.</string>
<string name="glucosetype_finger">Vingerprik</string> <string name="glucosetype_finger">Vingerprik</string>
<string name="glucosetype_sensor">Sensor</string> <string name="glucosetype_sensor">Sensor</string>
<string name="high_mark">Hoog grens</string> <string name="high_mark">Hoog grens</string>
<string name="hours">Uren</string> <string name="hours">Uren</string>
<string name="icmissing">KH ratio ontbreekt in profieel. Standaard waarde toegepast</string>
<string name="import_from">Importeer instellingen van</string> <string name="import_from">Importeer instellingen van</string>
<string name="initializing">Initialisering</string> <string name="initializing">Initialisering</string>
<string name="danar_history_bolus">Bulossen</string> <string name="danar_history_bolus">Bulossen</string>
@ -252,7 +249,6 @@
<string name="disconnectpumpfor30m">Verbreek verbinding 30min met pomp</string> <string name="disconnectpumpfor30m">Verbreek verbinding 30min met pomp</string>
<string name="disconnectpumpfor3h">Verbreek verbinding 3u met pomp</string> <string name="disconnectpumpfor3h">Verbreek verbinding 3u met pomp</string>
<string name="dismiss">NEGEER</string> <string name="dismiss">NEGEER</string>
<string name="do_not_track_profile_switch">Negeer profiel wijzigingen</string>
<string name="iob">IOB</string> <string name="iob">IOB</string>
<string name="invalidprofile">Ongeldig profiel !!!</string> <string name="invalidprofile">Ongeldig profiel !!!</string>
<string name="insulin_shortname">INS</string> <string name="insulin_shortname">INS</string>
@ -527,7 +523,6 @@
<string name="danar_stats_warning_Message">Mogelijks inacuraat bij gebruik van bolussen om infusieset te vullen</string> <string name="danar_stats_warning_Message">Mogelijks inacuraat bij gebruik van bolussen om infusieset te vullen</string>
<string name="delta">Verschil</string> <string name="delta">Verschil</string>
<string name="dia">DIA:</string> <string name="dia">DIA:</string>
<string name="do_not_track_profile_switch_summary">Alle profiel wijzigingen worden genegeerd, aktief profiel wordt gebruikt</string>
<string name="edit_base_ic">Basis-IC aanpassen:</string> <string name="edit_base_ic">Basis-IC aanpassen:</string>
<string name="edit_base_isf">Basis-ISF aanpassen:</string> <string name="edit_base_isf">Basis-ISF aanpassen:</string>
<string name="enacted">Uitgevoerd</string> <string name="enacted">Uitgevoerd</string>
@ -602,7 +597,6 @@
<string name="smscommunicator_remotecommandnotallowed">Bevelen op astand zijn niet toegestaan</string> <string name="smscommunicator_remotecommandnotallowed">Bevelen op astand zijn niet toegestaan</string>
<string name="smscommunicator_tempbasalcanceled">Tijdelijk basaal afgebroken</string> <string name="smscommunicator_tempbasalcanceled">Tijdelijk basaal afgebroken</string>
<string name="smscommunicator_tempbasalcancelfailed">Afbreken van tijdelijk basaal mislukt</string> <string name="smscommunicator_tempbasalcancelfailed">Afbreken van tijdelijk basaal mislukt</string>
<string name="targetmissing">Streefdoel ontbreekt in profiel. Standaard waarde wordt gebruikt</string>
<string name="smscommunicator_tempbasalfailed">Start tijdelijk basaal mislukt</string> <string name="smscommunicator_tempbasalfailed">Start tijdelijk basaal mislukt</string>
<string name="openapsma_maxiob_summary">Deze waarde wordt de MAx IOB in OpenAPS context genoemt. Dit is standaard 0. Na enkele dagen of weken naargelang uw vertrouwen kan je dit getal wijzigen.</string> <string name="openapsma_maxiob_summary">Deze waarde wordt de MAx IOB in OpenAPS context genoemt. Dit is standaard 0. Na enkele dagen of weken naargelang uw vertrouwen kan je dit getal wijzigen.</string>
<string name="prefs_range_summary">Hoge en lage grens voor grafieken op het overzicht en op Wear</string> <string name="prefs_range_summary">Hoge en lage grens voor grafieken op het overzicht en op Wear</string>

View file

@ -561,7 +561,6 @@
<string name="absorptionsettings_title">Настройки усваиваемости</string> <string name="absorptionsettings_title">Настройки усваиваемости</string>
<string name="activate_profile">АКТИВИРОВАТЬ ПРОФИЛЬ</string> <string name="activate_profile">АКТИВИРОВАТЬ ПРОФИЛЬ</string>
<string name="basal_short">БАЗ</string> <string name="basal_short">БАЗ</string>
<string name="basalmissing">Базал отсутствует в профиле. Применяются данные по умолчанию</string>
<string name="careportal_activity_label">АКТИВНОСТЬ</string> <string name="careportal_activity_label">АКТИВНОСТЬ</string>
<string name="careportal_canulaage_label">канюля проработала</string> <string name="careportal_canulaage_label">канюля проработала</string>
<string name="careportal_canulaage_label_short">ВозрКан</string> <string name="careportal_canulaage_label_short">ВозрКан</string>
@ -584,17 +583,13 @@
<string name="date">дата</string> <string name="date">дата</string>
<string name="device">устройство</string> <string name="device">устройство</string>
<string name="dia_too_short" formatted="false">ачение длительности работы инс %s слишком мало - применено %s</string> <string name="dia_too_short" formatted="false">ачение длительности работы инс %s слишком мало - применено %s</string>
<string name="do_not_track_profile_switch">не отслеживать смены профиля</string>
<string name="do_not_track_profile_switch_summary">все смены профиля игнорируются; используется только активный профиль</string>
<string name="extendedbolus">расширенный болюс</string> <string name="extendedbolus">расширенный болюс</string>
<string name="free_peak_oref">Акуу-Зуфл Щкуа</string> <string name="free_peak_oref">Акуу-Зуфл Щкуа</string>
<string name="hours">час</string> <string name="hours">час</string>
<string name="icmissing">соотношение инс-углев отсутствует в профиле. применено соотн. по умолчанию</string>
<string name="insulin_oref_peak">Время пика действующего инс IOB</string> <string name="insulin_oref_peak">Время пика действующего инс IOB</string>
<string name="insulin_peak_time">время пика (в мин.)</string> <string name="insulin_peak_time">время пика (в мин.)</string>
<string name="invalid">НЕВЕРНО</string> <string name="invalid">НЕВЕРНО</string>
<string name="invalidprofile">Неверный профиль !!!</string> <string name="invalidprofile">Неверный профиль !!!</string>
<string name="isfmissing">фактор чувствительности к инс. отутствует в профиле. Применен фактор по умолчанию</string>
<string name="lock_screen">блокировка экрана</string> <string name="lock_screen">блокировка экрана</string>
<string name="lock_screen_short">блок</string> <string name="lock_screen_short">блок</string>
<string name="mdtp_cancel">отмена</string> <string name="mdtp_cancel">отмена</string>
@ -629,7 +624,6 @@
<string name="sensitivityoref0">Чувствительность Oref0</string> <string name="sensitivityoref0">Чувствительность Oref0</string>
<string name="sensitivityweightedaverage">средневзвешенная чувствительность</string> <string name="sensitivityweightedaverage">средневзвешенная чувствительность</string>
<string name="sv_lang">Шведский</string> <string name="sv_lang">Шведский</string>
<string name="targetmissing">Целевое значение отсутствует в профиле. Применено значение по умолчанию</string>
<string name="tempbasal">ВремБазал</string> <string name="tempbasal">ВремБазал</string>
<string name="temptarget">ВремЦель</string> <string name="temptarget">ВремЦель</string>
<string name="ultrafastactinginsulincomment">Fiasp</string> <string name="ultrafastactinginsulincomment">Fiasp</string>

View file

@ -19,7 +19,6 @@
<string name="basal">Basal</string> <string name="basal">Basal</string>
<string name="basal_rate">Basal E/tim</string> <string name="basal_rate">Basal E/tim</string>
<string name="basal_step">Basal steg</string> <string name="basal_step">Basal steg</string>
<string name="basalmissing">Basal saknas i profil. Använder grundbasal</string>
<string name="basalshortlabel">BR</string> <string name="basalshortlabel">BR</string>
<string name="basalvaluebelowminimum">Basal understiger min.nivå. Ingen profil satt</string> <string name="basalvaluebelowminimum">Basal understiger min.nivå. Ingen profil satt</string>
<string name="base_profile_label">Basalprofil</string> <string name="base_profile_label">Basalprofil</string>
@ -169,8 +168,6 @@
<string name="disconnectpumpfor30m">Frånkoppla pump i 30 min</string> <string name="disconnectpumpfor30m">Frånkoppla pump i 30 min</string>
<string name="disconnectpumpfor3h">Frånkoppla pump i 3 h</string> <string name="disconnectpumpfor3h">Frånkoppla pump i 3 h</string>
<string name="dismiss">TA BORT</string> <string name="dismiss">TA BORT</string>
<string name="do_not_track_profile_switch">Ignorera profilbyten</string>
<string name="do_not_track_profile_switch_summary">Alla profilbyten ignoreras och aktiv profil används alltid</string>
<string name="dont_show_again">Visa inte detta igen</string> <string name="dont_show_again">Visa inte detta igen</string>
<string name="duration">Duration</string> <string name="duration">Duration</string>
<string name="eatingsoon">Äta snart</string> <string name="eatingsoon">Äta snart</string>
@ -357,7 +354,6 @@
<string name="tempbasaldeliveryerror">Tempbasal ej tillförd</string> <string name="tempbasaldeliveryerror">Tempbasal ej tillförd</string>
<string name="tempbasal">Tempbasal</string> <string name="tempbasal">Tempbasal</string>
<string name="teenage">Tonåring</string> <string name="teenage">Tonåring</string>
<string name="targetmissing">Mål saknas i profil. Använder grundinställning</string>
<string name="target_range">Mål gränser:</string> <string name="target_range">Mål gränser:</string>
<string name="suspendloopfor3h">Stäng av loop i 3 h</string> <string name="suspendloopfor3h">Stäng av loop i 3 h</string>
<string name="suspendloopfor2h">Stäng av loop i 2 h</string> <string name="suspendloopfor2h">Stäng av loop i 2 h</string>
@ -549,7 +545,6 @@
<string name="edit_base_isf">Ändra Base-ISF:</string> <string name="edit_base_isf">Ändra Base-ISF:</string>
<string name="el_lang">Grekiska</string> <string name="el_lang">Grekiska</string>
<string name="end_user_license_agreement_text">MUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</string> <string name="end_user_license_agreement_text">MUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</string>
<string name="isfmissing">ISF fattas i profilen. Använder värde från grundinställning.</string>
<string name="lock_screen">Lås skärm</string> <string name="lock_screen">Lås skärm</string>
<string name="lock_screen_short">Lås</string> <string name="lock_screen_short">Lås</string>
<string name="mmol">mmol/l</string> <string name="mmol">mmol/l</string>

View file

@ -620,10 +620,6 @@
<string name="careportal_insulinage_label">Insulin age</string> <string name="careportal_insulinage_label">Insulin age</string>
<string name="hours">hours</string> <string name="hours">hours</string>
<string name="overview_newtempbasal_basaltype_label">Basal type</string> <string name="overview_newtempbasal_basaltype_label">Basal type</string>
<string name="isfmissing">ISF missing in profile. Using default.</string>
<string name="icmissing">IC missing in profile. Using default.</string>
<string name="basalmissing">Basal missing in profile. Using default.</string>
<string name="targetmissing">Target missing in profile. Using default.</string>
<string name="invalidprofile">Invalid profile !!!</string> <string name="invalidprofile">Invalid profile !!!</string>
<string name="profileswitch">ProfileSwitch</string> <string name="profileswitch">ProfileSwitch</string>
<string name="careportal_pbage_label">Pump battery age</string> <string name="careportal_pbage_label">Pump battery age</string>
@ -651,9 +647,6 @@
<string name="key_openapsama_autosens_period" translatable="false">openapsama_autosens_period</string> <string name="key_openapsama_autosens_period" translatable="false">openapsama_autosens_period</string>
<string name="key_nsclient_localbroadcasts" translatable="false">nsclient_localbroadcasts</string> <string name="key_nsclient_localbroadcasts" translatable="false">nsclient_localbroadcasts</string>
<string name="ratio_short">SEN</string> <string name="ratio_short">SEN</string>
<string name="key_do_not_track_profile_switch" translatable="false">do_not_track_profile_switch</string>
<string name="do_not_track_profile_switch">Ignore profile switch events</string>
<string name="do_not_track_profile_switch_summary">All profile switch events are ignored and active profile is always used</string>
<string name="pump">Pump</string> <string name="pump">Pump</string>
<string name="openaps">OpenAPS</string> <string name="openaps">OpenAPS</string>
<string name="device">Device</string> <string name="device">Device</string>
@ -992,6 +985,7 @@
<string name="overview_show_iob">Insulin On Board</string> <string name="overview_show_iob">Insulin On Board</string>
<string name="overview_show_basals">Basals</string> <string name="overview_show_basals">Basals</string>
<string name="closed_loop_disabled_on_dev_branch">Running dev version. Closed loop is disabled.</string> <string name="closed_loop_disabled_on_dev_branch">Running dev version. Closed loop is disabled.</string>
<string name="key_fromNSAreCommingFakedExtendedBoluses" translatable="false">fromNSAreCommingFakedExtendedBoluses</string>
<string name="engineering_mode_enabled">Engineering mode enabled</string> <string name="engineering_mode_enabled">Engineering mode enabled</string>
<string name="not_eng_mode_or_release">Engineering mode not enabled and not on release branch</string> <string name="not_eng_mode_or_release">Engineering mode not enabled and not on release branch</string>
<string name="pump_basebasalrate">%.2f U/h</string> <string name="pump_basebasalrate">%.2f U/h</string>

View file

@ -105,13 +105,6 @@
validate:minNumber="1" validate:minNumber="1"
validate:testType="floatNumericRange" /> validate:testType="floatNumericRange" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/profile">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_do_not_track_profile_switch"
android:summary="@string/do_not_track_profile_switch_summary"
android:title="@string/do_not_track_profile_switch" />
</PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:title="@string/bluetooth"> android:title="@string/bluetooth">

View file

@ -0,0 +1,174 @@
package info.nightscout.androidaps.data;
import com.squareup.otto.Bus;
import junit.framework.Assert;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.skyscreamer.jsonassert.JSONAssert;
import java.util.Calendar;
import java.util.TimeZone;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.utils.FabricPrivacy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Created by mike on 18.03.2018.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, VirtualPumpPlugin.class, FabricPrivacy.class})
public class ProfileTest {
PumpInterface pump = new VirtualPumpPlugin();
String validProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
String belowLimitValidProfile = "{\"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.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
String notAllignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
String notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"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\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
String noUnitsValidProfile = "{\"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\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}";
String wrongProfile = "{\"dia\":\"3\",\"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\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
//String profileStore = "{\"defaultProfile\":\"Default\",\"store\":{\"Default\":" + validProfile + "}}";
boolean notificationSent = false;
@Test
public void doTests() throws Exception {
prepareMock();
Profile p = new Profile();
// Test valid profile
p = new Profile(new JSONObject(validProfile), 100, 0);
Assert.assertEquals(true, p.isValid("Test"));
Assert.assertEquals(true, p.log().contains("NS units: mmol"));
JSONAssert.assertEquals(validProfile, p.getData(), false);
Assert.assertEquals(3.0d, p.getDia(), 0.01d);
Assert.assertEquals(TimeZone.getTimeZone("UTC"), p.getTimeZone());
Assert.assertEquals("00:30", p.format_HH_MM(30 * 60));
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 1);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
Assert.assertEquals(100d, p.getIsf(c.getTimeInMillis()), 0.01d);
c.set(Calendar.HOUR_OF_DAY, 2);
Assert.assertEquals(110d, p.getIsf(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(110d, p.getIsfTimeFromMidnight(2 * 60 * 60), 0.01d);
Assert.assertEquals("00:00 100,0 mmol/U\n" + "02:00 110,0 mmol/U", p.getIsfList().replace(".", ","));
Assert.assertEquals(30d, p.getIc(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(30d, p.getIcTimeFromMidnight(2 * 60 * 60), 0.01d);
Assert.assertEquals("00:00 30,0 g/U", p.getIcList().replace(".", ","));
Assert.assertEquals(0.1d, p.getBasal(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(0.1d, p.getBasalTimeFromMidnight(2 * 60 * 60), 0.01d);
Assert.assertEquals("00:00 0,10 U/h", p.getBasalList().replace(".", ","));
Assert.assertEquals(0.1d, p.getBasalValues()[0].value);
Assert.assertEquals(0.1d, p.getMaxDailyBasal());
Assert.assertEquals(2.4d, p.percentageBasalSum(), 0.01d);
Assert.assertEquals(2.4d, p.baseBasalSum(), 0.01d);
Assert.assertEquals(4.5d, p.getTarget(2 * 60 * 60), 0.01d);
Assert.assertEquals(4d, p.getTargetLow(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(4d, p.getTargetLowTimeFromMidnight(2 * 60 * 60), 0.01d);
Assert.assertEquals(5d, p.getTargetHigh(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(5d, p.getTargetHighTimeFromMidnight(2 * 60 * 60), 0.01d);
Assert.assertEquals("00:00 4,0 - 5,0 mmol", p.getTargetList().replace(".", ","));
Assert.assertEquals(100, p.getPercentage());
Assert.assertEquals(0, p.getTimeshift());
Assert.assertEquals(0.1d, p.toMgdl(0.1d, Constants.MGDL));
Assert.assertEquals(18d, p.toMgdl(1d, Constants.MMOL));
Assert.assertEquals(1d, p.toMmol(18d, Constants.MGDL));
Assert.assertEquals(18d, p.toMmol(18d, Constants.MMOL));
Assert.assertEquals(18d, p.fromMgdlToUnits(18d, Constants.MGDL));
Assert.assertEquals(1d, p.fromMgdlToUnits(18d, Constants.MMOL));
Assert.assertEquals(18d, p.toUnits(18d, 1d, Constants.MGDL));
Assert.assertEquals(1d, p.toUnits(18d, 1d, Constants.MMOL));
Assert.assertEquals("18", p.toUnitsString(18d, 1d, Constants.MGDL));
Assert.assertEquals("1,0", p.toUnitsString(18d, 1d, Constants.MMOL).replace(".", ","));
Assert.assertEquals("5 - 6", p.toTargetRangeString(5d, 6d, Constants.MGDL, Constants.MGDL));
Assert.assertEquals("4", p.toTargetRangeString(4d, 4d, Constants.MGDL, Constants.MGDL));
//Test basal profile below limit
p = new Profile(new JSONObject(belowLimitValidProfile), 100, 0);
p.isValid("Test");
Assert.assertEquals(true, notificationSent);
// Test profile w/o units
p = new Profile(new JSONObject(noUnitsValidProfile), 100, 0);
Assert.assertEquals(null, p.getUnits());
p = new Profile(new JSONObject(noUnitsValidProfile), Constants.MMOL);
Assert.assertEquals(Constants.MMOL, p.getUnits());
// failover to MGDL
p = new Profile(new JSONObject(noUnitsValidProfile), null);
Assert.assertEquals(Constants.MGDL, p.getUnits());
//Test profile not starting at midnight
p = new Profile(new JSONObject(notStartingAtZeroValidProfile), 100, 0);
Assert.assertEquals(30.0d, p.getIc(0), 0.01d);
// Test wrong profile
p = new Profile(new JSONObject(wrongProfile), 100, 0);
Assert.assertEquals(false, p.isValid("Test"));
// Test percentage functionality
p = new Profile(new JSONObject(validProfile), 50, 0);
Assert.assertEquals(0.05d, p.getBasal(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(1.2d, p.percentageBasalSum(), 0.01d);
Assert.assertEquals(60d, p.getIc(c.getTimeInMillis()), 0.01d);
Assert.assertEquals(220d, p.getIsf(c.getTimeInMillis()), 0.01d);
// Test timeshift functionality
p = new Profile(new JSONObject(validProfile), 100, 1);
Assert.assertEquals(
"00:00 110,0 mmol/U\n" +
"01:00 100,0 mmol/U\n" +
"03:00 110,0 mmol/U", p.getIsfList().replace(".", ","));
// Test hour alignment
MainApp.getConfigBuilder().getActivePump().getPumpDescription().is30minBasalRatesCapable = false;
notificationSent = false;
p = new Profile(new JSONObject(notAllignedBasalValidProfile), 100, 0);
p.isValid("Test");
Assert.assertEquals(true, notificationSent);
}
private void prepareMock() throws Exception {
ConfigBuilderPlugin configBuilderPlugin = mock(ConfigBuilderPlugin.class);
PowerMockito.mockStatic(ConfigBuilderPlugin.class);
MainApp mainApp = mock(MainApp.class);
PowerMockito.mockStatic(MainApp.class);
when(MainApp.instance()).thenReturn(mainApp);
when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin);
when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump);
when(MainApp.gs(R.string.minimalbasalvaluereplaced)).thenReturn("AnyString");
when(MainApp.gs(R.string.basalprofilenotaligned)).thenReturn("AnyString");
PowerMockito.mockStatic(FabricPrivacy.class);
// PowerMockito.doNothing().when(FabricPrivacy.log(""));
MockedBus bus = new MockedBus();
when(MainApp.bus()).thenReturn(bus);
}
class MockedBus extends Bus {
@Override
public void post(Object event) {
notificationSent = true;
}
}
}

View file

@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
*/ */
@RunWith(PowerMockRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, ConfigBuilderPlugin.class, ToastUtils.class, Context.class}) @PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, ToastUtils.class, Context.class})
public class CommandQueueTest extends CommandQueue { public class CommandQueueTest extends CommandQueue {
String profileJson = "{\"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\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"; String profileJson = "{\"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\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";