From e50c6fc8ed51a8db40b52e2a7541e03f54a5165b Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Mon, 25 Dec 2017 20:39:14 +0100 Subject: [PATCH 01/27] RS BLE modifications --- .../plugins/PumpDanaRS/services/BLEComm.java | 2 ++ .../androidaps/queue/QueueThread.java | 26 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java index f8d18a4d22..15b57231ea 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java @@ -164,6 +164,8 @@ public class BLEComm { scheduledDisconnection = null; if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { + log.debug("disconnect not possible: (mBluetoothAdapter == null) " + (mBluetoothAdapter == null)); + log.debug("disconnect not possible: (mBluetoothGatt == null) " + (mBluetoothGatt == null)); return; } setCharacteristicNotification(getUARTReadBTGattChar(), false); diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java index dd02c5e973..c0915d96e4 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java @@ -16,6 +16,8 @@ import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.queue.events.EventQueueChanged; import info.nightscout.utils.SP; @@ -52,12 +54,6 @@ public class QueueThread extends Thread { while (true) { PumpInterface pump = ConfigBuilderPlugin.getActivePump(); long secondsElapsed = (System.currentTimeMillis() - connectionStartTime) / 1000; - if (pump.isConnecting()) { - log.debug("QUEUE: connecting " + secondsElapsed); - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); - SystemClock.sleep(1000); - continue; - } if (!pump.isConnected() && secondsElapsed > Constants.PUMP_MAX_CONNECTION_TIME_IN_SECONDS) { MainApp.bus().post(new EventDismissBolusprogressIfRunning(new PumpEnactResult())); @@ -74,19 +70,37 @@ public class QueueThread extends Thread { //write time SP.putLong(R.string.key_btwatchdog_lastbark, System.currentTimeMillis()); //toggle BT + pump.stopConnecting(); + pump.disconnect("watchdog"); + SystemClock.sleep(1000); BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter.disable(); SystemClock.sleep(1000); mBluetoothAdapter.enable(); SystemClock.sleep(1000); //start over again once after watchdog barked + //Notification notification = new Notification(Notification.OLD_NSCLIENT, "Watchdog", Notification.URGENT); + //MainApp.bus().post(new EventNewNotification(notification)); connectionStartTime = lastCommandTime = System.currentTimeMillis(); + pump.connect("watchdog"); } else { queue.clear(); + log.debug("QUEUE: no connection possible"); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); + pump.disconnect("Queue empty"); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); return; } } + if (pump.isConnecting()) { + log.debug("QUEUE: connecting " + secondsElapsed); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); + SystemClock.sleep(1000); + continue; + } + + if (!pump.isConnected()) { log.debug("QUEUE: connect"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); From 3962808626f657529d0072ac35327286b40dd71b Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Sun, 21 Jan 2018 19:05:04 +0100 Subject: [PATCH 02/27] minimum of 30 min for unreachable alert --- .../info/nightscout/androidaps/MainActivity.java | 15 ++++++++++++++- app/src/main/res/xml/pref_others.xml | 11 ++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index b702897ba4..e77be36ba6 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -82,7 +82,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe Manifest.permission.WRITE_EXTERNAL_STORAGE}, CASE_STORAGE); } askForBatteryOptimizationPermission(); - checkUpgradeToProfileTarget(); + doMigrations(); if (Config.logFunctionCalls) log.debug("onCreate"); @@ -163,6 +163,19 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } } + private void doMigrations() { + + checkUpgradeToProfileTarget(); + + // guarantee that the unreachable threshold is at least 30 and of type String + // Added in 1.57 at 21.01.2018 + Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30); + SP.remove(R.string.key_pump_unreachable_threshold); + if(unreachable_threshold < 30) unreachable_threshold = 30; + SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString()); + } + + private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future boolean oldKeyExists = SP.contains("openapsma_min_bg"); if (oldKeyExists) { diff --git a/app/src/main/res/xml/pref_others.xml b/app/src/main/res/xml/pref_others.xml index 548b99e5b9..ba16f09c2f 100644 --- a/app/src/main/res/xml/pref_others.xml +++ b/app/src/main/res/xml/pref_others.xml @@ -1,5 +1,6 @@ - + @@ -76,12 +77,16 @@ android:defaultValue="true" android:key="@string/key_enable_pump_unreachable_alert" android:title="@string/enable_pump_unreachable_alert" /> - + android:title="@string/pump_unreachable_threshold"> + Date: Sun, 21 Jan 2018 22:51:30 +0100 Subject: [PATCH 03/27] fix stopping bolus connection error --- .../java/info/nightscout/androidaps/queue/CommandQueue.java | 2 -- .../main/java/info/nightscout/androidaps/queue/QueueThread.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java index 3e696e9857..04da1cd9a9 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java @@ -147,8 +147,6 @@ public class CommandQueue { public static void independentConnect(String reason, Callback callback) { CommandQueue tempCommandQueue = new CommandQueue(); tempCommandQueue.readStatus(reason, callback); - QueueThread tempThread = new QueueThread(tempCommandQueue); - tempThread.start(); } // returns true if command is queued diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java index acff83a1d2..d257bd24d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java @@ -35,7 +35,7 @@ public class QueueThread extends Thread { private PowerManager.WakeLock mWakeLock; public QueueThread(CommandQueue queue) { - super(QueueThread.class.toString()); + super(); this.queue = queue; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); From ef2a565c18d9bf1117a9f7a82119c8f2e5b1f26e Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 21 Jan 2018 23:20:41 +0100 Subject: [PATCH 04/27] set maxiob=0 only for objective 4 --- .../ConstraintsObjectives/ObjectivesFragment.java | 1 + .../ConstraintsObjectives/ObjectivesPlugin.java | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java index f633c1b5ac..e4eef9ff2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java @@ -197,6 +197,7 @@ public class ObjectivesFragment extends Fragment { ObjectivesPlugin.objectives.get(4).objective = MainApp.sResources.getString(R.string.objectives_4_objective); ObjectivesPlugin.objectives.get(5).objective = MainApp.sResources.getString(R.string.objectives_5_objective); ObjectivesPlugin.objectives.get(6).objective = MainApp.sResources.getString(R.string.objectives_6_objective); + ObjectivesPlugin.objectives.get(7).objective = MainApp.sResources.getString(R.string.objectives_7_objective); ObjectivesPlugin.objectives.get(0).gate = MainApp.sResources.getString(R.string.objectives_0_gate); ObjectivesPlugin.objectives.get(1).gate = MainApp.sResources.getString(R.string.objectives_1_gate); ObjectivesPlugin.objectives.get(2).gate = MainApp.sResources.getString(R.string.objectives_2_gate); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java index 794f66ef60..3b0891680d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java @@ -161,14 +161,14 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginBase.PUMP); boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false); boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled; - boolean hasBGData = DatabaseHelper.lastBg()!=null; + boolean hasBGData = DatabaseHelper.lastBg() != null; boolean apsEnabled = false; APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginBase.APS)) apsEnabled = true; - return new RequirementResult(hasBGData&&bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded, + return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded, MainApp.sResources.getString(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS) + "\n" + MainApp.sResources.getString(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission()) + (isVirtualPump ? "\n" + MainApp.sResources.getString(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "") @@ -187,7 +187,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { return new RequirementResult(closedModeEnabled, MainApp.sResources.getString(R.string.closedmodeenabled) + ": " + yesOrNo(closedModeEnabled)); case 4: double maxIOB = MainApp.getConfigBuilder().applyMaxIOBConstraints(1000d); - boolean maxIobSet = maxIOB > 0; + boolean maxIobSet = maxIOB > 0; return new RequirementResult(maxIobSet, MainApp.sResources.getString(R.string.maxiobset) + ": " + yesOrNo(maxIobSet)); default: return new RequirementResult(true, ""); @@ -320,12 +320,12 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { @Override public Double applyMaxIOBConstraints(Double maxIob) { - if (objectives.get(4).started.getTime() > 0 || objectives.get(2).accomplished.getTime() == 0) - return maxIob; - else { + if (objectives.get(3).started.getTime() > 0 && objectives.get(3).accomplished.getTime() == 0) { if (Config.logConstraintsChanges) log.debug("Limiting maxIOB " + maxIob + " to " + 0 + "U"); return 0d; + } else { + return maxIob; } } From f5a2c5bcd2e0319991d74d7e69bfdedb5e8d66ba Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 21 Jan 2018 23:38:24 +0100 Subject: [PATCH 05/27] cancel extending bolus on pump disconnection --- .../plugins/Overview/OverviewFragment.java | 40 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 41 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 3228b16198..a8ad9c7074 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -497,6 +497,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); + } + } + }); + } NSUpload.uploadOpenAPSOffline(30); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) { @@ -510,6 +520,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); + } + } + }); + } NSUpload.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) { @@ -523,6 +543,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); + } + } + }); + } NSUpload.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) { @@ -536,6 +566,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); + } + } + }); + } NSUpload.uploadOpenAPSOffline(180); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4d875c7d99..ef4478c208 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -860,5 +860,6 @@ Delivering the bolus and verifying the pump\'s history failed, please check the pump and manually create a bolus record using the Careportal tab if a bolus was delivered. Recovering from connection loss Not enough insulin for bolus left in reservoir + Extended bolus delivery error From f835c272adc129b54f75e492b0416de629c9d8e3 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 22 Jan 2018 17:18:18 +0100 Subject: [PATCH 06/27] more autosens logging --- .../plugins/IobCobCalculator/IobCobCalculatorPlugin.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index fbbbe43ccc..3522d3fc1e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -33,6 +33,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; +import info.nightscout.utils.DateUtil; /** * Created by mike on 24.04.2017. @@ -580,11 +581,11 @@ public class IobCobCalculatorPlugin implements PluginBase { return null; } if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) { - log.debug("AUTOSENSDATA null: data is old (" + reason + ")"); + log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time)); return null; } else { if (data == null) - log.debug("AUTOSENSDATA null: data == null (" + " " + reason + ")"); + log.debug("AUTOSENSDATA null: data == null (" + " " + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time)); return data; } } From d033407ba75865dd191d2c4af72419335b7da6d6 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 22 Jan 2018 19:12:22 +0100 Subject: [PATCH 07/27] fix rendering treatments with duration --- .../plugins/Overview/graphData/GraphData.java | 2 +- .../PointsWithLabelGraphSeries.java | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java index e76714c5b2..5d5a0832d5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java @@ -253,7 +253,7 @@ public class GraphData { } // Careportal - List careportalEvents = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, true); + List careportalEvents = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true); for (int tx = 0; tx < careportalEvents.size(); tx++) { DataPointWithLabelInterface t = careportalEvents.get(tx); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java index 7606a71f17..26892372d5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -141,9 +141,6 @@ public class PointsWithLabelGraphSeries e Iterator values = getValues(minX, maxX); // draw background - double lastEndY = 0; - double lastEndX = 0; - // draw data double diffY = maxY - minY; @@ -154,9 +151,8 @@ public class PointsWithLabelGraphSeries e float graphLeft = graphView.getGraphContentLeft(); float graphTop = graphView.getGraphContentTop(); - lastEndY = 0; - lastEndX = 0; - float firstX = 0; + float scaleX = (float) (graphWidth / diffX); + int i=0; while (values.hasNext()) { E value = values.next(); @@ -171,9 +167,6 @@ public class PointsWithLabelGraphSeries e double ratX = valX / diffX; double x = graphWidth * ratX; - double orgX = x; - double orgY = y; - // overdraw boolean overdraw = false; if (x > graphWidth) { // end right @@ -185,6 +178,14 @@ public class PointsWithLabelGraphSeries e if (y > graphHeight) { // end top overdraw = true; } + + long duration = value.getDuration(); + float endWithDuration = (float) (x + duration * scaleX + graphLeft + 1); + // cut off to graph start if needed + if (x < 0 && endWithDuration > 0) { + x = 0; + } + /* Fix a bug that continue to show the DOT after Y axis */ if(x < 0) { overdraw = true; @@ -195,8 +196,8 @@ public class PointsWithLabelGraphSeries e registerDataPoint(endX, endY, value); float xpluslength = 0; - if (value.getDuration() > 0) { - xpluslength = endX + Math.min((float) (value.getDuration() * graphWidth / diffX), graphLeft + graphWidth); + if (duration > 0) { + xpluslength = Math.min(endWithDuration, graphLeft + graphWidth); } // draw data point From 52e4496add447eea216d1d66b2ef6f3c56d744cc Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 22 Jan 2018 21:49:01 +0100 Subject: [PATCH 08/27] Careportal DB browser --- .../nightscout/androidaps/data/Profile.java | 1 + .../androidaps/db/CareportalEvent.java | 11 + .../androidaps/db/DatabaseHelper.java | 16 +- .../Treatments/TreatmentsFragment.java | 9 + .../TreatmentsCareportalFragment.java | 192 ++++++++++++++++++ .../layout/treatments_careportal_fragment.xml | 28 +++ .../res/layout/treatments_careportal_item.xml | 104 ++++++++++ .../main/res/layout/treatments_fragment.xml | 10 + 8 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java create mode 100644 app/src/main/res/layout/treatments_careportal_fragment.xml create mode 100644 app/src/main/res/layout/treatments_careportal_item.xml diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java index 5235545362..7bb693ef23 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -239,6 +239,7 @@ public class Profile { // if pump not available (at start) // do not store converted array basal_v = null; + isValidated = false; } } diff --git a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java index b80f4f932e..8c55034c9f 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -191,6 +191,17 @@ public class CareportalEvent implements DataPointWithLabelInterface { return Translator.translate(eventType); } + public String getNotes() { + try { + JSONObject object = new JSONObject(json); + if (object.has("notes")) + return object.getString("notes"); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + return ""; + } + @Override public long getDuration() { try { diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 69bc542dae..8613f18ab5 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -1473,7 +1473,21 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } catch (SQLException e) { log.error("Unhandled exception", e); } - return new ArrayList(); + return new ArrayList<>(); + } + + public List getCareportalEventsFromTime(boolean ascending) { + try { + List careportalEvents; + QueryBuilder queryBuilder = getDaoCareportalEvents().queryBuilder(); + queryBuilder.orderBy("date", ascending); + PreparedQuery preparedQuery = queryBuilder.prepare(); + careportalEvents = getDaoCareportalEvents().query(preparedQuery); + return careportalEvents; + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return new ArrayList<>(); } public void deleteCareportalEventById(String _id) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java index 6fcbcfe951..b10ad96697 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java @@ -20,6 +20,7 @@ import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsBolusFragment; +import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsCareportalFragment; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsExtendedBolusesFragment; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsProfileSwitchFragment; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsTempTargetFragment; @@ -33,6 +34,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli TextView tempBasalsTab; TextView tempTargetTab; TextView profileSwitchTab; + TextView careportalTab; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -45,11 +47,13 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli tempBasalsTab = (TextView) view.findViewById(R.id.treatments_tempbasals); tempTargetTab = (TextView) view.findViewById(R.id.treatments_temptargets); profileSwitchTab = (TextView) view.findViewById(R.id.treatments_profileswitches); + careportalTab = (TextView) view.findViewById(R.id.treatments_careportal); treatmentsTab.setOnClickListener(this); extendedBolusesTab.setOnClickListener(this); tempBasalsTab.setOnClickListener(this); tempTargetTab.setOnClickListener(this); profileSwitchTab.setOnClickListener(this); + careportalTab.setOnClickListener(this); setFragment(new TreatmentsBolusFragment()); setBackgroundColorOnSelected(treatmentsTab); @@ -87,6 +91,10 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli setFragment(new TreatmentsProfileSwitchFragment()); setBackgroundColorOnSelected(profileSwitchTab); break; + case R.id.treatments_careportal: + setFragment(new TreatmentsCareportalFragment()); + setBackgroundColorOnSelected(careportalTab); + break; } } @@ -104,6 +112,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli tempBasalsTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground)); tempTargetTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground)); profileSwitchTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground)); + careportalTab.setBackgroundColor(MainApp.sResources.getColor(R.color.defaultbackground)); selected.setBackgroundColor(MainApp.sResources.getColor(R.color.tabBgColorSelected)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java new file mode 100644 index 0000000000..7218198b43 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java @@ -0,0 +1,192 @@ +package info.nightscout.androidaps.plugins.Treatments.fragments; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Paint; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.CardView; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import com.squareup.otto.Subscribe; + +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.events.EventCareportalEventChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.NSUpload; +import info.nightscout.utils.SP; +import info.nightscout.utils.Translator; + +/** + * Created by mike on 13/01/17. + */ + +public class TreatmentsCareportalFragment extends SubscriberFragment implements View.OnClickListener { + + RecyclerView recyclerView; + LinearLayoutManager llm; + Button refreshFromNS; + + Context context; + + public class RecyclerViewAdapter extends RecyclerView.Adapter { + + List careportalEventList; + + RecyclerViewAdapter(List careportalEventList) { + this.careportalEventList = careportalEventList; + } + + @Override + public CareportalEventsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.treatments_careportal_item, viewGroup, false); + CareportalEventsViewHolder CareportalEventsViewHolder = new CareportalEventsViewHolder(v); + return CareportalEventsViewHolder; + } + + @Override + public void onBindViewHolder(CareportalEventsViewHolder holder, int position) { + CareportalEvent careportalEvent = careportalEventList.get(position); + holder.ns.setVisibility(NSUpload.isIdValid(careportalEvent._id) ? View.VISIBLE : View.GONE); + holder.date.setText(DateUtil.dateAndTimeString(careportalEvent.date)); + holder.note.setText(careportalEvent.getNotes()); + holder.type.setText(Translator.translate(careportalEvent.eventType)); + holder.remove.setTag(careportalEvent); + } + + @Override + public int getItemCount() { + return careportalEventList.size(); + } + + @Override + public void onAttachedToRecyclerView(RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + } + + public class CareportalEventsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + CardView cv; + TextView date; + TextView type; + TextView note; + TextView remove; + TextView ns; + + CareportalEventsViewHolder(View itemView) { + super(itemView); + cv = (CardView) itemView.findViewById(R.id.careportal_cardview); + date = (TextView) itemView.findViewById(R.id.careportal_date); + type = (TextView) itemView.findViewById(R.id.careportal_type); + note = (TextView) itemView.findViewById(R.id.careportal_note); + ns = (TextView) itemView.findViewById(R.id.ns_sign); + remove = (TextView) itemView.findViewById(R.id.careportal_remove); + remove.setOnClickListener(this); + remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + } + + @Override + public void onClick(View v) { + final CareportalEvent careportalEvent = (CareportalEvent) v.getTag(); + switch (v.getId()) { + case R.id.careportal_remove: + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(MainApp.sResources.getString(R.string.confirmation)); + builder.setMessage(MainApp.sResources.getString(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(careportalEvent.date)); + builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + final String _id = careportalEvent._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); + } + MainApp.getDbHelper().delete(careportalEvent); + } + }); + builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); + builder.show(); + break; + } + } + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.treatments_careportal_fragment, container, false); + + recyclerView = (RecyclerView) view.findViewById(R.id.careportal_recyclerview); + recyclerView.setHasFixedSize(true); + llm = new LinearLayoutManager(view.getContext()); + recyclerView.setLayoutManager(llm); + + RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false)); + recyclerView.setAdapter(adapter); + + refreshFromNS = (Button) view.findViewById(R.id.careportal_refreshfromnightscout); + refreshFromNS.setOnClickListener(this); + + context = getContext(); + + boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); + if (nsUploadOnly) + refreshFromNS.setVisibility(View.GONE); + + updateGUI(); + return view; + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.careportal_refreshfromnightscout: + AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext()); + builder.setTitle(this.getContext().getString(R.string.confirmation)); + builder.setMessage(this.getContext().getString(R.string.refresheventsfromnightscout) + " ?"); + builder.setPositiveButton(this.getContext().getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + MainApp.getDbHelper().resetCareportalEvents(); + Intent restartNSClient = new Intent(Intents.ACTION_RESTART); + MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); + } + }); + builder.setNegativeButton(this.getContext().getString(R.string.cancel), null); + builder.show(); + break; + } + + } + + @Subscribe + public void onStatusEvent(final EventCareportalEventChange ev) { + updateGUI(); + } + + @Override + protected void updateGUI() { + Activity activity = getActivity(); + if (activity != null) + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false)), false); + } + }); + } +} diff --git a/app/src/main/res/layout/treatments_careportal_fragment.xml b/app/src/main/res/layout/treatments_careportal_fragment.xml new file mode 100644 index 0000000000..710afed7bb --- /dev/null +++ b/app/src/main/res/layout/treatments_careportal_fragment.xml @@ -0,0 +1,28 @@ + + + + +