Merge pull request #1980 from MilosKozak/bw

Bolus wizard percentage
This commit is contained in:
Milos Kozak 2019-08-27 22:02:16 +02:00 committed by GitHub
commit 7f45b3d9da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 541 additions and 568 deletions

View file

@ -194,7 +194,7 @@ public class HistoryBrowseActivity extends NoSplashActivity {
@Subscribe @Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished e) { public void onStatusEvent(final EventAutosensCalculationFinished e) {
if (e.cause == eventCustomCalculationFinished) { if (e.getCause() == eventCustomCalculationFinished) {
log.debug("EventAutosensCalculationFinished"); log.debug("EventAutosensCalculationFinished");
runOnUiThread(() -> { runOnUiThread(() -> {
synchronized (HistoryBrowseActivity.this) { synchronized (HistoryBrowseActivity.this) {

View file

@ -155,7 +155,7 @@ public class LoopPlugin extends PluginBase {
*/ */
@Subscribe @Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) { public void onStatusEvent(final EventAutosensCalculationFinished ev) {
if (!(ev.cause instanceof EventNewBG)) { if (!(ev.getCause() instanceof EventNewBG)) {
// Autosens calculation not triggered by a new BG // Autosens calculation not triggered by a new BG
return; return;
} }

View file

@ -8,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
@ -59,17 +60,17 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
View view = inflater.inflate(R.layout.overview_editquickwizard_dialog, container, false); View view = inflater.inflate(R.layout.overview_editquickwizard_dialog, container, false);
buttonEdit = (EditText) view.findViewById(R.id.overview_editquickwizard_button_edit); buttonEdit = view.findViewById(R.id.overview_editquickwizard_button_edit);
carbsEdit = (EditText) view.findViewById(R.id.overview_editquickwizard_carbs_edit); carbsEdit = view.findViewById(R.id.overview_editquickwizard_carbs_edit);
fromSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_from_spinner); fromSpinner = view.findViewById(R.id.overview_editquickwizard_from_spinner);
toSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_to_spinner); toSpinner = view.findViewById(R.id.overview_editquickwizard_to_spinner);
useBGSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebg_spinner); useBGSpinner = view.findViewById(R.id.overview_editquickwizard_usebg_spinner);
useCOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usecob_spinner); useCOBSpinner = view.findViewById(R.id.overview_editquickwizard_usecob_spinner);
useBolusIOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebolusiob_spinner); useBolusIOBSpinner = view.findViewById(R.id.overview_editquickwizard_usebolusiob_spinner);
useBasalIOBSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usebasaliob_spinner); useBasalIOBSpinner = view.findViewById(R.id.overview_editquickwizard_usebasaliob_spinner);
useTrendSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usetrend_spinner); useTrendSpinner = view.findViewById(R.id.overview_editquickwizard_usetrend_spinner);
useSuperBolusSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usesuperbolus_spinner); useSuperBolusSpinner = view.findViewById(R.id.overview_editquickwizard_usesuperbolus_spinner);
useTempTargetSpinner = (Spinner) view.findViewById(R.id.overview_editquickwizard_usetemptarget_spinner); useTempTargetSpinner = view.findViewById(R.id.overview_editquickwizard_usetemptarget_spinner);
view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this);
@ -104,6 +105,19 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic
setSelection(useSuperBolusSpinner, entry.useSuperBolus()); setSelection(useSuperBolusSpinner, entry.useSuperBolus());
setSelection(useTempTargetSpinner, entry.useTempTarget()); setSelection(useTempTargetSpinner, entry.useTempTarget());
useCOBSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
processCob();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
processCob();
return view; return view;
} }
@ -147,6 +161,18 @@ public class EditQuickWizardDialog extends DialogFragment implements View.OnClic
} }
} }
private void processCob() {
if (getSelection(useCOBSpinner) == QuickWizardEntry.YES) {
useBolusIOBSpinner.setEnabled(false);
useBasalIOBSpinner.setEnabled(false);
setSelection(useBolusIOBSpinner, QuickWizardEntry.YES);
setSelection(useBasalIOBSpinner, QuickWizardEntry.YES);
} else {
useBolusIOBSpinner.setEnabled(true);
useBasalIOBSpinner.setEnabled(true);
}
}
int getSelection(Spinner spinner) { int getSelection(Spinner spinner) {
String value = spinner.getSelectedItem().toString(); String value = spinner.getSelectedItem().toString();
if (value.equals(MainApp.gs(R.string.yes))) if (value.equals(MainApp.gs(R.string.yes)))

View file

@ -1,450 +0,0 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.ArrayList;
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.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.BolusWizard;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.StringUtils;
import info.nightscout.androidaps.utils.ToastUtils;
public class WizardDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener, Spinner.OnItemSelectedListener {
private static Logger log = LoggerFactory.getLogger(WizardDialog.class);
Button okButton;
TextView bg;
TextView bgInsulin;
TextView bgUnits;
CheckBox bgCheckbox;
CheckBox ttCheckbox;
TextView carbs;
TextView carbsInsulin;
TextView bolusIobInsulin;
TextView basalIobInsulin;
CheckBox bolusIobCheckbox;
CheckBox basalIobCheckbox;
TextView correctionInsulin;
TextView total;
Spinner profileSpinner;
CheckBox superbolusCheckbox;
TextView superbolus;
TextView superbolusInsulin;
CheckBox bgtrendCheckbox;
TextView bgTrend;
TextView bgTrendInsulin;
LinearLayout cobLayout;
CheckBox cobCheckbox;
TextView cob;
TextView cobInsulin;
NumberPicker editBg;
NumberPicker editCarbs;
NumberPicker editCorr;
NumberPicker editCarbTime;
LinearLayout notesLayout;
EditText notesEdit;
Integer calculatedCarbs = 0;
BolusWizard wizard;
Context context;
//one shot guards
private boolean accepted;
private boolean okClicked;
public WizardDialog() {
super();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
@Override
public void onDetach() {
super.onDetach();
this.context = null;
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.WIZARD));
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean("bgCheckbox", bgCheckbox.isChecked());
savedInstanceState.putBoolean("ttCheckbox", ttCheckbox.isChecked());
savedInstanceState.putBoolean("bolusIobCheckbox", bolusIobCheckbox.isChecked());
savedInstanceState.putBoolean("basalIobCheckbox", basalIobCheckbox.isChecked());
savedInstanceState.putBoolean("bgtrendCheckbox", bgtrendCheckbox.isChecked());
savedInstanceState.putBoolean("cobCheckbox", cobCheckbox.isChecked());
savedInstanceState.putDouble("editBg", editBg.getValue());
savedInstanceState.putDouble("editCarbs", editCarbs.getValue());
savedInstanceState.putDouble("editCorr", editCorr.getValue());
savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue());
super.onSaveInstanceState(savedInstanceState);
}
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished e) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
calculateInsulin();
}
});
}
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
calculateInsulin();
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_wizard_dialog, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
okButton = (Button) view.findViewById(R.id.ok);
okButton.setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
bg = (TextView) view.findViewById(R.id.treatments_wizard_bg);
bgInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bginsulin);
bgUnits = (TextView) view.findViewById(R.id.treatments_wizard_bgunits);
carbs = (TextView) view.findViewById(R.id.treatments_wizard_carbs);
carbsInsulin = (TextView) view.findViewById(R.id.treatments_wizard_carbsinsulin);
bolusIobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bolusiobinsulin);
basalIobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin);
correctionInsulin = (TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin);
total = (TextView) view.findViewById(R.id.treatments_wizard_total);
superbolus = (TextView) view.findViewById(R.id.treatments_wizard_sb);
superbolusInsulin = (TextView) view.findViewById(R.id.treatments_wizard_sbinsulin);
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);
cobLayout = (LinearLayout) view.findViewById(R.id.treatments_wizard_cob_layout);
cob = (TextView) view.findViewById(R.id.treatments_wizard_cob);
cobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_cobinsulin);
bgCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox);
ttCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_ttcheckbox);
bgtrendCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgtrendcheckbox);
cobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_cobcheckbox);
bolusIobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox);
basalIobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_basaliobcheckbox);
superbolusCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_sbcheckbox);
loadCheckedStates();
bgCheckbox.setOnCheckedChangeListener(this);
ttCheckbox.setOnCheckedChangeListener(this);
bgtrendCheckbox.setOnCheckedChangeListener(this);
cobCheckbox.setOnCheckedChangeListener(this);
basalIobCheckbox.setOnCheckedChangeListener(this);
bolusIobCheckbox.setOnCheckedChangeListener(this);
superbolusCheckbox.setOnCheckedChangeListener(this);
profileSpinner = (Spinner) view.findViewById(R.id.treatments_wizard_profile);
profileSpinner.setOnItemSelectedListener(this);
editCarbTime = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbtimeinput);
editCorr = (NumberPicker) view.findViewById(R.id.treatments_wizard_correctioninput);
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbsinput);
editBg = (NumberPicker) view.findViewById(R.id.treatments_wizard_bginput);
superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE);
Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
Double maxCorrection = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.ok), textWatcher);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher);
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false, view.findViewById(R.id.ok), textWatcher);
initDialog();
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
//recovering state if there is something
if (savedInstanceState != null) {
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
editBg.setValue(savedInstanceState.getDouble("editBg"));
editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime"));
editCorr.setValue(savedInstanceState.getDouble("editCorr"));
}
return view;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
saveCheckedStates();
ttCheckbox.setEnabled(bgCheckbox.isChecked() && TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null);
calculateInsulin();
}
private void saveCheckedStates() {
SP.putBoolean(MainApp.gs(R.string.key_wizard_include_cob), cobCheckbox.isChecked());
SP.putBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked());
}
private void loadCheckedStates() {
bgtrendCheckbox.setChecked(SP.getBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), false));
cobCheckbox.setChecked(SP.getBoolean(MainApp.gs(R.string.key_wizard_include_cob), false));
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
calculateInsulin();
okButton.setVisibility(View.VISIBLE);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.noprofileselected));
okButton.setVisibility(View.GONE);
}
@Override
public synchronized void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
if (okClicked) {
log.debug("guarding: ok already clicked");
dismiss();
return;
}
okClicked = true;
wizard.confirmAndExecute(context);
dismiss();
break;
case R.id.cancel:
dismiss();
break;
}
}
private void initDialog() {
Profile profile = ProfileFunctions.getInstance().getProfile();
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null;
if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile));
dismiss();
return;
}
ArrayList<CharSequence> profileList;
profileList = profileStore.getProfileList();
profileList.add(0, MainApp.gs(R.string.active));
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(getContext(),
R.layout.spinner_centered, profileList);
profileSpinner.setAdapter(adapter);
String units = profile.getUnits();
bgUnits.setText(units);
if (units.equals(Constants.MGDL)) editBg.setStep(1d);
else editBg.setStep(0.1d);
// Set BG if not old
BgReading lastBg = DatabaseHelper.actualBg();
if (lastBg != null) {
editBg.setValue(lastBg.valueToUnits(units));
} else {
editBg.setValue(0d);
}
ttCheckbox.setEnabled(TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null);
// IOB calculation
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round();
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
bolusIobInsulin.setText(StringUtils.formatInsulin(-bolusIob.iob));
basalIobInsulin.setText(StringUtils.formatInsulin(-basalIob.basaliob));
calculateInsulin();
}
private void calculateInsulin() {
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
return; // not initialized yet
String profileName = profileSpinner.getSelectedItem().toString();
Profile specificProfile;
if (profileName.equals(MainApp.gs(R.string.active))) {
specificProfile = ProfileFunctions.getInstance().getProfile();
profileName = ProfileFunctions.getInstance().getProfileName();
} else
specificProfile = profileStore.getSpecificProfile(profileName);
// Entered values
Double c_bg = SafeParse.stringToDouble(editBg.getText());
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
Double corrAfterConstraint = c_correction;
if (c_correction > 0)
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
if (Math.abs(c_correction - corrAfterConstraint) > 0.01d) { // c_correction != corrAfterConstraint doesn't work
editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
return;
}
Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value();
if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01d) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
return;
}
c_bg = bgCheckbox.isChecked() ? c_bg : 0d;
TempTarget tempTarget = ttCheckbox.isChecked() ? TreatmentsPlugin.getPlugin().getTempTargetFromHistory() : null;
// COB
Double c_cob = 0d;
if (cobCheckbox.isChecked()) {
CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB");
if (cobInfo.displayCob != null)
c_cob = cobInfo.displayCob;
}
int carbTime = SafeParse.stringToInt(editCarbTime.getText());
wizard = new BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint, 100d, bgCheckbox.isChecked(), cobCheckbox.isChecked(), bolusIobCheckbox.isChecked(), basalIobCheckbox.isChecked(), superbolusCheckbox.isChecked(), ttCheckbox.isChecked(), bgtrendCheckbox.isChecked(), notesEdit.getText().toString(), carbTime);
bg.setText(c_bg + " ISF: " + DecimalFormatter.to1Decimal(wizard.getSens()));
bgInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBG()));
carbs.setText(DecimalFormatter.to0Decimal(c_carbs) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc()));
carbsInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCarbs()));
bolusIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBolusIOB()));
basalIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBasalsIOB()));
correctionInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCorrection()));
calculatedCarbs = carbsAfterConstraint;
// Superbolus
superbolus.setText(superbolusCheckbox.isChecked() ? MainApp.gs(R.string.twohours) : "");
superbolusInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromSuperBolus()));
// Trend
if (bgtrendCheckbox.isChecked() && wizard.getGlucoseStatus() != null) {
bgTrend.setText(
(wizard.getTrend() > 0 ? "+" : "")
+ Profile.toUnitsString(wizard.getTrend() * 3, wizard.getTrend() * 3 / Constants.MMOLL_TO_MGDL, specificProfile.getUnits())
+ " " + specificProfile.getUnits());
} else {
bgTrend.setText("");
}
bgTrendInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromTrend()));
// COB
if (cobCheckbox.isChecked()) {
cob.setText(DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc()));
cobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCOB()));
} else {
cob.setText("");
cobInsulin.setText("");
}
if (wizard.getCalculatedTotalInsulin() > 0d || calculatedCarbs > 0d) {
String insulinText = wizard.getCalculatedTotalInsulin() > 0d ? (DecimalFormatter.toPumpSupportedBolus(wizard.getCalculatedTotalInsulin()) + "U") : "";
String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
okButton.setVisibility(View.VISIBLE);
} else {
// TODO this should also be run when loading the dialog as the OK button is initially visible
// but does nothing if neither carbs nor insulin is > 0
total.setText(MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.getCarbsEquivalent()) + "g");
okButton.setVisibility(View.INVISIBLE);
}
}
}

View file

@ -0,0 +1,344 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.*
import android.widget.AdapterView
import android.widget.AdapterView.*
import android.widget.ArrayAdapter
import android.widget.CompoundButton
import androidx.fragment.app.DialogFragment
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.db.DatabaseHelper
import info.nightscout.androidaps.events.EventFeatureRunning
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.okcancel.*
import kotlinx.android.synthetic.main.overview_wizard_dialog.*
import org.slf4j.LoggerFactory
import java.text.DecimalFormat
import java.util.*
class WizardDialog : DialogFragment() {
private val log = LoggerFactory.getLogger(WizardDialog::class.java)
private var wizard: BolusWizard? = null
private var parentContext: Context? = null
//one shot guards
private var okClicked: Boolean = false
private val textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
calculateInsulin()
}
}
private var disposable: CompositeDisposable = CompositeDisposable()
override fun onAttach(context: Context?) {
super.onAttach(context)
this.parentContext = context
}
override fun onDetach() {
super.onDetach()
this.parentContext = null
}
override fun onResume() {
super.onResume()
MainApp.bus().post(EventFeatureRunning(EventFeatureRunning.Feature.WIZARD))
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("treatments_wizard_bginput", treatments_wizard_bginput.value)
savedInstanceState.putDouble("treatments_wizard_carbsinput", treatments_wizard_carbsinput.value)
savedInstanceState.putDouble("treatments_wizard_correctioninput", treatments_wizard_correctioninput.value)
savedInstanceState.putDouble("treatments_wizard_carbtimeinput", treatments_wizard_carbtimeinput.value)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
dialog.window?.requestFeature(Window.FEATURE_NO_TITLE)
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
dialog.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.overview_wizard_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
loadCheckedStates()
processCobCheckBox()
treatments_wizard_sbcheckbox.visibility = if (SP.getBoolean(R.string.key_usesuperbolus, false)) View.VISIBLE else View.GONE
treatments_wizard_notes_layout.visibility = if (SP.getBoolean(R.string.key_show_notes_entry_dialogs, false)) View.VISIBLE else View.GONE
val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value()
val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value()
treatments_wizard_bginput.setParams(savedInstanceState?.getDouble("treatments_wizard_bginput")
?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
treatments_wizard_carbsinput.setParams(savedInstanceState?.getDouble("treatments_wizard_carbsinput")
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
val bolusstep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep
?: 0.1
treatments_wizard_correctioninput.setParams(savedInstanceState?.getDouble("treatments_wizard_correctioninput")
?: 0.0, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
treatments_wizard_carbtimeinput.setParams(savedInstanceState?.getDouble("treatments_wizard_carbtimeinput")
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
initDialog()
// ok button
ok.setOnClickListener {
if (okClicked) {
log.debug("guarding: ok already clicked")
} else {
okClicked = true
parentContext?.let { context ->
wizard?.confirmAndExecute(context)
}
}
dismiss()
}
// cancel button
cancel.setOnClickListener { dismiss() }
// checkboxes
treatments_wizard_bgcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
treatments_wizard_ttcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
treatments_wizard_cobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
// profile spinner
treatments_wizard_profile.onItemSelectedListener = object : OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.noprofileselected))
ok.visibility = View.GONE
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
calculateInsulin()
ok.visibility = View.VISIBLE
}
}
// bus
disposable.add(RxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
activity?.runOnUiThread { calculateInsulin() }
}, {
FabricPrivacy.logException(it)
})
)
}
override fun onDestroyView() {
super.onDestroyView()
disposable.clear()
}
fun onCheckedChanged(buttonView: CompoundButton) {
saveCheckedStates()
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
if (buttonView.id == treatments_wizard_cobcheckbox.id)
processCobCheckBox()
calculateInsulin()
}
private fun processCobCheckBox() {
if (treatments_wizard_cobcheckbox.isChecked) {
treatments_wizard_bolusiobcheckbox.isEnabled = false
treatments_wizard_basaliobcheckbox.isEnabled = false
treatments_wizard_bolusiobcheckbox.isChecked = true
treatments_wizard_basaliobcheckbox.isChecked = true
} else {
treatments_wizard_bolusiobcheckbox.isEnabled = true
treatments_wizard_basaliobcheckbox.isEnabled = true
}
}
private fun saveCheckedStates() {
SP.putBoolean(MainApp.gs(R.string.key_wizard_include_cob), treatments_wizard_cobcheckbox.isChecked)
SP.putBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), treatments_wizard_bgtrendcheckbox.isChecked)
}
private fun loadCheckedStates() {
treatments_wizard_bgtrendcheckbox.isChecked = SP.getBoolean(MainApp.gs(R.string.key_wizard_include_trend_bg), false)
treatments_wizard_cobcheckbox.isChecked = SP.getBoolean(MainApp.gs(R.string.key_wizard_include_cob), false)
}
private fun initDialog() {
val profile = ProfileFunctions.getInstance().profile
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.noprofile))
dismiss()
return
}
val profileList: ArrayList<CharSequence>
profileList = profileStore.profileList
profileList.add(0, MainApp.gs(R.string.active))
context?.let { context ->
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
treatments_wizard_profile.adapter = adapter
} ?: return
val units = profile.units
treatments_wizard_bgunits.text = units
if (units == Constants.MGDL)
treatments_wizard_bginput.setStep(1.0)
else
treatments_wizard_bginput.setStep(0.1)
// Set BG if not old
val lastBg = DatabaseHelper.actualBg()
if (lastBg != null) {
treatments_wizard_bginput.value = lastBg.valueToUnits(units)
} else {
treatments_wizard_bginput.value = 0.0
}
treatments_wizard_ttcheckbox.isEnabled = TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
// IOB calculation
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments()
val bolusIob = TreatmentsPlugin.getPlugin().lastCalculationTreatments.round()
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals()
val basalIob = TreatmentsPlugin.getPlugin().lastCalculationTempBasals.round()
treatments_wizard_bolusiobinsulin.text = StringUtils.formatInsulin(-bolusIob.iob)
treatments_wizard_basaliobinsulin.text = StringUtils.formatInsulin(-basalIob.basaliob)
calculateInsulin()
treatments_wizard_percent_used.visibility = if (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100) View.VISIBLE else View.GONE
}
private fun calculateInsulin() {
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
if (treatments_wizard_profile.selectedItem == null || profileStore == null)
return // not initialized yet
var profileName = treatments_wizard_profile.selectedItem.toString()
val specificProfile: Profile?
if (profileName == MainApp.gs(R.string.active)) {
specificProfile = ProfileFunctions.getInstance().profile
profileName = ProfileFunctions.getInstance().profileName
} else
specificProfile = profileStore.getSpecificProfile(profileName)
if (specificProfile == null) return
// Entered values
var c_bg = SafeParse.stringToDouble(treatments_wizard_bginput.text)
val c_carbs = SafeParse.stringToInt(treatments_wizard_carbsinput.text)
var c_correction = SafeParse.stringToDouble(treatments_wizard_correctioninput.text)
val corrAfterConstraint = c_correction
if (c_correction > 0)
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(c_correction)).value()
if (Math.abs(c_correction - corrAfterConstraint) > 0.01) { // c_correction != corrAfterConstraint doesn't work
treatments_wizard_correctioninput.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied))
return
}
val carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(c_carbs)).value()
if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01) {
treatments_wizard_carbsinput.value = 0.0
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied))
return
}
c_bg = if (treatments_wizard_bgcheckbox.isChecked) c_bg else 0.0
val tempTarget = if (treatments_wizard_ttcheckbox.isChecked) TreatmentsPlugin.getPlugin().tempTargetFromHistory else null
// COB
var c_cob = 0.0
if (treatments_wizard_cobcheckbox.isChecked) {
val cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB")
cobInfo.displayCob?.let { c_cob = it }
}
val carbTime = SafeParse.stringToInt(treatments_wizard_carbtimeinput.text)
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint,
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
treatments_wizard_bgcheckbox.isChecked,
treatments_wizard_cobcheckbox.isChecked,
treatments_wizard_bolusiobcheckbox.isChecked,
treatments_wizard_basaliobcheckbox.isChecked,
treatments_wizard_sbcheckbox.isChecked,
treatments_wizard_ttcheckbox.isChecked,
treatments_wizard_bgtrendcheckbox.isChecked,
treatment_wizard_notes.text.toString(), carbTime)
wizard?.let { wizard ->
treatments_wizard_bg.text = c_bg.toString() + " ISF: " + DecimalFormatter.to1Decimal(wizard.sens)
treatments_wizard_bginsulin.text = StringUtils.formatInsulin(wizard.insulinFromBG)
treatments_wizard_carbs.text = DecimalFormatter.to0Decimal(c_carbs.toDouble()) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic)
treatments_wizard_carbsinsulin.text = StringUtils.formatInsulin(wizard.insulinFromCarbs)
treatments_wizard_bolusiobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromBolusIOB)
treatments_wizard_basaliobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromBasalsIOB)
treatments_wizard_correctioninsulin.text = StringUtils.formatInsulin(wizard.insulinFromCorrection)
// Superbolus
treatments_wizard_sb.text = if (treatments_wizard_sbcheckbox.isChecked) MainApp.gs(R.string.twohours) else ""
treatments_wizard_sbinsulin.text = StringUtils.formatInsulin(wizard.insulinFromSuperBolus)
// Trend
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, specificProfile.units)
+ " " + specificProfile.units)
} else {
treatments_wizard_bgtrend.text = ""
}
treatments_wizard_bgtrendinsulin.text = StringUtils.formatInsulin(wizard.insulinFromTrend)
// COB
if (treatments_wizard_cobcheckbox.isChecked) {
treatments_wizard_cob.text = DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic)
treatments_wizard_cobinsulin.text = StringUtils.formatInsulin(wizard.insulinFromCOB)
} else {
treatments_wizard_cob.text = ""
treatments_wizard_cobinsulin.text = ""
}
if (wizard.calculatedTotalInsulin > 0.0 || carbsAfterConstraint > 0.0) {
val insulinText = if (wizard.calculatedTotalInsulin > 0.0) DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U" else ""
val carbsText = if (carbsAfterConstraint > 0.0) DecimalFormatter.to0Decimal(carbsAfterConstraint.toDouble()) + "g" else ""
treatments_wizard_total.text = MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText
ok.visibility = View.VISIBLE
} else {
treatments_wizard_total.text = MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g"
ok.visibility = View.INVISIBLE
}
}
}
}

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
@ -312,6 +313,7 @@ public class IobCobThread extends Thread {
new Thread(() -> { new Thread(() -> {
SystemClock.sleep(1000); SystemClock.sleep(1000);
MainApp.bus().post(new EventAutosensCalculationFinished(cause)); MainApp.bus().post(new EventAutosensCalculationFinished(cause));
RxBus.INSTANCE.send(new EventAutosensCalculationFinished(cause));
}).start(); }).start();
} finally { } finally {
if (mWakeLock != null) if (mWakeLock != null)

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventLoop;
/**
* Created by mike on 30.04.2017.
*/
public class EventAutosensCalculationFinished extends EventLoop {
public Event cause;
public EventAutosensCalculationFinished(Event cause) {
this.cause = cause;
}
}

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.events
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventLoop
class EventAutosensCalculationFinished(var cause: Event) : EventLoop()

View file

@ -1,86 +0,0 @@
package info.nightscout.androidaps.plugins.treatments.dialogs;
import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.TextView;
import org.json.JSONObject;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.JsonHelper;
public class WizardInfoDialog extends DialogFragment implements OnClickListener {
JSONObject json;
public WizardInfoDialog() {
super();
}
public void setData(JSONObject json) {
this.json = json;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_wizardinfo_dialog, container, false);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
view.findViewById(R.id.ok).setOnClickListener(this);
// BG
((TextView) view.findViewById(R.id.treatments_wizard_bg)).setText(DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + " ISF: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "isf")));
((TextView) view.findViewById(R.id.treatments_wizard_bginsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinbg")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "insulinbgused"));
((CheckBox) view.findViewById(R.id.treatments_wizard_ttcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "ttused"));
// Trend
((TextView) view.findViewById(R.id.treatments_wizard_bgtrend)).setText(JsonHelper.safeGetString(json, "trend"));
((TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulintrend")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_bgtrendcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "trendused"));
// COB
((TextView) view.findViewById(R.id.treatments_wizard_cob)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "cob")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic")));
((TextView) view.findViewById(R.id.treatments_wizard_cobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincob")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_cobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "cobused"));
// Bolus IOB
((TextView) view.findViewById(R.id.treatments_wizard_bolusiobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "bolusiob")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "bolusiobused"));
// Basal IOB
((TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "basaliob")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_basaliobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "basaliobused"));
// Superbolus
((TextView) view.findViewById(R.id.treatments_wizard_sbinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinsuperbolus")) + "U");
((CheckBox) view.findViewById(R.id.treatments_wizard_sbcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "superbolusused"));
// Carbs
((TextView) view.findViewById(R.id.treatments_wizard_carbs)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "carbs")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic")));
((TextView) view.findViewById(R.id.treatments_wizard_carbsinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincarbs")) + "U");
// Correction
((TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "othercorrection")) + "U");
// Profile
((TextView) view.findViewById(R.id.treatments_wizard_profile)).setText(JsonHelper.safeGetString(json, "profile"));
// Notes
((TextView) view.findViewById(R.id.treatments_wizard_notes)).setText(JsonHelper.safeGetString(json, "notes"));
// Total
((TextView) view.findViewById(R.id.treatments_wizard_totalinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulin")) + "U");
setCancelable(true);
return view;
}
@Override
public synchronized void onClick(View view) {
switch (view.getId()) {
case R.id.ok:
dismiss();
break;
}
}
}

View file

@ -0,0 +1,70 @@
package info.nightscout.androidaps.plugins.treatments.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.JsonHelper
import kotlinx.android.synthetic.main.treatments_wizardinfo_dialog.*
import org.json.JSONObject
class WizardInfoDialog : DialogFragment() {
private var json: JSONObject? = null
fun setData(json: JSONObject) {
this.json = json
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
isCancelable = true
return inflater.inflate(R.layout.treatments_wizardinfo_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
close.setOnClickListener { dismiss() }
// BG
treatments_wizard_bg.text = DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + " ISF: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "isf"))
treatments_wizard_bginsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinbg")) + "U"
treatments_wizard_bgcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "insulinbgused")
treatments_wizard_ttcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "ttused")
// Trend
treatments_wizard_bgtrend.text = JsonHelper.safeGetString(json, "trend")
treatments_wizard_bgtrendinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulintrend")) + "U"
treatments_wizard_bgtrendcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "trendused")
// COB
treatments_wizard_cob.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "cob")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))
treatments_wizard_cobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincob")) + "U"
treatments_wizard_cobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "cobused")
// Bolus IOB
treatments_wizard_bolusiobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "bolusiob")) + "U"
treatments_wizard_bolusiobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "bolusiobused")
// Basal IOB
treatments_wizard_basaliobinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "basaliob")) + "U"
treatments_wizard_basaliobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "basaliobused")
// Superbolus
treatments_wizard_sbinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinsuperbolus")) + "U"
treatments_wizard_sbcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "superbolusused")
// Carbs
treatments_wizard_carbs.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "carbs")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))
treatments_wizard_carbsinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincarbs")) + "U"
// Correction
treatments_wizard_correctioninsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "othercorrection")) + "U"
// Profile
treatments_wizard_profile.text = JsonHelper.safeGetString(json, "profile")
// Notes
treatments_wizard_notes.text = JsonHelper.safeGetString(json, "notes")
// Percentage
treatments_wizard_percent_used.text = DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "percentageCorrection", 100.0)) + "%"
// Total
treatments_wizard_totalinsulin.text = DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulin")) + "U"
}
}

View file

@ -231,6 +231,7 @@ class BolusWizard @JvmOverloads constructor(val profile: Profile,
boluscalcJSON.put("insulintrend", insulinFromTrend) boluscalcJSON.put("insulintrend", insulinFromTrend)
boluscalcJSON.put("trend", trend) boluscalcJSON.put("trend", trend)
boluscalcJSON.put("ttused", useTT) boluscalcJSON.put("ttused", useTT)
boluscalcJSON.put("percentageCorrection", percentageCorrection)
} catch (e: JSONException) { } catch (e: JSONException) {
log.error("Unhandled exception", e) log.error("Unhandled exception", e)
} }

View file

@ -72,6 +72,19 @@ public class JsonHelper {
return result; return result;
} }
public static double safeGetDouble(JSONObject json, String fieldName, double defaultValue) {
double result = defaultValue;
if (json != null && json.has(fieldName)) {
try {
result = json.getDouble(fieldName);
} catch (JSONException ignored) {
}
}
return result;
}
public static int safeGetInt(JSONObject json, String fieldName) { public static int safeGetInt(JSONObject json, String fieldName) {
int result = 0; int result = 0;

View file

@ -197,6 +197,18 @@
android:text="2.35U 28g" android:text="2.35U 28g"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/treatments_wizard_percent_used"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:background="@drawable/background_darkgray"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="50%"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/iob" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -226,7 +238,7 @@
</LinearLayout> </LinearLayout>
<include layout="@layout/mdtp_done_button" /> <include layout="@layout/okcancel" />
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"

View file

@ -395,6 +395,41 @@
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="32dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="86dp"
android:text="@string/percent"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="94dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/treatments_wizard_percent_used"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="50dp"
android:gravity="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -440,7 +475,7 @@
android:paddingBottom="8dp"> android:paddingBottom="8dp">
<Button <Button
android:id="@+id/ok" android:id="@+id/close"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"

View file

@ -1667,8 +1667,11 @@
<string name="pump_no_connection_d">No connection for %1$d day(s) %2$d hours</string> <string name="pump_no_connection_d">No connection for %1$d day(s) %2$d hours</string>
<string name="insulinFromCob"><![CDATA[COB insulin: <font color=\'%1$s\'>%2$.1fg %3$.2fU</font>]]></string> <string name="insulinFromCob"><![CDATA[COB insulin: <font color=\'%1$s\'>%2$.1fg %3$.2fU</font>]]></string>
<string name="bolusconstraintappliedwarning"><![CDATA[<font color=\'%1$s\'>Bolus constraint applied: %2$.2fU to %3$.2fU</font>]]></string> <string name="bolusconstraintappliedwarning"><![CDATA[<font color=\'%1$s\'>Bolus constraint applied: %2$.2fU to %3$.2fU</font>]]></string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! Slow carbs absorption detected: %2$d%% of time. Double check your calculation. COB can be really off !!!!!</font>]]></string> <string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! Slow carbs absorption detected: %2$d%% of time. Double check your calculation. COB can be overestimated thus more insulin could be given !!!!!</font>]]></string>
<string name="reservoirvalue">%1$.0f / %2$d U</string> <string name="reservoirvalue">%1$.0f / %2$d U</string>
<string name="key_boluswizard_percentage" translatable="false">boluswizard_percentage</string>
<string name="partialboluswizard">Deliver this part of bolus wizard result [%]</string>
<string name="deliverpartofboluswizard">Bolus wizard performs calculation but only this part of calculated insulin is delivered. Useful with SMB algorithm.</string>
<string name="loading">Loading ...</string> <string name="loading">Loading ...</string>
<plurals name="objective_days"> <plurals name="objective_days">

View file

@ -143,6 +143,19 @@
<PreferenceScreen android:title="@string/advancedsettings_title" android:key="@string/key_advancedsettings"> <PreferenceScreen android:title="@string/advancedsettings_title" android:key="@string/key_advancedsettings">
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="100"
android:dialogMessage="@string/deliverpartofboluswizard"
android:inputType="number"
android:key="@string/key_boluswizard_percentage"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/partialboluswizard"
validate:maxNumber="100"
validate:minNumber="10"
validate:testType="numericRange" />
<SwitchPreference <SwitchPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/key_usesuperbolus" android:key="@string/key_usesuperbolus"