manual tempbasal dialog

This commit is contained in:
Milos Kozak 2016-06-20 20:45:55 +02:00
parent cc45f74c25
commit 7cb0e0e588
25 changed files with 660 additions and 193 deletions

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintRtlHardcoded" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

View file

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

View file

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View file

@ -19,7 +19,7 @@ public class Config {
public static final boolean logPumpComm = true;
public static final boolean logPrefsChange = true;
public static final boolean logConfigBuilder = true;
public static final boolean logConstrainsChnages = true;
public static final boolean logConstraintsChanges = true;
// Developing mode only - never turn on
public static final boolean fakeGlucoseData = true;

View file

@ -4,23 +4,30 @@ import android.os.Parcel;
import android.os.Parcelable;
public class Result extends Object implements Parcelable{
public boolean success = false;
public boolean enacted = false;
public boolean success = false; // request was processed successfully (but possible no change was needed)
public boolean enacted = false; // request was processed successfully and change has been made
public String comment = "";
public Integer duration = -1;
public Double absolute = -1d;
public Integer percent = -1;
public Double bolusDelivered = 0d;
// Result of basal change
public Integer duration = -1; // duration set [minutes]
public Double absolute = -1d; // absolute rate [U/h] , isPercent = false
public Integer percent = -1; // percent of current basal [%] (100% = current basal), isPercent = true
public boolean isPercent = false; // if true percent is used, otherwise absolute
// Result of bolus delivery
public Double bolusDelivered = 0d; // real value of delivered insulin
public String log() {
return "Success: " + success + " Enacted: " + enacted + " Comment: " + comment + " Duration: " + duration + " Absolute: " + absolute + " Percent: " + percent;
return "Success: " + success + " Enacted: " + enacted + " Comment: " + comment + " Duration: " + duration + " Absolute: " + absolute + " Percent: " + percent + " IsPercent: " + isPercent;
}
public String toString() {
String ret = "Success: " + success;
if (enacted) {
ret += "\nEnacted: " + enacted + "\nComment: " + comment + "\nDuration: " + duration + " min\nAbsolute: " + absolute + " U/h";
if (isPercent) {
ret += "\nEnacted: " + enacted + "\nComment: " + comment + "\nDuration: " + duration + " min\nPercent: " + percent + "%";
} else {
ret += "\nEnacted: " + enacted + "\nComment: " + comment + "\nDuration: " + duration + " min\nAbsolute: " + absolute + " U/h";
}
} else {
ret += "\nComment: " + comment;
}
@ -36,6 +43,7 @@ public class Result extends Object implements Parcelable{
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(success ? 1 : 0);
dest.writeInt(enacted ? 1 : 0);
dest.writeInt(isPercent ? 1 : 0);
dest.writeString(comment);
dest.writeInt(duration);
dest.writeDouble(absolute);
@ -55,6 +63,7 @@ public class Result extends Object implements Parcelable{
protected Result(Parcel in) {
success = in.readInt() == 1 ? true : false;
enacted = in.readInt() == 1 ? true : false;
isPercent = in.readInt() == 1 ? true : false;
duration = in.readInt();
comment = in.readString();
absolute = in.readDouble();

View file

@ -5,9 +5,11 @@ import info.nightscout.androidaps.plugins.APSResult;
/**
* Created by mike on 15.06.2016.
*/
public interface ConstrainsInterface {
public interface ConstraintsInterface {
boolean isAutomaticProcessingEnabled();
boolean manualConfirmationNeeded();
APSResult applyBasalConstrains(APSResult result);
APSResult applyBasalConstraints(APSResult request);
Double applyBasalConstraints(Double absoluteRate);
Integer applyBasalConstraints(Integer percentRate);
}

View file

@ -12,7 +12,7 @@ public interface PluginBase {
int PROFILE = 4;
int APS = 5;
int PUMP = 6;
int CONSTRAINS = 7;
int CONSTRAINTS = 7;
int LOOP = 8;
public int getType();

View file

@ -12,13 +12,11 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
@ -39,21 +37,19 @@ import info.nightscout.androidaps.data.Result;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.ConstrainsInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TempBasalsInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.APSResult;
import info.nightscout.androidaps.plugins.TempBasals.TempBasalsFragment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DateUtil;
public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpInterface, ConstrainsInterface {
public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpInterface, ConstraintsInterface {
private static Logger log = LoggerFactory.getLogger(ConfigBuilderFragment.class);
private static final String PREFS_NAME = "Settings";
@ -64,7 +60,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
ListView tempsListView;
ListView profileListView;
ListView apsListView;
ListView constrainsListView;
ListView constraintsListView;
ListView generalListView;
PluginCustomAdapter pumpDataAdapter = null;
@ -73,7 +69,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
PluginCustomAdapter tempsDataAdapter = null;
PluginCustomAdapter profileDataAdapter = null;
PluginCustomAdapter apsDataAdapter = null;
PluginCustomAdapter constrainsDataAdapter = null;
PluginCustomAdapter constraintsDataAdapter = null;
PluginCustomAdapter generalDataAdapter = null;
@ -118,7 +114,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
tempsListView = (ListView) view.findViewById(R.id.configbuilder_tempslistview);
profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview);
apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview);
constrainsListView = (ListView) view.findViewById(R.id.configbuilder_constrainslistview);
constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview);
generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview);
setViews();
@ -144,9 +140,9 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainActivity.getSpecificPluginsList(PluginBase.APS));
apsListView.setAdapter(apsDataAdapter);
setListViewHeightBasedOnChildren(apsListView);
constrainsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINS));
constrainsListView.setAdapter(constrainsDataAdapter);
setListViewHeightBasedOnChildren(constrainsListView);
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS));
constraintsListView.setAdapter(constraintsDataAdapter);
setListViewHeightBasedOnChildren(constraintsListView);
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainActivity.getSpecificPluginsList(PluginBase.GENERAL));
generalListView.setAdapter(generalDataAdapter);
setListViewHeightBasedOnChildren(generalListView);
@ -200,7 +196,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
/*
* Pump interface
*
* Config builder return itself as a pump and check constrains before it passes command to pump driver
* Config builder return itself as a pump and check constraints before it passes command to pump driver
*/
@Nullable
public PumpInterface getActivePump() {
@ -261,7 +257,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
if (insulin > maxbolus || carbs > maxcarbs) {
Result failResult = new Result();
failResult.success = false;
failResult.comment = MainApp.instance().getString(R.string.constrains_violation);
failResult.comment = MainApp.instance().getString(R.string.constraints_violation);
return failResult;
}
Result result = activePump.deliverTreatment(insulin, carbs);
@ -283,29 +279,55 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
return result;
}
/**
* apply constraints, set temp based on absolute valus and expecting absolute result
*
* @param absoluteRate
* @param durationInMinutes
* @return
*/
@Override
public Result setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) {
// TODO: constrains here
return activePump.setTempBasalAbsolute(absoluteRate, durationInMinutes);
Double rateAfterConstraints = applyBasalConstraints(absoluteRate);
Result result = activePump.setTempBasalAbsolute(rateAfterConstraints, durationInMinutes);
if (result.enacted) {
uploadTempBasalStartAbsolute(result.absolute, result.duration);
MainApp.bus().post(new EventTempBasalChange());
}
return result;
}
/**
* apply constraints, set temp based on percent and expecting result in percent
*
* @param percent 0 ... 100 ...
* @param durationInMinutes
* @return result
*/
@Override
public Result setTempBasalPercent(Integer percent, Integer durationInMinutes) {
// TODO: constrains here
return activePump.setTempBasalPercent(percent, durationInMinutes);
Integer percentAfterConstraints = applyBasalConstraints(percent);
Result result = activePump.setTempBasalPercent(percentAfterConstraints, durationInMinutes);
if (result.enacted) {
uploadTempBasalStartPercent(result.percent, result.duration);
MainApp.bus().post(new EventTempBasalChange());
}
return result;
}
@Override
public Result setExtendedBolus(Double insulin, Integer durationInMinutes) {
// TODO: constrains here
// TODO: constraints here
return activePump.setExtendedBolus(insulin, durationInMinutes);
}
@Override
public Result cancelTempBasal() {
Result result = activePump.cancelTempBasal();
if (result.enacted)
if (result.enacted) {
uploadTempBasalEnd();
MainApp.bus().post(new EventTempBasalChange());
}
return result;
}
@ -314,11 +336,32 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
return activePump.cancelExtendedBolus();
}
/**
* expect absolute request and allow both absolute and percent response based on pump capabilities
* @param request
* @return
*/
@Override
public Result applyAPSRequest(APSResult request) {
Result result = activePump.applyAPSRequest(request);
if (result.enacted)
uploadTempBasalStart(result.absolute, result.duration);
Double rateAfterConstraints = applyBasalConstraints(request.rate);
request.rate = rateAfterConstraints;
Result result = activePump.applyAPSRequest(request);
if (result.enacted) {
if (result.isPercent) {
if (result.percent == 0) {
uploadTempBasalEnd();
} else {
uploadTempBasalStartPercent(result.percent, result.duration);
}
} else {
if (result.absolute == 0d) {
uploadTempBasalEnd();
} else {
uploadTempBasalStartAbsolute(result.absolute, result.duration);
}
}
MainApp.bus().post(new EventTempBasalChange());
}
return result;
}
@ -405,8 +448,8 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
if (pluginList.size() < 2)
holder.checkboxEnabled.setEnabled(false);
// Constrains cannot be disabled
if (type == PluginBase.CONSTRAINS)
// Constraints cannot be disabled
if (type == PluginBase.CONSTRAINTS)
holder.checkboxEnabled.setEnabled(false);
// Hide disabled profiles by default
@ -446,7 +489,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
// Multiple selection allowed
case PluginBase.APS:
case PluginBase.GENERAL:
case PluginBase.CONSTRAINS:
case PluginBase.CONSTRAINTS:
break;
// Single selection allowed
case PluginBase.PROFILE:
@ -478,7 +521,7 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
// Multiple selection allowed
case PluginBase.APS:
case PluginBase.GENERAL:
case PluginBase.CONSTRAINS:
case PluginBase.CONSTRAINTS:
break;
// Single selection allowed
case PluginBase.PROFILE:
@ -607,15 +650,15 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
}
/**
* Constrains interface
* Constraints interface
**/
@Override
public boolean isAutomaticProcessingEnabled() {
boolean result = true;
ArrayList<PluginBase> constrainsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINS);
for (PluginBase p : constrainsPlugins) {
ConstrainsInterface constrain = (ConstrainsInterface) p;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
result = result && constrain.isAutomaticProcessingEnabled();
}
@ -626,9 +669,9 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
public boolean manualConfirmationNeeded() {
boolean result = false;
ArrayList<PluginBase> constrainsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINS);
for (PluginBase p : constrainsPlugins) {
ConstrainsInterface constrain = (ConstrainsInterface) p;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
result = result || constrain.manualConfirmationNeeded();
}
@ -636,29 +679,72 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
}
@Override
public APSResult applyBasalConstrains(APSResult result) {
ArrayList<PluginBase> constrainsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINS);
for (PluginBase p : constrainsPlugins) {
ConstrainsInterface constrain = (ConstrainsInterface) p;
public APSResult applyBasalConstraints(APSResult result) {
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
constrain.applyBasalConstrains(result);
constrain.applyBasalConstraints(result);
}
return result;
}
public static void uploadTempBasalStart(Double absolute, double durationInMinutes) {
try {
//SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
//boolean useAbsoluteForUpload = sp.getBoolean("ns_sync_use_absolute", false);
@Override
public Double applyBasalConstraints(Double absoluteRate) {
Double rateAfterConstrain = absoluteRate;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
rateAfterConstrain = constrain.applyBasalConstraints(rateAfterConstrain);
}
return rateAfterConstrain;
}
@Override
public Integer applyBasalConstraints(Integer percentRate) {
Integer rateAfterConstrain = percentRate;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
rateAfterConstrain = constrain.applyBasalConstraints(rateAfterConstrain);
}
return rateAfterConstrain;
}
public static void uploadTempBasalStartAbsolute(Double absolute, double durationInMinutes) {
try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject();
data.put("eventType", "Temp Basal");
data.put("duration", durationInMinutes);
//if (useAbsoluteForUpload && absolute != null)
data.put("absolute", absolute);
//else
// data.put("percent", percent - 100);
data.put("absolute", absolute);
data.put("created_at", DateUtil.toISOString(new Date()));
data.put("enteredBy", MainApp.instance().getString(R.string.app_name));
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
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);
List<ResolveInfo> q = context.getPackageManager().queryBroadcastReceivers(intent, 0);
if (q.size() < 1) {
log.error("DBADD No receivers");
} else log.debug("DBADD dbAdd " + q.size() + " receivers " + data.toString());
} catch (JSONException e) {
}
}
public static void uploadTempBasalStartPercent(Integer percent, double durationInMinutes) {
try {
Context context = MainApp.instance().getApplicationContext();
JSONObject data = new JSONObject();
data.put("eventType", "Temp Basal");
data.put("duration", durationInMinutes);
data.put("percent", percent - 100);
data.put("created_at", DateUtil.toISOString(new Date()));
data.put("enteredBy", MainApp.instance().getString(R.string.app_name));
Bundle bundle = new Bundle();

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.Loop;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@ -10,7 +9,6 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
@ -29,7 +27,7 @@ import info.nightscout.androidaps.data.Result;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.ConstrainsInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.APSResult;
@ -42,14 +40,14 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
TextView lastEnactView;
TextView sourceView;
TextView requestView;
TextView constrainsProcessedView;
TextView constraintsProcessedView;
TextView setByPumpView;
boolean confirmed;
class LastRun implements Parcelable {
public APSResult request = null;
public APSResult constrainsProcessed = null;
public APSResult constraintsProcessed = null;
public Result setByPump = null;
public String source = null;
public Date lastAPSRun = null;
@ -63,11 +61,11 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(request, 0);
dest.writeParcelable(constrainsProcessed, 0);
dest.writeParcelable(constraintsProcessed, 0);
dest.writeParcelable(setByPump, 0);
dest.writeString(source);
dest.writeLong(lastAPSRun.getTime());
dest.writeLong(lastEnact.getTime());
dest.writeLong(lastEnact!= null ? lastEnact.getTime(): 0l);
}
public final Parcelable.Creator<LastRun> CREATOR = new Parcelable.Creator<LastRun>() {
@ -82,7 +80,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
private LastRun(Parcel in) {
request = in.readParcelable(APSResult.class.getClassLoader());
constrainsProcessed = in.readParcelable(APSResult.class.getClassLoader());
constraintsProcessed = in.readParcelable(APSResult.class.getClassLoader());
setByPump = in.readParcelable(Result.class.getClassLoader());
source = in.readString();
lastAPSRun = new Date(in.readLong());
@ -157,7 +155,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
lastEnactView = (TextView) view.findViewById(R.id.loop_lastenact);
sourceView = (TextView) view.findViewById(R.id.loop_source);
requestView = (TextView) view.findViewById(R.id.loop_request);
constrainsProcessedView = (TextView) view.findViewById(R.id.loop_constrainsprocessed);
constraintsProcessedView = (TextView) view.findViewById(R.id.loop_constraintsprocessed);
setByPumpView = (TextView) view.findViewById(R.id.loop_setbypump);
runNowButton = (Button) view.findViewById(R.id.loop_run);
runNowButton.setOnClickListener(this);
@ -210,19 +208,19 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
@Subscribe
public void onStatusEvent(final EventNewBG ev) {
ConstrainsInterface constrainsInterface = MainActivity.getConfigBuilder();
if (constrainsInterface.isAutomaticProcessingEnabled()) {
ConstraintsInterface constraintsInterface = MainActivity.getConfigBuilder();
if (constraintsInterface.isAutomaticProcessingEnabled()) {
invoke();
updateGUI();
}
}
private void invoke() {
ConstrainsInterface constrainsInterface = MainActivity.getConfigBuilder();
ConstraintsInterface constraintsInterface = MainActivity.getConfigBuilder();
PumpInterface pumpInterface = MainActivity.getConfigBuilder().getActivePump();
APSResult result = null;
if (constrainsInterface == null || pumpInterface == null || !isEnabled())
if (constraintsInterface == null || pumpInterface == null || !isEnabled())
return;
APSInterface usedAPS = null;
@ -255,7 +253,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
}
confirmed = false;
if (constrainsInterface.manualConfirmationNeeded()) {
if (constraintsInterface.manualConfirmationNeeded()) {
// TODO: user notification here
confirmed = true;
} else {
@ -263,15 +261,15 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
}
// check rate for constrais
APSResult resultAfterConstrains = result.clone();
APSResult resultAfterConstraints = result.clone();
if (result.changeRequested) {
constrainsInterface.applyBasalConstrains(resultAfterConstrains);
Result applyResult = pumpInterface.applyAPSRequest(resultAfterConstrains);
constraintsInterface.applyBasalConstraints(resultAfterConstraints);
Result applyResult = pumpInterface.applyAPSRequest(resultAfterConstraints);
Date lastEnact = lastRun != null ? lastRun.lastEnact : new Date(0, 0, 0);
lastRun = new LastRun();
lastRun.request = result;
lastRun.constrainsProcessed = resultAfterConstrains;
lastRun.constraintsProcessed = resultAfterConstraints;
lastRun.setByPump = applyResult;
lastRun.source = ((PluginBase) usedAPS).getName();
lastRun.lastAPSRun = new Date();
@ -282,7 +280,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
} else {
if (lastRun == null) lastRun = new LastRun();
lastRun.request = result;
lastRun.constrainsProcessed = resultAfterConstrains;
lastRun.constraintsProcessed = resultAfterConstraints;
lastRun.setByPump = null;
lastRun.source = null;
lastRun.lastAPSRun = new Date();
@ -298,7 +296,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
public void run() {
if (lastRun != null) {
requestView.setText(lastRun.request != null ? lastRun.request.toString() : "");
constrainsProcessedView.setText(lastRun.constrainsProcessed != null ? lastRun.constrainsProcessed.toString() : "");
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toString() : "");
setByPumpView.setText(lastRun.setByPump != null ? lastRun.setByPump.toString() : "");
sourceView.setText(lastRun.source != null ? lastRun.source.toString() : "");
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
@ -315,7 +313,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
@Override
public void run() {
requestView.setText("");
constrainsProcessedView.setText("");
constraintsProcessedView.setText("");
setByPumpView.setText("");
sourceView.setText("");
lastRunView.setText("");

View file

@ -25,11 +25,11 @@ import java.util.List;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.ConstrainsInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.APSResult;
public class ObjectivesFragment extends Fragment implements View.OnClickListener, PluginBase, ConstrainsInterface {
public class ObjectivesFragment extends Fragment implements View.OnClickListener, PluginBase, ConstraintsInterface {
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
RecyclerView recyclerView;
@ -42,7 +42,7 @@ public class ObjectivesFragment extends Fragment implements View.OnClickListener
@Override
public int getType() {
return PluginBase.CONSTRAINS;
return PluginBase.CONSTRAINTS;
}
@Override
@ -314,7 +314,7 @@ public class ObjectivesFragment extends Fragment implements View.OnClickListener
}
/**
* Constrains interface
* Constraints interface
**/
@Override
public boolean isAutomaticProcessingEnabled() {
@ -327,8 +327,18 @@ public class ObjectivesFragment extends Fragment implements View.OnClickListener
}
@Override
public APSResult applyBasalConstrains(APSResult result) {
public APSResult applyBasalConstraints(APSResult result) {
return result;
}
@Override
public Double applyBasalConstraints(Double absoluteRate) {
return absoluteRate;
}
@Override
public Integer applyBasalConstraints(Integer percentRate) {
return percentRate;
}
}

View file

@ -0,0 +1,112 @@
package info.nightscout.androidaps.plugins.Overview.Dialogs;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Result;
import info.nightscout.androidaps.interfaces.PumpInterface;
public class NewTempBasalDialog extends DialogFragment implements View.OnClickListener {
Button okButton;
EditText basalEdit;
RadioButton percentRadio;
RadioButton absoluteRadio;
RadioButton h05Radio;
RadioButton h10Radio;
RadioButton h20Radio;
RadioButton h30Radio;
RadioButton h40Radio;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_newtempbasal_fragment, container, false);
okButton = (Button) view.findViewById(R.id.overview_newtempbasal_okbutton);
basalEdit = (EditText) view.findViewById(R.id.overview_newtempbasal_basal);
percentRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_percent);
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute);
h05Radio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_05h);
h10Radio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_1h);
h20Radio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_2h);
h30Radio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_3h);
h40Radio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_4h);
okButton.setOnClickListener(this);
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.overview_newtempbasal_okbutton:
try {
int basalPercent = 100;
String basalText = basalEdit.getText().toString().replace(",", ".");
Double basal = Double.parseDouble(!basalText.equals("") ? basalText : "0");
final boolean setAsPercent = percentRadio.isChecked();
int durationInMinutes = 30;
if (h10Radio.isChecked()) durationInMinutes = 60;
if (h20Radio.isChecked()) durationInMinutes = 120;
if (h30Radio.isChecked()) durationInMinutes = 180;
if (h40Radio.isChecked()) durationInMinutes = 240;
String confirmMessage = getString(R.string.setbasalquestion);
if (setAsPercent) {
basalPercent = MainActivity.getConfigBuilder().applyBasalConstraints(basal.intValue());
confirmMessage += " " + basalPercent + "% ?";
if (basalPercent != basal.intValue())
confirmMessage += "\n" + getString(R.string.constraintapllied);
} else {
Double basalAfterConstraint = MainActivity.getConfigBuilder().applyBasalConstraints(basal);
confirmMessage += " " + basalAfterConstraint + " U/h ?";
if (basalAfterConstraint != basal)
confirmMessage += "\n" + getString(R.string.constraintapllied);
basal = basalAfterConstraint;
}
final int finalBasalPercent = basalPercent;
final Double finalBasal = basal;
final int finalDurationInMinutes = durationInMinutes;
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
builder.setTitle(this.getContext().getString(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
PumpInterface pump = MainActivity.getConfigBuilder().getActivePump();
Result result;
if (setAsPercent) {
result = pump.setTempBasalPercent(finalBasalPercent, finalDurationInMinutes);
} else {
result = pump.setTempBasalAbsolute(finalBasal, finalDurationInMinutes);
}
if (!result.success) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getContext().getString(R.string.treatmentdeliveryerror));
builder.setMessage(result.comment);
builder.setPositiveButton(getContext().getString(R.string.ok), null);
builder.show();
}
}
});
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View file

@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.Overview.Dialogs;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -15,10 +13,9 @@ import android.widget.TextView;
import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.data.Result;
public class NewTreatmentDialogFragment extends DialogFragment implements OnClickListener {
public class NewTreatmentDialog extends DialogFragment implements OnClickListener {
Button deliverButton;
TextView insulin;
@ -27,7 +24,7 @@ public class NewTreatmentDialogFragment extends DialogFragment implements OnClic
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_newtreatment_fragment, null, false);
View view = inflater.inflate(R.layout.overview_newtreatment_fragment, null, false);
deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton);
@ -48,26 +45,28 @@ public class NewTreatmentDialogFragment extends DialogFragment implements OnClic
Double maxbolus = Double.parseDouble(SP.getString("treatmentssafety_maxbolus", "3"));
Double maxcarbs = Double.parseDouble(SP.getString("treatmentssafety_maxcarbs", "48"));
String insulinText = this.insulin.getText().toString().replace(",", ".");
String carbsText = this.carbs.getText().toString().replace(",", ".");
Double insulin = Double.parseDouble(!insulinText.equals("") ? this.insulin.getText().toString() : "0");
Double carbs = Double.parseDouble(!carbsText.equals("") ? this.carbs.getText().toString() : "0");
if (insulin > maxbolus) {
this.insulin.setText("");
} else if (carbs > maxcarbs) {
this.carbs.setText("");
} else if (insulin > 0d || carbs > 0d) {
dismiss();
Result result = MainActivity.getConfigBuilder().getActivePump().deliverTreatment(insulin, carbs);
if (!result.success) {
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
builder.setTitle(this.getContext().getString(R.string.bolusdeliveryerror));
builder.setMessage(result.comment);
builder.setPositiveButton(this.getContext().getString(R.string.ok), null);
builder.show();
try {
String insulinText = this.insulin.getText().toString().replace(",", ".");
String carbsText = this.carbs.getText().toString().replace(",", ".");
Double insulin = Double.parseDouble(!insulinText.equals("") ? insulinText : "0");
Double carbs = Double.parseDouble(!carbsText.equals("") ? carbsText : "0");
if (insulin > maxbolus) {
this.insulin.setText("");
} else if (carbs > maxcarbs) {
this.carbs.setText("");
} else if (insulin > 0d || carbs > 0d) {
dismiss();
Result result = MainActivity.getConfigBuilder().getActivePump().deliverTreatment(insulin, carbs);
if (!result.success) {
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
builder.setTitle(this.getContext().getString(R.string.treatmentdeliveryerror));
builder.setMessage(result.comment);
builder.setPositiveButton(this.getContext().getString(R.string.ok), null);
builder.show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}

View file

@ -15,7 +15,6 @@ import android.widget.TextView;
import java.text.DecimalFormat;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
@ -26,7 +25,7 @@ import info.nightscout.androidaps.plugins.OpenAPSMA.IobTotal;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.*;
public class WizardDialogFragment extends DialogFragment implements OnClickListener {
public class WizardDialog extends DialogFragment implements OnClickListener {
Button wizardDialogDeliverButton;
TextView correctionInput;
@ -69,7 +68,7 @@ public class WizardDialogFragment extends DialogFragment implements OnClickListe
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_wizard_fragment, null, false);
View view = inflater.inflate(R.layout.overview_wizard_fragment, null, false);
wizardDialogDeliverButton = (Button) view.findViewById(R.id.treatments_wizard_deliverButton);
wizardDialogDeliverButton.setOnClickListener(this);

View file

@ -38,10 +38,12 @@ import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialogFragment;
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialogFragment;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTempBasalDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
import info.nightscout.client.data.NSProfile;
@ -53,9 +55,13 @@ public class OverviewFragment extends Fragment implements PluginBase {
TextView deltaView;
GraphView bgGraph;
LinearLayout cancelTempLayout;
LinearLayout setTempLayout;
Button cancelTempButton;
Button treatmentButton;
Button wizardButton;
Button setTempButton;
Button setExtenedButton;
boolean visibleNow = false;
Handler loopHandler = new Handler();
@ -141,12 +147,16 @@ public class OverviewFragment extends Fragment implements PluginBase {
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
treatmentButton = (Button) view.findViewById(R.id.overview_treatment);
wizardButton = (Button) view.findViewById(R.id.overview_wizard);
setTempButton = (Button) view.findViewById(R.id.overview_settempbasal);
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
setTempLayout = (LinearLayout) view.findViewById(R.id.overview_settemplayout);
cancelTempLayout = (LinearLayout) view.findViewById(R.id.overview_canceltemplayout);
treatmentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
NewTreatmentDialogFragment treatmentDialogFragment = new NewTreatmentDialogFragment();
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog();
treatmentDialogFragment.show(manager, "TreatmentDialog");
}
});
@ -155,8 +165,8 @@ public class OverviewFragment extends Fragment implements PluginBase {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
WizardDialogFragment wizardDialogFragment = new WizardDialogFragment();
wizardDialogFragment.show(manager, "WizardDialog");
WizardDialog wizardDialog = new WizardDialog();
wizardDialog.show(manager, "WizardDialog");
}
});
@ -170,6 +180,16 @@ public class OverviewFragment extends Fragment implements PluginBase {
}
}
});
setTempButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
NewTempBasalDialog newTempDialog = new NewTempBasalDialog();
newTempDialog.show(manager, "NewTempDialog");
}
});
updateGUI();
return view;
}
@ -183,6 +203,20 @@ public class OverviewFragment extends Fragment implements PluginBase {
MainApp.bus().register(this);
}
@Subscribe
public void onStatusEvent(final EventTreatmentChange ev) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI();
}
});
else
log.debug("EventTreatmentChange: Activity is null");
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
Activity activity = getActivity();
@ -243,10 +277,12 @@ public class OverviewFragment extends Fragment implements PluginBase {
if (pump.isTempBasalInProgress()) {
TempBasal activeTemp = pump.getTempBasal();
cancelTempButton.setVisibility(View.VISIBLE);
cancelTempLayout.setVisibility(View.VISIBLE);
setTempLayout.setVisibility(View.GONE);
cancelTempButton.setText(MainApp.instance().getString(R.string.cancel) + ": " + activeTemp.toString());
} else {
cancelTempButton.setVisibility(View.INVISIBLE);
cancelTempLayout.setVisibility(View.GONE);
setTempLayout.setVisibility(View.VISIBLE);
}
// **** BG value ****

View file

@ -2,17 +2,8 @@ package info.nightscout.androidaps.plugins.SafetyFragment;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -21,19 +12,19 @@ import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.ConstrainsInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.plugins.APSResult;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.Round;
public class SafetyFragment extends Fragment implements PluginBase, ConstrainsInterface {
public class SafetyFragment extends Fragment implements PluginBase, ConstraintsInterface {
private static Logger log = LoggerFactory.getLogger(SafetyFragment.class);
@Override
public int getType() {
return PluginBase.CONSTRAINS;
return PluginBase.CONSTRAINTS;
}
@Override
@ -71,7 +62,7 @@ public class SafetyFragment extends Fragment implements PluginBase, ConstrainsIn
}
/**
* Constrains interface
* Constraints interface
**/
@Override
public boolean isAutomaticProcessingEnabled() {
@ -84,33 +75,83 @@ public class SafetyFragment extends Fragment implements PluginBase, ConstrainsIn
}
@Override
public APSResult applyBasalConstrains(APSResult result) {
public APSResult applyBasalConstraints(APSResult result) {
result.rate = applyBasalConstraints(result.rate);
return result;
}
@Override
public Double applyBasalConstraints(Double absoluteRate) {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
Double maxBasal = Double.parseDouble(SP.getString("openapsma_max_basal", "1").replace(",", "."));
NSProfile profile = MainActivity.getConfigBuilder().getActiveProfile().getProfile();
if (result.rate < 0) result.rate = 0;
if (absoluteRate < 0) absoluteRate = 0d;
Integer maxBasalMult = 4;
Integer maxBasalFromDaily = 3;
// Check percentRate but absolute rate too, because we know real current basal in pump
Double origRate = result.rate;
if (result.rate > maxBasal) {
result.rate = maxBasal;
if (Config.logConstrainsChnages)
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + result.rate + "U/h");
Double origRate = absoluteRate;
if (absoluteRate > maxBasal) {
absoluteRate = maxBasal;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + absoluteRate + "U/h");
}
if (result.rate > maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight())) {
result.rate = Math.floor(maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight()) * 100) / 100;
if (Config.logConstrainsChnages)
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + result.rate + "U/h");
if (absoluteRate > maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight())) {
absoluteRate = Math.floor(maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight()) * 100) / 100;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h");
}
if (result.rate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
result.rate = profile.getMaxDailyBasal() * maxBasalFromDaily;
if (Config.logConstrainsChnages)
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + result.rate + "U/h");
if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h");
}
return result;
return absoluteRate;
}
@Override
public Integer applyBasalConstraints(Integer percentRate) {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
Double maxBasal = Double.parseDouble(SP.getString("openapsma_max_basal", "1").replace(",", "."));
NSProfile profile = MainActivity.getConfigBuilder().getActiveProfile().getProfile();
Double currentBasal = profile.getBasal(profile.secondsFromMidnight());
Double absoluteRate = currentBasal * ((double) percentRate / 100);
if (Config.logConstraintsChanges)
log.debug("Percent rate " + percentRate + "% recalculated to " + absoluteRate + "U/h with current basal " + currentBasal + "U/h");
if (absoluteRate < 0) absoluteRate = 0d;
Integer maxBasalMult = 4;
Integer maxBasalFromDaily = 3;
// Check percentRate but absolute rate too, because we know real current basal in pump
Double origRate = absoluteRate;
if (absoluteRate > maxBasal) {
absoluteRate = maxBasal;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + absoluteRate + "U/h");
}
if (absoluteRate > maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight())) {
absoluteRate = Math.floor(maxBasalMult * profile.getBasal(NSProfile.secondsFromMidnight()) * 100) / 100;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h");
}
if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily;
if (Config.logConstraintsChanges)
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h");
}
Integer percentRateAfterConst = new Double(absoluteRate / currentBasal * 100).intValue();
if (percentRateAfterConst < 100) Round.ceilTo(absoluteRate, 10d).intValue();
else Round.floorTo(absoluteRate, 10d).intValue();
if (Config.logConstraintsChanges)
log.debug("Recalculated percent rate " + percentRate + "% to " + percentRateAfterConst + "%");
return percentRateAfterConst;
}
}

View file

@ -278,6 +278,7 @@ public class VirtualPumpFragment extends Fragment implements PluginBase, PumpInt
result.success = true;
result.enacted = true;
result.percent = percent;
result.isPercent = true;
result.duration = durationInMinutes;
result.comment = getString(R.string.virtualpump_resultok);
try {
@ -374,6 +375,8 @@ public class VirtualPumpFragment extends Fragment implements PluginBase, PumpInt
if (isTempBasalInProgress()) {
if (request.rate == getTempBasalAbsoluteRate()) {
Result noChange = new Result();
noChange.absolute = request.rate;
noChange.duration = tempBasal.getPlannedRemainingMinutes();
noChange.enacted = false;
noChange.comment = "Temp basal set correctly";
noChange.success = true;
@ -384,6 +387,8 @@ public class VirtualPumpFragment extends Fragment implements PluginBase, PumpInt
}
if (request.rate == getBaseBasalRate()) {
Result noChange = new Result();
noChange.absolute = request.rate;
noChange.duration = 0;
noChange.enacted = false;
noChange.comment = "Basal set correctly";
noChange.success = true;

View file

@ -10,4 +10,16 @@ public class Round {
}
return 0d;
}
public static Double floorTo(Double x, Double step) {
if (x != 0d) {
return Math.floor(x / step) * step;
}
return 0d;
}
public static Double ceilTo(Double x, Double step) {
if (x != 0d) {
return Math.ceil(x / step) * step;
}
return 0d;
}
}

View file

@ -116,12 +116,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="@string/configbuilder_constrains"
android:text="@string/configbuilder_constraints"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<ListView
android:id="@+id/configbuilder_constrainslistview"
android:id="@+id/configbuilder_constraintslistview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"

View file

@ -96,11 +96,11 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/loop_constrainsprocessed_label"
android:text="@string/loop_constraintsprocessed_label"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/loop_constrainsprocessed"
android:id="@+id/loop_constraintsprocessed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"

View file

@ -6,42 +6,42 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/overview_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|top"
android:textSize="100dp" />
android:textSize="60dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layout_marginTop="10dp">
android:layout_marginTop="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/overview_timeago"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/overview_delta"
android:layout_marginLeft="10dp" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
@ -52,44 +52,72 @@
android:layout_height="200dip" />
<LinearLayout
android:orientation="horizontal"
android:id="@+id/overview_canceltemplayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel temp basal"
android:id="@+id/overview_canceltemp"
android:background="@color/colorCancelTempButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="0.5" />
android:layout_weight="0.5"
android:background="@color/colorCancelTempButton"
android:text="Cancel temp basal" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/overview_settemplayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:id="@+id/overview_settempbasal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Treatment"
android:id="@+id/overview_treatment"
android:background="@color/colorTreatmentButton"
android:layout_margin="10dp"
android:layout_weight="0.5" />
android:layout_weight="0.5"
android:background="@color/colorSetTempButton"
android:text="TempBasal" />
<Button
android:layout_width="wrap_content"
android:id="@+id/overview_extendedbolus"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Calculator"
android:id="@+id/overview_wizard"
android:background="@color/colorWizardButton"
android:layout_margin="10dp"
android:layout_weight="0.5" />
android:layout_weight="0.5"
android:background="@color/colorSetExtendedButton"
android:text="Extended Bolus" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/overview_treatment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="0.5"
android:background="@color/colorTreatmentButton"
android:text="@string/overview_treatment_label" />
<Button
android:id="@+id/overview_wizard"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="0.5"
android:background="@color/colorWizardButton"
android:text="@string/overview_calculator_label" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,108 @@
<?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:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/overview_newtempbasal_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/overview_newtempbasal_percent_label"
android:checked="true"
android:layout_marginRight="20dp" />
<RadioButton
android:id="@+id/overview_newtempbasal_absolute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="U/h"
android:layout_marginLeft="20dp" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="@string/overview_newtempbasal_basal_label"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/overview_newtempbasal_basal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:inputType="numberDecimal"
android:minWidth="200dp"
android:padding="10dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0.5 h"
android:id="@+id/overview_newtempbasal_05h"
android:checked="true" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1 h"
android:id="@+id/overview_newtempbasal_1h" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2 h"
android:id="@+id/overview_newtempbasal_2h" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3 h"
android:id="@+id/overview_newtempbasal_3h" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4 h"
android:id="@+id/overview_newtempbasal_4h" />
</RadioGroup>
<Button
android:id="@+id/overview_newtempbasal_okbutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="OK"
android:textSize="20sp" />
</LinearLayout>

View file

@ -12,4 +12,6 @@
<color name="colorTreatmentButton">#FFB347</color>
<color name="colorWizardButton">#77dd77</color>
<color name="colorCancelTempButton">#FF47C8FF</color>
<color name="colorSetTempButton">#FF478EFF</color>
<color name="colorSetExtendedButton">#FFDD7792</color>
</resources>

View file

@ -104,14 +104,14 @@
<string name="configbuilder_general">General</string>
<string name="days">days</string>
<string name="minimalduration">Minimal duration</string>
<string name="configbuilder_constrains">Constrains</string>
<string name="configbuilder_constraints">Constraints</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="loop">Loop</string>
<string name="configbuilder_loop">Loop</string>
<string name="loop_aps_label">APS</string>
<string name="loop_constrainsprocessed_label">After processed constrains</string>
<string name="loop_constraintsprocessed_label">After processed constraints</string>
<string name="loop_setbypump_label">Set by pump</string>
<string name="openapsma_lastenact_label">Last enacted</string>
<string name="dialog">Dialog</string>
@ -128,7 +128,14 @@
<string name="maxbasaliob_summary">Maximum amount of non-bolus IOB OpenAPS can deliver</string>
<string name="lowsuspend_low_title">Low BG threshold</string>
<string name="openapsma_disabled">Plugin is disabled</string>
<string name="constrains_violation">Constrains violation</string>
<string name="bolusdeliveryerror">Treatment delivery error</string>
<string name="constraints_violation">Constraints violation</string>
<string name="treatmentdeliveryerror">Treatment delivery error</string>
<string name="overview_newtempbasal_basal_label">Basal value</string>
<string name="overview_newtempbasal_percent_label">% (100% = current)</string>
<string name="setbasalquestion">Set new temp basal:</string>
<string name="overview_treatment_label">Treatment</string>
<string name="overview_calculator_label">Calculator</string>
<string name="constraintapllied">Constraint applied!</string>
<string name="confirmation">Confirmation</string>
</resources>