diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java index e49b10b066..49ecf1f07d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java @@ -34,17 +34,19 @@ import info.nightscout.androidaps.plugins.PumpInsight.connector.CancelBolusTaskR import info.nightscout.androidaps.plugins.PumpInsight.connector.Connector; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpCallback; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; +import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; +import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; import info.nightscout.utils.DateUtil; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import sugar.free.sightparser.applayer.AppLayerMessage; +import sugar.free.sightparser.applayer.descriptors.ActiveBolusType; +import sugar.free.sightparser.applayer.descriptors.PumpStatus; import sugar.free.sightparser.applayer.remote_control.CancelTBRMessage; import sugar.free.sightparser.applayer.remote_control.ExtendedBolusMessage; import sugar.free.sightparser.applayer.remote_control.StandardBolusMessage; -import sugar.free.sightparser.applayer.status.BolusType; -import sugar.free.sightparser.applayer.status.PumpStatus; import sugar.free.sightparser.handling.SingleMessageTaskRunner; import sugar.free.sightparser.handling.TaskRunner; import sugar.free.sightparser.handling.taskrunners.SetTBRTaskRunner; @@ -83,6 +85,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { private boolean fragmentVisible = true; private PumpDescription pumpDescription = new PumpDescription(); private double basalRate = 0; + private Connector connector; private final TaskRunner.ResultCallback statusResultHandler = new TaskRunner.ResultCallback() { @Override @@ -105,9 +108,10 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { statusResultTime = Helpers.tsl(); processStatusResult(); updateGui(); + connector.requestHistoryReSync(); + connector.requestHistorySync(); } }; - private Connector connector; private InsightPumpPlugin() { log("InsightPumpPlugin"); @@ -336,6 +340,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { lastDataTime = new Date(); // Do nothing here. we are using MainApp.getConfigBuilder().getActiveProfile().getProfile(); PumpEnactResult result = new PumpEnactResult(); + result.enacted = false; result.success = false; Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60); MainApp.bus().post(new EventNewNotification(notification)); @@ -364,25 +369,29 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - PumpEnactResult result = new PumpEnactResult(); - result.success = true; + final PumpEnactResult result = new PumpEnactResult(); result.bolusDelivered = detailedBolusInfo.insulin; result.carbsDelivered = detailedBolusInfo.carbs; result.enacted = result.bolusDelivered > 0 || result.carbsDelivered > 0; result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - final UUID cmd = deliverBolus((float) detailedBolusInfo.insulin); // actually request delivery - final Cstatus cs = async.busyWaitForCommandResult(cmd, 10000); - result.percent = 100; - result.success = cs == Cstatus.SUCCESS; + + // is there an insulin component to the treatment? + if (detailedBolusInfo.insulin > 0) { + final UUID cmd = deliverBolus((float) detailedBolusInfo.insulin); // actually request delivery + if (cmd == null) { + return pumpEnactFailure(); + } + final Cstatus cs = async.busyWaitForCommandResult(cmd, 10000); + result.success = cs.success(); + } else { + result.success = true; // always true with carb only treatments + } if (result.success) { log("Success!"); - if (Config.logPumpComm) - log.debug("Delivering treatment insulin: " + detailedBolusInfo.insulin + "U carbs: " + detailedBolusInfo.carbs + "g " + result); - final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); bolusingEvent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), detailedBolusInfo.insulin); bolusingEvent.percent = 100; @@ -391,9 +400,14 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { } else { log.debug("Failure to deliver treatment"); } - MainApp.bus().post(new EventInsightPumpUpdateGui()); - lastDataTime = new Date(); + if (Config.logPumpComm) + log.debug("Delivering treatment insulin: " + detailedBolusInfo.insulin + "U carbs: " + detailedBolusInfo.carbs + "g " + result); + + updateGui(); + + lastDataTime = new Date(); + connector.requestHistorySync(30000); return result; } @@ -422,7 +436,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).isPercent(false).duration(durationInMinutes); pumpEnactResult.absolute = absoluteRate; // TODO get converted value? - pumpEnactResult.success = cs == Cstatus.SUCCESS; + pumpEnactResult.success = cs.success(); pumpEnactResult.isTempCancel = false; // do we test this here? pumpEnactResult.comment = async.getCommandComment(cmd); @@ -443,6 +457,9 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { lastDataTime = new Date(); updateGui(); + + connector.requestHistorySync(5000); + return pumpEnactResult; } @@ -461,7 +478,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).isPercent(true).duration(durationInMinutes); pumpEnactResult.percent = percent; - pumpEnactResult.success = cs == Cstatus.SUCCESS; + pumpEnactResult.success = cs.success(); pumpEnactResult.isTempCancel = percent == 100; // 100% temp basal is a cancellation pumpEnactResult.comment = async.getCommandComment(cmd); @@ -477,6 +494,12 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { } updateGui(); + + if (Config.logPumpComm) + log.debug("Set temp basal " + percent + "% for " + durationInMinutes + "m"); + + connector.requestHistorySync(5000); + return pumpEnactResult; } @@ -493,6 +516,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { // TODO isn't conditional on one apparently being in progress only the history change boolean enacted = false; final Cstatus cs = async.busyWaitForCommandResult(cmd, 10000); + if (MainApp.getConfigBuilder().isTempBasalInProgress()) { enacted = true; TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); @@ -504,7 +528,9 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { if (Config.logPumpComm) log.debug("Canceling temp basal: "); // TODO get more info - return new PumpEnactResult().success(cs == Cstatus.SUCCESS).enacted(true).isTempCancel(true); + connector.requestHistorySync(5000); + + return new PumpEnactResult().success(cs.success()).enacted(true).isTempCancel(true); } @@ -525,7 +551,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { log("Got command status: " + cs); PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).bolusDelivered(insulin).duration(durationInMinutes); - pumpEnactResult.success = cs == Cstatus.SUCCESS; + pumpEnactResult.success = cs.success(); pumpEnactResult.comment = async.getCommandComment(cmd); if (pumpEnactResult.success) { @@ -542,6 +568,9 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { log.debug("Setting extended bolus: " + insulin + " mins:" + durationInMinutes + " " + pumpEnactResult.comment); updateGui(); + + connector.requestHistorySync(30000); + return pumpEnactResult; } @@ -552,7 +581,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { // TODO note always sends cancel to pump but only changes history if present - final UUID cmd = aSyncTaskRunner(new CancelBolusTaskRunner(connector.getServiceConnector(), BolusType.EXTENDED), "Cancel extended bolus"); + final UUID cmd = aSyncTaskRunner(new CancelBolusTaskRunner(connector.getServiceConnector(), ActiveBolusType.EXTENDED), "Cancel extended bolus"); if (cmd == null) { return pumpEnactFailure(); @@ -560,8 +589,6 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { final Cstatus cs = async.busyWaitForCommandResult(cmd, 10000); - // TODO logging? history - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { ExtendedBolus exStop = new ExtendedBolus(System.currentTimeMillis()); exStop.source = Source.USER; @@ -569,19 +596,22 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { MainApp.getConfigBuilder().addToHistoryExtendedBolus(exStop); } + if (Config.logPumpComm) + log.debug("Cancel extended bolus:"); + updateGui(); - return new PumpEnactResult().success(cs == Cstatus.SUCCESS).enacted(true); + connector.requestHistorySync(5000); + return new PumpEnactResult().success(cs.success()).enacted(true); } private synchronized UUID deliverBolus(float bolusValue) { - log("!!!!!!!!!! DeliverBolus: " + bolusValue); + log("DeliverBolus: " + bolusValue); // Bare sanity checking should be done elsewhere if (bolusValue == 0) return null; - if (bolusValue < 0) return null; if (bolusValue > 20) return null; @@ -594,76 +624,6 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { return aSyncSingleCommand(message, "Deliver Bolus " + bolusValue); } - - /* - @Override - public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); - PumpEnactResult result = cancelExtendedBolus(); - if (!result.success) - return result; - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = System.currentTimeMillis(); - extendedBolus.insulin = insulin; - extendedBolus.durationInMinutes = durationInMinutes; - extendedBolus.source = Source.USER; - result.success = false; - result.enacted = true; - result.bolusDelivered = insulin; - result.isTempCancel = false; - result.duration = durationInMinutes; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - treatmentsInterface.addToHistoryExtendedBolus(extendedBolus); - if (Config.logPumpComm) - log.debug("Setting extended bolus: " + result); - MainApp.bus().post(new EventInsightPumpUpdateGui()); - lastDataTime = new Date(); - return result; - } - */ - - /* @Override - public PumpEnactResult cancelTempBasal(boolean force) { - TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); - PumpEnactResult result = new PumpEnactResult(); - result.success = true; - result.isTempCancel = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - if (treatmentsInterface.isTempBasalInProgress()) { - result.enacted = true; - TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); - tempStop.source = Source.USER; - treatmentsInterface.addToHistoryTempBasal(tempStop); - //tempBasal = null; - if (Config.logPumpComm) - log.debug("Canceling temp basal: " + result); - MainApp.bus().post(new EventInsightPumpUpdateGui()); - } - lastDataTime = new Date(); - return result; - } -*/ - /* @Override - public PumpEnactResult cancelExtendedBolus() { - TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); - PumpEnactResult result = new PumpEnactResult(); - if (treatmentsInterface.isInHistoryExtendedBoluslInProgress()) { - ExtendedBolus exStop = new ExtendedBolus(System.currentTimeMillis()); - exStop.source = Source.USER; - treatmentsInterface.addToHistoryExtendedBolus(exStop); - } - result.success = false; - result.enacted = true; - result.isTempCancel = true; - result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - if (Config.logPumpComm) - log.debug("Canceling extended basal: " + result); - MainApp.bus().post(new EventInsightPumpUpdateGui()); - lastDataTime = new Date(); - return result; - }*/ - - @Override public JSONObject getJSONStatus() { @@ -725,7 +685,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { if (statusResult != null) { batteryPercent = statusResult.getBatteryAmountMessage().getBatteryAmount(); reservoirInUnits = (int) statusResult.getCartridgeAmountMessage().getCartridgeAmount(); - basalRate = roundDouble(statusResult.getCurrentBasalMessage().getCurrentBasalAmount(),2); + basalRate = roundDouble(statusResult.getCurrentBasalMessage().getCurrentBasalAmount(), 2); initialized = true; // basic communication test } } @@ -734,13 +694,13 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { return MainApp.instance().getString(id); } - public List getStatusItems() { + List getStatusItems() { final List l = new ArrayList<>(); // Todo last contact time l.add(new StatusItem("Status", connector.getLastStatusMessage())); - l.add(new StatusItem("Changed",connector.getNiceLastStatusTime())); + l.add(new StatusItem("Changed", connector.getNiceLastStatusTime())); boolean pumpRunning; // also check time since received @@ -780,13 +740,21 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface { } } + l.add(new StatusItem("Log book", HistoryReceiver.getStatusString())); + + if (LiveHistory.getStatus().length() > 0) { + l.add(new StatusItem("Last Action", LiveHistory.getStatus())); + } + + Connector.get().requestHistorySync(); + if (connector.uiFresh()) { Helpers.runOnUiThreadDelayed(new Runnable() { @Override public void run() { updateGui(); } - },1000); + }, 1000); } return l; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java index eda17c7a36..189cb3ed01 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java @@ -1,19 +1,21 @@ package info.nightscout.androidaps.plugins.PumpInsight.connector; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; +import android.os.PowerManager; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; +import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; +import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; import sugar.free.sightparser.handling.ServiceConnectionCallback; import sugar.free.sightparser.handling.SightServiceConnector; import sugar.free.sightparser.handling.StatusCallback; import sugar.free.sightparser.pipeline.Status; +import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_START_RESYNC; +import static sugar.free.sightparser.handling.HistoryBroadcast.ACTION_START_SYNC; + /** * Created by jamorham on 23/01/2018. * @@ -27,33 +29,31 @@ import sugar.free.sightparser.pipeline.Status; public class Connector { + //public static final String ACTION_START_RESYNC = "sugar.free.sightremote.services.HistorySyncService.START_RESYNC"; private static final String TAG = "InsightConnector"; private static final String COMPANION_APP_PACKAGE = "sugar.free.sightremote"; - private static final String HISTORY_IDENTIFIER = "sugar.free.sightremote.history"; - private static final String HISTORY_RECEIVER = "sugar.free.sightremote.HISTORY"; + private final static long FRESH_MS = 70000; private static volatile Connector instance; + private static volatile HistoryReceiver historyReceiver; private volatile SightServiceConnector serviceConnector; private volatile Status lastStatus = null; private volatile long lastStatusTime = -1; private boolean companionAppInstalled = false; private int serviceReconnects = 0; - private StatusCallback statusCallback = new StatusCallback() { @Override public synchronized void onStatusChange(Status status) { - log("Status change: " + status); - lastStatus = status; - lastStatusTime = Helpers.tsl(); - switch (status) { - // TODO automated reactions to change in status - } - MainApp.bus().post(new EventInsightPumpUpdateGui()); - } + log("Status change: " + status); + lastStatus = status; + lastStatusTime = Helpers.tsl(); + + MainApp.bus().post(new EventInsightPumpUpdateGui()); + } }; - private ServiceConnectionCallback connectionCallback = new ServiceConnectionCallback() { + @Override public synchronized void onServiceConnected() { log("On service connected"); @@ -80,24 +80,8 @@ public class Connector { } }; - private BroadcastReceiver historyReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - log("Receiving history broadcast!"); - - // TODO check action - final Bundle bundle = intent.getBundleExtra(HISTORY_IDENTIFIER); - if (bundle != null) { - //HistoryArray history = (HistoryArray) bundle.getSerializable("history"); - } else { - log("History bundle was null!"); - } - } - }; - - private Connector() { - registerHistoryReceiver(); + initializeHistoryReceiver(); } public static Connector get() { @@ -126,6 +110,13 @@ public class Connector { android.util.Log.e("INSIGHTPUMP", msg); } + @SuppressWarnings("AccessStaticViaInstance") + private synchronized void initializeHistoryReceiver() { + if (historyReceiver == null) { + historyReceiver = new HistoryReceiver(); + } + historyReceiver.registerHistoryReceiver(); + } public synchronized void init() { log("Connector::init()"); @@ -224,7 +215,11 @@ public class Connector { public boolean uiFresh() { // todo check other changes - if (Helpers.msSince(lastStatusTime) < 70000) { + + if (Helpers.msSince(lastStatusTime) < FRESH_MS) { + return true; + } + if (Helpers.msSince(LiveHistory.getStatusTime()) < FRESH_MS) { return true; } return false; @@ -241,15 +236,48 @@ public class Connector { } } - private synchronized void registerHistoryReceiver() { - try { - MainApp.instance().unregisterReceiver(historyReceiver); - } catch (Exception e) { - // + public void requestHistorySync() { + requestHistorySync(0); + } + + public void requestHistoryReSync() { + requestHistoryReSync(0); + } + + public void requestHistorySync(long delay) { + if (Helpers.ratelimit("insight-history-sync-request", 10)) { + final Intent intent = new Intent(ACTION_START_SYNC); + sendBroadcastToCompanion(intent, delay); } - MainApp.instance().registerReceiver(historyReceiver, new IntentFilter(HISTORY_RECEIVER)); + } + public void requestHistoryReSync(long delay) { + if (Helpers.ratelimit("insight-history-resync-request", 300)) { + final Intent intent = new Intent(ACTION_START_RESYNC); + sendBroadcastToCompanion(intent, delay); + } + } + private void sendBroadcastToCompanion(final Intent intent, final long delay) { + new Thread(new Runnable() { + @Override + public void run() { + final PowerManager.WakeLock wl = Helpers.getWakeLock("insight-companion-delay", 60000); + intent.setPackage(COMPANION_APP_PACKAGE); + intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + try { + if (delay > 0) { + + Thread.sleep(delay); + } + } catch (InterruptedException e) { + // + } finally { + Helpers.releaseWakeLock(wl); + } + MainApp.instance().sendBroadcast(intent); + } + }).start(); } public boolean lastStatusRecent() {