Esempio n. 1
0
 private void displayCurrentInfoFromReading(BgReading lastBgReading, boolean predictive) {
   double estimate = 0;
   if ((new Date().getTime()) - (60000 * 11) - lastBgReading.timestamp > 0) {
     notificationText.setText("Signal Missed");
     if (!predictive) {
       estimate = lastBgReading.calculated_value;
     } else {
       estimate = BgReading.estimated_bg(lastBgReading.timestamp + (6000 * 7));
     }
     currentBgValueText.setText(bgGraphBuilder.unitized_string(estimate));
     currentBgValueText.setPaintFlags(
         currentBgValueText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
     dexbridgeBattery.setPaintFlags(
         dexbridgeBattery.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
   } else {
     if (notificationText.getText().length() == 0) {
       notificationText.setTextColor(Color.WHITE);
     }
     if (!predictive) {
       estimate = lastBgReading.calculated_value;
       String stringEstimate = bgGraphBuilder.unitized_string(estimate);
       String slope_arrow = lastBgReading.slopeArrow();
       if (lastBgReading.hide_slope) {
         slope_arrow = "";
       }
       currentBgValueText.setText(stringEstimate + " " + slope_arrow);
     } else {
       estimate = BgReading.activePrediction();
       String stringEstimate = bgGraphBuilder.unitized_string(estimate);
       currentBgValueText.setText(stringEstimate + " " + BgReading.activeSlopeArrow());
     }
   }
   int minutes = (int) (System.currentTimeMillis() - lastBgReading.timestamp) / (60 * 1000);
   notificationText.append("\n" + minutes + ((minutes == 1) ? " Minute ago" : " Minutes ago"));
   List<BgReading> bgReadingList = BgReading.latest(2);
   if (bgReadingList != null && bgReadingList.size() == 2) {
     // same logic as in xDripWidget (refactor that to BGReadings to avoid redundancy / later
     // inconsistencies)?
     if (BgGraphBuilder.isXLargeTablet(getApplicationContext())) {
       notificationText.append("  ");
     } else {
       notificationText.append("\n");
     }
     notificationText.append(bgGraphBuilder.unitizedDeltaString(true, true));
   }
   if (bgGraphBuilder.unitized(estimate) <= bgGraphBuilder.lowMark) {
     currentBgValueText.setTextColor(Color.parseColor("#C30909"));
   } else if (bgGraphBuilder.unitized(estimate) >= bgGraphBuilder.highMark) {
     currentBgValueText.setTextColor(Color.parseColor("#FFBB33"));
   } else {
     currentBgValueText.setTextColor(Color.WHITE);
   }
 }
  public String unitizedDeltaString(boolean showUnit, boolean highGranularity) {

    List<BgReading> last2 = BgReading.latest(2);
    if (last2.size() < 2 || last2.get(0).timestamp - last2.get(1).timestamp > 20 * 60 * 1000) {
      // don't show delta if there are not enough values or the values are more than 20 mintes apart
      return "???";
    }

    double value = BgReading.currentSlope() * 5 * 60 * 1000;

    if (Math.abs(value) > 100) {
      // a delta > 100 will not happen with real BG values -> problematic sensor data
      return "ERR";
    }

    // TODO: allow localization from os settings once pebble doesn't require english locale
    DecimalFormat df = new DecimalFormat("#", new DecimalFormatSymbols(Locale.ENGLISH));
    String delta_sign = "";
    if (value > 0) {
      delta_sign = "+";
    }
    if (doMgdl) {

      if (highGranularity) {
        df.setMaximumFractionDigits(1);
      } else {
        df.setMaximumFractionDigits(0);
      }

      return delta_sign + df.format(unitized(value)) + (showUnit ? " mg/dL" : "");
    } else {

      if (highGranularity) {
        df.setMaximumFractionDigits(2);
      } else {
        df.setMaximumFractionDigits(1);
      }

      df.setMinimumFractionDigits(1);
      df.setMinimumIntegerDigits(1);
      return delta_sign + df.format(unitized(value)) + (showUnit ? " mmol/L" : "");
    }
  }
Esempio n. 3
0
  private void updateCurrentBgInfoCommon(TextView notificationText) {
    if (alreadyDisplayedBgInfoCommon) return; // with bluetooth and wifi, skip second time
    alreadyDisplayedBgInfoCommon = true;

    final boolean isSensorActive = Sensor.isActive();
    if (!isSensorActive) {
      notificationText.setText("Now start your sensor");
      return;
    }

    final long now = System.currentTimeMillis();
    if (Sensor.currentSensor().started_at + 60000 * 60 * 2 >= now) {
      double waitTime = (Sensor.currentSensor().started_at + 60000 * 60 * 2 - now) / 60000.0;
      notificationText.setText(
          "Please wait while sensor warms up! (" + String.format("%.2f", waitTime) + " minutes)");
      return;
    }

    if (BgReading.latest(2).size() > 1) {
      List<Calibration> calibrations = Calibration.latest(2);
      if (calibrations.size() > 1) {
        if (calibrations.get(0).possible_bad != null
            && calibrations.get(0).possible_bad == true
            && calibrations.get(1).possible_bad != null
            && calibrations.get(1).possible_bad != true) {
          notificationText.setText(
              "Possible bad calibration slope, please have a glass of water, wash hands, then recalibrate in a few!");
        }
        displayCurrentInfo();
      } else {
        notificationText.setText("Please enter two calibrations to get started!");
      }
    } else {
      if (BgReading.latestUnCalculated(2).size() < 2) {
        notificationText.setText("Please wait, need 2 readings from transmitter first.");
      } else {
        List<Calibration> calibrations = Calibration.latest(2);
        if (calibrations.size() < 2) {
          notificationText.setText("Please enter two calibrations to get started!");
        }
      }
    }
  }
 public BgGraphBuilder(Context context, long start, long end, int numValues) {
   end_time = end;
   start_time = start;
   bgReadings = BgReading.latestForGraph(numValues, start, end);
   calibrations = Calibration.latestForGraph(numValues, start, end);
   this.context = context;
   this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
   this.highMark = Double.parseDouble(prefs.getString("highValue", "170"));
   this.lowMark = Double.parseDouble(prefs.getString("lowValue", "70"));
   this.doMgdl = (prefs.getString("units", "mgdl").equals("mgdl"));
   defaultMinY = unitized(40);
   defaultMaxY = unitized(250);
   pointSize = isXLargeTablet(context) ? 5 : 3;
   axisTextSize = isXLargeTablet(context) ? 20 : Axis.DEFAULT_TEXT_SIZE_SP;
   previewAxisTextSize = isXLargeTablet(context) ? 12 : 5;
   hoursPreviewStep = isXLargeTablet(context) ? 2 : 1;
 }
Esempio n. 5
0
  public void displayCurrentInfo() {
    DecimalFormat df = new DecimalFormat("#");
    df.setMaximumFractionDigits(0);

    boolean isDexbridge = CollectionServiceStarter.isDexbridgeWixel(getApplicationContext());
    int bridgeBattery = prefs.getInt("bridge_battery", 0);

    if (isDexbridge) {
      if (bridgeBattery == 0) {
        dexbridgeBattery.setText("Waiting for packet");
      } else {
        dexbridgeBattery.setText("Bridge Battery: " + bridgeBattery + "%");
      }
      if (bridgeBattery < 50) dexbridgeBattery.setTextColor(Color.YELLOW);
      if (bridgeBattery < 25) dexbridgeBattery.setTextColor(Color.RED);
      else dexbridgeBattery.setTextColor(Color.GREEN);
      dexbridgeBattery.setVisibility(View.VISIBLE);
    } else {
      dexbridgeBattery.setVisibility(View.INVISIBLE);
    }

    if ((currentBgValueText.getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) > 0) {
      currentBgValueText.setPaintFlags(
          currentBgValueText.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
      dexbridgeBattery.setPaintFlags(
          dexbridgeBattery.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
    }
    BgReading lastBgReading = BgReading.lastNoSenssor();
    boolean predictive =
        PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
            .getBoolean("predictive_bg", false);
    if (isBTShare) {
      predictive = false;
    }
    if (lastBgReading != null) {
      displayCurrentInfoFromReading(lastBgReading, predictive);
    }
    setupCharts();
  }
/** Created by stephenblack on 11/15/14. */
public class BgGraphBuilder {
  public static final int FUZZER = (1000 * 30 * 5);
  public double end_time = (new Date().getTime() + (60000 * 10)) / FUZZER;
  public double start_time = end_time - ((60000 * 60 * 24)) / FUZZER;
  public Context context;
  public SharedPreferences prefs;
  public double highMark;
  public double lowMark;
  public double defaultMinY;
  public double defaultMaxY;
  public boolean doMgdl;
  final int pointSize;
  final int axisTextSize;
  final int previewAxisTextSize;
  final int hoursPreviewStep;

  private double endHour;
  private final int numValues = (60 / 5) * 24;
  private final List<BgReading> bgReadings =
      BgReading.latestForGraph(numValues, (start_time * FUZZER));
  private List<PointValue> inRangeValues = new ArrayList<PointValue>();
  private List<PointValue> highValues = new ArrayList<PointValue>();
  private List<PointValue> lowValues = new ArrayList<PointValue>();
  private List<PointValue> rawInterpretedValues = new ArrayList<PointValue>();
  public Viewport viewport;

  public BgGraphBuilder(Context context) {
    this.context = context;
    this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
    this.highMark = Double.parseDouble(prefs.getString("highValue", "170"));
    this.lowMark = Double.parseDouble(prefs.getString("lowValue", "70"));
    this.doMgdl = (prefs.getString("units", "mgdl").compareTo("mgdl") == 0);
    defaultMinY = unitized(40);
    defaultMaxY = unitized(250);
    pointSize = isXLargeTablet(context) ? 5 : 3;
    axisTextSize = isXLargeTablet(context) ? 20 : Axis.DEFAULT_TEXT_SIZE_SP;
    previewAxisTextSize = isXLargeTablet(context) ? 12 : 5;
    hoursPreviewStep = isXLargeTablet(context) ? 2 : 1;
  }

  public LineChartData lineData() {
    LineChartData lineData = new LineChartData(defaultLines());
    lineData.setAxisYLeft(yAxis());
    lineData.setAxisXBottom(xAxis());
    return lineData;
  }

  public LineChartData previewLineData() {
    LineChartData previewLineData = new LineChartData(lineData());
    previewLineData.setAxisYLeft(yAxis());
    previewLineData.setAxisXBottom(previewXAxis());
    previewLineData.getLines().get(4).setPointRadius(2);
    previewLineData.getLines().get(5).setPointRadius(2);
    previewLineData.getLines().get(6).setPointRadius(2);
    return previewLineData;
  }

  public List<Line> defaultLines() {
    addBgReadingValues();
    List<Line> lines = new ArrayList<Line>();
    lines.add(minShowLine());
    lines.add(maxShowLine());
    lines.add(highLine());
    lines.add(lowLine());
    lines.add(inRangeValuesLine());
    lines.add(lowValuesLine());
    lines.add(highValuesLine());
    lines.add(rawInterpretedLine());
    return lines;
  }

  public Line highValuesLine() {
    Line highValuesLine = new Line(highValues);
    highValuesLine.setColor(Utils.COLOR_ORANGE);
    highValuesLine.setHasLines(false);
    highValuesLine.setPointRadius(pointSize);
    highValuesLine.setHasPoints(true);
    return highValuesLine;
  }

  public Line lowValuesLine() {
    Line lowValuesLine = new Line(lowValues);
    lowValuesLine.setColor(Color.parseColor("#C30909"));
    lowValuesLine.setHasLines(false);
    lowValuesLine.setPointRadius(pointSize);
    lowValuesLine.setHasPoints(true);
    return lowValuesLine;
  }

  public Line inRangeValuesLine() {
    Line inRangeValuesLine = new Line(inRangeValues);
    inRangeValuesLine.setColor(Utils.COLOR_BLUE);
    inRangeValuesLine.setHasLines(false);
    inRangeValuesLine.setPointRadius(pointSize);
    inRangeValuesLine.setHasPoints(true);
    return inRangeValuesLine;
  }

  public Line rawInterpretedLine() {
    Line line = new Line(rawInterpretedValues);
    line.setHasLines(false);
    line.setPointRadius(1);
    line.setHasPoints(true);
    return line;
  }

  private void addBgReadingValues() {
    for (BgReading bgReading : bgReadings) {
      if (bgReading.raw_calculated != 0 && prefs.getBoolean("interpret_raw", false)) {
        rawInterpretedValues.add(
            new PointValue(
                (float) (bgReading.timestamp / FUZZER),
                (float) unitized(bgReading.raw_calculated)));
      } else if (bgReading.calculated_value >= 400) {
        highValues.add(
            new PointValue((float) (bgReading.timestamp / FUZZER), (float) unitized(400)));
      } else if (unitized(bgReading.calculated_value) >= highMark) {
        highValues.add(
            new PointValue(
                (float) (bgReading.timestamp / FUZZER),
                (float) unitized(bgReading.calculated_value)));
      } else if (unitized(bgReading.calculated_value) >= lowMark) {
        inRangeValues.add(
            new PointValue(
                (float) (bgReading.timestamp / FUZZER),
                (float) unitized(bgReading.calculated_value)));
      } else if (bgReading.calculated_value >= 40) {
        lowValues.add(
            new PointValue(
                (float) (bgReading.timestamp / FUZZER),
                (float) unitized(bgReading.calculated_value)));
      } else if (bgReading.calculated_value > 13) {
        lowValues.add(new PointValue((float) (bgReading.timestamp / FUZZER), (float) unitized(40)));
      }
    }
  }

  public Line highLine() {
    List<PointValue> highLineValues = new ArrayList<PointValue>();
    highLineValues.add(new PointValue((float) start_time, (float) highMark));
    highLineValues.add(new PointValue((float) end_time, (float) highMark));
    Line highLine = new Line(highLineValues);
    highLine.setHasPoints(false);
    highLine.setStrokeWidth(1);
    highLine.setColor(Utils.COLOR_ORANGE);
    return highLine;
  }

  public Line lowLine() {
    List<PointValue> lowLineValues = new ArrayList<PointValue>();
    lowLineValues.add(new PointValue((float) start_time, (float) lowMark));
    lowLineValues.add(new PointValue((float) end_time, (float) lowMark));
    Line lowLine = new Line(lowLineValues);
    lowLine.setHasPoints(false);
    lowLine.setAreaTransparency(50);
    lowLine.setColor(Color.parseColor("#C30909"));
    lowLine.setStrokeWidth(1);
    lowLine.setFilled(true);
    return lowLine;
  }

  public Line maxShowLine() {
    List<PointValue> maxShowValues = new ArrayList<PointValue>();
    maxShowValues.add(new PointValue((float) start_time, (float) defaultMaxY));
    maxShowValues.add(new PointValue((float) end_time, (float) defaultMaxY));
    Line maxShowLine = new Line(maxShowValues);
    maxShowLine.setHasLines(false);
    maxShowLine.setHasPoints(false);
    return maxShowLine;
  }

  public Line minShowLine() {
    List<PointValue> minShowValues = new ArrayList<PointValue>();
    minShowValues.add(new PointValue((float) start_time, (float) defaultMinY));
    minShowValues.add(new PointValue((float) end_time, (float) defaultMinY));
    Line minShowLine = new Line(minShowValues);
    minShowLine.setHasPoints(false);
    minShowLine.setHasLines(false);
    return minShowLine;
  }

  ///////// AXIS RELATED//////////////
  public Axis yAxis() {
    Axis yAxis = new Axis();
    yAxis.setAutoGenerated(false);
    List<AxisValue> axisValues = new ArrayList<AxisValue>();

    for (int j = 1; j <= 12; j += 1) {
      if (doMgdl) {
        axisValues.add(new AxisValue(j * 50));
      } else {
        axisValues.add(new AxisValue(j * 2));
      }
    }
    yAxis.setValues(axisValues);
    yAxis.setHasLines(true);
    yAxis.setMaxLabelChars(5);
    yAxis.setInside(true);
    yAxis.setTextSize(axisTextSize);
    return yAxis;
  }

  public Axis xAxis() {
    Axis xAxis = new Axis();
    xAxis.setAutoGenerated(false);
    List<AxisValue> xAxisValues = new ArrayList<AxisValue>();
    GregorianCalendar now = new GregorianCalendar();
    GregorianCalendar today =
        new GregorianCalendar(
            now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
    final java.text.DateFormat timeFormat = hourFormat();
    timeFormat.setTimeZone(TimeZone.getDefault());
    double start_hour_block = today.getTime().getTime();
    double timeNow = new Date().getTime();
    for (int l = 0; l <= 24; l++) {
      if ((start_hour_block + (60000 * 60 * (l))) < timeNow) {
        if ((start_hour_block + (60000 * 60 * (l + 1))) >= timeNow) {
          endHour = start_hour_block + (60000 * 60 * (l));
          l = 25;
        }
      }
    }
    for (int l = 0; l <= 24; l++) {
      double timestamp = (endHour - (60000 * 60 * l));
      xAxisValues.add(
          new AxisValue((long) (timestamp / FUZZER), (timeFormat.format(timestamp)).toCharArray()));
    }
    xAxis.setValues(xAxisValues);
    xAxis.setHasLines(true);
    xAxis.setTextSize(axisTextSize);
    return xAxis;
  }

  private SimpleDateFormat hourFormat() {
    return new SimpleDateFormat(DateFormat.is24HourFormat(context) ? "HH" : "h a");
  }

  public static boolean isXLargeTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout
            & Configuration.SCREENLAYOUT_SIZE_MASK)
        >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
  }

  public Axis previewXAxis() {
    List<AxisValue> previewXaxisValues = new ArrayList<AxisValue>();
    final java.text.DateFormat timeFormat = hourFormat();
    timeFormat.setTimeZone(TimeZone.getDefault());
    for (int l = 0; l <= 24; l += hoursPreviewStep) {
      double timestamp = (endHour - (60000 * 60 * l));
      previewXaxisValues.add(
          new AxisValue((long) (timestamp / FUZZER), (timeFormat.format(timestamp)).toCharArray()));
    }
    Axis previewXaxis = new Axis();
    previewXaxis.setValues(previewXaxisValues);
    previewXaxis.setHasLines(true);
    previewXaxis.setTextSize(previewAxisTextSize);
    return previewXaxis;
  }

  ///////// VIEWPORT RELATED//////////////
  public Viewport advanceViewport(Chart chart, Chart previewChart) {
    viewport = new Viewport(previewChart.getMaximumViewport());
    viewport.inset((float) ((86400000 / 2.5) / FUZZER), 0);
    double distance_to_move =
        ((new Date().getTime()) / FUZZER)
            - viewport.left
            - (((viewport.right - viewport.left) / 2));
    viewport.offset((float) distance_to_move, 0);
    return viewport;
  }

  public double unitized(double value) {
    if (doMgdl) {
      return value;
    } else {
      return mmolConvert(value);
    }
  }

  public String unitized_string(double value) {
    DecimalFormat df = new DecimalFormat("#");
    if (value >= 400) {
      return "HIGH";
    } else if (value >= 40) {
      if (doMgdl) {
        df.setMaximumFractionDigits(0);
        return df.format(value);
      } else {
        df.setMaximumFractionDigits(1);
        // next line ensures mmol/l value is XX.x always.  Required by PebbleSync, and probably not
        // a bad idea.
        df.setMinimumFractionDigits(1);
        return df.format(mmolConvert(value));
      }
    } else if (value > 12) {
      return "LOW";
    } else {
      switch ((int) value) {
        case 0:
          return "??0";
        case 1:
          return "?SN";
        case 2:
          return "??2";
        case 3:
          return "?NA";
        case 5:
          return "?NC";
        case 6:
          return "?CD";
        case 9:
          return "?AD";
        case 12:
          return "?RF";
        default:
          return "???";
      }
    }
  }

  public String unitizedDeltaString(double value) {
    DecimalFormat df = new DecimalFormat("#");
    df.setMaximumFractionDigits(1);
    String delta_sign = "";
    if (value > 0.1) {
      delta_sign = "+";
    }
    if (doMgdl) {
      return delta_sign + df.format(unitized(value)) + " mg/dl";
    } else {
      df.setMinimumFractionDigits(1);
      df.setMinimumIntegerDigits(1);
      return delta_sign + df.format(unitized(value)) + " mmol";
    }
  }

  public double mmolConvert(double mgdl) {
    return mgdl * Constants.MGDL_TO_MMOLL;
  }

  public String unit() {
    if (doMgdl) {
      return "mg/dl";
    } else {
      return "mmol";
    }
  }
}