AndroidAPS/app/src/main/res/layout/overview_fragment.xml

1843 lines
88 KiB
XML
Raw Normal View History

package info.nightscout.androidaps.plugins.Overview;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
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.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.LabelFormatter;
import com.jjoe64.graphview.ValueDependentColor;
import com.jjoe64.graphview.Viewport;
import com.jjoe64.graphview.series.BarGraphSeries;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.jjoe64.graphview.series.Series;
import com.squareup.otto.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
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.DetailedBolusInfo;
import info.nightscout.androidaps.data.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
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.EventPumpStatusChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTempTargetChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
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.BasalData;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
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.OpenAPSAMA.DetermineBasalResultAMA;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.AreaGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DoubleDataPoint;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.FixedLineGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
import info.nightscout.utils.BolusWizard;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.OKDialog;
import info.nightscout.utils.Profiler;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
import info.nightscout.utils.ToastUtils;
//Added By Rumen for staledata alarm
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
public class OverviewFragment extends Fragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
public static OverviewPlugin getPlugin() {
return overviewPlugin;
}
TextView timeView;
TextView bgView;
TextView arrowView;
TextView timeAgoView;
TextView deltaView;
TextView avgdeltaView;
TextView baseBasalView;
TextView extendedBolusView;
TextView activeProfileView;
TextView iobView;
TextView cobView;
TextView apsModeView;
TextView tempTargetView;
TextView pumpStatusView;
TextView pumpDeviceStatusView;
TextView openapsDeviceStatusView;
TextView uploaderDeviceStatusView;
LinearLayout loopStatusLayout;
LinearLayout pumpStatusLayout;
GraphView bgGraph;
GraphView iobGraph;
TextView iage;
TextView cage;
TextView sage;
TextView pbage;
CheckBox showPredictionView;
CheckBox showBasalsView;
CheckBox showIobView;
CheckBox showCobView;
CheckBox showDeviationsView;
CheckBox showRatiosView;
RecyclerView notificationsView;
LinearLayoutManager llm;
LinearLayout acceptTempLayout;
Button treatmentButton;
Button wizardButton;
Button calibrationButton;
Button acceptTempButton;
Button quickWizardButton;
CheckBox lockScreen;
boolean smallWidth;
boolean smallHeight;
public static boolean shorttextmode = false;
private int rangeToDisplay = 6; // for graph
Handler sLoopHandler = new Handler();
Runnable sRefreshLoop = null;
private static Handler sHandler;
private static HandlerThread sHandlerThread;
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledUpdate = null;
public OverviewFragment() {
super();
if (sHandlerThread == null) {
sHandlerThread = new HandlerThread(OverviewFragment.class.getSimpleName());
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//check screen width
final DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screen_width = dm.widthPixels;
int screen_height = dm.heightPixels;
smallWidth = screen_width < Constants.SMALL_WIDTH;
smallHeight = screen_height < Constants.SMALL_HEIGHT;
boolean landscape = screen_height < screen_width;
View view;
if (MainApp.sResources.getBoolean(R.bool.isTablet) && BuildConfig.NSCLIENTOLNY) {
view = inflater.inflate(R.layout.overview_fragment_nsclient_tablet, container, false);
} else if (BuildConfig.NSCLIENTOLNY) {
view = inflater.inflate(R.layout.overview_fragment_nsclient, container, false);
shorttextmode = true;
} else if (smallHeight || landscape) {
view = inflater.inflate(R.layout.overview_fragment_smallheight, container, false);
} else {
view = inflater.inflate(R.layout.overview_fragment, container, false);
}
timeView = (TextView) view.findViewById(R.id.overview_time);
bgView = (TextView) view.findViewById(R.id.overview_bg);
arrowView = (TextView) view.findViewById(R.id.overview_arrow);
if (smallWidth) {
arrowView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 35);
}
timeAgoView = (TextView) view.findViewById(R.id.overview_timeago);
deltaView = (TextView) view.findViewById(R.id.overview_delta);
avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta);
baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal);
extendedBolusView = (TextView) view.findViewById(R.id.overview_extendedbolus);
activeProfileView = (TextView) view.findViewById(R.id.overview_activeprofile);
pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus);
pumpDeviceStatusView = (TextView) view.findViewById(R.id.overview_pump);
openapsDeviceStatusView = (TextView) view.findViewById(R.id.overview_openaps);
uploaderDeviceStatusView = (TextView) view.findViewById(R.id.overview_uploader);
loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout);
pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout);
pumpStatusView.setBackgroundColor(MainApp.sResources.getColor(R.color.colorInitializingBorder));
iobView = (TextView) view.findViewById(R.id.overview_iob);
cobView = (TextView) view.findViewById(R.id.overview_cob);
apsModeView = (TextView) view.findViewById(R.id.overview_apsmode);
tempTargetView = (TextView) view.findViewById(R.id.overview_temptarget);
iage = (TextView) view.findViewById(R.id.careportal_insulinage);
cage = (TextView) view.findViewById(R.id.careportal_canulaage);
sage = (TextView) view.findViewById(R.id.careportal_sensorage);
pbage = (TextView) view.findViewById(R.id.careportal_pbage);
bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph);
iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph);
treatmentButton = (Button) view.findViewById(R.id.overview_treatmentbutton);
treatmentButton.setOnClickListener(this);
wizardButton = (Button) view.findViewById(R.id.overview_wizardbutton);
wizardButton.setOnClickListener(this);
acceptTempButton = (Button) view.findViewById(R.id.overview_accepttempbutton);
if (acceptTempButton != null)
acceptTempButton.setOnClickListener(this);
quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizardbutton);
quickWizardButton.setOnClickListener(this);
calibrationButton = (Button) view.findViewById(R.id.overview_calibrationbutton);
if (calibrationButton != null)
calibrationButton.setOnClickListener(this);
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
showPredictionView = (CheckBox) view.findViewById(R.id.overview_showprediction);
showBasalsView = (CheckBox) view.findViewById(R.id.overview_showbasals);
showIobView = (CheckBox) view.findViewById(R.id.overview_showiob);
showCobView = (CheckBox) view.findViewById(R.id.overview_showcob);
showDeviationsView = (CheckBox) view.findViewById(R.id.overview_showdeviations);
showRatiosView = (CheckBox) view.findViewById(R.id.overview_showratios);
showPredictionView.setChecked(SP.getBoolean("showprediction", false));
showBasalsView.setChecked(SP.getBoolean("showbasals", true));
showIobView.setChecked(SP.getBoolean("showiob", false));
showCobView.setChecked(SP.getBoolean("showcob", false));
showDeviationsView.setChecked(SP.getBoolean("showdeviations", false));
showRatiosView.setChecked(SP.getBoolean("showratios", false));
showPredictionView.setOnCheckedChangeListener(this);
showBasalsView.setOnCheckedChangeListener(this);
showIobView.setOnCheckedChangeListener(this);
showCobView.setOnCheckedChangeListener(this);
showDeviationsView.setOnCheckedChangeListener(this);
showRatiosView.setOnCheckedChangeListener(this);
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
notificationsView.setHasFixedSize(true);
llm = new LinearLayoutManager(view.getContext());
notificationsView.setLayoutManager(llm);
bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
bgGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
iobGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
bgGraph.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
rangeToDisplay += 6;
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
SP.putInt(R.string.key_rangetodisplay, rangeToDisplay);
updateGUI("rangeChange");
return false;
}
});
lockScreen = (CheckBox) view.findViewById(R.id.overview_lockscreen);
if (lockScreen != null) {
lockScreen.setChecked(SP.getBoolean("lockscreen", false));
lockScreen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SP.putBoolean("lockscreen", isChecked);
MainApp.bus().post(new EventSetWakeLock(isChecked));
}
});
}
return view;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (activeloop == null)
return;
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
if (activeloop.isEnabled(PluginBase.LOOP)) {
menu.add(MainApp.sResources.getString(R.string.disableloop));
if (!activeloop.isSuspended()) {
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor3h));
} else {
menu.add(MainApp.sResources.getString(R.string.resume));
}
}
if (!activeloop.isEnabled(PluginBase.LOOP))
menu.add(MainApp.sResources.getString(R.string.enableloop));
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (buttonView.getId()) {
case R.id.overview_showprediction:
case R.id.overview_showbasals:
case R.id.overview_showiob:
break;
case R.id.overview_showcob:
showDeviationsView.setOnCheckedChangeListener(null);
showDeviationsView.setChecked(false);
showDeviationsView.setOnCheckedChangeListener(this);
break;
case R.id.overview_showdeviations:
showCobView.setOnCheckedChangeListener(null);
showCobView.setChecked(false);
showCobView.setOnCheckedChangeListener(this);
break;
case R.id.overview_showratios:
break;
}
SP.putBoolean("showiob", showIobView.isChecked());
SP.putBoolean("showprediction", showPredictionView.isChecked());
SP.putBoolean("showbasals", showBasalsView.isChecked());
SP.putBoolean("showcob", showCobView.isChecked());
SP.putBoolean("showdeviations", showDeviationsView.isChecked());
SP.putBoolean("showratios", showRatiosView.isChecked());
scheduleUpdateGUI("onGraphCheckboxesCheckedChanged");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
activeloop.setFragmentVisible(PluginBase.LOOP, false);
MainApp.getConfigBuilder().storeSettings();
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(60); // upload 60 min, we don;t know real duration
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
activeloop.setFragmentVisible(PluginBase.LOOP, true);
MainApp.getConfigBuilder().storeSettings();
updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) {
activeloop.suspendTo(0L);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) {
activeloop.suspendTo(System.currentTimeMillis() + 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(60);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) {
activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(120);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) {
activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(180);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) {
activeloop.suspendTo(System.currentTimeMillis() + 10 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(600);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().cancelTempBasal(true);
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 30);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(30);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
activeloop.suspendTo(System.currentTimeMillis() + 1 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().cancelTempBasal(true);
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(60);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().cancelTempBasal(true);
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 2 * 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(120);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000);
updateGUI("suspendmenu");
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().cancelTempBasal(true);
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 3 * 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
NSUpload.uploadOpenAPSOffline(180);
return true;
}
return super.onContextItemSelected(item);
}
@Override
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
switch (v.getId()) {
case R.id.overview_accepttempbutton:
onClickAcceptTemp();
break;
case R.id.overview_quickwizardbutton:
onClickQuickwizard();
break;
case R.id.overview_wizardbutton:
WizardDialog wizardDialog = new WizardDialog();
wizardDialog.show(manager, "WizardDialog");
break;
case R.id.overview_calibrationbutton:
CalibrationDialog calibrationDialog = new CalibrationDialog();
calibrationDialog.show(manager, "CalibrationDialog");
break;
case R.id.overview_treatmentbutton:
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog();
treatmentDialogFragment.show(manager, "TreatmentDialog");
break;
case R.id.overview_pumpstatus:
if (MainApp.getConfigBuilder().isSuspended() || !MainApp.getConfigBuilder().isInitialized())
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().refreshDataFromPump("RefreshClicked");
}
});
break;
}
}
private void onClickAcceptTemp() {
if (ConfigBuilderPlugin.getActiveLoop() != null) {
ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.changeRequested) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getContext().getString(R.string.confirmation));
builder.setMessage(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
sHandler.post(new Runnable() {
@Override
public void run() {
hideTempRecommendation();
clearNotification();
PumpEnactResult applyResult = MainApp.getConfigBuilder().applyAPSRequest(finalLastRun.constraintsProcessed);
if (applyResult.enacted) {
finalLastRun.setByPump = applyResult;
finalLastRun.lastEnact = new Date();
finalLastRun.lastOpenModeAccept = new Date();
NSUpload.uploadDeviceStatus();
ObjectivesPlugin objectivesPlugin = (ObjectivesPlugin) MainApp.getSpecificPlugin(ObjectivesPlugin.class);
if (objectivesPlugin != null) {
ObjectivesPlugin.manualEnacts++;
ObjectivesPlugin.saveProgress();
}
}
scheduleUpdateGUI("onClickAcceptTemp");
}
});
Answers.getInstance().logCustom(new CustomEvent("AcceptTemp"));
}
});
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
builder.show();
}
}
}
void onClickQuickwizard() {
final BgReading actualBg = DatabaseHelper.actualBg();
final Profile profile = MainApp.getConfigBuilder().getProfile();
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && actualBg != null) {
quickWizardButton.setVisibility(View.VISIBLE);
BolusWizard wizard = new BolusWizard();
wizard.doCalc(profile, quickWizardEntry.carbs(), 0d, actualBg.valueToUnits(profile.getUnits()), 0d, true, true, false, false);
final JSONObject boluscalcJSON = new JSONObject();
try {
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiobused", true);
boluscalcJSON.put("basaliobused", true);
boluscalcJSON.put("bg", actualBg.valueToUnits(profile.getUnits()));
boluscalcJSON.put("insulinbg", wizard.insulinFromBG);
boluscalcJSON.put("insulinbgused", true);
boluscalcJSON.put("bgdiff", wizard.bgDiff);
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", quickWizardEntry.carbs());
boluscalcJSON.put("othercorrection", 0d);
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("insulin", wizard.calculatedTotalInsulin);
} catch (JSONException e) {
e.printStackTrace();
}
if (wizard.calculatedTotalInsulin > 0d && quickWizardEntry.carbs() > 0d) {
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
String confirmMessage = getString(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(wizard.calculatedTotalInsulin);
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(quickWizardEntry.carbs());
confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U";
confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
if (!insulinAfterConstraints.equals(wizard.calculatedTotalInsulin) || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.treatmentdeliveryerror));
builder.setMessage(getString(R.string.constraints_violation) + "\n" + getString(R.string.changeyourinput));
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
builder.show();
return;
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Integer finalCarbsAfterConstraints = carbsAfterConstraints;
final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
final ConfigBuilderPlugin pump = MainApp.getConfigBuilder();
sHandler.post(new Runnable() {
@Override
public void run() {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
PumpEnactResult result = pump.deliverTreatment(detailedBolusInfo);
if (!result.success) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.treatmentdeliveryerror));
builder.setMessage(result.comment);
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
builder.show();
}
}
});
Answers.getInstance().logCustom(new CustomEvent("QuickWizard"));
}
}
});
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
}
}
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
sLoopHandler.removeCallbacksAndMessages(null);
unregisterForContextMenu(apsModeView);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
sRefreshLoop = new Runnable() {
@Override
public void run() {
scheduleUpdateGUI("refreshLoop");
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
// Added by Rumen for STALE DATA ALARM
boolean isThereStaleData = Notification.isAlarmForStaleData();
log.debug("isThereIsStaleData: "+isThereStaleData);
if(isThereStaleData){
Notification notification = new Notification(Notification.NSALARM, getString(R.string.nsalarm_staledata), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
}
// end of insert
}
};
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
registerForContextMenu(apsModeView);
updateGUI("onResume");
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
scheduleUpdateGUI("EventInitializationChanged");
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange ev) {
scheduleUpdateGUI("EventPreferenceChange");
}
@Subscribe
public void onStatusEvent(final EventRefreshOverview ev) {
scheduleUpdateGUI(ev.from);
}
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
scheduleUpdateGUI("EventAutosensCalculationFinished");
}
@Subscribe
public void onStatusEvent(final EventTreatmentChange ev) {
scheduleUpdateGUI("EventTreatmentChange");
}
@Subscribe
public void onStatusEvent(final EventCareportalEventChange ev) {
scheduleUpdateGUI("EventCareportalEventChange");
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
scheduleUpdateGUI("EventTempBasalChange");
}
@Subscribe
public void onStatusEvent(final EventExtendedBolusChange ev) {
scheduleUpdateGUI("EventExtendedBolusChange");
}
// Handled by EventAutosensCalculationFinished
// @Subscribe
// public void onStatusEvent(final EventNewBG ev) {
// scheduleUpdateGUI("EventNewBG");
// }
@Subscribe
public void onStatusEvent(final EventNewOpenLoopNotification ev) {
scheduleUpdateGUI("EventNewOpenLoopNotification");
}
// Handled by EventAutosensCalculationFinished
// @Subscribe
// public void onStatusEvent(final EventNewBasalProfile ev) {
// scheduleUpdateGUI("EventNewBasalProfile");
// }
@Subscribe
public void onStatusEvent(final EventTempTargetChange ev) {
scheduleUpdateGUI("EventTempTargetChange");
}
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged s) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updatePumpStatus(s.textStatus());
}
});
}
private void hideTempRecommendation() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (acceptTempLayout != null)
acceptTempLayout.setVisibility(View.GONE);
}
});
}
private void clearNotification() {
NotificationManager notificationManager =
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(Constants.notificationID);
}
private void updatePumpStatus(String status) {
if (!status.equals("")) {
pumpStatusView.setText(status);
pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE);
} else {
pumpStatusLayout.setVisibility(View.GONE);
loopStatusLayout.setVisibility(View.VISIBLE);
}
}
public void scheduleUpdateGUI(final String from) {
class UpdateRunnable implements Runnable {
public void run() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI(from);
scheduledUpdate = null;
}
});
}
}
// prepare task for execution in 400 msec
// cancel waiting task to prevent multiple updates
if (scheduledUpdate != null)
scheduledUpdate.cancel(false);
Runnable task = new UpdateRunnable();
final int msec = 500;
scheduledUpdate = worker.schedule(task, msec, TimeUnit.MILLISECONDS);
}
@SuppressLint("SetTextI18n")
public void updateGUI(String from) {
log.debug("updateGUI entered from: " + from);
Date updateGUIStart = new Date();
if (getActivity() == null)
return;
if (timeView != null) { //must not exists
timeView.setText(DateUtil.timeString(new Date()));
}
if (MainApp.getConfigBuilder().getProfile() == null) {// app not initialized yet
pumpStatusView.setText(R.string.noprofileset);
pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE);
return;
}
pumpStatusLayout.setVisibility(View.GONE);
loopStatusLayout.setVisibility(View.VISIBLE);
updateNotifications();
CareportalFragment.updateAge(getActivity(), sage, iage, cage, pbage);
BgReading actualBG = DatabaseHelper.actualBg();
BgReading lastBG = DatabaseHelper.lastBg();
PumpInterface pump = MainApp.getConfigBuilder();
Profile profile = MainApp.getConfigBuilder().getProfile();
String units = profile.getUnits();
if (units == null) {
pumpStatusView.setText(R.string.noprofileset);
pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE);
return;
}
// open loop mode
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (Config.APS && MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable) {
apsModeView.setVisibility(View.VISIBLE);
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.loopenabled));
apsModeView.setTextColor(Color.BLACK);
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuperBolus()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuperbolusfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (pump.isSuspended()) {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.looppumpsuspended));
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
if (MainApp.getConfigBuilder().isClosedModeEnabled()) {
apsModeView.setText(MainApp.sResources.getString(R.string.closedloop));
} else {
apsModeView.setText(MainApp.sResources.getString(R.string.openloop));
}
} else {
apsModeView.setBackgroundColor(MainApp.sResources.getColor(R.color.loopdisabled));
apsModeView.setText(MainApp.sResources.getString(R.string.disabledloop));
apsModeView.setTextColor(Color.WHITE);
}
} else {
apsModeView.setVisibility(View.GONE);
}
// temp target
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
if (tempTarget != null) {
tempTargetView.setTextColor(Color.BLACK);
tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetBackground));
tempTargetView.setVisibility(View.VISIBLE);
if (tempTarget.low == tempTarget.high)
tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, units), units));
else
tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, units), units) + " - " + Profile.toUnitsString(tempTarget.high, Profile.fromMgdlToUnits(tempTarget.high, units), units));
} else {
Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL;
Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL;
if (!units.equals(Constants.MGDL)) {
maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL;
minBgDefault = Constants.MIN_BG_DEFAULT_MMOL;
}
tempTargetView.setTextColor(Color.WHITE);
tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetDisabledBackground));
double low = SP.getDouble("openapsma_min_bg", minBgDefault);
double high = SP.getDouble("openapsma_max_bg", maxBgDefault);
if (low == high)
tempTargetView.setText("" + low);
else
tempTargetView.setText(low + " - " + high);
tempTargetView.setVisibility(View.VISIBLE);
}
if (Config.NSCLIENT && tempTarget == null) {
tempTargetView.setVisibility(View.GONE);
}
// **** Temp button ****
if (acceptTempLayout != null) {
boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested
if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) {
acceptTempLayout.setVisibility(View.VISIBLE);
acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
} else {
acceptTempLayout.setVisibility(View.GONE);
}
}
// **** Calibration button ****
if (calibrationButton != null) {
if (MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && DatabaseHelper.actualBg() != null) {
calibrationButton.setVisibility(View.VISIBLE);
} else {
calibrationButton.setVisibility(View.GONE);
}
}
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
String basalText = "";
if (shorttextmode) {
if (activeTemp != null) {
basalText = "T: " + activeTemp.toStringVeryShort();
} else {
basalText = DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h";
}
baseBasalView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String fullText = MainApp.sResources.getString(R.string.virtualpump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h\n";
if (activeTemp != null) {
fullText += MainApp.sResources.getString(R.string.virtualpump_tempbasal_label) + ": " + activeTemp.toStringFull();
}
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.basal), fullText, null);
}
});
} else {
if (activeTemp != null) {
basalText = activeTemp.toStringFull() + " ";
}
if (Config.NSCLIENT)
basalText += "(" + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + " U/h)";
else if (pump.getPumpDescription().isTempBasalCapable) {
basalText += "(" + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + "U/h)";
}
}
if (activeTemp != null) {
baseBasalView.setTextColor(MainApp.sResources.getColor(R.color.basal));
} else {
baseBasalView.setTextColor(Color.WHITE);
}
baseBasalView.setText(basalText);
final ExtendedBolus extendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
String extendedBolusText = "";
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
extendedBolusText = extendedBolus.toString();
}
if (extendedBolusView != null) { // must not exists in all layouts
if (shorttextmode) {
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
extendedBolusText = DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + "U/h";
} else {
extendedBolusText = "";
}
extendedBolusView.setText(extendedBolusText);
extendedBolusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.extendedbolus), extendedBolus.toString(), null);
}
});
} else {
extendedBolusView.setText(extendedBolusText);
}
}
activeProfileView.setText(MainApp.getConfigBuilder().getProfileName());
activeProfileView.setBackgroundColor(Color.GRAY);
activeProfileView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
activeProfileView.setLongClickable(true);
tempTargetView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.temptarget;
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
tempTargetView.setLongClickable(true);
// QuickWizard button
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
quickWizardButton.setVisibility(View.VISIBLE);
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = new BolusWizard();
wizard.doCalc(profile, quickWizardEntry.carbs(), 0d, lastBG.valueToUnits(units), 0d, true, true, false, false);
text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U";
quickWizardButton.setText(text);
if (wizard.calculatedTotalInsulin <= 0)
quickWizardButton.setVisibility(View.GONE);
} else
quickWizardButton.setVisibility(View.GONE);
// Bolus and calc button
if (pump.isInitialized() && !pump.isSuspended()) {
wizardButton.setVisibility(View.VISIBLE);
treatmentButton.setVisibility(View.VISIBLE);
} else {
wizardButton.setVisibility(View.GONE);
treatmentButton.setVisibility(View.GONE);
}
Double lowLine = SP.getDouble("low_mark", 0d);
Double highLine = SP.getDouble("high_mark", 0d);
if (lowLine < 1) {
lowLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units);
}
if (highLine < 1) {
highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units);
}
// **** BG value ****
if (lastBG != null) {
int color = MainApp.sResources.getColor(R.color.inrange);
if (lastBG.valueToUnits(units) < lowLine)
color = MainApp.sResources.getColor(R.color.low);
else if (lastBG.valueToUnits(units) > highLine)
color = MainApp.sResources.getColor(R.color.high);
bgView.setText(lastBG.valueToUnitsToString(units));
arrowView.setText(lastBG.directionToSymbol());
bgView.setTextColor(color);
arrowView.setTextColor(color);
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
if (glucoseStatus != null) {
deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units);
if (avgdeltaView != null)
avgdeltaView.setText("øΔ15m: " + Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) +
" øΔ40m: " + Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units));
} else {
deltaView.setText("Δ " + MainApp.sResources.getString(R.string.notavailable));
if (avgdeltaView != null)
avgdeltaView.setText("");
}
} else {
return;
}
Integer flag = bgView.getPaintFlags();
if (actualBG == null) {
flag |= Paint.STRIKE_THRU_TEXT_FLAG;
} else
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
bgView.setPaintFlags(flag);
Long agoMsec = System.currentTimeMillis() - lastBG.date;
int agoMin = (int) (agoMsec / 60d / 1000d);
timeAgoView.setText(String.format(MainApp.sResources.getString(R.string.minago), agoMin));
// iob
MainApp.getConfigBuilder().updateTotalIOBTreatments();
MainApp.getConfigBuilder().updateTotalIOBTempBasals();
final IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments().round();
final IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round();
if (shorttextmode) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U";
iobView.setText(iobtext);
iobView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n"
+ getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n"
+ getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n";
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.iob), iobtext, null);
}
});
} else if (MainApp.sResources.getBoolean(R.bool.isTablet)) {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
+ getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U "
+ getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)";
iobView.setText(iobtext);
} else {
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
+ DecimalFormatter.to2Decimal(bolusIob.iob) + "/"
+ DecimalFormatter.to2Decimal(basalIob.basaliob) + ")";
iobView.setText(iobtext);
}
// cob
if (cobView != null) { // view must not exists
String cobText = "";
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(System.currentTimeMillis());
if (autosensData != null)
cobText = (int) autosensData.cob + " g";
cobView.setText(cobText);
}
boolean showPrediction = showPredictionView.isChecked() && finalLastRun != null && finalLastRun.constraintsProcessed.getClass().equals(DetermineBasalResultAMA.class);
if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS)) {
showPredictionView.setVisibility(View.VISIBLE);
getActivity().findViewById(R.id.overview_showprediction_label).setVisibility(View.VISIBLE);
} else {
showPredictionView.setVisibility(View.GONE);
getActivity().findViewById(R.id.overview_showprediction_label).setVisibility(View.GONE);
}
// pump status from ns
if (pumpDeviceStatusView != null) {
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
pumpDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus(), null);
}
});
}
// OpenAPS status from ns
if (openapsDeviceStatusView != null) {
openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus());
openapsDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus(), null);
}
});
}
// Uploader status from ns
if (uploaderDeviceStatusView != null) {
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatus());
uploaderDeviceStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null);
}
});
}
// ****** GRAPH *******
//log.debug("updateGUI checkpoint 1");
// allign to hours
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR, 1);
int hoursToFetch;
long toTime;
long fromTime;
long endTime;
if (showPrediction) {
int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
predHours = Math.min(2, predHours);
predHours = Math.max(0, predHours);
hoursToFetch = rangeToDisplay - predHours;
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
endTime = toTime + predHours * 60 * 60 * 1000L;
} else {
hoursToFetch = rangeToDisplay;
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
endTime = toTime;
}
LineGraphSeries<DataPoint> basalsLineSeries = null;
LineGraphSeries<DataPoint> absoluteBasalsLineSeries = null;
LineGraphSeries<DataPoint> baseBasalsSeries = null;
LineGraphSeries<DataPoint> tempBasalsSeries = null;
AreaGraphSeries<DoubleDataPoint> areaSeries;
LineGraphSeries<DataPoint> seriesNow, seriesNow2;
// **** TEMP BASALS graph ****
Double maxBasalValueFound = 0d;
long now = System.currentTimeMillis();
if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) {
List<DataPoint> baseBasalArray = new ArrayList<>();
List<DataPoint> tempBasalArray = new ArrayList<>();
List<DataPoint> basalLineArray = new ArrayList<>();
List<DataPoint> absoluteBasalLineArray = new ArrayList<>();
double lastLineBasal = 0;
double lastAbsoluteLineBasal = 0;
double lastBaseBasal = 0;
double lastTempBasal = 0;
for (long time = fromTime; time < now; time += 60 * 1000L) {
BasalData basalData = IobCobCalculatorPlugin.getBasalData(time);
double baseBasalValue = basalData.basal;
double absoluteLineValue = baseBasalValue;
double tempBasalValue = 0;
double basal = 0d;
if (basalData.isTempBasalRunning) {
absoluteLineValue = tempBasalValue = basalData.tempBasalAbsolute;
if (tempBasalValue != lastTempBasal) {
tempBasalArray.add(new DataPoint(time, lastTempBasal));
tempBasalArray.add(new DataPoint(time, basal = tempBasalValue));
}
if (lastBaseBasal != 0d) {
baseBasalArray.add(new DataPoint(time, lastBaseBasal));
baseBasalArray.add(new DataPoint(time, 0d));
lastBaseBasal = 0d;
}
} else {
if (baseBasalValue != lastBaseBasal) {
baseBasalArray.add(new DataPoint(time, lastBaseBasal));
baseBasalArray.add(new DataPoint(time, basal = baseBasalValue));
lastBaseBasal = baseBasalValue;
}
if (lastTempBasal != 0) {
tempBasalArray.add(new DataPoint(time, lastTempBasal));
tempBasalArray.add(new DataPoint(time, 0d));
}
}
if (baseBasalValue != lastLineBasal) {
basalLineArray.add(new DataPoint(time, lastLineBasal));
basalLineArray.add(new DataPoint(time, baseBasalValue));
}
if (absoluteLineValue != lastAbsoluteLineBasal) {
absoluteBasalLineArray.add(new DataPoint(time, lastAbsoluteLineBasal));
absoluteBasalLineArray.add(new DataPoint(time, basal));
}
lastAbsoluteLineBasal = absoluteLineValue;
lastLineBasal = baseBasalValue;
lastTempBasal = tempBasalValue;
maxBasalValueFound = Math.max(maxBasalValueFound, basal);
}
basalLineArray.add(new DataPoint(now, lastLineBasal));
baseBasalArray.add(new DataPoint(now, lastBaseBasal));
tempBasalArray.add(new DataPoint(now, lastTempBasal));
absoluteBasalLineArray.add(new DataPoint(now, lastAbsoluteLineBasal));
DataPoint[] baseBasal = new DataPoint[baseBasalArray.size()];
baseBasal = baseBasalArray.toArray(baseBasal);
baseBasalsSeries = new LineGraphSeries<>(baseBasal);
baseBasalsSeries.setDrawBackground(true);
baseBasalsSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.basebasal));
baseBasalsSeries.setThickness(0);
DataPoint[] tempBasal = new DataPoint[tempBasalArray.size()];
tempBasal = tempBasalArray.toArray(tempBasal);
tempBasalsSeries = new LineGraphSeries<>(tempBasal);
tempBasalsSeries.setDrawBackground(true);
tempBasalsSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.tempbasal));
tempBasalsSeries.setThickness(0);
DataPoint[] basalLine = new DataPoint[basalLineArray.size()];
basalLine = basalLineArray.toArray(basalLine);
basalsLineSeries = new LineGraphSeries<>(basalLine);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setPathEffect(new DashPathEffect(new float[]{2, 4}, 0));
paint.setColor(MainApp.sResources.getColor(R.color.basal));
basalsLineSeries.setCustomPaint(paint);
DataPoint[] absoluteBasalLine = new DataPoint[absoluteBasalLineArray.size()];
absoluteBasalLine = absoluteBasalLineArray.toArray(absoluteBasalLine);
absoluteBasalsLineSeries = new LineGraphSeries<>(absoluteBasalLine);
Paint absolutePaint = new Paint();
absolutePaint.setStyle(Paint.Style.STROKE);
absolutePaint.setStrokeWidth(4);
absolutePaint.setColor(MainApp.sResources.getColor(R.color.basal));
absoluteBasalsLineSeries.setCustomPaint(absolutePaint);
}
//log.debug("updateGUI checkpoint 2");
// **** IOB COB DEV graph ****
class DeviationDataPoint extends DataPoint {
public int color;
public DeviationDataPoint(double x, double y, int color) {
super(x, y);
this.color = color;
}
}
FixedLineGraphSeries<DataPoint> iobSeries;
FixedLineGraphSeries<DataPoint> cobSeries;
BarGraphSeries<DeviationDataPoint> devSeries;
LineGraphSeries<DataPoint> ratioSeries;
Double maxIobValueFound = 0d;
Double maxCobValueFound = 0d;
Double maxDevValueFound = 0d;
Double maxRatioValueFound = 0d;
if (showIobView.isChecked() || showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) {
//Date start = new Date();
List<DataPoint> iobArray = new ArrayList<>();
List<DataPoint> cobArray = new ArrayList<>();
List<DeviationDataPoint> devArray = new ArrayList<>();
List<DataPoint> ratioArray = new ArrayList<>();
double lastIob = 0;
int lastCob = 0;
for (long time = fromTime; time <= now; time += 5 * 60 * 1000L) {
if (showIobView.isChecked()) {
double iob = IobCobCalculatorPlugin.calulateFromTreatmentsAndTemps(time).iob;
if (Math.abs(lastIob - iob) > 0.02) {
if (Math.abs(lastIob - iob) > 0.2)
iobArray.add(new DataPoint(time, lastIob));
iobArray.add(new DataPoint(time, iob));
maxIobValueFound = Math.max(maxIobValueFound, Math.abs(iob));
lastIob = iob;
}
}
if (showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) {
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
if (autosensData != null && showCobView.isChecked()) {
int cob = (int) autosensData.cob;
if (cob != lastCob) {
if (autosensData.carbsFromBolus > 0)
cobArray.add(new DataPoint(time, lastCob));
cobArray.add(new DataPoint(time, cob));
maxCobValueFound = Math.max(maxCobValueFound, cob);
lastCob = cob;
}
}
if (autosensData != null && showDeviationsView.isChecked()) {
int color = Color.BLACK; // "="
if (autosensData.pastSensitivity.equals("C")) color = Color.GRAY;
if (autosensData.pastSensitivity.equals("+")) color = Color.GREEN;
if (autosensData.pastSensitivity.equals("-")) color = Color.RED;
devArray.add(new DeviationDataPoint(time, autosensData.deviation, color));
maxDevValueFound = Math.max(maxDevValueFound, Math.abs(autosensData.deviation));
}
if (autosensData != null && showRatiosView.isChecked()) {
ratioArray.add(new DataPoint(time, autosensData.autosensRatio));
maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio));
}
}
}
//Profiler.log(log, "IOB processed", start);
DataPoint[] iobData = new DataPoint[iobArray.size()];
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.setThickness(3);
Double maxByScale = null;
int graphsToShow = 0;
if (showIobView.isChecked()) {
if (maxByScale == null) maxByScale = maxIobValueFound;
graphsToShow++;
}
if (showCobView.isChecked()) {
if (maxByScale == null) maxByScale = maxCobValueFound;
graphsToShow++;
}
if (showDeviationsView.isChecked()) {
if (maxByScale == null) maxByScale = maxDevValueFound;
graphsToShow++;
}
if (showRatiosView.isChecked()) {
if (maxByScale == null) maxByScale = maxRatioValueFound;
graphsToShow++;
}
if (graphsToShow > 1) {
if (!maxByScale.equals(maxCobValueFound)) {
List<DataPoint> cobArrayRescaled = new ArrayList<>();
for (int ci = 0; ci < cobArray.size(); ci++) {
cobArrayRescaled.add(new DataPoint(cobArray.get(ci).getX(), cobArray.get(ci).getY() * maxByScale / maxCobValueFound / 2));
}
cobArray = cobArrayRescaled;
}
if (!maxByScale.equals(maxDevValueFound)) {
List<DeviationDataPoint> devArrayRescaled = new ArrayList<>();
for (int ci = 0; ci < devArray.size(); ci++) {
devArrayRescaled.add(new DeviationDataPoint(devArray.get(ci).getX(), devArray.get(ci).getY() * maxByScale / maxDevValueFound, devArray.get(ci).color));
}
devArray = devArrayRescaled;
}
if (!maxByScale.equals(maxRatioValueFound)) {
List<DataPoint> ratioArrayRescaled = new ArrayList<>();
for (int ci = 0; ci < ratioArray.size(); ci++) {
ratioArrayRescaled.add(new DataPoint(ratioArray.get(ci).getX(), (ratioArray.get(ci).getY() - 1) * maxByScale / maxRatioValueFound));
}
ratioArray = ratioArrayRescaled;
}
}
// COB
DataPoint[] cobData = new DataPoint[cobArray.size()];
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.setThickness(3);
// DEVIATIONS
DeviationDataPoint[] devData = new DeviationDataPoint[devArray.size()];
devData = devArray.toArray(devData);
devSeries = new BarGraphSeries<>(devData);
devSeries.setValueDependentColor(new ValueDependentColor<DeviationDataPoint>() {
@Override
public int get(DeviationDataPoint data) {
return data.color;
}
});
// RATIOS
DataPoint[] ratioData = new DataPoint[ratioArray.size()];
ratioData = ratioArray.toArray(ratioData);
ratioSeries = new LineGraphSeries<>(ratioData);
ratioSeries.setColor(MainApp.sResources.getColor(R.color.ratio));
ratioSeries.setThickness(3);
iobGraph.getSeries().clear();
if (showIobView.isChecked() && iobData.length > 0) {
addSeriesWithoutInvalidate(iobSeries, iobGraph);
}
if (showCobView.isChecked() && cobData.length > 0) {
addSeriesWithoutInvalidate(cobSeries, iobGraph);
}
if (showDeviationsView.isChecked() && devData.length > 0) {
addSeriesWithoutInvalidate(devSeries, iobGraph);
}
if (showRatiosView.isChecked() && ratioData.length > 0) {
addSeriesWithoutInvalidate(ratioSeries, iobGraph);
}
iobGraph.setVisibility(View.VISIBLE);
} else {
iobGraph.setVisibility(View.GONE);
}
//log.debug("updateGUI checkpoint 3");
// remove old data from graph
bgGraph.getSecondScale().getSeries().clear();
bgGraph.getSeries().clear();
//log.debug("updateGUI checkpoint 4");
// **** Area ****
DoubleDataPoint[] areaDataPoints = new DoubleDataPoint[]{
new DoubleDataPoint(fromTime, lowLine, highLine),
new DoubleDataPoint(endTime, lowLine, highLine)
};
areaSeries = new AreaGraphSeries<>(areaDataPoints);
addSeriesWithoutInvalidate(areaSeries, bgGraph);
areaSeries.setColor(0);
areaSeries.setDrawBackground(true);
areaSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.inrangebackground));
// set manual x bounds to have nice steps
bgGraph.getViewport().setMaxX(endTime);
bgGraph.getViewport().setMinX(fromTime);
bgGraph.getViewport().setXAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
bgGraph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space
iobGraph.getViewport().setMaxX(endTime);
iobGraph.getViewport().setMinX(fromTime);
iobGraph.getViewport().setXAxisBoundsManual(true);
iobGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
iobGraph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space
//log.debug("updateGUI checkpoint 5");
// **** BG graph ****
List<BgReading> bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true);
List<DataPointWithLabelInterface> bgListArray = new ArrayList<>();
if (bgReadingsArray.size() == 0) {
return;
}
Iterator<BgReading> it = bgReadingsArray.iterator();
Double maxBgValue = 0d;
while (it.hasNext()) {
BgReading bg = it.next();
if (bg.value > maxBgValue) maxBgValue = bg.value;
bgListArray.add(bg);
}
if (showPrediction) {
DetermineBasalResultAMA amaResult = (DetermineBasalResultAMA) finalLastRun.constraintsProcessed;
List<BgReading> predArray = amaResult.getPredictions();
bgListArray.addAll(predArray);
}
maxBgValue = Profile.fromMgdlToUnits(maxBgValue, units);
maxBgValue = units.equals(Constants.MGDL) ? Round.roundTo(maxBgValue, 40d) + 80 : Round.roundTo(maxBgValue, 2d) + 4;
if (highLine > maxBgValue) maxBgValue = highLine;
Integer numOfVertLines = units.equals(Constants.MGDL) ? (int) (maxBgValue / 40 + 1) : (int) (maxBgValue / 2 + 1);
DataPointWithLabelInterface[] bg = new DataPointWithLabelInterface[bgListArray.size()];
bg = bgListArray.toArray(bg);
if (bg.length > 0) {
addSeriesWithoutInvalidate(new PointsWithLabelGraphSeries<>(bg), bgGraph);
}
//log.debug("updateGUI checkpoint 6");
// Treatments
List<DataPointWithLabelInterface> filteredTreatments = new ArrayList<>();
List<Treatment> treatments = MainApp.getConfigBuilder().getTreatmentsFromHistory();
for (int tx = 0; tx < treatments.size(); tx++) {
DataPointWithLabelInterface t = treatments.get(tx);
if (t.getX() < fromTime || t.getX() > endTime) continue;
t.setY(getNearestBg((long) t.getX(), bgReadingsArray));
filteredTreatments.add(t);
}
//log.debug("updateGUI checkpoint 7");
// ProfileSwitch
List<ProfileSwitch> profileSwitches = MainApp.getConfigBuilder().getProfileSwitchesFromHistory().getList();
for (int tx = 0; tx < profileSwitches.size(); tx++) {
DataPointWithLabelInterface t = profileSwitches.get(tx);
if (t.getX() < fromTime || t.getX() > endTime) continue;
filteredTreatments.add(t);
}
//log.debug("updateGUI checkpoint 8");
// Extended bolus
if (!pump.isFakingTempsByExtendedBoluses()) {
List<ExtendedBolus> extendedBoluses = MainApp.getConfigBuilder().getExtendedBolusesFromHistory().getList();
for (int tx = 0; tx < extendedBoluses.size(); tx++) {
DataPointWithLabelInterface t = extendedBoluses.get(tx);
if (t.getX() + t.getDuration() < fromTime || t.getX() > endTime) continue;
if (t.getDuration() == 0) continue;
t.setY(getNearestBg((long) t.getX(), bgReadingsArray));
filteredTreatments.add(t);
}
}
//log.debug("updateGUI checkpoint 9");
// Careportal
List<CareportalEvent> careportalEvents = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, true);
for (int tx = 0; tx < careportalEvents.size(); tx++) {
DataPointWithLabelInterface t = careportalEvents.get(tx);
if (t.getX() + t.getDuration() < fromTime || t.getX() > endTime) continue;
t.setY(getNearestBg((long) t.getX(), bgReadingsArray));
filteredTreatments.add(t);
}
DataPointWithLabelInterface[] treatmentsArray = new DataPointWithLabelInterface[filteredTreatments.size()];
treatmentsArray = filteredTreatments.toArray(treatmentsArray);
if (treatmentsArray.length > 0) {
addSeriesWithoutInvalidate(new PointsWithLabelGraphSeries<>(treatmentsArray), bgGraph);
}
//log.debug("updateGUI checkpoint 10");
// set manual y bounds to have nice steps
bgGraph.getViewport().setMaxY(maxBgValue);
bgGraph.getViewport().setMinY(0);
bgGraph.getViewport().setYAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines);
// set second scale
if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) {
bgGraph.getSecondScale().setMinY(0);
bgGraph.getSecondScale().setMaxY(maxBgValue / lowLine * maxBasalValueFound * 1.2d);
bgGraph.getSecondScale().addSeries(baseBasalsSeries);
bgGraph.getSecondScale().addSeries(tempBasalsSeries);
bgGraph.getSecondScale().addSeries(basalsLineSeries);
bgGraph.getSecondScale().addSeries(absoluteBasalsLineSeries);
}
bgGraph.getSecondScale().setLabelFormatter(new LabelFormatter() {
@Override
public String formatLabel(double value, boolean isValueX) {
return "";
}
@Override
public void setViewport(Viewport viewport) {
}
});
//log.debug("updateGUI checkpoint 11");
// **** NOW line ****
DataPoint[] nowPoints = new DataPoint[]{
new DataPoint(now, 0),
new DataPoint(now, maxBgValue)
};
addSeriesWithoutInvalidate(seriesNow = new LineGraphSeries<>(nowPoints), bgGraph);
seriesNow.setDrawDataPoints(false);
DataPoint[] nowPoints2 = new DataPoint[]{
new DataPoint(now, 0),
new DataPoint(now, maxIobValueFound)
};
addSeriesWithoutInvalidate(seriesNow2 = new LineGraphSeries<>(nowPoints2), iobGraph);
seriesNow2.setDrawDataPoints(false);
//seriesNow.setThickness(1);
// custom paint to make a dotted line
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));
paint.setColor(Color.WHITE);
seriesNow.setCustomPaint(paint);
seriesNow2.setCustomPaint(paint);
bgGraph.onDataChanged(false, false);
iobGraph.onDataChanged(false, false);
Profiler.log(log, from, updateGUIStart);
}
public double getNearestBg(long date, List<BgReading> bgReadingsArray) {
double bg = 0;
String units = MainApp.getConfigBuilder().getProfileUnits();
for (int r = bgReadingsArray.size() - 1; r >= 0; r--) {
BgReading reading = bgReadingsArray.get(r);
if (reading.date > date) continue;
bg = Profile.fromMgdlToUnits(reading.value, units);
break;
}
return bg;
}
void addSeriesWithoutInvalidate(Series s, GraphView graph) {
s.onGraphViewAttached(graph);
graph.getSeries().add(s);
}
//Notifications
static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.NotificationsViewHolder> {
List<Notification> notificationsList;
RecyclerViewAdapter(List<Notification> notificationsList) {
this.notificationsList = notificationsList;
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false);
return new NotificationsViewHolder(v);
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
Notification notification = notificationsList.get(position);
holder.dismiss.setTag(notification);
holder.text.setText(notification.text);
holder.time.setText(DateUtil.timeString(notification.date));
if (notification.level == Notification.URGENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
else if (notification.level == Notification.NORMAL)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationNormal));
else if (notification.level == Notification.LOW)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow));
else if (notification.level == Notification.INFO)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo));
else if (notification.level == Notification.ANNOUNCEMENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationAnnouncement));
}
@Override
public int getItemCount() {
return notificationsList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView time;
TextView text;
Button dismiss;
NotificationsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.notification_cardview);
time = (TextView) itemView.findViewById(R.id.notification_time);
text = (TextView) itemView.findViewById(R.id.notification_text);
dismiss = (Button) itemView.findViewById(R.id.notification_dismiss);
dismiss.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Notification notification = (Notification) v.getTag();
switch (v.getId()) {
case R.id.notification_dismiss:
MainApp.bus().post(new EventDismissNotification(notification.id));
if (notification.nsAlarm != null) {
BroadcastAckAlarm.handleClearAlarm(notification.nsAlarm, MainApp.instance().getApplicationContext(), 60 * 60 * 1000L);
}
break;
}
}
}
}
void updateNotifications() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
NotificationStore nstore = getPlugin().notificationStore;
nstore.removeExpired();
if (nstore.store.size() > 0) {
RecyclerViewAdapter adapter = new RecyclerViewAdapter(nstore.store);
notificationsView.setAdapter(adapter);
notificationsView.setVisibility(View.VISIBLE);
} else {
notificationsView.setVisibility(View.GONE);
}
}
});
}
}