This commit is contained in:
TebbeUbben 2018-03-10 21:24:04 +01:00
commit 7329d3abff
32 changed files with 1026 additions and 176 deletions

View file

@ -38,6 +38,14 @@ public class Constants {
//DanaR
public static final double dailyLimitWarning = 0.95d;
// Temp targets
public static final int defaultActivityTTDuration = 90; // min
public static final double defaultActivityTTmgdl = 90d;
public static final double defaultActivityTTmmol = 5d;
public static final int defaultEatingSoonTTDuration = 45; // min
public static final double defaultEatingSoonTTmgdl = 140d;
public static final double defaultEatingSoonTTmmol = 8d;
//NSClientInternal
public static final int MAX_LOG_LINES = 100;

View file

@ -247,6 +247,10 @@ public class MainApp extends Application {
return sResources.getString(id, args);
}
public static int gc(int id) {
return sResources.getColor(id);
}
public static MainApp instance() {
return sInstance;
}

View file

@ -442,6 +442,14 @@ public class Profile {
return ret;
}
public double getTarget(){
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
}
private double getTarget(Integer time) {
return (getTargetLow(time) + getTargetHigh(time))/2;
}
public Double getTargetLow() {
return getTargetLow(secondsFromMidnight(System.currentTimeMillis()));
}

View file

@ -41,6 +41,10 @@ public class TempTarget implements Interval {
@DatabaseField
public int durationInMinutes;
public double target() {
return (low + high) / 2;
}
public boolean isEqual(TempTarget other) {
if (date != other.date) {
return false;

View file

@ -325,13 +325,13 @@ public class TemporaryBasal implements Interval {
if(profile != null) {
double basal = profile.getBasal();
if(basal != 0){
return Math.round(rate*100d/basal) + "% ";
return Math.round(rate*100d/basal) + "%";
}
}
}
return DecimalFormatter.to2Decimal(rate) + "U/h ";
return DecimalFormatter.to2Decimal(rate) + "U/h";
} else { // percent
return percentRate + "% ";
return percentRate + "%";
}
}

View file

@ -176,7 +176,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
double targetBg = (minBg + maxBg) / 2;
double targetBg = Profile.toMgdl(profile.getTarget(), units);
minBg = Round.roundTo(minBg, 0.1d);
maxBg = Round.roundTo(maxBg, 0.1d);
@ -202,7 +202,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
isTempTarget = true;
minBg = HardLimits.verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
maxBg = HardLimits.verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
targetBg = HardLimits.verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
targetBg = HardLimits.verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
}

View file

@ -179,7 +179,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
double maxBasal = SafeParse.stringToDouble(SP.getString("openapsma_max_basal", "1"));
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
double targetBg = (minBg + maxBg) / 2;
double targetBg = Profile.toMgdl(profile.getTarget(), units);
minBg = Round.roundTo(minBg, 0.1d);
maxBg = Round.roundTo(maxBg, 0.1d);
@ -205,7 +205,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
if (tempTarget != null) {
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
}
maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA());

View file

@ -181,7 +181,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
double targetBg = (minBg + maxBg) / 2;
double targetBg = Profile.toMgdl(profile.getTarget(), units);
minBg = Round.roundTo(minBg, 0.1d);
maxBg = Round.roundTo(maxBg, 0.1d);
@ -207,7 +207,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
isTempTarget = true;
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
}

View file

@ -36,15 +36,15 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Loop.APSResult;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.OpenAPSSMB.DetermineBasalResultSMB;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -69,9 +69,9 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
private static final double FAV1_DEFAULT = 5;
private static final double FAV2_DEFAULT = 10;
private static final double FAV3_DEFAULT = 20;
private CheckBox suspendLoopCheckbox;
private CheckBox startActivityTTCheckbox;
private CheckBox startEatingSoonTTCheckbox;
private Integer maxCarbs;
@ -103,7 +103,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
}
}
@ -127,6 +127,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
startEatingSoonTTCheckbox = view.findViewById(R.id.carbs_eating_soon_tt);
dateButton = view.findViewById(R.id.newcarbs_eventdate);
timeButton = view.findViewById(R.id.newcarb_eventtime);
@ -138,6 +139,10 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
dateButton.setOnClickListener(this);
timeButton.setOnClickListener(this);
//To be able to select only one TT at a time
startEatingSoonTTCheckbox.setOnClickListener(this);
startActivityTTCheckbox.setOnClickListener(this);
// TODO prefilling carbs, maybe
// TODO maybe update suggested carbs to target TT when checked
// APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult();
@ -147,13 +152,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
fav1Button = view.findViewById(R.id.newcarbs_plus1);
fav1Button.setOnClickListener(this);
fav1Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_1), String.valueOf(FAV1_DEFAULT)));
fav1Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_1, String.valueOf(FAV1_DEFAULT)));
fav2Button = view.findViewById(R.id.newcarbs_plus2);
fav2Button.setOnClickListener(this);
fav2Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_2), String.valueOf(FAV2_DEFAULT)));
fav2Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_2, String.valueOf(FAV2_DEFAULT)));
fav3Button = view.findViewById(R.id.newcarbs_plus3);
fav3Button.setOnClickListener(this);
fav3Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_3), String.valueOf(FAV3_DEFAULT)));
fav3Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_3, String.valueOf(FAV3_DEFAULT)));
suspendLoopCheckbox = view.findViewById(R.id.newcarbs_suspend_loop);
@ -197,19 +202,26 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
break;
case R.id.newcarbs_plus1:
editCarbs.setValue(editCarbs.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_1), FAV1_DEFAULT));
+ SP.getDouble(R.string.key_carbs_button_increment_1, FAV1_DEFAULT));
validateInputs();
break;
case R.id.newcarbs_plus2:
editCarbs.setValue(editCarbs.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_2), FAV2_DEFAULT));
+ SP.getDouble(R.string.key_carbs_button_increment_2, FAV2_DEFAULT));
validateInputs();
break;
case R.id.newcarbs_plus3:
editCarbs.setValue(editCarbs.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_3), FAV3_DEFAULT));
+ SP.getDouble(R.string.key_carbs_button_increment_3, FAV3_DEFAULT));
validateInputs();
break;
case R.id.newcarbs_activity_tt:
startEatingSoonTTCheckbox.setChecked(false);
break;
case R.id.carbs_eating_soon_tt:
startActivityTTCheckbox.setChecked(false);
break;
}
}
@ -227,20 +239,46 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
String confirmMessage = "";
if (carbs > 0)
confirmMessage += getString(R.string.carbs) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>";
confirmMessage += MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>";
if (!carbsAfterConstraints.equals(carbs))
confirmMessage += "<br/><font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + getString(R.string.carbsconstraintapplied) + "</font>";
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>";
if (suspendLoopCheckbox.isChecked()) {
confirmMessage += "<br/>" + "Loop: " + "<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + "Suspend for 30 min</font>";
confirmMessage += "<br/>" + MainApp.gs(R.string.loop) + ": " + "<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.suspendloopfor30min) + "</font>";
}
double prefTTDuration = SP.getDouble(R.string.key_activity_duration, 90d);
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 90d;
double prefTT = SP.getDouble(R.string.key_activity_target, 140d);
double tt = prefTT > 0 ? prefTT : 140d;
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if (currentProfile == null)
return;
int activityTTDuration = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration);
activityTTDuration = activityTTDuration > 0 ? activityTTDuration : Constants.defaultActivityTTDuration;
double activityTT = SP.getDouble(R.string.key_activity_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl);
activityTT = activityTT > 0 ? activityTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl;
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
eatingSoonTT = eatingSoonTT > 0 ? Profile.toMgdl(eatingSoonTT, currentProfile.getUnits()) : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
if (startActivityTTCheckbox.isChecked()) {
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>";
if (currentProfile.getUnits().equals(Constants.MMOL)) {
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + ((int) activityTTDuration) + " min)</font>";
} else
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + ((int) activityTTDuration) + " min)</font>";
}
if (startEatingSoonTTCheckbox.isChecked() && !startActivityTTCheckbox.isChecked()) {
if (currentProfile.getUnits().equals(Constants.MMOL)) {
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>";
} else
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>";
}
final double finalActivityTT = activityTT;
final double finalEatigSoonTT = eatingSoonTT;
final int finalActivityTTDuration = activityTTDuration;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
if (StringUtils.isNoneEmpty(food)) {
confirmMessage += "<br/>" + "Food: " + food;
@ -249,66 +287,80 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
if (!initialEventTime.equals(eventTime)) {
confirmMessage += "<br/> Time: " + DateUtil.dateAndTimeString(eventTime);
}
if (confirmMessage.length() > 0) {
final int finalCarbsAfterConstraints = carbsAfterConstraints;
final int finalCarbsAfterConstraints = carbsAfterConstraints;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(this.getContext().getString(R.string.confirmation));
if (confirmMessage.startsWith("<br/>"))
confirmMessage = confirmMessage.substring("<br/>".length());
builder.setMessage(Html.fromHtml(confirmMessage));
builder.setPositiveButton(getString(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
builder.setTitle(MainApp.gs(R.string.confirmation));
if (confirmMessage.startsWith("<br/>"))
confirmMessage = confirmMessage.substring("<br/>".length());
if (suspendLoopCheckbox.isChecked()) {
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
builder.setMessage(Html.fromHtml(confirmMessage));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (suspendLoopCheckbox.isChecked()) {
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
}
}
}
});
}
});
}
if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget();
tempTarget.date = System.currentTimeMillis();
tempTarget.durationInMinutes = (int) ttDuration;
tempTarget.reason = "Activity";
tempTarget.source = Source.USER;
tempTarget.low = (int) tt;
tempTarget.high = (int) tt;
MainApp.getDbHelper().createOrUpdate(tempTarget);
}
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());
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());
MainApp.getDbHelper().createOrUpdate(tempTarget);
}
if (finalCarbsAfterConstraints > 0 || food != null) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.date = eventTime.getTime();
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
if (finalCarbsAfterConstraints > 0 || food != null) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.date = eventTime.getTime();
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
// detailedBolusInfo.food = food;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
}
}
}
});
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
dismiss();
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
} else
dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
}
@Override
@ -326,4 +378,4 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
eventTime.setSeconds(second);
timeButton.setText(DateUtil.timeString(eventTime));
}
}
}

View file

@ -246,8 +246,19 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
double tt = prefTT > 0 ? prefTT : 80d;
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if(currentProfile == null)
return;
if(currentProfile.getUnits().equals(Constants.MMOL))
tt = prefTT > 0 ? Profile.toMgdl(prefTT, Constants.MMOL) : 80d;
else
tt = prefTT > 0 ? prefTT : 80d;
final double finalTT = tt;
if (startESMCheckbox.isChecked()) {
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>";
if(currentProfile.getUnits().equals("mmol")){
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min </font>";
} else
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>";
}
if (!initialEventTime.equals(eventTime)) {
@ -277,8 +288,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
tempTarget.durationInMinutes = (int) ttDuration;
tempTarget.reason = "Eating soon";
tempTarget.source = Source.USER;
tempTarget.low = (int) tt;
tempTarget.high = (int) tt;
tempTarget.low = (int) finalTT;
tempTarget.high = (int) finalTT;
MainApp.getDbHelper().createOrUpdate(tempTarget);
}
@ -339,4 +350,4 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
eventTime.setSeconds(second);
timeButton.setText(DateUtil.timeString(eventTime));
}
}
}

View file

@ -249,7 +249,7 @@ public class GraphData {
if (tt == null) {
value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2;
} else {
value = (tt.low + tt.high) / 2;
value = tt.target();
}
if (lastTarget > 0 && lastTarget != value) {
targetsSeriesArray.add(new DataPoint(time, lastTarget));

View file

@ -481,7 +481,7 @@ public class ActionStringHandler {
ret += "DEFAULT RANGE: ";
ret += profile.getTargetLow() + " - " + profile.getTargetHigh();
ret += " target: " + (profile.getTargetLow() + profile.getTargetHigh()) / 2;
ret += " target: " + profile.getTarget();
return ret;
}

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventBolusRequested;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventLoop;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventPreferenceChange;
@ -18,6 +19,7 @@ import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.Wear.wearintegration.WatchUpdaterService;
@ -168,6 +170,11 @@ public class WearPlugin implements PluginBase {
sendDataToWatch(true, true, false);
}
@Subscribe
public void onStatusEvent(final EventOpenAPSUpdateGui ev){
sendDataToWatch(true, true, false);
}
@Subscribe
public void onStatusEvent(final EventExtendedBolusChange ev) {
sendDataToWatch(true, true, false);
@ -197,7 +204,7 @@ public class WearPlugin implements PluginBase {
@Subscribe
public void onStatusEvent(final EventOverviewBolusProgress ev) {
if(!ev.isSMB()||SP.getBoolean("wear_notifySMB", false)) {
if(!ev.isSMB()||SP.getBoolean("wear_notifySMB", true)) {
Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS);
intent.putExtra("progresspercent", ev.percent);
intent.putExtra("progressstatus", ev.status);
@ -251,11 +258,4 @@ public class WearPlugin implements PluginBase {
public static void unRegisterWatchUpdaterService() {
watchUS = null;
}
public void overviewNotification(int id, String message) {
if(SP.getBoolean("wear_overview_notification", false)){
ActionStringHandler.expectNotificationAction(message, id);
}
}
}

View file

@ -6,6 +6,8 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.util.Log;
@ -19,11 +21,15 @@ import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import org.mozilla.javascript.tools.jsc.Main;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
@ -35,6 +41,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
@ -82,6 +89,7 @@ public class WatchUpdaterService extends WearableListenerService implements
private static Logger log = LoggerFactory.getLogger(WatchUpdaterService.class);
private Handler handler;
@Override
public void onCreate() {
@ -91,6 +99,11 @@ public class WatchUpdaterService extends WearableListenerService implements
if (wear_integration) {
googleApiConnect();
}
if (handler == null) {
HandlerThread handlerThread = new HandlerThread(this.getClass().getSimpleName() + "Handler");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
}
public void listenForChangeInSettings() {
@ -123,34 +136,33 @@ public class WatchUpdaterService extends WearableListenerService implements
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = null;
if (intent != null) {
action = intent.getAction();
}
String action = intent != null ? intent.getAction() : null;
if (wear_integration) {
if (googleApiClient.isConnected()) {
if (ACTION_RESEND.equals(action)) {
resendData();
} else if (ACTION_OPEN_SETTINGS.equals(action)) {
sendNotification();
} else if (ACTION_SEND_STATUS.equals(action)) {
sendStatus();
} else if (ACTION_SEND_BASALS.equals(action)) {
sendBasals();
} else if (ACTION_SEND_BOLUSPROGRESS.equals(action)) {
sendBolusProgress(intent.getIntExtra("progresspercent", 0), intent.hasExtra("progressstatus") ? intent.getStringExtra("progressstatus") : "");
} else if (ACTION_SEND_ACTIONCONFIRMATIONREQUEST.equals(action)) {
String title = intent.getStringExtra("title");
String message = intent.getStringExtra("message");
String actionstring = intent.getStringExtra("actionstring");
sendActionConfirmationRequest(title, message, actionstring);
handler.post(() -> {
if (googleApiClient.isConnected()) {
if (ACTION_RESEND.equals(action)) {
resendData();
} else if (ACTION_OPEN_SETTINGS.equals(action)) {
sendNotification();
} else if (ACTION_SEND_STATUS.equals(action)) {
sendStatus();
} else if (ACTION_SEND_BASALS.equals(action)) {
sendBasals();
} else if (ACTION_SEND_BOLUSPROGRESS.equals(action)) {
sendBolusProgress(intent.getIntExtra("progresspercent", 0), intent.hasExtra("progressstatus") ? intent.getStringExtra("progressstatus") : "");
} else if (ACTION_SEND_ACTIONCONFIRMATIONREQUEST.equals(action)) {
String title = intent.getStringExtra("title");
String message = intent.getStringExtra("message");
String actionstring = intent.getStringExtra("actionstring");
sendActionConfirmationRequest(title, message, actionstring);
} else {
sendData();
}
} else {
sendData();
googleApiClient.connect();
}
} else {
googleApiClient.connect();
}
});
}
return START_STICKY;
@ -345,11 +357,15 @@ public class WatchUpdaterService extends WearableListenerService implements
}
long now = System.currentTimeMillis();
long startTimeWindow = now - (long) (60000 * 60 * 5.5);
final long startTimeWindow = now - (long) (60000 * 60 * 5.5);
ArrayList<DataMap> basals = new ArrayList<>();
ArrayList<DataMap> temps = new ArrayList<>();
ArrayList<DataMap> boluses = new ArrayList<>();
ArrayList<DataMap> predictions = new ArrayList<>();
Profile profile = MainApp.getConfigBuilder().getProfile();
@ -447,9 +463,31 @@ public class WatchUpdaterService extends WearableListenerService implements
}
}
List<Treatment> treatments = MainApp.getConfigBuilder().getTreatmentsFromHistory();
for (Treatment treatment:treatments) {
if(treatment.date > startTimeWindow){
boluses.add(treatmentMap(treatment.date, treatment.insulin, treatment.carbs, treatment.isSMB, treatment.isValid));
}
}
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if(SP.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.request.hasPredictions && finalLastRun.constraintsProcessed != null){
List<BgReading> predArray = finalLastRun.constraintsProcessed.getPredictions();
if (!predArray.isEmpty()) {
for (BgReading bg : predArray) {
predictions.add(predictionMap(bg.date, bg.value));
}
}
}
DataMap dm = new DataMap();
dm.putDataMapArrayList("basals", basals);
dm.putDataMapArrayList("temps", temps);
dm.putDataMapArrayList("boluses", boluses);
dm.putDataMapArrayList("predictions", predictions);
new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient).execute(dm);
}
@ -472,6 +510,23 @@ public class WatchUpdaterService extends WearableListenerService implements
return dm;
}
private DataMap treatmentMap(long date, double bolus, double carbs, boolean isSMB, boolean isValid) {
DataMap dm = new DataMap();
dm.putLong("date", date);
dm.putDouble("bolus", bolus);
dm.putDouble("carbs", carbs);
dm.putBoolean("isSMB", isSMB);
dm.putBoolean("isValid", isValid);
return dm;
}
private DataMap predictionMap(long timestamp, double sgv) {
DataMap dm = new DataMap();
dm.putLong("timestamp", timestamp);
dm.putDouble("sgv", sgv);
return dm;
}
private void sendNotification() {
if (googleApiClient.isConnected()) {

View file

@ -184,7 +184,7 @@ public class StatuslinePlugin implements PluginBase {
TemporaryBasal activeTemp = treatmentsInterface.getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) {
status += activeTemp.toStringShort();
status += activeTemp.toStringShort() + " ";
}
//IOB

View file

@ -394,7 +394,9 @@
android:paddingRight="0dp"
android:text="@string/overview_treatment_label"
android:textColor="@color/colorTreatmentButton"
android:textSize="10sp" />
android:textSize="10sp"
android:visibility="gone"/>
<info.nightscout.utils.SingleClickButton
android:id="@+id/overview_insulinbutton"
@ -423,7 +425,8 @@
android:paddingRight="0dp"
android:text="@string/overview_carbs_label"
android:textColor="@color/colorCarbsButton"
android:textSize="10sp" />
android:textSize="10sp"
android:visibility="gone"/>
<info.nightscout.utils.SingleClickButton
android:id="@+id/overview_wizardbutton"
@ -467,7 +470,8 @@
android:paddingRight="0dp"
android:text="@string/overview_cgm"
android:textColor="@color/colorCalibrationButton"
android:textSize="10sp"/>
android:textSize="10sp"
android:visibility="gone"/>
<info.nightscout.utils.SingleClickButton
android:id="@+id/overview_quickwizardbutton"

View file

@ -34,23 +34,30 @@
<CheckBox
android:id="@+id/newcarbs_activity_tt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="@string/start_activity_tt" />
<CheckBox
android:id="@+id/carbs_eating_soon_tt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="Start activity TT"/>
android:text="@string/start_eating_soon_tt" />
<CheckBox
android:id="@+id/newcarbs_suspend_loop"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:text="Suspend loop for 30 min"/>
android:text="@string/suspendloopfor30min" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_gravity="center_horizontal">
android:layout_gravity="center_horizontal"
android:padding="5dp">
<TextView
android:id="@+id/newcarbs_eventdate"
@ -76,7 +83,7 @@
android:layout_gravity="center_horizontal"
android:width="180dp"
android:inputType="text|textCapWords"
android:visibility="gone"/>
android:visibility="gone" />
<info.nightscout.utils.NumberPicker
android:id="@+id/newcarb_carbsamount"
@ -91,8 +98,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginBottom="5dp">
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<Button
android:id="@+id/newcarbs_plus1"
@ -122,4 +129,4 @@
</LinearLayout>
</ScrollView>
</FrameLayout>
</FrameLayout>

View file

@ -34,14 +34,14 @@
<CheckBox
android:id="@+id/newinsulin_start_eating_soon_tt"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="Start eating soon TT" />
<CheckBox
android:id="@+id/newinsulin_record_only"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Don't bolus, record only" />
@ -115,4 +115,4 @@
</LinearLayout>
</ScrollView>
</FrameLayout>
</FrameLayout>

View file

@ -965,9 +965,15 @@
<string name="ns_create_announcements_from_errors_title">Create announcements from errors</string>
<string name="ns_create_announcements_from_errors_summary">Create Nightscout announcement for error dialogs and local alerts (also viewable in Careportal under Treatments)</string>
<string name="dexcomG5_shortname" translatable="false">G5</string>
<string name="wear_predictions_summary">Show the predictions on the watchface.</string>
<string name="wear_predictions_title">Predictions</string>
<string name="data_choices">Data Choices</string>
<string name="fabric_upload">Fabric Upload</string>
<string name="allow_automated_crash_reporting">Allow automated crash reporting and feature usage data to be sent to the developers via the fabric.io service.</string>
<string name="g5appnotdetected">Please update your G5 app to supported version</string>
<string name="suspendloopfor30min">Suspend for 30 min</string>
<string name="start_activity_tt">Start Activity TT</string>
<string name="start_eating_soon_tt">Start Eating soon TT</string>
<string name="temptargetshort">TT</string>
</resources>

View file

@ -32,10 +32,16 @@
android:title="@string/wear_showbgi_title" />
<SwitchPreference
android:defaultValue="false"
android:defaultValue="true"
android:key="wear_notifySMB"
android:summary="@string/wear_notifysmb_summary"
android:title="@string/wear_notifysmb_title" />
<SwitchPreference
android:defaultValue="true"
android:key="wear_predictions"
android:summary="@string/wear_predictions_summary"
android:title="@string/wear_predictions_title" />
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>
</PreferenceScreen>

View file

@ -16,6 +16,10 @@ public class BgWatchData implements Comparable<BgWatchData>{
this.timestamp = aTimestamp;
}
public BgWatchData(){
}
@Override
public boolean equals(Object that){
if(! (that instanceof BgWatchData)){

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.data;
/**
* Created by adrian on 17/11/16.
*/
public class BolusWatchData {
public long date;
public double bolus;
public double carbs;
public boolean isSMB;
public boolean isValid;
}

View file

@ -22,6 +22,7 @@ import android.support.v4.content.LocalBroadcastManager;
import android.support.wearable.view.WatchViewStub;
import android.support.wearable.watchface.WatchFaceStyle;
import android.text.format.DateFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
@ -32,18 +33,18 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.android.gms.wearable.DataMap;
import com.ustwo.clockwise.wearable.WatchFace;
import com.ustwo.clockwise.common.WatchFaceTime;
import com.ustwo.clockwise.common.WatchMode;
import com.ustwo.clockwise.common.WatchShape;
import com.ustwo.clockwise.wearable.WatchFace;
import java.util.ArrayList;
import java.util.Date;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.BasalWatchData;
import info.nightscout.androidaps.data.BgWatchData;
import info.nightscout.androidaps.data.BolusWatchData;
import info.nightscout.androidaps.data.ListenerService;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.TempWatchData;
import info.nightscout.androidaps.interaction.menus.MainMenuActivity;
import lecho.lib.hellocharts.view.LineChartView;
@ -53,6 +54,7 @@ import lecho.lib.hellocharts.view.LineChartView;
*/
public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPreferenceChangeListener {
public final static IntentFilter INTENT_FILTER;
public static final int SCREENSIZE_SMALL = 280;
public TextView mTime, mSgv, mTimestamp, mDelta, mAvgDelta;
public RelativeLayout mRelativeLayout;
public long sgvLevel = 0;
@ -64,6 +66,8 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
public int gridColour = Color.WHITE;
public int basalBackgroundColor = Color.BLUE;
public int basalCenterColor = Color.BLUE;
public int bolusColor = Color.MAGENTA;
public int carbsColor = Color.GREEN;
public int pointSize = 2;
public boolean lowResMode = false;
public boolean layoutSet = false;
@ -73,6 +77,9 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
public ArrayList<BgWatchData> bgDataList = new ArrayList<>();
public ArrayList<TempWatchData> tempWatchDataList = new ArrayList<>();
public ArrayList<BasalWatchData> basalWatchDataList = new ArrayList<>();
public ArrayList<BolusWatchData> bolusWatchDataList = new ArrayList<>();
public ArrayList<BgWatchData> predictionList = new ArrayList<>();
public PowerManager.WakeLock wakeLock;
public View layoutView;
private final Point displaySize = new Point();
@ -88,6 +95,8 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
private String batteryString = "--";
private String sgvString = "--";
private String externalStatusString = "no status";
private String cobString = "";
private TextView statusView;
private long chartTapTime = 0l;
private long sgvTapTime = 0l;
@ -108,7 +117,12 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
.getDefaultSharedPreferences(this);
sharedPrefs.registerOnSharedPreferenceChangeListener(this);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutView = inflater.inflate(R.layout.activity_bigchart, null);
DisplayMetrics metrics = getResources().getDisplayMetrics();
if(metrics.widthPixels < SCREENSIZE_SMALL || metrics.heightPixels < SCREENSIZE_SMALL){
layoutView = inflater.inflate(R.layout.activity_bigchart_small, null);
} else {
layoutView = inflater.inflate(R.layout.activity_bigchart, null);
}
performViewSetup();
}
@ -341,6 +355,8 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
DataMap dataMap = DataMap.fromBundle(bundle);
wakeLock.acquire(50);
externalStatusString = dataMap.getString("externalStatusString");
cobString = dataMap.getString("cob");
showAgeAndStatus();
@ -392,6 +408,29 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
basalWatchDataList.add(bwd);
}
}
ArrayList<DataMap> boluses = dataMap.getDataMapArrayList("boluses");
if (boluses != null) {
bolusWatchDataList = new ArrayList<>();
for (DataMap bolus : boluses) {
BolusWatchData bwd = new BolusWatchData();
bwd.date = bolus.getLong("date");
bwd.bolus = bolus.getDouble("bolus");
bwd.carbs = bolus.getDouble("carbs");
bwd.isSMB = bolus.getBoolean("isSMB");
bwd.isValid = bolus.getBoolean("isValid");
bolusWatchDataList.add(bwd);
}
}
ArrayList<DataMap> predictions = dataMap.getDataMapArrayList("predictions");
if (boluses != null) {
predictionList = new ArrayList<>();
for (DataMap prediction : predictions) {
BgWatchData bwd = new BgWatchData();
bwd.timestamp = prediction.getLong("timestamp");
bwd.sgv = prediction.getDouble("sgv");
predictionList.add(bwd);
}
}
}
private void showAgeAndStatus() {
@ -410,7 +449,12 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
}
if(showStatus){
statusView.setText(externalStatusString);
String status = externalStatusString;
if (sharedPrefs.getBoolean("show_cob", true)) {
status = externalStatusString + " " + cobString;
}
statusView.setText(status);
statusView.setVisibility(View.VISIBLE);
} else {
statusView.setVisibility(View.GONE);
@ -634,9 +678,9 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
if(bgDataList.size() > 0) { //Dont crash things just because we dont have values, people dont like crashy things
int timeframe = Integer.parseInt(sharedPrefs.getString("chart_timeframe", "3"));
if (lowResMode) {
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, pointSize, midColor, gridColour, basalBackgroundColor, basalCenterColor, timeframe);
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, carbsColor, timeframe);
} else {
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, pointSize, highColor, lowColor, midColor, gridColour, basalBackgroundColor, basalCenterColor, timeframe);
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, highColor, lowColor, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, carbsColor, timeframe);
}
chart.setLineChartData(bgGraphBuilder.lineData());
@ -646,4 +690,4 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre
ListenerService.requestData(this);
}
}
}
}

View file

@ -66,6 +66,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen
public int gridColor = Color.WHITE;
public int basalBackgroundColor = Color.BLUE;
public int basalCenterColor = Color.BLUE;
public int bolusColor = Color.MAGENTA;
public boolean lowResMode = false;
public boolean layoutSet = false;
public boolean bIsRound = false;
@ -75,6 +76,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen
public ArrayList<BgWatchData> bgDataList = new ArrayList<>();
public ArrayList<TempWatchData> tempWatchDataList = new ArrayList<>();
public ArrayList<BasalWatchData> basalWatchDataList = new ArrayList<>();
public ArrayList<BgWatchData> predictionList = new ArrayList<>();
public PowerManager.WakeLock wakeLock;
// related endTime manual layout
public View layoutView;
@ -628,9 +630,9 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen
if(bgDataList.size() > 0) { //Dont crash things just because we dont have values, people dont like crashy things
int timeframe = Integer.parseInt(sharedPrefs.getString("chart_timeframe", "3"));
if (lowResMode) {
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, pointSize, midColor, gridColor, basalBackgroundColor, basalCenterColor, timeframe);
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, null, pointSize, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, Color.GREEN, timeframe);
} else {
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, pointSize, highColor, lowColor, midColor, gridColor, basalBackgroundColor, basalCenterColor, timeframe);
bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList,predictionList, tempWatchDataList, basalWatchDataList, null, pointSize, highColor, lowColor, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, Color.GREEN, timeframe);
}
chart.setLineChartData(bgGraphBuilder.lineData());

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.watchfaces;
import android.content.Context;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.preference.PreferenceManager;
import android.text.format.DateFormat;
@ -8,13 +9,13 @@ import android.text.format.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import info.nightscout.androidaps.data.BasalWatchData;
import info.nightscout.androidaps.data.BgWatchData;
import info.nightscout.androidaps.data.BolusWatchData;
import info.nightscout.androidaps.data.TempWatchData;
import lecho.lib.hellocharts.model.Axis;
import lecho.lib.hellocharts.model.AxisValue;
@ -27,6 +28,10 @@ import lecho.lib.hellocharts.model.Viewport;
* Created by emmablack on 11/15/14.
*/
public class BgGraphBuilder {
public static final double MAX_PREDICTION__TIME_RATIO = (3d / 5);
private long predictionEndTime;
private List<BgWatchData> predictionsList;
private ArrayList<BolusWatchData> bolusWatchDataList;
private ArrayList<BasalWatchData> basalWatchDataList;
public List<TempWatchData> tempWatchDataList;
private int timespan;
@ -45,9 +50,11 @@ public class BgGraphBuilder {
public int gridColour;
public int basalCenterColor;
public int basalBackgroundColor;
private int bolusInvalidColor;
private int carbsColor;
public boolean singleLine = false;
private long endHour;
private List<PointValue> inRangeValues = new ArrayList<PointValue>();
private List<PointValue> highValues = new ArrayList<PointValue>();
private List<PointValue> lowValues = new ArrayList<PointValue>();
@ -55,10 +62,10 @@ public class BgGraphBuilder {
//used for low resolution screen.
public BgGraphBuilder(Context context, List<BgWatchData> aBgList, List<TempWatchData> tempWatchDataList, ArrayList<BasalWatchData> basalWatchDataList, int aPointSize, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int timespan) {
end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.)
start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago
public BgGraphBuilder(Context context, List<BgWatchData> aBgList, List<BgWatchData> predictionsList, List<TempWatchData> tempWatchDataList, ArrayList<BasalWatchData> basalWatchDataList, ArrayList<BolusWatchData> bolusWatchDataList, int aPointSize, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusInvalidColor, int carbsColor, int timespan) {
this.start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago
this.bgDataList = aBgList;
this.predictionsList = predictionsList;
this.context = context;
this.highMark = aBgList.get(aBgList.size() - 1).high;
this.lowMark = aBgList.get(aBgList.size() - 1).low;
@ -70,15 +77,21 @@ public class BgGraphBuilder {
this.timespan = timespan;
this.tempWatchDataList = tempWatchDataList;
this.basalWatchDataList = basalWatchDataList;
this.bolusWatchDataList = (bolusWatchDataList!=null)?bolusWatchDataList:new ArrayList<BolusWatchData>();
this.gridColour = gridColour;
this.basalCenterColor = basalCenterColor;
this.basalBackgroundColor = basalBackgroundColor;
this.bolusInvalidColor = bolusInvalidColor;
this.carbsColor = carbsColor;
this.end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.)
this.predictionEndTime = getPredictionEndTime();
this.end_time = (predictionEndTime>end_time)?predictionEndTime:end_time;
}
public BgGraphBuilder(Context context, List<BgWatchData> aBgList, List<TempWatchData> tempWatchDataList, ArrayList<BasalWatchData> basalWatchDataList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int timespan) {
end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.)
start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago
public BgGraphBuilder(Context context, List<BgWatchData> aBgList, List<BgWatchData> predictionsList, List<TempWatchData> tempWatchDataList, ArrayList<BasalWatchData> basalWatchDataList, ArrayList<BolusWatchData> bolusWatchDataList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusInvalidColor, int carbsColor, int timespan) {
this.start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago
this.bgDataList = aBgList;
this.predictionsList = predictionsList;
this.context = context;
this.highMark = aBgList.get(aBgList.size() - 1).high;
this.lowMark = aBgList.get(aBgList.size() - 1).low;
@ -89,9 +102,15 @@ public class BgGraphBuilder {
this.timespan = timespan;
this.tempWatchDataList = tempWatchDataList;
this.basalWatchDataList = basalWatchDataList;
this.bolusWatchDataList = (bolusWatchDataList!=null)?bolusWatchDataList:new ArrayList<BolusWatchData>();
this.gridColour = gridColour;
this.basalCenterColor = basalCenterColor;
this.basalBackgroundColor = basalBackgroundColor;
this.bolusInvalidColor = bolusInvalidColor;
this.carbsColor = carbsColor;
this.end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.)
this.predictionEndTime = getPredictionEndTime();
this.end_time = (predictionEndTime>end_time)?predictionEndTime:end_time;
}
public LineChartData lineData() {
@ -102,6 +121,7 @@ public class BgGraphBuilder {
}
public List<Line> defaultLines() {
addBgReadingValues();
List<Line> lines = new ArrayList<Line>();
lines.add(highLine());
@ -154,6 +174,12 @@ public class BgGraphBuilder {
}
lines.add(basalLine((float) minChart, factor, highlight));
lines.add(bolusLine((float) minChart));
lines.add(bolusInvalidLine((float) minChart));
lines.add(carbsLine((float) minChart));
lines.add(smbLine((float) minChart));
lines.add(predictionLine());
return lines;
}
@ -180,6 +206,98 @@ public class BgGraphBuilder {
}
private Line bolusLine(float offset) {
List<PointValue> pointValues = new ArrayList<PointValue>();
for (BolusWatchData bwd: bolusWatchDataList) {
if(bwd.date > start_time && bwd.date <= end_time && !bwd.isSMB && bwd.isValid && bwd.bolus > 0) {
pointValues.add(new PointValue(fuzz(bwd.date), (float) offset-2));
}
}
Line line = new Line(pointValues);
line.setColor(basalCenterColor);
line.setHasLines(false);
line.setPointRadius(pointSize*2);
line.setHasPoints(true);
return line;
}
private Line smbLine(float offset) {
List<PointValue> pointValues = new ArrayList<PointValue>();
for (BolusWatchData bwd: bolusWatchDataList) {
if(bwd.date > start_time && bwd.date <= end_time && bwd.isSMB && bwd.isValid && bwd.bolus > 0) {
pointValues.add(new PointValue(fuzz(bwd.date), (float) offset-2));
}
}
Line line = new Line(pointValues);
line.setColor(basalCenterColor);
line.setHasLines(false);
line.setPointRadius(pointSize);
line.setHasPoints(true);
return line;
}
private Line bolusInvalidLine(float offset) {
List<PointValue> pointValues = new ArrayList<PointValue>();
for (BolusWatchData bwd: bolusWatchDataList) {
if(bwd.date > start_time && bwd.date <= end_time && !(bwd.isValid && (bwd.bolus > 0 || bwd.carbs > 0))) {
pointValues.add(new PointValue(fuzz(bwd.date), (float) offset-2));
}
}
Line line = new Line(pointValues);
line.setColor(bolusInvalidColor);
line.setHasLines(false);
line.setPointRadius(pointSize);
line.setHasPoints(true);
return line;
}
private Line carbsLine(float offset) {
List<PointValue> pointValues = new ArrayList<PointValue>();
for (BolusWatchData bwd: bolusWatchDataList) {
if(bwd.date > start_time && bwd.date <= end_time && !bwd.isSMB && bwd.isValid && bwd.carbs > 0) {
pointValues.add(new PointValue(fuzz(bwd.date), (float) offset+2));
}
}
Line line = new Line(pointValues);
line.setColor(carbsColor);
line.setHasLines(false);
line.setPointRadius(pointSize*2);
line.setHasPoints(true);
return line;
}
private Line predictionLine() {
List<PointValue> pointValues = new ArrayList<PointValue>();
long endTime = getPredictionEndTime();
for (BgWatchData bwd: predictionsList) {
if(bwd.timestamp <= endTime) {
pointValues.add(new PointValue(fuzz(bwd.timestamp), (float) bwd.sgv));
}
}
Line line = new Line(pointValues);
line.setColor(Color.MAGENTA);
line.setHasLines(false);
int size = pointSize/2;
size = (size>0)?size:1;
line.setPointRadius(size);
line.setHasPoints(true);
return line;
}
public Line highValuesLine() {
Line highValuesLine = new Line(highValues);
highValuesLine.setColor(highColor);
@ -309,38 +427,42 @@ public class BgGraphBuilder {
public Axis xAxis() {
final boolean is24 = DateFormat.is24HourFormat(context);
SimpleDateFormat timeFormat = new SimpleDateFormat(is24? "HH" : "h a");
timeFormat.setTimeZone(TimeZone.getDefault());
long timeNow = System.currentTimeMillis();
Axis xAxis = new Axis();
xAxis.setAutoGenerated(false);
List<AxisValue> xAxisValues = new ArrayList<AxisValue>();
GregorianCalendar now = new GregorianCalendar();
GregorianCalendar today = new GregorianCalendar(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
SimpleDateFormat timeFormat = new SimpleDateFormat(is24? "HH" : "h a");
timeFormat.setTimeZone(TimeZone.getDefault());
long start_hour = today.getTime().getTime();
long timeNow = System.currentTimeMillis();
for (int l = 0; l <= 24; l++) {
if ((start_hour + (60000 * 60 * (l))) < timeNow) {
if ((start_hour + (60000 * 60 * (l + 1))) >= timeNow) {
endHour = start_hour + (60000 * 60 * (l));
l = 25;
}
}
}
//get the time-tick at the full hour after start_time
GregorianCalendar startGC = new GregorianCalendar();
startGC.setTimeInMillis(start_time);
startGC.set(Calendar.MILLISECOND, 0);
startGC.set(Calendar.SECOND, 0);
startGC.set(Calendar.MINUTE, 0);
startGC.add(Calendar.HOUR, 1);
long start_hour = startGC.getTimeInMillis();
//Display current time on the graph
SimpleDateFormat longTimeFormat = new SimpleDateFormat(is24? "HH:mm" : "h:mm a");
xAxisValues.add(new AxisValue(fuzz(timeNow), (longTimeFormat.format(timeNow)).toCharArray()));
xAxisValues.add(new AxisValue(fuzz(timeNow)).setLabel((longTimeFormat.format(timeNow))));
//Add whole hours endTime the axis (as long as they are more than 15 mins away from the current time)
for (int l = 0; l <= 24; l++) {
long timestamp = endHour - (60000 * 60 * l);
if((timestamp - timeNow < 0) && (timestamp > start_time)) {
if(Math.abs(timestamp - timeNow) > (1000 * 60 * 8 * timespan)){
xAxisValues.add(new AxisValue(fuzz(timestamp), (timeFormat.format(timestamp)).toCharArray()));
}else {
xAxisValues.add(new AxisValue(fuzz(timestamp), "".toCharArray()));
}
long hourTick = start_hour;
// add all full hours within the timeframe
while (hourTick < end_time){
if(Math.abs(hourTick - timeNow) > (1000 * 60 * 8 * timespan)){
xAxisValues.add(new AxisValue(fuzz(hourTick)).setLabel(timeFormat.format(hourTick)));
} else {
//don't print hour label if too close to now to avoid overlaps
xAxisValues.add(new AxisValue(fuzz(hourTick)).setLabel(""));
}
//increment by one hour
hourTick += 60*60*1000;
}
xAxis.setValues(xAxisValues);
xAxis.setTextSize(10);
xAxis.setHasLines(true);
@ -350,6 +472,17 @@ public class BgGraphBuilder {
return xAxis;
}
public long getPredictionEndTime() {
long maxPredictionDate = System.currentTimeMillis();
for (BgWatchData prediction :
predictionsList) {
if (maxPredictionDate < prediction.timestamp) {
maxPredictionDate = prediction.timestamp;
}
}
return (long) Math.min(maxPredictionDate, System.currentTimeMillis() + MAX_PREDICTION__TIME_RATIO *timespan*1000*60*60);
}
public float fuzz(long value) {
return (float) Math.round(value / fuzzyTimeDenom);
}

View file

@ -13,6 +13,7 @@ import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Shader;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
@ -22,6 +23,7 @@ import android.support.v4.content.LocalBroadcastManager;
import android.support.wearable.view.WatchViewStub;
import android.support.wearable.watchface.WatchFaceStyle;
import android.text.format.DateFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
@ -30,6 +32,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.wearable.DataMap;
import com.ustwo.clockwise.common.WatchFaceTime;
@ -40,6 +43,7 @@ import com.ustwo.clockwise.wearable.WatchFace;
import java.util.ArrayList;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.data.BasalWatchData;
import info.nightscout.androidaps.data.BgWatchData;
import info.nightscout.androidaps.data.ListenerService;
@ -52,6 +56,7 @@ import lecho.lib.hellocharts.view.LineChartView;
*/
public class NOChart extends WatchFace implements SharedPreferences.OnSharedPreferenceChangeListener {
public final static IntentFilter INTENT_FILTER;
public static final int SCREENSIZE_SMALL = 280;
public TextView mTime, mSgv, mTimestamp, mDelta, mAvgDelta;
public RelativeLayout mRelativeLayout;
public long sgvLevel = 0;
@ -96,6 +101,12 @@ public class NOChart extends WatchFace implements SharedPreferences.OnSharedPref
sharedPrefs.registerOnSharedPreferenceChangeListener(this);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutView = inflater.inflate(R.layout.activity_nochart, null);
DisplayMetrics metrics = getResources().getDisplayMetrics();
if(metrics.widthPixels < SCREENSIZE_SMALL || metrics.heightPixels < SCREENSIZE_SMALL){
layoutView = inflater.inflate(R.layout.activity_nochart_small, null);
} else {
layoutView = inflater.inflate(R.layout.activity_nochart, null);
}
performViewSetup();
}
@ -514,4 +525,4 @@ public class NOChart extends WatchFace implements SharedPreferences.OnSharedPref
ListenerService.requestData(this); // attempt endTime recover missing data
}
}
}
}

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
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:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_bigchart_small"
app:roundLayout="@layout/round_activity_bigchart_small"
tools:context=".watchfaces.Home"
tools:deviceIds="wear"/>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
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:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_nochart_small"
app:roundLayout="@layout/round_activity_nochart_small"
tools:context=".watchfaces.Home"
tools:deviceIds="wear"/>

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".watchfaces.Home" tools:deviceIds="wear_square"
android:background="@color/black"
android:id="@+id/main_layout">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAlignment="center">
<TextView
android:id="@+id/delta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginRight="5dp"
android:gravity="center_horizontal|bottom"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
<TextView
android:id="@+id/sgv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="34sp" />
<TextView
android:id="@+id/avgdelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginLeft="5dp"
android:gravity="center_horizontal|bottom"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
<TextView
android:id="@+id/aps_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5sp"
android:text="E xU/h IOB: x (x+x)"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<lecho.lib.hellocharts.view.LineChartView
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:layout_weight="1"
android:gravity="center_horizontal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-5sp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:textAlignment="center">
<TextView
android:id="@+id/watch_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginRight="6dp"
android:paddingTop="-5sp"
android:text="12:00"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="34sp" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:text="--'"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".watchfaces.Home" tools:deviceIds="wear_square"
android:background="@color/black"
android:id="@+id/main_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical"
android:textAlignment="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAlignment="center">
<TextView
android:id="@+id/delta"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:layout_marginRight="5dp"
android:gravity="center_vertical|center_horizontal|center"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
<TextView
android:id="@+id/sgv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="45sp" />
<TextView
android:id="@+id/avgdelta"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:gravity="center_vertical|center_horizontal|center"
android:text=" ---"
android:textColor="#FFFFFF"
android:textSize="26sp" />
</LinearLayout>
<View
android:id="@+id/dummy1"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="bottom"
android:gravity="center_horizontal" />
<TextView
android:id="@+id/aps_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="No Loop Status"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="21sp" />
<View
android:id="@+id/dummy2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="bottom"
android:layout_weight="0"
android:gravity="center_horizontal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
android:orientation="horizontal"
android:textAlignment="center">
<TextView
android:id="@+id/watch_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginRight="6dp"
android:text="23:24"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="45sp" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:text="--'"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".watchfaces.Home" tools:deviceIds="wear_square"
android:background="@color/black"
android:id="@+id/main_layout">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAlignment="center">
<TextView
android:id="@+id/delta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginRight="5dp"
android:gravity="center_horizontal|bottom"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
<TextView
android:id="@+id/sgv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="34sp" />
<TextView
android:id="@+id/avgdelta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginLeft="5dp"
android:gravity="center_horizontal|bottom"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
<TextView
android:id="@+id/aps_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5sp"
android:text="E xU/h IOB: x (x+x)"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="18sp" />
<lecho.lib.hellocharts.view.LineChartView
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:layout_weight="1"
android:gravity="center_horizontal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-5sp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:textAlignment="center">
<TextView
android:id="@+id/watch_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginRight="6dp"
android:paddingTop="-5sp"
android:text="12:00"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="34sp" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:text="--'"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".watchfaces.Home" tools:deviceIds="wear_square"
android:background="@color/black"
android:id="@+id/main_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical"
android:textAlignment="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-5dp"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAlignment="center">
<TextView
android:id="@+id/delta"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:layout_marginRight="5dp"
android:gravity="center_vertical|center_horizontal|center"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="24sp" />
<TextView
android:id="@+id/sgv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="---"
android:textColor="#FFFFFF"
android:textSize="45sp" />
<TextView
android:id="@+id/avgdelta"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:gravity="center_vertical|center_horizontal|center"
android:text=" ---"
android:textColor="#FFFFFF"
android:textSize="26sp" />
</LinearLayout>
<View
android:id="@+id/dummy1"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="bottom"
android:gravity="center_horizontal" />
<TextView
android:id="@+id/aps_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="No Loop Status"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="21sp" />
<View
android:id="@+id/dummy2"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="bottom"
android:layout_weight="0"
android:gravity="center_horizontal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
android:orientation="horizontal"
android:textAlignment="center">
<TextView
android:id="@+id/watch_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginRight="6dp"
android:text="23:24"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="45sp" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:text="--'"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>