Merge branch 'dev' into dev

This commit is contained in:
Tebbe Ubben 2018-04-21 23:22:02 +02:00 committed by GitHub
commit f4e02a4862
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 1526 additions and 951 deletions

View file

@ -63,7 +63,7 @@ android {
targetSdkVersion 25
multiDexEnabled true
versionCode 1500
version "1.60d-dev"
version "1.60e-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

View file

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

View file

@ -59,6 +59,7 @@ public class Constants {
//Autosens
public static final double DEVIATION_TO_BE_EQUAL = 2.0;
public static final double DEFAULT_MAX_ABSORPTION_TIME = 6.0;
// Pump
public static final int PUMP_MAX_CONNECTION_TIME_IN_SECONDS = 120 - 1;

View file

@ -46,7 +46,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
ImageButton chartButton;
boolean showBasal = true;
boolean showIob, showCob, showDev, showRat;
boolean showIob, showCob, showDev, showRat, showDevslope;
@BindView(R.id.historybrowse_date)
@ -267,6 +267,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
boolean useCobForScale = false;
boolean useDevForScale = false;
boolean useRatioForScale = false;
boolean useDevSlopeForScale = false;
if (showIob) {
useIobForScale = true;
@ -276,6 +277,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
useDevForScale = true;
} else if (showRat) {
useRatioForScale = true;
} else if (showDevslope) {
useDevSlopeForScale = true;
}
if (showIob)
@ -286,6 +289,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
if (showRat)
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
if (showDevslope)
secondGraphData.addDeviationSlope(fromTime, toTime, useDevSlopeForScale, 1d);
// **** NOW line ****
// set manual x bounds to have nice steps
@ -293,7 +298,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
secondGraphData.addNowLine(pointer);
// do GUI update
if (showIob || showCob || showDev || showRat) {
if (showIob || showCob || showDev || showRat || showDevslope) {
iobGraph.setVisibility(View.VISIBLE);
} else {
iobGraph.setVisibility(View.GONE);
@ -354,23 +359,31 @@ public class HistoryBrowseActivity extends AppCompatActivity {
item.setCheckable(true);
item.setChecked(showRat);
if (MainApp.devBranch) {
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
title = item.getTitle();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(showDevslope);
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
showBasal = !item.isChecked();
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
showIob = !item.isChecked();
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
showCob = !item.isChecked();
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
showDev = !item.isChecked();
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
showRat = !item.isChecked();
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) {
showDevslope = !item.isChecked();
}
updateGUI("onGraphCheckboxesCheckedChanged");
return true;

View file

@ -67,7 +67,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
MainApp.bus().post(new EventRefreshGui());
}
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
OKDialog.show(this, MainApp.sResources.getString(R.string.configbuilder_sensitivity), MainApp.sResources.getString(R.string.sensitivity_warning), null);
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
}
updatePrefSummary(myPreferenceFragment.getPreference(key));
}
@ -81,13 +81,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
EditTextPreference editTextPref = (EditTextPreference) pref;
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
pref.setSummary("******");
} else if (pref.getKey().equals(MainApp.sResources.getString(R.string.key_danars_name))) {
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
} else if (editTextPref.getText() != null && !editTextPref.getText().equals("")) {
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText());
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) {
pref.setSummary(MainApp.sResources.getString(R.string.smscommunicator_allowednumbers_summary));
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary));
}
}
}
@ -127,9 +127,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
if (id != -1) {
addPreferencesFromResource(id);
addPreferencesFromResource(R.xml.pref_advanced);
} else {
addPreferencesFromResource(R.xml.pref_overview);
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
addPreferencesFromResource(R.xml.pref_password);
@ -137,9 +135,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResource(R.xml.pref_age);
addPreferencesFromResource(R.xml.pref_language);
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
addPreferencesFromResource(R.xml.pref_quickwizard);
}
addPreferencesFromResource(R.xml.pref_overview);
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginType.BGSOURCE);
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginType.CONSTRAINTS);

View file

@ -130,7 +130,7 @@ public class DataService extends IntentService {
handleNewDataFromDexcomG5(intent);
}
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
if (nsClientEnabled || SP.getBoolean(R.string.ns_autobackfill, true))
if (nsClientEnabled || SP.getBoolean(R.string.key_ns_autobackfill, true))
handleNewDataFromNSClient(intent);
// Objectives 0
ObjectivesPlugin.bgIsAvailableInNS = true;
@ -197,7 +197,8 @@ public class DataService extends IntentService {
bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME);
bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP);
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW);
String source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified");
SourceXdripPlugin.getPlugin().setSource(source);
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP");
}

View file

@ -37,6 +37,8 @@ public interface Intents {
String EXTRA_SENSOR_BATTERY = "com.eveningoutpost.dexdrip.Extras.SensorBattery";
String EXTRA_TIMESTAMP = "com.eveningoutpost.dexdrip.Extras.Time";
String EXTRA_RAW = "com.eveningoutpost.dexdrip.Extras.Raw";
String XDRIP_DATA_SOURCE_DESCRIPTION = "com.eveningoutpost.dexdrip.Extras.SourceDesc";
String ACTION_NEW_BG_ESTIMATE_NO_DATA = "com.eveningoutpost.dexdrip.BgEstimateNoData";

View file

@ -11,4 +11,5 @@ public class MealData {
public double slopeFromMinDeviation = 999;
public long lastBolusTime;
public long lastCarbTime = 0L;
public double usedMinCarbsImpact = 0d;
}

View file

@ -195,8 +195,7 @@ public class BgReading implements DataPointWithLabelInterface {
@Override
public float getSize() {
boolean isTablet = MainApp.sResources.getBoolean(R.bool.isTablet);
return isTablet ? 8 : 5;
return 1;
}
@Override

View file

@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
@ -45,6 +46,7 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistor
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.utils.JsonHelper;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.PercentageSplitter;
import info.nightscout.utils.ToastUtils;
@ -662,7 +664,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try {
String units = MainApp.getConfigBuilder().getProfileUnits();
String units = JsonHelper.safeGetString(trJson, "units", MainApp.getConfigBuilder().getProfileUnits());
TempTarget tempTarget = new TempTarget()
.date(trJson.getLong("mills"))
.duration(trJson.getInt("duration"))

View file

@ -5,7 +5,9 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -14,6 +16,8 @@ import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
@ -21,8 +25,6 @@ import com.google.common.base.Joiner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Constants;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
@ -41,19 +43,45 @@ import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
import static info.nightscout.utils.DateUtil.now;
public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
private CheckBox pumpSiteChangeCheckbox;
private CheckBox insulinCartridgeChangeCheckbox;
private NumberPicker editInsulin;
double amount1 = 0d;
double amount2 = 0d;
double amount3 = 0d;
NumberPicker editInsulin;
CheckBox pumpSiteChangeCheckbox;
CheckBox insulinCartridgeChangeCheckbox;
private EditText notesEdit;
public FillDialog() {
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
private void validateInputs() {
int time = editInsulin.getValue().intValue();
if (Math.abs(time) > 12 * 60) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
}
@Override
@ -67,45 +95,47 @@ public class FillDialog extends DialogFragment implements OnClickListener {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
pumpSiteChangeCheckbox = view.findViewById(R.id.catheter_change);
insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change);
pumpSiteChangeCheckbox = view.findViewById(R.id.fill_catheter_change);
insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false);
editInsulin = view.findViewById(R.id.fill_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
//setup preset buttons
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
Button preset1Button = view.findViewById(R.id.fill_preset_button1);
amount1 = SP.getDouble("fill_button1", 0.3);
amount2 = SP.getDouble("fill_button2", 0d);
amount3 = SP.getDouble("fill_button3", 0d);
if (amount1 > 0) {
button1.setVisibility(View.VISIBLE);
button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
button1.setOnClickListener(this);
preset1Button.setVisibility(View.VISIBLE);
preset1Button.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
preset1Button.setOnClickListener(this);
} else {
button1.setVisibility(View.GONE);
preset1Button.setVisibility(View.GONE);
}
Button preset2Button = view.findViewById(R.id.fill_preset_button2);
amount2 = SP.getDouble("fill_button2", 0d);
if (amount2 > 0) {
button2.setVisibility(View.VISIBLE);
button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
button2.setOnClickListener(this);
preset2Button.setVisibility(View.VISIBLE);
preset2Button.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
preset2Button.setOnClickListener(this);
} else {
button2.setVisibility(View.GONE);
preset2Button.setVisibility(View.GONE);
}
Button preset3Button = view.findViewById(R.id.fill_preset_button3);
amount3 = SP.getDouble("fill_button3", 0d);
if (amount3 > 0) {
button3.setVisibility(View.VISIBLE);
button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
button3.setOnClickListener(this);
preset3Button.setVisibility(View.VISIBLE);
preset3Button.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
preset3Button.setOnClickListener(this);
} else {
button3.setVisibility(View.GONE);
preset3Button.setVisibility(View.GONE);
}
LinearLayout notesLayout = view.findViewById(R.id.fill_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.fill_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
@ -154,42 +184,50 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (insulinCartridgeChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_insulin_cartridge_change) + "</font>");
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
confirmMessage.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (confirmMessage.isEmpty())
confirmMessage.add(MainApp.gs(R.string.no_action_selected));
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
detailedBolusInfo.notes = notes;
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
}
});
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
}
long now = System.currentTimeMillis();
if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now);
if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000);
});
});
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
}
if (pumpSiteChangeCheckbox.isChecked())
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
if (insulinCartridgeChangeCheckbox.isChecked())
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
dismiss();

View file

@ -51,6 +51,7 @@ import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.JsonHelper;
@ -210,19 +211,22 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
}
boolean erase = false;
String units = MainApp.getConfigBuilder().getProfileUnits();
DefaultValueHelper helper = new DefaultValueHelper();
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
defaultDuration = SP.getDouble(R.string.key_eatingsoon_duration, 0d);
defaultTarget = SP.getDouble(R.string.key_eatingsoon_target, 0d);
defaultDuration = helper.determineEatingSoonTTDuration();
defaultTarget = helper.determineEatingSoonTT(units);
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
defaultDuration = SP.getDouble(R.string.key_activity_duration, 0d);
defaultTarget = SP.getDouble(R.string.key_activity_target, 0d);
defaultDuration = helper.determineActivityTTDuration();
defaultTarget = helper.determineActivityTT(units);
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
defaultDuration = SP.getDouble(R.string.key_hypo_duration, 0d);
defaultTarget = SP.getDouble(R.string.key_hypo_target, 0d);
defaultDuration = helper.determineHypoTTDuration();
defaultTarget = helper.determineHypoTT(units);
} else {
defaultDuration = 0;
erase = true;
}
if (defaultTarget != 0 || erase) {
editTemptarget.setValue(defaultTarget);
}

View file

@ -7,20 +7,25 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.utils.SP;
/**
* Created by mike on 25.04.2017.
*/
public class AutosensData {
public class AutosensData implements DataPointWithLabelInterface {
private static Logger log = LoggerFactory.getLogger(AutosensData.class);
static class CarbsInPast {
@ -34,14 +39,14 @@ public class AutosensData {
carbs = t.carbs;
remaining = t.carbs;
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, 4d);
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
double ic = profile.getIc(t.date);
min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic;
log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
} else {
min5minCarbImpact = SP.getDouble("openapsama_min_5m_carbimpact", 3.0);
min5minCarbImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
}
}
}
@ -63,25 +68,33 @@ public class AutosensData {
public double autosensRatio = 1d;
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public double usedMinCarbsImpact = 0d;
public boolean failoverToMinAbsorbtionRate = false;
@Override
public String toString() {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ;
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation;
}
public int minOld() {
return (int) ((System.currentTimeMillis() - time) / 1000 / 60);
}
// remove carbs older than 4h
// remove carbs older than timeframe
public void removeOldCarbs(long toTime) {
double maxAbsorptionHours = Constants.DEFAULT_MAX_ABSORPTION_TIME;
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
} else {
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
}
for (int i = 0; i < activeCarbsList.size(); i++) {
CarbsInPast c = activeCarbsList.get(i);
if (c.time + 4 * 60 * 60 * 1000L < toTime) {
if (c.time + maxAbsorptionHours * 60 * 60 * 1000L < toTime) {
activeCarbsList.remove(i--);
if (c.remaining > 0)
cob -= c.remaining;
log.debug("Removing carbs at "+ new Date(toTime).toLocaleString() + " + after 4h :" + new Date(c.time).toLocaleString());
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString());
}
}
}
@ -98,4 +111,57 @@ public class AutosensData {
}
}
// ------- DataPointWithLabelInterface ------
private Scale scale;
public void setScale(Scale scale) {
this.scale = scale;
}
@Override
public double getX() {
return time;
}
@Override
public double getY() {
return scale.transform(cob);
}
@Override
public void setY(double y) {
}
@Override
public String getLabel() {
return null;
}
@Override
public long getDuration() {
return 0;
}
@Override
public PointsWithLabelGraphSeries.Shape getShape() {
return PointsWithLabelGraphSeries.Shape.COBFAILOVER;
}
@Override
public float getSize() {
return 1f;
}
@Override
public int getColor() {
return MainApp.gc(R.color.cob);
}
@Override
public int getSecondColor() {
return 0;
}
}

View file

@ -74,7 +74,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
.neverVisible(true)
.alwaysEnabled(true)
);
}
}
@Override
protected void onStart() {
@ -548,7 +548,9 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
if (ev.isChanged(R.string.key_openapsama_autosens_period) ||
ev.isChanged(R.string.key_age) ||
ev.isChanged(R.string.key_absorption_maxtime)
ev.isChanged(R.string.key_absorption_maxtime) ||
ev.isChanged(R.string.key_openapsama_min_5m_carbimpact) ||
ev.isChanged(R.string.key_absorption_cutoff)
) {
stopCalculation("onEventPreferenceChange");
synchronized (dataLock) {

View file

@ -17,15 +17,22 @@ import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP;
/**
* Created by mike on 23.01.2018.
@ -91,6 +98,8 @@ public class IobCobThread extends Thread {
AutosensData previous = autosensDataTable.get(prevDataTime);
// start from oldest to be able sub cob
for (int i = bucketed_data.size() - 4; i >= 0; i--) {
MainApp.bus().post(new EventIobCalculationProgress(i + "/" + bucketed_data.size()));
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
iobCobCalculatorPlugin.stopCalculationTrigger = false;
log.debug("Aborting calculation thread (trigger): " + from);
@ -199,18 +208,27 @@ public class IobCobThread extends Thread {
if (previous != null && previous.cob > 0) {
// calculate sum of min carb impact from all active treatments
double totalMinCarbsImpact = 0d;
for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) {
AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii);
totalMinCarbsImpact += c.min5minCarbImpact;
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
//when the impact depends on a max time, sum them up as smaller carb sizes make them smaller
for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) {
AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii);
totalMinCarbsImpact += c.min5minCarbImpact;
}
} else {
//Oref sensitivity
totalMinCarbsImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
}
// figure out how many carbs that represents
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
double ci = Math.max(deviation, totalMinCarbsImpact);
if (ci != deviation)
autosensData.failoverToMinAbsorbtionRate = true;
autosensData.absorbed = ci * profile.getIc(bgTime) / sens;
// and add that to the running total carbsAbsorbed
autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d);
autosensData.substractAbosorbedCarbs();
autosensData.usedMinCarbsImpact = totalMinCarbsImpact;
}
autosensData.removeOldCarbs(bgTime);
autosensData.cob += autosensData.carbsFromBolus;
@ -254,6 +272,7 @@ public class IobCobThread extends Thread {
log.debug("Finishing calculation thread: " + from);
} finally {
mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress(""));
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.plugins.IobCobCalculator.events;
import info.nightscout.androidaps.events.Event;
public class EventIobCalculationProgress extends Event {
public String progress;
public EventIobCalculationProgress(String progress) {
this.progress = progress;
}
}

View file

@ -213,8 +213,12 @@ public class DetermineBasalAdapterAMAJS {
mProfile.put("current_basal", basalrate);
mProfile.put("temptargetSet", tempTargetSet);
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
//TODO: align with max-absorption model in AMA sensitivity
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
//align with max-absorption model in AMA sensitivity
if(mealData.usedMinCarbsImpact > 0){
mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
} else {
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
}
if (units.equals(Constants.MMOL)) {
mProfile.put("out_units", "mmol/L");

View file

@ -243,9 +243,12 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
mProfile.put("maxCOB", SMBDefaults.maxCOB);
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
//TODO: align with max-absorption model in AMA sensitivity
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
;
//align with max-absorption model in AMA sensitivity
if(mealData.usedMinCarbsImpact > 0){
mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
} else {
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
}
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);

View file

@ -1,15 +1,14 @@
package info.nightscout.androidaps.plugins.Overview.Dialogs;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.HandlerThread;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -19,20 +18,15 @@ import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
import com.google.common.base.Joiner;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@ -50,38 +44,32 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener, CompoundButton.OnCheckedChangeListener {
import static info.nightscout.utils.DateUtil.now;
public class NewCarbsDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
private NumberPicker editCarbs;
private TextView dateButton;
private TextView timeButton;
private Date initialEventTime;
private Date eventTime;
private Button fav1Button;
private Button fav2Button;
private Button fav3Button;
private EditText notesEdit;
private static final int FAV1_DEFAULT = 5;
private static final int FAV2_DEFAULT = 10;
private static final int FAV3_DEFAULT = 20;
private RadioButton startActivityTTCheckbox;
private RadioButton startEatingSoonTTCheckbox;
private RadioButton startHypoTTCheckbox;
private boolean togglingTT;
private NumberPicker editTime;
private NumberPicker editDuration;
private NumberPicker editCarbs;
private Integer maxCarbs;
private EditText notesEdit;
//one shot guards
private boolean accepted;
private boolean okClicked;
@ -94,6 +82,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
@ -102,12 +91,21 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
validateInputs();
}
};
private void validateInputs() {
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
int time = editTime.getValue().intValue();
if (time > 12 * 60 || time < -12 * 60) {
editTime.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
Double duration = editDuration.getValue();
if (duration > 10) {
editDuration.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
int carbs = editCarbs.getValue().intValue();
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
@ -125,12 +123,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
startActivityTTCheckbox.setOnCheckedChangeListener(this);
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
@ -138,29 +130,35 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
startHypoTTCheckbox.setOnCheckedChangeListener(this);
dateButton = view.findViewById(R.id.newcarbs_eventdate);
timeButton = view.findViewById(R.id.newcarb_eventtime);
editTime = view.findViewById(R.id.newcarbs_time);
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
initialEventTime = new Date();
eventTime = new Date(initialEventTime.getTime());
dateButton.setText(DateUtil.dateString(eventTime));
timeButton.setText(DateUtil.timeString(eventTime));
dateButton.setOnClickListener(this);
timeButton.setOnClickListener(this);
LinearLayout durationLayout = view.findViewById(R.id.newcarbs_duration_layout);
durationLayout.setVisibility(MainApp.engineeringMode ? View.VISIBLE : View.GONE);
fav1Button = view.findViewById(R.id.newcarbs_plus1);
editDuration = view.findViewById(R.id.new_carbs_duration);
editDuration.setParams(0d, 0d, 10d, 1d, new DecimalFormat("0"), false, textWatcher);
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
Button fav1Button = view.findViewById(R.id.newcarbs_plus1);
fav1Button.setOnClickListener(this);
fav1Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
fav2Button = view.findViewById(R.id.newcarbs_plus2);
Button fav2Button = view.findViewById(R.id.newcarbs_plus2);
fav2Button.setOnClickListener(this);
fav2Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
fav3Button = view.findViewById(R.id.newcarbs_plus3);
Button fav3Button = view.findViewById(R.id.newcarbs_plus3);
fav3Button.setOnClickListener(this);
fav3Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
notesEdit = (EditText) view.findViewById(R.id.newcarbs_notes);
LinearLayout notesLayout = view.findViewById(R.id.newcarbs_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.newcarbs_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
@ -173,8 +171,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
@Override
public synchronized void onClick(View view) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(eventTime);
switch (view.getId()) {
case R.id.ok:
submit();
@ -182,28 +178,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
case R.id.cancel:
dismiss();
break;
case R.id.newcarbs_eventdate:
DatePickerDialog dpd = DatePickerDialog.newInstance(
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
dpd.setThemeDark(true);
dpd.dismissOnPause(true);
dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
break;
case R.id.newcarb_eventtime:
TimePickerDialog tpd = TimePickerDialog.newInstance(
this,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
DateFormat.is24HourFormat(getActivity())
);
tpd.setThemeDark(true);
tpd.dismissOnPause(true);
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
break;
case R.id.newcarbs_plus1:
editCarbs.setValue(Math.max(0, editCarbs.getValue()
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
@ -309,39 +283,35 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
}
okClicked = true;
try {
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if (currentProfile == null) {
return;
}
int carbs = editCarbs.getValue().intValue();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
final String units = currentProfile.getUnits();
DefaultValueHelper helper = new DefaultValueHelper();
int activityTTDuration = helper.determineActivityTTDuration();
double activityTT = helper.determineActivityTT(units);
int eatingSoonTTDuration = helper.determineEatingSoonTTDuration();
double eatingSoonTT = helper.determineEatingSoonTT(units);
int hypoTTDuration = helper.determineHypoTTDuration();
double hypoTT = helper.determineHypoTT(units);
List<String> actions = new LinkedList<>();
if (carbs > 0)
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>");
if (!carbsAfterConstraints.equals(carbs))
actions.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>");
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 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
int hypoTTDuration = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
hypoTTDuration = hypoTTDuration > 0 ? hypoTTDuration : Constants.defaultHypoTTDuration;
double hypoTT = SP.getDouble(R.string.key_hypo_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl);
hypoTT = hypoTT > 0 ? hypoTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl;
if (startActivityTTCheckbox.isChecked()) {
String unitLabel = "mg/dl";
if (currentProfile.getUnits().equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + activityTTDuration + " min)</font>");
} else
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + activityTTDuration + " min)</font>");
unitLabel = "mmol/l";
}
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)</font>");
}
if (startEatingSoonTTCheckbox.isChecked()) {
@ -357,34 +327,45 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)</font>");
}
int timeOffset = editTime.getValue().intValue();
final long time = now() + timeOffset * 1000 * 60;
if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
}
int duration = editDuration.getValue().intValue();
if (duration > 0) {
actions.add(MainApp.gs(R.string.duration) + ": " + duration + MainApp.gs(R.string.shorthour));
}
if (carbs > 0) {
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>");
}
if (!carbsAfterConstraints.equals(carbs)) {
actions.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>");
}
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final double finalActivityTT = activityTT;
final int finalActivityTTDuration = activityTTDuration;
final double finalEatigSoonTT = eatingSoonTT;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
final double finalHypoTT = hypoTT;
final int finalHypoTTDuration = hypoTTDuration;
final String finalNotes = notesEdit.getText().toString();
if (!initialEventTime.equals(eventTime)) {
actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
}
final int finalCarbsAfterConstraints = carbsAfterConstraints;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(actions.isEmpty()
? MainApp.gs(R.string.no_action_selected)
: Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (carbsAfterConstraints > 0 || startActivityTTCheckbox.isChecked()
|| startEatingSoonTTCheckbox.isChecked() || startHypoTTCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
@ -415,34 +396,25 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (finalCarbsAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.date = eventTime.getTime();
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = finalNotes;
if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
if (carbsAfterConstraints > 0) {
if (duration == 0) {
createCarb(carbsAfterConstraints, time, notes);
} else {
long remainingCarbs = carbsAfterConstraints;
int ticks = (duration * 4); //duration guaranteed to be integer greater zero
for (int i = 0; i < ticks; i++){
long carbTime = time + i * 15 * 60 * 1000;
long smallCarbAmount = Math.round((1d * remainingCarbs) / (ticks-i)); //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
remainingCarbs -= smallCarbAmount;
createCarb(smallCarbAmount, carbTime, notes);
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
}
}
}
}
});
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
@ -451,19 +423,30 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
}
}
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
eventTime.setYear(year - 1900);
eventTime.setMonth(monthOfYear);
eventTime.setDate(dayOfMonth);
dateButton.setText(DateUtil.dateString(eventTime));
}
@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
eventTime.setHours(hourOfDay);
eventTime.setMinutes(minute);
eventTime.setSeconds(second);
timeButton.setText(DateUtil.timeString(eventTime));
private void createCarb(long carbs, long time, @Nullable String notes) {
DetailedBolusInfo carbInfo = new DetailedBolusInfo();
carbInfo.date = time;
carbInfo.eventType = CareportalEvent.CARBCORRECTION;
carbInfo.carbs = carbs;
carbInfo.context = getContext();
carbInfo.source = Source.USER;
carbInfo.notes = notes;
if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo && carbInfo.date <= now()) {
ConfigBuilderPlugin.getCommandQueue().bolus(carbInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo);
}
}
}

View file

@ -9,7 +9,6 @@ import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -18,19 +17,16 @@ import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
@ -54,30 +50,25 @@ import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
public class NewInsulinDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
import static info.nightscout.utils.DateUtil.now;
public class NewInsulinDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class);
private NumberPicker editInsulin;
private TextView dateButton;
private TextView timeButton;
private Date initialEventTime;
private Date eventTime;
private Button plus1Button;
private Button plus2Button;
private Button plus3Button;
public static final double PLUS1_DEFAULT = 0.5d;
public static final double PLUS2_DEFAULT = 1d;
public static final double PLUS3_DEFAULT = 2d;
private CheckBox startESMCheckbox;
private CheckBox startEatingSoonTTCheckbox;
private CheckBox recordOnlyCheckbox;
private LinearLayout editLayout;
private NumberPicker editTime;
private NumberPicker editInsulin;
private Double maxInsulin;
private EditText notesEdit;
//one shot guards
private boolean accepted;
private boolean okClicked;
@ -90,6 +81,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateInputs();
}
@Override
@ -98,12 +90,16 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
validateInputs();
}
};
private void validateInputs() {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
int time = editTime.getValue().intValue();
if (Math.abs(time) > 12 * 60) {
editTime.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
}
Double insulin = editInsulin.getValue();
if (insulin > maxInsulin) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
@ -121,39 +117,34 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
startEatingSoonTTCheckbox = view.findViewById(R.id.newinsulin_start_eating_soon_tt);
recordOnlyCheckbox = view.findViewById(R.id.newinsulin_record_only);
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> editLayout.setVisibility(isChecked ? View.VISIBLE : View.GONE));
editLayout = view.findViewById(R.id.newinsulin_time_layout);
editLayout.setVisibility(View.GONE);
editTime = view.findViewById(R.id.newinsulin_time);
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
editInsulin = view.findViewById(R.id.newinsulin_amount);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
initialEventTime = new Date();
eventTime = new Date(initialEventTime.getTime());
dateButton.setText(DateUtil.dateString(eventTime));
timeButton.setText(DateUtil.timeString(eventTime));
dateButton.setOnClickListener(this);
timeButton.setOnClickListener(this);
plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05);
Button plus1Button = view.findViewById(R.id.newinsulin_plus05);
plus1Button.setOnClickListener(this);
plus1Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10);
Button plus2Button = view.findViewById(R.id.newinsulin_plus10);
plus2Button.setOnClickListener(this);
plus2Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20);
Button plus3Button = view.findViewById(R.id.newinsulin_plus20);
plus3Button.setOnClickListener(this);
plus3Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt);
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only);
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (dateButton != null) dateButton.setEnabled(isChecked);
if (timeButton != null) timeButton.setEnabled(isChecked);
});
LinearLayout notesLayout = view.findViewById(R.id.newinsulin_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = view.findViewById(R.id.newinsulin_notes);
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
@ -167,8 +158,6 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
@Override
public synchronized void onClick(View view) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(eventTime);
switch (view.getId()) {
case R.id.ok:
submit();
@ -176,28 +165,6 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
case R.id.cancel:
dismiss();
break;
case R.id.newinsulin_eventdate:
DatePickerDialog dpd = DatePickerDialog.newInstance(
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
dpd.setThemeDark(true);
dpd.dismissOnPause(true);
dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
break;
case R.id.newinsulin_eventtime:
TimePickerDialog tpd = TimePickerDialog.newInstance(
this,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
DateFormat.is24HourFormat(getActivity())
);
tpd.setThemeDark(true);
tpd.dismissOnPause(true);
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
break;
case R.id.newinsulin_plus05:
editInsulin.setValue(Math.max(0, editInsulin.getValue()
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
@ -225,6 +192,10 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
okClicked = true;
try {
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if (currentProfile == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
@ -239,92 +210,90 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
if (!insulinAfterConstraints.equals(insulin))
actions.add("<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d);
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if (currentProfile == null)
return;
double tt;
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;
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 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
if (startESMCheckbox.isChecked()) {
if (currentProfile.getUnits().equals("mmol")) {
actions.add("TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min </font>");
if (startEatingSoonTTCheckbox.isChecked()) {
if (currentProfile.getUnits().equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
} else
actions.add("TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>");
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
}
if (!initialEventTime.equals(eventTime)) {
actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
int timeOffset = editTime.getValue().intValue();
final long time = now() + timeOffset * 1000 * 60;
if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
}
final String notes = notesEdit.getText().toString();
if (!notes.isEmpty()) {
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
}
final double finalInsulinAfterConstraints = insulinAfterConstraints;
final double finalEatigSoonTT = eatingSoonTT;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(actions.isEmpty()
? MainApp.gs(R.string.no_action_selected)
: Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (finalInsulinAfterConstraints > 0 || startEatingSoonTTCheckbox.isChecked()) {
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(actions)));
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (startESMCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration((int) ttDuration)
.reason("Eating soon")
.source(Source.USER)
.low((int) finalTT)
.high((int) finalTT);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget()
.date(System.currentTimeMillis())
.duration(finalEatingSoonTTDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
.high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
}
if (finalInsulinAfterConstraints <= 0.01) {
return;
}
if (recordOnlyCheckbox.isChecked()) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.date = eventTime.getTime();
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
} else {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = notes;
if (recordOnlyCheckbox.isChecked()) {
detailedBolusInfo.date = time;
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
} else {
detailedBolusInfo.date = now();
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
}
});
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
}
}
}
});
});
} else {
builder.setMessage(MainApp.gs(R.string.no_action_selected));
}
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
@ -332,20 +301,4 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
log.error("Unhandled exception", e);
}
}
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
eventTime.setYear(year - 1900);
eventTime.setMonth(monthOfYear);
eventTime.setDate(dayOfMonth);
dateButton.setText(DateUtil.dateString(eventTime));
}
@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
eventTime.setHours(hourOfDay);
eventTime.setMinutes(minute);
eventTime.setSeconds(second);
timeButton.setText(DateUtil.timeString(eventTime));
}
}

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SafeParse;
@ -104,7 +105,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);

View file

@ -105,6 +105,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
NumberPicker editCorr;
NumberPicker editCarbTime;
LinearLayout notesLayout;
EditText notesEdit;
Integer calculatedCarbs = 0;
@ -209,7 +210,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
superbolus = (TextView) view.findViewById(R.id.treatments_wizard_sb);
superbolusInsulin = (TextView) view.findViewById(R.id.treatments_wizard_sbinsulin);
notesEdit = (EditText) view.findViewById(R.id.newcarbs_notes);
notesLayout = view.findViewById(R.id.treatments_wizard_notes_layout);
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
notesEdit = (EditText) view.findViewById(R.id.treatment_wizard_notes);
bgTrend = (TextView) view.findViewById(R.id.treatments_wizard_bgtrend);
bgTrendInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin);

View file

@ -5,7 +5,6 @@ import android.app.Activity;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
@ -15,10 +14,8 @@ import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
@ -33,7 +30,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageButton;
@ -52,8 +48,6 @@ import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@ -79,6 +73,7 @@ import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventProfileSwitchChange;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.events.EventTempBasalChange;
@ -96,9 +91,9 @@ import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAckAlarm;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
@ -107,10 +102,8 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.NewInsulinDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationRecyclerViewAdapter;
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
@ -149,6 +142,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
TextView pumpDeviceStatusView;
TextView openapsDeviceStatusView;
TextView uploaderDeviceStatusView;
TextView iobCalculationProgressView;
LinearLayout loopStatusLayout;
LinearLayout pumpStatusLayout;
GraphView bgGraph;
@ -190,9 +184,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final Object updateSync = new Object();
public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN}
;
public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN, DEVSLOPE}
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledUpdate = null;
@ -244,6 +236,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
pumpDeviceStatusView = (TextView) view.findViewById(R.id.overview_pump);
openapsDeviceStatusView = (TextView) view.findViewById(R.id.overview_openaps);
uploaderDeviceStatusView = (TextView) view.findViewById(R.id.overview_uploader);
iobCalculationProgressView = (TextView) view.findViewById(R.id.overview_iobcalculationprogess);
loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout);
pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout);
@ -415,26 +408,33 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item.setCheckable(true);
item.setChecked(SP.getBoolean("showratios", false));
if (MainApp.devBranch) {
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
title = item.getTitle();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(SP.getBoolean("showdevslope", false));
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == CHARTTYPE.PRE.ordinal()) {
SP.putBoolean("showprediction", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.BAS.ordinal()) {
SP.putBoolean("showbasals", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.IOB.ordinal()) {
SP.putBoolean("showiob", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.COB.ordinal()) {
SP.putBoolean("showcob", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.DEV.ordinal()) {
SP.putBoolean("showdeviations", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) {
SP.putBoolean("showratios", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.DEVSLOPE.ordinal()) {
SP.putBoolean("showdevslope", !item.isChecked());
}
scheduleUpdateGUI("onGraphCheckboxesCheckedChanged");
return true;
@ -898,6 +898,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
scheduleUpdateGUI("EventTempTargetChange");
}
@Subscribe
public void onStatusEvent(final EventProfileSwitchChange ev) {
scheduleUpdateGUI("EventProfileSwitchChange");
}
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged s) {
Activity activity = getActivity();
@ -905,15 +910,22 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
activity.runOnUiThread(() -> updatePumpStatus(s.textStatus()));
}
@Subscribe
public void onStatusEvent(final EventIobCalculationProgress e) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
if (iobCalculationProgressView != null)
iobCalculationProgressView.setText(e.progress);
});
}
private void hideTempRecommendation() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (acceptTempLayout != null)
acceptTempLayout.setVisibility(View.GONE);
}
activity.runOnUiThread(() -> {
if (acceptTempLayout != null)
acceptTempLayout.setVisibility(View.GONE);
});
}
@ -1380,7 +1392,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
useDevForScale = true;
} else if (SP.getBoolean("showratios", false)) {
useRatioForScale = true;
} else if (Config.displayDeviationSlope) {
} else if (SP.getBoolean("showdevslope", false)) {
useDSForScale = true;
}
@ -1392,7 +1404,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
if (SP.getBoolean("showratios", false))
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
if (Config.displayDeviationSlope)
if (SP.getBoolean("showdevslope", false))
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
// **** NOW line ****
@ -1404,7 +1416,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
FragmentActivity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(() -> {
if (SP.getBoolean("showiob", true) || SP.getBoolean("showcob", true) || SP.getBoolean("showdeviations", false) || SP.getBoolean("showratios", false) || Config.displayDeviationSlope) {
if (SP.getBoolean("showiob", true)
|| SP.getBoolean("showcob", true)
|| SP.getBoolean("showdeviations", false)
|| SP.getBoolean("showratios", false)
|| SP.getBoolean("showdevslope", false)) {
iobGraph.setVisibility(View.VISIBLE);
} else {
iobGraph.setVisibility(View.GONE);

View file

@ -108,7 +108,7 @@ public class GraphData {
inRangeAreaSeries = new AreaGraphSeries<>(inRangeAreaDataPoints);
inRangeAreaSeries.setColor(0);
inRangeAreaSeries.setDrawBackground(true);
inRangeAreaSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.inrangebackground));
inRangeAreaSeries.setBackgroundColor(MainApp.gc(R.color.inrangebackground));
addSeries(inRangeAreaSeries);
}
@ -184,14 +184,14 @@ public class GraphData {
baseBasal = baseBasalArray.toArray(baseBasal);
baseBasalsSeries = new LineGraphSeries<>(baseBasal);
baseBasalsSeries.setDrawBackground(true);
baseBasalsSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.basebasal));
baseBasalsSeries.setBackgroundColor(MainApp.gc(R.color.basebasal));
baseBasalsSeries.setThickness(0);
ScaledDataPoint[] tempBasal = new ScaledDataPoint[tempBasalArray.size()];
tempBasal = tempBasalArray.toArray(tempBasal);
tempBasalsSeries = new LineGraphSeries<>(tempBasal);
tempBasalsSeries.setDrawBackground(true);
tempBasalsSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.tempbasal));
tempBasalsSeries.setBackgroundColor(MainApp.gc(R.color.tempbasal));
tempBasalsSeries.setThickness(0);
ScaledDataPoint[] basalLine = new ScaledDataPoint[basalLineArray.size()];
@ -201,7 +201,7 @@ public class GraphData {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity * 2);
paint.setPathEffect(new DashPathEffect(new float[]{2, 4}, 0));
paint.setColor(MainApp.sResources.getColor(R.color.basal));
paint.setColor(MainApp.gc(R.color.basal));
basalsLineSeries.setCustomPaint(paint);
ScaledDataPoint[] absoluteBasalLine = new ScaledDataPoint[absoluteBasalLineArray.size()];
@ -210,7 +210,7 @@ public class GraphData {
Paint absolutePaint = new Paint();
absolutePaint.setStyle(Paint.Style.STROKE);
absolutePaint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity * 2);
absolutePaint.setColor(MainApp.sResources.getColor(R.color.basal));
absolutePaint.setColor(MainApp.gc(R.color.basal));
absoluteBasalsLineSeries.setCustomPaint(absolutePaint);
basalScale.setMultiplier(maxY * scale / maxBasalValueFound);
@ -259,7 +259,7 @@ public class GraphData {
targets = targetsSeriesArray.toArray(targets);
targetsSeries = new LineGraphSeries<>(targets);
targetsSeries.setDrawBackground(false);
targetsSeries.setColor(MainApp.sResources.getColor(R.color.tempTargetBackground));
targetsSeries.setColor(MainApp.gc(R.color.tempTargetBackground));
targetsSeries.setThickness(2);
addSeries(targetsSeries);
@ -351,8 +351,8 @@ public class GraphData {
iobData = iobArray.toArray(iobData);
iobSeries = new FixedLineGraphSeries<>(iobData);
iobSeries.setDrawBackground(true);
iobSeries.setBackgroundColor(0x80FFFFFF & MainApp.sResources.getColor(R.color.iob)); //50%
iobSeries.setColor(MainApp.sResources.getColor(R.color.iob));
iobSeries.setBackgroundColor(0x80FFFFFF & MainApp.gc(R.color.iob)); //50%
iobSeries.setColor(MainApp.gc(R.color.iob));
iobSeries.setThickness(3);
if (useForScale)
@ -365,6 +365,7 @@ public class GraphData {
// scale in % of vertical size (like 0.3)
public void addCob(long fromTime, long toTime, boolean useForScale, double scale) {
List<DataPointWithLabelInterface> minFailoverActiveList = new ArrayList<>();
FixedLineGraphSeries<ScaledDataPoint> cobSeries;
List<ScaledDataPoint> cobArray = new ArrayList<>();
Double maxCobValueFound = 0d;
@ -382,6 +383,10 @@ public class GraphData {
maxCobValueFound = Math.max(maxCobValueFound, cob);
lastCob = cob;
}
if (autosensData.failoverToMinAbsorbtionRate) {
autosensData.setScale(cobScale);
minFailoverActiveList.add(autosensData);
}
}
}
@ -390,8 +395,8 @@ public class GraphData {
cobData = cobArray.toArray(cobData);
cobSeries = new FixedLineGraphSeries<>(cobData);
cobSeries.setDrawBackground(true);
cobSeries.setBackgroundColor(0xB0FFFFFF & MainApp.sResources.getColor(R.color.cob)); //50%
cobSeries.setColor(MainApp.sResources.getColor(R.color.cob));
cobSeries.setBackgroundColor(0xB0FFFFFF & MainApp.gc(R.color.cob)); //50%
cobSeries.setColor(MainApp.gc(R.color.cob));
cobSeries.setThickness(3);
if (useForScale)
@ -400,6 +405,10 @@ public class GraphData {
cobScale.setMultiplier(maxY * scale / maxCobValueFound);
addSeries(cobSeries);
DataPointWithLabelInterface[] minFailover = new DataPointWithLabelInterface[minFailoverActiveList.size()];
minFailover = minFailoverActiveList.toArray(minFailover);
addSeries(new PointsWithLabelGraphSeries<>(minFailover));
}
// scale in % of vertical size (like 0.3)
@ -468,7 +477,7 @@ public class GraphData {
ScaledDataPoint[] ratioData = new ScaledDataPoint[ratioArray.size()];
ratioData = ratioArray.toArray(ratioData);
ratioSeries = new LineGraphSeries<>(ratioData);
ratioSeries.setColor(MainApp.sResources.getColor(R.color.ratio));
ratioSeries.setColor(MainApp.gc(R.color.ratio));
ratioSeries.setThickness(3);
if (useForScale)
@ -504,13 +513,13 @@ public class GraphData {
ScaledDataPoint[] ratioMaxData = new ScaledDataPoint[dsMaxArray.size()];
ratioMaxData = dsMaxArray.toArray(ratioMaxData);
dsMaxSeries = new LineGraphSeries<>(ratioMaxData);
dsMaxSeries.setColor(Color.MAGENTA);
dsMaxSeries.setColor(MainApp.gc(R.color.devslopepos));
dsMaxSeries.setThickness(3);
ScaledDataPoint[] ratioMinData = new ScaledDataPoint[dsMinArray.size()];
ratioMinData = dsMinArray.toArray(ratioMinData);
dsMinSeries = new LineGraphSeries<>(ratioMinData);
dsMinSeries.setColor(Color.YELLOW);
dsMinSeries.setColor(MainApp.gc(R.color.devslopeneg));
dsMinSeries.setThickness(3);
if (useForScale)

View file

@ -3,42 +3,46 @@ package info.nightscout.androidaps.plugins.Overview.graphExtensions;
/**
* GraphView
* Copyright (C) 2014 Jonas Gehring
*
* <p>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License,
* with the "Linking Exception", which can be found at the license.txt
* file in this program.
*
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* <p>
* You should have received a copy of the GNU General Public License
* with the "Linking Exception" along with this program; if not,
* write to the author Jonas Gehring <g.jjoe64@gmail.com>.
* <p>
* Added by mike
*/
/**
* Added by mike
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.TypedValue;
// Added by Rumen for scalable text
import android.content.Context;
import info.nightscout.androidaps.MainApp;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.BaseSeries;
import java.util.Iterator;
import info.nightscout.androidaps.MainApp;
// Added by Rumen for scalable text
/**
* Series that plots the data as points.
* The points can be different shapes or a
@ -74,7 +78,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
OPENAPSOFFLINE,
EXERCISE,
GENERAL,
GENERALWITHDURATION
GENERALWITHDURATION,
COBFAILOVER
}
/**
@ -148,7 +153,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
float scaleX = (float) (graphWidth / diffX);
int i=0;
int i = 0;
while (values.hasNext()) {
E value = values.next();
@ -182,7 +187,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
}
/* Fix a bug that continue to show the DOT after Y axis */
if(x < 0) {
if (x < 0) {
overdraw = true;
}
@ -197,10 +202,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
// draw data point
if (!overdraw) {
if (value.getShape() == Shape.BG) {
if (value.getShape() == Shape.BG || value.getShape() == Shape.COBFAILOVER) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
} else if (value.getShape() == Shape.PREDICTION) {
mPaint.setColor(value.getColor());
mPaint.setStyle(Paint.Style.FILL);
@ -211,20 +216,20 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint);
} else if (value.getShape() == Shape.RECTANGLE) {
canvas.drawRect(endX-scaledPxSize, endY-scaledPxSize, endX+scaledPxSize, endY+scaledPxSize, mPaint);
canvas.drawRect(endX - scaledPxSize, endY - scaledPxSize, endX + scaledPxSize, endY + scaledPxSize, mPaint);
} else if (value.getShape() == Shape.TRIANGLE) {
mPaint.setStrokeWidth(0);
Point[] points = new Point[3];
points[0] = new Point((int)endX, (int)(endY-scaledPxSize));
points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67));
points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67));
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
drawArrows(points, canvas, mPaint);
} else if (value.getShape() == Shape.BOLUS) {
mPaint.setStrokeWidth(0);
Point[] points = new Point[3];
points[0] = new Point((int)endX, (int)(endY-scaledPxSize));
points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67));
points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67));
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint);
if (value.getLabel() != null) {
@ -234,15 +239,15 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStrokeWidth(2);
Point[] points = new Point[3];
float size = value.getSize() * scaledPxSize;
points[0] = new Point((int)endX, (int)(endY-size));
points[1] = new Point((int)(endX+size), (int)(endY+size*0.67));
points[2] = new Point((int)(endX-size), (int)(endY+size*0.67));
points[0] = new Point((int) endX, (int) (endY - size));
points[1] = new Point((int) (endX + size), (int) (endY + size * 0.67));
points[2] = new Point((int) (endX - size), (int) (endY + size * 0.67));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint);
} else if (value.getShape() == Shape.EXTENDEDBOLUS) {
mPaint.setStrokeWidth(0);
if (value.getLabel() != null) {
Rect bounds = new Rect((int)endX, (int)endY + 3, (int) (xpluslength), (int) endY + 8);
Rect bounds = new Rect((int) endX, (int) endY + 3, (int) (xpluslength), (int) endY + 8);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawRect(bounds, mPaint);
mPaint.setTextSize((float) (scaledTextSize));
@ -254,7 +259,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStrokeWidth(0);
if (value.getLabel() != null) {
//mPaint.setTextSize((int) (scaledPxSize * 3));
mPaint.setTextSize((float) (scaledTextSize*1.2));
mPaint.setTextSize((float) (scaledTextSize * 1.2));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
Rect bounds = new Rect();
mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds);
@ -355,7 +360,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
* @param paint paint object
*/
private void drawArrows(Point[] point, Canvas canvas, Paint paint) {
float [] points = new float[8];
float[] points = new float[8];
points[0] = point[0].x;
points[1] = point[0].y;
points[2] = point[1].x;
@ -368,10 +373,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
canvas.save();
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint);
Path path = new Path();
path.moveTo(point[0].x , point[0].y);
path.lineTo(point[1].x,point[1].y);
path.lineTo(point[2].x,point[2].y);
canvas.drawPath(path,paint);
path.moveTo(point[0].x, point[0].y);
path.lineTo(point[1].x, point[1].y);
path.lineTo(point[2].x, point[2].y);
canvas.drawPath(path, paint);
canvas.restore();
}
@ -381,7 +386,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
float py = endY + scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize*0.8));
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
mPaint.setTextAlign(Paint.Align.RIGHT);
@ -393,7 +398,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
float py = endY - scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize*0.8));
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);

View file

@ -304,7 +304,11 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte
@Override
public void getPumpStatus() {
if (sExecutionService != null) sExecutionService.getPumpStatus();
if (sExecutionService != null) {
sExecutionService.getPumpStatus();
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
}
}
@Override

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
@ -129,7 +130,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
// Plugin base interface
@Override
public String getName() {
return MainApp.instance().getString(R.string.danarpump);
return MainApp.gs(R.string.danarpump);
}
@Override
@ -158,10 +159,13 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.success = connectionOK && detailedBolusInfo.insulin == t.insulin;
result.bolusDelivered = t.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (!result.success)
result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStartWithSpeed.errorCode);
else
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
detailedBolusInfo.insulin = t.insulin;
@ -173,7 +177,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0d;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
@ -342,7 +346,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
PumpEnactResult result = new PumpEnactResult();
result.success = true;
result.enacted = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = true;
return result;
}
@ -358,13 +362,13 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
if (!pump.isTempBasalInProgress) {
result.success = true;
result.isTempCancel = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelRealTempBasal: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
result.isTempCancel = true;
log.error("cancelRealTempBasal: Failed to cancel temp basal");
return result;

View file

@ -11,6 +11,8 @@ import info.nightscout.utils.HardLimits;
public class MsgBolusStart extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgBolusStart.class);
public static int errorCode;
public MsgBolusStart() {
SetCommand(0x0102);
}
@ -29,13 +31,13 @@ public class MsgBolusStart extends MessageBase {
@Override
public void handleMessage(byte[] bytes) {
int result = intFromBuff(bytes, 0, 1);
if (result != 2) {
errorCode = intFromBuff(bytes, 0, 1);
if (errorCode != 2) {
failed = true;
log.debug("Messsage response: " + result + " FAILED!!");
log.debug("Messsage response: " + errorCode + " FAILED!!");
} else {
if (Config.logDanaMessageDetail)
log.debug("Messsage response: " + result);
log.debug("Messsage response: " + errorCode + " OK");
}
}
}

View file

@ -11,6 +11,8 @@ import info.nightscout.utils.HardLimits;
public class MsgBolusStartWithSpeed extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgBolusStartWithSpeed.class);
public static int errorCode;
public MsgBolusStartWithSpeed() {
SetCommand(0x0104);
}
@ -30,13 +32,13 @@ public class MsgBolusStartWithSpeed extends MessageBase {
@Override
public void handleMessage(byte[] bytes) {
int result = intFromBuff(bytes, 0, 1);
if (result != 2) {
errorCode = intFromBuff(bytes, 0, 1);
if (errorCode != 2) {
failed = true;
log.debug("Messsage response: " + result + " FAILED!!");
log.debug("Messsage response: " + errorCode + " FAILED!!");
} else {
if (Config.logDanaMessageDetail)
log.debug("Messsage response: " + result);
log.debug("Messsage response: " + errorCode + " OK");
}
}
}

View file

@ -339,7 +339,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{
} else {
ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null);
}
return true;
return !start.failed;
}
public boolean carbsEntry(int amount) {

View file

@ -18,14 +18,15 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
@ -130,7 +131,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
// Plugin base interface
@Override
public String getName() {
return MainApp.instance().getString(R.string.danarkoreanpump);
return MainApp.gs(R.string.danarkoreanpump);
}
@Override
@ -159,10 +160,13 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.success = connectionOK && detailedBolusInfo.insulin == t.insulin;
result.bolusDelivered = t.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (!result.success)
result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStart.errorCode);
else
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
detailedBolusInfo.insulin = t.insulin;
@ -174,7 +178,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0d;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
@ -343,7 +347,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
PumpEnactResult result = new PumpEnactResult();
result.success = true;
result.enacted = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = true;
return result;
}
@ -359,13 +363,13 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
if (!pump.isTempBasalInProgress) {
result.success = true;
result.isTempCancel = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelRealTempBasal: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
result.isTempCancel = true;
log.error("cancelRealTempBasal: Failed to cancel temp basal");
return result;

View file

@ -286,7 +286,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
mBolusingTreatment = null;
ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null);
return true;
return !start.failed;
}
public boolean carbsEntry(int amount) {

View file

@ -26,6 +26,7 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Bolus_Set_Step_Bolus_Start;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.Constraint;
@ -178,8 +179,6 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
final Object o = new Object();
danaRSService.connect(from, mDeviceAddress, o);
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
}
}
@ -205,8 +204,11 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
@Override
public void getPumpStatus() {
if (danaRSService != null)
if (danaRSService != null) {
danaRSService.getPumpStatus();
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
}
}
// DanaR interface
@ -368,7 +370,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
}
// RS stores end time for bolus, we need to adjust time
// default delivery speed is 12 sec/U
detailedBolusInfo.date = DateUtil.now() + (long)(speed * detailedBolusInfo.insulin * 1000);
detailedBolusInfo.date = DateUtil.now() + (long) (speed * detailedBolusInfo.insulin * 1000);
// clean carbs to prevent counting them as twice because they will picked up as another record
// I don't think it's necessary to copy DetailedBolusInfo right now for carbs records
double carbs = detailedBolusInfo.carbs;
@ -384,10 +386,13 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.success = connectionOK && detailedBolusInfo.insulin == t.insulin;
result.bolusDelivered = t.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (!result.success)
result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, DanaRS_Packet_Bolus_Set_Step_Bolus_Start.errorCode);
else
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
return result;
@ -396,7 +401,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0d;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
@ -500,7 +505,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
result.isTempCancel = false;
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("setTempBasalPercent: Invalid input");
return result;
}
@ -512,7 +517,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
result.enacted = false;
result.success = true;
result.isTempCancel = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
result.isPercent = true;
@ -530,7 +535,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
@ -541,7 +546,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror);
result.comment = MainApp.gs(R.string.tempbasaldeliveryerror);
log.error("setTempBasalPercent: Failed to set temp basal");
return result;
}
@ -552,7 +557,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
@ -563,7 +568,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
log.error("setHighTempBasalPercent: Failed to set temp basal");
return result;
}
@ -579,7 +584,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = false;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.duration = pump.extendedBolusRemainingMinutes;
result.absolute = pump.extendedBolusAbsoluteRate;
result.isPercent = false;
@ -592,7 +597,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAbsoluteRate - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.extendedBolusRemainingMinutes;
result.absolute = pump.extendedBolusAbsoluteRate;
@ -604,7 +609,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
log.error("setExtendedBolus: Failed to extended bolus");
return result;
}
@ -621,13 +626,13 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
if (!pump.isTempBasalInProgress) {
result.success = true;
result.isTempCancel = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelRealTempBasal: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
result.isTempCancel = true;
log.error("cancelRealTempBasal: Failed to cancel temp basal");
return result;
@ -645,13 +650,13 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
}
if (!pump.isExtendedInProgress) {
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelExtendedBolus: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
return result;
}

View file

@ -7,58 +7,63 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.utils.HardLimits;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Step_Bolus_Start.class);
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Step_Bolus_Start.class);
private double amount;
private int speed;
private double amount;
private int speed;
public boolean failed;
public boolean failed;
public static int errorCode;
public DanaRS_Packet_Bolus_Set_Step_Bolus_Start() {
public DanaRS_Packet_Bolus_Set_Step_Bolus_Start() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START;
}
// Speed 0 => 12 sec/U, 1 => 30 sec/U, 2 => 60 sec/U
public DanaRS_Packet_Bolus_Set_Step_Bolus_Start(double amount, int speed) {
this();
public DanaRS_Packet_Bolus_Set_Step_Bolus_Start(double amount, int speed) {
this();
// HARDCODED LIMIT
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
// HARDCODED LIMIT
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
this.amount = amount;
this.speed = speed;
this.amount = amount;
this.speed = speed;
if (Config.logDanaMessageDetail)
log.debug("Bolus start : " + amount + " speed: " + speed);
}
if (Config.logDanaMessageDetail)
log.debug("Bolus start : " + amount + " speed: " + speed);
}
@Override
public byte[] getRequestParams() {
int stepBolusRate = (int) (amount * 100);
byte[] request = new byte[3];
request[0] = (byte) (stepBolusRate & 0xff);
request[1] = (byte) ((stepBolusRate >>> 8) & 0xff);
request[2] = (byte) (speed & 0xff);
return request;
}
@Override
public void handleMessage(byte[] data) {
int result = intFromBuff(data, 0, 1);
if (Config.logDanaMessageDetail) {
if (result == 0)
log.debug("Result OK");
else
log.error("Result Error: " + result);
}
}
@Override
public byte[] getRequestParams() {
int stepBolusRate = (int) (amount * 100);
byte[] request = new byte[3];
request[0] = (byte) (stepBolusRate & 0xff);
request[1] = (byte) ((stepBolusRate >>> 8) & 0xff);
request[2] = (byte) (speed & 0xff);
return request;
}
@Override
public String getFriendlyName() {
return "BOLUS__SET_STEP_BOLUS_START";
}
@Override
public void handleMessage(byte[] data) {
errorCode = intFromBuff(data, 0, 1);
if (Config.logDanaMessageDetail) {
if (errorCode == 0)
log.debug("Result OK");
else {
failed = true;
log.error("Result Error: " + errorCode);
}
}
}
@Override
public String getFriendlyName() {
return "BOLUS__SET_STEP_BOLUS_START";
}
}

View file

@ -273,7 +273,7 @@ public class DanaRSService extends Service {
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.disconnecting)));
}
});
return true;
return !start.failed;
}
public void bolusStop() {

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage;
import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed;
import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
@ -119,7 +120,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
// Plugin base interface
@Override
public String getName() {
return MainApp.instance().getString(R.string.danarv2pump);
return MainApp.gs(R.string.danarv2pump);
}
@Override
@ -173,10 +174,13 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.success = connectionOK && detailedBolusInfo.insulin == t.insulin;
result.bolusDelivered = t.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (!result.success)
result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStartWithSpeed.errorCode);
else
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
// remove carbs because it's get from history seprately
@ -186,7 +190,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0d;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
@ -287,7 +291,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
result.isTempCancel = false;
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
result.comment = MainApp.gs(R.string.danar_invalidinput);
log.error("setTempBasalPercent: Invalid input");
return result;
}
@ -299,7 +303,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
result.enacted = false;
result.success = true;
result.isTempCancel = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
result.isPercent = true;
@ -317,7 +321,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
@ -328,7 +332,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.tempbasaldeliveryerror);
result.comment = MainApp.gs(R.string.tempbasaldeliveryerror);
log.error("setTempBasalPercent: Failed to set temp basal");
return result;
}
@ -339,7 +343,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
@ -350,7 +354,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
log.error("setHighTempBasalPercent: Failed to set temp basal");
return result;
}
@ -367,13 +371,13 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
if (!pump.isTempBasalInProgress) {
result.success = true;
result.isTempCancel = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.comment = MainApp.gs(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelRealTempBasal: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.comment = MainApp.gs(R.string.danar_valuenotsetproperly);
result.isTempCancel = true;
log.error("cancelRealTempBasal: Failed to cancel temp basal");
return result;

View file

@ -386,7 +386,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.disconnecting)));
}
});
return true;
return !start.failed;
}
public void bolusStop() {

View file

@ -12,6 +12,8 @@ import info.nightscout.androidaps.interfaces.PluginType;
public class SourceXdripPlugin extends PluginBase implements BgSourceInterface {
private static SourceXdripPlugin plugin = null;
boolean advancedFiltering;
public static SourceXdripPlugin getPlugin() {
if (plugin == null)
@ -29,6 +31,10 @@ public class SourceXdripPlugin extends PluginBase implements BgSourceInterface {
@Override
public boolean advancedFilteringSupported() {
return false;
return advancedFiltering;
}
public void setSource(String source) {
this.advancedFiltering = source.contains("G5 Native");
}
}

View file

@ -40,6 +40,8 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
@ -211,22 +213,35 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (profile == null) return result;
long now = System.currentTimeMillis();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * T.hours(1).msecs())).longValue();
long dia_ago = now - (Double.valueOf(profile.getDia() * T.hours(1).msecs())).longValue();
double maxAbsorptionHours = Constants.DEFAULT_MAX_ABSORPTION_TIME;
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
} else {
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
}
long absorptionTime_ago = now - (Double.valueOf(maxAbsorptionHours * T.hours(1).msecs())).longValue();
synchronized (treatments) {
for (Treatment treatment : treatments) {
if (!treatment.isValid)
continue;
long t = treatment.date;
if (t > dia_ago && t <= now) {
if (treatment.carbs >= 1) {
result.carbs += treatment.carbs;
result.lastCarbTime = t;
}
if (treatment.insulin > 0 && treatment.mealBolus) {
result.boluses += treatment.insulin;
}
}
if (t > absorptionTime_ago && t <= now) {
if (treatment.carbs >= 1) {
result.carbs += treatment.carbs;
if(t > result.lastCarbTime)
result.lastCarbTime = t;
}
}
}
}
@ -235,6 +250,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
result.mealCOB = autosensData.cob;
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation;
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation;
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact;
}
result.lastBolusTime = getLastBolusTime();
return result;
@ -452,7 +468,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
//log.debug("Adding new Treatment record" + carbsTreatment);
}
if (newRecordCreated && detailedBolusInfo.isValid)
NSUpload.uploadBolusWizardRecord(detailedBolusInfo);
NSUpload.uploadTreatmentRecord(detailedBolusInfo);
return newRecordCreated;
}

View file

@ -89,6 +89,10 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
else
holder.iob.setTextColor(holder.carbs.getCurrentTextColor());
if (t.date > DateUtil.now())
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorScheduled));
else
holder.date.setTextColor(holder.carbs.getCurrentTextColor());
holder.remove.setTag(t);
}

View file

@ -84,14 +84,10 @@ public class TreatmentsTempTargetFragment extends SubscriberFragment implements
holder.reasonLabel.setText("");
holder.reasonColon.setText("");
}
if (tempTarget.isInProgress()) {
if (tempTarget == currentlyActiveTarget) {
// active as newest
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorInProgress));
} else {
// other's that might become active again after the latest (overlapping) is over
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
}
if (tempTarget.isInProgress() && tempTarget == currentlyActiveTarget) {
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive));
} else if (tempTarget.date > DateUtil.now()) {
holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorScheduled));
} else {
holder.date.setTextColor(holder.reasonColon.getCurrentTextColor());
}

View file

@ -166,14 +166,19 @@ public class CommandQueue {
public boolean bolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
Command.CommandType type = detailedBolusInfo.isSMB ? Command.CommandType.SMB_BOLUS : Command.CommandType.BOLUS;
if (isRunning(type)) {
if (callback != null)
callback.result(executingNowError()).run();
return false;
}
if(type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0){
type = Command.CommandType.CARBS_ONLY_TREATMENT;
//Carbs only can be added in parallel as they can be "in the future".
} else {
if (isRunning(type)) {
if (callback != null)
callback.result(executingNowError()).run();
return false;
}
// remove all unfinished boluses
removeAll(type);
// remove all unfinished boluses
removeAll(type);
}
// apply constraints
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
@ -183,12 +188,14 @@ public class CommandQueue {
if (detailedBolusInfo.isSMB) {
add(new CommandSMBBolus(detailedBolusInfo, callback));
} else {
add(new CommandBolus(detailedBolusInfo, callback));
// Bring up bolus progress dialog (start here, so the dialog is shown when the bolus is requested,
// not when the Bolus command is starting. The command closes the dialog upon completion).
showBolusProgressDialog(detailedBolusInfo.insulin, detailedBolusInfo.context);
// Notify Wear about upcoming bolus
MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
add(new CommandBolus(detailedBolusInfo, callback, type));
if(type.equals(Command.CommandType.BOLUS)) {
// Bring up bolus progress dialog (start here, so the dialog is shown when the bolus is requested,
// not when the Bolus command is starting. The command closes the dialog upon completion).
showBolusProgressDialog(detailedBolusInfo.insulin, detailedBolusInfo.context);
// Notify Wear about upcoming bolus
MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
}
}
notifyAboutNewCommand();
@ -198,7 +205,7 @@ public class CommandQueue {
// returns true if command is queued
public boolean tempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) {
if (isRunning(Command.CommandType.TEMPBASAL)) {
if (!enforceNew && isRunning(Command.CommandType.TEMPBASAL)) {
if (callback != null)
callback.result(executingNowError()).run();
return false;
@ -219,7 +226,7 @@ public class CommandQueue {
// returns true if command is queued
public boolean tempBasalPercent(Integer percent, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) {
if (isRunning(Command.CommandType.TEMPBASAL)) {
if (!enforceNew && isRunning(Command.CommandType.TEMPBASAL)) {
if (callback != null)
callback.result(executingNowError()).run();
return false;
@ -261,7 +268,7 @@ public class CommandQueue {
// returns true if command is queued
public boolean cancelTempBasal(boolean enforceNew, Callback callback) {
if (isRunning(Command.CommandType.TEMPBASAL)) {
if (!enforceNew && isRunning(Command.CommandType.TEMPBASAL)) {
if (callback != null)
callback.result(executingNowError()).run();
return false;

View file

@ -12,6 +12,7 @@ public abstract class Command {
public enum CommandType {
BOLUS,
SMB_BOLUS,
CARBS_ONLY_TREATMENT,
TEMPBASAL,
EXTENDEDBOLUS,
BASALPROFILE,

View file

@ -16,8 +16,8 @@ import info.nightscout.utils.DecimalFormatter;
public class CommandBolus extends Command {
DetailedBolusInfo detailedBolusInfo;
public CommandBolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
commandType = CommandType.BOLUS;
public CommandBolus(DetailedBolusInfo detailedBolusInfo, Callback callback, CommandType type) {
commandType = type;
this.detailedBolusInfo = detailedBolusInfo;
this.callback = callback;
}

View file

@ -46,13 +46,13 @@ public class DecimalFormatter {
}
public static String toPumpSupportedBolus(double value) {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.05
? to2Decimal(value)
: to1Decimal(value);
}
public static DecimalFormat pumpSupportedBolusFormat() {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01
return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.05
? new DecimalFormat("0.00")
: new DecimalFormat("0.0");
}

View file

@ -0,0 +1,90 @@
package info.nightscout.utils;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
public class DefaultValueHelper {
/**
* returns the corresponding EatingSoon TempTarget based on the given units (MMOL / MGDL)
*
* @param units
* @return
*/
public double getDefaultEatingSoonTT(String units) {
return Constants.MMOL.equals(units) ? Constants.defaultEatingSoonTTmmol
: Constants.defaultEatingSoonTTmgdl;
}
/**
* returns the corresponding Activity TempTarget based on the given units (MMOL / MGDL)
*
* @param units
* @return
*/
public double getDefaultActivityTT(String units) {
return Constants.MMOL.equals(units) ? Constants.defaultActivityTTmmol
: Constants.defaultActivityTTmgdl;
}
/**
* returns the corresponding Hypo TempTarget based on the given units (MMOL / MGDL)
*
* @param units
* @return
*/
public double getDefaultHypoTT(String units) {
return Constants.MMOL.equals(units) ? Constants.defaultHypoTTmmol
: Constants.defaultHypoTTmgdl;
}
/**
* returns the configured EatingSoon TempTarget, if this is set to 0, the Default-Value is returned.
*
* @param units
* @return
*/
public double determineEatingSoonTT(String units) {
double value = SP.getDouble(R.string.key_eatingsoon_target, this.getDefaultEatingSoonTT(units));
return value > 0 ? value : this.getDefaultEatingSoonTT(units);
}
public int determineEatingSoonTTDuration() {
int value = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
return value > 0 ? value : Constants.defaultEatingSoonTTDuration;
}
/**
* returns the configured Activity TempTarget, if this is set to 0, the Default-Value is returned.
*
* @param units
* @return
*/
public double determineActivityTT(String units) {
double value = SP.getDouble(R.string.key_activity_target, this.getDefaultActivityTT(units));
return value > 0 ? value : this.getDefaultActivityTT(units);
}
public int determineActivityTTDuration() {
int value = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration);
return value > 0 ? value : Constants.defaultActivityTTDuration;
}
/**
* returns the configured Hypo TempTarget, if this is set to 0, the Default-Value is returned.
*
* @param units
* @return
*/
public double determineHypoTT(String units) {
double value = SP.getDouble(R.string.key_hypo_target, this.getDefaultHypoTT(units));
return value > 0 ? value : this.getDefaultHypoTT(units);
}
public int determineHypoTTDuration() {
int value = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
return value > 0 ? value : Constants.defaultHypoTTDuration;
}
}

View file

@ -14,10 +14,9 @@ import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
import info.nightscout.utils.NSUpload;
/**
* Created by adrian on 17/12/17.
@ -26,12 +25,12 @@ import info.nightscout.utils.NSUpload;
public class LocalAlertUtils {
private static Logger log = LoggerFactory.getLogger(LocalAlertUtils.class);
public static int missedReadingsThreshold() {
return SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30) * 60 * 1000;
public static long missedReadingsThreshold() {
return T.mins(SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30)).msecs();
}
private static int pumpUnreachableThreshold() {
return SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30) * 60 * 1000;
private static long pumpUnreachableThreshold() {
return T.mins(SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30)).msecs();
}
public static void checkPumpUnreachableAlarm(Date lastConnection, boolean isStatusOutdated) {
@ -49,11 +48,13 @@ public class LocalAlertUtils {
NSUpload.uploadError(n.text);
}
}
if (!isStatusOutdated && !alarmTimeoutExpired)
MainApp.bus().post(new EventDismissNotification(Notification.PUMP_UNREACHABLE));
}
/*Presnoozes the alarms with 5 minutes if no snooze exists.
* Call only at startup!
*/
* Call only at startup!
*/
public static void presnoozeAlarms() {
if (SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) {
SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000);
@ -74,7 +75,7 @@ public class LocalAlertUtils {
SP.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm);
}
public static void notifyPumpStatusRead(){
public static void notifyPumpStatusRead() {
//TODO: persist the actual time the pump is read and simplify the whole logic when to alarm
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();

View file

@ -7,6 +7,7 @@ import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
@ -258,7 +259,7 @@ public class NSUpload {
}
}
public static void uploadBolusWizardRecord(DetailedBolusInfo detailedBolusInfo) {
public static void uploadTreatmentRecord(DetailedBolusInfo detailedBolusInfo) {
JSONObject data = new JSONObject();
try {
data.put("eventType", detailedBolusInfo.eventType);
@ -309,13 +310,21 @@ public class NSUpload {
public static void uploadTempTarget(TempTarget tempTarget) {
try {
Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile == null) {
log.error("Profile is null. Skipping upload");
return;
}
JSONObject data = new JSONObject();
data.put("eventType", CareportalEvent.TEMPORARYTARGET);
data.put("duration", tempTarget.durationInMinutes);
data.put("reason", tempTarget.reason);
data.put("targetBottom", tempTarget.low);
data.put("targetTop", tempTarget.high);
data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits()));
data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, profile.getUnits()));
data.put("created_at", DateUtil.toISOString(tempTarget.date));
data.put("units", profile.getUnits());
data.put("enteredBy", MainApp.instance().getString(R.string.app_name));
uploadCareportalEntryToNS(data);
} catch (JSONException e) {
@ -500,7 +509,7 @@ public class NSUpload {
}
}
public static void uploadEvent(String careportalEvent, long time) {
public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
@ -510,6 +519,9 @@ public class NSUpload {
data.put("eventType", careportalEvent);
data.put("created_at", DateUtil.toISOString(time));
data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name)));
if (notes != null) {
data.put("notes", notes);
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}

View file

@ -5,6 +5,7 @@ import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -148,7 +149,7 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
}
public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, TextWatcher textWatcher) {
if(this.textWatcher != null) {
if (this.textWatcher != null) {
editText.removeTextChangedListener(this.textWatcher);
}
setParams(initValue, minValue, maxValue, step, formater, allowZero);
@ -164,6 +165,8 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
this.formater = formater;
this.allowZero = allowZero;
editText.setKeyListener(DigitsKeyListener.getInstance(minValue < 0, step != Math.rint(step)));
if (textWatcher != null)
editText.removeTextChangedListener(textWatcher);
updateEditText();
@ -202,7 +205,7 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener,
updateEditText();
}
private void dec( int multiplier) {
private void dec(int multiplier) {
value -= step * multiplier;
if (value < minValue) {
value = minValue;

View file

@ -1,97 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:focusableInTouchMode="true"
android:padding="10dp">
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:padding="5dp"
android:src="@drawable/icon_cp_pump_canula" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="10dp"
android:text="@string/primefill"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorInsulinButton" />
<ImageView
android:layout_width="match_parent"
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
<CheckBox
android:id="@+id/fill_catheter_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:padding="5dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/icon_cp_pump_canula" />
android:text="@string/careportal_pumpsitechange" />
<LinearLayout
android:id="@+id/careportal_newnstreatment_insulin_layout"
<CheckBox
android:id="@+id/fill_cartridge_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
<CheckBox
android:id="@+id/catheter_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="Pump site change" />
<CheckBox
android:id="@+id/cartridge_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:text="Insulin cartridge change" />
<info.nightscout.utils.NumberPicker
android:id="@+id/treatments_newtreatment_insulinamount"
android:layout_width="130dp"
android:layout_height="40dp"
android:layout_gravity="end"
android:layout_marginBottom="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp">
<Button
android:id="@+id/fill_preset_button1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.3U" />
<Button
android:id="@+id/fill_preset_button2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.7U" />
<Button
android:id="@+id/fill_preset_button3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1.2U" />
</LinearLayout>
<include layout="@layout/mdtp_done_button" />
android:text="@string/careportal_insulincartridgechange" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
</ScrollView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/overview_insulin_label" />
<info.nightscout.utils.NumberPicker
android:id="@+id/fill_insulinamount"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="end"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/insulin_unit_shortname" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/fill_preset_button1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.3U" />
<Button
android:id="@+id/fill_preset_button2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0.7U" />
<Button
android:id="@+id/fill_preset_button3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1.2U" />
</LinearLayout>
<LinearLayout
android:id="@+id/fill_notes_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:width="60dp"
android:padding="2dp"
android:text="@string/careportal_newnstreatment_notes_label"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:textStyle="bold" />
<EditText
android:id="@+id/fill_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text|textCapSentences" />
</LinearLayout>
<include layout="@layout/mdtp_done_button" />
</LinearLayout>
</ScrollView>

View file

@ -96,6 +96,13 @@
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="15sp" />
</RelativeLayout>
<com.jjoe64.graphview.GraphView

View file

@ -23,8 +23,7 @@
android:layout_height="match_parent"
android:text="1"
android:textColor="@android:color/black"
android:inputType="numberDecimal"
android:digits="0123456789.,"
android:inputType="number"
android:gravity="center"
android:imeOptions="actionDone"
/>

View file

@ -239,23 +239,30 @@
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1">
<com.jjoe64.graphview.GraphView
android:id="@+id/overview_bggraph"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<com.jjoe64.graphview.GraphView
android:id="@+id/overview_bggraph"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/overview_chartMenuButton"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<ImageButton
android:id="@+id/overview_chartMenuButton"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="15sp" />
</RelativeLayout>
@ -299,8 +306,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="5dp"
android:orientation="horizontal">
android:orientation="horizontal"
android:paddingRight="5dp">
<info.nightscout.utils.SingleClickButton
android:id="@+id/overview_treatmentbutton"

View file

@ -491,6 +491,13 @@
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="15sp" />
</RelativeLayout>
<com.jjoe64.graphview.GraphView

View file

@ -577,6 +577,13 @@
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="15sp" />
</RelativeLayout>
<com.jjoe64.graphview.GraphView

View file

@ -255,6 +255,13 @@
android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
<TextView
android:id="@+id/overview_iobcalculationprogess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="15sp" />
</RelativeLayout>
<com.jjoe64.graphview.GraphView

View file

@ -11,6 +11,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -18,19 +19,32 @@
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/carbs"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorCarbsButton" />
<ImageView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:src="@drawable/icon_cp_bolus_carbs" />
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="5dp"
android:layout_gravity="center"
android:src="@drawable/icon_cp_bolus_carbs" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="10dp"
android:text="@string/carbs"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorCarbsButton" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
@ -55,44 +69,102 @@
android:id="@+id/newcarbs_hypo_tt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:text="@string/start_hypo_tt" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/time" />
<info.nightscout.utils.NumberPicker
android:id="@+id/newcarbs_time"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="end"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/shortminute" />
</LinearLayout>
<LinearLayout
android:id="@+id/newcarbs_duration_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/duration"/>
<info.nightscout.utils.NumberPicker
android:id="@+id/new_carbs_duration"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:layout_gravity="end" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/shorthour"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp">
android:paddingBottom="5dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/newcarbs_eventdate"
android:layout_width="wrap_content"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp"
android:text="2017/05/05" />
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/overview_carbs_label" />
<info.nightscout.utils.NumberPicker
android:id="@+id/newcarb_carbsamount"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="end"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<TextView
android:id="@+id/newcarb_eventtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp"
android:text="08:20pm" />
android:layout_gravity="center_vertical"
android:text="@string/shortgramm" />
</LinearLayout>
<info.nightscout.utils.NumberPicker
android:id="@+id/newcarb_carbsamount"
android:layout_width="130dp"
android:layout_height="40dp"
android:layout_gravity="end"
android:layout_marginBottom="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -123,15 +195,16 @@
</LinearLayout>
<LinearLayout
android:id="@+id/newcarbs_notes_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_gravity="center_vertical"
android:width="60dp"
android:padding="2dp"
android:text="@string/careportal_newnstreatment_notes_label"
@ -142,7 +215,7 @@
android:id="@+id/newcarbs_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
android:inputType="text|textCapSentences" />
</LinearLayout>

View file

@ -16,20 +16,31 @@
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/overview_insulin_label"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorInsulinButton" />
<ImageView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:padding="5dp"
android:src="@drawable/icon_bolus" />
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="5dp"
android:layout_gravity="center"
android:src="@drawable/icon_bolus" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="10dp"
android:textAlignment="center"
android:text="@string/overview_insulin_label"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/colorInsulinButton" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
@ -52,46 +63,74 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:id="@+id/newinsulin_time_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:paddingTop="5dp">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/time" />
<info.nightscout.utils.NumberPicker
android:id="@+id/newinsulin_time"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="end"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/shortminute" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="5dp">
android:paddingBottom="5dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/newinsulin_eventdate"
android:layout_width="wrap_content"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:padding="5dp"
android:text="2017/05/05" />
android:layout_gravity="center_vertical"
android:textStyle="bold"
android:text="@string/overview_insulin_label" />
<info.nightscout.utils.NumberPicker
android:id="@+id/newinsulin_amount"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="end"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<TextView
android:id="@+id/newinsulin_eventtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:padding="5dp"
android:text="08:20pm" />
android:layout_gravity="center_vertical"
android:text="@string/insulin_unit_shortname" />
</LinearLayout>
<info.nightscout.utils.NumberPicker
android:id="@+id/treatments_newinsulin_amount"
android:layout_width="130dp"
android:layout_height="40dp"
android:layout_gravity="end"
android:layout_marginBottom="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<Button
@ -117,6 +156,31 @@
</LinearLayout>
<LinearLayout
android:id="@+id/newinsulin_notes_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:width="60dp"
android:padding="2dp"
android:text="@string/careportal_newnstreatment_notes_label"
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:textStyle="bold" />
<EditText
android:id="@+id/newinsulin_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text|textCapSentences" />
</LinearLayout>
<include layout="@layout/mdtp_done_button" />
</LinearLayout>

View file

@ -216,11 +216,12 @@
android:textStyle="bold" />
<EditText
android:id="@+id/newcarbs_notes"
android:id="@+id/treatment_wizard_notes"
android:layout_width="155dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:inputType="text|textCapSentences"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

View file

@ -8,6 +8,8 @@
<color name="uam">#ffea00</color>
<color name="zt">#ff9500</color>
<color name="ratio">#FFFFFF</color>
<color name="devslopepos">#FFFFFF00</color>
<color name="devslopeneg">#FFFF00FF</color>
<color name="inrange">#00FF00</color>
<color name="low">#FF0000</color>
<color name="high">#FFFF00</color>
@ -49,7 +51,7 @@
<color name="colorSetExtendedButton">#FFDD7792</color>
<color name="colorProfileSwitchButton">#ca77dd</color>
<color name="colorInProgress">#c45026</color>
<color name="colorScheduled">#de7550</color>
<color name="colorActive">#1b5e20</color>
<color name="loopenabled">#47c8ff</color>

View file

@ -619,6 +619,8 @@
<string name="sensitivityaaps">Sensitivity AAPS</string>
<string name="absorptionsettings_title">Absorption settings</string>
<string name="key_absorption_maxtime" translatable="false">absorption_maxtime</string>
<string name="key_absorption_cutoff" translatable="false">absorption_cutoff</string>
<string name="absorption_maxtime_title">Meal max absorption time [h]</string>
<string name="absorption_maxtime_summary">Time in hours where is expected all carbs from meal will be absorbed</string>
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
@ -715,6 +717,8 @@
<string name="connectiontimedout">Connection timed out</string>
<string name="food">Food</string>
<string name="shortgramm">g</string>
<string name="shortminute">m</string>
<string name="shorthour">h</string>
<string name="none"><![CDATA[<none>]]></string>
<string name="shortkilojoul">kJ</string>
<string name="shortenergy">En</string>
@ -998,4 +1002,18 @@
<string name="pump_stopped">Pump stopped</string>
<string name="pump_started">Pump paused</string>
<string name="pump_paused">Pump started</string>
<string name="absorption_cutoff_title">Meal max absorption time [h]</string>
<string name="absorption_cutoff_summary">Time at which any meal is considered absorbed. Remaining carbs will be cut off.</string>
<string name="time">Time</string>
<string name="key_show_notes_entry_dialogs">show_notes_entry_dialogs</string>
<string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string>
<string name="key_openapsama_min_5m_carbimpact" translatable="false">openapsama_min_5m_carbimpact</string>
<string name="boluserrorcode">Asked: %.2fU Delivered: %.2fU Error code: %d</string>
<string name="firstinsulinincrement">First insulin increment</string>
<string name="secondinsulinincrement">Second insulin increment</string>
<string name="thirdinsulinincrement">Third insulin increment</string>
<string name="firstcarbsincrement">First carbs increment</string>
<string name="secondcarbsincrement">Second carbs increment</string>
<string name="thirdcarbsincrement">Third carbs increment</string>
<string name="cgm">CGM</string>
</resources>

View file

@ -6,10 +6,10 @@
android:title="@string/absorptionsettings_title">
<com.andreabaccega.widget.ValidatingEditTextPreference
validate:testType="numericRange"
validate:minNumber="1"
validate:minNumber="4"
validate:maxNumber="10"
android:digits="0123456789.,"
android:defaultValue="3"
android:defaultValue="6"
android:selectAllOnFocus="true"
android:inputType="number"
android:maxLines="20"

View file

@ -8,14 +8,27 @@
validate:testType="floatNumericRange"
validate:floatminNumber="0.1"
validate:floatmaxNumber="12.0"
android:defaultValue="3.0"
android:defaultValue="8.0"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberDecimal"
android:maxLines="20"
android:title="@string/openapsama_min_5m_carbimpact"
android:dialogMessage="@string/openapsama_min_5m_carbimpact_summary"
android:key="openapsama_min_5m_carbimpact" />
android:key="@string/key_openapsama_min_5m_carbimpact" />
<com.andreabaccega.widget.ValidatingEditTextPreference
validate:testType="numericRange"
validate:minNumber="4"
validate:maxNumber="10"
android:digits="0123456789.,"
android:defaultValue="6"
android:selectAllOnFocus="true"
android:inputType="number"
android:maxLines="20"
android:title="@string/absorption_cutoff_title"
android:dialogMessage="@string/absorption_cutoff_summary"
android:key="@string/key_absorption_cutoff" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -5,29 +5,6 @@
android:key="advanced"
android:title="@string/advancedsettings_title">
<PreferenceScreen android:title="@string/advancedsettings_title">
<PreferenceCategory android:title="@string/nightscout">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_ns_upload_only"
android:summary="@string/ns_upload_only_summary"
android:title="@string/ns_upload_only" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_ns_noupload"
android:summary="@string/ns_noupload_summary"
android:title="@string/ns_noupload" />
<SwitchPreference
android:defaultValue="false"
android:key="ns_sync_use_absolute"
android:title="@string/ns_sync_use_absolute_title" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/superbolus">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_usesuperbolus"
android:summary="@string/enablesuperbolus_summary"
android:title="@string/enablesuperbolus" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/openapsma">
<SwitchPreference
android:defaultValue="false"

View file

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:validate="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
android:key="ns_api"
android:title="@string/nsclientinternal_title">
<PreferenceCategory android:title="@string/nsclientinternal_title">
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="https://{YOUR-SITE}.azurewebsites.net/"
@ -15,93 +14,112 @@
validate:testType="webUrl" />
<EditTextPreference
android:defaultValue=""
android:dialogMessage="@string/nsclientinternal_secret_dialogmessage"
android:dialogTitle="@string/nsclientinternal_secret_dialogtitle"
android:inputType="textPassword"
android:key="@string/key_nsclientinternal_api_secret"
android:title="@string/nsclientinternal_secret_title" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_autobackfill"
android:title="@string/ns_autobackfill" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_logappstartedevent"
android:title="@string/ns_logappstartedevent" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_create_announcements_from_errors"
android:title="@string/ns_create_announcements_from_errors_title"
android:summary="@string/ns_create_announcements_from_errors_summary"/>
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_localbroadcasts"
android:title="@string/ns_localbroadcasts_title"
android:summary="@string/ns_localbroadcasts"/>
<PreferenceScreen android:title="@string/ns_alarmoptions">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_urgent_high"
android:title="@string/nsalarm_urgenthigh"/>
android:title="@string/nsalarm_urgenthigh" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_high"
android:title="@string/nsalarm_high"/>
android:title="@string/nsalarm_high" />
<SwitchPreference
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_low"
android:title="@string/nsalarm_low"/>
android:title="@string/nsalarm_low" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_urgent_low"
android:title="@string/nsalarm_urgentlow"/>
android:title="@string/nsalarm_urgentlow" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_staledata"
android:title="@string/nsalarm_staledata"/>
android:title="@string/nsalarm_staledata" />
<com.andreabaccega.widget.ValidatingEditTextPreference
validate:testType="numericRange"
validate:minNumber="15"
validate:maxNumber="120"
android:digits="0123456789"
android:defaultValue="16"
android:digits="0123456789"
android:inputType="number"
android:key="@string/key_nsalarm_staledatavalue"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="number"
android:maxLines="20"
android:title="@string/nsalarm_staledatavalue_label"
android:key="@string/key_nsalarm_staledatavalue" />
validate:maxNumber="120"
validate:minNumber="15"
validate:testType="numericRange" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_nsalarm_urgent_staledata"
android:title="@string/nsalarm_urgentstaledata"/>
android:title="@string/nsalarm_urgentstaledata" />
<com.andreabaccega.widget.ValidatingEditTextPreference
validate:testType="numericRange"
validate:minNumber="30"
validate:maxNumber="180"
android:digits="0123456789"
android:defaultValue="31"
android:digits="0123456789"
android:inputType="number"
android:key="@string/key_nsalarm_urgent_staledatavalue"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="number"
android:maxLines="20"
android:title="@string/nsalarm_urgent_staledatavalue_label"
android:key="@string/key_nsalarm_urgent_staledatavalue" />
validate:maxNumber="180"
validate:minNumber="30"
validate:testType="numericRange" />
</PreferenceScreen>
<PreferenceScreen android:title="@string/advancedsettings_title">
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_autobackfill"
android:title="@string/ns_autobackfill" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_create_announcements_from_errors"
android:summary="@string/ns_create_announcements_from_errors_summary"
android:title="@string/ns_create_announcements_from_errors_title" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_ns_localbroadcasts"
android:summary="@string/ns_localbroadcasts"
android:title="@string/ns_localbroadcasts_title" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_ns_upload_only"
android:summary="@string/ns_upload_only_summary"
android:title="@string/ns_upload_only" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_ns_noupload"
android:summary="@string/ns_noupload_summary"
android:title="@string/ns_noupload" />
<SwitchPreference
android:defaultValue="false"
android:key="ns_sync_use_absolute"
android:title="@string/ns_sync_use_absolute_title" />
</PreferenceScreen>

View file

@ -1,116 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:validate="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="@string/overview">
<PreferenceScreen android:title="@string/overview_buttons_selection">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_show_treatment_button"
android:title="Treatments" />
android:title="@string/treatments" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_show_wizard_button"
android:title="@string/overview_calculator_label"/>
android:title="@string/overview_calculator_label" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_show_insulin_button"
android:title="Insulin" />
android:title="@string/configbuilder_insulin" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_insulin_button"
validate:testType="floatNumericRange"
validate:floatminNumber="-5.0"
validate:floatmaxNumber="5.0"
android:defaultValue="0.5"
android:selectAllOnFocus="true"
android:singleLine="true"
android:dependency="@string/key_show_insulin_button"
android:dialogMessage="@string/insulin_increment_button_message"
android:inputType="numberDecimal|numberDecimal|numberSigned"
android:key="@string/key_insulin_button_increment_1"
android:maxLines="20"
android:title="First insulin increment"
android:dialogMessage="@string/insulin_increment_button_message"
android:key="@string/key_insulin_button_increment_1" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_insulin_button"
validate:testType="floatNumericRange"
validate:floatminNumber="-5.0"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/firstinsulinincrement"
validate:floatmaxNumber="5.0"
validate:floatminNumber="-5.0"
validate:testType="floatNumericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="1.0"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberDecimal|numberSigned"
android:maxLines="20"
android:title="Second insulin increment"
android:dialogMessage="@string/insulin_increment_button_message"
android:key="@string/key_insulin_button_increment_2" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_insulin_button"
validate:testType="floatNumericRange"
validate:floatminNumber="-5.0"
validate:floatmaxNumber="5.0"
android:defaultValue="2.0"
android:dialogMessage="@string/insulin_increment_button_message"
android:inputType="numberDecimal|numberSigned"
android:key="@string/key_insulin_button_increment_2"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberDecimal|numberSigned"
android:maxLines="20"
android:title="Third insulin increment"
android:title="@string/secondinsulinincrement"
validate:floatmaxNumber="5.0"
validate:floatminNumber="-5.0"
validate:testType="floatNumericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="2.0"
android:dependency="@string/key_show_insulin_button"
android:dialogMessage="@string/insulin_increment_button_message"
android:key="@string/key_insulin_button_increment_3"/>
android:inputType="numberDecimal|numberSigned"
android:key="@string/key_insulin_button_increment_3"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/thirdinsulinincrement"
validate:floatmaxNumber="5.0"
validate:floatminNumber="-5.0"
validate:testType="floatNumericRange" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_show_carbs_button"
android:title="Carbs" />
android:title="@string/carbs" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_carbs_button"
validate:testType="numericRange"
validate:minNumber="-50"
validate:maxNumber="50"
android:defaultValue="5"
android:dependency="@string/key_show_carbs_button"
android:dialogMessage="@string/carb_increment_button_message"
android:inputType="numberSigned"
android:key="@string/key_carbs_button_increment_1"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberSigned"
android:maxLines="20"
android:title="First carbs increment"
android:dialogMessage="@string/carb_increment_button_message"
android:key="@string/key_carbs_button_increment_1" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_carbs_button"
validate:testType="numericRange"
validate:minNumber="-50"
android:title="@string/firstcarbsincrement"
validate:maxNumber="50"
validate:minNumber="-50"
validate:testType="numericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="10"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberSigned"
android:maxLines="20"
android:title="Second carbs increment"
android:dialogMessage="@string/carb_increment_button_message"
android:key="@string/key_carbs_button_increment_2" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:dependency="@string/key_show_carbs_button"
validate:testType="numericRange"
validate:minNumber="-50"
validate:maxNumber="50"
android:defaultValue="20"
android:dialogMessage="@string/carb_increment_button_message"
android:inputType="numberSigned"
android:key="@string/key_carbs_button_increment_2"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:inputType="numberSigned"
android:maxLines="20"
android:title="Third carbs increment"
android:title="@string/secondcarbsincrement"
validate:maxNumber="50"
validate:minNumber="-50"
validate:testType="numericRange" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="20"
android:dependency="@string/key_show_carbs_button"
android:dialogMessage="@string/carb_increment_button_message"
android:key="@string/key_carbs_button_increment_3" />
android:inputType="numberSigned"
android:key="@string/key_carbs_button_increment_3"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/thirdcarbsincrement"
validate:maxNumber="50"
validate:minNumber="-50"
validate:testType="numericRange" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_show_cgm_button"
android:title="CGM"
android:summary="@string/show_cgm_button_summary"/>
android:summary="@string/show_cgm_button_summary"
android:title="@string/cgm" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_show_calibration_button"
android:title="@string/overview_calibration"
android:summary="@string/show_calibration_button_summary"/>
android:summary="@string/show_calibration_button_summary"
android:title="@string/overview_calibration" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_show_notes_entry_dialogs"
android:title="@string/overview_show_notes_field_in_dialogs_title" />
</PreferenceScreen>
<Preference
android:key="quickwizard"
android:title="@string/quickwizardsettings">
<intent android:action="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
</Preference>
<PreferenceScreen android:title="@string/advancedsettings_title">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_usesuperbolus"
android:summary="@string/enablesuperbolus_summary"
android:title="@string/enablesuperbolus" />
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/quickwizard">
<Preference
android:key="quickwizard"
android:title="@string/quickwizardsettings">
<intent android:action="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity"/>
</Preference>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -31,7 +31,7 @@ android {
defaultConfig {
applicationId "info.nightscout.androidaps"
minSdkVersion 21
targetSdkVersion 25
targetSdkVersion 23
versionCode 1
versionName "1.0.2"
buildConfigField "String", "BUILDVERSION", generateGitBuild()