TDDStatsActivity ->kt

This commit is contained in:
Milos Kozak 2021-02-13 22:14:06 +01:00
parent 7d80176c75
commit 0ce35c6439
3 changed files with 509 additions and 613 deletions

View file

@ -1,528 +0,0 @@
package info.nightscout.androidaps.activities;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.events.EventDanaRSyncStatus;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class TDDStatsActivity extends NoSplashAppCompatActivity {
@Inject AAPSLogger aapsLogger;
@Inject ResourceHelper resourceHelper;
@Inject RxBusWrapper rxBus;
@Inject SP sp;
@Inject ProfileFunction profileFunction;
@Inject ActivePluginProvider activePlugin;
@Inject CommandQueueProvider commandQueue;
@Inject DatabaseHelperInterface databaseHelper;
@Inject FabricPrivacy fabricPrivacy;
@Inject AapsSchedulers aapsSchedulers;
private final CompositeDisposable disposable = new CompositeDisposable();
TextView statusView, statsMessage, totalBaseBasal2;
EditText totalBaseBasal;
Button reloadButton;
LinearLayoutManager llm;
TableLayout tl, ctl, etl;
String TBB;
double magicNumber;
DecimalFormat decimalFormat;
List<TDD> historyList = new ArrayList<>();
List<TDD> dummies;
public TDDStatsActivity() {
super();
}
@Override
protected void onResume() {
super.onResume();
disposable.add(rxBus
.toObservable(EventPumpStatusChanged.class)
.observeOn(aapsSchedulers.getMain())
.subscribe(event -> statusView.setText(event.getStatus(resourceHelper)), exception -> fabricPrivacy.logException(exception))
);
disposable.add(rxBus
.toObservable(EventDanaRSyncStatus.class)
.observeOn(aapsSchedulers.getMain())
.subscribe(event -> {
aapsLogger.debug("EventDanaRSyncStatus: " + event.getMessage());
statusView.setText(event.getMessage());
}, exception -> fabricPrivacy.logException(exception))
);
}
@Override
protected void onPause() {
super.onPause();
disposable.clear();
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View myView = getCurrentFocus();
if (myView instanceof EditText) {
Rect rect = new Rect();
myView.getGlobalVisibleRect(rect);
if (!rect.contains((int) event.getRawX(), (int) event.getRawY())) {
myView.clearFocus();
}
}
}
return super.dispatchTouchEvent(event);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.danar_statsactivity);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
statusView = findViewById(R.id.danar_stats_connection_status);
reloadButton = findViewById(R.id.danar_statsreload);
totalBaseBasal = findViewById(R.id.danar_stats_editTotalBaseBasal);
totalBaseBasal2 = findViewById(R.id.danar_stats_editTotalBaseBasal2);
statsMessage = findViewById(R.id.danar_stats_Message);
statusView.setVisibility(View.GONE);
statsMessage.setVisibility(View.GONE);
totalBaseBasal2.setEnabled(false);
totalBaseBasal2.setClickable(false);
totalBaseBasal2.setFocusable(false);
totalBaseBasal2.setInputType(0);
decimalFormat = new DecimalFormat("0.000");
llm = new LinearLayoutManager(this);
TBB = sp.getString("TBB", "10.00");
Profile profile = profileFunction.getProfile();
if (profile != null) {
double cppTBB = profile.baseBasalSum();
TBB = decimalFormat.format(cppTBB);
sp.putString("TBB", TBB);
}
totalBaseBasal.setText(TBB);
if (!activePlugin.getActivePump().getPumpDescription().needsManualTDDLoad)
reloadButton.setVisibility(View.GONE);
// stats table
tl = findViewById(R.id.main_table);
TableRow tr_head = new TableRow(this);
tr_head.setBackgroundColor(Color.DKGRAY);
tr_head.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
TextView label_date = new TextView(this);
label_date.setText(resourceHelper.gs(R.string.date));
label_date.setTextColor(Color.WHITE);
tr_head.addView(label_date);
TextView label_basalrate = new TextView(this);
label_basalrate.setText(resourceHelper.gs(R.string.basalrate));
label_basalrate.setTextColor(Color.WHITE);
tr_head.addView(label_basalrate);
TextView label_bolus = new TextView(this);
label_bolus.setText(resourceHelper.gs(R.string.bolus));
label_bolus.setTextColor(Color.WHITE);
tr_head.addView(label_bolus);
TextView label_tdd = new TextView(this);
label_tdd.setText(resourceHelper.gs(R.string.tdd));
label_tdd.setTextColor(Color.WHITE);
tr_head.addView(label_tdd);
TextView label_ratio = new TextView(this);
label_ratio.setText(resourceHelper.gs(R.string.ratio));
label_ratio.setTextColor(Color.WHITE);
tr_head.addView(label_ratio);
// add stats headers to tables
tl.addView(tr_head, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
// cumulative table
ctl = findViewById(R.id.cumulative_table);
TableRow ctr_head = new TableRow(this);
ctr_head.setBackgroundColor(Color.DKGRAY);
ctr_head.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
TextView label_cum_amount_days = new TextView(this);
label_cum_amount_days.setText(resourceHelper.gs(R.string.amount_days));
label_cum_amount_days.setTextColor(Color.WHITE);
ctr_head.addView(label_cum_amount_days);
TextView label_cum_tdd = new TextView(this);
label_cum_tdd.setText(resourceHelper.gs(R.string.tdd));
label_cum_tdd.setTextColor(Color.WHITE);
ctr_head.addView(label_cum_tdd);
TextView label_cum_ratio = new TextView(this);
label_cum_ratio.setText(resourceHelper.gs(R.string.ratio));
label_cum_ratio.setTextColor(Color.WHITE);
ctr_head.addView(label_cum_ratio);
// add cummulative headers to tables
ctl.addView(ctr_head, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
// expontial table
etl = findViewById(R.id.expweight_table);
TableRow etr_head = new TableRow(this);
etr_head.setBackgroundColor(Color.DKGRAY);
etr_head.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
TextView label_exp_weight = new TextView(this);
label_exp_weight.setText(resourceHelper.gs(R.string.weight));
label_exp_weight.setTextColor(Color.WHITE);
etr_head.addView(label_exp_weight);
TextView label_exp_tdd = new TextView(this);
label_exp_tdd.setText(resourceHelper.gs(R.string.tdd));
label_exp_tdd.setTextColor(Color.WHITE);
etr_head.addView(label_exp_tdd);
TextView label_exp_ratio = new TextView(this);
label_exp_ratio.setText(resourceHelper.gs(R.string.ratio));
label_exp_ratio.setTextColor(Color.WHITE);
etr_head.addView(label_exp_ratio);
// add expontial headers to tables
etl.addView(etr_head, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
reloadButton.setOnClickListener(v -> {
runOnUiThread(() -> {
reloadButton.setVisibility(View.GONE);
statusView.setVisibility(View.VISIBLE);
statsMessage.setVisibility(View.VISIBLE);
statsMessage.setText(resourceHelper.gs(R.string.warning_Message));
});
commandQueue.loadTDDs(new Callback() {
@Override
public void run() {
loadDataFromDB();
runOnUiThread(() -> {
reloadButton.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE);
statsMessage.setVisibility(View.GONE);
});
}
});
});
totalBaseBasal.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
totalBaseBasal.clearFocus();
return true;
}
return false;
});
totalBaseBasal.setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
totalBaseBasal.getText().clear();
} else {
sp.putString("TBB", totalBaseBasal.getText().toString());
TBB = sp.getString("TBB", "");
loadDataFromDB();
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(totalBaseBasal.getWindowToken(), 0);
}
});
loadDataFromDB();
}
private void loadDataFromDB() {
historyList = databaseHelper.getTDDs();
//only use newest 10
historyList = historyList.subList(0, Math.min(10, historyList.size()));
//fill single gaps
dummies = new LinkedList<>();
DateFormat df = new SimpleDateFormat("dd.MM.", Locale.getDefault());
for (int i = 0; i < historyList.size() - 1; i++) {
TDD elem1 = historyList.get(i);
TDD elem2 = historyList.get(i + 1);
if (!df.format(new Date(elem1.date)).equals(df.format(new Date(elem2.date + 25 * 60 * 60 * 1000)))) {
TDD dummy = new TDD();
dummy.date = elem1.date - 24 * 60 * 60 * 1000;
dummy.basal = elem1.basal / 2;
dummy.bolus = elem1.bolus / 2;
dummies.add(dummy);
elem1.basal /= 2;
elem1.bolus /= 2;
}
}
historyList.addAll(dummies);
Collections.sort(historyList, (lhs, rhs) -> (int) (rhs.date - lhs.date));
runOnUiThread(() -> {
cleanTable(tl);
cleanTable(ctl);
cleanTable(etl);
DateFormat df1 = new SimpleDateFormat("dd.MM.", Locale.getDefault());
if (TextUtils.isEmpty(TBB)) {
totalBaseBasal.setError("Please Enter Total Base Basal");
return;
} else {
magicNumber = SafeParse.stringToDouble(TBB);
}
magicNumber *= 2;
totalBaseBasal2.setText(decimalFormat.format(magicNumber));
int i = 0;
double sum = 0d;
double weighted03 = 0d;
double weighted05 = 0d;
double weighted07 = 0d;
//TDD table
for (TDD record : historyList) {
double tdd = record.getTotal();
// Create the table row
TableRow tr = new TableRow(TDDStatsActivity.this);
if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY);
if (dummies.contains(record)) {
tr.setBackgroundColor(Color.argb(125, 255, 0, 0));
}
tr.setId(100 + i);
tr.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
// Here create the TextView dynamically
TextView labelDATE = new TextView(TDDStatsActivity.this);
labelDATE.setId(200 + i);
labelDATE.setText(df1.format(new Date(record.date)));
labelDATE.setTextColor(Color.WHITE);
tr.addView(labelDATE);
TextView labelBASAL = new TextView(TDDStatsActivity.this);
labelBASAL.setId(300 + i);
labelBASAL.setText(resourceHelper.gs(R.string.formatinsulinunits, record.basal));
labelBASAL.setTextColor(Color.WHITE);
tr.addView(labelBASAL);
TextView labelBOLUS = new TextView(TDDStatsActivity.this);
labelBOLUS.setId(400 + i);
labelBOLUS.setText(resourceHelper.gs(R.string.formatinsulinunits, record.bolus));
labelBOLUS.setTextColor(Color.WHITE);
tr.addView(labelBOLUS);
TextView labelTDD = new TextView(TDDStatsActivity.this);
labelTDD.setId(500 + i);
labelTDD.setText(resourceHelper.gs(R.string.formatinsulinunits, tdd));
labelTDD.setTextColor(Color.WHITE);
tr.addView(labelTDD);
TextView labelRATIO = new TextView(TDDStatsActivity.this);
labelRATIO.setId(600 + i);
labelRATIO.setText(Math.round(100 * tdd / magicNumber) + "%");
labelRATIO.setTextColor(Color.WHITE);
tr.addView(labelRATIO);
// add stats rows to tables
tl.addView(tr, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
i++;
}
i = 0;
//cumulative TDDs
for (TDD record : historyList) {
if (!historyList.isEmpty() && df1.format(new Date(record.date)).equals(df1.format(new Date()))) {
//Today should not be included
continue;
}
i++;
sum = sum + record.getTotal();
// Create the cumtable row
TableRow ctr = new TableRow(TDDStatsActivity.this);
if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY);
ctr.setId(700 + i);
ctr.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
// Here create the TextView dynamically
TextView labelDAYS = new TextView(TDDStatsActivity.this);
labelDAYS.setId(800 + i);
labelDAYS.setText("" + i);
labelDAYS.setTextColor(Color.WHITE);
ctr.addView(labelDAYS);
TextView labelCUMTDD = new TextView(TDDStatsActivity.this);
labelCUMTDD.setId(900 + i);
labelCUMTDD.setText(resourceHelper.gs(R.string.formatinsulinunits, sum / i));
labelCUMTDD.setTextColor(Color.WHITE);
ctr.addView(labelCUMTDD);
TextView labelCUMRATIO = new TextView(TDDStatsActivity.this);
labelCUMRATIO.setId(1000 + i);
labelCUMRATIO.setText(Math.round(100 * sum / i / magicNumber) + "%");
labelCUMRATIO.setTextColor(Color.WHITE);
ctr.addView(labelCUMRATIO);
// add cummulative rows to tables
ctl.addView(ctr, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
}
if (isOldData(historyList) && activePlugin.getActivePump().getPumpDescription().needsManualTDDLoad) {
statsMessage.setVisibility(View.VISIBLE);
statsMessage.setText(resourceHelper.gs(R.string.olddata_Message));
} else {
tl.setBackgroundColor(Color.TRANSPARENT);
}
if (!historyList.isEmpty() && df1.format(new Date(historyList.get(0).date)).equals(df1.format(new Date()))) {
//Today should not be included
historyList.remove(0);
}
Collections.reverse(historyList);
i = 0;
for (TDD record : historyList) {
double tdd = record.getTotal();
if (i == 0) {
weighted03 = tdd;
weighted05 = tdd;
weighted07 = tdd;
} else {
weighted07 = (weighted07 * 0.3 + tdd * 0.7);
weighted05 = (weighted05 * 0.5 + tdd * 0.5);
weighted03 = (weighted03 * 0.7 + tdd * 0.3);
}
i++;
}
// Create the exptable row
TableRow etr = new TableRow(TDDStatsActivity.this);
if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY);
etr.setId(1100 + i);
etr.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
// Here create the TextView dynamically
TextView labelWEIGHT = new TextView(TDDStatsActivity.this);
labelWEIGHT.setId(1200 + i);
labelWEIGHT.setText("0.3\n" + "0.5\n" + "0.7");
labelWEIGHT.setTextColor(Color.WHITE);
etr.addView(labelWEIGHT);
TextView labelEXPTDD = new TextView(TDDStatsActivity.this);
labelEXPTDD.setId(1300 + i);
labelEXPTDD.setText(resourceHelper.gs(R.string.formatinsulinunits, weighted03) + "\n" +
resourceHelper.gs(R.string.formatinsulinunits, weighted05) + "\n" +
resourceHelper.gs(R.string.formatinsulinunits, weighted07));
labelEXPTDD.setTextColor(Color.WHITE);
etr.addView(labelEXPTDD);
TextView labelEXPRATIO = new TextView(TDDStatsActivity.this);
labelEXPRATIO.setId(1400 + i);
labelEXPRATIO.setText(Math.round(100 * weighted03 / magicNumber) + "%\n"
+ Math.round(100 * weighted05 / magicNumber) + "%\n"
+ Math.round(100 * weighted07 / magicNumber) + "%");
labelEXPRATIO.setTextColor(Color.WHITE);
etr.addView(labelEXPRATIO);
// add exponentail rows to tables
etl.addView(etr, new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
});
}
private void cleanTable(TableLayout table) {
int childCount = table.getChildCount();
// Remove all rows except the first one
if (childCount > 1) {
table.removeViews(1, childCount - 1);
}
}
public boolean isOldData(List<TDD> historyList) {
PumpType type = activePlugin.getActivePump().getPumpDescription().pumpType;
boolean startsYesterday = type == PumpType.DanaR || type == PumpType.DanaRS || type == PumpType.DanaRv2 || type == PumpType.DanaRKorean || type == PumpType.AccuChekInsight;
DateFormat df = new SimpleDateFormat("dd.MM.", Locale.getDefault());
return (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).date)).equals(df.format(new Date(System.currentTimeMillis() - (startsYesterday ? 1000 * 60 * 60 * 24 : 0))))));
}
}

View file

@ -0,0 +1,429 @@
package info.nightscout.androidaps.activities
import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.Rect
import android.os.Bundle
import android.text.TextUtils
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TableLayout
import android.widget.TableRow
import android.widget.TextView
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.core.databinding.ActivityTddStatsBinding
import info.nightscout.androidaps.db.TDD
import info.nightscout.androidaps.events.EventDanaRSyncStatus
import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.SafeParse
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import java.text.DateFormat
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
import kotlin.math.min
import kotlin.math.roundToInt
class TDDStatsActivity : NoSplashAppCompatActivity() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var aapsSchedulers: AapsSchedulers
private lateinit var binding: ActivityTddStatsBinding
private val disposable = CompositeDisposable()
lateinit var tbb: String
private var magicNumber = 0.0
private var decimalFormat: DecimalFormat = DecimalFormat("0.000")
private var historyList: MutableList<TDD> = mutableListOf()
private var dummies: MutableList<TDD> = mutableListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTddStatsBinding.inflate(layoutInflater)
setContentView(binding.root)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
binding.connectionStatus.visibility = View.GONE
binding.message.visibility = View.GONE
binding.totalBaseBasal2.isEnabled = false
binding.totalBaseBasal2.isClickable = false
binding.totalBaseBasal2.isFocusable = false
binding.totalBaseBasal2.inputType = 0
tbb = sp.getString("TBB", "10.00")
val profile = profileFunction.getProfile()
if (profile != null) {
val cppTBB = profile.baseBasalSum()
tbb = decimalFormat.format(cppTBB)
sp.putString("TBB", tbb)
}
binding.totalBaseBasal.setText(tbb)
if (!activePlugin.activePump.pumpDescription.needsManualTDDLoad) binding.reload.visibility = View.GONE
// stats table
// add stats headers to tables
binding.mainTable.addView(
TableRow(this).also { trHead ->
trHead.setBackgroundColor(Color.DKGRAY)
trHead.layoutParams = TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
trHead.addView(TextView(this).also { labelDate ->
labelDate.text = resourceHelper.gs(R.string.date)
labelDate.setTextColor(Color.WHITE)
})
trHead.addView(TextView(this).also { labelBasalRate ->
labelBasalRate.text = resourceHelper.gs(R.string.basalrate)
labelBasalRate.setTextColor(Color.WHITE)
})
trHead.addView(TextView(this).also { labelBolus ->
labelBolus.text = resourceHelper.gs(R.string.bolus)
labelBolus.setTextColor(Color.WHITE)
})
trHead.addView(TextView(this).also { labelTdd ->
labelTdd.text = resourceHelper.gs(R.string.tdd)
labelTdd.setTextColor(Color.WHITE)
})
trHead.addView(TextView(this).also { labelRatio ->
labelRatio.text = resourceHelper.gs(R.string.ratio)
labelRatio.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
)
// cumulative table
binding.cumulativeTable.addView(
TableRow(this).also { ctrHead ->
ctrHead.setBackgroundColor(Color.DKGRAY)
ctrHead.layoutParams = TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
ctrHead.addView(TextView(this).also { labelCumAmountDays ->
labelCumAmountDays.text = resourceHelper.gs(R.string.amount_days)
labelCumAmountDays.setTextColor(Color.WHITE)
})
ctrHead.addView(TextView(this).also { labelCumTdd ->
labelCumTdd.text = resourceHelper.gs(R.string.tdd)
labelCumTdd.setTextColor(Color.WHITE)
})
ctrHead.addView(TextView(this).also { labelCumRatio ->
labelCumRatio.text = resourceHelper.gs(R.string.ratio)
labelCumRatio.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
)
// exponential table
binding.expweightTable.addView(
TableRow(this).also { etrHead ->
etrHead.setBackgroundColor(Color.DKGRAY)
etrHead.layoutParams = TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
etrHead.addView(TextView(this).also { labelExpWeight ->
labelExpWeight.text = resourceHelper.gs(R.string.weight)
labelExpWeight.setTextColor(Color.WHITE)
})
etrHead.addView(TextView(this).also { labelExpTdd ->
labelExpTdd.text = resourceHelper.gs(R.string.tdd)
labelExpTdd.setTextColor(Color.WHITE)
})
etrHead.addView(TextView(this).also { labelExpRatio ->
labelExpRatio.text = resourceHelper.gs(R.string.ratio)
labelExpRatio.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
)
binding.reload.setOnClickListener {
binding.reload.visibility = View.GONE
binding.connectionStatus.visibility = View.VISIBLE
binding.message.visibility = View.VISIBLE
binding.message.text = resourceHelper.gs(R.string.warning_Message)
commandQueue.loadTDDs(object : Callback() {
override fun run() {
loadDataFromDB()
runOnUiThread {
binding.reload.visibility = View.VISIBLE
binding.connectionStatus.visibility = View.GONE
binding.message.visibility = View.GONE
}
}
})
}
binding.totalBaseBasal.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
binding.totalBaseBasal.clearFocus()
return@setOnEditorActionListener true
}
false
}
binding.totalBaseBasal.setOnFocusChangeListener { _: View?, hasFocus: Boolean ->
if (hasFocus) {
binding.totalBaseBasal.text.clear()
} else {
sp.putString("TBB", binding.totalBaseBasal.text.toString())
tbb = sp.getString("TBB", "")
loadDataFromDB()
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.totalBaseBasal.windowToken, 0)
}
}
loadDataFromDB()
}
override fun onResume() {
super.onResume()
disposable.add(rxBus
.toObservable(EventPumpStatusChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ event -> binding.connectionStatus.text = event.getStatus(resourceHelper) }, fabricPrivacy::logException)
)
disposable.add(rxBus
.toObservable(EventDanaRSyncStatus::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ event ->
aapsLogger.debug("EventDanaRSyncStatus: " + event.message)
binding.connectionStatus.text = event.message
}, fabricPrivacy::logException)
)
}
override fun onPause() {
super.onPause()
disposable.clear()
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
val myView = currentFocus
if (myView is EditText) {
val rect = Rect()
myView.getGlobalVisibleRect(rect)
if (!rect.contains(event.rawX.toInt(), event.rawY.toInt())) {
myView.clearFocus()
}
}
}
return super.dispatchTouchEvent(event)
}
@SuppressLint("SetTextI18n")
private fun loadDataFromDB() {
historyList.clear()
historyList.addAll(databaseHelper.getTDDs())
//only use newest 10
historyList = historyList.subList(0, min(10, historyList.size))
//fill single gaps
val df: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault())
for (i in 0 until historyList.size - 1) {
val elem1 = historyList[i]
val elem2 = historyList[i + 1]
if (df.format(Date(elem1.date)) != df.format(Date(elem2.date + 25 * 60 * 60 * 1000))) {
val dummy = TDD()
dummy.date = elem1.date - 24 * 60 * 60 * 1000
dummy.basal = elem1.basal / 2
dummy.bolus = elem1.bolus / 2
dummies.add(dummy)
elem1.basal /= 2.0
elem1.bolus /= 2.0
}
}
historyList.addAll(dummies)
historyList.sortWith { lhs: TDD, rhs: TDD -> (rhs.date - lhs.date).toInt() }
runOnUiThread {
cleanTable(binding.mainTable)
cleanTable(binding.cumulativeTable)
cleanTable(binding.expweightTable)
val df1: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault())
if (TextUtils.isEmpty(tbb)) {
binding.totalBaseBasal.error = "Please Enter Total Base Basal"
return@runOnUiThread
} else {
magicNumber = SafeParse.stringToDouble(tbb)
}
magicNumber *= 2.0
binding.totalBaseBasal2.text = decimalFormat.format(magicNumber)
var i = 0
var sum = 0.0
var weighted03 = 0.0
var weighted05 = 0.0
var weighted07 = 0.0
//TDD table
for (record in historyList) {
val tdd = record.getTotal()
// Create the table row
binding.mainTable.addView(
TableRow(this@TDDStatsActivity).also { tr ->
if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY)
if (dummies.contains(record))
tr.setBackgroundColor(Color.argb(125, 255, 0, 0))
tr.id = 100 + i
tr.layoutParams = TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT)
// Here create the TextView dynamically
tr.addView(TextView(this@TDDStatsActivity).also { labelDATE ->
labelDATE.id = 200 + i
labelDATE.text = df1.format(Date(record.date))
labelDATE.setTextColor(Color.WHITE)
})
tr.addView(TextView(this@TDDStatsActivity).also { labelBASAL ->
labelBASAL.id = 300 + i
labelBASAL.text = resourceHelper.gs(R.string.formatinsulinunits, record.basal)
labelBASAL.setTextColor(Color.WHITE)
})
tr.addView(TextView(this@TDDStatsActivity).also { labelBOLUS ->
labelBOLUS.id = 400 + i
labelBOLUS.text = resourceHelper.gs(R.string.formatinsulinunits, record.bolus)
labelBOLUS.setTextColor(Color.WHITE)
})
tr.addView(TextView(this@TDDStatsActivity).also { labelTDD ->
labelTDD.id = 500 + i
labelTDD.text = resourceHelper.gs(R.string.formatinsulinunits, tdd)
labelTDD.setTextColor(Color.WHITE)
})
tr.addView(TextView(this@TDDStatsActivity).also { labelRATIO ->
labelRATIO.id = 600 + i
labelRATIO.text = (100 * tdd / magicNumber).roundToInt().toString() + "%"
labelRATIO.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT))
i++
}
i = 0
//cumulative TDDs
for (record in historyList) {
if (historyList.isNotEmpty() && df1.format(Date(record.date)) == df1.format(Date()))
//Today should not be included
continue
i++
sum += record.getTotal()
// Create the cumulative table row
binding.cumulativeTable.addView(
TableRow(this@TDDStatsActivity).also { ctr ->
if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY)
ctr.id = 700 + i
ctr.layoutParams = TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
// Here create the TextView dynamically
ctr.addView(TextView(this@TDDStatsActivity).also { labelDAYS ->
labelDAYS.id = 800 + i
labelDAYS.text = i.toString()
labelDAYS.setTextColor(Color.WHITE)
})
ctr.addView(TextView(this@TDDStatsActivity).also { labelCUMTDD ->
labelCUMTDD.id = 900 + i
labelCUMTDD.text = resourceHelper.gs(R.string.formatinsulinunits, sum / i)
labelCUMTDD.setTextColor(Color.WHITE)
})
ctr.addView(TextView(this@TDDStatsActivity).also { labelCUMRATIO ->
labelCUMRATIO.id = 1000 + i
labelCUMRATIO.text = (100 * sum / i / magicNumber).roundToInt().toString() + "%"
labelCUMRATIO.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
)
}
if (isOldData(historyList) && activePlugin.activePump.pumpDescription.needsManualTDDLoad) {
binding.message.visibility = View.VISIBLE
binding.message.text = resourceHelper.gs(R.string.olddata_Message)
} else binding.mainTable.setBackgroundColor(Color.TRANSPARENT)
if (historyList.isNotEmpty() && df1.format(Date(historyList[0].date)) == df1.format(Date())) {
//Today should not be included
historyList.removeAt(0)
}
historyList.reverse()
i = 0
for (record in historyList) {
val tdd = record.getTotal()
if (i == 0) {
weighted03 = tdd
weighted05 = tdd
weighted07 = tdd
} else {
weighted07 = weighted07 * 0.3 + tdd * 0.7
weighted05 = weighted05 * 0.5 + tdd * 0.5
weighted03 = weighted03 * 0.7 + tdd * 0.3
}
i++
}
// Create the exponential table row
binding.expweightTable.addView(
TableRow(this@TDDStatsActivity).also { etr ->
if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY)
etr.id = 1100 + i
etr.layoutParams = TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
// Here create the TextView dynamically
etr.addView(TextView(this@TDDStatsActivity).also { labelWEIGHT ->
labelWEIGHT.id = 1200 + i
labelWEIGHT.text = "0.3\n0.5\n0.7"
labelWEIGHT.setTextColor(Color.WHITE)
})
etr.addView(TextView(this@TDDStatsActivity).also { labelEXPTDD ->
labelEXPTDD.id = 1300 + i
labelEXPTDD.text = """
${resourceHelper.gs(R.string.formatinsulinunits, weighted03)}
${resourceHelper.gs(R.string.formatinsulinunits, weighted05)}
${resourceHelper.gs(R.string.formatinsulinunits, weighted07)}
""".trimIndent()
labelEXPTDD.setTextColor(Color.WHITE)
})
etr.addView(TextView(this@TDDStatsActivity).also { labelEXPRATIO ->
labelEXPRATIO.id = 1400 + i
labelEXPRATIO.text = """
${(100 * weighted03 / magicNumber).roundToInt()}%
${(100 * weighted05 / magicNumber).roundToInt()}%
${(100 * weighted07 / magicNumber).roundToInt()}%
""".trimIndent()
labelEXPRATIO.setTextColor(Color.WHITE)
})
}, TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)
)
}
}
private fun cleanTable(table: TableLayout) {
val childCount = table.childCount
// Remove all rows except the first one
if (childCount > 1) table.removeViews(1, childCount - 1)
}
private fun isOldData(historyList: List<TDD>): Boolean {
val type = activePlugin.activePump.pumpDescription.pumpType
val startsYesterday = type == PumpType.DanaR || type == PumpType.DanaRS || type == PumpType.DanaRv2 || type == PumpType.DanaRKorean || type == PumpType.AccuChekInsight
val df: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault())
return historyList.size < 3 || df.format(Date(historyList[0].date)) != df.format(Date(System.currentTimeMillis() - if (startsYesterday) 1000 * 60 * 60 * 24 else 0))
}
}

View file

@ -3,14 +3,15 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="info.nightscout.androidaps.activities.TDDStatsActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -20,48 +21,47 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:textColor="@color/mdtp_white"
android:background="@drawable/pillborder"
android:text="@string/tdd" />
android:gravity="center_horizontal"
android:text="@string/tdd"
android:textColor="@color/mdtp_white" />
<TableLayout
android:stretchColumns="0,1,2,3,4"
android:id="@+id/main_table"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</TableLayout>
android:layout_weight="1"
android:stretchColumns="0,1,2,3,4" />
<Space
android:layout_width="10dp"
android:layout_height="10dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:textColor="@color/mdtp_white"
android:background="@drawable/pillborder"
android:gravity="center_horizontal"
android:text="@string/cumulative_tdd" />
android:text="@string/cumulative_tdd"
android:textColor="@color/mdtp_white" />
<TableLayout
android:stretchColumns="0,1,2"
android:id="@+id/cumulative_table"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1">
android:layout_height="0dp"
android:layout_weight="1"
android:stretchColumns="0,1,2">
</TableLayout>
</LinearLayout>
@ -71,78 +71,78 @@
android:layout_height="10dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true">
android:focusableInTouchMode="true"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textColor="@color/mdtp_white"
android:background="@drawable/pillborder"
android:text="@string/expweight" />
android:gravity="center_horizontal"
android:text="@string/expweight"
android:textColor="@color/mdtp_white" />
<TableLayout
android:stretchColumns="0,1,2"
android:id="@+id/expweight_table"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1">
</TableLayout>
android:layout_height="0dp"
android:layout_weight="1"
android:stretchColumns="0,1,2" />
<Space
android:layout_width="10dp"
android:layout_height="10dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:text="@string/tbb"
android:labelFor="@+id/danar_stats_editTotalBaseBasal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:layout_weight="1" />
android:labelFor="@+id/total_base_basal"
android:text="@string/tbb" />
<EditText
android:id="@+id/total_base_basal"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:layout_marginRight="10dp"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/mdtp_white"
android:layout_marginEnd="10dp"
android:autofillHints="@string/tbb"
android:background="@drawable/pillborder"
android:id="@+id/danar_stats_editTotalBaseBasal" />
android:gravity="center_vertical|center_horizontal"
android:inputType="numberDecimal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/mdtp_white" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:text="@string/tbb2"
android:labelFor="@+id/danar_stats_editTotalBaseBasal2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:layout_weight="1" />
android:labelFor="@+id/total_base_basal_2"
android:text="@string/tbb2" />
<TextView
android:id="@+id/total_base_basal_2"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginEnd="10dp"
android:gravity="center_vertical|center_horizontal"
android:layout_marginRight="10dp"
android:textColor="@color/mdtp_white"
android:id="@+id/danar_stats_editTotalBaseBasal2" />
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/mdtp_white" />
</LinearLayout>
</LinearLayout>
@ -150,52 +150,47 @@
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/danar_historybuttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:baselineAligned="false">
android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout
android:orientation="vertical"
<TextView
android:id="@+id/connection_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal" />
<TextView
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:layout_weight="1">
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/pillborder"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/warning_Message"
android:textColor="#ff0000"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:id="@+id/danar_stats_connection_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal" />
<Space
android:layout_width="match_parent"
android:layout_height="5dp" />
<TextView
android:id="@+id/danar_stats_Message"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textStyle="bold"
android:textColor="#ff0000"
android:background="@drawable/pillborder"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/warning_Message" />
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/reload"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawableStart="@drawable/ic_actions_refill"
android:text="@string/reload" />
<Space
android:layout_width="match_parent"
android:layout_height="5dp" />
<Button
android:id="@+id/danar_statsreload"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textColor="@color/mdtp_white"
android:background="@drawable/pillborder"
android:text="@string/reload" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>