Merge remote-tracking branch 'origin/dev' into combo-scripter-v2

* origin/dev:
  Careportal DB browser
  fix rendering treatments with duration
  more autosens logging
  cancel extending bolus on pump disconnection
  set maxiob=0 only for objective 4
  fix stopping bolus connection error
This commit is contained in:
Johannes Mockenhaupt 2018-01-23 02:04:02 +01:00
commit b7f8913cae
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
17 changed files with 435 additions and 24 deletions

View file

@ -239,6 +239,7 @@ public class Profile {
// if pump not available (at start)
// do not store converted array
basal_v = null;
isValidated = false;
}
}

View file

@ -191,6 +191,17 @@ public class CareportalEvent implements DataPointWithLabelInterface {
return Translator.translate(eventType);
}
public String getNotes() {
try {
JSONObject object = new JSONObject(json);
if (object.has("notes"))
return object.getString("notes");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return "";
}
@Override
public long getDuration() {
try {

View file

@ -1508,7 +1508,21 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<CareportalEvent>();
return new ArrayList<>();
}
public List<CareportalEvent> getCareportalEventsFromTime(boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
return careportalEvents;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public void deleteCareportalEventById(String _id) {

View file

@ -197,6 +197,7 @@ public class ObjectivesFragment extends Fragment {
ObjectivesPlugin.objectives.get(4).objective = MainApp.sResources.getString(R.string.objectives_4_objective);
ObjectivesPlugin.objectives.get(5).objective = MainApp.sResources.getString(R.string.objectives_5_objective);
ObjectivesPlugin.objectives.get(6).objective = MainApp.sResources.getString(R.string.objectives_6_objective);
ObjectivesPlugin.objectives.get(7).objective = MainApp.sResources.getString(R.string.objectives_7_objective);
ObjectivesPlugin.objectives.get(0).gate = MainApp.sResources.getString(R.string.objectives_0_gate);
ObjectivesPlugin.objectives.get(1).gate = MainApp.sResources.getString(R.string.objectives_1_gate);
ObjectivesPlugin.objectives.get(2).gate = MainApp.sResources.getString(R.string.objectives_2_gate);

View file

@ -320,12 +320,12 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
@Override
public Double applyMaxIOBConstraints(Double maxIob) {
if (objectives.get(4).started.getTime() > 0 || objectives.get(2).accomplished.getTime() == 0)
return maxIob;
else {
if (objectives.get(3).started.getTime() > 0 && objectives.get(3).accomplished.getTime() == 0) {
if (Config.logConstraintsChanges)
log.debug("Limiting maxIOB " + maxIob + " to " + 0 + "U");
return 0d;
} else {
return maxIob;
}
}

View file

@ -33,6 +33,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
import info.nightscout.utils.DateUtil;
/**
* Created by mike on 24.04.2017.
@ -580,11 +581,11 @@ public class IobCobCalculatorPlugin implements PluginBase {
return null;
}
if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
log.debug("AUTOSENSDATA null: data is old (" + reason + ")");
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
return null;
} else {
if (data == null)
log.debug("AUTOSENSDATA null: data == null (" + " " + reason + ")");
log.debug("AUTOSENSDATA null: data == null (" + " " + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
return data;
}
}

View file

@ -498,6 +498,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
});
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
}
}
});
}
NSUpload.uploadOpenAPSOffline(30);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
@ -511,6 +521,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
});
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
}
}
});
}
NSUpload.uploadOpenAPSOffline(60);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
@ -524,6 +544,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
});
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
}
}
});
}
NSUpload.uploadOpenAPSOffline(120);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
@ -537,6 +567,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
});
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
}
}
});
}
NSUpload.uploadOpenAPSOffline(180);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {

View file

@ -253,7 +253,7 @@ public class GraphData {
}
// Careportal
List<CareportalEvent> careportalEvents = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, true);
List<CareportalEvent> careportalEvents = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true);
for (int tx = 0; tx < careportalEvents.size(); tx++) {
DataPointWithLabelInterface t = careportalEvents.get(tx);

View file

@ -141,9 +141,6 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
Iterator<E> values = getValues(minX, maxX);
// draw background
double lastEndY = 0;
double lastEndX = 0;
// draw data
double diffY = maxY - minY;
@ -154,9 +151,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
float graphLeft = graphView.getGraphContentLeft();
float graphTop = graphView.getGraphContentTop();
lastEndY = 0;
lastEndX = 0;
float firstX = 0;
float scaleX = (float) (graphWidth / diffX);
int i=0;
while (values.hasNext()) {
E value = values.next();
@ -171,9 +167,6 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
double ratX = valX / diffX;
double x = graphWidth * ratX;
double orgX = x;
double orgY = y;
// overdraw
boolean overdraw = false;
if (x > graphWidth) { // end right
@ -185,6 +178,14 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
if (y > graphHeight) { // end top
overdraw = true;
}
long duration = value.getDuration();
float endWithDuration = (float) (x + duration * scaleX + graphLeft + 1);
// cut off to graph start if needed
if (x < 0 && endWithDuration > 0) {
x = 0;
}
/* Fix a bug that continue to show the DOT after Y axis */
if(x < 0) {
overdraw = true;
@ -195,8 +196,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
registerDataPoint(endX, endY, value);
float xpluslength = 0;
if (value.getDuration() > 0) {
xpluslength = endX + Math.min((float) (value.getDuration() * graphWidth / diffX), graphLeft + graphWidth);
if (duration > 0) {
xpluslength = Math.min(endWithDuration, graphLeft + graphWidth);
}
// draw data point

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsBolusFragment;
import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsCareportalFragment;
import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsExtendedBolusesFragment;
import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsProfileSwitchFragment;
import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsTempTargetFragment;
@ -33,6 +34,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli
TextView tempBasalsTab;
TextView tempTargetTab;
TextView profileSwitchTab;
TextView careportalTab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -45,11 +47,13 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli
tempBasalsTab = (TextView) view.findViewById(R.id.treatments_tempbasals);
tempTargetTab = (TextView) view.findViewById(R.id.treatments_temptargets);
profileSwitchTab = (TextView) view.findViewById(R.id.treatments_profileswitches);
careportalTab = (TextView) view.findViewById(R.id.treatments_careportal);
treatmentsTab.setOnClickListener(this);
extendedBolusesTab.setOnClickListener(this);
tempBasalsTab.setOnClickListener(this);
tempTargetTab.setOnClickListener(this);
profileSwitchTab.setOnClickListener(this);
careportalTab.setOnClickListener(this);
setFragment(new TreatmentsBolusFragment());
setBackgroundColorOnSelected(treatmentsTab);
@ -87,6 +91,10 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli
setFragment(new TreatmentsProfileSwitchFragment());
setBackgroundColorOnSelected(profileSwitchTab);
break;
case R.id.treatments_careportal:
setFragment(new TreatmentsCareportalFragment());
setBackgroundColorOnSelected(careportalTab);
break;
}
}
@ -104,6 +112,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli
tempBasalsTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground));
tempTargetTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground));
profileSwitchTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground));
careportalTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground));
selected.setBackgroundColor(MainApp.sResources.getColor(R.color.tabBgColorSelected));
}

View file

@ -0,0 +1,192 @@
package info.nightscout.androidaps.plugins.Treatments.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle;
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.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
import info.nightscout.utils.Translator;
/**
* Created by mike on 13/01/17.
*/
public class TreatmentsCareportalFragment extends SubscriberFragment implements View.OnClickListener {
RecyclerView recyclerView;
LinearLayoutManager llm;
Button refreshFromNS;
Context context;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.CareportalEventsViewHolder> {
List<CareportalEvent> careportalEventList;
RecyclerViewAdapter(List<CareportalEvent> careportalEventList) {
this.careportalEventList = careportalEventList;
}
@Override
public CareportalEventsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.treatments_careportal_item, viewGroup, false);
CareportalEventsViewHolder CareportalEventsViewHolder = new CareportalEventsViewHolder(v);
return CareportalEventsViewHolder;
}
@Override
public void onBindViewHolder(CareportalEventsViewHolder holder, int position) {
CareportalEvent careportalEvent = careportalEventList.get(position);
holder.ns.setVisibility(NSUpload.isIdValid(careportalEvent._id) ? View.VISIBLE : View.GONE);
holder.date.setText(DateUtil.dateAndTimeString(careportalEvent.date));
holder.note.setText(careportalEvent.getNotes());
holder.type.setText(Translator.translate(careportalEvent.eventType));
holder.remove.setTag(careportalEvent);
}
@Override
public int getItemCount() {
return careportalEventList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public class CareportalEventsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView date;
TextView type;
TextView note;
TextView remove;
TextView ns;
CareportalEventsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.careportal_cardview);
date = (TextView) itemView.findViewById(R.id.careportal_date);
type = (TextView) itemView.findViewById(R.id.careportal_type);
note = (TextView) itemView.findViewById(R.id.careportal_note);
ns = (TextView) itemView.findViewById(R.id.ns_sign);
remove = (TextView) itemView.findViewById(R.id.careportal_remove);
remove.setOnClickListener(this);
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
}
@Override
public void onClick(View v) {
final CareportalEvent careportalEvent = (CareportalEvent) v.getTag();
switch (v.getId()) {
case R.id.careportal_remove:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
builder.setMessage(MainApp.sResources.getString(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(careportalEvent.date));
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final String _id = careportalEvent._id;
if (NSUpload.isIdValid(_id)) {
NSUpload.removeCareportalEntryFromNS(_id);
} else {
UploadQueue.removeID("dbAdd", _id);
}
MainApp.getDbHelper().delete(careportalEvent);
}
});
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
builder.show();
break;
}
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.treatments_careportal_fragment, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.careportal_recyclerview);
recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false));
recyclerView.setAdapter(adapter);
refreshFromNS = (Button) view.findViewById(R.id.careportal_refreshfromnightscout);
refreshFromNS.setOnClickListener(this);
context = getContext();
boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false);
if (nsUploadOnly)
refreshFromNS.setVisibility(View.GONE);
updateGUI();
return view;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.careportal_refreshfromnightscout:
AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext());
builder.setTitle(this.getContext().getString(R.string.confirmation));
builder.setMessage(this.getContext().getString(R.string.refresheventsfromnightscout) + " ?");
builder.setPositiveButton(this.getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainApp.getDbHelper().resetCareportalEvents();
Intent restartNSClient = new Intent(Intents.ACTION_RESTART);
MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient);
}
});
builder.setNegativeButton(this.getContext().getString(R.string.cancel), null);
builder.show();
break;
}
}
@Subscribe
public void onStatusEvent(final EventCareportalEventChange ev) {
updateGUI();
}
@Override
protected void updateGUI() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false)), false);
}
});
}
}

View file

@ -147,8 +147,6 @@ public class CommandQueue {
public static void independentConnect(String reason, Callback callback) {
CommandQueue tempCommandQueue = new CommandQueue();
tempCommandQueue.readStatus(reason, callback);
QueueThread tempThread = new QueueThread(tempCommandQueue);
tempThread.start();
}
// returns true if command is queued

View file

@ -34,7 +34,7 @@ public class QueueThread extends Thread {
private PowerManager.WakeLock mWakeLock;
public QueueThread(CommandQueue queue) {
super(QueueThread.class.toString());
super();
this.queue = queue;
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);

View file

@ -0,0 +1,28 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsCareportalFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/careportal_refreshfromnightscout"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/refresheventsfromnightscout" />
<android.support.v7.widget.RecyclerView
android:id="@+id/careportal_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</FrameLayout>

View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/careportal_cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
card_view:cardBackgroundColor="?android:colorBackground">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="true"
android:orientation="horizontal">
<com.joanzapata.iconify.widget.IconTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical|right"
android:paddingLeft="10dp"
android:paddingRight="5dp"
android:text="{fa-clock-o}" />
<TextView
android:id="@+id/careportal_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:text="1.1.2000 18:00"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/careportal_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:paddingRight="10dp"
android:text=""
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:text="" />
<TextView
android:id="@+id/ns_sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="NS"
android:textColor="@color/colorSetTempButton" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/careportal_note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="Activity" />
<TextView
android:id="@+id/careportal_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/overview_quickwizard_item_remove_button"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
</LinearLayout>
</android.support.v7.widget.CardView>

View file

@ -71,6 +71,16 @@
android:paddingRight="5dp"
android:text="@string/profileswitch" />
<TextView
android:id="@+id/treatments_careportal"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center_vertical|center_horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="@string/careportal" />
</com.google.android.flexbox.FlexboxLayout>
<FrameLayout

View file

@ -862,5 +862,6 @@
<string name="combo_error_bolus_verification_failed">Delivering the bolus and verifying the pump\'s history failed, please check the pump and manually create a bolus record using the Careportal tab if a bolus was delivered.</string>
<string name="combo_error_bolus_recovery_progress">Recovering from connection loss</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Not enough insulin for bolus left in reservoir</string>
<string name="extendedbolusdeliveryerror">Extended bolus delivery error</string>
</resources>