fix conflict

This commit is contained in:
Milos Kozak 2018-03-28 10:25:58 +02:00
commit fc2da20743
74 changed files with 1788 additions and 666 deletions

View file

@ -24,6 +24,7 @@ ext {
repositories {
maven { url 'https://maven.fabric.io/public' }
jcenter { url "https://jcenter.bintray.com/" }
}
def generateGitBuild = { ->
@ -62,7 +63,7 @@ android {
targetSdkVersion 23
multiDexEnabled true
versionCode 1500
version "1.60a-dev"
version "1.60b-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild()
@ -210,6 +211,7 @@ dependencies {
compile "com.google.guava:guava:20.0"
compile "net.danlew:android.joda:2.9.9.1"
compile "uk.com.robust-it:cloning:1.9.9"
compile 'org.mozilla:rhino:1.7.7.2'

View file

@ -24,7 +24,7 @@ public class Config {
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
public static final boolean displayDeviationSlope = true;
public static final boolean displayDeviationSlope = false;
public static final boolean detailedLog = true;
public static final boolean logFunctionCalls = true;

View file

@ -31,7 +31,6 @@ import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
@ -188,7 +187,7 @@ public class MainApp extends Application {
pluginsList.add(new PersistentNotificationPlugin(this));
pluginsList.add(NSClientPlugin.getPlugin());
pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin());
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
MainApp.getConfigBuilder().initialize();
}
@ -389,6 +388,8 @@ public class MainApp extends Application {
}
public static boolean isEngineeringModeOrRelease() {
if (!BuildConfig.APS)
return true;
return engineeringMode || !devBranch;
}

View file

@ -64,31 +64,31 @@ public class DataService extends IntentService {
if (Config.logFunctionCalls)
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
xDripEnabled = true;
nsClientEnabled = false;
mm640gEnabled = false;
glimpEnabled = false;
dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
xDripEnabled = false;
nsClientEnabled = true;
mm640gEnabled = false;
glimpEnabled = false;
dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
xDripEnabled = false;
nsClientEnabled = false;
mm640gEnabled = true;
glimpEnabled = false;
dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
xDripEnabled = false;
nsClientEnabled = false;
mm640gEnabled = false;
glimpEnabled = true;
dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
xDripEnabled = false;
nsClientEnabled = false;
mm640gEnabled = false;

View file

@ -4,9 +4,11 @@ import java.util.ArrayList;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
/**
* Created by mike on 19.03.2018.
@ -41,6 +43,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return isSMBModeEnabled(new Constraint<>(true));
}
public Constraint<Boolean> isAdvancedFilteringEnabled() {
return isAdvancedFilteringEnabled(new Constraint<>(true));
}
public Constraint<Double> getMaxBasalAllowed(Profile profile) {
return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile);
}
@ -121,6 +127,17 @@ public class ConstraintChecker implements ConstraintsInterface {
return value;
}
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue;
constraint.isAdvancedFilteringEnabled(value);
}
return value;
}
@Override
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);

View file

@ -2,6 +2,8 @@ package info.nightscout.androidaps.data;
import android.content.Context;
import com.rits.cloning.Cloner;
import org.json.JSONObject;
import java.util.Date;
@ -30,21 +32,22 @@ public class DetailedBolusInfo {
public long deliverAt = 0; // SMB should be delivered within 1 min from this time
public DetailedBolusInfo copy() {
DetailedBolusInfo copy = new DetailedBolusInfo();
copy.date = this.date;
copy.eventType = this.eventType;
copy.insulin = this.insulin;
copy.carbs = this.carbs;
copy.source = this.source;
copy.isValid = this.isValid;
copy.glucose = this.glucose;
copy.glucoseType = this.glucoseType;
copy.carbTime = this.carbTime;
copy.boluscalc = this.boluscalc;
copy.context = this.context;
copy.pumpId = this.pumpId;
copy.isSMB = this.isSMB;
return copy;
DetailedBolusInfo n = new DetailedBolusInfo();
n.date = date;
n.eventType = eventType;
n.insulin = insulin;
n.carbs = carbs;
n.source = source;
n.isValid = isValid;
n.glucose = glucose;
n.glucoseType = glucoseType;
n.carbTime = carbTime;
n.boluscalc = boluscalc;
n.context = context;
n.pumpId = pumpId;
n.isSMB = isSMB;
n.deliverAt = deliverAt;
return n;
}
@Override

View file

@ -21,6 +21,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.Round;
@ -40,17 +41,10 @@ public class GlucoseStatus {
@Override
public String toString() {
return MainApp.sResources.getString(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" +
MainApp.sResources.getString(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" +
MainApp.sResources.getString(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" +
MainApp.sResources.getString(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
}
public Spanned toSpanned() {
return Html.fromHtml("<b>" + MainApp.sResources.getString(R.string.glucose) + "</b>: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.delta) + "</b>: " + DecimalFormatter.to0Decimal(delta) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.short_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.long_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl");
return MainApp.gs(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" +
MainApp.gs(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" +
MainApp.gs(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" +
MainApp.gs(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
}
public GlucoseStatus() {
@ -75,11 +69,15 @@ public class GlucoseStatus {
@Nullable
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
// load 45min
long fromtime = (long) (System.currentTimeMillis() - 60 * 1000L * 45);
long fromtime = DateUtil.now() - 60 * 1000L * 45;
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
int sizeRecords = data.size();
if (sizeRecords < 1 || (data.get(0).date < System.currentTimeMillis() - 7 * 60 * 1000L && !allowOldData)) {
if (sizeRecords == 0) {
return null;
}
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
return null;
}
@ -87,13 +85,14 @@ public class GlucoseStatus {
long now_date = now.date;
double change;
if (sizeRecords < 2) {
if (sizeRecords == 1) {
GlucoseStatus status = new GlucoseStatus();
status.glucose = now.value;
status.short_avgdelta = 0d;
status.delta = 0d;
status.long_avgdelta = 0d;
status.avgdelta = 0d; // for OpenAPS MA
status.date = now_date;
return status.round();
}

View file

@ -16,7 +16,11 @@ import info.nightscout.androidaps.interfaces.Interval;
public abstract class Intervals<T extends Interval> {
LongSparseArray<T> rawData = new LongSparseArray<T>(); // oldest at index 0
LongSparseArray<T> rawData; // oldest at index 0
public Intervals() {
rawData = new LongSparseArray<T>();
}
public synchronized Intervals reset() {
rawData = new LongSparseArray<T>();
@ -27,8 +31,7 @@ public abstract class Intervals<T extends Interval> {
/**
* The List must be sorted by `T.start()` in ascending order
*
* */
*/
public synchronized void add(List<T> list) {
for (T interval : list) {
rawData.put(interval.start(), interval);
@ -36,6 +39,10 @@ public abstract class Intervals<T extends Interval> {
merge();
}
public synchronized void add(T interval) {
rawData.put(interval.start(), interval);
merge();
}
public synchronized List<T> getList() {
@ -86,5 +93,4 @@ public abstract class Intervals<T extends Interval> {
}
}

View file

@ -7,6 +7,16 @@ public class Iob {
public double iobContrib = 0d;
public double activityContrib = 0d;
public Iob iobContrib(double iobContrib) {
this.iobContrib = iobContrib;
return this;
}
public Iob activityContrib(double activityContrib) {
this.activityContrib = activityContrib;
return this;
}
public Iob plus(Iob iob) {
iobContrib += iob.iobContrib;
activityContrib += iob.activityContrib;

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.data;
import com.rits.cloning.Cloner;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
@ -35,20 +37,9 @@ public class IobTotal {
long time;
public IobTotal clone() {
IobTotal copy = new IobTotal(time);
copy.iob = iob;
copy.activity = activity;
copy.bolussnooze = bolussnooze;
copy.basaliob = basaliob;
copy.netbasalinsulin = netbasalinsulin;
copy.hightempinsulin = hightempinsulin;
copy.lastBolusTime = lastBolusTime;
copy.lastTempDate = lastTempDate;
copy.lastTempDuration = lastTempDuration;
copy.lastTempRate = lastTempRate;
copy.iobWithZeroTemp = iobWithZeroTemp;
return copy;
public IobTotal copy() {
Cloner cloner = new Cloner();
return cloner.deepClone(this);
}
public IobTotal(long time) {
@ -82,6 +73,8 @@ public class IobTotal {
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
result.lastBolusTime = bolusIOB.lastBolusTime;
result.lastTempDate = basalIob.lastTempDate;
result.lastTempRate = basalIob.lastTempRate;
@ -97,6 +90,8 @@ public class IobTotal {
this.basaliob = Round.roundTo(this.basaliob, 0.001);
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
this.netInsulin = Round.roundTo(this.netInsulin, 0.001);
this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001);
return this;
}

View file

@ -2,7 +2,9 @@ package info.nightscout.androidaps.data;
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Interval;
/**
@ -11,6 +13,14 @@ import info.nightscout.androidaps.interfaces.Interval;
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
public NonOverlappingIntervals() {
super();
}
public NonOverlappingIntervals (Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
@ -27,4 +37,5 @@ public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
if (index >= 0) return rawData.valueAt(index);
return null;
}
}

View file

@ -11,6 +11,14 @@ import info.nightscout.androidaps.interfaces.Interval;
public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
public OverlappingIntervals() {
super();
}
public OverlappingIntervals(Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() {
boolean needToCut = false;
long cutTime = 0;

View file

@ -22,7 +22,15 @@ import info.nightscout.utils.DateUtil;
public class ProfileIntervals<T extends Interval> {
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0
private LongSparseArray<T> rawData; // oldest at index 0
public ProfileIntervals () {
rawData = new LongSparseArray<>();
}
public ProfileIntervals (ProfileIntervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized ProfileIntervals reset() {
rawData = new LongSparseArray<>();
@ -30,9 +38,11 @@ public class ProfileIntervals<T extends Interval> {
}
public synchronized void add(T newInterval) {
if (newInterval.isValid()) {
rawData.put(newInterval.start(), newInterval);
merge();
}
}
public synchronized void add(List<T> list) {
for (T interval : list) {
@ -56,10 +66,12 @@ 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);
// if we request data older than first record, use oldest with zero duration instead
for (index = 0; index < rawData.size(); index++) {
if (rawData.valueAt(index).durationInMsec() == 0) {
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index);
}
}
return null;
}
@ -117,4 +129,9 @@ public class ProfileIntervals<T extends Interval> {
public synchronized T getReversed(int index) {
return rawData.valueAt(size() - 1 - index);
}
@Override
public String toString() {
return rawData.toString();
}
}

View file

@ -58,7 +58,7 @@ import info.nightscout.utils.PercentageSplitter;
/**
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
*
* <p>
* This class can safely be called from Services, but should not call Services to avoid circular dependencies.
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
@ -893,14 +893,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try {
String units = MainApp.getConfigBuilder().getProfileUnits();
TempTarget tempTarget = new TempTarget();
tempTarget.date = trJson.getLong("mills");
tempTarget.durationInMinutes = trJson.getInt("duration");
tempTarget.low = Profile.toMgdl(trJson.getDouble("targetBottom"), units);
tempTarget.high = Profile.toMgdl(trJson.getDouble("targetTop"), units);
tempTarget.reason = trJson.getString("reason");
tempTarget._id = trJson.getString("_id");
tempTarget.source = Source.NIGHTSCOUT;
TempTarget tempTarget = new TempTarget()
.date(trJson.getLong("mills"))
.duration(trJson.getInt("duration"))
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
.reason(trJson.getString("reason"))
._id(trJson.getString("_id"))
.source(Source.NIGHTSCOUT);
createOrUpdate(tempTarget);
} catch (JSONException e) {
log.error("Unhandled exception", e);
@ -1169,10 +1169,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
createOrUpdate(extendedBolus);
} else {
TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = trJson.getLong("mills");
tempBasal.source = Source.NIGHTSCOUT;
tempBasal.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0;
TemporaryBasal tempBasal = new TemporaryBasal()
.date(trJson.getLong("mills"))
.source(Source.NIGHTSCOUT)
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
if (trJson.has("duration")) {
tempBasal.durationInMinutes = trJson.getInt("duration");
}

View file

@ -61,6 +61,31 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
private Profile profile = null;
public ProfileSwitch date(long date) {
this.date = date;
return this;
}
public ProfileSwitch profileName(String profileName) {
this.profileName = profileName;
return this;
}
public ProfileSwitch profile(Profile profile) {
this.profile = profile;
return this;
}
public ProfileSwitch source(int source) {
this.source = source;
return this;
}
public ProfileSwitch duration(int duration) {
this.durationInMinutes = duration;
return this;
}
@Nullable
public Profile getProfileObject() {
if (profile == null)

View file

@ -71,6 +71,41 @@ public class TempTarget implements Interval {
reason = t.reason;
}
public TempTarget date(long date) {
this.date = date;
return this;
}
public TempTarget low(double low) {
this.low = low;
return this;
}
public TempTarget high(double high) {
this.high = high;
return this;
}
public TempTarget duration(int duration) {
this.durationInMinutes = duration;
return this;
}
public TempTarget reason(String reason) {
this.reason = reason;
return this;
}
public TempTarget _id(String _id) {
this._id = _id;
return this;
}
public TempTarget source(int source) {
this.source = source;
return this;
}
// -------- Interval interface ---------
Long cuttedEnd = null;

View file

@ -60,8 +60,36 @@ public class TemporaryBasal implements Interval {
public TemporaryBasal() {
}
public TemporaryBasal(long date) {
public TemporaryBasal date(long date) {
this.date = date;
return this;
}
public TemporaryBasal duration(int durationInMinutes) {
this.durationInMinutes = durationInMinutes;
return this;
}
public TemporaryBasal absolute(double absoluteRate) {
this.absoluteRate = absoluteRate;
this.isAbsolute = true;
return this;
}
public TemporaryBasal percent(int percentRate) {
this.percentRate = percentRate;
this.isAbsolute = false;
return this;
}
public TemporaryBasal source(int source) {
this.source = source;
return this;
}
public TemporaryBasal pumpId(long pumpId) {
this.pumpId = pumpId;
return this;
}
public TemporaryBasal(ExtendedBolus extendedBolus) {

View file

@ -128,7 +128,7 @@ public class Treatment implements DataPointWithLabelInterface {
@Override
public String getLabel() {
String label = "";
if (insulin > 0) label += DecimalFormatter.to2Decimal(insulin) + "U";
if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin) + "U";
if (carbs > 0)
label += "~" + DecimalFormatter.to0Decimal(carbs) + "g";
return label;
@ -149,7 +149,7 @@ public class Treatment implements DataPointWithLabelInterface {
@Override
public float getSize() {
return 10;
return 2;
}
@Override

View file

@ -27,6 +27,10 @@ public interface ConstraintsInterface {
return value;
}
default Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
return value;
}
default Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
return absoluteRate;
}

View file

@ -116,9 +116,14 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) {
tempTarget.setVisibility(View.GONE);
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
profileSwitch.setVisibility(View.VISIBLE);
} else {
profileSwitch.setVisibility(View.GONE);
}
if (MainApp.getConfigBuilder().getProfile() == null) {
tempTarget.setVisibility(View.GONE);
extendedBolus.setVisibility(View.GONE);
extendedBolusCancel.setVisibility(View.GONE);
tempBasal.setVisibility(View.GONE);
@ -126,6 +131,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
fill.setVisibility(View.GONE);
return;
}
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
&& pump.getPumpDescription().isSetBasalProfileCapable;

View file

@ -1,11 +1,11 @@
package info.nightscout.androidaps.plugins.Actions.dialogs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -13,17 +13,23 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Constants;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
@ -31,6 +37,7 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -38,13 +45,13 @@ import info.nightscout.utils.SafeParse;
public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
Button deliverButton;
double amount1 = 0d;
double amount2 = 0d;
double amount3 = 0d;
NumberPicker editInsulin;
CheckBox pumpSiteChangeCheckbox;
CheckBox insulinCartridgeChangeCheckbox;
public FillDialog() {
}
@ -54,22 +61,24 @@ public class FillDialog extends DialogFragment implements OnClickListener {
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fill_dialog, null, false);
deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
deliverButton.setOnClickListener(this);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
pumpSiteChangeCheckbox = view.findViewById(R.id.catheter_change);
insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false);
//setup preset buttons
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
View divider = view.findViewById(R.id.fill_preset_divider);
amount1 = SP.getDouble("fill_button1", 0.3);
amount2 = SP.getDouble("fill_button2", 0d);
@ -77,81 +86,85 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (amount1 > 0) {
button1.setVisibility(View.VISIBLE);
button1.setText(DecimalFormatter.to2Decimal(amount1) + "U");
button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
button1.setOnClickListener(this);
} else {
button1.setVisibility(View.GONE);
}
if (amount2 > 0) {
button2.setVisibility(View.VISIBLE);
button2.setText(DecimalFormatter.to2Decimal(amount2) + "U");
button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
button2.setOnClickListener(this);
} else {
button2.setVisibility(View.GONE);
}
if (amount3 > 0) {
button3.setVisibility(View.VISIBLE);
button3.setText(DecimalFormatter.to2Decimal(amount3) + "U");
button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
button3.setOnClickListener(this);
} else {
button3.setVisibility(View.GONE);
}
if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) {
divider.setVisibility(View.GONE);
}
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onResume() {
super.onResume();
if (getDialog() != null)
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.treatments_newtreatment_deliverbutton:
Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString());
confirmAndDeliver(insulin);
case R.id.ok:
confirmAndDeliver();
break;
case R.id.cancel:
dismiss();
break;
case R.id.fill_preset_button1:
confirmAndDeliver(amount1);
editInsulin.setValue(amount1);
break;
case R.id.fill_preset_button2:
confirmAndDeliver(amount2);
editInsulin.setValue(amount2);
break;
case R.id.fill_preset_button3:
confirmAndDeliver(amount3);
editInsulin.setValue(amount3);
break;
}
}
private void confirmAndDeliver(Double insulin) {
private void confirmAndDeliver() {
try {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
String confirmMessage = getString(R.string.fillwarning) + "\n";
List<String> confirmMessage = new LinkedList<>();
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U";
if (insulinAfterConstraints - insulin != 0)
confirmMessage += "\n" + getString(R.string.constraintapllied);
if (insulinAfterConstraints > 0) {
confirmMessage.add(MainApp.gs(R.string.fillwarning));
confirmMessage.add("");
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>");
if (!insulinAfterConstraints.equals(insulin))
confirmMessage.add("<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
}
if (pumpSiteChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_pump_site_change) + "</font>");
if (insulinCartridgeChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_insulin_cartridge_change) + "</font>");
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(this.getContext().getString(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (confirmMessage.isEmpty())
confirmMessage.add(MainApp.gs(R.string.no_action_selected));
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
@ -173,7 +186,9 @@ public class FillDialog extends DialogFragment implements OnClickListener {
});
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
}
}
long now = System.currentTimeMillis();
if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now);
if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000);
});
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();

View file

@ -51,13 +51,13 @@ import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
@ -108,6 +108,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
Date eventTime;
private static Integer seconds = null;
public void setOptions(OptionsToShow options, int event) {
this.options = options;
this.event = MainApp.sResources.getString(event);
@ -115,6 +117,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public NewNSTreatmentDialog() {
super();
if (seconds == null) {
seconds = new Double(Math.random() * 59).intValue();
}
}
@Override
@ -327,7 +333,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
}
};
Double maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
Double maxAbsolute = HardLimits.maxBasal();
if (profile != null)
maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher);
@ -340,19 +348,19 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift);
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false);
ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(DateUtil.now());
if (ps != null && ps.isCPP) {
final int percentage = ps.percentage;
final int timeshift = ps.timeshift;
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h");
reuseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
reuseButton.setOnClickListener(v -> {
editPercentage.setValue((double) percentage);
editTimeshift.setValue((double) timeshift);
}
});
}
if (ps == null) {
options.duration = false;
}
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
@ -440,7 +448,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
eventTime.setHours(hourOfDay);
eventTime.setMinutes(minute);
eventTime.setSeconds(second);
eventTime.setSeconds(this.seconds++); // randomize seconds to prevent creating record of the same time, if user choose time manually
timeButton.setText(DateUtil.timeString(eventTime));
updateBGforDateTime();
}
@ -692,17 +700,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} else if (options.executeTempTarget) {
try {
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = eventTime.getTime();
tempTarget.durationInMinutes = data.getInt("duration");
tempTarget.reason = data.getString("reason");
tempTarget.source = Source.USER;
TempTarget tempTarget = new TempTarget()
.date(eventTime.getTime())
.duration(data.getInt("duration"))
.reason(data.getString("reason"))
.source(Source.USER);
if (tempTarget.durationInMinutes != 0) {
tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits());
tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits());
tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()))
.high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()));
} else {
tempTarget.low = 0;
tempTarget.high = 0;
tempTarget.low(0).high(0);
}
log.debug("Creating new TempTarget db record: " + tempTarget.toString());
MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -17,11 +17,13 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.crashlytics.android.answers.CustomEvent;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.PreferencesActivity;
import info.nightscout.androidaps.R;
@ -35,6 +37,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin;
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
@ -43,33 +46,46 @@ import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.PasswordProtection;
public class ConfigBuilderFragment extends Fragment {
static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin();
static public ConfigBuilderPlugin getPlugin() {
return configBuilderPlugin;
}
public class ConfigBuilderFragment extends SubscriberFragment {
@BindView(R.id.configbuilder_insulinlistview)
ListView insulinListView;
@BindView(R.id.configbuilder_sensitivitylistview)
ListView sensitivityListView;
@BindView(R.id.configbuilder_bgsourcelistview)
ListView bgsourceListView;
@BindView(R.id.configbuilder_bgsourcelabel)
TextView bgsourceLabel;
@BindView(R.id.configbuilder_pumplistview)
ListView pumpListView;
@BindView(R.id.configbuilder_pumplabel)
TextView pumpLabel;
@BindView(R.id.configbuilder_looplistview)
ListView loopListView;
@BindView(R.id.configbuilder_looplabel)
TextView loopLabel;
@BindView(R.id.configbuilder_treatmentslistview)
ListView treatmentsListView;
@BindView(R.id.configbuilder_treatmentslabel)
TextView treatmentsLabel;
@BindView(R.id.configbuilder_profilelistview)
ListView profileListView;
@BindView(R.id.configbuilder_profilelabel)
TextView profileLabel;
@BindView(R.id.configbuilder_apslistview)
ListView apsListView;
@BindView(R.id.configbuilder_apslabel)
TextView apsLabel;
@BindView(R.id.configbuilder_constraintslistview)
ListView constraintsListView;
@BindView(R.id.configbuilder_constraintslabel)
TextView constraintsLabel;
@BindView(R.id.configbuilder_generallistview)
ListView generalListView;
@BindView(R.id.configbuilder_mainlayout)
LinearLayout mainLayout;
@BindView(R.id.configbuilder_unlock)
Button unlock;
PluginCustomAdapter insulinDataAdapter = null;
@ -84,51 +100,17 @@ public class ConfigBuilderFragment extends Fragment {
PluginCustomAdapter generalDataAdapter = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview);
sensitivityListView = (ListView) view.findViewById(R.id.configbuilder_sensitivitylistview);
bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview);
bgsourceLabel = (TextView) view.findViewById(R.id.configbuilder_bgsourcelabel);
pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview);
pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel);
loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview);
loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel);
treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview);
treatmentsLabel = (TextView) view.findViewById(R.id.configbuilder_treatmentslabel);
profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview);
profileLabel = (TextView) view.findViewById(R.id.configbuilder_profilelabel);
apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview);
apsLabel = (TextView) view.findViewById(R.id.configbuilder_apslabel);
constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview);
constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel);
generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview);
unbinder = ButterKnife.bind(this, view);
mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout);
unlock = (Button) view.findViewById(R.id.configbuilder_unlock);
setViews();
if (PasswordProtection.isLocked("settings_password")) {
if (PasswordProtection.isLocked("settings_password"))
mainLayout.setVisibility(View.GONE);
unlock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
@Override
public void run() {
mainLayout.setVisibility(View.VISIBLE);
else
unlock.setVisibility(View.GONE);
}
}, null);
}
});
} else {
unlock.setVisibility(View.GONE);
}
return view;
} catch (Exception e) {
FabricPrivacy.logException(e);
@ -137,7 +119,18 @@ public class ConfigBuilderFragment extends Fragment {
return null;
}
void setViews() {
@OnClick(R.id.configbuilder_unlock)
public void onClickUnlock() {
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
mainLayout.setVisibility(View.VISIBLE);
unlock.setVisibility(View.GONE);
}, null);
}
@Override
protected void updateGUI() {
insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN);
insulinListView.setAdapter(insulinDataAdapter);
setListViewHeightBasedOnChildren(insulinListView);
@ -182,7 +175,6 @@ public class ConfigBuilderFragment extends Fragment {
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL);
generalListView.setAdapter(generalDataAdapter);
setListViewHeightBasedOnChildren(generalListView);
}
/*
@ -194,7 +186,7 @@ public class ConfigBuilderFragment extends Fragment {
private ArrayList<PluginBase> pluginList;
final private int type;
public PluginCustomAdapter(Context context, int textViewResourceId,
PluginCustomAdapter(Context context, int textViewResourceId,
ArrayList<PluginBase> pluginList, int type) {
super(context, textViewResourceId, pluginList);
this.pluginList = new ArrayList<>();
@ -209,10 +201,11 @@ public class ConfigBuilderFragment extends Fragment {
ImageView settings;
}
@NonNull
@Override
public View getView(int position, View view, ViewGroup parent) {
public View getView(int position, View view, @NonNull ViewGroup parent) {
PluginViewHolder holder = null;
PluginViewHolder holder;
PluginBase plugin = pluginList.get(position);
if (view == null) {
@ -231,60 +224,45 @@ public class ConfigBuilderFragment extends Fragment {
view.setTag(holder);
holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
holder.checkboxEnabled.setOnClickListener(v -> {
CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag();
plugin.setPluginEnabled(type, cb.isChecked());
plugin.setFragmentVisible(type, cb.isChecked());
onEnabledCategoryChanged(plugin, type);
configBuilderPlugin.storeSettings();
PluginBase plugin1 = (PluginBase) cb.getTag();
plugin1.setPluginEnabled(type, cb.isChecked());
plugin1.setFragmentVisible(type, cb.isChecked());
onEnabledCategoryChanged(plugin1, type);
ConfigBuilderPlugin.getPlugin().storeSettings();
MainApp.bus().post(new EventRefreshGui());
MainApp.bus().post(new EventConfigBuilderChange());
getPlugin().logPluginStatus();
ConfigBuilderPlugin.getPlugin().logPluginStatus();
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
}
});
holder.checkboxVisible.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
holder.checkboxVisible.setOnClickListener(v -> {
CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag();
plugin.setFragmentVisible(type, cb.isChecked());
configBuilderPlugin.storeSettings();
PluginBase plugin12 = (PluginBase) cb.getTag();
plugin12.setFragmentVisible(type, cb.isChecked());
ConfigBuilderPlugin.getPlugin().storeSettings();
MainApp.bus().post(new EventRefreshGui());
getPlugin().logPluginStatus();
}
ConfigBuilderPlugin.getPlugin().logPluginStatus();
});
holder.settings.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final PluginBase plugin = (PluginBase) v.getTag();
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
@Override
public void run() {
holder.settings.setOnClickListener(v -> {
final PluginBase plugin13 = (PluginBase) v.getTag();
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
Intent i = new Intent(getContext(), PreferencesActivity.class);
i.putExtra("id", plugin.getPreferencesId());
i.putExtra("id", plugin13.getPreferencesId());
startActivity(i);
}
}, null);
}
});
holder.name.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final PluginBase plugin = (PluginBase) v.getTag();
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
@Override
public void run() {
holder.name.setOnLongClickListener(v -> {
final PluginBase plugin14 = (PluginBase) v.getTag();
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
Intent i = new Intent(getContext(), PreferencesActivity.class);
i.putExtra("id", plugin.getPreferencesId());
i.putExtra("id", plugin14.getPreferencesId());
startActivity(i);
}
}, null);
return false;
}
});
} else {
@ -317,7 +295,7 @@ public class ConfigBuilderFragment extends Fragment {
if (pluginList.size() < 2) {
holder.checkboxEnabled.setEnabled(false);
plugin.setPluginEnabled(type, true);
getPlugin().storeSettings();
ConfigBuilderPlugin.getPlugin().storeSettings();
}
// Constraints cannot be disabled
@ -396,17 +374,17 @@ public class ConfigBuilderFragment extends Fragment {
}
} else { // enable first plugin in list
if (type == PluginBase.PUMP)
MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setPluginEnabled(type, true);
VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.INSULIN)
MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setPluginEnabled(type, true);
InsulinFastactingPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.SENSITIVITY)
MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setPluginEnabled(type, true);
SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.PROFILE)
MainApp.getSpecificPlugin(NSProfilePlugin.class).setPluginEnabled(type, true);
NSProfilePlugin.getPlugin().setPluginEnabled(type, true);
else
pluginsInCategory.get(0).setPluginEnabled(type, true);
}
setViews();
updateGUI();
}
}

View file

@ -4,12 +4,15 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.CustomEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
@ -20,6 +23,7 @@ import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileIntervals;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ExtendedBolus;
@ -45,6 +49,7 @@ import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.ToastUtils;
@ -54,7 +59,15 @@ import info.nightscout.utils.ToastUtils;
public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class);
private static BgSourceInterface activeBgSource;
private static ConfigBuilderPlugin configBuilderPlugin;
static public ConfigBuilderPlugin getPlugin() {
if (configBuilderPlugin == null)
configBuilderPlugin = new ConfigBuilderPlugin();
return configBuilderPlugin;
}
private BgSourceInterface activeBgSource;
private static PumpInterface activePump;
private static ProfileInterface activeProfile;
private static TreatmentsInterface activeTreatments;
@ -193,7 +206,7 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
return commandQueue;
}
public static BgSourceInterface getActiveBgSource() {
public BgSourceInterface getActiveBgSource() {
return activeBgSource;
}
@ -653,11 +666,14 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
if (profileSwitch.profileJson != null) {
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
} else {
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
ProfileStore profileStore = activeProfile.getProfile();
if (profileStore != null) {
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
if (profile != null)
return profileSwitch.profileName;
}
}
}
return MainApp.gs(R.string.noprofileselected);
}
@ -692,6 +708,14 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
return profile;
}
}
if (getProfileSwitchesFromHistory().size() > 0) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("time", time)
.putCustomAttribute("getProfileSwitchesFromHistory", getProfileSwitchesFromHistory().toString())
);
}
log.debug("getProfile at the end: returning null");
return null;
}

View file

@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
@ -126,6 +128,21 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
boolean enabled = SP.getBoolean(R.string.key_use_smb, false);
if (!enabled)
value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this);
ConstraintChecker constraintChecker = MainApp.getConstraintChecker();
Constraint<Boolean> closedLoop = constraintChecker.isClosedLoopAllowed();
if (!closedLoop.value())
value.set(false, MainApp.gs(R.string.smbnotallowedinopenloopmode), this);
return value;
}
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource();
if (bgSource != null) {
if (!bgSource.advancedFilteringSupported())
value.set(false, MainApp.gs(R.string.smbalwaysdisabled), this);
}
return value;
}

View file

@ -64,7 +64,8 @@ public class AutosensData {
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public String log(long time) {
@Override
public String toString() {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ;
}

View file

@ -351,12 +351,11 @@ public class IobCobCalculatorPlugin implements PluginBase {
IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round();
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
// Add expected zere temp basal for next 240 mins
IobTotal basalIobWithZeroTemp = basalIob.clone();
TemporaryBasal t = new TemporaryBasal();
t.date = now + 60 * 1000L;
t.durationInMinutes = 240;
t.isAbsolute = true;
t.absoluteRate = 0;
IobTotal basalIobWithZeroTemp = basalIob.copy();
TemporaryBasal t = new TemporaryBasal()
.date(now + 60 * 1000L)
.duration(240)
.absolute(0);
if (t.date < time) {
IobTotal calc = t.iobCalc(time);
basalIobWithZeroTemp.plus(calc);

View file

@ -4,6 +4,9 @@ import android.content.Context;
import android.os.PowerManager;
import android.support.v4.util.LongSparseArray;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.CustomEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -11,6 +14,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
@ -22,6 +26,7 @@ import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.queue.QueueThread;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
/**
* Created by mike on 23.01.2018.
@ -151,8 +156,10 @@ public class IobCobThread extends Thread {
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
for (int past = 1; past < 12; past++) {
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
int past = 1;
try {
for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) {
@ -167,6 +174,17 @@ public class IobCobThread extends Thread {
//if (Config.logAutosensData)
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
}
} catch (Exception e) {
log.error("Unhandled exception", e);
FabricPrivacy.logException(e);
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString())
.putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
.putCustomAttribute("past", past)
);
}
}
}
@ -228,7 +246,7 @@ public class IobCobThread extends Thread {
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
if (Config.logAutosensData)
log.debug(autosensData.log(bgTime));
log.debug(autosensData.toString());
}
}
MainApp.bus().post(new EventAutosensCalculationFinished(cause));

View file

@ -62,7 +62,7 @@ public class APSResult {
// smb
if (smb != 0)
ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n");
ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U\n");
// reason
ret += MainApp.sResources.getString(R.string.reason) + ": " + reason;
@ -87,7 +87,7 @@ public class APSResult {
// smb
if (smb != 0)
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.to2Decimal(smb) + " U<br>");
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U<br>");
// reason
ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;");

View file

@ -46,6 +46,7 @@ public class DetermineBasalAdapterSMBJS {
private JSONObject mCurrentTemp;
private JSONObject mAutosensData = null;
private boolean mMicrobolusAllowed;
private boolean mSMBAlwaysAllowed;
private String storedCurrentTemp = null;
private String storedIobData = null;
@ -55,6 +56,7 @@ public class DetermineBasalAdapterSMBJS {
private String storedMeal_data = null;
private String storedAutosens_data = null;
private String storedMicroBolusAllowed = null;
private String storedSMBAlwaysAllowed = null;
private String scriptDebug = "";
@ -82,6 +84,7 @@ public class DetermineBasalAdapterSMBJS {
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
log.debug("Reservoir data: " + "undefined");
log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed));
log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed));
DetermineBasalResultSMB determineBasalResultSMB = null;
@ -210,7 +213,8 @@ public class DetermineBasalAdapterSMBJS {
MealData mealData,
double autosensDataRatio,
boolean tempTargetSet,
boolean microBolusAllowed
boolean microBolusAllowed,
boolean smbAlwaysAllowed
) throws JSONException {
String units = profile.getUnits();
@ -244,12 +248,11 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
boolean SMBEnabled = MainApp.getConstraintChecker().isSMBModeEnabled().value() && MainApp.getConstraintChecker().isClosedLoopAllowed().value();
mProfile.put("enableSMB_with_COB", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_COB, false));
mProfile.put("enableSMB_with_temptarget", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
mProfile.put("allowSMB_with_high_temptarget", SMBEnabled && SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false));
mProfile.put("enableSMB_always", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
mProfile.put("enableSMB_after_carbs", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false));
mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_enableSMB_always, false) && smbAlwaysAllowed);
mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && smbAlwaysAllowed);
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
@ -308,6 +311,7 @@ public class DetermineBasalAdapterSMBJS {
mAutosensData.put("ratio", 1.0);
}
mMicrobolusAllowed = microBolusAllowed;
mSMBAlwaysAllowed = smbAlwaysAllowed;
}

View file

@ -95,26 +95,26 @@ public class OpenAPSSMBFragment extends SubscriberFragment {
}
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
if (determineBasalAdapterSMBJS != null) {
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()));
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()));
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim());
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim());
try {
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
iobDataView.setText(String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0)));
iobDataView.setText((String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))).trim());
} catch (JSONException e) {
e.printStackTrace();
iobDataView.setText("JSONException");
log.error("Unhandled exception", e);
iobDataView.setText("JSONException see log for details");
}
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()));
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()));
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug());
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim());
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim());
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim());
if (lastAPSResult != null && lastAPSResult.inputConstraints != null)
constraintsView.setText(lastAPSResult.inputConstraints.getReasons());
constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim());
}
if (plugin.lastAPSRun != null) {
lastRunView.setText(plugin.lastAPSRun.toLocaleString());
lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim());
}
if (plugin.lastAutosensResult != null) {
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()));
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim());
}
}
});

View file

@ -231,6 +231,15 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
} else {
lastAutosensResult = new AutosensResult();
}
Constraint<Boolean> smbAllowed = new Constraint<>(true);
MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed);
inputConstraints.copyReasons(smbAllowed);
Constraint<Boolean> smbAlwaysEnabled = new Constraint<>(true);
MainApp.getConstraintChecker().isAdvancedFilteringEnabled(smbAlwaysEnabled);
inputConstraints.copyReasons(smbAlwaysEnabled);
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
Profiler.log(log, "SMB data gathering", start);
@ -239,7 +248,8 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio
isTempTarget,
true //microBolusAllowed
smbAllowed.value(),
smbAlwaysEnabled.value()
);
} catch (JSONException e) {
log.error(e.getMessage());

View file

@ -380,31 +380,31 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
accepted = true;
if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = finalActivityTTDuration;
tempTarget.reason = MainApp.gs(R.string.activity);
tempTarget.source = Source.USER;
tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalActivityTTDuration)
.reason(MainApp.gs(R.string.activity))
.source(Source.USER)
.low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = finalEatingSoonTTDuration;
tempTarget.reason = MainApp.gs(R.string.eatingsoon);
tempTarget.source = Source.USER;
tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalEatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startHypoTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = finalHypoTTDuration;
tempTarget.reason = MainApp.gs(R.string.hypo);
tempTarget.source = Source.USER;
tempTarget.low = Profile.toMgdl(finalHypoTT, currentProfile.getUnits());
tempTarget.high = Profile.toMgdl(finalHypoTT, currentProfile.getUnits());
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalHypoTTDuration)
.reason(MainApp.gs(R.string.hypo))
.source(Source.USER)
.low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget);
}

View file

@ -20,7 +20,6 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
@ -48,6 +47,8 @@ import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -124,7 +125,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
@ -160,7 +161,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
}
private String toSignedString(double value) {
return value > 0 ? "+" + value : String.valueOf(value);
String formatted = DecimalFormatter.toPumpSupportedBolus(value);
return value > 0 ? "+" + formatted : formatted;
}
@Override
@ -279,13 +281,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
accepted = true;
if (startESMCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = (int) ttDuration;
tempTarget.reason = "Eating soon";
tempTarget.source = Source.USER;
tempTarget.low = (int) finalTT;
tempTarget.high = (int) finalTT;
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration((int) ttDuration)
.reason("Eating soon")
.source(Source.USER)
.low((int) finalTT)
.high((int) finalTT);
MainApp.getDbHelper().createOrUpdate(tempTarget);
}
@ -319,7 +321,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
}
}
});
Answers.getInstance().logCustom(new CustomEvent("Bolus"));
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
}
}
});

View file

@ -243,7 +243,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, new DecimalFormat("0.00"), false, textWatcher);
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
initDialog();
@ -260,19 +260,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
private void saveCheckedStates() {
//SP.putBoolean(getString(R.string.key_wizard_include_bg), bgCheckbox.isChecked());
SP.putBoolean(getString(R.string.key_wizard_include_cob), cobCheckbox.isChecked());
SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked());
//SP.putBoolean(getString(R.string.key_wizard_include_bolus_iob), bolusIobCheckbox.isChecked());
//SP.putBoolean(getString(R.string.key_wizard_include_basal_iob), basalIobCheckbox.isChecked());
}
private void loadCheckedStates() {
//bgCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bg), true));
bgtrendCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_trend_bg), false));
cobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_cob), false));
//bolusIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bolus_iob), true));
//basalIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_basal_iob), true));
}
@Override
@ -461,7 +455,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double c_bg = SafeParse.stringToDouble(editBg.getText());
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
Double corrAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
Double corrAfterConstraint = c_correction;
if (c_correction > 0)
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
@ -534,7 +530,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U") : "";
String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.toPumpSupportedBolus(calculatedTotalInsulin) + "U") : "";
String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
okButton.setVisibility(View.VISIBLE);

View file

@ -288,13 +288,28 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
llm = new LinearLayoutManager(view.getContext());
notificationsView.setLayoutManager(llm);
int axisWidth = 50;
if (dm.densityDpi <= 120)
axisWidth = 3;
else if (dm.densityDpi <= 160)
axisWidth = 10;
else if (dm.densityDpi <= 320)
axisWidth = 35;
else if (dm.densityDpi <= 420)
axisWidth = 50;
else if (dm.densityDpi <= 560)
axisWidth = 70;
else
axisWidth = 80;
bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
bgGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
iobGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
@ -1166,7 +1181,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
extendedBolusView.setText(extendedBolusText);
}
if (extendedBolusText.equals(""))
extendedBolusView.setVisibility(View.GONE);
extendedBolusView.setVisibility(View.INVISIBLE);
else
extendedBolusView.setVisibility(View.VISIBLE);
}
@ -1194,7 +1209,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
quickWizardButton.setVisibility(View.VISIBLE);
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false);
text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U";
text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U";
quickWizardButton.setText(text);
if (wizard.calculatedTotalInsulin <= 0)
quickWizardButton.setVisibility(View.GONE);

View file

@ -48,11 +48,11 @@ import java.util.Iterator;
*/
public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> extends BaseSeries<E> {
// Default spSize
int spSize = 12;
int spSize = 14;
// Convert the sp to pixels
Context context = MainApp.instance().getApplicationContext();
float scaledTextSize = spSize * context.getResources().getDisplayMetrics().scaledDensity;
float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 1.5f;
float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 3f;
/**
* choose a predefined shape to render for
@ -233,9 +233,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
} else if (value.getShape() == Shape.SMB) {
mPaint.setStrokeWidth(2);
Point[] points = new Point[3];
points[0] = new Point((int)endX, (int)(endY-value.getSize()));
points[1] = new Point((int)(endX+value.getSize()), (int)(endY+value.getSize()*0.67));
points[2] = new Point((int)(endX-value.getSize()), (int)(endY+value.getSize()*0.67));
float size = value.getSize() * scaledPxSize;
points[0] = new Point((int)endX, (int)(endY-size));
points[1] = new Point((int)(endX+size), (int)(endY+size*0.67));
points[2] = new Point((int)(endX-size), (int)(endY+size*0.67));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint);
} else if (value.getShape() == Shape.EXTENDEDBOLUS) {

View file

@ -7,6 +7,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
@ -16,16 +17,19 @@ import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
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.Careportal.Dialogs.NewNSTreatmentDialog;
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 info.nightscout.utils.OKDialog;
import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;
@ -53,6 +57,8 @@ public class NSProfileFragment extends SubscriberFragment {
TextView target;
@BindView(R.id.basal_graph)
ProfileGraph basalGraph;
@BindView(R.id.nsprofile_profileswitch)
Button activateButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -79,13 +85,6 @@ public class NSProfileFragment extends SubscriberFragment {
@Override
protected void updateGUI() {
if (MainApp.getConfigBuilder().getProfile() == null) {
noProfile.setVisibility(View.VISIBLE);
return;
} else {
noProfile.setVisibility(View.GONE);
}
ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile();
if (profileStore != null) {
ArrayList<CharSequence> profileList = profileStore.getProfileList();
@ -97,6 +96,9 @@ public class NSProfileFragment extends SubscriberFragment {
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName()))
profileSpinner.setSelection(p);
}
noProfile.setVisibility(View.GONE);
} else {
noProfile.setVisibility(View.VISIBLE);
}
}
@ -117,10 +119,15 @@ public class NSProfileFragment extends SubscriberFragment {
target.setText(profile.getTargetList());
basalGraph.show(profile);
}
if (profile.isValid("NSProfileFragment"))
if (profile.isValid("NSProfileFragment")) {
invalidProfile.setVisibility(View.GONE);
else
activateButton.setVisibility(View.VISIBLE);
} else {
invalidProfile.setVisibility(View.VISIBLE);
activateButton.setVisibility(View.GONE);
}
} else {
activateButton.setVisibility(View.GONE);
}
}
@ -135,5 +142,20 @@ public class NSProfileFragment extends SubscriberFragment {
isf.setText("");
basal.setText("");
target.setText("");
activateButton.setVisibility(View.GONE);
}
@OnClick(R.id.nsprofile_profileswitch)
public void onClickProfileSwitch() {
String name = profileSpinner.getSelectedItem() != null ? profileSpinner.getSelectedItem().toString() : "";
ProfileStore store = NSProfilePlugin.getPlugin().getProfile();
if (store != null) {
Profile profile = store.getSpecificProfile(name);
if (profile != null) {
OKDialog.showConfirmation(getActivity(), MainApp.gs(R.string.activate_profile) + ": " + name + " ?", () ->
NewNSTreatmentDialog.doProfileSwitch(store, name, 0, 100, 0)
);
}
}
}
}

View file

@ -109,10 +109,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@NonNull
private static final ComboPump pump = new ComboPump();
/** This is used to determine when to pass a bolus cancel request to the scripter */
/**
* This is used to determine when to pass a bolus cancel request to the scripter
*/
private volatile boolean scripterIsBolusing;
/** This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)}
* will reset this flag. */
/**
* This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)}
* will reset this flag.
*/
private volatile boolean cancelBolus;
/**
@ -131,10 +135,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
*/
private volatile boolean pumpHistoryChanged = false;
/** Cache of the last <=2 boluses on the pump. Used to detect changes in pump history,
/**
* Cache of the last <=2 boluses on the pump. Used to detect changes in pump history,
* requiring reading pump more history. This is read/set in {@link #checkHistory()} when changed
* pump history was detected and was read, as well as in {@link #deliverBolus(DetailedBolusInfo)}
* after bolus delivery. Newest record is the first one. */
* after bolus delivery. Newest record is the first one.
*/
private volatile List<Bolus> recentBoluses = new ArrayList<>(0);
public static ComboPlugin getPlugin() {
@ -373,7 +379,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new Date(pump.lastSuccessfulCmdTime);
}
/** Runs pump initializing if needed and reads the pump state from the main screen. */
/**
* Runs pump initializing if needed and reads the pump state from the main screen.
*/
@Override
public synchronized void getPumpStatus() {
log.debug("getPumpStatus called");
@ -445,7 +453,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
MainApp.bus().post(new EventComboPumpUpdateGUI());
}
/** Updates local cache with state (reservoir level, last bolus ...) returned from the pump */
/**
* Updates local cache with state (reservoir level, last bolus ...) returned from the pump
*/
private void updateLocalData(CommandResult result) {
if (result.reservoirLevel != PumpState.UNKNOWN) {
pump.reservoirLevel = result.reservoirLevel;
@ -737,7 +747,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
cancelBolus = true;
}
/** Note: AAPS calls this solely to enact OpenAPS suggestions
/**
* Note: AAPS calls this solely to enact OpenAPS suggestions
*
* @param force the force parameter isn't used currently since we always set the tbr -
* there might be room for optimization to first test the currently running tbr
@ -804,12 +815,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
PumpState state = commandResult.state;
if (state.tbrActive && state.tbrPercent == adjustedPercent
&& (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) {
TemporaryBasal tempStart = new TemporaryBasal();
tempStart.date = state.timestamp;
tempStart.durationInMinutes = state.tbrRemainingDuration;
tempStart.percentRate = state.tbrPercent;
tempStart.isAbsolute = false;
tempStart.source = Source.USER;
TemporaryBasal tempStart = new TemporaryBasal()
.date(state.timestamp)
.duration(state.tbrRemainingDuration)
.percent(state.tbrPercent)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart);
MainApp.bus().post(new EventComboPumpUpdateGUI());
@ -825,7 +835,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return OPERATION_NOT_SUPPORTED;
}
/** Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED
/**
* Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED
* alert. This relies on TemporaryBasal objects to properly reflect the pumps state,
* which is ensured by {@link #checkAndResolveTbrMismatch(PumpState)}, which runs on each
* connect. When a hard cancel is requested, the pump is queried for it's TBR state to
@ -850,10 +861,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new PumpEnactResult().success(false).enacted(false);
}
if (!cancelResult.state.tbrActive) {
TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = cancelResult.state.timestamp;
tempBasal.durationInMinutes = 0;
tempBasal.source = Source.USER;
TemporaryBasal tempBasal = new TemporaryBasal()
.date(cancelResult.state.timestamp)
.duration(0)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
return new PumpEnactResult().isTempCancel(true).success(true).enacted(true);
} else {
@ -995,12 +1006,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now);
if (aapsTbr == null || aapsTbr.percentRate != 0) {
log.debug("Creating 15m zero temp since pump is suspended");
TemporaryBasal newTempBasal = new TemporaryBasal();
newTempBasal.date = now;
newTempBasal.percentRate = 0;
newTempBasal.isAbsolute = false;
newTempBasal.durationInMinutes = 15;
newTempBasal.source = Source.USER;
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(now)
.percent(0)
.duration(15)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
}
}
@ -1047,8 +1057,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
}
}
/** Check pump time (on the main menu) and raise notification if time is off.
* (setting clock is not supported by ruffy) */
/**
* Check pump time (on the main menu) and raise notification if time is off.
* (setting clock is not supported by ruffy)
*/
private void checkPumpTime(PumpState state) {
if (state.pumpTime == 0) {
// time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field)
@ -1124,12 +1136,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "new TBR on pump"));
TemporaryBasal newTempBasal = new TemporaryBasal();
newTempBasal.date = now;
newTempBasal.percentRate = state.tbrPercent;
newTempBasal.isAbsolute = false;
newTempBasal.durationInMinutes = state.tbrRemainingDuration;
newTempBasal.source = Source.USER;
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(now)
.percent(state.tbrPercent)
.duration(state.tbrRemainingDuration)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
} else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) {
log.debug("Ending AAPS-TBR since pump has no TBR active");
@ -1137,10 +1148,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR cancelled on pump"));
TemporaryBasal tempStop = new TemporaryBasal();
tempStop.date = now;
tempStop.durationInMinutes = 0;
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal()
.date(now)
.duration(0)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
} else if (aapsTbr != null && state.tbrActive
&& (aapsTbr.percentRate != state.tbrPercent ||
@ -1150,23 +1161,24 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR on pump differs from AAPS TBR"));
TemporaryBasal tempStop = new TemporaryBasal();
tempStop.date = now - 1000;
tempStop.durationInMinutes = 0;
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal()
.date(now - 1000)
.duration(0)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
TemporaryBasal newTempBasal = new TemporaryBasal();
newTempBasal.date = now;
newTempBasal.percentRate = state.tbrPercent;
newTempBasal.isAbsolute = false;
newTempBasal.durationInMinutes = state.tbrRemainingDuration;
newTempBasal.source = Source.USER;
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(now)
.percent(state.tbrPercent)
.duration(state.tbrRemainingDuration)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
}
}
/**Reads the pump's history and updates the DB accordingly. */
/**
* Reads the pump's history and updates the DB accordingly.
*/
private boolean readHistory(@Nullable PumpHistoryRequest request) {
CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request));
if (!historyResult.success) {
@ -1203,7 +1215,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return updated;
}
/** Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same
/**
* Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same
* minute. Best effort, since this covers only boluses up to 6.0 U and relies on other code
* to prevent a boluses with the same amount to be delivered within the same minute.
* Should be good enough, even with command mode, it's a challenge to create that situation

View file

@ -10,7 +10,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;

View file

@ -68,33 +68,29 @@ public class MsgStatusTempBasal extends MessageBase {
if (danaRPump.isTempBasalInProgress) {
if (tempBasal.percentRate != danaRPump.tempBasalPercent) {
// Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(danaRPump.tempBasalStart.getTime() - 1000);
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart.getTime() - 1000).source(Source.USER);
treatmentsInterface.addToHistoryTempBasal(tempStop);
// Create new
TemporaryBasal newTempBasal = new TemporaryBasal();
newTempBasal.date = danaRPump.tempBasalStart.getTime();
newTempBasal.percentRate = danaRPump.tempBasalPercent;
newTempBasal.isAbsolute = false;
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60;
newTempBasal.source = Source.USER;
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(danaRPump.tempBasalStart.getTime())
.percent(danaRPump.tempBasalPercent)
.duration(danaRPump.tempBasalTotalSec / 60)
.source(Source.USER);
treatmentsInterface.addToHistoryTempBasal(newTempBasal);
}
} else {
// Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(now);
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal().date(now).source(Source.USER);
treatmentsInterface.addToHistoryTempBasal(tempStop);
}
} else {
if (danaRPump.isTempBasalInProgress) {
// Create new
TemporaryBasal newTempBasal = new TemporaryBasal();
newTempBasal.date = danaRPump.tempBasalStart.getTime();
newTempBasal.percentRate = danaRPump.tempBasalPercent;
newTempBasal.isAbsolute = false;
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60;
newTempBasal.source = Source.USER;
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(danaRPump.tempBasalStart.getTime())
.percent(danaRPump.tempBasalPercent)
.duration(danaRPump.tempBasalTotalSec / 60)
.source(Source.USER);
treatmentsInterface.addToHistoryTempBasal(newTempBasal);
}
}

View file

@ -85,10 +85,7 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet {
int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF);
int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF);
TemporaryBasal temporaryBasal = new TemporaryBasal();
temporaryBasal.date = datetime.getTime();
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = datetime.getTime();
TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime.getTime()).source(Source.PUMP).pumpId(datetime.getTime());
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime();

View file

@ -56,10 +56,10 @@ public class MsgHistoryEvents_v2 extends MessageBase {
int param1 = intFromBuff(bytes, 7, 2);
int param2 = intFromBuff(bytes, 9, 2);
TemporaryBasal temporaryBasal = new TemporaryBasal();
temporaryBasal.date = datetime.getTime();
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = datetime.getTime();
TemporaryBasal temporaryBasal = new TemporaryBasal()
.date(datetime.getTime())
.source(Source.PUMP)
.pumpId(datetime.getTime());
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime();

View file

@ -592,12 +592,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) {
// create log entry
final TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = System.currentTimeMillis();
tempBasal.isAbsolute = false;
tempBasal.percentRate = percent_amount;
tempBasal.durationInMinutes = durationInMinutes;
tempBasal.source = Source.USER;
final TemporaryBasal tempBasal = new TemporaryBasal()
.date(System.currentTimeMillis())
.percent(percent_amount)
.duration(durationInMinutes)
.source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
}
@ -643,12 +642,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) {
// create log entry
final TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = System.currentTimeMillis();
tempBasal.isAbsolute = false;
tempBasal.percentRate = percent;
tempBasal.durationInMinutes = durationInMinutes;
tempBasal.source = Source.USER; // TODO check this is correct
final TemporaryBasal tempBasal = new TemporaryBasal()
.date(System.currentTimeMillis())
.percent(percent)
.duration(durationInMinutes)
.source(Source.USER); // TODO check this is correct
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
}
@ -683,13 +681,10 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
}
// TODO isn't conditional on one apparently being in progress only the history change
boolean enacted = false;
final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME);
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
enacted = true;
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis());
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
}
lastDataTime = new Date();

View file

@ -10,9 +10,8 @@ import info.nightscout.androidaps.db.TemporaryBasal;
/**
* Created by jamorham on 27/01/2018.
*
* <p>
* Write to the History Log
*
*/
class HistoryLogAdapter {
@ -25,7 +24,7 @@ class HistoryLogAdapter {
void createTBRrecord(Date eventDate, int percent, int duration, long record_id) {
TemporaryBasal temporaryBasal = new TemporaryBasal(eventDate.getTime());
TemporaryBasal temporaryBasal = new TemporaryBasal().date(eventDate.getTime());
final TemporaryBasal temporaryBasalFromHistory = MainApp.getConfigBuilder().getTempBasalFromHistory(eventDate.getTime());
@ -50,10 +49,10 @@ class HistoryLogAdapter {
}
}
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = record_id;
temporaryBasal.percentRate = percent;
temporaryBasal.durationInMinutes = duration;
temporaryBasal.source(Source.PUMP)
.pumpId(record_id)
.percent(percent)
.duration(duration);
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal);
}

View file

@ -98,7 +98,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.01d;
pumpDescription.isRefillingCapable = false;
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = false;
pumpDescription.is30minBasalRatesCapable = true;
@ -291,12 +291,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) {
TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder();
TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = System.currentTimeMillis();
tempBasal.isAbsolute = true;
tempBasal.absoluteRate = absoluteRate;
tempBasal.durationInMinutes = durationInMinutes;
tempBasal.source = Source.USER;
TemporaryBasal tempBasal = new TemporaryBasal()
.date(System.currentTimeMillis())
.absolute(absoluteRate)
.duration(durationInMinutes)
.source(Source.USER);
PumpEnactResult result = new PumpEnactResult();
result.success = true;
result.enacted = true;
@ -321,12 +320,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
if (!result.success)
return result;
}
TemporaryBasal tempBasal = new TemporaryBasal();
tempBasal.date = System.currentTimeMillis();
tempBasal.isAbsolute = false;
tempBasal.percentRate = percent;
tempBasal.durationInMinutes = durationInMinutes;
tempBasal.source = Source.USER;
TemporaryBasal tempBasal = new TemporaryBasal()
.date(System.currentTimeMillis())
.percent(percent)
.duration(durationInMinutes)
.source(Source.USER);
result.success = true;
result.enacted = true;
result.percent = percent;
@ -376,8 +374,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (treatmentsInterface.isTempBasalInProgress()) {
result.enacted = true;
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis());
tempStop.source = Source.USER;
TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
treatmentsInterface.addToHistoryTempBasal(tempStop);
//tempBasal = null;
if (Config.logPumpComm)

View file

@ -57,7 +57,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
private IobTotal lastTreatmentCalculation;
private IobTotal lastTempBasalsCalculation;
public static List<Treatment> treatments;
private final static ArrayList<Treatment> treatments = new ArrayList<>();
private final static Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>();
private final static Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>();
private final static Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
@ -146,8 +146,10 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia();
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false);
synchronized (treatments) {
treatments.clear();
treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false));
}
}
private static void initializeTempBasalData() {
@ -202,6 +204,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
double dia = profile.getDia();
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid) continue;
@ -220,6 +223,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
total.bolussnooze += bIOB.iobContrib;
}
}
}
if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses())
synchronized (extendedBoluses) {
@ -248,6 +252,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
long now = System.currentTimeMillis();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue();
synchronized (treatments) {
for (Treatment treatment : treatments) {
if (!treatment.isValid)
continue;
@ -262,6 +267,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
}
}
}
}
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("getMealData()");
if (autosensData != null) {
@ -275,12 +281,15 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public List<Treatment> getTreatmentsFromHistory() {
return treatments;
synchronized (treatments) {
return (List<Treatment>) treatments.clone();
}
}
@Override
public List<Treatment> getTreatments5MinBackFromHistory(long time) {
List<Treatment> in5minback = new ArrayList<>();
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos);
if (!t.isValid)
@ -290,15 +299,18 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
}
return in5minback;
}
}
@Override
public long getLastBolusTime() {
long now = System.currentTimeMillis();
long last = 0;
synchronized (treatments) {
for (Treatment t : treatments) {
if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now)
last = t.date;
}
}
log.debug("Last bolus time: " + new Date(last).toLocaleString());
return last;
}
@ -425,14 +437,14 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public Intervals<ExtendedBolus> getExtendedBolusesFromHistory() {
synchronized (extendedBoluses) {
return extendedBoluses;
return new NonOverlappingIntervals<>(extendedBoluses);
}
}
@Override
public Intervals<TemporaryBasal> getTemporaryBasalsFromHistory() {
synchronized (tempBasals) {
return tempBasals;
return new NonOverlappingIntervals<>(tempBasals);
}
}
@ -514,7 +526,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public Intervals<TempTarget> getTempTargetsFromHistory() {
synchronized (tempTargets) {
return tempTargets;
return new OverlappingIntervals<>(tempTargets);
}
}
@ -534,7 +546,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override
public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() {
synchronized (profiles) {
return profiles;
return new ProfileIntervals<>(profiles);
}
}

View file

@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.utils.Round;
/**
* Created by Adrian on 15.04.2018.
@ -48,7 +49,7 @@ public class ProfileGraph extends GraphView {
getViewport().setYAxisBoundsManual(true);
getViewport().setMinY(0);
getViewport().setMaxY(profile.getMaxDailyBasal()*1.1);
getViewport().setMaxY(Round.ceilTo(profile.getMaxDailyBasal()*1.1, 0.5));
getGridLabelRenderer().setNumHorizontalLabels(13);
getGridLabelRenderer().setVerticalLabelsColor(basalSeries.getColor());

View file

@ -76,7 +76,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
return;
Treatment t = treatments.get(position);
holder.date.setText(DateUtil.dateAndTimeString(t.date));
holder.insulin.setText(DecimalFormatter.to2Decimal(t.insulin) + " U");
holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(t.insulin) + " U");
holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g");
Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia());
holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U");
@ -176,7 +176,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.treatments);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory());
recyclerView.setAdapter(adapter);
iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal);
@ -232,7 +232,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.treatments), false);
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false);
if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) {
iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U");
activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U");

View file

@ -80,7 +80,7 @@ public class TreatmentsExtendedBolusesFragment extends SubscriberFragment {
holder.date.setText(DateUtil.dateAndTimeString(extendedBolus.date) + " - " + DateUtil.timeString(extendedBolus.end()));
}
holder.duration.setText(DecimalFormatter.to0Decimal(extendedBolus.durationInMinutes) + " min");
holder.insulin.setText(DecimalFormatter.to2Decimal(extendedBolus.insulin) + " U");
holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(extendedBolus.insulin) + " U");
holder.realDuration.setText(DecimalFormatter.to0Decimal(extendedBolus.getRealDuration()) + " min");
IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis());
holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U");

View file

@ -100,7 +100,11 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%");
}
holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration()) + " min");
IobTotal iob = tempBasal.iobCalc(System.currentTimeMillis());
IobTotal iob = new IobTotal(System.currentTimeMillis());
try { // in case app loaded and still no profile selected
iob = tempBasal.iobCalc(System.currentTimeMillis());
} catch (Exception e) {
}
holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob) + " U");
holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U");
holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h");

View file

@ -604,17 +604,15 @@ public class ActionStringHandler {
}
private static void generateTempTarget(int duration, double low, double high) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = duration;
tempTarget.reason = "WearPlugin";
tempTarget.source = Source.USER;
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(duration)
.reason("WearPlugin")
.source(Source.USER);
if (tempTarget.durationInMinutes != 0) {
tempTarget.low = low;
tempTarget.high = high;
tempTarget.low(low).high(high);
} else {
tempTarget.low = 0;
tempTarget.high = 0;
tempTarget.low(0).high(0);
}
MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -159,5 +159,8 @@ public class DateUtil {
return timeFrameString(timestamp - System.currentTimeMillis());
}
public static long now() {
return System.currentTimeMillis();
}
}

View file

@ -2,6 +2,8 @@ package info.nightscout.utils;
import java.text.DecimalFormat;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
/**
* Created by mike on 11.07.2016.
*/
@ -26,4 +28,16 @@ public class DecimalFormatter {
public static String to3Decimal(double value) {
return format3dec.format(value);
}
public static String toPumpSupportedBolus(double value) {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01
? to2Decimal(value)
: to1Decimal(value);
}
public static DecimalFormat pumpSupportedBolusFormat() {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01
? new DecimalFormat("0.00")
: new DecimalFormat("0.0");
}
}

View file

@ -140,7 +140,7 @@ public class NSUpload {
data.put("splitNow", 0);
data.put("splitExt", 100);
data.put("enteredinsulin", extendedBolus.insulin);
data.put("relative", extendedBolus.insulin);
data.put("relative", extendedBolus.insulin / extendedBolus.durationInMinutes * 60); // U/h
if (extendedBolus.pumpId != 0)
data.put("pumpId", extendedBolus.pumpId);
data.put("created_at", DateUtil.toISOString(extendedBolus.date));
@ -475,6 +475,27 @@ public class NSUpload {
}
}
public static void uploadEvent(String careportalEvent, long time) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
JSONObject data = new JSONObject();
try {
data.put("eventType", careportalEvent);
data.put("created_at", DateUtil.toISOString(time));
data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name)));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString());
}
public static void removeFoodFromNS(String _id) {
try {
Context context = MainApp.instance().getApplicationContext();

View file

@ -61,4 +61,19 @@ public class OKDialog {
log.debug("show_dialog exception: " + e);
}
}
public static void showConfirmation(final Activity activity, String message, final Runnable runnable) {
AlertDialog alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme))
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
dialog.dismiss();
if (runnable != null) {
SystemClock.sleep(100);
activity.runOnUiThread(runnable);
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
}

View file

@ -0,0 +1,59 @@
package info.nightscout.utils;
/**
* Created by mike on 26.03.2018.
*/
public class T {
private long time; // in msec
public static T msecs(long msec) {
T t = new T();
t.time = msec;
return t;
}
public static T secs(long sec) {
T t = new T();
t.time = sec * 1000L;
return t;
}
public static T mins(long min) {
T t = new T();
t.time = min * 60 * 1000L;
return t;
}
public static T hours(long hour) {
T t = new T();
t.time = hour * 60 * 60 * 1000L;
return t;
}
public static T days(long day) {
T t = new T();
t.time = day * 24 * 60 * 60 * 1000L;
return t;
}
public long msecs() {
return time;
}
public long secs() {
return time / 1000L;
}
public long mins() {
return time / 60 / 1000L;
}
public long hours() {
return time / 60 / 60 / 1000L;
}
public long days() {
return time / 24 / 60 / 60 / 1000L;
}
}

View file

@ -1,110 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:padding="10dp">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/careportal_newnstreatment_insulin_layout"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="vertical"
android:focusableInTouchMode="true"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:width="120dp"
android:padding="10dp"
android:text="@string/treatments_newtreatment_insulinamount_label"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:textStyle="bold" />
android:padding="5dp"
android:text="@string/primefill"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorInsulinButton" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:padding="5dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/icon_cp_pump_canula" />
<LinearLayout
android:id="@+id/careportal_newnstreatment_insulin_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
<CheckBox
android:id="@+id/catheter_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="Pump site change" />
<CheckBox
android:id="@+id/cartridge_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:text="Insulin cartridge change" />
<info.nightscout.utils.NumberPicker
android:id="@+id/treatments_newtreatment_insulinamount"
android:layout_width="130dp"
android:layout_height="40dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:text="U"
android:textAppearance="?android:attr/textAppearanceSmall" />
android:layout_height="40dp"
android:layout_gravity="end"
android:layout_marginBottom="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/treatments_newtreatment_deliverbutton"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="@string/primefill"
android:textSize="20sp" />
</LinearLayout>
<View
android:id="@+id/fill_preset_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal">
android:layout_height="match_parent"
android:layout_marginTop="5dp">
<Button
android:id="@+id/fill_preset_button1"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:padding="10dp"
android:text="0.3U"
android:textSize="20sp" />
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.3U" />
<Button
android:id="@+id/fill_preset_button2"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:padding="10dp"
android:text="0.7U"
android:textSize="20sp" />
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.7U" />
<Button
android:id="@+id/fill_preset_button3"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:padding="10dp"
android:text="1.2U"
android:textSize="20sp" />
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1.2U" />
</LinearLayout>
<include layout="@layout/mdtp_done_button" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -101,7 +101,7 @@
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/icon_actions_refill"
android:drawableTop="@drawable/icon_cp_pump_canula"
android:text="@string/primefill" />
</LinearLayout>

View file

@ -14,4 +14,14 @@
layout="@layout/profileviewer_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/nsprofile_profileswitch"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/activate_profile"
android:textColor="@color/colorProfileSwitchButton" />
</LinearLayout>

View file

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -11,7 +9,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"

View file

@ -990,5 +990,9 @@
<string name="unsafeusage">unsafe usage</string>
<string name="key_openapsama_useautosens" translatable="false">openapsama_useautosens</string>
<string name="readstatusfailed">Read status failed</string>
<string name="record_pump_site_change">Record pump site change</string>
<string name="record_insulin_cartridge_change">Record insulin cartridge change</string>
<string name="smbalwaysdisabled">SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering</string>
<string name="smbnotallowedinopenloopmode">SMB not allowed in open loop mode</string>
</resources>

View file

@ -13,7 +13,9 @@ import java.util.Locale;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.utils.SP;
@ -56,6 +58,14 @@ public class AAPSMocker {
when(MainApp.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable");
when(MainApp.gs(R.string.loop)).thenReturn("Loop");
when(MainApp.gs(R.string.loop_shortname)).thenReturn("LOOP");
when(MainApp.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering");
when(MainApp.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode");
when(MainApp.gs(R.string.Glimp)).thenReturn("Glimp");
when(MainApp.gs(R.string.glucose)).thenReturn("Glucose");
when(MainApp.gs(R.string.delta)).thenReturn("Delta");
when(MainApp.gs(R.string.short_avgdelta)).thenReturn("Short avg. delta");
when(MainApp.gs(R.string.long_avgdelta)).thenReturn("Long avg. delta");
when(MainApp.gs(R.string.zerovalueinprofile)).thenReturn("Invalid profile: %s");
}
public static MainApp mockMainApp() {
@ -71,6 +81,11 @@ public class AAPSMocker {
when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin);
}
public static void mockConstraintsChecker() {
ConstraintChecker constraintChecker = mock(ConstraintChecker.class);
when(MainApp.getConstraintChecker()).thenReturn(constraintChecker);
}
public static void mockBus() {
Bus bus = PowerMockito.mock(Bus.class);
when(MainApp.bus()).thenReturn(bus);
@ -88,9 +103,16 @@ public class AAPSMocker {
when(MainApp.instance().getApplicationContext()).thenReturn(context);
}
public static Profile getValidProfile() throws JSONException {
public static void mockDatabaseHelper() {
DatabaseHelper databaseHelper = mock(DatabaseHelper.class);
when(MainApp.getDbHelper()).thenReturn(databaseHelper);
}
public static Profile getValidProfile() {
try {
if (profile == null)
profile = new Profile(new JSONObject(validProfile), Constants.MGDL);
} catch (JSONException e) {}
return profile;
}
}

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.data;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class DetailedBolusInfoTest {
@Test
public void toStringShouldBeOverloaded() {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
Assert.assertEquals(true, detailedBolusInfo.toString().contains("insulin"));
}
@Test
public void copyShouldCopyAllProperties() {
DetailedBolusInfo d1 = new DetailedBolusInfo();
d1.deliverAt = 123;
DetailedBolusInfo d2 = d1.copy();
Assert.assertEquals(true, EqualsBuilder.reflectionEquals(d2, d1));
}
}

View file

@ -0,0 +1,184 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Before;
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 java.util.ArrayList;
import java.util.List;
import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.powermock.api.mockito.PowerMockito.when;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, DatabaseHelper.class, DateUtil.class})
public class GlucoseStatusTest {
@Test
public void toStringShouldBeOverloaded() {
GlucoseStatus glucoseStatus = new GlucoseStatus();
Assert.assertEquals(true, glucoseStatus.toString().contains("Delta"));
}
@Test
public void roundtest() {
GlucoseStatus glucoseStatus = new GlucoseStatus();
glucoseStatus.glucose = 100.11111;
Assert.assertEquals(100.1, glucoseStatus.round().glucose, 0.0001);
}
@Test
public void calculateValidGlucoseStatus() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateValidBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(214d, glucoseStatus.glucose, 0.001d);
Assert.assertEquals(-2d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(-2.5d, glucoseStatus.short_avgdelta, 0.001d); // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(-2.5d, glucoseStatus.avgdelta, 0.001d); // the same as short_avgdelta
Assert.assertEquals(-2d, glucoseStatus.long_avgdelta, 0.001d); // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date); // latest date
}
@Test
public void calculateMostRecentGlucoseStatus() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateMostRecentBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(215d, glucoseStatus.glucose, 0.001d); // (214+216) / 2
Assert.assertEquals(-1.25d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(-1.25d, glucoseStatus.short_avgdelta, 0.001d);
Assert.assertEquals(-1.25d, glucoseStatus.avgdelta, 0.001d);
Assert.assertEquals(0d, glucoseStatus.long_avgdelta, 0.001d);
Assert.assertEquals(1514766850000L, glucoseStatus.date); // date is average too
}
@Test
public void oneRecordShouldProduceZeroDeltas() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOneCurrentRecordBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(214d, glucoseStatus.glucose, 0.001d);
Assert.assertEquals(0d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(0d, glucoseStatus.short_avgdelta, 0.001d); // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(0d, glucoseStatus.avgdelta, 0.001d); // the same as short_avgdelta
Assert.assertEquals(0d, glucoseStatus.long_avgdelta, 0.001d); // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date); // latest date
}
@Test
public void insuffientDataShouldReturnNull() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateInsufficientBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(null, glucoseStatus);
}
@Test
public void oldDataShouldReturnNull() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOldBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(null, glucoseStatus);
}
@Test
public void returnOldDataIfAllowed() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOldBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(true);
Assert.assertNotEquals(null, glucoseStatus);
}
@Test
public void averageShouldNotFailOnEmptyArray() {
Assert.assertEquals(0d, GlucoseStatus.average(new ArrayList<>()), 0.001d);
}
@Before
public void initMocking() {
AAPSMocker.mockMainApp();
AAPSMocker.mockStrings();
AAPSMocker.mockDatabaseHelper();
PowerMockito.mockStatic(DateUtil.class);
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
}
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
List<BgReading> generateValidBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}")))); // +2
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":219,\"mills\":1514766300000,\"direction\":\"Flat\"}")))); // +3
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":223,\"mills\":1514766000000,\"direction\":\"Flat\"}")))); // +4
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":222,\"mills\":1514765700000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":224,\"mills\":1514765400000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateMostRecentBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766800000,\"direction\":\"Flat\"}")))); // +2
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateInsufficientBgData() {
List<BgReading> list = new ArrayList<>();
return list;
}
List<BgReading> generateOldBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateOneCurrentRecordBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
}

View file

@ -0,0 +1,41 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 27.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class IobTest {
@Test
public void plusTest() {
Iob a = new Iob().iobContrib(1).activityContrib(2);
Iob b = new Iob().iobContrib(3).activityContrib(4);
a.plus(b);
Assert.assertEquals(4d, a.iobContrib, 0.01d);
Assert.assertEquals(6d, a.activityContrib, 0.01d);
}
@Test
public void equalTest() {
Iob a1 = new Iob().iobContrib(1).activityContrib(2);
Iob a2 = new Iob().iobContrib(1).activityContrib(2);
Iob b = new Iob().iobContrib(3).activityContrib(4);
Assert.assertEquals(true, a1.equals(a1));
Assert.assertEquals(true, a1.equals(a2));
Assert.assertEquals(false, a1.equals(b));
Assert.assertEquals(false, a1.equals(null));
Assert.assertEquals(false, a1.equals(new Object()));
}
@Test
public void hashCodeTest() {
Iob a = new Iob().iobContrib(1).activityContrib(2);
Assert.assertNotEquals(0, a.hashCode());
}
}

View file

@ -0,0 +1,144 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.utils.DateUtil;
/**
* Created by mike on 27.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class IobTotalTest {
long now = DateUtil.now();
@Test
public void copytest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
IobTotal b = a.copy();
Assert.assertEquals(a.iob, b.iob, 0.01d);
}
@Test
public void plusTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 10;
a.bolussnooze = 10;
a.basaliob = 10;
a.netbasalinsulin = 10;
a.hightempinsulin = 10;
a.netInsulin = 10;
a.extendedBolusInsulin = 10;
a.plus(a.copy());
Assert.assertEquals(20, a.iob, 0.01d);
Assert.assertEquals(20, a.activity, 0.01d);
Assert.assertEquals(20, a.bolussnooze, 0.01d);
Assert.assertEquals(20, a.basaliob, 0.01d);
Assert.assertEquals(20, a.netbasalinsulin, 0.01d);
Assert.assertEquals(20, a.hightempinsulin, 0.01d);
Assert.assertEquals(20, a.netInsulin, 0.01d);
Assert.assertEquals(20, a.extendedBolusInsulin, 0.01d);
}
@Test
public void combineTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
IobTotal b = a.copy();
IobTotal c = IobTotal.combine(a, b);
Assert.assertEquals(a.time, c.time, 0.01d);
Assert.assertEquals(23, c.iob, 0.01d);
Assert.assertEquals(22, c.activity, 0.01d);
Assert.assertEquals(12, c.bolussnooze, 0.01d);
Assert.assertEquals(26, c.basaliob, 0.01d);
Assert.assertEquals(28, c.netbasalinsulin, 0.01d);
Assert.assertEquals(30, c.hightempinsulin, 0.01d);
Assert.assertEquals(32, c.netInsulin, 0.01d);
Assert.assertEquals(34, c.extendedBolusInsulin, 0.01d);
}
@Test
public void roundTest() {
IobTotal a = new IobTotal(now);
a.iob = 1.1111111111111;
a.activity = 1.1111111111111;
a.bolussnooze = 1.1111111111111;
a.basaliob = 1.1111111111111;
a.netbasalinsulin = 1.1111111111111;
a.hightempinsulin = 1.1111111111111;
a.netInsulin = 1.1111111111111;
a.extendedBolusInsulin = 1.1111111111111;
a.round();
Assert.assertEquals(1.111d, a.iob, 0.00001d);
Assert.assertEquals(1.1111d, a.activity, 0.00001d);
Assert.assertEquals(1.1111d, a.bolussnooze, 0.00001d);
Assert.assertEquals(1.111d, a.basaliob, 0.00001d);
Assert.assertEquals(1.111d, a.netbasalinsulin, 0.00001d);
Assert.assertEquals(1.111d, a.hightempinsulin, 0.00001d);
Assert.assertEquals(1.111d, a.netInsulin, 0.00001d);
Assert.assertEquals(1.111d, a.extendedBolusInsulin, 0.00001d);
}
@Test
public void jsonTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
try {
JSONObject j = a.json();
Assert.assertEquals(a.iob, j.getDouble("iob"), 0.0000001d);
Assert.assertEquals(a.basaliob, j.getDouble("basaliob"), 0.0000001d);
Assert.assertEquals(a.activity, j.getDouble("activity"), 0.0000001d);
Assert.assertEquals(now, DateUtil.fromISODateString(j.getString("time")).getTime(), 1000);
} catch (Exception e) {
Assert.fail("Exception: " + e.getMessage());
}
}
@Test
public void determineBasalJsonTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
a.iobWithZeroTemp = new IobTotal(now);
try {
JSONObject j = a.determineBasalJson();
Assert.assertEquals(a.iob, j.getDouble("iob"), 0.0000001d);
Assert.assertEquals(a.basaliob, j.getDouble("basaliob"), 0.0000001d);
Assert.assertEquals(a.bolussnooze, j.getDouble("bolussnooze"), 0.0000001d);
Assert.assertEquals(a.activity, j.getDouble("activity"), 0.0000001d);
Assert.assertEquals(0, j.getLong("lastBolusTime"));
Assert.assertEquals(now, DateUtil.fromISODateString(j.getString("time")).getTime(), 1000);
Assert.assertNotNull(j.getJSONObject("iobWithZeroTemp"));
} catch (Exception e) {
Assert.fail("Exception: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,18 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class MealDataTest {
@Test
public void canCreateObject() {
MealData md = new MealData();
Assert.assertEquals(0d, md.boluses, 0.01d);
}
}

View file

@ -0,0 +1,58 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class NonOverapingIntervalsTest {
private final long startDate = DateUtil.now();
NonOverlappingIntervals<TemporaryBasal> list = new NonOverlappingIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new TemporaryBasal().date(startDate).duration((int) T.hours(10).mins()).absolute(1));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// stop temp after 5h
list.add(new TemporaryBasal().date(startDate + T.hours(5).msecs()).duration(0));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(1d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// insert 1h interval inside
list.add(new TemporaryBasal().date(startDate + T.hours(3).msecs()).duration((int) T.hours(1).mins()).absolute(2));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() - 1));
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(3).msecs()).absoluteRate, 0.01d);
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(4).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(4).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new TemporaryBasal().date(startDate).duration((int) T.hours(10).mins()).absolute(1));
NonOverlappingIntervals<TemporaryBasal> list2 = new NonOverlappingIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
}

View file

@ -0,0 +1,72 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class OverapingIntervalsTest {
private final long startDate = DateUtil.now();
OverlappingIntervals<TempTarget> list = new OverlappingIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new TempTarget().date(startDate).duration((int) T.hours(10).mins()).low(100).high(100));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// stop temp target after 5h
list.add(new TempTarget().date(startDate + T.hours(5).msecs()).duration(0));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// insert 1h interval inside
list.add(new TempTarget().date(startDate + T.hours(3).msecs()).duration((int) T.hours(1).mins()).low(200).high(200));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(200d, list.getValueByInterval(startDate + T.hours(3).msecs()).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(4).msecs() + 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new TempTarget().date(startDate).duration((int) T.hours(10).mins()).low(100).high(100));
OverlappingIntervals<TempTarget> list2 = new OverlappingIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
@Test
public void testReversingArrays() {
List<TempTarget> someList = new ArrayList<>();
someList.add(new TempTarget().date(startDate).duration((int) T.hours(3).mins()).low(200).high(200));
someList.add(new TempTarget().date(startDate + T.hours(1).msecs()).duration((int) T.hours(1).mins()).low(100).high(100));
list.reset();
list.add(someList);
Assert.assertEquals(startDate, list.get(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversedList().get(0).date);
}
}

View file

@ -0,0 +1,93 @@
package info.nightscout.androidaps.data;
import com.squareup.otto.Bus;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, Bus.class})
public class ProfileIntervalsTest {
private final long startDate = DateUtil.now();
ProfileIntervals<ProfileSwitch> list = new ProfileIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new ProfileSwitch().date(startDate).duration((int) T.hours(10).mins()).profileName("1").profile(AAPSMocker.getValidProfile()));
// for older date first record should be returned only if has zero duration
Assert.assertEquals(null, list.getValueToTime(startDate - T.secs(1).msecs()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate)).profileName);
Assert.assertEquals(null, list.getValueToTime(startDate + T.hours(10).msecs() + 1));
list.reset();
list.add(new ProfileSwitch().date(startDate).profileName("1").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate - T.secs(1).msecs())).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate)).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(10).msecs() + 1)).profileName);
// switch to different profile after 5h
list.add(new ProfileSwitch().date(startDate + T.hours(5).msecs()).duration(0).profileName("2").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate - T.secs(1).msecs())).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(5).msecs() - 1)).profileName);
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(5).msecs() + 1)).profileName);
// insert 1h interval inside
list.add(new ProfileSwitch().date(startDate + T.hours(6).msecs()).duration((int) T.hours(1).mins()).profileName("3").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(6).msecs() - 1)).profileName);
Assert.assertEquals("3", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(6).msecs() + 1)).profileName);
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(7).msecs() + 1)).profileName);
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new ProfileSwitch().date(startDate).duration((int) T.hours(10).mins()).profileName("4").profile(AAPSMocker.getValidProfile()));
ProfileIntervals<ProfileSwitch> list2 = new ProfileIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
@Test
public void invalidProfilesShouldNotBeReturned() {
list.reset();
list.add(new ProfileSwitch().date(startDate + T.hours(1).msecs()).profileName("6"));
Assert.assertEquals(null, list.get(0));
}
@Test
public void testReversingArrays() {
List<ProfileSwitch> someList = new ArrayList<>();
someList.add(new ProfileSwitch().date(startDate).duration((int) T.hours(3).mins()).profileName("5").profile(AAPSMocker.getValidProfile()));
someList.add(new ProfileSwitch().date(startDate + T.hours(1).msecs()).duration((int) T.hours(1).mins()).profileName("6").profile(AAPSMocker.getValidProfile()));
list.reset();
list.add(someList);
Assert.assertEquals(startDate, list.get(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversedList().get(0).date);
}
@Before
public void prepareMock() {
AAPSMocker.mockMainApp();
AAPSMocker.mockStrings();
AAPSMocker.mockBus();
}
}

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP;
@ -110,10 +111,21 @@ public class ConstraintsCheckerTest {
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void isAdvancedFilteringEnabledTest() throws Exception {
when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin());
Constraint<Boolean> c = constraintChecker.isAdvancedFilteringEnabled();
Assert.assertEquals(true, c.getReasonList().size() == 1); // Safety
Assert.assertEquals(true, c.getMostLimitedReasonList().size() == 1); // Safety
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void isSMBModeEnabledTest() throws Exception {
objectivesPlugin.objectives.get(7).setStarted(new Date(0));
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true));
Constraint<Boolean> c = constraintChecker.isSMBModeEnabled();
Assert.assertEquals(true, c.getReasonList().size() == 2); // Safety & Objectives
@ -240,6 +252,7 @@ public class ConstraintsCheckerTest {
MainApp mainApp = AAPSMocker.mockMainApp();
AAPSMocker.mockConfigBuilder();
AAPSMocker.mockConstraintsChecker();
AAPSMocker.mockApplicationContext();
AAPSMocker.mockBus();
AAPSMocker.mockStrings();

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
import info.nightscout.utils.SP;
import static org.mockito.Mockito.when;
@ -70,6 +71,7 @@ public class SafetyPluginTest {
@Test
public void notEnabledSMBInPreferencesDisablesSMB() throws Exception {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true));
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c);
@ -77,6 +79,27 @@ public class SafetyPluginTest {
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void openLoopPreventsSMB() throws Exception {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(true);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(false));
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c);
Assert.assertEquals(true, c.getReasons().contains("SMB not allowed in open loop mode"));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void bgsourceShouldPreventSMBAlways() throws Exception {
when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin());
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isAdvancedFilteringEnabled(c);
Assert.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons());
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void basalRateShouldBeLimited() throws Exception {
when(SP.getDouble(R.string.key_openapsma_max_basal, 1d)).thenReturn(1d);
@ -204,9 +227,12 @@ public class SafetyPluginTest {
public void prepareMock() {
AAPSMocker.mockMainApp();
AAPSMocker.mockConfigBuilder();
AAPSMocker.mockConstraintsChecker();
AAPSMocker.mockSP();
AAPSMocker.mockStrings();
when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump);
safetyPlugin = SafetyPlugin.getPlugin();

View file

@ -0,0 +1,24 @@
package info.nightscout.utils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class TTest {
@Test
public void doTests() {
Assert.assertEquals(1, T.msecs(1000).secs());
Assert.assertEquals(1, T.secs(60).mins());
Assert.assertEquals(1, T.mins(60).hours());
Assert.assertEquals(1, T.hours(24).days());
Assert.assertEquals(24, T.days(1).hours());
Assert.assertEquals(60000, T.mins(1).msecs());
}
}