From 6e025a3ca262a67a0f988830117a2f00e8ba7aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Beloncle?= Date: Mon, 19 Feb 2018 21:42:46 +0100 Subject: [PATCH 1/2] merge master (#5) * include bluereader basis * include bluereader basis * include bluereader basis * Repair Speak trend, and add translation (initial en/de) * Add Bridge_battery upload Nightscout toright bridge name * correct typo double down * correct minor differeces to master origin * correct wrong import class * Correct Spacing and lining changes to be in sync with origin * Correct speak bug (switch from mol to everytime) Include Translation for trend Include translation for Speak settings * Correct speak bug (switch from mol to everytime) Include Translation for trend Include translation for Speak settings * Translation Croatian v1.0 * Update locales.xml * Follower and MDNS fixes * isCollecting() proguard exclusion * WebServices: Add status.json endpoint and sgv brief mode * BluetoothScan: Concurrent modification race condition fix * ActivityRecognizedService: concurrency fix * Add code to receive more data and close the gaps. Signed-off-by: Tzachi Dar * Use existing code to close per 5 minutes gaps. Signed-off-by: Tzachi Dar * Multiply the "raw data" by 1000 and devide it by Constants.LIBRE_MULTIPLIER to make it feet the normal behavior. Signed-off-by: Tzachi Dar * Simple fill the 10 minutes gap, by adding the last point to the interpolation graph. Signed-off-by: Tzachi Dar * Receive an array of results instead of one result only. Signed-off-by: Tzachi Dar * Disable external_blukon_algorithm to allow more testing. Signed-off-by: Tzachi Dar * undo unneeded changes * LicenseAgreementActivity: fix null pointer exception * ImportDatabaseActivity: fix null pointer exception * Nightscout: Extra de-duplication and activity endpoint initial support * WebServices: sgv endpoint add count= parameter --- Documentation/technical/Local_Web_Services.md | 14 + app/proguard-rules.pro | 1 + .../eveningoutpost/dexdrip/BluetoothScan.java | 3 +- .../java/com/eveningoutpost/dexdrip/Home.java | 9 + .../dexdrip/ImportDatabaseActivity.java | 8 +- .../dexdrip/LibreAlarmReceiver.java | 10 +- .../dexdrip/LicenseAgreementActivity.java | 22 +- .../dexdrip/Models/BgReading.java | 12 +- .../eveningoutpost/dexdrip/Models/JoH.java | 9 + .../dexdrip/Models/LibreOOPAlgorithm.java | 115 ++- .../dexdrip/Models/OOPResults.java | 28 + .../dexdrip/Models/Treatments.java | 2 +- .../dexdrip/NSEmulatorReceiver.java | 58 +- .../Services/ActivityRecognizedService.java | 22 +- .../Services/DexCollectionService.java | 1 + .../UtilityModels/NightscoutUploader.java | 261 +++++- .../dexdrip/dagger/Singleton.java | 4 + .../dexdrip/utils/BgToSpeech.java | 15 +- .../eveningoutpost/dexdrip/utils/Mdns.java | 6 +- .../dexdrip/webservices/RouteFinder.java | 3 + .../dexdrip/webservices/WebServiceModule.java | 8 + .../dexdrip/webservices/WebServiceSgv.java | 38 +- .../dexdrip/webservices/WebServiceStatus.java | 46 + app/src/main/res/values-de/strings-de.xml | 13 + app/src/main/res/values-es/strings-es.xml | 7 + app/src/main/res/values-hr/strings-hr.xml | 827 ++++++++++++++++++ app/src/main/res/values-it/strings-it.xml | 7 + app/src/main/res/values/locales.xml | 4 +- app/src/main/res/values/strings.xml | 20 +- .../main/res/xml/pref_advanced_settings.xml | 20 +- 30 files changed, 1487 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/com/eveningoutpost/dexdrip/Models/OOPResults.java create mode 100644 app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceStatus.java create mode 100644 app/src/main/res/values-hr/strings-hr.xml diff --git a/Documentation/technical/Local_Web_Services.md b/Documentation/technical/Local_Web_Services.md index 2dc634545d..27fbf9f381 100644 --- a/Documentation/technical/Local_Web_Services.md +++ b/Documentation/technical/Local_Web_Services.md @@ -35,6 +35,8 @@ You can combine both like a normal query string: http://127.0.0.1:17580/sgv.json?steps=1234&heart=123 +There is another option `brief_mode=Y` which you can use to exclude some of the data fields from the results to reduce response size. + You can also access the tasker endpoint by appending a query parameter http://127.0.0.1:17580/sgv.json?tasker=osnooze @@ -45,6 +47,18 @@ look for `tasker_result` in the first line of the json reply to indicate success `SNOOZE` is the traditional tasker snooze which will send snooze to followers and uses more cpu +### status.json endpoint + +This implements a small subset of the data you might receive from Nightscouts status.json + + http://127.0.0.1:17580/status.json + +Results look like: + + {"thresholds":{"bgHigh":9.4,"bgLow":3.9}} + +High and low marks set within the app represented in the local units. + ### Tasker endpoint The `/tasker` endpoint lets you push requests to the tasker interface via http. So a watch face which can only support web based endpoints (eg FitBit) could send a snooze request as below: diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 2b62c24eb1..2a303adcf7 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -99,6 +99,7 @@ -keepclassmembers class com.eveningoutpost.dexdrip.** { public static boolean isRunning(); + public static boolean isCollecting(); } -dontnote rx.internal.util.PlatformDependent diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/BluetoothScan.java b/app/src/main/java/com/eveningoutpost/dexdrip/BluetoothScan.java index f5b6e3e77d..a21efa9821 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/BluetoothScan.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/BluetoothScan.java @@ -224,7 +224,8 @@ public void onScanResult(int callbackType, final ScanResult result) { runOnUiThread(new Runnable() { @Override public void run() { - if (device.getName() != null && device.getName().length() > 0) { + final String deviceName = device.getName(); + if (deviceName != null && deviceName.length() > 0) { mLeDeviceListAdapter.addDevice(device); try { if (result.getScanRecord() != null) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Home.java b/app/src/main/java/com/eveningoutpost/dexdrip/Home.java index c9f2d55cc8..bb98f1ed08 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Home.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Home.java @@ -1323,6 +1323,15 @@ private void naturalLanguageRecognition(String allWords) { } else if (get_engineering_mode() && allWords.contentEquals("enable fake data source")) { Pref.setString(DexCollectionType.DEX_COLLECTION_METHOD, DexCollectionType.Mock.toString()); JoH.static_toast_long("YOU ARE NOW USING FAKE DATA!!!"); + } else if (allWords.contentEquals("reset heart rate sync")) { + PersistentStore.setLong("nightscout-rest-heartrate-synced-time",0); + JoH.static_toast_long("Cleared heart rate sync data"); + } else if (allWords.contentEquals("reset step count sync")) { + PersistentStore.setLong("nightscout-rest-steps-synced-time",0); + JoH.static_toast_long("Cleared step count sync data"); + } else if (allWords.contentEquals("reset motion count sync")) { + PersistentStore.setLong("nightscout-rest-motion-synced-time",0); + JoH.static_toast_long("Cleared motion count sync data"); } else if (allWords.contentEquals("vehicle mode test")) { ActivityRecognizedService.spoofActivityRecogniser(mActivity, JoH.tsl() + "^" + 0); staticRefreshBGCharts(); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java index e2a190cc68..77acebf7bc 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/ImportDatabaseActivity.java @@ -125,8 +125,12 @@ public boolean accept(File path) { return path.isDirectory(); } }); - for (File subdirectory : subdirectories) { - addAllDatabases(subdirectory, databases); + try { + for (File subdirectory : subdirectories) { + addAllDatabases(subdirectory, databases); + } + } catch (NullPointerException e) { + // nothing found } return true; } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/LibreAlarmReceiver.java b/app/src/main/java/com/eveningoutpost/dexdrip/LibreAlarmReceiver.java index 6a6123da5b..46067f1c9c 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/LibreAlarmReceiver.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/LibreAlarmReceiver.java @@ -42,8 +42,8 @@ public class LibreAlarmReceiver extends BroadcastReceiver { private static final String TAG = "jamorham librereceiver"; private static final boolean debug = false; - private static final boolean d = false; - private static final boolean use_raw = true; + private static final boolean d = true; + private static final boolean use_raw_ = true; private static final double segmentation_timeslice = Constants.MINUTE_IN_MS * 4.5; private static SharedPreferences prefs; private static long oldest = -1; @@ -185,6 +185,10 @@ public static void processReadingDataTransferObject(ReadingData.TransferObject o LibreOOPAlgorithm.SendData(object.data.raw_data); return; } + CalculateFromDataTransferObject(object, use_raw_); + } + + public static void CalculateFromDataTransferObject(ReadingData.TransferObject object, boolean use_raw) { // insert any recent data we can final List mTrend = object.data.trend; @@ -244,7 +248,7 @@ public static void processReadingDataTransferObject(ReadingData.TransferObject o final List polyyList = new ArrayList(); for (GlucoseData gd : mHistory) { if (d) - Log.d(TAG, "history : " + JoH.dateTimeText(gd.realDate) + " " + gd.glucose(true)); + Log.d(TAG, "history : " + JoH.dateTimeText(gd.realDate) + " " + gd.glucose(false)); polyxList.add((double) gd.realDate); if (use_raw) { polyyList.add((double) gd.glucoseLevelRaw); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/LicenseAgreementActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/LicenseAgreementActivity.java index 17bff0e0f4..88bc7ec60d 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/LicenseAgreementActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/LicenseAgreementActivity.java @@ -13,7 +13,6 @@ import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.UserError; -import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; @@ -30,13 +29,20 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); IUnderstand = prefs.getBoolean("I_understand", false); - setContentView(R.layout.activity_license_agreement); - JoH.fixActionBar(this); - findViewById(R.id.googlelicenses).setAlpha(0.5f); - agreeCheckBox = (CheckBox) findViewById(R.id.agreeCheckBox); - agreeCheckBox.setChecked(IUnderstand); - saveButton = (Button) findViewById(R.id.saveButton); - addListenerOnButton(); + try { + setContentView(R.layout.activity_license_agreement); + + JoH.fixActionBar(this); + findViewById(R.id.googlelicenses).setAlpha(0.5f); + agreeCheckBox = (CheckBox) findViewById(R.id.agreeCheckBox); + agreeCheckBox.setChecked(IUnderstand); + saveButton = (Button) findViewById(R.id.saveButton); + addListenerOnButton(); + + } catch (UnsupportedOperationException e) { + JoH.static_toast_long("Unable to display license agreement? blocked by user? Cannot continue"); + finish(); + } /* try { final int gplaystatus = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext()); if (gplaystatus != ConnectionResult.SUCCESS) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java index e5d8f49a13..9cd164558a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/BgReading.java @@ -1057,11 +1057,19 @@ public static void bgReadingInsertFromInt(int value, long timestamp, boolean do_ bgr.timestamp = timestamp; bgr.calculated_value = value; + // rough code for testing! bgr.filtered_calculated_value = value; - bgr.raw_data = value*1000; - bgr.filtered_data = value*1000; + bgr.raw_data = value; + bgr.age_adjusted_raw_value = value; + bgr.filtered_data = value; + + final Sensor forced_sensor = Sensor.currentSensor(); + if (forced_sensor != null) { + bgr.sensor = forced_sensor; + bgr.sensor_uuid = forced_sensor.uuid; + } try { if (readingNearTimeStamp(bgr.timestamp) == null) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java index be8fce5abe..e6cf480717 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java @@ -73,6 +73,8 @@ import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.net.URLEncoder; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -1369,4 +1371,11 @@ public static int parseIntWithDefault(String number, int radix, int defaultVal) return defaultVal; } } + + public static double roundDouble(double value, int places) { + if (places < 0) throw new IllegalArgumentException("Invalid decimal places"); + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/LibreOOPAlgorithm.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/LibreOOPAlgorithm.java index 7da53e8973..0d5038d965 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/LibreOOPAlgorithm.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/LibreOOPAlgorithm.java @@ -3,32 +3,46 @@ import android.content.Intent; import android.os.Bundle; +import com.eveningoutpost.dexdrip.LibreAlarmReceiver; +import com.eveningoutpost.dexdrip.NSEmulatorReceiver; import com.eveningoutpost.dexdrip.xdrip; import com.eveningoutpost.dexdrip.ImportedLibraries.usbserial.util.HexDump; import com.eveningoutpost.dexdrip.Models.UserError.Log; +import com.eveningoutpost.dexdrip.Services.TransmitterRawData; +import com.eveningoutpost.dexdrip.UtilityModels.Constants; import com.eveningoutpost.dexdrip.UtilityModels.Intents; +import com.eveningoutpost.dexdrip.UtilityModels.MockDataSource; +import com.eveningoutpost.dexdrip.UtilityModels.Pref; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import static com.eveningoutpost.dexdrip.Models.BgReading.bgReadingInsertFromJson; + +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; + +import org.json.JSONException; public class LibreOOPAlgorithm { - private static final String TAG = "LibreOOPAlgorithm"; - + private static final String TAG = "LibreOOPAlgorithm"; + static public void SendData(byte[] fullData) { - if(fullData == null) { - Log.e(TAG, "SendData called with null data"); - return; - } - - if(fullData.length < 344) { - Log.e(TAG, "SendData called with data size too small. " + fullData.length); - return; - } - Log.i(TAG, "Sending full data to OOP Algorithm data-len = " + fullData.length); - - fullData = java.util.Arrays.copyOfRange(fullData, 0, 0x158); - Log.i(TAG, "Data that will be sent is " + HexDump.dumpHexString(fullData)); - - Intent intent = new Intent(Intents.XDRIP_PLUS_LIBRE_DATA); + if(fullData == null) { + Log.e(TAG, "SendData called with null data"); + return; + } + + if(fullData.length < 344) { + Log.e(TAG, "SendData called with data size too small. " + fullData.length); + return; + } + Log.i(TAG, "Sending full data to OOP Algorithm data-len = " + fullData.length); + + fullData = java.util.Arrays.copyOfRange(fullData, 0, 0x158); + Log.i(TAG, "Data that will be sent is " + HexDump.dumpHexString(fullData)); + + Intent intent = new Intent(Intents.XDRIP_PLUS_LIBRE_DATA); Bundle bundle = new Bundle(); bundle.putByteArray(Intents.LIBRE_DATA_BUFFER, fullData); bundle.putLong(Intents.LIBRE_DATA_TIMESTAMP, JoH.tsl()); @@ -38,4 +52,71 @@ static public void SendData(byte[] fullData) { } + static public void HandleData(String oopData) { + Log.e(TAG, "HandleData called with " + oopData); + OOPResults oOPResults = null; + try { + final Gson gson = new GsonBuilder().create(); + OOPResults []oOPResultsArray = null; + oOPResultsArray = gson.fromJson(oopData, OOPResults[].class); + if(oOPResultsArray.length > 0) { + oOPResults = oOPResultsArray[0]; + } else { + Log.e(TAG, "oOPResultsArray exists, but size is zero"); + return; + } + } catch (Exception e) { //TODO: what exception should we catch here. + Log.e(TAG, "HandleData cought exception ", e); + return; + } + boolean use_raw = Pref.getBooleanDefaultFalse("calibrate_external_libre_algorithm"); + ReadingData.TransferObject libreAlarmObject = new ReadingData.TransferObject(); + libreAlarmObject.data = new ReadingData(); + libreAlarmObject.data.trend = new ArrayList(); + + double factor = 1; + if(use_raw) { + // When handeling raw, data is expected to be bigger in a factor of 1000 and + // is then devided by Constants.LIBRE_MULTIPLIER + factor = 1000 / Constants.LIBRE_MULTIPLIER; + } + + // Add the first object, that is the current time + GlucoseData glucoseData = new GlucoseData(); + glucoseData.sensorTime = oOPResults.currentTime; + glucoseData.realDate = oOPResults.timestamp; + glucoseData.glucoseLevel = (int)(oOPResults.currentBg * factor); + glucoseData.glucoseLevelRaw = (int)(oOPResults.currentBg * factor); + + libreAlarmObject.data.trend.add(glucoseData); + + // TODO: Add here data of last 10 minutes or whatever. + + + // Add the historic data + libreAlarmObject.data.history = new ArrayList(); + for(HistoricBg historicBg : oOPResults.historicBg) { + if(historicBg.quality == 0) { + glucoseData = new GlucoseData(); + glucoseData.realDate = oOPResults.timestamp + (historicBg.time - oOPResults.currentTime) * 60000; + glucoseData.glucoseLevel = (int)(historicBg.bg * factor); + glucoseData.glucoseLevelRaw = (int)(historicBg.bg * factor); + libreAlarmObject.data.history.add(glucoseData); + } + } + + // Add the current point again. This is needed in order to have the last gaps closed. + // TODO: Base this on real BG values. + glucoseData = new GlucoseData(); + glucoseData.realDate = oOPResults.timestamp; + glucoseData.glucoseLevel = (int)(oOPResults.currentBg * factor); + glucoseData.glucoseLevelRaw = (int)(oOPResults.currentBg * factor); + libreAlarmObject.data.history.add(glucoseData); + + + + Log.e(TAG, "HandleData Created the following object " + libreAlarmObject.toString()); + LibreAlarmReceiver.CalculateFromDataTransferObject(libreAlarmObject, use_raw); + + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/OOPResults.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/OOPResults.java new file mode 100644 index 0000000000..ddeff2e7ae --- /dev/null +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/OOPResults.java @@ -0,0 +1,28 @@ +package com.eveningoutpost.dexdrip.Models; + + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.List; + +class HistoricBg { + + public int quality; + public int time; + public double bg; +} + +public class OOPResults { + double currentBg; + int currentTime; + int currenTrend; + HistoricBg [] historicBg; + long timestamp; + String serialNumber; + + String toGson() { + Gson gson = new GsonBuilder().create(); + return gson.toJson(this); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Models/Treatments.java b/app/src/main/java/com/eveningoutpost/dexdrip/Models/Treatments.java index e4e04bc617..444bea6198 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Models/Treatments.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Models/Treatments.java @@ -409,7 +409,7 @@ public static synchronized boolean pushTreatmentFromJson(String json, boolean fr Log.d(TAG, "Skipping AndroidAPS started message"); return false; } - if (mytreatment.eventType.equals("Temp Basal")) { + if ((mytreatment.eventType != null) && (mytreatment.eventType.equals("Temp Basal"))) { // we don't yet parse or process these Log.d(TAG, "Skipping Temp Basal msg"); return false; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/NSEmulatorReceiver.java b/app/src/main/java/com/eveningoutpost/dexdrip/NSEmulatorReceiver.java index 41e77c2bd9..2b460f8dee 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/NSEmulatorReceiver.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/NSEmulatorReceiver.java @@ -10,6 +10,7 @@ import android.preference.PreferenceManager; import com.eveningoutpost.dexdrip.Models.JoH; +import com.eveningoutpost.dexdrip.Models.LibreOOPAlgorithm; import com.eveningoutpost.dexdrip.Models.Sensor; import com.eveningoutpost.dexdrip.Models.UserError.Log; import com.eveningoutpost.dexdrip.UtilityModels.Intents; @@ -100,26 +101,19 @@ public void run() { if ((data != null) && (data.length() > 0)) { try { final JSONArray json_array = new JSONArray(data); - final JSONObject json_object = json_array.getJSONObject(0); - final String type = json_object.getString("type"); - switch (type) { - case "sgv": - JSONObject faux_bgr = new JSONObject(); - faux_bgr.put("timestamp", json_object.getLong("date")); - faux_bgr.put("calculated_value", json_object.getDouble("sgv")); - faux_bgr.put("filtered_calculated_value", json_object.getDouble("sgv")); - // sanity checking??? - // fake up some extra data - faux_bgr.put("raw_data", json_object.getDouble("sgv")); - faux_bgr.put("age_adjusted_raw_value", json_object.getDouble("sgv")); - faux_bgr.put("filtered_data", json_object.getDouble("sgv")); - faux_bgr.put("uuid", UUID.randomUUID().toString()); - - Log.d(TAG, "Received NSEmulator SGV: " + faux_bgr); - bgReadingInsertFromJson(faux_bgr.toString(), true, true); // notify and force sensor - break; - default: - Log.e(TAG, "Unknown entries type: " + type); + if(json_array.length() >= 1) { + LibreOOPAlgorithm.HandleData(json_array.getString(1)); + } else { + final JSONObject json_object = json_array.getJSONObject(0); + final String type = json_object.getString("type"); + switch (type) { + case "sgv": + bgReadingInsertFromData(json_object.getLong("date"), json_object.getDouble("sgv"), true); + + break; + default: + Log.e(TAG, "Unknown entries type: " + type); + } } @@ -194,5 +188,27 @@ public void run() { } }.start(); } - + static public void bgReadingInsertFromData(long timestamp, double sgv, boolean do_notification) { + Log.e(TAG, "bgReadingInsertFromData called timestamp = " + timestamp+ " bg = " + sgv + " time =" + JoH.dateTimeText(timestamp)); + JSONObject faux_bgr = new JSONObject(); + try { + faux_bgr.put("timestamp", timestamp); + faux_bgr.put("calculated_value", sgv); + faux_bgr.put("filtered_calculated_value", sgv); + // sanity checking??? + // fake up some extra data + faux_bgr.put("raw_data", sgv); + faux_bgr.put("age_adjusted_raw_value", sgv); + faux_bgr.put("filtered_data", sgv); + + faux_bgr.put("uuid", UUID.randomUUID().toString()); + } catch (JSONException e) { + // TODO Auto-generated catch block + Log.e(TAG, "Got JSON exception: " + e); + return; + } + + Log.d(TAG, "Received NSEmulator SGV: " + faux_bgr); + bgReadingInsertFromJson(faux_bgr.toString(), do_notification, true); // notify and force sensor + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/ActivityRecognizedService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/ActivityRecognizedService.java index aa71ccd2bd..ac253f36e8 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/ActivityRecognizedService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/ActivityRecognizedService.java @@ -14,6 +14,7 @@ import android.support.v4.app.NotificationManagerCompat; import android.support.v7.app.NotificationCompat; import android.util.Log; +import android.util.SparseArray; import com.eveningoutpost.dexdrip.ErrorsActivity; import com.eveningoutpost.dexdrip.GcmActivity; @@ -419,7 +420,7 @@ private synchronized void requestUpdates(int frequency) { } } - private void stopUpdates() { + private synchronized void stopUpdates() { try { if (d) Log.d(TAG, "stopUpdates called"); ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mApiClient, get_pending_intent()); @@ -703,6 +704,20 @@ protected static class motionDataWrapper { } public static class motionData { + + private static final SparseArray classification = new SparseArray<>(); + + static { + classification.put(DetectedActivity.IN_VEHICLE, "in vehicle"); + classification.put(DetectedActivity.ON_BICYCLE, "on bicycle"); + classification.put(DetectedActivity.ON_FOOT, "on foot"); + classification.put(DetectedActivity.RUNNING, "running"); + classification.put(DetectedActivity.STILL, "still"); + classification.put(DetectedActivity.TILTING, "tilting"); + classification.put(DetectedActivity.UNKNOWN, "unknown"); + classification.put(DetectedActivity.WALKING, "walking"); + } + @Expose public long timestamp; @Expose @@ -713,5 +728,10 @@ public motionData(long timestamp, int activity) { this.activity = activity; } + public String toPrettyType() { + final String value = classification.get(this.activity); + return value != null ? value : "unclassified " + activity; + } + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/DexCollectionService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/DexCollectionService.java index ebe8491c57..e7627cf1ca 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/DexCollectionService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/DexCollectionService.java @@ -288,6 +288,7 @@ public void onDestroy() { Log.i(TAG, "SERVICE STOPPED"); } + // remember needs proguard exclusion due to access by reflection public static boolean isCollecting() { if (static_use_blukon) { return Blukon.isCollecting(); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NightscoutUploader.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NightscoutUploader.java index d36a399751..df704fac65 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NightscoutUploader.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NightscoutUploader.java @@ -15,10 +15,13 @@ import com.eveningoutpost.dexdrip.Models.BloodTest; import com.eveningoutpost.dexdrip.Models.Calibration; import com.eveningoutpost.dexdrip.Models.DateUtil; +import com.eveningoutpost.dexdrip.Models.HeartRate; import com.eveningoutpost.dexdrip.Models.JoH; +import com.eveningoutpost.dexdrip.Models.StepCounter; import com.eveningoutpost.dexdrip.Models.Treatments; import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.Models.UserError.Log; +import com.eveningoutpost.dexdrip.Services.ActivityRecognizedService; import com.eveningoutpost.dexdrip.utils.CipherUtils; import com.eveningoutpost.dexdrip.utils.DexCollectionType; import com.eveningoutpost.dexdrip.xdrip; @@ -30,8 +33,10 @@ import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.WriteConcern; +import com.squareup.okhttp.Interceptor; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.ResponseBody; @@ -54,6 +59,9 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; +import okio.BufferedSink; +import okio.GzipSink; +import okio.Okio; import retrofit.Call; import retrofit.Response; import retrofit.Retrofit; @@ -82,6 +90,7 @@ public class NightscoutUploader { private static final int SOCKET_TIMEOUT = 60000; private static final int CONNECTION_TIMEOUT = 30000; private static final boolean d = false; + private static final boolean USE_GZIP = true; public static long last_success_time = -1; public static long last_exception_time = -1; @@ -136,6 +145,9 @@ public interface NightscoutService { @DELETE("treatments/{id}") Call deleteTreatment(@Header("api-secret") String secret, @Path("id") String id); + @POST("activity") + Call uploadActivity(@Header("api-secret") String secret, @Body RequestBody body); + } private class UploaderException extends RuntimeException { @@ -151,6 +163,7 @@ public NightscoutUploader(Context context) { mContext = context; prefs = PreferenceManager.getDefaultSharedPreferences(mContext); client = new OkHttpClient(); + if (USE_GZIP) client.interceptors().add(new GzipRequestInterceptor()); client.setConnectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); client.setWriteTimeout(SOCKET_TIMEOUT, TimeUnit.MILLISECONDS); client.setReadTimeout(SOCKET_TIMEOUT, TimeUnit.MILLISECONDS); @@ -448,33 +461,43 @@ private synchronized boolean doRESTtreatmentDownload(SharedPreferences prefs) { if (existing == null) existing = Treatments.byuuid(uuid); if ((existing == null) && (!from_xdrip)) { - // TODO check for close timestamp duplicates perhaps - Log.ueh(TAG, "New Treatment from Nightscout: Carbs: " + carbs + " Insulin: " + insulin + " timestamp: " + JoH.dateTimeText(timestamp) + ((notes != null) ? " Note: "+notes : "")); - final Treatments t; - if ((carbs > 0) || (insulin > 0)) { - t = Treatments.create(carbs, insulin, timestamp, nightscout_id); - if (notes != null) t.notes = notes; - } else { - t = Treatments.create_note(notes, timestamp, -1, nightscout_id); - if (t == null) { - Log.d(TAG, "Create note baulked and returned null, so skipping"); - bad_uuids.add(nightscout_id); - continue; + // check for close timestamp duplicates perhaps + existing = Treatments.byTimestamp(timestamp, 60000); + if (!((existing != null) && (JoH.roundDouble(existing.insulin, 2) == JoH.roundDouble(insulin, 2)) + && (JoH.roundDouble(existing.carbs, 2) == JoH.roundDouble(carbs, 2)) + && ((existing.notes == null && notes == null) || ((existing.notes != null) && existing.notes.equals(notes != null ? notes : ""))))) + { + + Log.ueh(TAG, "New Treatment from Nightscout: Carbs: " + carbs + " Insulin: " + insulin + " timestamp: " + JoH.dateTimeText(timestamp) + ((notes != null) ? " Note: " + notes : "")); + final Treatments t; + if ((carbs > 0) || (insulin > 0)) { + t = Treatments.create(carbs, insulin, timestamp, nightscout_id); + if (notes != null) t.notes = notes; + } else { + t = Treatments.create_note(notes, timestamp, -1, nightscout_id); + if (t == null) { + Log.d(TAG, "Create note baulked and returned null, so skipping"); + bad_uuids.add(nightscout_id); + continue; + } } - } - //t.uuid = nightscout_id; // replace with nightscout uuid - try { - t.enteredBy = tr.getString("enteredBy") + " " + VIA_NIGHTSCOUT_TAG; - } catch (JSONException e) { - t.enteredBy = VIA_NIGHTSCOUT_TAG; - } + //t.uuid = nightscout_id; // replace with nightscout uuid + try { + t.enteredBy = tr.getString("enteredBy") + " " + VIA_NIGHTSCOUT_TAG; + } catch (JSONException e) { + t.enteredBy = VIA_NIGHTSCOUT_TAG; + } - t.save(); - // sync again! - // pushTreatmentSync(t, false); - if (Home.get_show_wear_treatments()) pushTreatmentSyncToWatch(t, true); - new_data = true; + t.save(); + // sync again! + // pushTreatmentSync(t, false); + if (Home.get_show_wear_treatments()) + pushTreatmentSyncToWatch(t, true); + new_data = true; + } else { + Log.e(TAG, "Skipping treatment as it appears identical to one we already have: " + JoH.dateTimeText(timestamp) + " " + insulin + " " + carbs + " " + notes); + } } else { if (existing != null) { if (d) @@ -642,6 +665,17 @@ private void doRESTUploadTo(NightscoutService nightscoutService, String secret, handleRestFailure(msg); } } + // TODO we may want to check nightscout version before trying to upload!! + // TODO in the future we may want to merge these in to a single post + if (Pref.getBooleanDefaultFalse("use_pebble_health") && (Home.get_engineering_mode())) { + try { + postHeartRate(nightscoutService, secret); + postStepsCount(nightscoutService, secret); + postMotionTracking(nightscoutService, secret); + } catch (Exception e) { + Log.e(TAG, "Exception uploading REST API heartrate: " + e.getMessage()); + } + } } private static synchronized void handleRestFailure(String msg) { @@ -916,6 +950,152 @@ private void postTreatments(NightscoutService nightscoutService, String apiSecre } } + private static int activityErrorCount = 0; + private static final int MAX_ACTIVITY_RECORDS = 500; + + private void postHeartRate(NightscoutService nightscoutService, String apiSecret) throws Exception { + Log.d(TAG, "Processing heartrate for RESTAPI"); + if (apiSecret != null) { + final String STORE_COUNTER = "nightscout-rest-heartrate-synced-time"; + final long syncedTillTime = Math.max(PersistentStore.getLong(STORE_COUNTER), JoH.tsl() - Constants.DAY_IN_MS * 7); + final List readings = HeartRate.latestForGraph((MAX_ACTIVITY_RECORDS / Math.min(1, Math.max(activityErrorCount, MAX_ACTIVITY_RECORDS / 10))), syncedTillTime); + final JSONArray data = new JSONArray(); + //final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US); + //format.setTimeZone(TimeZone.getDefault()); + long highest_timestamp = 0; + if (readings.size() > 0) { + for (HeartRate reading : readings) { + final JSONObject json = new JSONObject(); + json.put("type", "hr-bpm"); + json.put("timeStamp", reading.timestamp); + //json.put("dateString", format.format(reading.timestamp)); + json.put("created_at", DateUtil.toISOString(reading.timestamp)); + + json.put("bpm", reading.bpm); + if (reading.accuracy != 1) json.put("accuracy", reading.accuracy); + data.put(json); + + highest_timestamp = Math.max(highest_timestamp, reading.timestamp); + } + // send to nightscout - update counter + + final RequestBody body = RequestBody.create(MediaType.parse("application/json"), data.toString()); + Response r; + + r = nightscoutService.uploadActivity(apiSecret, body).execute(); + + if (!r.isSuccess()) { + activityErrorCount++; + UserError.Log.e(TAG, "Unable to upload heart-rate data to Nightscout - check nightscout version"); + throw new UploaderException(r.message(), r.code()); + } else { + PersistentStore.setLong(STORE_COUNTER, highest_timestamp); + UserError.Log.e(TAG, "Updating heartrate synced record count (success) " + JoH.dateTimeText(highest_timestamp) + " Processed: " + readings.size() + " records"); + } + } + } else { + UserError.Log.e(TAG, "Api secret is null"); + } + } + + + + private void postStepsCount(NightscoutService nightscoutService, String apiSecret) throws Exception { + Log.d(TAG, "Processing steps for RESTAPI"); + final String STORE_COUNTER = "nightscout-rest-steps-synced-time"; + if (apiSecret != null) { + final long syncedTillTime = Math.max(PersistentStore.getLong(STORE_COUNTER), JoH.tsl() - Constants.DAY_IN_MS * 7); + final List readings = StepCounter.latestForGraph((MAX_ACTIVITY_RECORDS / Math.min(1, Math.max(activityErrorCount, MAX_ACTIVITY_RECORDS / 10))), syncedTillTime); + final JSONArray data = new JSONArray(); + //final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US); + //format.setTimeZone(TimeZone.getDefault()); + long highest_timestamp = 0; + if (readings.size() > 0) { + for (StepCounter reading : readings) { + final JSONObject json = new JSONObject(); + json.put("type", "steps-total"); + json.put("timeStamp", reading.timestamp); + //json.put("dateString", format.format(reading.timestamp)); + json.put("created_at", DateUtil.toISOString(reading.timestamp)); + + json.put("steps", reading.metric); + data.put(json); + + highest_timestamp = Math.max(highest_timestamp, reading.timestamp); + } + // send to nightscout - update counter + + final RequestBody body = RequestBody.create(MediaType.parse("application/json"), data.toString()); + Response r; + + r = nightscoutService.uploadActivity(apiSecret, body).execute(); + + if (!r.isSuccess()) { + activityErrorCount++; + UserError.Log.e(TAG, "Unable to upload steps data to Nightscout - check nightscout version"); + throw new UploaderException(r.message(), r.code()); + } else { + PersistentStore.setLong(STORE_COUNTER, highest_timestamp); + UserError.Log.e(TAG, "Updating steps synced record count (success) " + JoH.dateTimeText(highest_timestamp) + " Processed: " + readings.size() + " records"); + } + } + } else { + UserError.Log.e(TAG, "Api secret is null"); + } + } + + private void postMotionTracking(NightscoutService nightscoutService, String apiSecret) throws Exception { + Log.d(TAG, "Processing motion tracking for RESTAPI"); + final String STORE_COUNTER = "nightscout-rest-motion-synced-time"; + if (apiSecret != null) { + final long syncedTillTime = Math.max(PersistentStore.getLong(STORE_COUNTER), JoH.tsl() - Constants.DAY_IN_MS * 7); + final ArrayList readings = ActivityRecognizedService.getForGraph(syncedTillTime, JoH.tsl()); + int counter = 0; + + final JSONArray data = new JSONArray(); + //final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US); + //format.setTimeZone(TimeZone.getDefault()); + long highest_timestamp = 0; + if (readings.size() > 0) { + for (ActivityRecognizedService.motionData reading : readings) { + counter++; + if (counter > (MAX_ACTIVITY_RECORDS / Math.min(1, Math.max(activityErrorCount, MAX_ACTIVITY_RECORDS / 10)))) break; + final JSONObject json = new JSONObject(); + json.put("type", "motion-class"); + + json.put("timeStamp", reading.timestamp); + //json.put("dateString", format.format(reading.timestamp)); + json.put("created_at", DateUtil.toISOString(reading.timestamp)); + + json.put("class", reading.toPrettyType()); + data.put(json); + + highest_timestamp = Math.max(highest_timestamp, reading.timestamp); + } + // send to nightscout - update counter + + final RequestBody body = RequestBody.create(MediaType.parse("application/json"), data.toString()); + Response r; + + r = nightscoutService.uploadActivity(apiSecret, body).execute(); + + if (!r.isSuccess()) { + activityErrorCount++; + UserError.Log.e(TAG, "Unable to upload motion data to Nightscout - check nightscout version"); + throw new UploaderException(r.message(), r.code()); + } else { + PersistentStore.setLong(STORE_COUNTER, highest_timestamp); + UserError.Log.e(TAG, "Updating motion synced record count (success) " + JoH.dateTimeText(highest_timestamp) + " Processed: " + readings.size() + " records"); + } + } + } else { + UserError.Log.e(TAG, "Api secret is null"); + } + } + + + + private static final String LAST_NIGHTSCOUT_BATTERY_LEVEL = "last-nightscout-battery-level"; private void postDeviceStatus(NightscoutService nightscoutService, String apiSecret) throws Exception { @@ -1162,4 +1342,37 @@ public int getBatteryLevel() { return (int) (((float) level / (float) scale) * 100.0f); } else return 50; } + + static class GzipRequestInterceptor implements Interceptor { + @Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + return chain.proceed(originalRequest); + } + + Request compressedRequest = originalRequest.newBuilder() + .header("Content-Encoding", "gzip") + .method(originalRequest.method(), gzip(originalRequest.body())) + .build(); + return chain.proceed(compressedRequest); + } + + private RequestBody gzip(final RequestBody body) { + return new RequestBody() { + @Override public MediaType contentType() { + return body.contentType(); + } + + @Override public long contentLength() { + return -1; // We don't know the compressed length in advance! + } + + @Override public void writeTo(BufferedSink sink) throws IOException { + BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); + body.writeTo(gzipSink); + gzipSink.close(); + } + }; + } + } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/dagger/Singleton.java b/app/src/main/java/com/eveningoutpost/dexdrip/dagger/Singleton.java index 8a82916421..00d2e81b6b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/dagger/Singleton.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/dagger/Singleton.java @@ -46,6 +46,10 @@ public class Singleton extends SingletonHotel { @Named("WebServiceSgv") Lazy webServiceSgv; + @Inject + @Named("WebServiceStatus") + Lazy webServiceStatus; + @Inject @Named("WebServiceSteps") Lazy webServiceSteps; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utils/BgToSpeech.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/BgToSpeech.java index f870d46004..03d9d4141d 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utils/BgToSpeech.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utils/BgToSpeech.java @@ -62,29 +62,28 @@ public static void realSpeakNow(final double value, long timestamp, String delta private static String mungeDeltaName(String delta_name) { - // TODO multi-language + from R.string switch (delta_name) { case "DoubleDown": - delta_name = "Double Down"; + delta_name = xdrip.getAppContext().getString(R.string.DoubleDown); break; case "SingleDown": - delta_name = "Single Down"; + delta_name = xdrip.getAppContext().getString(R.string.SingleDown); break; case "FortyFiveDown": - delta_name = "Slight Down"; + delta_name = xdrip.getAppContext().getString(R.string.FortyFiveDown); break; case "Flat": - delta_name = "Flat"; + delta_name = xdrip.getAppContext().getString(R.string.Flat); break; case "FortyFiveUp": - delta_name = "Slight Up"; + delta_name = xdrip.getAppContext().getString(R.string.FortyFiveUp); break; case "SingleUp": - delta_name = "Single Up"; + delta_name = xdrip.getAppContext().getString(R.string.SingleUp); break; case "DoubleUp": - delta_name = "Double up"; + delta_name = xdrip.getAppContext().getString(R.string.DoubleUp); break; case "NOT COMPUTABLE": delta_name = ""; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Mdns.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Mdns.java index 59c06fb515..64b021381a 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Mdns.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Mdns.java @@ -55,11 +55,11 @@ String prettyName() { } private static final HashMap iplookup = new HashMap<>(); - private static boolean hunt_running = false; + private static volatile boolean hunt_running = false; private static int errorCounter = 0; private final AtomicInteger outstanding = new AtomicInteger(); - private long locked_until = 0; + private volatile long locked_until = 0; private NsdManager mNsdManager; private static NsdManager.DiscoveryListener mDiscoveryListener; private NsdManager.ResolveListener mResolveListener; @@ -179,6 +179,8 @@ private synchronized void singleResolveService(NsdServiceInfo service) { } catch (InterruptedException e) { UserError.Log.e(TAG, "Interrupted waiting to resolver lock!"); + } catch (IllegalArgumentException e) { + UserError.Log.e(TAG, "got illegal argument exception in singleResolveService: ", e); } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/RouteFinder.java b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/RouteFinder.java index 7f763b7d4e..c79c94ddca 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/RouteFinder.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/RouteFinder.java @@ -30,6 +30,9 @@ public class RouteFinder { // support for nightscout style sgv.json endpoint routes.add(new Pair<>("sgv.json", "WebServiceSgv")); + // support for nightscout style barebones status.json endpoint + routes.add(new Pair<>("status.json", "WebServiceStatus")); + // support for working with step counter routes.add(new Pair<>("steps/", "WebServiceSteps")); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceModule.java b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceModule.java index 167b1b354b..aa34c5bc36 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceModule.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceModule.java @@ -45,6 +45,14 @@ BaseWebService providesWebServiceSgv() { return new WebServiceSgv(); } + @Provides + @Singleton + @Named("WebServiceStatus") + BaseWebService providesWebServiceStatus() { + if (d) Log.d("INJECT", "creating WebServiceStatus"); + return new WebServiceStatus(); + } + @Provides @Singleton @Named("WebServiceTasker") diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceSgv.java b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceSgv.java index 1dc9d8993e..da6f91ea66 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceSgv.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceSgv.java @@ -43,9 +43,23 @@ public WebResponse request(String query) { int heart_result_code = 0; // result code for any heart cgi parameters, 200 = good int tasker_result_code = 0; // result code for any heart cgi parameters, 200 = good int units_indicator = 1; // show the units we are using + boolean brief = false; // whether to cut out portions of the data final Map cgi = getQueryParameters(query); + int count = 24; + + if (cgi.containsKey("count")) { + try { + count = Integer.valueOf(cgi.get("count")); + count = Math.min(count, 100); + count = Math.max(count, 1); + UserError.Log.d(TAG, "SGV count request for: " + count + " entries"); + } catch (Exception e) { + // meh + } + } + if (cgi.containsKey("steps")) { UserError.Log.d(TAG, "Received steps request: " + cgi.get("steps")); // forward steps request to steps route @@ -67,8 +81,13 @@ public WebResponse request(String query) { tasker_result_code = tasker_reply_wr.resultCode; } + if (cgi.containsKey("brief_mode")) { + brief = true; + } + + final JSONArray reply = new JSONArray(); - final List readings = BgReading.latest(24); + final List readings = BgReading.latest(count); if (readings != null) { // populate json structures try { @@ -79,8 +98,10 @@ public WebResponse request(String query) { // for each reading produce a json record for (BgReading reading : readings) { final JSONObject item = new JSONObject(); - item.put("_id", reading.uuid); - item.put("device", collector_device); + if (!brief) { + item.put("_id", reading.uuid); + item.put("device", collector_device); + } item.put("date", reading.timestamp); item.put("dateString", DateUtil.toNightscoutFormat(reading.timestamp)); item.put("sysTime", DateUtil.toNightscoutFormat(reading.timestamp)); @@ -88,11 +109,12 @@ public WebResponse request(String query) { item.put("delta", new BigDecimal(reading.getDg_slope() * 5 * 60 * 1000).setScale(3, BigDecimal.ROUND_HALF_UP)); item.put("direction", reading.getDg_deltaName()); item.put("noise", reading.noiseValue()); - item.put("filtered", (long) (reading.filtered_data * 1000)); - item.put("unfiltered", (long) (reading.raw_data * 1000)); - item.put("rssi", 100); - item.put("type", "sgv"); - + if (!brief) { + item.put("filtered", (long) (reading.filtered_data * 1000)); + item.put("unfiltered", (long) (reading.raw_data * 1000)); + item.put("rssi", 100); + item.put("type", "sgv"); + } if (units_indicator > 0) { item.put("units_hint", Pref.getString("units", "mgdl").equals("mgdl") ? "mgdl" : "mmol"); units_indicator = 0; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceStatus.java b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceStatus.java new file mode 100644 index 0000000000..11b7d948e9 --- /dev/null +++ b/app/src/main/java/com/eveningoutpost/dexdrip/webservices/WebServiceStatus.java @@ -0,0 +1,46 @@ +package com.eveningoutpost.dexdrip.webservices; + +import android.util.Log; + +import com.eveningoutpost.dexdrip.Models.UserError; +import com.eveningoutpost.dexdrip.UtilityModels.Pref; + +import org.json.JSONException; +import org.json.JSONObject; + +import static com.eveningoutpost.dexdrip.Models.JoH.tolerantParseDouble; + +/** + * Created by jamorham on 04/02/2018. + */ + +public class WebServiceStatus extends BaseWebService { + + private static String TAG = "WebServiceStatus"; + + // process the request and produce a response object + public WebResponse request(String query) { + final JSONObject reply = new JSONObject(); + + // populate json structures + try { + // thresholds":{"bgHigh":260,"bgTargetTop":180,"bgTargetBottom":80,"bgLow":55} + double highMark = tolerantParseDouble(Pref.getString("highValue", "170")); + double lowMark = tolerantParseDouble(Pref.getString("lowValue", "70")); + + final JSONObject thresholds = new JSONObject(); + thresholds.put("bgHigh", highMark); + thresholds.put("bgLow", lowMark); + + reply.put("thresholds", thresholds); + + Log.d(TAG, "Output: " + reply.toString()); + } catch (JSONException e) { + UserError.Log.wtf(TAG, "Got json exception: " + e); + } + + return new WebResponse(reply.toString()); + } + + +} diff --git a/app/src/main/res/values-de/strings-de.xml b/app/src/main/res/values-de/strings-de.xml index 670066c2fa..a981eb0d3d 100644 --- a/app/src/main/res/values-de/strings-de.xml +++ b/app/src/main/res/values-de/strings-de.xml @@ -772,4 +772,17 @@ Ton wiederholen Telemetrie aktivieren Sende die Daten zu den Entwickler über die Erfolgsquote verschiedener Geräte. + schnell fallend + fallend + leicht fallend + gleichbleibend + leicht steigend + steigend + schnell steigend + Sprich den Trend mit aus + Sprich alles zwei mal + Sprachgeschwindigkeit + Sprachliche Tonhöhe + Sprich Alarme + Spricht die Alarmwerte bei Über-/Unterschreitungn aus diff --git a/app/src/main/res/values-es/strings-es.xml b/app/src/main/res/values-es/strings-es.xml index c715679221..749ddea3e7 100644 --- a/app/src/main/res/values-es/strings-es.xml +++ b/app/src/main/res/values-es/strings-es.xml @@ -472,4 +472,11 @@ Número de glucosa filtrado Si el teléfono tiene capacidades de conversión de texto a voz se leerá cada nueva lectura. Cargar los registros + caída rápida + cayendo + ligeramente decreciente + consistente + aumentando levemente + ascendente + aumentando rápidamente diff --git a/app/src/main/res/values-hr/strings-hr.xml b/app/src/main/res/values-hr/strings-hr.xml new file mode 100644 index 0000000000..71bd3de170 --- /dev/null +++ b/app/src/main/res/values-hr/strings-hr.xml @@ -0,0 +1,827 @@ + + + Bluetooth skeniranje + Spojeno + Odspojeno + Skeniranje + Stani + Osvježi + Izvoz baze podataka + Izvoz CSV format (SiDiary format) + Uvoz baze podataka + Greška: Bluetooth nije podržan od strane ovog uređaja + Neprepoznati uređaj + Spajanje na uređaj + Tablica sirovih podataka + Tablica izračunatih podataka + Pokreni novi senzor + Lokacija novog senzora + Zaustavi senzor + Navigacija + Otvori područje navigacije + Zatvori područje navigacije + Baždarenje + Aktivnost povezanih USB-ova + Odgodi alarm + Odgodi alarm na x minuta + Potvrdi + Zaboravi + Ne + Ne ponavljaj ovo pitanje + "Lista grešaka i događaja" + Glavna aktivnost + Lažni brojevi + Izmijeni alarm + Početno baždaranje + Prebrisati baždarenje + Spremanje u oblak + Automatska konfiguracija + Automatski konfiguriraj koristeći barkod. + Skeniraj dijeljeni barkod + Ili skeniraj barkod dijeljenog prijamnika + MongoDB + Ukoliko koristite MongoLab i Azure ovo bi trebalo uključiti + URI + Unesi MongoDB URI" + Zamijenite vrijednosti iz primjera u {} sa svojim ispravnim vrijednostima + mongodb://{korisnik}:{lozinka}@{host}.mongolab.com:{11111}/{baza} + Ime kolekcije + Unesi ime kolekcije + Ovo je ime kolekcije gdje će CGM podaci biti pohranjeni + Ime kolekcije statusa uređaja + Unesi ime kolekcije statusa uređaja" + Ovo je ime kolekcije gdje će biti pohranjeni podaci o bateriji i drugim uređajima + Nightscout sinkronizacija (REST-API) + Omogućeno + REST API je alternativa direktnom mongodb učitavanju + Bazični URL + Unesi bazični API URL + Ovo je samo bazični URL, sustav uploada će automatski dodati unose za POST. API_SECRET na serveru se mora slagati s vašim tajnim ključem iz ove postavke. + https://tajnikljuc@{NAZIV-SAJTA}.azurewebsites.net/api/v1/ + Zarezom odvojena lista oblika ip:port (primjerice 37.142.132.220:50005,37.142.132.220:50010,mongodb://user:pass@ds053958.mongolab.com:53958/db/collection) + Unesi ip adrese i portove prijamnika (uključujući mongodb adresu ukoliko je potrebno) + Lokacija nije omogućena + Da bi Bluetooth pronalaženje radilo na novijim uređajima, lokacija mora biti omogućena. xDrip ne prati vašu lokaciju i ova postavka može biti onemogućeno nakon uspješnog uparivanja. + Omogući + Lokalno odašiljanje + Omogući lokalno odašiljanje podataka tako da ostale aplikacije (npr. NightWatch) mogu zaprimati nove vrijednosti + Dijeli Test + Koristi Pebble Trend Watchface + Koristi/instaliraj Pebble Trend Watchface (eksperimentalno) + Prikaži trend + Prikaži trend GUK-a na xDrip Pebble watchface. + Prikaži liniju Visoko + Prikaži liniju Nisko + Nešto je pošlo po zlu :( poslano je izvješće kako bi pomoglo popravku problema. + Samo ovdje kliknite ikonu Tick za potvrdu. Ne biste trebali promijeniti konfiguraciju. + Konfiguracija Tasker + finish_preferences_activity + Dodaj widget + Lista alarma + Izgovaraj tretman + Nadogradnja za xDrip+ je dostupna + Dijeli postavke preko QR koda + Pošalji povratnu informaciju Jamorham-u + Parakeet mapa + Prikaži postavke + Uvezi / Izvezi značajke + Ponovno pošalji vrijednosti glukoze prema satu + Otvori postavke na Wear-u + Resetiraj Wear DB + Izbriši + Svi savjeti na sučelju će se ponovno prikazati od samog početka + Dugme za bilješku + Dugme za bilješku sada traži glasovni unos.\n\nDugotrajno pritisnite na njega za unos putem tipkovnice ili promjenu opcija. + Dugme za ponavljanje + Dugne za ponavljanje služi za korak unaprijed kroz prethodno poništene simulacije tretmana, baždareanja i bilješke\n\nNakon 30 minuta će se ponovno sakriti + Dugme za poništavanje + Dugme za poništavanje služi za korak unatrag kroz simulacije tretmana, baždarenja i bilješke\n\nAfter 30 minutes it will hide again + Dodaj bilješku + Test krvi + Dijeli + Uređivać profila tretmana + Prvo koristite izbornik za traženje vašeg BT uređaja ili pak izmijenite Izvor podataka u postavkama! + Prvo konfigurirajte ip adresu vašeg wifi wixel čitaća ili url parakeet-a + Sada pokrenite senzor ili pogledajte postavke + Molimo pričekajte dok se senzor pripremi! ( + " min)" + Moguće pogrešan nagib baždarenja, molimo popijte čašu vode, operite ruke te ponovno baždarite za nekoliko minuta! + Molimo sačekajte, prvo su potrebna 2 očitanja sa odašiljača. + Za početak molimo unesite dva baždarenja! + Sada se uparite sa svojim Dexcom Share + Sada u postavkama odaberite pokretanje vašeg senzora + Dvostruko provjerite serijski broj Dexcom primača (receivera), trebao bi bit 10 znakova, nemojte zaboraviti slova + Molimo podesite serijski broj vašeg Dexcom primača (receivera) u postavkama aplikacije + Nažalost vaša android verzija ne podržava Bluetooth Low Energy + Čekam na paket + Dugotrajno Visoko > + " min" + do + Predviđeno Nisko + u + Da, uđi u način za promjenu postavki + Ne, zadrži Parakeet kao što jeste + Jeste li sigurni da želite prebaciti Parakeet u način za promjenu postavki?\n\nUobičajeno ovo se koristi isključivo za slanje daljnjih SMS poruka na Parakeet u cilju rekonfiguracije postavki o tome koji odašiljač (Transmitter) sluša itd. + Podijeli, obriši ili ne učini ništa + Podijeli ovaj blok u dva + Obriši ovaj vremenski blok + Odustani - ne učini ništa + Dodano + Provjera ažuriranja.. + Signal propušten + " min. prije" + " min. prije" + Prikaži Parakeet kartu + Prebaci Parakeet u način za promjenu postavki + Pogledaj zapise događaja + Dijeli postavke preko QR koda + Provjeri ažuriranja - noviju verziju + Pošalji povratnu informaciju - poruku programeru + Početni ekran + Graf baždarenja + Jedinice glukoze + mmol/l ili mg/dl Visoko i Nisko + Opće postavke + Vrijednost za Visoko + Vrijednost za Nisko + Licencni ugovor za krajnjeg korisnika + Spremi + Pogledajte važno upozorenje + Pogledajte Google licence + Nije za medicinsku upotrebu - isključivo istraživački alat + Dubinske postavke za algoritme + Vrijednosti predviđanja niže razine + Pad glukoze za 1 jedinicu + xDrip+ postavke simulacije predviđanja + Postavke za sinkronizaciju među uređajima (handsets) + xDrip+ postavke sinkronizacije + xDrip+ postavke ažuriranja + Automatska provjera ažuriranja + Kanaz za ažuriranja + Pošalji informacije o rušenjima sustava programeru + Automatsko izvještavanje o rušenjima sustava + Pošalji poruku s povratnom informacijom + Postavke kopiranja + Prikaži QR kodove postavki + Učitaj / Spremi postavke sa/na SD karticu + Alarmi i upozorenja + Upozorenja i obavijesti + Lista upozorenja razine glukoze + Postavke upozorenja glukoze + Pametno odgađanje + Upozorenja baždarenja + Upozorenje propuštenog očitanja + Ostala upozorenja + Dodatna upozorenja (xDrip+) + Upozorenje za dugotrajno Visoko + Upozorenje za prognozirano Nisko + Ekstrapoliraj podatke u cilju prognoziranja Niskih + Alarm za prognozirano Nisko u min + Ostala xDrip+ upozorenja + xDrip+ postavke prikaza + Prilagodbe prikaza + Inzulin, ugljikohidratni omjeri itd. za modele + Grama ugljikohidrata koliko pokriva 1 jedinica + Linearni model apsorpcije ugljikohidrata po satu + Brzina apsorpcije ugljikohidrata + Izračunaj uključujući trend glukoze + Koristi moment trenda + Unesi baždarenje + Status sustava + Postavke + Tablica podataka baždarenja + Tablica podataka GUK + Trenutačno nije moguće baždariti + Hardverski izvor podataka + Unesite 10 znakovni serijski broj Dexcom primača (receivera) + Dexcom odašiljač (Transmitter) ID + Pokreći (upogoni) kolektor u prvom planu + Prikazuje trajan graf obavijesti, vidljiv na zaključanom ekranu te sprečava android da ugasi ovaj servis. + Lista primača (receivera) + Dodatni tagovi za zapise + Ovdje uneseni tagovi biti će zapisani u xDrip. Format je tag:razina. Razina može biti v,d,i. Kao primjer bgreading:i,DexCollectionService:v. Ovi tagovi će biti zapisani kao niski prioritet u listu grešaka i događaja. + Unesite više tagova koje želite da budu zapisivani + Postavke izvora podataka + Značajke pametnog sata + Wear integracija + Pošalji podatke na Android Wear Watchface. + Android Wear integracija + Omogući uslugu Wear prikupljanja + Spoji Wear na BT kolektor kada je telefon izvan dosega + Prisili uslugu Wear prikupljanja + Prisili telefon da koristi uslugu Wear prikupljanja + Onemogući prisilu kada je baterija slaba + Onemogući prisilu usluge Wear prikupljanja kada je na Wear-u aktivno upozorenja o slaboj bateriji + Onemogući prislu kod propuštenih očitanja + Onemogući prisilu usluge Wear prikupljanja na minute od posljednjeg očitanja sa Wera-a + Minute od posljednjeg očitanja sa Wear-a + Uređaj na kojem radi kolektorska usluga + Prisili telefon da koristi ovu uslugu Wear prikupljanja + Sinkroniziraj Wear zapise + Pošalji Wear zapise u preglednik događaja + Prefiks Wear zapisa + Prefiks koji se koristi za unose Wear zapisa + Prikaži tretmane + Prikaži točke tretmana na grafikonu + Koristi Wear podatke o zdravlju + Prikupi i prikaži brojač koraka kada je dostupno + Pebble integracija + Pošalji podatke na Pebble sučelje. + Pebble sat integracija + Standardno ili trend pebble sučelje + Odaberi Pebble sučelje + Poruka za prikaz kada razina GUK-a dostigne posebnu vrijednost iznad + Tekst za prikaz kada se dostigne posebna vrijednost + Posebna vrijednost + Povijest + Statistika + Odgađanje upozorenja + Manje učestale postavke + Pregledaj nedavne greške/upozorenja + Ostale postavke + Stariji suvišni sustavi za održavanje budnosti koji mogu snažnije iscrpiti bateriju no mogu biti potrebni za NightWatch ili Android Wear + Koristite prekomjerne sustave za održavanje budnosti + Govori očitanja + Dodatna linija statusa + Dexcom Share Server upload + Upload podataka na Dexcom servere tako da možete koristiti vaše podatke sa Dexcom aplikacijama + Upravljanje sljedbenicima (followers) + Upravljanje postojećim sljedbenicima (followers) i pozivanje novih. + Glukoza, baždarenje i ostala upozorenja + Profil glasnoće upozorenja + Pametnu upozoravanje + Onemogući alarme za vrijeme telefonskog razgovora + Započni odgađanje + Podesi sve za faktor + Vrati na početak + Pebble i Android Wear opcije + Prilagodi boje + xDrip+ postavke boja + Vrijednosti glukoze i linije + Visoke vrijednosti glukoze + Vrijednosti glukoze u rasponu + Odabrana početna postavka boje + xDrip+ dodatne postavke + Primjer grafikona + Krivulje treatmana / prognoza + Ugljikohidrata po jedinici + Svakodnevno + Inzulinska osjetljivost: pad glukoze po jedinici + Baterija odašiljača (Transmittera) + VRLO NISKO + Nisko + " jedinice" + jedinic. + ugljikohidrat. + kad + Govori svoj tretman npr.:\nx.x jedinica inzulina / xx grama ugljikohidrata + Prepoznavanje govora nije podržano + Bilješka tretmana + Nije moguć izvoz baze :( + "Izvezeno u " + Početne postavke za glasovni unos sljedeći puta + Učinjeno + Unošenje baždarenja sada će poništiti vaše prethodno uneseno baždarenje. + Unesi vrijednost glukoze u krvi + Ovo ne služi ničemu, to je samo kako da bi se pratile razlike u svrhu poboljšanja algoritama + Ne postoje aktivna upozorenja + Aktivno upozorenja postoji imena + (nije odgođeno) + "Sva upozorenja onemogućena do " + "Upozorenja Nisko onemogućena do " + "Upozorenja Visoko onemogućena do " + Početne postavke odgađanja + Dok se ponovno ne omogući + Postavi + Onemogući upozorenja Nisko + Ponovno omogući upozorenja Nisko + Onemogući upozorenja Visoko + Ponovno omogući upozorenja Visoko + Onemogući sva upozorenja + Ponovno omogući sva upozorenja + Odgađanje upozorenja od strane sata + "Kanal ažuriranja: " + Nova verzija je dostupna + Detalji verzije + Preuzmi sada + Automatski provjeri ažuriranja + Ovdje možete pohraniti postavke na vanjsku memoriju za pohranu (SD kartica).\n\nJednom kada su pohranjene na vanjsku memoriju potencijalno je moguće da bilo koja aplikacija čita postavke koje mogu sadržavati osjetljive informacije.\n\nUkoliko vas to zabrinjava savjetuje vam se da obrišete te spremljene postavke jednom kada ih ponovno uvezete. + Spremi sve postavke na SD karticu + Učitaj sve postavke sa SD kartice + Izbriši sve postavke sa SD kartice + Automatska konfiguracija]]> + samo xDrip Plus postavke sigurnosnsog ključa (Security Key) + Prikaži opće i postavke prikupljanja + Kopiraj sve postavke + Senszor je spreman, molimo unesite početno baždarenje + Da biste počeli, molimo učiniti jedan ili dva testa krvi iz prsta i ovdje unesite vrijednosti! + Unesite prvu vrijednost GUK-a + Unesite drugu vrijednost GUK-a + Uređivanje jezika + Konfiguriraj propuštena očitanja + Instaliraj Pebble aplikaciju kontrole odgađanja + Instaliraj Pebble sučelje klasičnog trenda + Instaliraj Pebble sučelje trenda + Instaliraj Pebble sučelje + Povijest glukoze + Uvezi bazu podataka + Tablica senzora + Tablica očitanja GUK-a + Dugotrano pritisni za podjelu ili brisanje + Pritisni i zadrži pozadinu za podjelu ili brisanje vremenskog bloka + Traži + Vrati na početne SVE jezične postavke + Prikaži samo prilagođene unose + Postavke na eksternoj memoriji za pohranu + Obavijesti me o novim apk izdanjima + Odaberite Stable, Beta ili Alpha izdanja + Web forma za davanje povratnre informacije u svrhu slanja programerima poruka i rejtinga za xDrip+ + Budi glavni (master) za sljedbenike (followers) + Ovaj uređaj će slati podatke sljedbenicima (followers) + Šalji Parakeet lokaciju na karti sljedbenicima (followers) + Sinkroniziraj Parakeet GeoLokaciju + Onemoguće svu sinkronizaciju + Privremena zaobilazna opcija, potpuno zaustavlja svu sinkronizaciju. Može zahtjevati ponovno pokretanje sustava nakon ponovnog omogućavanja. Koristiti s oprezom! + Automatske nadogradnje, izvještaji o rušenju sustava i povratne informacije programeru + Prijevod iz masovnih izvora + Molimo ovdje unesite vaše pitanje ili komentar.\n\nUkoliko navedete email adresu možete dobiti odgovor.\n\n + Neobavezna kontakt informacija ovdje, npr. e-mail + Pošalji poruku + Molimo naznačite što općenito mislite o aplikaciji + Postavke spremljene na SD karticu Downloads + Ne mogu zapisati na SD karticu - provjerite ovlasti? + Postavke učitane! - Ponovno pokretanje + Nije moguće učitati postavke - provjerite ovlasti ili dokument? + Nije moguć zapis na vanjsku memoriju za pohranu podataka + Uspješno obrisano + Problem pri brisanju + Nije moguć zapis na SD karticu - nije moguće spremanje + SD kartica nije čitljiva + Učitavanje postavki iz xDrip glavne linije + Upozorenje postoje postavke od xDrip i xDrip+ - učitavanje od xDrip+ + "Datum nove verzije: " + "Datum stare verzije: " + Govori tekst svoje bilješke + Alarm ako je iznad razine Visoko + dulje od (min.) + Odabir zvuka za alarm dugotrajno Visoko. + Zvuk za dugotrajno Visoko + Prognoza Nisko + Aktiviraj alarm za prognozu Nisko + Obavijesti kada vrijeme za prognozu Nisko dostigne prag + Zvuk za prognozu Nisko + Odabir zvuka za alarm za prognozu Nisko. + Obavijesti kada se parakeet uređaj prestane javljati + Upozorenja vezana uz Parakeet + Obavijest za parakeet aktiviraj tiho za vrijeme punjenje + Tiho upozorenje za vrijeme punjenja + Upozorenja počinju odgođeno i moraju trajati neko vrijeme da bi se uistinu oglasila + Alarmi utišani za vrijeme telefonskog razgovora + Potisni upozorenja ukoliko su propuštena očitanja + Alarmi za vrijednosti kod koji je prisutan šum (noisy) + Nastavi odgađanje ukoliko glukoza ide u pravom smjeru + Nemoj upozoravati ukoliko glukoza ide u pravom smjeru + Zvuk zahtjeva za baždarenje + Prikazuj liniju filtriranog + Prikaži sićušne točkice umjesto malih točkica na grafikonu + Prikaži liniju Visoko + Prikaži liniju Nisko + Postavi period trenda za prikaz + Vremenski period trenda + Prikaži vrijednost promjene - delta + Prikaži promjenu - delta + Prikaži jedinice promjene - delta + Prikaži jedinice promjene - delta + Prikaži strelicu nagiba + Prikaži strelicu nagiba + Vibriraj sat za upozorenje kada ne dobivamo nikakve podatke o glukozi + Vibriraj u slučaju propuštenog signala + Vibriraj sat za upozorenje kada se bluetooth odspoji + Vibriraj kada nema bluetooth-a + Posebna vrijednost glukoze za prikaz niže navedene poruke + Bluetooth sustavi za održavanje budnosti + Kompatibilni odašiljači + Prikaži tablice podataka + Prikaži Bridge bateriju + Zatvori GATT u slučaju BLE odspajanja + Onemogući upozorenje u vezi baterije + Dodatni tekst status + Prosjek + U postotku + Postotak Visokih + Postotak Niskih + Trenutno vrijeme. + Vrijeme + Prikaži dodatnu liniju + Prikaži na widgetu + Podaci baždarenja (dugo) + Podaci baždarenja (kratko) + Pohrani lokaciju senzora u cilju pomoći pri unapređenju algoritma + Pomogni programerrima da unaprijede xDrip algoritam. + Pomogni zajednici + Dvostruki dodir ili štipkanje (pinch) za zumiranje. + Pokreni senzor + Otklanjanje neispravnosti (debug) i razne druge opcije + Niske vrijednosti glukoze + Vraćanje na zadane postavke + Filtrirane vrijednosti + Boja tretmana + Tamna boja tretmana + Boja predikcije + Tamna boja predikcije + Linije prosjeka i cilja + Linija 8-satnog prosjeka + Linija 24-satnog prosjeka + Linija ciljane glukoze + Napomene i točkice + Pozadina testa iz krvi + Prednji plan testa iz krvi + Pozadina tretmana + Prednji plan tretmana + Pozadine + Pozadina glavnog grafikona + Pozadina grafikona s obavijestima + Pozadina grafikona widgeta + Pokušaj ispraviti (zaobići) očitanja sa šumovima + Prikaži savjete / sugestije koje prikazuju funkcije dugmeta itd.. Odznačite i označite da biste povratili na početno stanje + Prikaži savjete za sučelje + Na grafikonu prikaži mrežu linija za vrijeme + Na grafikonu prikaži mrežu linija za glukozu + Prikaži ispis filtirani podataka + Prikaži ispis sirovih podataka + Prikaži liniju ciljane vrijednosti na grafikonu + Prikaži nedavni prosjek na grafikonu + Prikaži ukupni prosjek na grafikonu + Prikaži krivulju momenta + Prikaži vrijednosti očitanja sa šumovima + Parakeet i dodatne testne značajke + Trajanje inzulina u satima + Početne postavke omjera osjetljivosti jetre + Ključ koji se koristi umjesto Google korisničkog računa + Sinkroniziraj koristeći prilagođeni sigurnosni ključ + Handset Group Security Sync Key + Handset sync grouping key + Naziv upozorenja: + Prag: + Početne postavke odgađanja: + Ponovno aktiviraj svakih \n x minuta ukoliko\n nije prepoznat: + Ton upozorenja: + Odaberi dokument + Odaberi vrijeme za upozorenje: + cijeli dan + (dodirni za promejnu) + Nadjačaj tihi način rada telefona: + Vibriraj pri upozorenju + test upozorenja + onemogući upozorenje + spremi upozorenje + makni upozorenje + odgodi upozorenje prije nego se oglasi + Kreiraj upozorenje Nisko + Kreiraj upozorenje Visoko + (Dugotrajni pritisak na postojeće upozorenje za izmjenu) + Dodavanje + visoko + upozorenje + Upozorenje Visoko + Upozorenje Nisko + Baterija + xBridge baterija + Libre baterija + Parakeet baterija + Nakon baždarenja, prilagodi nedavne sirove vrijednosti na grafikonu kako bi se uskladilo sa novim baždarenjem + Ponovno napišite povijest + Vidljiva mreža linija za vrijeme + Vidljiva mreža linija za glukozu + Korisno za šumove i propuštena očitanja + Standardne xDrip izračunate vrijednosti + Prikaži ciljanu liniju idealne glukoze + Prikaži linju 8-satnog prosjeka + Prikaži linju 24-satnog prosjeka + Unutarnje funkcioniranje modela predikcije + Unutarnje funkcioniranje modela šumova + Visina glukoze iz filtriranog + Ukoliko telefon ima tekst-u-govor mogućnosti izgovarati će svako novo očitanje. + Pošalji zapise + OFF + ON + Instaliraj Pebble applikacije + Koristi zadnjih 24 sata umjesto vremena od ponoći za statistiku. + Klizajući prozor + Podijeli + Obriši + Skeniranje mjerača + Isključivanje prisiljavanja usluge Wear prikupljanja zbog slabe baterije Wear-a! + Isključivanje prisiljavanja usluge Wear prikupljanja zbog %1$d min. propuštenih očitanja na satu! + #.## + U:%1$su + Ugljikohidrati:%1$sg + UH/I:%1$s + Koraci:%1$d + km:%1$s + mi:%1$s + Ukoliko koristite privatnu InfluxDB bazu podataka, ovo bi trebalo omogućiti + InfluxDB + https://{host}:{port} + Zamijenite vrijednosti iz primjera u zagradama {} sa vašim ispravnim vrijednostima + Unesite InfluxDB URI + xdrip + Baza podataka služi za pohranu mjerenja. Sjetite se kreirati ju na serveru. + Baza podataka + root + Korisničko ime za autorizaciju. Preporuka je da se ne dozvoljava korištenje bez autorizacije. + Korisnik + root + Lozinka za autorizaciju. Preporuka je da se ne dozvoljava korištenje bez autorizacije. + Lozinka + Koristi sićušne točkice + Vibriraj sat prilikom aktivnih upozorenja o glukozi + Vibriraj kod upozorenja + Dodajte na pebble dugme da biste preko sata odmah odgodili bilo koje aktivno upozorenje. Također za značajke udaljenog odgađanja. + Za interakciju sa drugim kompatibilnim aplikacijama + Među-aplikacijske posatvke + Koristi zaglađivanje šumova te dodatke itd. (ukoliko je omogućeno) za odaslanu vrijednost + Pošaljite prikazanu vrijednost glukoze + Emitirajte bez obraćanja pozornosti na model starijih prava + Podaci o procesu tretmana primljeni od aplikacije NSClient + Prihvati tretmane + Obradi baždarenja primljena od drugih aplikacija + Prilagođeni jezik za izgovorene vrijednosti, npr.: de ili en_IN + Svaki put izgovaraj vrijednosti glukoze dva puta + U ☰ izborniku prikaži kraticu za uključivanje glasovnog unosa očitanja + Kratica za glasovni unosa očitanja + Na Androidu 6+ osiguraj da je optimizacija baterije isključena. Preporučeno + Nemoj stalno zapitkivati o optimizaciji baterije. Nije preporučljivo + Upit (napomena) za optimizaciju baterije + Napredne Bluetooth postavke + Bluetooth postavke + Automatski uključi bluetooth, ukoliko je isključen, kada se pokušavamo spojiit na bluetooth uređaj + Uključi bluetooth + Ponovno pokreni Bluetooth gašenjem i ponovnim paljenjem ukoliko ne dobijemo očitanja u 20 min. + Bluetooth Watchdog + Ponovno pokreni Bluetooth gašenjem i ponovnim paljenjem kao način da se G5 izvor podataka zadrži aktivnim u radu. Bez ovoga G5 kolektor može ne uspijevati. + G5 Bluetooth Watchdog + Ukoliko se bluetooth watchdog učestalo aktivira možete probati deaktivirati ovu opciju da vidite pomaže li to + Stariji bluetooth sustavi za održavanje budnosti koji mogu snažnije iscrpiti bateriju no mogu biti potrebni za bluetooth prijem + Ponovno pokreni Bluetooth gašenjem i ponovnim paljenjem svakih nekoliko minuta! Odaberite samo ukoliko testirate. Može uzrokovati prekide svega drugoga što koristi bluetooth. + Konstantno isponovna pokreći bluetooth + Eksperimentalna podrška za \'Transmiter\' uređaj od @FPV-UAV - isključivo test + Transmiter (PL) podrška + Experimentalna podrška za rfduino od Tomasz Stachowicz + RFDUINO podrška + Opetovano isponova pokreći kolektorski servis na svaku najavu propuštenih podataka. Omogućiti samo ukoliko dolazi do propuštanja podataka. + Agresivno ponovno pokretanja servisa + Stara metoda - nije preporučeno! Pokušava prediktirati očitanja svake minute bazirano na nekoliko posljednjih vrijednosti. + Korištenje blukon algoritma izvan procesa. + Prikaži prediktirane vrijednosti + Blukon algoritam izvan procesa. + Ukoliko se koristi Share, xDrip će prikazati vrijednosti koje su uobičajeno skrivene na primaču (receiveru). + Interpretiraj sirove vrijednosti + Ukoliko je potrebno, kolisti baždarenja iz prijeašnjeg vremena, npr. ako su baždarenja rijetko rađena. + Rijetka baždarenja + Dodatne postavke zapisivanja + Automatski šalji listu zapisanih događaja i grešaka programerima + Omogući udaljeno zapisivanje + Postavi AppID zapisivanja + Omogućite samo ako imate problema sa aplikacijom. + Pohrani zapise u svrhu rješavanja problema + Prikaži tablice s podacima o baždarenju i GUK-u na navigacijskoj traci. + Onemogući upozorenje za slabu bateriju odašiljača (transmittera) na početnom ekranu. (Relevantno samo za primače iz kućne radinosti.) + Inženjerski način + Dozvoljava promjene i najnesigurnijih postavki što može uzrokovati potpuni krah! + Spremi bazu podataka na dnevnoj bazi + Dozvoljava servisu dnevnih namjera da spremi bazu podataka prije brisanja + Opcije za dodatnu liniju + Današnja prosječna vrijednost. + A1c procjena u DCCT formatu (%) + A1c DCCT + A1c procjena u IFCC formatu (mmol/mol) + A1c IFCC + Postotak vrijednosti unutar raspona. + Postotak vrijednosti ispod raspona. + Postotak vrijednosti iznad raspona. + Prikaži standardnu devijaciju vrijednosti. + Standardna devijacija + Prikaži ukupno ugljikohidrata u tretmanu + Ukupno ugljikohidrata + Prikaži ukupno inzulina u tretmanu + Ukupno inzulina + Postotak primljenih očitanja senzora + Postotak uhvaćenih paketa + Prikaži procjenu preciznosti baždarenja u zadnja 3 dana + Procjena preciznosti + Također prikaži dodatnu statusnu liniju na widgetu + Prikaži nagib i odsječak u dugom obliku. + Prikaži nagib i odsječak u kratkom obliku. + Prikaži nagib i podatke o glukozi od aktivnog plugina + Plugin za baždarenje + Napredno baždarenje + Dodatne opcije vezane uz baždarenje + Odaberite da li baždariti sa GUK vrijednostima iz unosa tretmana + Koristi GUK vrijednosti tretmana + Eksperimentalni sekundarni plugin za baždarenje + Prikaži rezultate glukoze plugina na glavnom grafikonu + Prikaz podataka plugina na grafikonu + Koristi plugin za glukozu + Glavni prikaz visine glukoze dolazi od plugina! + Plugin nadjačava SVE + SVE nove vrijednosti glukoze će biti računate i spremljene od strane odabranog plugina, a ne od strane standardnog xDrip algoritma. Ovo nije testirano i može biti netočno i sa greškama. Koristiti uz iznimni oprez. + Originalni uži raspon dozvoljenih nagiba unutar xDrip klasičnog algoritma baždarenja (prije-2017). Standardni nagibi vjerojatnije! (jedino inženjerski način rada) + Način baždarenja stara škola + kako ćete primati podatke od svog Dexcoma/odašiljača (transmittera)? + Opcije za skeniranje NFC senzora sa telefonom + Značajke NFC skeniranja + Koristi NFC + Dopusti senzorima da budu skenirani kada je aplikacija otvorena. Povijesni podaci će biti popunjeni unatrag. Vrlo eksperimentalno! Busite svjesni da ovo možda može uništiti senzor. Prvo testirajte kompatibilnost telefona sa senzorom koji je skoro istekao. Upozoreni ste! + Starost-dob senzora + Prikaži vrijeme isteka senzora bazirano na 14.5 dana + Prikaži starost senzora na glavnom ekranu + Izmjeni ukupne dane senzora + NFC skeniranje će se pojaviti samo kada je xDrip+ aplikacija vidljiva + NFC skeniranje će također raditi na ekranu za pokretanje aplikacija + Skeniranje i kada nismo u xDrip+ + Vibriraj za označavanje status skeniranja + Zvučni signal kod skeniranja unutar xDrip+ aplikacije + Koristi bržu multi-block metodu čitanja + Koristi any-tag optimiziranu metodu čitanja + Dijagnostika/prototip vrijednosti duboke razine + ID vsšeg Dexcom odašiljača (Transmittera), npr. 12AB3 + Napredne G5 postavke za rijetke situacije + G5 postavke za otklanjanje neispravnosti (debug) + Neki uređaji rade bolje kada konstantno skeniraju, drugi pak ne. Ukoliko je očitavanje pouzdano kada ova postavka nije omogućena, to bi trebalo pozitivno utjecati na vijek baterije. Uobičajeno najbolje je držati ovu postavku onemogućenom + Skeniraj tražeći G5 konstantno + Za neke Android uređaje ovo je presudno da bi se pravilno spojili, no može uzrokovati propuštena očitanja kada su u upotrebi druge UI intenzivne aktivnosti. + Forsiraj G5 na UI način + Autoriziraj G5 prije svakog očitanja + Ovo će pokušati potpunu autorizaciju pri svakom pokušaja očitanja. Potrebno za novije verzije firmwarea G5 odašiljača (transmittera). + Odspoji G5 prije svakog očitanja + Ovo će maknuti G5 sa liste uparenih uređaja na vašem uređaju, te pokušati potpunu autorizaciju i spajanje pri svakom pokušaju očitavanja. + Eksperimentalni način koji ne koristi sirove podatke + Koristi bađdarene podatke kao izvor + Sinkronizacija podataka + Opcije za Nightscout, MongoDB ili Dexcom Share upload + Upload u oblak (cloud) + Omogući Nightscout Mongo DB sinkronizaciju + Mongo DB Uri + Za lokalne server sa 192.168.x.x adresama, preskoči upload kada nema spoja na lokalnu mrežu. + Preskoči LAN upload + Omogući InfluxDB sinkronizaciju + InfluxDB Uri + InfluxDB ime baze podataka + Korisnik + Lozinka + Omogući ovo za upload na Dexcom servere + Upload GUK vrijednosti kao Dexcom Share + Onemogućeno = Vaš korisnički račun i sljedbeničke (follower) aplikacije su izvan granica SAD-a + Omogućena = Vaš korisnički račun i sljedbeničke (follower) aplikacije su iz SAD-a + Korisnički račun Dexcom baziran u SAD-u + Vaše korisničko ime za Dexcom web stranicu + Dexcom korisničko ime + Vaša lozinka za Dexcom web stranicu + Dexcom korisnička lozinka + 10 znakovni serijski broj Dexcom primača (Receiver) + 10 znakovni serijski broj testnog načina + Glukometri + Optcije za bežićne glukometre + Automatski se spoji i povuci podatke sa glukometra koji je sukladan standardima poput Contour Next One + Koristi Bluetooth glukometar + Skeniraj tražeči Bluetooth glukometar + Omogući ovo da se oglasi zvučni signal kada se glukometar spoji, odspoji ili sinkronizira podatke + Pokazatelji zvučnog signala + Kada je primljen novi rezultat glukoze u krvi, pitaj bi li isti trebao biti korišten za baždarenje + Koristi glukometar za baždarenja + Baždari bez traženja potvrde korsiteći nova očitanja glukoze u krvi ukoliko se uvjeti za to čine odgovarajućima (eksperimentalno) + Automatsko baždarenje + Maksimalna vrijednost za koju smatrate da je u rasponu. + Minimalna vrijednost za koju smatrate da je u rasponu. + Pritisak na tipku glasnoće pojačaj (gore) ili smanji (dolje) će odgoditi aktivni alarm kada je u aplikaciji + Dugme stišavanja alarma + Kreiraj kraticu (shortcut) iz glavne navigacije na ekran razine GUK-a + Kratica (shortcut) na upozorenja razine GUK-a + Potisni odgođena i aktivna upozorenja nakon predodređenog perioda propuštenih očitanja + Potisni odgođena i aktivna upozorenja nakon .. min. (minimum 10) + Upozori kada je zatraženo baždarenje + Koliko sati među zahtjevima za baždarenje + Sati među baždarenjima + Postavke zvuka korištenog pri zahtjevima za baždarenje. + Nadjačaj tihi način rada + Čak i kod punjenja + Odznačite da ne traži baždarenja kada se telefon puni + Ustraj pri upozorenju ako nikakvo baždarenje nije provedeno + Ponavljanje upozorenja + Broj minuta koje trebaju proći prije ponovnog zahtjeva za baždarenjem. + Minuta ponavljanja upozorenja + Upozori nakon x minuta vrijednosti sa šumovima + Odgađanje upozorenja + Broj minuta prije ponovnog upozorenja nakon odgađanja. + Ponovno upozorenje prije roka odgađanja + Ponovno upozorenje ukoliko prije toga nije odgođeno + Vrijeme ponovnog upozorenja + Broj SEKUNDI koje trebaju proći prije ponovne aktivacije istog upozorenja. + GUK pada brzo + GUK raste brzo + prag brzine padanja + prag brzine rasta + Postavke zvuka za GUK upozorenja. + Zvuk upozorenja + Nadjačaj tihi način rada na tim upozorenjima + Ponavljanje maksimalno svakih (min.) + Kada moment trenda pokaže biti će prognozirano Nisko + Obavijesti kada razina baterije padne ispod + Upozorenje baterije kolektora + Postotak koji označava slabu bateriju + 20 min.]]> + Novi sljedbenik (follower) zvoni + Ugljikohidratni omjer + Inzulinska osjetljivost + Vrijednost sekundarnog plugina glukoze + Pedometar - brojač koraka 1. boja + Pedometar - brojač koraka 2. boja + Flair boje + Koristi Flair boje + Boja trake stanja sustava + Boja navigacijske trake sustava + Prisili engleski tekst + Trenutno se koristi lokalni jezik vašeg uređaja + Trenutno se prisiljava upotreba alternativnog jezika + Ukoliko trebate prijevod za alternativni jezik u sklopu xDrip+ + Odaberite određeni jezik + Linije u rasponu na widgetu + Prikaži linje Visoko i Nisko na widgetu. + Zakašnjelo ali stabilnije kada ima šumova (nije preporučeno) + Prikaži pregled bolus čarobnjaka (wizard) + Prikaži izračune Inzulin/Ugljikohidrati + Prikaži izračune Inzulin/Ugljikohidrati u svako vrijeme + Uvijek prikaži pregled bolus čarobnjaka (wizarda) + Prikaži dodatne i alfa testne značajke + Prikaži meni podsjetnika i značajke + Omogući značajke podsjsetnika + Prikaži matematičke simulacije bazirane na podacima iz profila te zapisima o ugljikohidrati/inzulin omjeru + Prediktivne simulacije + Vrijednosti predikcije niske razine + Početne postavke ciljane vrijednosti glukoze + Početne postavke maksimalnog utjecaja jetre (0-1) + Slanje i primanje udaljenih odgađanja + Udaljeno odgađanje + Odgađanje će utišati sve uređaje u grupi ukoliko su na njima omogućene niže navedene postavke prihvaćanja + Pošalji odgodu svima + Izbaci pop-up dijalog da bi se potvrdilo slanje odgode na svaki udaljeni uređaj + Potvrdi slanje odgode + Dozvoli udaljenim uređajima da utišaju alarme na ovom uređaju + Prihvaćaj udaljena odgađanja + Prihvati samo ukoliko ime udaljene wifi mreže počinje istim slovima kao i naše te se slaže vrlo blisko + Wifi ime se mora podudarati + Otkrivanje kretanja i način rada u vozilu + xDrip+ praćenje kretanja + Koristi senzore za otkrivanje vrsti kretanja + Omogući praćenje kretanja + Pohrani nedavne vrste kretanja i prikaži ih na glavnom grafikonu + Zapisivanje i prikaz kretanja + Podaci o kretanju radije se uzimaju od udaljenog izvora nego od lokalnog uređaja + Koristi udaljno kretanje + Budi glavni (master) za podatke o kretanju čak i ako smo pratitelji (follower). Postavite ovo samo na jednom uređaju! + Ponašaj se kao glavni (master) za kretanje + Kada je otkriveno kretanje vozila omogući dodatne značajke + Omogući način rada u vozilu + Povećaj razinu na kojoj će alarmi za Nisko biti aktivirani kada je u načinu rada u vozilu + Podigni prag za \'Nisko\' + Zvuk obavijesti kada je otkriven način rada u vozilu + Pusti zvuk + Ponavljaj zvuk obavijesti svakih 90 minuta ukoliko je još u načinu rada u vozilu + Ponavljaj zvuk + Omogući telemetriju + Programerima pošalji podatke o stopi uspješnosti različitih uređaja + Počni ispravljati očitanja sa šumovima čak i na vrlo niskim razinama šumova (jedino inženjerski način rada) + Izvezi počevši od kada? + Blucon + Koristi senzor gravitacije za rotaciju elemenata + Bridge baterija je slaba + Podsjetnici + greška + Instaliraj Tekst-U-Govor za podatke? + (Nakon instalacije jezike moguće je da treba pritisnuti \"Ponovno pokreni kolektor\" u statusu sustava.) + Zaustavi senzor + Početno baždarenje + Baždarenje ne može biti prazno + Neispravan broj pri baždarenju! + Baždarenje je izvan dosega + Pretraživanje bilješki + Uređivanje bilješke + Ovdje podesite tekst bilješke. Za ovo nema poništavanja + Pretraživani pojam nije pronađen + Bluetooth skeniranje + Upozorenja razine + Poništi baždarenje + Zaustavite vaš senzor isključivo kada uistinu planirate ga skinuti, a u suprotnom ostavite uključeno! + Ponovno pokreni kolektor + Zaboravi uređaj + Ostale bilješke: + Izbriši buduće podatke + Prikaži samo neprevedeno + Prikupljaju se početna očitanja + Kolektor podataka je uključen + Primljeno je nešto nedavnih podataka + Primljeno je dovoljno dobrih podataka za baždarenje + Oglasi zvuk kada bude spremno za baždarenje + Primanje podataka od %s Collector + diff --git a/app/src/main/res/values-it/strings-it.xml b/app/src/main/res/values-it/strings-it.xml index e99ce1481c..2c3f093e76 100644 --- a/app/src/main/res/values-it/strings-it.xml +++ b/app/src/main/res/values-it/strings-it.xml @@ -491,4 +491,11 @@ Sliding Window APRI Cancella + veloce caduta + falling + leggermente decrescente + coerente + leggermente crescente + crescente + crescente veloce diff --git a/app/src/main/res/values/locales.xml b/app/src/main/res/values/locales.xml index 8655528650..6231146ffc 100644 --- a/app/src/main/res/values/locales.xml +++ b/app/src/main/res/values/locales.xml @@ -17,6 +17,7 @@ Nederlands Italiano Suomi + Hrvatski en @@ -35,5 +36,6 @@ nl it fi + hr - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c3f9f8415c..817f0b1212 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -599,9 +599,11 @@ Repeatedly restart the collection service at any hint of missing data. Enable only if you are getting data loss. Aggressive service restarts Old method - Not Recommended! Attempts to predict readings each minute based on the past few values. - Use an out of process blukon algorithm. + Use an out of process libre algorithm. (blukon/NFC/LibreAlarm) Display Predictive Values Out of process blukon algorithm. + Apply xDrip calibration methods on OOP data. + OOP algorithm calibration. If using Share, xDrip will show values when they are normally hidden on the receiver. Interpret Raw Values If needed, use calibrations from longer ago, eg if calibrations are supplied infrequently. @@ -851,4 +853,20 @@ Received Enough Good Data to Calibrate Play sound when ready for Calibration Receiving Data from %s Collector + + + Double Down + Single Down + Slight Down + Flat + Slight Up + Single Up + Double Up + + Speak trend arrow name + Speak everything twice + Speech speed + Speech pitch + Speak Alerts + Also give some spoken alert messages diff --git a/app/src/main/res/xml/pref_advanced_settings.xml b/app/src/main/res/xml/pref_advanced_settings.xml index 494f450344..f85e49cb1a 100644 --- a/app/src/main/res/xml/pref_advanced_settings.xml +++ b/app/src/main/res/xml/pref_advanced_settings.xml @@ -251,15 +251,15 @@ + android:title="@string/Speak_Alerts" /> + android:summary="@string/Speak_trend_arrow_name" /> + android:summary="@string/Speak_everything_twice" /> + + Date: Mon, 26 Mar 2018 21:19:23 +0200 Subject: [PATCH 2/2] - set default timer for agressive service restart to 6min instead of 5 - cosmetics --- .../dexdrip/Services/MissedReadingService.java | 6 +++--- .../com/eveningoutpost/dexdrip/UtilityModels/Blukon.java | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java index 9bb0250cad..6a9180dfda 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/MissedReadingService.java @@ -152,9 +152,9 @@ private void checkBackAfterMissedTime(long alarmIn) { // alarmIn is relative time ms public void setAlarm(long alarmIn, boolean force) { - if(!force && (alarmIn < 5 * 60 * 1000)) { - // No need to check more than once every 5 minutes - alarmIn = 5 * 60 * 1000; + if(!force && (alarmIn < 6 * 60 * 1000)) { + // No need to check more than once every 6 minutes as most CGM wake-up every 5min + alarmIn = 6 * 60 * 1000; } alarmIn = Math.max(alarmIn, 5000); // don't try to set less than 5 seconds in the future diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java index d3f1d0b8ca..2a6eb7fabe 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java @@ -91,6 +91,8 @@ public static boolean isCollecting() { } } + Log.w(TAG,"isCollecting() returns: " + m_communicationStarted); + return m_communicationStarted; } @@ -99,7 +101,7 @@ public static void clearPin() { } public static void initialize() { - Log.i(TAG, "initialize!"); + Log.w(TAG, "initialize Blukon!"); Pref.setInt("bridge_battery", 0); //force battery to no-value before first reading Pref.setInt("nfc_sensor_age", 0); //force sensor age to no-value before first reading JoH.clearRatelimit(BLUKON_GETSENSORAGE_TIMER);