2016-06-07 21:48:17 +02:00
|
|
|
package info.nightscout.androidaps.db;
|
|
|
|
|
2020-01-01 23:23:16 +01:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
2016-06-07 21:48:17 +02:00
|
|
|
import com.j256.ormlite.field.DatabaseField;
|
|
|
|
import com.j256.ormlite.table.DatabaseTable;
|
|
|
|
|
2017-06-06 17:14:17 +02:00
|
|
|
import java.util.Date;
|
2019-05-13 13:18:10 +02:00
|
|
|
import java.util.List;
|
2017-06-07 00:11:33 +02:00
|
|
|
import java.util.Objects;
|
2017-06-06 17:14:17 +02:00
|
|
|
|
2020-01-01 23:23:16 +01:00
|
|
|
import javax.inject.Inject;
|
|
|
|
|
2020-03-10 18:58:27 +01:00
|
|
|
import dagger.android.HasAndroidInjector;
|
2016-06-07 21:48:17 +02:00
|
|
|
import info.nightscout.androidaps.Constants;
|
2017-06-05 00:50:31 +02:00
|
|
|
import info.nightscout.androidaps.MainApp;
|
|
|
|
import info.nightscout.androidaps.R;
|
2020-01-01 23:23:16 +01:00
|
|
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
|
|
|
import info.nightscout.androidaps.logging.LTag;
|
|
|
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
|
2019-02-28 23:16:50 +01:00
|
|
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
2020-01-01 23:23:16 +01:00
|
|
|
import info.nightscout.androidaps.utils.DateUtil;
|
2019-02-26 20:38:27 +01:00
|
|
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
2020-01-01 23:23:16 +01:00
|
|
|
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
2019-05-13 13:18:10 +02:00
|
|
|
import info.nightscout.androidaps.utils.T;
|
2020-01-01 23:23:16 +01:00
|
|
|
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
2016-06-07 21:48:17 +02:00
|
|
|
|
2016-07-21 15:10:42 +02:00
|
|
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
2017-06-05 00:50:31 +02:00
|
|
|
public class BgReading implements DataPointWithLabelInterface {
|
2020-03-10 18:58:27 +01:00
|
|
|
@Inject public AAPSLogger aapsLogger;
|
|
|
|
@Inject public DefaultValueHelper defaultValueHelper;
|
|
|
|
@Inject public ProfileFunction profileFunction;
|
|
|
|
@Inject public ResourceHelper resourceHelper;
|
2016-06-07 21:48:17 +02:00
|
|
|
|
2017-05-21 22:05:03 +02:00
|
|
|
@DatabaseField(id = true)
|
|
|
|
public long date;
|
2016-06-07 21:48:17 +02:00
|
|
|
|
2017-05-21 22:05:03 +02:00
|
|
|
@DatabaseField
|
|
|
|
public boolean isValid = true;
|
2016-06-07 21:48:17 +02:00
|
|
|
|
|
|
|
@DatabaseField
|
|
|
|
public double value;
|
|
|
|
@DatabaseField
|
2016-12-27 20:41:28 +01:00
|
|
|
public String direction;
|
2016-06-07 21:48:17 +02:00
|
|
|
@DatabaseField
|
|
|
|
public double raw;
|
|
|
|
|
|
|
|
@DatabaseField
|
2017-05-21 22:05:03 +02:00
|
|
|
public int source = Source.NONE;
|
|
|
|
@DatabaseField
|
|
|
|
public String _id = null; // NS _id
|
|
|
|
|
2017-08-21 15:36:52 +02:00
|
|
|
public boolean isCOBPrediction = false; // true when drawing predictions as bg points (COB)
|
|
|
|
public boolean isaCOBPrediction = false; // true when drawing predictions as bg points (aCOB)
|
|
|
|
public boolean isIOBPrediction = false; // true when drawing predictions as bg points (IOB)
|
|
|
|
public boolean isUAMPrediction = false; // true when drawing predictions as bg points (UAM)
|
2017-12-11 18:45:04 +01:00
|
|
|
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
|
2017-06-05 00:50:31 +02:00
|
|
|
|
2017-06-06 17:14:17 +02:00
|
|
|
public BgReading() {
|
2020-03-10 18:58:27 +01:00
|
|
|
MainApp.instance().androidInjector().inject(this);
|
2017-06-06 17:14:17 +02:00
|
|
|
}
|
2016-06-07 21:48:17 +02:00
|
|
|
|
|
|
|
public BgReading(NSSgv sgv) {
|
2017-05-21 22:05:03 +02:00
|
|
|
date = sgv.getMills();
|
2016-06-07 21:48:17 +02:00
|
|
|
value = sgv.getMgdl();
|
2017-03-18 23:35:43 +01:00
|
|
|
raw = sgv.getFiltered() != null ? sgv.getFiltered() : value;
|
2016-12-27 20:41:28 +01:00
|
|
|
direction = sgv.getDirection();
|
2017-12-15 01:03:31 +01:00
|
|
|
_id = sgv.getId();
|
2016-06-07 21:48:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public Double valueToUnits(String units) {
|
|
|
|
if (units.equals(Constants.MGDL))
|
|
|
|
return value;
|
|
|
|
else
|
|
|
|
return value * Constants.MGDL_TO_MMOLL;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String valueToUnitsToString(String units) {
|
2016-07-11 18:07:54 +02:00
|
|
|
if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(value);
|
2016-07-11 18:42:14 +02:00
|
|
|
else return DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL);
|
2016-06-07 21:48:17 +02:00
|
|
|
}
|
|
|
|
|
2017-06-06 17:14:17 +02:00
|
|
|
public String directionToSymbol() {
|
2016-12-27 20:41:28 +01:00
|
|
|
String symbol = "";
|
2019-05-10 08:47:32 +02:00
|
|
|
if (direction == null)
|
2019-04-23 09:07:32 +02:00
|
|
|
direction = calculateDirection();
|
2019-05-10 08:47:32 +02:00
|
|
|
|
|
|
|
if (direction.compareTo("DoubleDown") == 0) {
|
2016-12-27 20:41:28 +01:00
|
|
|
symbol = "\u21ca";
|
|
|
|
} else if (direction.compareTo("SingleDown") == 0) {
|
|
|
|
symbol = "\u2193";
|
|
|
|
} else if (direction.compareTo("FortyFiveDown") == 0) {
|
|
|
|
symbol = "\u2198";
|
|
|
|
} else if (direction.compareTo("Flat") == 0) {
|
|
|
|
symbol = "\u2192";
|
|
|
|
} else if (direction.compareTo("FortyFiveUp") == 0) {
|
|
|
|
symbol = "\u2197";
|
|
|
|
} else if (direction.compareTo("SingleUp") == 0) {
|
|
|
|
symbol = "\u2191";
|
|
|
|
} else if (direction.compareTo("DoubleUp") == 0) {
|
|
|
|
symbol = "\u21c8";
|
|
|
|
} else if (isSlopeNameInvalid(direction)) {
|
|
|
|
symbol = "??";
|
|
|
|
}
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
2019-05-10 08:47:32 +02:00
|
|
|
private static boolean isSlopeNameInvalid(String direction) {
|
|
|
|
return direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
2016-12-27 20:41:28 +01:00
|
|
|
direction.compareTo("NOT COMPUTABLE") == 0 ||
|
|
|
|
direction.compareTo("OUT_OF_RANGE") == 0 ||
|
|
|
|
direction.compareTo("OUT OF RANGE") == 0 ||
|
2017-11-29 16:07:26 +01:00
|
|
|
direction.compareTo("NONE") == 0 ||
|
2019-05-10 08:47:32 +02:00
|
|
|
direction.compareTo("NotComputable") == 0;
|
2016-12-27 20:41:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-01 23:23:16 +01:00
|
|
|
@NonNull @Override
|
2016-06-07 21:48:17 +02:00
|
|
|
public String toString() {
|
2016-06-07 23:36:22 +02:00
|
|
|
return "BgReading{" +
|
2017-05-21 22:05:03 +02:00
|
|
|
"date=" + date +
|
2020-01-01 23:23:16 +01:00
|
|
|
", date=" + DateUtil.dateAndTimeString(date) +
|
2016-06-07 21:48:17 +02:00
|
|
|
", value=" + value +
|
2016-12-27 20:41:28 +01:00
|
|
|
", direction=" + direction +
|
2016-06-07 21:48:17 +02:00
|
|
|
", raw=" + raw +
|
|
|
|
'}';
|
|
|
|
}
|
2016-06-09 00:01:28 +02:00
|
|
|
|
2018-06-29 22:43:54 +02:00
|
|
|
public boolean isDataChanging(BgReading other) {
|
|
|
|
if (date != other.date) {
|
2020-01-01 23:23:16 +01:00
|
|
|
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
|
2018-06-29 22:43:54 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (value != other.value)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:14:17 +02:00
|
|
|
public boolean isEqual(BgReading other) {
|
|
|
|
if (date != other.date) {
|
2020-01-01 23:23:16 +01:00
|
|
|
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
|
2017-06-06 17:14:17 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (value != other.value)
|
|
|
|
return false;
|
|
|
|
if (raw != other.raw)
|
|
|
|
return false;
|
2018-07-28 11:31:37 +02:00
|
|
|
if (!Objects.equals(direction, other.direction))
|
2017-06-06 17:14:17 +02:00
|
|
|
return false;
|
2017-06-07 00:11:33 +02:00
|
|
|
if (!Objects.equals(_id, other._id))
|
2017-06-06 17:14:17 +02:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void copyFrom(BgReading other) {
|
|
|
|
if (date != other.date) {
|
2020-01-01 23:23:16 +01:00
|
|
|
aapsLogger.error(LTag.GLUCOSE, "Copying different");
|
2017-06-06 17:14:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
value = other.value;
|
|
|
|
raw = other.raw;
|
|
|
|
direction = other.direction;
|
|
|
|
_id = other._id;
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:41:12 +02:00
|
|
|
public BgReading date(long date) {
|
|
|
|
this.date = date;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2018-09-06 11:18:15 +02:00
|
|
|
public BgReading date(Date date) {
|
|
|
|
this.date = date.getTime();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:41:12 +02:00
|
|
|
public BgReading value(double value) {
|
|
|
|
this.value = value;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2017-06-05 00:50:31 +02:00
|
|
|
// ------------------ DataPointWithLabelInterface ------------------
|
2016-06-09 00:01:28 +02:00
|
|
|
@Override
|
|
|
|
public double getX() {
|
2017-05-21 22:05:03 +02:00
|
|
|
return date;
|
2016-06-09 00:01:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double getY() {
|
2020-01-01 23:23:16 +01:00
|
|
|
return valueToUnits(profileFunction.getUnits());
|
2016-06-09 00:01:28 +02:00
|
|
|
}
|
2016-07-17 15:04:33 +02:00
|
|
|
|
2017-06-05 00:50:31 +02:00
|
|
|
@Override
|
|
|
|
public void setY(double y) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getLabel() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public long getDuration() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public PointsWithLabelGraphSeries.Shape getShape() {
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isPrediction())
|
|
|
|
return PointsWithLabelGraphSeries.Shape.PREDICTION;
|
|
|
|
else
|
|
|
|
return PointsWithLabelGraphSeries.Shape.BG;
|
2017-06-05 00:50:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public float getSize() {
|
2018-04-19 22:31:07 +02:00
|
|
|
return 1;
|
2017-06-05 00:50:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getColor() {
|
2020-01-01 23:23:16 +01:00
|
|
|
String units = profileFunction.getUnits();
|
|
|
|
Double lowLine = defaultValueHelper.determineLowLine();
|
|
|
|
Double highLine = defaultValueHelper.determineHighLine();
|
|
|
|
int color = resourceHelper.gc(R.color.inrange);
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isPrediction())
|
2018-05-01 19:16:28 +02:00
|
|
|
return getPredectionColor();
|
2017-06-05 00:50:31 +02:00
|
|
|
else if (valueToUnits(units) < lowLine)
|
2020-01-01 23:23:16 +01:00
|
|
|
color = resourceHelper.gc(R.color.low);
|
2017-06-05 00:50:31 +02:00
|
|
|
else if (valueToUnits(units) > highLine)
|
2020-01-01 23:23:16 +01:00
|
|
|
color = resourceHelper.gc(R.color.high);
|
2017-06-05 00:50:31 +02:00
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
2018-05-02 00:51:59 +02:00
|
|
|
public int getPredectionColor() {
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isIOBPrediction)
|
2020-01-01 23:23:16 +01:00
|
|
|
return resourceHelper.gc(R.color.iob);
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isCOBPrediction)
|
2020-01-01 23:23:16 +01:00
|
|
|
return resourceHelper.gc(R.color.cob);
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isaCOBPrediction)
|
2020-01-01 23:23:16 +01:00
|
|
|
return 0x80FFFFFF & resourceHelper.gc(R.color.cob);
|
2017-08-21 15:36:52 +02:00
|
|
|
if (isUAMPrediction)
|
2020-01-01 23:23:16 +01:00
|
|
|
return resourceHelper.gc(R.color.uam);
|
2017-12-11 18:45:04 +01:00
|
|
|
if (isZTPrediction)
|
2020-01-01 23:23:16 +01:00
|
|
|
return resourceHelper.gc(R.color.zt);
|
2017-08-21 15:36:52 +02:00
|
|
|
return R.color.mdtp_white;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isPrediction() {
|
2017-12-11 18:45:04 +01:00
|
|
|
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
2017-08-21 15:36:52 +02:00
|
|
|
}
|
|
|
|
|
2019-04-23 09:07:32 +02:00
|
|
|
|
|
|
|
// Copied from xDrip+
|
2019-05-10 08:47:32 +02:00
|
|
|
String calculateDirection() {
|
2019-05-13 13:18:10 +02:00
|
|
|
// Rework to get bgreaings from internal DB and calculate on that base
|
|
|
|
|
|
|
|
List<BgReading> bgReadingsList = MainApp.getDbHelper().getAllBgreadingsDataFromTime(this.date - T.mins(10).msecs(), false);
|
|
|
|
if (bgReadingsList == null || bgReadingsList.size() < 2)
|
2019-05-10 08:47:32 +02:00
|
|
|
return "NONE";
|
2019-05-13 13:18:10 +02:00
|
|
|
BgReading current = bgReadingsList.get(1);
|
|
|
|
BgReading previous = bgReadingsList.get(0);
|
|
|
|
|
|
|
|
if (bgReadingsList.get(1).date < bgReadingsList.get(0).date) {
|
|
|
|
current = bgReadingsList.get(0);
|
|
|
|
previous = bgReadingsList.get(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
double slope;
|
2019-04-23 09:07:32 +02:00
|
|
|
|
2019-04-30 14:07:43 +02:00
|
|
|
// Avoid division by 0
|
2019-05-13 13:18:10 +02:00
|
|
|
if (current.date == previous.date)
|
2019-04-30 14:07:43 +02:00
|
|
|
slope = 0;
|
|
|
|
else
|
2019-05-13 13:18:10 +02:00
|
|
|
slope = (previous.value - current.value) / (previous.date - current.date);
|
2019-05-10 08:47:32 +02:00
|
|
|
|
2020-01-01 23:23:16 +01:00
|
|
|
aapsLogger.error(LTag.GLUCOSE, "Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date));
|
2019-05-10 08:47:32 +02:00
|
|
|
|
2019-04-23 09:07:32 +02:00
|
|
|
double slope_by_minute = slope * 60000;
|
|
|
|
String arrow = "NONE";
|
|
|
|
|
|
|
|
if (slope_by_minute <= (-3.5)) {
|
|
|
|
arrow = "DoubleDown";
|
|
|
|
} else if (slope_by_minute <= (-2)) {
|
|
|
|
arrow = "SingleDown";
|
|
|
|
} else if (slope_by_minute <= (-1)) {
|
|
|
|
arrow = "FortyFiveDown";
|
|
|
|
} else if (slope_by_minute <= (1)) {
|
|
|
|
arrow = "Flat";
|
|
|
|
} else if (slope_by_minute <= (2)) {
|
|
|
|
arrow = "FortyFiveUp";
|
|
|
|
} else if (slope_by_minute <= (3.5)) {
|
|
|
|
arrow = "SingleUp";
|
|
|
|
} else if (slope_by_minute <= (40)) {
|
|
|
|
arrow = "DoubleUp";
|
|
|
|
}
|
2020-01-01 23:23:16 +01:00
|
|
|
aapsLogger.error(LTag.GLUCOSE, "Direction set to: " + arrow);
|
2019-04-23 09:07:32 +02:00
|
|
|
return arrow;
|
|
|
|
}
|
2016-06-07 21:48:17 +02:00
|
|
|
}
|