use of com.eveningoutpost.dexdrip.Models.BgReading in project xDrip by NightscoutFoundation.
the class NightscoutUploader method doMongoUpload.
private boolean doMongoUpload(SharedPreferences prefs, List<BgReading> glucoseDataSets, List<Calibration> meterRecords, List<Calibration> calRecords) {
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
format.setTimeZone(TimeZone.getDefault());
final String dbURI = prefs.getString("cloud_storage_mongodb_uri", null);
if (dbURI != null) {
try {
final URI uri = new URI(dbURI.trim());
if ((uri.getHost().startsWith("192.168.")) && prefs.getBoolean("skip_lan_uploads_when_no_lan", true) && (!JoH.isLANConnected())) {
Log.d(TAG, "Skipping mongo upload to: " + dbURI + " due to no LAN connection");
return false;
}
} catch (URISyntaxException e) {
UserError.Log.e(TAG, "Invalid mongo URI: " + e);
}
}
final String collectionName = prefs.getString("cloud_storage_mongodb_collection", null);
final String dsCollectionName = prefs.getString("cloud_storage_mongodb_device_status_collection", "devicestatus");
if (dbURI != null && collectionName != null) {
try {
// connect to db
MongoClientURI uri = new MongoClientURI(dbURI.trim() + "?socketTimeoutMS=180000");
MongoClient client = new MongoClient(uri);
// get db
DB db = client.getDB(uri.getDatabase());
// get collection
DBCollection dexcomData = db.getCollection(collectionName.trim());
try {
Log.i(TAG, "The number of EGV records being sent to MongoDB is " + glucoseDataSets.size());
for (BgReading record : glucoseDataSets) {
// make db object
BasicDBObject testData = new BasicDBObject();
testData.put("device", "xDrip-" + prefs.getString("dex_collection_method", "BluetoothWixel"));
if (record != null) {
// KS
testData.put("date", record.timestamp);
testData.put("dateString", format.format(record.timestamp));
testData.put("sgv", Math.round(record.calculated_value));
testData.put("direction", record.slopeName());
testData.put("type", "sgv");
testData.put("filtered", record.ageAdjustedFiltered() * 1000);
testData.put("unfiltered", record.usedRaw() * 1000);
testData.put("rssi", 100);
testData.put("noise", record.noiseValue());
dexcomData.insert(testData, WriteConcern.UNACKNOWLEDGED);
} else
Log.e(TAG, "MongoDB BG record is null.");
}
Log.i(TAG, "The number of MBG records being sent to MongoDB is " + meterRecords.size());
for (Calibration meterRecord : meterRecords) {
// make db object
BasicDBObject testData = new BasicDBObject();
testData.put("device", "xDrip-" + prefs.getString("dex_collection_method", "BluetoothWixel"));
testData.put("type", "mbg");
testData.put("date", meterRecord.timestamp);
testData.put("dateString", format.format(meterRecord.timestamp));
testData.put("mbg", meterRecord.bg);
dexcomData.insert(testData, WriteConcern.UNACKNOWLEDGED);
}
for (Calibration calRecord : calRecords) {
// do not upload undefined slopes
if (calRecord.slope == 0d)
break;
// make db object
BasicDBObject testData = new BasicDBObject();
testData.put("device", "xDrip-" + prefs.getString("dex_collection_method", "BluetoothWixel"));
testData.put("date", calRecord.timestamp);
testData.put("dateString", format.format(calRecord.timestamp));
if (calRecord.check_in) {
testData.put("slope", (calRecord.first_slope));
testData.put("intercept", ((calRecord.first_intercept)));
testData.put("scale", calRecord.first_scale);
} else {
testData.put("slope", (1000 / calRecord.slope));
testData.put("intercept", ((calRecord.intercept * -1000) / (calRecord.slope)));
testData.put("scale", 1);
}
testData.put("type", "cal");
dexcomData.insert(testData, WriteConcern.UNACKNOWLEDGED);
}
// TODO: quick port from original code, revisit before release
DBCollection dsCollection = db.getCollection(dsCollectionName);
BasicDBObject devicestatus = new BasicDBObject();
devicestatus.put("uploaderBattery", getBatteryLevel());
devicestatus.put("created_at", format.format(System.currentTimeMillis()));
dsCollection.insert(devicestatus, WriteConcern.UNACKNOWLEDGED);
// treatments mongo sync using unified queue
Log.d(TAG, "Starting treatments mongo direct");
final long THIS_QUEUE = UploaderQueue.MONGO_DIRECT;
final DBCollection treatmentDb = db.getCollection("treatments");
final List<UploaderQueue> tups = UploaderQueue.getPendingbyType(Treatments.class.getSimpleName(), THIS_QUEUE);
if (tups != null) {
for (UploaderQueue up : tups) {
if ((up.action.equals("insert") || (up.action.equals("update")))) {
Treatments treatment = Treatments.byid(up.reference_id);
if (treatment != null) {
BasicDBObject record = new BasicDBObject();
record.put("timestamp", treatment.timestamp);
record.put("eventType", treatment.eventType);
record.put("enteredBy", treatment.enteredBy);
if (treatment.notes != null)
record.put("notes", treatment.notes);
record.put("uuid", treatment.uuid);
record.put("carbs", treatment.carbs);
record.put("insulin", treatment.insulin);
record.put("created_at", treatment.created_at);
final BasicDBObject searchQuery = new BasicDBObject().append("uuid", treatment.uuid);
// treatmentDb.insert(record, WriteConcern.UNACKNOWLEDGED);
Log.d(TAG, "Sending upsert for: " + treatment.toJSON());
treatmentDb.update(searchQuery, record, true, false);
} else {
Log.d(TAG, "Got null for treatment id: " + up.reference_id);
}
up.completed(THIS_QUEUE);
} else if (up.action.equals("delete")) {
if (up.reference_uuid != null) {
Log.d(TAG, "Processing treatment delete mongo sync for: " + up.reference_uuid);
final BasicDBObject searchQuery = new BasicDBObject().append("uuid", up.reference_uuid);
Log.d(TAG, treatmentDb.remove(searchQuery, WriteConcern.UNACKNOWLEDGED).toString());
}
up.completed(THIS_QUEUE);
} else {
Log.e(TAG, "Unsupported operation type for treatment: " + up.action);
}
}
Log.d(TAG, "Processed " + tups.size() + " Treatment mongo direct upload records");
}
client.close();
failurecount = 0;
return true;
} catch (Exception e) {
Log.e(TAG, "Unable to upload data to mongo " + e.getMessage());
failurecount++;
if (failurecount > 4) {
Home.toaststaticnext("Mongo " + failurecount + " up fails: " + e.getMessage().substring(0, 51));
}
} finally {
if (client != null) {
client.close();
}
}
} catch (Exception e) {
Log.e(TAG, "Unable to upload data to mongo " + e.getMessage());
}
}
return false;
}
use of com.eveningoutpost.dexdrip.Models.BgReading in project xDrip by NightscoutFoundation.
the class Notifications method createOngoingNotification.
/* private Notification createExtensionPage(long hours) {
return new NotificationCompat.Builder(mContext)
.extend(new NotificationCompat.WearableExtender()
.setBackground(createWearBitmap(hours))
.setHintShowBackgroundOnly(true)
.setHintAvoidBackgroundClipping(true)
)
.build();
}*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public synchronized Notification createOngoingNotification(BgGraphBuilder bgGraphBuilder, Context context) {
mContext = context;
ReadPerfs(mContext);
Intent intent = new Intent(mContext, Home.class);
List<BgReading> lastReadings = BgReading.latest(2);
BgReading lastReading = null;
if (lastReadings != null && lastReadings.size() >= 2) {
lastReading = lastReadings.get(0);
}
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mContext);
stackBuilder.addParentStack(Home.class);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext, NotificationChannels.ONGOING_CHANNEL);
// final NotificationCompat.Builder b = new NotificationCompat.Builder(mContext); // temporary fix until ONGOING CHANNEL is silent by default on android 8+
// temporary fix until ONGOING CHANNEL is silent by default on android 8+
final Notification.Builder b = new Notification.Builder(mContext);
// b.setOngoing(true); // TODO CHECK THIS!!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
b.setVisibility(Pref.getBooleanDefaultFalse("public_notifications") ? Notification.VISIBILITY_PUBLIC : Notification.VISIBILITY_PRIVATE);
b.setCategory(NotificationCompat.CATEGORY_STATUS);
}
if (Pref.getBooleanDefaultFalse("high_priority_notifications")) {
b.setPriority(Notification.PRIORITY_HIGH);
}
final BestGlucose.DisplayGlucose dg = (use_best_glucose) ? BestGlucose.getDisplayGlucose() : null;
// could be preference option
final boolean use_color_in_notification = false;
final SpannableString titleString = new SpannableString(lastReading == null ? "BG Reading Unavailable" : (dg != null) ? (dg.spannableString(dg.unitized + " " + dg.delta_arrow, use_color_in_notification)) : (lastReading.displayValue(mContext) + " " + lastReading.slopeArrow()));
b.setContentTitle(titleString).setContentText("xDrip Data collection service is running.").setSmallIcon(R.drawable.ic_action_communication_invert_colors_on).setUsesChronometer(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// user has a chance to disable the feature
if (SystemClock.uptimeMillis() > Constants.MINUTE_IN_MS * 15) {
if (NumberGraphic.numberIconEnabled()) {
if ((dg != null) && (!dg.isStale())) {
final Bitmap icon_bitmap = NumberGraphic.getBitmap(dg.unitized);
if (icon_bitmap != null)
b.setSmallIcon(Icon.createWithBitmap(icon_bitmap));
}
}
}
}
if (lastReading != null) {
b.setWhen(lastReading.timestamp);
final SpannableString deltaString = new SpannableString("Delta: " + ((dg != null) ? (dg.spannableString(dg.unitized_delta + (dg.from_plugin ? " " + context.getString(R.string.p_in_circle) : ""))) : bgGraphBuilder.unitizedDeltaString(true, true)));
b.setContentText(deltaString);
iconBitmap = new BgSparklineBuilder(mContext).setHeight(64).setWidth(64).setStart(System.currentTimeMillis() - 60000 * 60 * 3).setBgGraphBuilder(bgGraphBuilder).setBackgroundColor(getCol(X.color_notification_chart_background)).build();
b.setLargeIcon(iconBitmap);
Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle();
notifiationBitmap = new BgSparklineBuilder(mContext).setBgGraphBuilder(bgGraphBuilder).showHighLine().showLowLine().setStart(System.currentTimeMillis() - 60000 * 60 * 3).showAxes(true).setBackgroundColor(getCol(X.color_notification_chart_background)).setShowFiltered(DexCollectionType.hasFiltered() && Pref.getBooleanDefaultFalse("show_filtered_curve")).build();
bigPictureStyle.bigPicture(notifiationBitmap).setSummaryText(deltaString).setBigContentTitle(titleString);
b.setStyle(bigPictureStyle);
}
b.setContentIntent(resultPendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
b.setLocalOnly(true);
}
return b.build();
}
use of com.eveningoutpost.dexdrip.Models.BgReading in project xDrip by NightscoutFoundation.
the class WixelReader method setSerialDataToTransmitterRawData.
private void setSerialDataToTransmitterRawData(int raw_data, int filtered_data, int sensor_battery_leve, Long CaptureTime) {
final TransmitterData transmitterData = TransmitterData.create(raw_data, filtered_data, sensor_battery_leve, CaptureTime);
if (transmitterData != null) {
final Sensor sensor = Sensor.currentSensor();
if (sensor != null) {
BgReading bgReading = BgReading.create(transmitterData.raw_data, filtered_data, null, CaptureTime);
// sensor.latest_battery_level = (sensor.latest_battery_level!=0)?Math.min(sensor.latest_battery_level, transmitterData.sensor_battery_level):transmitterData.sensor_battery_level;
// don't lock it only going downwards
sensor.latest_battery_level = transmitterData.sensor_battery_level;
sensor.save();
} else {
Log.d(TAG, "No Active Sensor, Data only stored in Transmitter Data");
}
}
}
use of com.eveningoutpost.dexdrip.Models.BgReading in project xDrip by NightscoutFoundation.
the class Home method displayCurrentInfoFromReading.
private void displayCurrentInfoFromReading(BgReading lastBgReading, boolean predictive) {
double estimate = 0;
double estimated_delta = 0;
if (lastBgReading == null)
return;
final BestGlucose.DisplayGlucose dg = BestGlucose.getDisplayGlucose();
if (dg == null)
return;
// String slope_arrow = lastBgReading.slopeArrow();
String slope_arrow = dg.delta_arrow;
String extrastring = "";
// when stale
if ((new Date().getTime()) - stale_data_millis() - lastBgReading.timestamp > 0) {
notificationText.setText(R.string.signal_missed);
if (!predictive) {
// estimate = lastBgReading.calculated_value;
estimate = dg.mgdl;
} 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 {
// not stale
if (notificationText.getText().length() == 0) {
notificationText.setTextColor(Color.WHITE);
}
boolean bg_from_filtered = Pref.getBoolean("bg_from_filtered", false);
if (!predictive) {
// estimate = lastBgReading.calculated_value; // normal
estimate = dg.mgdl;
currentBgValueText.setTypeface(null, Typeface.NORMAL);
// if noise has settled down then switch off filtered mode
if ((bg_from_filtered) && (BgGraphBuilder.last_noise < BgGraphBuilder.NOISE_FORGIVE) && (Pref.getBoolean("bg_compensate_noise", false))) {
bg_from_filtered = false;
Pref.setBoolean("bg_from_filtered", false);
}
// TODO this should be partially already be covered by dg - recheck
if (BestGlucose.compensateNoise()) {
// this maybe needs scaling based on noise intensity
estimate = BgGraphBuilder.best_bg_estimate;
estimated_delta = BgGraphBuilder.best_bg_estimate - BgGraphBuilder.last_bg_estimate;
// delta by minute
slope_arrow = BgReading.slopeToArrowSymbol(estimated_delta / (BgGraphBuilder.DEXCOM_PERIOD / 60000));
currentBgValueText.setTypeface(null, Typeface.ITALIC);
// warning symbol !
extrastring = "\u26A0";
if ((BgGraphBuilder.last_noise > BgGraphBuilder.NOISE_HIGH) && (DexCollectionType.hasFiltered())) {
// force filtered mode
bg_from_filtered = true;
}
}
if (bg_from_filtered) {
currentBgValueText.setPaintFlags(currentBgValueText.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
estimate = lastBgReading.filtered_calculated_value;
} else {
currentBgValueText.setPaintFlags(currentBgValueText.getPaintFlags() & ~Paint.UNDERLINE_TEXT_FLAG);
}
String stringEstimate = bgGraphBuilder.unitized_string(estimate);
if ((lastBgReading.hide_slope) || (bg_from_filtered)) {
slope_arrow = "";
}
currentBgValueText.setText(stringEstimate + " " + slope_arrow);
} else {
// old depreciated prediction
estimate = BgReading.activePrediction();
String stringEstimate = bgGraphBuilder.unitized_string(estimate);
currentBgValueText.setText(stringEstimate + " " + BgReading.activeSlopeArrow());
}
if (extrastring.length() > 0)
currentBgValueText.setText(extrastring + currentBgValueText.getText());
}
int minutes = (int) (System.currentTimeMillis() - lastBgReading.timestamp) / (60 * 1000);
if ((!small_width) || (notificationText.length() > 0))
notificationText.append("\n");
if (!small_width) {
notificationText.append(minutes + ((minutes == 1) ? getString(R.string.space_minute_ago) : getString(R.string.space_minutes_ago)));
} else {
// small screen
notificationText.append(minutes + getString(R.string.space_mins));
currentBgValueText.setPadding(0, 0, 0, 0);
}
if (small_screen) {
if (currentBgValueText.getText().length() > 4)
currentBgValueText.setTextSize(25);
}
// do we actually need to do this query here if we again do it in unitizedDeltaString
List<BgReading> bgReadingList = BgReading.latest(2, is_follower);
if (bgReadingList != null && bgReadingList.size() == 2) {
// same logic as in xDripWidget (refactor that to BGReadings to avoid redundancy / later inconsistencies)?
// display_delta = bgGraphBuilder.unitizedDeltaString(true, true, is_follower);
display_delta = dg.unitized_delta;
if (BestGlucose.compensateNoise()) {
// final double estimated_delta = BgGraphBuilder.best_bg_estimate - BgGraphBuilder.last_bg_estimate;
display_delta = bgGraphBuilder.unitizedDeltaStringRaw(true, true, estimated_delta);
addDisplayDelta();
if (!Pref.getBoolean("show_noise_workings", false)) {
notificationText.append("\nNoise: " + bgGraphBuilder.noiseString(BgGraphBuilder.last_noise));
}
} else {
addDisplayDelta();
}
}
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);
}
// TODO this should be made more efficient probably
if (Pref.getBooleanDefaultFalse("display_glucose_from_plugin") && (PluggableCalibration.getCalibrationPluginFromPreferences() != null)) {
// adds warning P in circle icon
currentBgValueText.setText(getString(R.string.p_in_circle) + currentBgValueText.getText());
}
}
use of com.eveningoutpost.dexdrip.Models.BgReading in project xDrip by NightscoutFoundation.
the class CustomComplicationProviderService method onComplicationUpdate.
/*
* Called when the complication needs updated data from your provider. There are four scenarios
* when this will happen:
*
* 1. An active watch face complication is changed to use this provider
* 2. A complication using this provider becomes active
* 3. The period of time you specified in the manifest has elapsed (UPDATE_PERIOD_SECONDS)
* 4. You triggered an update from your own class via the
* ProviderUpdateRequester.requestUpdate() method.
*/
@Override
public void onComplicationUpdate(int complicationId, int dataType, ComplicationManager complicationManager) {
Log.d(TAG, "onComplicationUpdate() id: " + complicationId);
// Create Tap Action so that the user can trigger an update by tapping the complication.
final ComponentName thisProvider = new ComponentName(this, getClass());
// We pass the complication id, so we can only update the specific complication tapped.
final PendingIntent complicationPendingIntent = ComplicationTapBroadcastReceiver.getToggleIntent(this, thisProvider, complicationId);
String numberText = "";
BgReading bgReading = BgReading.last(false);
if ((bgReading == null) || (JoH.msSince(bgReading.timestamp) >= FRESH_MS)) {
try {
// we may be in another process!
ActiveAndroid.clearCache();
} catch (Exception e) {
Log.d(TAG, "Couldn't clear cache: " + e);
}
bgReading = BgReading.last(false);
}
boolean is_stale = false;
if (bgReading == null) {
numberText = "null";
} else {
if (JoH.msSince(bgReading.timestamp) < STALE_MS) {
numberText = bgReading.displayValue(this) + " " + bgReading.displaySlopeArrow();
} else {
numberText = "old " + niceTimeSinceBgReading(bgReading);
is_stale = true;
}
}
Log.d(TAG, "Returning complication text: " + numberText);
COMPLICATION_STATE state = COMPLICATION_STATE.get_enum((int) PersistentStore.getLong(ComplicationTapBroadcastReceiver.COMPLICATION_STORE));
if (state == null)
state = COMPLICATION_STATE.DELTA;
ComplicationData complicationData = null;
switch(dataType) {
case ComplicationData.TYPE_SHORT_TEXT:
final ComplicationData.Builder builder = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT).setShortText(ComplicationText.plainText(numberText)).setTapAction(complicationPendingIntent);
UserError.Log.d(TAG, "TYPE_SHORT_TEXT Current complication state:" + state);
switch(state) {
case DELTA:
builder.setShortTitle(ComplicationText.plainText(getDeltaText(bgReading, is_stale)));
break;
case AGO:
builder.setShortTitle(ComplicationText.plainText(niceTimeSinceBgReading(bgReading)));
break;
default:
builder.setShortTitle(ComplicationText.plainText("ERR!"));
}
complicationData = builder.build();
break;
case ComplicationData.TYPE_LONG_TEXT:
String numberTextLong = numberText + " " + getDeltaText(bgReading, is_stale) + " (" + niceTimeSinceBgReading(bgReading) + ")";
Log.d(TAG, "Returning complication text Long: " + numberTextLong);
// Loop status by @gregorybel
String externalStatusString = PersistentStore.getString("remote-status-string");
Log.d(TAG, "Returning complication status: " + externalStatusString);
final ComplicationData.Builder builderLong = new ComplicationData.Builder(ComplicationData.TYPE_LONG_TEXT).setLongTitle(ComplicationText.plainText(numberTextLong)).setLongText(ComplicationText.plainText(externalStatusString)).setTapAction(complicationPendingIntent);
UserError.Log.d(TAG, "TYPE_LONG_TEXT Current complication state:" + state);
complicationData = builderLong.build();
break;
default:
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Unexpected complication type " + dataType);
}
}
if (complicationData != null) {
complicationManager.updateComplicationData(complicationId, complicationData);
} else {
// If no data is sent, we still need to inform the ComplicationManager, so the update
// job can finish and the wake lock isn't held any longer than necessary.
complicationManager.noUpdateRequired(complicationId);
}
}
Aggregations