Merge branch 'dev' into dev-merge
This commit is contained in:
commit
643f3aee6c
47 changed files with 496 additions and 388 deletions
|
@ -57,7 +57,7 @@ android {
|
|||
targetSdkVersion 23
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "1.59-dev"
|
||||
version "1.60-dev"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||
|
||||
|
@ -238,6 +238,7 @@ dependencies {
|
|||
testCompile "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||
testCompile "joda-time:joda-time:2.9.4.2"
|
||||
testCompile "com.google.truth:truth:0.39"
|
||||
testCompile "org.skyscreamer:jsonassert:1.5.0"
|
||||
|
||||
androidTestCompile "org.mockito:mockito-core:2.7.22"
|
||||
androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||
|
|
|
@ -96,7 +96,7 @@ public class DataService extends IntentService {
|
|||
dexcomG5Enabled = true;
|
||||
}
|
||||
|
||||
boolean isNSProfile = ConfigBuilderPlugin.getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
||||
boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
||||
|
||||
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
|
||||
Bundle bundles = intent.getExtras();
|
||||
|
@ -368,9 +368,6 @@ public class DataService extends IntentService {
|
|||
ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
|
||||
NSProfilePlugin.getPlugin().storeNewProfile(profileStore);
|
||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
||||
// if there are no profile switches this should lead to profile update
|
||||
if (MainApp.getConfigBuilder().getProfileSwitchesFromHistory().size() == 0)
|
||||
MainApp.bus().post(new EventNewBasalProfile());
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Received profileStore: " + activeProfile + " " + profile);
|
||||
} catch (JSONException e) {
|
||||
|
|
|
@ -2,8 +2,6 @@ package info.nightscout.androidaps.data;
|
|||
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
|
||||
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -19,41 +17,43 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class Profile {
|
||||
private static Logger log = LoggerFactory.getLogger(Profile.class);
|
||||
|
||||
private JSONObject json;
|
||||
private String units = null;
|
||||
private double dia = Constants.defaultDIA;
|
||||
private TimeZone timeZone = TimeZone.getDefault();
|
||||
private String units;
|
||||
private double dia;
|
||||
private TimeZone timeZone;
|
||||
private JSONArray isf;
|
||||
private LongSparseArray<Double> isf_v = null; // oldest at index 0
|
||||
private LongSparseArray<Double> isf_v; // oldest at index 0
|
||||
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 LongSparseArray<Double> basal_v = null; // oldest at index 0
|
||||
private LongSparseArray<Double> basal_v; // oldest at index 0
|
||||
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 LongSparseArray<Double> targetHigh_v = null; // oldest at index 0
|
||||
private LongSparseArray<Double> targetHigh_v; // oldest at index 0
|
||||
|
||||
private int percentage = 100;
|
||||
private int timeshift = 0;
|
||||
private int percentage;
|
||||
private int timeshift;
|
||||
|
||||
private boolean isValid = true;
|
||||
private boolean isValidated = false;
|
||||
protected boolean isValid;
|
||||
protected boolean isValidated;
|
||||
|
||||
// Default constructor for tests
|
||||
protected Profile() {
|
||||
}
|
||||
|
||||
// Constructor from profileStore JSON
|
||||
public Profile(JSONObject json, String units) {
|
||||
this(json, 100, 0);
|
||||
init(json, 100, 0);
|
||||
if (this.units == null) {
|
||||
if (units != null)
|
||||
this.units = units;
|
||||
|
@ -65,6 +65,22 @@ public class Profile {
|
|||
}
|
||||
|
||||
public Profile(JSONObject json, int percentage, int timeshift) {
|
||||
init(json, percentage, timeshift);
|
||||
}
|
||||
|
||||
protected void init(JSONObject json, int percentage, int timeshift) {
|
||||
units = null;
|
||||
dia = Constants.defaultDIA;
|
||||
timeZone = TimeZone.getDefault();
|
||||
isf_v = null;
|
||||
ic_v = null;
|
||||
basal_v = null;
|
||||
targetLow_v = null;
|
||||
targetHigh_v = null;
|
||||
|
||||
isValid = true;
|
||||
isValidated = false;
|
||||
|
||||
this.percentage = percentage;
|
||||
this.timeshift = timeshift;
|
||||
this.json = json;
|
||||
|
@ -78,53 +94,12 @@ public class Profile {
|
|||
if (json.has("timezone"))
|
||||
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
||||
isf = json.getJSONArray("sens");
|
||||
if (getIsf(0) == null) {
|
||||
int defaultISF = units.equals(Constants.MGDL) ? 400 : 20;
|
||||
isf = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultISF + "\",\"timeAsSeconds\":\"0\"}]");
|
||||
Notification noisf = new Notification(Notification.ISF_MISSING, MainApp.sResources.getString(R.string.isfmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(noisf));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.ISF_MISSING));
|
||||
}
|
||||
ic = json.getJSONArray("carbratio");
|
||||
if (getIc(0) == null) {
|
||||
int defaultIC = 25;
|
||||
ic = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultIC + "\",\"timeAsSeconds\":\"0\"}]");
|
||||
Notification noic = new Notification(Notification.IC_MISSING, MainApp.sResources.getString(R.string.icmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(noic));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.IC_MISSING));
|
||||
}
|
||||
basal = json.getJSONArray("basal");
|
||||
if (getBasal(0) == null) {
|
||||
double defaultBasal = 0.1d;
|
||||
basal = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultBasal + "\",\"timeAsSeconds\":\"0\"}]");
|
||||
Notification nobasal = new Notification(Notification.BASAL_MISSING, MainApp.sResources.getString(R.string.basalmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(nobasal));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.BASAL_MISSING));
|
||||
}
|
||||
targetLow = json.getJSONArray("target_low");
|
||||
if (getTargetLow(0) == null) {
|
||||
double defaultLow = units.equals(Constants.MGDL) ? 120 : 6;
|
||||
targetLow = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultLow + "\",\"timeAsSeconds\":\"0\"}]");
|
||||
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notarget));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING));
|
||||
}
|
||||
targetHigh = json.getJSONArray("target_high");
|
||||
if (getTargetHigh(0) == null) {
|
||||
double defaultHigh = units.equals(Constants.MGDL) ? 160 : 8;
|
||||
targetHigh = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultHigh + "\",\"timeAsSeconds\":\"0\"}]");
|
||||
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notarget));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.invalidprofile));
|
||||
isValid = false;
|
||||
isValidated = true;
|
||||
}
|
||||
|
@ -133,7 +108,7 @@ public class Profile {
|
|||
public String log() {
|
||||
String ret = "\n";
|
||||
for (Integer hour = 0; hour < 24; hour++) {
|
||||
double value = getBasal((Integer) (hour * 60 * 60));
|
||||
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
|
||||
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
||||
}
|
||||
ret += "NS units: " + getUnits();
|
||||
|
@ -155,6 +130,10 @@ public class Profile {
|
|||
}
|
||||
|
||||
// mmol or mg/dl
|
||||
public void setUnits(String units) {
|
||||
this.units = units;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
@ -164,6 +143,11 @@ public class Profile {
|
|||
}
|
||||
|
||||
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
|
||||
if (array == null) {
|
||||
isValid = false;
|
||||
return new LongSparseArray<>();
|
||||
}
|
||||
|
||||
double multiplier = getMultiplier(array);
|
||||
|
||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||
|
@ -235,7 +219,7 @@ public class Profile {
|
|||
for (int i = 0; i < basal_v.size(); i++) {
|
||||
if (basal_v.valueAt(i) < description.basalMinimumRate) {
|
||||
basal_v.setValueAt(i, description.basalMinimumRate);
|
||||
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
||||
sendBelowMinimumNotification(from);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -249,6 +233,10 @@ public class Profile {
|
|||
return isValid;
|
||||
}
|
||||
|
||||
protected void sendBelowMinimumNotification(String from) {
|
||||
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
||||
}
|
||||
|
||||
private void validate(LongSparseArray array) {
|
||||
if (array.size() == 0) {
|
||||
isValid = false;
|
||||
|
@ -262,6 +250,7 @@ public class Profile {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
|
@ -281,6 +270,7 @@ public class Profile {
|
|||
}
|
||||
return lastValue;
|
||||
}
|
||||
*/
|
||||
|
||||
Integer getShitfTimeSecs(Integer originalTime) {
|
||||
Integer shiftedTime = originalTime + timeshift * 60 * 60;
|
||||
|
@ -322,7 +312,7 @@ public class Profile {
|
|||
return multiplier;
|
||||
}
|
||||
|
||||
private Double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
||||
private double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
for (Integer index = 0; index < array.size(); index++) {
|
||||
|
@ -337,7 +327,7 @@ public class Profile {
|
|||
return lastValue;
|
||||
}
|
||||
|
||||
private String format_HH_MM(Integer timeAsSeconds) {
|
||||
protected String format_HH_MM(Integer timeAsSeconds) {
|
||||
String time;
|
||||
int hour = timeAsSeconds / 60 / 60;
|
||||
int minutes = (timeAsSeconds - hour * 60 * 60) / 60;
|
||||
|
@ -364,51 +354,55 @@ public class Profile {
|
|||
return retValue;
|
||||
}
|
||||
|
||||
public Double getIsf() {
|
||||
return getIsf(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getIsf() {
|
||||
return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Double getIsf(long time) {
|
||||
return getIsf(secondsFromMidnight(time));
|
||||
public double getIsf(long time) {
|
||||
return getIsfTimeFromMidnight(secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public Double getIsf(Integer timeAsSeconds) {
|
||||
double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValueToTime(isf_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIsfList() {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
|
||||
}
|
||||
|
||||
public Double getIc() {
|
||||
return getIc(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getIc() {
|
||||
return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Double getIc(long time) {
|
||||
return getIc(secondsFromMidnight(time));
|
||||
public double getIc(long time) {
|
||||
return getIcTimeFromMidnight(secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public Double getIc(Integer timeAsSeconds) {
|
||||
public double getIcTimeFromMidnight(int timeAsSeconds) {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValueToTime(ic_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIcList() {
|
||||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), " g/U");
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U");
|
||||
}
|
||||
|
||||
public Double getBasal() {
|
||||
return getBasal(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getBasal() {
|
||||
return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Double getBasal(long time) {
|
||||
return getBasal(secondsFromMidnight(time));
|
||||
public double getBasal(long time) {
|
||||
return getBasalTimeFromMidnight(secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public synchronized Double getBasal(Integer timeAsSeconds) {
|
||||
public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) {
|
||||
if (basal_v == null) {
|
||||
basal_v = convertToSparseArray(basal);
|
||||
}
|
||||
|
@ -418,17 +412,17 @@ public class Profile {
|
|||
public String getBasalList() {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U");
|
||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U/h");
|
||||
}
|
||||
|
||||
public class BasalValue {
|
||||
public BasalValue(Integer timeAsSeconds, Double value) {
|
||||
public BasalValue(int timeAsSeconds, double value) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Integer timeAsSeconds;
|
||||
public Double value;
|
||||
public int timeAsSeconds;
|
||||
public double value;
|
||||
}
|
||||
|
||||
public synchronized BasalValue[] getBasalValues() {
|
||||
|
@ -438,7 +432,7 @@ public class Profile {
|
|||
|
||||
for (Integer index = 0; index < basal_v.size(); index++) {
|
||||
Integer tas = (int) basal_v.keyAt(index);
|
||||
Double value = basal_v.valueAt(index);
|
||||
double value = basal_v.valueAt(index);
|
||||
ret[index] = new BasalValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
|
@ -448,52 +442,56 @@ public class Profile {
|
|||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
private double getTarget(Integer time) {
|
||||
return (getTargetLow(time) + getTargetHigh(time))/2;
|
||||
protected double getTarget(int timeAsSeconds) {
|
||||
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2;
|
||||
}
|
||||
|
||||
public Double getTargetLow() {
|
||||
return getTargetLow(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getTargetLow() {
|
||||
return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Double getTargetLow(long time) {
|
||||
return getTargetLow(secondsFromMidnight(time));
|
||||
public double getTargetLow(long time) {
|
||||
return getTargetLowTimeFromMidnight(secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public Double getTargetLow(Integer timeAsSeconds) {
|
||||
public double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
return getValueToTime(targetLow_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public Double getTargetHigh() {
|
||||
return getTargetHigh(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getTargetHigh() {
|
||||
return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Double getTargetHigh(long time) {
|
||||
return getTargetHigh(secondsFromMidnight(time));
|
||||
public double getTargetHigh(long time) {
|
||||
return getTargetHighTimeFromMidnight(secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public Double getTargetHigh(Integer timeAsSeconds) {
|
||||
public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getTargetList() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits());
|
||||
}
|
||||
|
||||
public double getMaxDailyBasal() {
|
||||
Double max = 0d;
|
||||
for (Integer hour = 0; hour < 24; hour++) {
|
||||
double value = getBasal((Integer) (hour * 60 * 60));
|
||||
double max = 0d;
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
|
||||
if (value > max) max = value;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static Integer secondsFromMidnight() {
|
||||
public static int secondsFromMidnight() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
long now = c.getTimeInMillis();
|
||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||
|
@ -504,7 +502,7 @@ public class Profile {
|
|||
return (int) (passed / 1000);
|
||||
}
|
||||
|
||||
public static Integer secondsFromMidnight(long date) {
|
||||
public static int secondsFromMidnight(long date) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTimeInMillis(date);
|
||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||
|
@ -515,22 +513,22 @@ public class Profile {
|
|||
return (int) (passed / 1000);
|
||||
}
|
||||
|
||||
public static Double toMgdl(Double value, String units) {
|
||||
public static double toMgdl(double value, String units) {
|
||||
if (units.equals(Constants.MGDL)) return value;
|
||||
else return value * Constants.MMOLL_TO_MGDL;
|
||||
}
|
||||
|
||||
public static Double toMmol(Double value, String units) {
|
||||
public static double toMmol(double value, String units) {
|
||||
if (units.equals(Constants.MGDL)) return value * Constants.MGDL_TO_MMOLL;
|
||||
else return value;
|
||||
}
|
||||
|
||||
public static Double fromMgdlToUnits(Double value, String units) {
|
||||
public static double fromMgdlToUnits(double value, String units) {
|
||||
if (units.equals(Constants.MGDL)) return value;
|
||||
else return value * Constants.MGDL_TO_MMOLL;
|
||||
}
|
||||
|
||||
public static Double toUnits(Double valueInMgdl, Double valueInMmol, String units) {
|
||||
public static double toUnits(Double valueInMgdl, Double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL)) return valueInMgdl;
|
||||
else return valueInMmol;
|
||||
}
|
||||
|
@ -556,7 +554,7 @@ public class Profile {
|
|||
public double percentageBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasal((Integer) (i * 60 * 60));
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -565,7 +563,7 @@ public class Profile {
|
|||
public double baseBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasal((Integer) (i * 60 * 60)) / getMultiplier(basal_v);
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60) / getMultiplier(basal_v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@ package info.nightscout.androidaps.data;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by mike on 09.05.2017.
|
||||
|
@ -16,6 +20,7 @@ import info.nightscout.androidaps.interfaces.Interval;
|
|||
// When no interval match the lastest record without duration is used
|
||||
|
||||
public class ProfileIntervals<T extends Interval> {
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
|
||||
|
||||
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) {
|
||||
int index = binarySearch(time);
|
||||
if (index >= 0) return rawData.valueAt(index);
|
||||
// if we request data older than first record, use oldest instead
|
||||
if (rawData.size() > 0) {
|
||||
log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
|
||||
return rawData.valueAt(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1709,7 +1709,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (trJson.has("profileJson"))
|
||||
profileSwitch.profileJson = trJson.getString("profileJson");
|
||||
else {
|
||||
ProfileStore store = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
||||
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null) {
|
||||
profileSwitch.profileJson = profile.getData().toString();
|
||||
|
|
|
@ -96,7 +96,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
|||
noProfileView = view.findViewById(R.id.profileview_noprofile);
|
||||
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
|
||||
|
||||
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
||||
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
if (profileStore == null) {
|
||||
noProfileView.setVisibility(View.VISIBLE);
|
||||
butonsLayout.setVisibility(View.GONE);
|
||||
|
|
|
@ -59,6 +59,7 @@ import info.nightscout.utils.FabricPrivacy;
|
|||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.OKDialog;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.Translator;
|
||||
|
@ -73,7 +74,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
|
||||
Profile profile;
|
||||
ProfileStore profileStore;
|
||||
String units;
|
||||
String units = Constants.MGDL;
|
||||
|
||||
TextView eventTypeText;
|
||||
LinearLayout layoutPercent;
|
||||
|
@ -168,19 +169,24 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
|
||||
// profile
|
||||
profile = MainApp.getConfigBuilder().getProfile();
|
||||
profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
||||
ArrayList<CharSequence> profileList;
|
||||
units = profile != null ? profile.getUnits() : Constants.MGDL;
|
||||
profileList = profileStore.getProfileList();
|
||||
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(),
|
||||
R.layout.spinner_centered, profileList);
|
||||
profileSpinner.setAdapter(adapter);
|
||||
// set selected to actual profile
|
||||
for (int p = 0; p < profileList.size(); p++) {
|
||||
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false)))
|
||||
profileSpinner.setSelection(p);
|
||||
profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
if (profileStore == null) {
|
||||
if (options.eventType == R.id.careportal_profileswitch) {
|
||||
log.error("Profile switch called but plugin doesn't contain valid profile");
|
||||
}
|
||||
} else {
|
||||
ArrayList<CharSequence> profileList;
|
||||
units = profile != null ? profile.getUnits() : Constants.MGDL;
|
||||
profileList = profileStore.getProfileList();
|
||||
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(getContext(),
|
||||
R.layout.spinner_centered, profileList);
|
||||
profileSpinner.setAdapter(adapter);
|
||||
// set selected to actual profile
|
||||
for (int p = 0; p < profileList.size(); p++) {
|
||||
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false)))
|
||||
profileSpinner.setSelection(p);
|
||||
}
|
||||
}
|
||||
|
||||
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
|
||||
|
||||
// temp target
|
||||
|
@ -720,7 +726,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
profileSwitch.source = Source.USER;
|
||||
profileSwitch.profileName = profileName;
|
||||
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
|
||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
|
||||
profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
|
||||
profileSwitch.durationInMinutes = duration;
|
||||
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
||||
profileSwitch.timeshift = timeshift;
|
||||
|
@ -752,7 +758,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
profileSwitch.source = Source.USER;
|
||||
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
|
||||
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
|
||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
|
||||
profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
|
||||
profileSwitch.durationInMinutes = duration;
|
||||
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
||||
profileSwitch.timeshift = timeshift;
|
||||
|
|
|
@ -201,7 +201,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
return activeBgSource;
|
||||
}
|
||||
|
||||
public static ProfileInterface getActiveProfileInterface() {
|
||||
public ProfileInterface getActiveProfileInterface() {
|
||||
return activeProfile;
|
||||
}
|
||||
|
||||
|
@ -762,33 +762,21 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
}
|
||||
|
||||
public String getProfileName(long time, boolean customized) {
|
||||
boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false);
|
||||
if (!ignoreProfileSwitchEvents) {
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
}
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
}
|
||||
}
|
||||
// Unable to determine profile, failover to default
|
||||
String defaultProfile = activeProfile.getProfile().getDefaultProfileName();
|
||||
if (defaultProfile != null)
|
||||
return defaultProfile;
|
||||
// If default from plugin fails .... create empty
|
||||
return "Default";
|
||||
return MainApp.gs(R.string.noprofileselected);
|
||||
}
|
||||
|
||||
public boolean isProfileValid(String from) {
|
||||
return getProfile() != null && getProfile().isValid(from) &&
|
||||
activeProfile != null &&
|
||||
activeProfile.getProfile() != null &&
|
||||
activeProfile.getProfile().getDefaultProfile() != null &&
|
||||
activeProfile.getProfile().getDefaultProfile().isValid(from);
|
||||
return getProfile() != null && getProfile().isValid(from);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -808,41 +796,16 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
return null; //app not initialized
|
||||
}
|
||||
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time));
|
||||
boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false);
|
||||
if (!ignoreProfileSwitchEvents) {
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return profileSwitch.getProfileObject();
|
||||
} else if (activeProfile.getProfile() != null) {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profile;
|
||||
}
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return profileSwitch.getProfileObject();
|
||||
} else if (activeProfile.getProfile() != null) {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
// Unable to determine profile, failover to default
|
||||
if (activeProfile.getProfile() == null) {
|
||||
log.debug("getProfile activeProfile.getProfile() == null: returning null (activeProfile=" + activeProfile.getClass().getSimpleName() + ")");
|
||||
return null; //app not initialized
|
||||
}
|
||||
Profile defaultProfile = activeProfile.getProfile().getDefaultProfile();
|
||||
if (defaultProfile != null)
|
||||
return defaultProfile;
|
||||
// If default from plugin fails .... create empty
|
||||
try {
|
||||
Notification noisf = new Notification(Notification.ISF_MISSING, MainApp.sResources.getString(R.string.isfmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(noisf));
|
||||
Notification noic = new Notification(Notification.IC_MISSING, MainApp.sResources.getString(R.string.icmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(noic));
|
||||
Notification nobasal = new Notification(Notification.BASAL_MISSING, MainApp.sResources.getString(R.string.basalmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(nobasal));
|
||||
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notarget));
|
||||
return new Profile(new JSONObject("{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"6\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"8\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}}"), 100, 0);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
log.debug("getProfile at the end: returning null");
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -110,11 +110,6 @@ public class IobCobThread extends Thread {
|
|||
return; // profile not set yet
|
||||
}
|
||||
|
||||
if (profile.getIsf(bgTime) == null) {
|
||||
log.debug("Aborting calculation thread (no ISF): " + from);
|
||||
return; // profile not set yet
|
||||
}
|
||||
|
||||
if (Config.logAutosensData)
|
||||
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ public class DetermineBasalAdapterAMAJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
||||
mProfile.put("skip_neutral_temps", true);
|
||||
|
|
|
@ -212,9 +212,9 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
|
|
@ -172,7 +172,7 @@ public class DetermineBasalAdapterMAJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
|
||||
mProfile.put("current_basal", basalRate);
|
||||
|
||||
|
|
|
@ -212,9 +212,9 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
|||
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
|
|
@ -228,7 +228,7 @@ public class DetermineBasalAdapterSMBJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
||||
|
||||
|
|
|
@ -216,9 +216,9 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
|||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
||||
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return;
|
||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return;
|
||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return;
|
||||
|
|
|
@ -400,7 +400,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
|
||||
private void initDialog() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
||||
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile));
|
||||
|
@ -444,7 +444,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
}
|
||||
|
||||
private void calculateInsulin() {
|
||||
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
||||
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
|
||||
return; // not initialized yet
|
||||
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();
|
||||
|
|
|
@ -187,7 +187,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
final Object updateSync = new Object();
|
||||
|
||||
public enum CHARTTYPE {PRE,BAS, IOB, COB, DEV, SEN};
|
||||
public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN};
|
||||
|
||||
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledUpdate = null;
|
||||
|
||||
|
@ -344,7 +345,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
SpannableString s;
|
||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||
|
||||
if(predictionsAvailable) {
|
||||
if (predictionsAvailable) {
|
||||
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions");
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
|
@ -464,7 +465,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
} else if (v == activeProfileView) {
|
||||
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
|
||||
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
|
||||
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
|
||||
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -966,7 +969,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
if (timeView != null) { //must not exists
|
||||
timeView.setText(DateUtil.timeString(new Date()));
|
||||
}
|
||||
if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {// app not initialized yet
|
||||
if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {
|
||||
pumpStatusView.setText(R.string.noprofileset);
|
||||
pumpStatusLayout.setVisibility(View.VISIBLE);
|
||||
loopStatusLayout.setVisibility(View.GONE);
|
||||
|
@ -983,12 +986,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null) {
|
||||
pumpStatusView.setText(R.string.noprofileset);
|
||||
pumpStatusLayout.setVisibility(View.VISIBLE);
|
||||
loopStatusLayout.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
final String units = profile.getUnits();
|
||||
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||
|
|
|
@ -42,10 +42,7 @@ public class Notification {
|
|||
public static final int APPROACHING_DAILY_LIMIT = 11;
|
||||
public static final int NSCLIENT_NO_WRITE_PERMISSION = 12;
|
||||
public static final int MISSING_SMS_PERMISSION = 13;
|
||||
public static final int ISF_MISSING = 14;
|
||||
public static final int IC_MISSING = 15;
|
||||
public static final int BASAL_MISSING = 16;
|
||||
public static final int TARGET_MISSING = 17;
|
||||
|
||||
public static final int NSANNOUNCEMENT = 18;
|
||||
public static final int NSALARM = 19;
|
||||
public static final int NSURGENTALARM = 20;
|
||||
|
|
|
@ -14,47 +14,55 @@ import com.squareup.otto.Subscribe;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnItemSelected;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
||||
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;
|
||||
|
||||
public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener {
|
||||
private Spinner profileSpinner;
|
||||
private TextView noProfile;
|
||||
private TextView units;
|
||||
private TextView dia;
|
||||
private TextView activeProfile;
|
||||
private TextView ic;
|
||||
private TextView isf;
|
||||
private TextView basal;
|
||||
private TextView target;
|
||||
|
||||
public class NSProfileFragment extends SubscriberFragment {
|
||||
@BindView(R.id.nsprofile_spinner)
|
||||
Spinner profileSpinner;
|
||||
@BindView(R.id.profileview_noprofile)
|
||||
TextView noProfile;
|
||||
@BindView(R.id.profileview_invalidprofile)
|
||||
TextView invalidProfile;
|
||||
@BindView(R.id.profileview_units)
|
||||
TextView units;
|
||||
@BindView(R.id.profileview_dia)
|
||||
TextView dia;
|
||||
@BindView(R.id.profileview_activeprofile)
|
||||
TextView activeProfile;
|
||||
@BindView(R.id.profileview_ic)
|
||||
TextView ic;
|
||||
@BindView(R.id.profileview_isf)
|
||||
TextView isf;
|
||||
@BindView(R.id.profileview_basal)
|
||||
TextView basal;
|
||||
@BindView(R.id.profileview_target)
|
||||
TextView target;
|
||||
@BindView(R.id.basal_graph)
|
||||
ProfileGraph basalGraph;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
try {
|
||||
View layout = inflater.inflate(R.layout.nsprofile_fragment, container, false);
|
||||
|
||||
profileSpinner = (Spinner) layout.findViewById(R.id.nsprofile_spinner);
|
||||
noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile);
|
||||
units = (TextView) layout.findViewById(R.id.profileview_units);
|
||||
dia = (TextView) layout.findViewById(R.id.profileview_dia);
|
||||
activeProfile = (TextView) layout.findViewById(R.id.profileview_activeprofile);
|
||||
ic = (TextView) layout.findViewById(R.id.profileview_ic);
|
||||
isf = (TextView) layout.findViewById(R.id.profileview_isf);
|
||||
basal = (TextView) layout.findViewById(R.id.profileview_basal);
|
||||
target = (TextView) layout.findViewById(R.id.profileview_target);
|
||||
|
||||
profileSpinner.setOnItemSelectedListener(this);
|
||||
View view = inflater.inflate(R.layout.nsprofile_fragment, container, false);
|
||||
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
updateGUI();
|
||||
return layout;
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
@ -66,12 +74,7 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
|
|||
public void onStatusEvent(final EventNSProfileUpdateGUI ev) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI();
|
||||
}
|
||||
});
|
||||
activity.runOnUiThread(() -> updateGUI());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,9 +100,9 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
String name = parent.getItemAtPosition(position).toString();
|
||||
@OnItemSelected(R.id.nsprofile_spinner)
|
||||
public void onItemSelected(Spinner spinner, int position) {
|
||||
String name = spinner.getItemAtPosition(position).toString();
|
||||
|
||||
ProfileStore store = NSProfilePlugin.getPlugin().getProfile();
|
||||
if (store != null) {
|
||||
|
@ -112,12 +115,18 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
|
|||
isf.setText(profile.getIsfList());
|
||||
basal.setText(profile.getBasalList());
|
||||
target.setText(profile.getTargetList());
|
||||
basalGraph.show(profile);
|
||||
}
|
||||
if (profile.isValid("NSProfileFragment"))
|
||||
invalidProfile.setVisibility(View.GONE);
|
||||
else
|
||||
invalidProfile.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
@OnItemSelected(value = R.id.nsprofile_spinner, callback = NOTHING_SELECTED)
|
||||
public void onNothingSelected() {
|
||||
invalidProfile.setVisibility(View.VISIBLE);
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
units.setText("");
|
||||
dia.setText("");
|
||||
|
|
|
@ -120,19 +120,6 @@ public class NSProfilePlugin implements PluginBase, ProfileInterface {
|
|||
profile = new ProfileStore(newProfile.getData());
|
||||
storeNSProfile();
|
||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
||||
if (MainApp.getConfigBuilder().isProfileValid("storeNewProfile")) {
|
||||
ConfigBuilderPlugin.getCommandQueue().setProfile(MainApp.getConfigBuilder().getProfile(), new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (result.enacted) {
|
||||
SmsCommunicatorPlugin smsCommunicatorPlugin = MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class);
|
||||
if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginBase.GENERAL)) {
|
||||
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.sResources.getString(R.string.profile_set_ok));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void storeNSProfile() {
|
||||
|
|
|
@ -184,7 +184,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
Double profileValue = profile.getBasalTimeFromMidnight((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
|
|
|
@ -241,7 +241,7 @@ public class DanaRPump {
|
|||
for (Integer hour = 0; hour < 24; hour++) {
|
||||
//Some values get truncated to the next lower one.
|
||||
// -> round them to two decimals and make sure we are a small delta larger (that will get truncated)
|
||||
double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001;
|
||||
double value = Math.round(100d * nsProfile.getBasalTimeFromMidnight((Integer) (hour * 60 * 60)))/100d + 0.00001;
|
||||
if (Config.logDanaMessageDetail)
|
||||
log.debug("NS basal value for " + hour + ":00 is " + value);
|
||||
record[hour] = value;
|
||||
|
|
|
@ -428,7 +428,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
|
||||
for (int h = 0; h < basalValues; h++) {
|
||||
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
|
||||
Double profileValue = profile.getBasal((Integer) (h * basalIncrement));
|
||||
Double profileValue = profile.getBasalTimeFromMidnight((Integer) (h * basalIncrement));
|
||||
if (profileValue == null) return true;
|
||||
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
|
||||
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
|
||||
|
|
|
@ -52,12 +52,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
|
|||
private PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
private static void loadFakingStatus() {
|
||||
fromNSAreCommingFakedExtendedBoluses = SP.getBoolean("fromNSAreCommingFakedExtendedBoluses", false);
|
||||
fromNSAreCommingFakedExtendedBoluses = SP.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false);
|
||||
}
|
||||
|
||||
public static void setFakingStatus(boolean newStatus) {
|
||||
fromNSAreCommingFakedExtendedBoluses = newStatus;
|
||||
SP.putBoolean("fromNSAreCommingFakedExtendedBoluses", fromNSAreCommingFakedExtendedBoluses);
|
||||
SP.putBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, fromNSAreCommingFakedExtendedBoluses);
|
||||
}
|
||||
|
||||
public static boolean getFakingStatus() {
|
||||
|
@ -73,7 +73,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
private VirtualPumpPlugin() {
|
||||
public VirtualPumpPlugin() {
|
||||
pumpDescription.isBolusCapable = true;
|
||||
pumpDescription.bolusStep = 0.1d;
|
||||
|
||||
|
@ -245,7 +245,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
|
|||
public double getBaseBasalRate() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile != null)
|
||||
return profile.getBasal() != null ? profile.getBasal() : 0d;
|
||||
return profile.getBasal();
|
||||
else
|
||||
return 0d;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class BGSourceFragment extends SubscriberFragment {
|
|||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false));
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
profile = ConfigBuilderPlugin.getActiveProfileInterface().getProfile().getDefaultProfile();
|
||||
profile = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile().getDefaultProfile();
|
||||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -33,8 +33,8 @@ public class ProfileGraph extends GraphView {
|
|||
List<DataPoint> basalArray = new ArrayList<>();
|
||||
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
basalArray.add(new DataPoint(hour, profile.getBasal(new Integer(hour*60*60))));
|
||||
basalArray.add(new DataPoint(hour+1, profile.getBasal(new Integer(hour*60*60))));
|
||||
basalArray.add(new DataPoint(hour, profile.getBasalTimeFromMidnight(new Integer(hour*60*60))));
|
||||
basalArray.add(new DataPoint(hour+1, profile.getBasalTimeFromMidnight(new Integer(hour*60*60))));
|
||||
}
|
||||
DataPoint[] basalDataPoints = new DataPoint[basalArray.size()];
|
||||
basalDataPoints = basalArray.toArray(basalDataPoints);
|
||||
|
|
|
@ -12,6 +12,9 @@ import android.widget.TextView;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
@ -30,19 +33,36 @@ public class ProfileViewerDialog extends DialogFragment {
|
|||
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class);
|
||||
|
||||
private TextView noProfile;
|
||||
private TextView units;
|
||||
private TextView dia;
|
||||
private TextView activeProfile;
|
||||
private TextView ic;
|
||||
private TextView isf;
|
||||
private TextView basal;
|
||||
private TextView target;
|
||||
private View dateDelimiter;
|
||||
private LinearLayout dateLayout;
|
||||
private TextView dateTextView;
|
||||
private Button refreshButton;
|
||||
private ProfileGraph basalGraph;
|
||||
@BindView(R.id.profileview_noprofile)
|
||||
TextView noProfile;
|
||||
@BindView(R.id.profileview_invalidprofile)
|
||||
TextView invalidProfile;
|
||||
@BindView(R.id.profileview_units)
|
||||
TextView units;
|
||||
@BindView(R.id.profileview_dia)
|
||||
TextView dia;
|
||||
@BindView(R.id.profileview_activeprofile)
|
||||
TextView activeProfile;
|
||||
@BindView(R.id.profileview_ic)
|
||||
TextView ic;
|
||||
@BindView(R.id.profileview_isf)
|
||||
TextView isf;
|
||||
@BindView(R.id.profileview_basal)
|
||||
TextView basal;
|
||||
@BindView(R.id.profileview_target)
|
||||
TextView target;
|
||||
@BindView(R.id.profileview_datedelimiter)
|
||||
View dateDelimiter;
|
||||
@BindView(R.id.profileview_datelayout)
|
||||
LinearLayout dateLayout;
|
||||
@BindView(R.id.profileview_date)
|
||||
TextView dateTextView;
|
||||
@BindView(R.id.profileview_reload)
|
||||
Button refreshButton;
|
||||
@BindView(R.id.basal_graph)
|
||||
ProfileGraph basalGraph;
|
||||
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static ProfileViewerDialog newInstance(long time) {
|
||||
ProfileViewerDialog dialog = new ProfileViewerDialog();
|
||||
|
@ -61,31 +81,26 @@ public class ProfileViewerDialog extends DialogFragment {
|
|||
time = getArguments().getLong("time");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (unbinder != null)
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.profileviewer_fragment, container, false);
|
||||
View view = inflater.inflate(R.layout.profileviewer_fragment, container, false);
|
||||
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
|
||||
noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile);
|
||||
units = (TextView) layout.findViewById(R.id.profileview_units);
|
||||
dia = (TextView) layout.findViewById(R.id.profileview_dia);
|
||||
activeProfile = (TextView) layout.findViewById(R.id.profileview_activeprofile);
|
||||
ic = (TextView) layout.findViewById(R.id.profileview_ic);
|
||||
isf = (TextView) layout.findViewById(R.id.profileview_isf);
|
||||
basal = (TextView) layout.findViewById(R.id.profileview_basal);
|
||||
target = (TextView) layout.findViewById(R.id.profileview_target);
|
||||
refreshButton = (Button) layout.findViewById(R.id.profileview_reload);
|
||||
refreshButton.setVisibility(View.GONE);
|
||||
dateDelimiter = layout.findViewById(R.id.profileview_datedelimiter);
|
||||
dateDelimiter.setVisibility(View.VISIBLE);
|
||||
dateLayout = (LinearLayout) layout.findViewById(R.id.profileview_datelayout);
|
||||
dateLayout.setVisibility(View.VISIBLE);
|
||||
dateTextView = (TextView) layout.findViewById(R.id.profileview_date);
|
||||
basalGraph = (ProfileGraph) layout.findViewById(R.id.basal_graph);
|
||||
|
||||
setContent();
|
||||
return layout;
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -114,6 +129,11 @@ public class ProfileViewerDialog extends DialogFragment {
|
|||
basal.setText(profile.getBasalList());
|
||||
target.setText(profile.getTargetList());
|
||||
basalGraph.show(profile);
|
||||
|
||||
if (profile.isValid("ProfileViewDialog"))
|
||||
invalidProfile.setVisibility(View.GONE);
|
||||
else
|
||||
invalidProfile.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
|
|
@ -586,7 +586,7 @@ public class ActionStringHandler {
|
|||
}
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
||||
if (profile == null || profile.getBasal() == null) {
|
||||
if (profile == null) {
|
||||
msg += MainApp.sResources.getString(R.string.notloadedplugins) + "\n";
|
||||
}
|
||||
if (!"".equals(msg)) {
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package info.nightscout.androidaps.queue.commands;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
|
||||
/**
|
||||
|
@ -11,7 +16,7 @@ import info.nightscout.androidaps.queue.Callback;
|
|||
*/
|
||||
|
||||
public class CommandSetProfile extends Command {
|
||||
Profile profile;
|
||||
private Profile profile;
|
||||
|
||||
public CommandSetProfile(Profile profile, Callback callback) {
|
||||
commandType = CommandType.BASALPROFILE;
|
||||
|
@ -24,6 +29,15 @@ public class CommandSetProfile extends Command {
|
|||
PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile);
|
||||
if (callback != null)
|
||||
callback.result(r).run();
|
||||
|
||||
// Send SMS notification if ProfileSwitch is comming from NS
|
||||
ProfileSwitch profileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
|
||||
if (r.enacted && profileSwitch.source == Source.NIGHTSCOUT) {
|
||||
SmsCommunicatorPlugin smsCommunicatorPlugin = MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class);
|
||||
if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginBase.GENERAL)) {
|
||||
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.sResources.getString(R.string.profile_set_ok));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -52,7 +52,7 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
|||
private void checkPump() {
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (pump != null && profile != null && profile.getBasal() != null) {
|
||||
if (pump != null && profile != null) {
|
||||
Date lastConnection = pump.lastDataTime();
|
||||
boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis();
|
||||
boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep;
|
||||
|
|
|
@ -78,7 +78,7 @@ public class LocalAlertUtils {
|
|||
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (pump != null && profile != null && profile.getBasal() != null) {
|
||||
if (pump != null && profile != null) {
|
||||
Date lastConnection = pump.lastDataTime();
|
||||
long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold();
|
||||
if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
<include
|
||||
layout="@layout/profileviewer_fragment"
|
||||
layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
|
@ -13,6 +13,17 @@
|
|||
android:layout_height="wrap_content"
|
||||
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
|
||||
android:id="@+id/profileview_noprofile"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -61,6 +72,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/profileview_datedelimiter"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
|
@ -68,14 +80,13 @@
|
|||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@color/listdelimiter"
|
||||
android:id="@+id/profileview_datedelimiter"
|
||||
android:visibility="gone"/>
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/profileview_datelayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/profileview_datelayout"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
|
@ -333,11 +344,13 @@
|
|||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph
|
||||
android:id="@+id/basal_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="20dp"
|
||||
android:layout_height="100dip" />
|
||||
android:layout_height="100dip"
|
||||
android:layout_margin="20dp" />
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
|
@ -393,11 +406,11 @@
|
|||
android:background="@color/listdelimiter" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/profileview_reload"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/reloadprofile"
|
||||
android:id="@+id/profileview_reload"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/reloadprofile"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -561,10 +561,6 @@
|
|||
<string name="careportal_insulinage_label">Възраст на инсулина</string>
|
||||
<string name="hours">часа</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="profileswitch">Смяна на профил</string>
|
||||
<string name="careportal_pbage_label">Възраст на батерията на помпата</string>
|
||||
|
@ -581,8 +577,6 @@
|
|||
<string name="nsalarm_urgent_staledatavalue_label">Много стари данни при повече от [мин]</string>
|
||||
<string name="openapsama_autosens_period">Интервал за autosens [ч]</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="openaps">OpenAPS</string>
|
||||
<string name="device">Устройство</string>
|
||||
|
|
|
@ -555,14 +555,10 @@
|
|||
<string name="danarv2pump">DanaRv2</string>
|
||||
<string name="dev">ODCH</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="hours">hodin</string>
|
||||
<string name="icmissing">I:S chybí. Je použita výchozí hodnota.</string>
|
||||
<string name="invalidprofile">Chybný profil !!!</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_short">Zámek</string>
|
||||
<string name="mdtp_cancel">Zrušit</string>
|
||||
|
@ -592,7 +588,6 @@
|
|||
<string name="xdripstatus_settings">Status z xDripu (hodinky)</string>
|
||||
<string name="xdripstatus_shortname">xds</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="temptarget">DočasnýCíl</string>
|
||||
<string name="wear_overviewnotifications">Oznámení na hodinkách</string>
|
||||
|
@ -609,7 +604,6 @@
|
|||
<string name="openaps_short">OAPS</string>
|
||||
<string name="danar_bluetooth_status">Bluetooth status</string>
|
||||
<string name="careportal_activity_label">AKTIVITA & 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_short">BAZ</string>
|
||||
<string name="unsupportednsversion">Nepodporovaná verze Nightscoutu</string>
|
||||
|
|
|
@ -353,7 +353,6 @@
|
|||
<string name="app_name">AndroidAPS</string>
|
||||
<string name="basal_short">BAS</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="batteryoptimalizationerror">Smartphone untertützt anscheinend das Deaktivieren der Akku-Leistungsoptimierung nicht!</string>
|
||||
<string name="bolus_step">Bolus-Schritt</string>
|
||||
|
@ -368,7 +367,6 @@
|
|||
<string name="paused">Pausiert</string>
|
||||
<string name="patientage">Patientenalter</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="tempbasaldeliveryerror">TBR Abgabe-Fehler</string>
|
||||
<string name="temptarget">Temporäres Ziel</string>
|
||||
|
@ -414,8 +412,6 @@
|
|||
<string name="disconnectpumpfor15m">Trenne Pumpe für 15 Min.</string>
|
||||
<string name="disconnectpumpfor30m">Trenne Pumpe für 30 Min.</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="eatingsoon">Bald essen</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="edit_base_ic">Bearbeite Basis-IC:</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="isfmissing">ISF fehlt im Profil. Verwende Standard-Wert.</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="nsalarm_staledata">Veraltete Daten</string>
|
||||
|
|
|
@ -559,10 +559,6 @@
|
|||
<string name="careportal_insulinage_label">Χρόνος ζωής Ινσουλίνης</string>
|
||||
<string name="hours">ώρες</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="profileswitch">ΜΕταβείτε στο προφίλ</string>
|
||||
<string name="careportal_pbage_label">Χρόνος ζωής μπαταρίας αντλίας</string>
|
||||
|
@ -580,8 +576,6 @@
|
|||
<string name="openapsama_autosens_period">"Εσωτερικά διαστήματα για autosense [h] "</string>
|
||||
<string name="openapsama_autosens_period_summary">Ποσότητα ωρών κατά το παρελθόν για ανίχνευση ευαισθησίας (εξαιρείται ο χρόνος απορρόφησης υδατανθράκων)</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="openaps">OpenAPS</string>
|
||||
<string name="device">Συσκευή</string>
|
||||
|
|
|
@ -564,10 +564,6 @@
|
|||
<string name="careportal_insulinage_label">Edad insulina</string>
|
||||
<string name="hours">horas</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="profileswitch">CambioPerfil</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_summary">Horas en el pasado para detectar sensividad (tiempo de absorcion de carbohidratos no incluidos)</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="openaps">OpenAPS</string>
|
||||
<string name="device">Aparato</string>
|
||||
|
|
|
@ -557,10 +557,6 @@
|
|||
<string name="careportal_insulinage_label">Durée d\'insuline</string>
|
||||
<string name="hours">Heures</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="profileswitch">Changement de Profil</string>
|
||||
<string name="careportal_pbage_label">Durée batterie pompe</string>
|
||||
|
@ -578,8 +574,6 @@
|
|||
<string name="openapsama_autosens_period">"l’intervalle pour autosens [h] "</string>
|
||||
<string name="openapsama_autosens_period_summary">Le nombre d’heures écoulées pour la détection de sensibilité (le temps d’absorption des glucides est exclu)</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="openaps">OpenAPS</string>
|
||||
<string name="device">Dispositif</string>
|
||||
|
|
|
@ -570,10 +570,6 @@
|
|||
<string name="careportal_insulinage_label">인슐린 사용기간</string>
|
||||
<string name="hours">시간</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="profileswitch">프로파일변경</string>
|
||||
<string name="careportal_pbage_label">펌프배터리사용기간</string>
|
||||
|
@ -591,8 +587,6 @@
|
|||
<string name="openapsama_autosens_period">autosens 시간 [h]</string>
|
||||
<string name="openapsama_autosens_period_summary">민감도를 감지하기 위해 계산될 총 시간 (탄수화물 흡수 시간은 제외됩니다.)</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="openaps">OpenAPS</string>
|
||||
<string name="device">Device</string>
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
<string name="treatmentssafety_maxcarbs_title">Max toegestaane koolhydraten [g]</string>
|
||||
<string name="basal">Basaal</string>
|
||||
<string name="basal_short">BAS</string>
|
||||
<string name="basalmissing">Basaal ontbreekt in profiel. Standaard actief</string>
|
||||
<string name="basalshortlabel">BAS</string>
|
||||
<string name="base_profile_label">Basis Profiel</string>
|
||||
<string name="batterydischarged">Pomp Batterij Leeg</string>
|
||||
|
@ -221,12 +220,10 @@
|
|||
<string name="loop_shortname">LOOP</string>
|
||||
<string name="it_lang">Italiano</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_sensor">Sensor</string>
|
||||
<string name="high_mark">Hoog grens</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="initializing">Initialisering</string>
|
||||
<string name="danar_history_bolus">Bulossen</string>
|
||||
|
@ -252,7 +249,6 @@
|
|||
<string name="disconnectpumpfor30m">Verbreek verbinding 30min met pomp</string>
|
||||
<string name="disconnectpumpfor3h">Verbreek verbinding 3u met pomp</string>
|
||||
<string name="dismiss">NEGEER</string>
|
||||
<string name="do_not_track_profile_switch">Negeer profiel wijzigingen</string>
|
||||
<string name="iob">IOB</string>
|
||||
<string name="invalidprofile">Ongeldig profiel !!!</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="delta">Verschil</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_isf">Basis-ISF aanpassen:</string>
|
||||
<string name="enacted">Uitgevoerd</string>
|
||||
|
@ -602,7 +597,6 @@
|
|||
<string name="smscommunicator_remotecommandnotallowed">Bevelen op astand zijn niet toegestaan</string>
|
||||
<string name="smscommunicator_tempbasalcanceled">Tijdelijk basaal afgebroken</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="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>
|
||||
|
|
|
@ -561,7 +561,6 @@
|
|||
<string name="absorptionsettings_title">Настройки усваиваемости</string>
|
||||
<string name="activate_profile">АКТИВИРОВАТЬ ПРОФИЛЬ</string>
|
||||
<string name="basal_short">БАЗ</string>
|
||||
<string name="basalmissing">Базал отсутствует в профиле. Применяются данные по умолчанию</string>
|
||||
<string name="careportal_activity_label">АКТИВНОСТЬ</string>
|
||||
<string name="careportal_canulaage_label">канюля проработала</string>
|
||||
<string name="careportal_canulaage_label_short">ВозрКан</string>
|
||||
|
@ -584,17 +583,13 @@
|
|||
<string name="date">дата</string>
|
||||
<string name="device">устройство</string>
|
||||
<string name="dia_too_short" formatted="false">pначение длительности работы инс %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="free_peak_oref">Акуу-Зуфл Щкуа</string>
|
||||
<string name="hours">час</string>
|
||||
<string name="icmissing">соотношение инс-углев отсутствует в профиле. применено соотн. по умолчанию</string>
|
||||
<string name="insulin_oref_peak">Время пика действующего инс IOB</string>
|
||||
<string name="insulin_peak_time">время пика (в мин.)</string>
|
||||
<string name="invalid">НЕВЕРНО</string>
|
||||
<string name="invalidprofile">Неверный профиль !!!</string>
|
||||
<string name="isfmissing">фактор чувствительности к инс. отутствует в профиле. Применен фактор по умолчанию</string>
|
||||
<string name="lock_screen">блокировка экрана</string>
|
||||
<string name="lock_screen_short">блок</string>
|
||||
<string name="mdtp_cancel">отмена</string>
|
||||
|
@ -629,7 +624,6 @@
|
|||
<string name="sensitivityoref0">Чувствительность Oref0</string>
|
||||
<string name="sensitivityweightedaverage">средневзвешенная чувствительность</string>
|
||||
<string name="sv_lang">Шведский</string>
|
||||
<string name="targetmissing">Целевое значение отсутствует в профиле. Применено значение по умолчанию</string>
|
||||
<string name="tempbasal">ВремБазал</string>
|
||||
<string name="temptarget">ВремЦель</string>
|
||||
<string name="ultrafastactinginsulincomment">Fiasp</string>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<string name="basal">Basal</string>
|
||||
<string name="basal_rate">Basal E/tim</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="basalvaluebelowminimum">Basal understiger min.nivå. Ingen profil satt</string>
|
||||
<string name="base_profile_label">Basalprofil</string>
|
||||
|
@ -169,8 +168,6 @@
|
|||
<string name="disconnectpumpfor30m">Frånkoppla pump i 30 min</string>
|
||||
<string name="disconnectpumpfor3h">Frånkoppla pump i 3 h</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="duration">Duration</string>
|
||||
<string name="eatingsoon">Äta snart</string>
|
||||
|
@ -357,7 +354,6 @@
|
|||
<string name="tempbasaldeliveryerror">Tempbasal ej tillförd</string>
|
||||
<string name="tempbasal">Tempbasal</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="suspendloopfor3h">Stäng av loop i 3 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="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="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_short">Lås</string>
|
||||
<string name="mmol">mmol/l</string>
|
||||
|
|
|
@ -620,10 +620,6 @@
|
|||
<string name="careportal_insulinage_label">Insulin age</string>
|
||||
<string name="hours">hours</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="profileswitch">ProfileSwitch</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_nsclient_localbroadcasts" translatable="false">nsclient_localbroadcasts</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="openaps">OpenAPS</string>
|
||||
<string name="device">Device</string>
|
||||
|
@ -992,6 +985,7 @@
|
|||
<string name="overview_show_iob">Insulin On Board</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="key_fromNSAreCommingFakedExtendedBoluses" translatable="false">fromNSAreCommingFakedExtendedBoluses</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="pump_basebasalrate">%.2f U/h</string>
|
||||
|
|
|
@ -105,13 +105,6 @@
|
|||
validate:minNumber="1"
|
||||
validate:testType="floatNumericRange" />
|
||||
</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
|
||||
android:title="@string/bluetooth">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@ import static org.mockito.Mockito.when;
|
|||
*/
|
||||
|
||||
@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 {
|
||||
|
||||
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\"}";
|
||||
|
|
Loading…
Reference in a new issue