diff --git a/app/build.gradle b/app/build.gradle
index 6ecea2b3e1..d4b18b1df0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -192,6 +192,8 @@ dependencies {
compile "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
compile "com.google.android.gms:play-services-wearable:7.5.0"
compile(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
+ compile(name: "sightparser-release", ext: "aar")
+
compile("com.google.android:flexbox:0.3.0") {
exclude group: "com.android.support"
}
diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java
index 02576cb23d..848afb34e5 100644
--- a/app/src/main/java/info/nightscout/androidaps/MainApp.java
+++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java
@@ -54,6 +54,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
+import info.nightscout.androidaps.plugins.PumpInsight.InsightPumpPlugin;
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
@@ -129,6 +130,7 @@ public class MainApp extends Application {
if (Config.DANAR) pluginsList.add(DanaRv2Plugin.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin());
pluginsList.add(CareportalPlugin.getPlugin());
+ if (Config.APS) pluginsList.add(InsightPumpPlugin.getPlugin());
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getPlugin());
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java
new file mode 100644
index 0000000000..53b68ebc9a
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java
@@ -0,0 +1,106 @@
+package info.nightscout.androidaps.plugins.PumpInsight;
+
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.squareup.otto.Subscribe;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import info.nightscout.androidaps.MainApp;
+import info.nightscout.androidaps.R;
+import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
+import info.nightscout.androidaps.plugins.PumpInsight.connector.Connector;
+import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui;
+
+import com.crashlytics.android.Crashlytics;
+
+public class InsightPumpFragment extends SubscriberFragment {
+ private static Logger log = LoggerFactory.getLogger(InsightPumpFragment.class);
+
+ TextView basaBasalRateView;
+ TextView tempBasalView;
+ TextView extendedBolusView;
+ TextView batteryView;
+ TextView reservoirView;
+ TextView statusView;
+ Connector connector = Connector.get();
+
+ private static Handler sLoopHandler = new Handler();
+ private static Runnable sRefreshLoop = null;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (sRefreshLoop == null) {
+ sRefreshLoop = new Runnable() {
+ @Override
+ public void run() {
+ updateGUI();
+ sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
+ }
+ };
+ sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ try {
+ View view = inflater.inflate(R.layout.insightpump_fragment, container, false);
+ basaBasalRateView = (TextView) view.findViewById(R.id.insightpump_basabasalrate);
+ tempBasalView = (TextView) view.findViewById(R.id.insightpump_tempbasal);
+ extendedBolusView = (TextView) view.findViewById(R.id.insightpump_extendedbolus);
+ batteryView = (TextView) view.findViewById(R.id.insightpump_battery);
+ reservoirView = (TextView) view.findViewById(R.id.insightpump_reservoir);
+ statusView = (TextView) view.findViewById(R.id.insightpump_status);
+
+ return view;
+ } catch (Exception e) {
+ Crashlytics.logException(e);
+ }
+
+ return null;
+ }
+
+ @Subscribe
+ public void onStatusEvent(final EventInsightPumpUpdateGui ev) {
+ updateGUI();
+ }
+
+ @Override
+ protected void updateGUI() {
+ Activity activity = getActivity();
+ if (activity != null && basaBasalRateView != null)
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ InsightPumpPlugin insightPumpPlugin = InsightPumpPlugin.getPlugin();
+ basaBasalRateView.setText(insightPumpPlugin.getBaseBasalRate() + "U");
+ if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
+ tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull());
+ } else {
+ tempBasalView.setText("");
+ }
+ if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
+ extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString());
+ } else {
+ extendedBolusView.setText("");
+ }
+ batteryView.setText(insightPumpPlugin.batteryPercent + "%");
+ reservoirView.setText(insightPumpPlugin.reservoirInUnits + "U");
+
+ statusView.setText(connector.getLastStatusMessage());
+ }
+ });
+ }
+}
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
new file mode 100644
index 0000000000..ceff1c1ff3
--- /dev/null
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java
@@ -0,0 +1,207 @@
+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.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.util.Log;
+
+import info.nightscout.androidaps.MainApp;
+import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui;
+import sugar.free.sightparser.handling.ServiceConnectionCallback;
+import sugar.free.sightparser.handling.SightServiceConnector;
+import sugar.free.sightparser.handling.StatusCallback;
+import sugar.free.sightparser.pipeline.Status;
+
+/**
+ * Created by jamorham on 23/01/2018.
+ *
+ * Connects to SightRemote app service using SightParser library
+ *
+ * SightRemote and SightParser created by Tebbe Ubben
+ *
+ * Original proof of concept SightProxy by jamorham
+ *
+ */
+
+public class Connector {
+
+ private static final String TAG = "InsightConnector";
+ private static final String COMPANION_APP_PACKAGE = "sugar.free.sightremote";
+ private static final String STATUS_RECEIVER = "sugar.free.sightparser.handling.StatusCallback";
+ private static volatile Connector instance;
+ private volatile SightServiceConnector serviceConnector;
+ private volatile Status lastStatus = null;
+ private volatile long lastStatusTime = -1;
+ private boolean companionAppInstalled = false;
+ private StatusCallback statusCallback = new StatusCallback() {
+ @Override
+ public void onStatusChange(Status status) {
+
+ synchronized (this) {
+ log("Status change: " + status);
+ lastStatus = status;
+ lastStatusTime = tsl();
+ switch (status) {
+ // TODO automated reactions to change in status
+ }
+ MainApp.bus().post(new EventInsightPumpUpdateGui());
+ }
+ }
+ };
+
+ private BroadcastReceiver statusReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context ctx, Intent intent) {
+ log("Receiving broadcast!");
+ final String str = intent.getStringExtra("STATUS_MESSAGE");
+ try {
+ statusCallback.onStatusChange(str);
+ } catch (RemoteException e) {
+ log("Remote exception: " + e);
+ }
+ }
+ };
+
+ private ServiceConnectionCallback connectionCallback = new ServiceConnectionCallback() {
+ @Override
+ public void onServiceConnected() {
+ log("On service connected");
+ serviceConnector.connect();
+ statusCallback.onStatusChange(safeGetStatus());
+ }
+
+ @Override
+ public void onServiceDisconnected() {
+ log("Disconnected from service");
+ }
+ };
+
+ private Connector() {
+ registerReceiver();
+ }
+
+ public static Connector get() {
+ if (instance == null) {
+ init_instance();
+ }
+ return instance;
+ }
+
+ private synchronized static void init_instance() {
+ if (instance == null) {
+ instance = new Connector();
+ }
+ }
+
+ private static long tsl() {
+ return System.currentTimeMillis();
+ }
+
+ private static boolean isCompanionAppInstalled() {
+ return checkPackageExists(MainApp.instance(), COMPANION_APP_PACKAGE);
+ }
+
+ private static boolean checkPackageExists(Context context, String packageName) {
+ try {
+ final PackageManager pm = context.getPackageManager();
+ final PackageInfo pi = pm.getPackageInfo(packageName, 0);
+ return pi.packageName.equals(packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ } catch (Exception e) {
+ Log.wtf(TAG, "Exception trying to determine packages! " + e);
+ return false;
+ }
+ }
+
+ public static void connectToPump() {
+ log("Attempting to connect to pump");
+ get().getServiceConnector().connect();
+ }
+
+ private static void log(String msg) {
+ android.util.Log.e("PUMPPUMP", msg);
+ }
+
+ private void registerReceiver() {
+ try {
+ MainApp.instance().unregisterReceiver(statusReceiver);
+ } catch (Exception e) {
+ //
+ }
+ MainApp.instance().registerReceiver(statusReceiver, new IntentFilter(STATUS_RECEIVER));
+ }
+
+ public synchronized void init() {
+ log("init");
+ if (serviceConnector == null) {
+ companionAppInstalled = isCompanionAppInstalled();
+ if (companionAppInstalled) {
+ serviceConnector = new SightServiceConnector(MainApp.instance());
+ serviceConnector.addStatusCallback(statusCallback);
+ serviceConnector.setConnectionCallback(connectionCallback);
+ serviceConnector.connectToService();
+ log("Trying to connect");
+ } else {
+ log("Not trying init due to missing companion app");
+ }
+ }
+ }
+
+ public SightServiceConnector getServiceConnector() {
+ init();
+ return serviceConnector;
+ }
+
+ public String getCurrent() {
+ init();
+ return safeGetStatus().toString();
+ }
+
+ public Status safeGetStatus() {
+ if (isConnected()) return serviceConnector.getStatus();
+ return Status.DISCONNECTED;
+ }
+
+ public Status getLastStatus() {
+ return lastStatus;
+ }
+
+ public boolean isConnected() {
+ return serviceConnector != null && serviceConnector.isConnectedToService();
+ }
+
+ public boolean isPumpConnected() {
+ //return isConnected() && serviceConnector.isUseable();
+ return isConnected() && getLastStatus() == Status.CONNECTED;
+ }
+
+ public String getLastStatusMessage() {
+
+ if (!companionAppInstalled) {
+ return "Companion app does not appear to be installed!";
+ }
+
+ if (!isConnected()) {
+ return "Not connected to companion app!";
+ }
+
+ if (lastStatus == null) {
+ return "Unknown";
+ }
+
+ switch (lastStatus) {
+ default:
+ return lastStatus.toString();
+ }
+ }
+
+ public boolean lastStatusRecent() {
+ return true; // TODO evaluate whether current
+ }
+
+}
diff --git a/app/src/main/res/layout/insightpump_fragment.xml b/app/src/main/res/layout/insightpump_fragment.xml
new file mode 100644
index 0000000000..4d1db0eb57
--- /dev/null
+++ b/app/src/main/res/layout/insightpump_fragment.xml
@@ -0,0 +1,276 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ef4478c208..748a5cd017 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -861,5 +861,7 @@
Recovering from connection loss
Not enough insulin for bolus left in reservoir
Extended bolus delivery error
+ Insight
+ Insight
diff --git a/app/src/main/res/xml/pref_insightpump.xml b/app/src/main/res/xml/pref_insightpump.xml
new file mode 100644
index 0000000000..b760c162aa
--- /dev/null
+++ b/app/src/main/res/xml/pref_insightpump.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file