diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index bc33c025a2..a709c33d18 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -68,6 +68,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; +import info.nightscout.androidaps.plugins.PumpMedtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin; @@ -174,8 +175,10 @@ public class MainApp extends Application { if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin()); pluginsList.add(CareportalPlugin.getPlugin()); - if (Config.PUMPDRIVERS && engineeringMode) + if (Config.PUMPDRIVERS && engineeringMode) { pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here + pluginsList.add(MedtronicPumpPlugin.getPlugin()); + } if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin()); if (Config.MDI) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkCommunicationManager.java index 85c0dad718..9265be5849 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkCommunicationManager.java @@ -211,7 +211,7 @@ public abstract class RileyLinkCommunicationManager { byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)0, - (byte)0, (byte)0, 500, (byte)0); + (byte)0, (byte)0, 1000, (byte)0); if (resp.wasTimeout()) { LOG.error("scanForPump: Failed to find pump at frequency {}", frequencies[i]); } else if (resp.looksLikeRadioPacket()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkUtil.java index 2c8b4e4c00..2a1393de02 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/RileyLinkUtil.java @@ -55,7 +55,7 @@ public class RileyLinkUtil { private static RileyLinkTargetFrequency rileyLinkTargetFrequency; // Broadcasts: RileyLinkBLE, RileyLinkService, - //private static RileyLinkIPCConnection rileyLinkIPCConnection; + // private static RileyLinkIPCConnection rileyLinkIPCConnection; private static RileyLinkTargetDevice targetDevice; private static RileyLinkEncodingType encoding; private static RileyLinkSelectPreference rileyLinkSelectPreference; @@ -157,7 +157,8 @@ public class RileyLinkUtil { public static boolean sendNotification(ServiceNotification notification, Integer clientHashcode) { - return RileyLinkUtil.rileyLinkService.sendNotification(notification, clientHashcode); + // return RileyLinkUtil.rileyLinkIPCConnection.sendNotification(notification, clientHashcode); + return false; } @@ -200,6 +201,10 @@ public class RileyLinkUtil { // RileyLinkUtil.rileyLinkIPCConnection = rileyLinkIPCConnection; // } + // public static RileyLinkIPCConnection getRileyLinkIPCConnection() { + // return RileyLinkUtil.rileyLinkIPCConnection; + // } + public static RileyLinkTargetFrequency getRileyLinkTargetFrequency() { return RileyLinkUtil.rileyLinkTargetFrequency; } @@ -217,6 +222,7 @@ public class RileyLinkUtil { } + @Deprecated public static BleAdvertisedData parseAdertisedData(byte[] advertisedData) { List uuids = new ArrayList(); String name = null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/RFTools.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/RFTools.java index eac1215a9b..4b8ec223f2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/RFTools.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/RFTools.java @@ -11,6 +11,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.CRC; /** * Created by geoff on 7/31/15. */ +// TODO refactor this DRY public class RFTools { public static final byte[] codes = new byte[] { 21, 49, 50, 35, 52, 37, 38, 22, 26, 25, 42, 11, 44, 13, 14, 28 }; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/data/RadioResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/data/RadioResponse.java index 5c4fb6b793..6e66e7b467 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/data/RadioResponse.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/ble/data/RadioResponse.java @@ -100,8 +100,17 @@ public class RadioResponse { decodedPayload = encodedPayload; break; case FourByteSixByte: + LOG.debug("encodedPayload: {}", ByteUtil.getHex(encodedPayload)); byte[] decodeThis = RFTools.decode4b6b(encodedPayload); + LOG.debug("decodedPayload: {}", ByteUtil.getHex(decodeThis)); decodedOK = true; + + if (decodeThis == null || decodeThis.length == 0) { + LOG.error("Decoded payload length is zero."); + decodedOK = false; + return; + } + decodedPayload = ByteUtil.substring(decodeThis, 0, decodeThis.length - 1); receivedCRC = decodeThis[decodeThis.length - 1]; byte calculatedCRC = CRC.crc8(decodedPayload); @@ -114,7 +123,7 @@ public class RadioResponse { throw new NotImplementedException("this {" + RileyLinkUtil.getEncoding().toString() + "} encoding is not supported"); } - } catch (NumberFormatException e) { + } catch (NumberFormatException e) { decodedOK = false; LOG.error("Failed to decode radio data: " + ByteUtil.shortHexString(encodedPayload)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkBroadcastReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkBroadcastReceiver.java new file mode 100644 index 0000000000..f7241fb317 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkBroadcastReceiver.java @@ -0,0 +1,296 @@ +package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service; + +/** + * Created by andy on 10/23/18. + */ + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.v4.content.LocalBroadcastManager; + +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkConst; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkUtil; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkError; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.DiscoverGattServicesTask; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.InitializePumpManagerTask; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTask; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor; +import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask; +import info.nightscout.utils.SP; + +/** + * I added this class outside of RileyLinkService, because for now it's very important part of RL framework and + * where we get a lot of problems. Especially merging between AAPS and RileyLinkAAPS. I might put it back at + * later time + */ +public class RileyLinkBroadcastReceiver extends BroadcastReceiver { + + private static final Logger LOG = LoggerFactory.getLogger(RileyLinkBroadcastReceiver.class); + + RileyLinkService serviceInstance; + // protected RileyLinkIPCConnection rileyLinkIPCConnection; + protected Map> broadcastIdentifiers = null; + String deviceSpecificPrefix; + Context context; + + + public RileyLinkBroadcastReceiver(RileyLinkService serviceInstance, Context context) { + this.serviceInstance = serviceInstance; + this.context = context; + + // TODO remove in AAPS -- Andy + // rileyLinkIPCConnection = new RileyLinkIPCConnection(context); + // RileyLinkUtil.setRileyLinkIPCConnection(rileyLinkIPCConnection); + + createBroadcastIdentifiers(); + } + + + private void createBroadcastIdentifiers() { + + this.broadcastIdentifiers = new HashMap<>(); + + // Bluetooth + this.broadcastIdentifiers.put("Bluetooth", Arrays.asList( // + RileyLinkConst.Intents.BluetoothConnected, // + RileyLinkConst.Intents.BluetoothReconnected, // + RileyLinkConst.Intents.BluetoothReconnected)); + + // TuneUp + this.broadcastIdentifiers.put("TuneUp", Arrays.asList( // + // RT2Const.IPC.MSG_PUMP_tunePump, // + // RT2Const.IPC.MSG_PUMP_quickTune, // + RileyLinkConst.IPC.MSG_PUMP_tunePump, // + RileyLinkConst.IPC.MSG_PUMP_quickTune)); + + // RileyLink + this.broadcastIdentifiers.put("RileyLink", Arrays.asList( // + RileyLinkConst.Intents.RileyLinkDisconnected, // + RileyLinkConst.Intents.RileyLinkReady, // + RileyLinkConst.Intents.RileyLinkDisconnected, // + RileyLinkConst.Intents.RileyLinkNewAddressSet, // + RileyLinkConst.Intents.RileyLinkDisconnect)); + + // Device Specific + deviceSpecificPrefix = serviceInstance.getDeviceSpecificBroadcastsIdentifierPrefix(); + + // Application specific + // this.broadcastIdentifiers.put("AppSpecific", Arrays.asList( // + // RT2Const.serviceLocal.ipcBound, // + // RT2Const.IPC.MSG_ServiceCommand, // + // RT2Const.serviceLocal.INTENT_sessionCompleted)); + + } + + + @Override + public void onReceive(Context context, Intent intent) { + + if (intent == null) { + LOG.error("onReceive: received null intent"); + } else { + String action = intent.getAction(); + if (action == null) { + LOG.error("onReceive: null action"); + } else { + LOG.debug("Received Broadcast: " + action); + + if (!processBluetoothBroadcasts(action) && // + !processRileyLinkBroadcasts(action) && // + !processTuneUpBroadcasts(action) && // + !processDeviceSpecificBroadcasts(action, intent) && // + !processApplicationSpecificBroadcasts(action, intent) // + ) { + LOG.error("Unhandled broadcast: action=" + action); + } + } + } + } + + + public void registerBroadcasts() { + + IntentFilter intentFilter = new IntentFilter(); + + for (Map.Entry> stringListEntry : broadcastIdentifiers.entrySet()) { + + for (String intentKey : stringListEntry.getValue()) { + System.out.println("Intent: " + intentKey); + intentFilter.addAction(intentKey); + } + } + + if (deviceSpecificPrefix != null) { + serviceInstance.registerDeviceSpecificBroadcasts(intentFilter); + } + + LocalBroadcastManager.getInstance(context).registerReceiver(this, intentFilter); + + } + + + private boolean processRileyLinkBroadcasts(String action) { + + if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) { + if (BluetoothAdapter.getDefaultAdapter().isEnabled()) { + RileyLinkUtil + .setServiceState(RileyLinkServiceState.BluetoothReady, RileyLinkError.RileyLinkUnreachable); + } else { + RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled); + } + + return true; + } else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) { + LOG.warn("MedtronicConst.Intents.RileyLinkReady"); + // sendIPCNotification(RT2Const.IPC.MSG_note_WakingPump); + this.serviceInstance.rileyLinkBLE.enableNotifications(); + this.serviceInstance.rfspy.startReader(); // call startReader from outside? + + this.serviceInstance.rfspy.initializeRileyLink(); + String bleVersion = this.serviceInstance.rfspy.getBLEVersionCached(); + RileyLinkFirmwareVersion rlVersion = this.serviceInstance.rfspy.getRLVersionCached(); + + LOG.debug("RfSpy version (BLE113): " + bleVersion); + this.serviceInstance.rileyLinkServiceData.versionBLE113 = bleVersion; + + LOG.debug("RfSpy Radio version (CC110): " + rlVersion.name()); + this.serviceInstance.rileyLinkServiceData.versionCC110 = rlVersion; + + ServiceTask task = new InitializePumpManagerTask(RileyLinkUtil.getTargetDevice()); + ServiceTaskExecutor.startTask(task); + LOG.info("Announcing RileyLink open For business"); + + return true; + } else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) { + if (BluetoothAdapter.getDefaultAdapter().isEnabled()) { + RileyLinkUtil + .setServiceState(RileyLinkServiceState.BluetoothReady, RileyLinkError.RileyLinkUnreachable); + } else { + RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled); + } + + return true; + } else if (action.equals(RileyLinkConst.Intents.RileyLinkNewAddressSet)) { + String RileylinkBLEAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, ""); + if (RileylinkBLEAddress.equals("")) { + LOG.error("No Rileylink BLE Address saved in app"); + } else { + // showBusy("Configuring Service", 50); + // rileyLinkBLE.findRileyLink(RileylinkBLEAddress); + this.serviceInstance.reconfigureRileyLink(RileylinkBLEAddress); + // MainApp.getServiceClientConnection().setThisRileylink(RileylinkBLEAddress); + } + + return true; + } else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnect)) { + this.serviceInstance.disconnectRileyLink(); + + return true; + } else { + return false; + } + + } + + + public boolean processBluetoothBroadcasts(String action) { + + if (action.equals(RileyLinkConst.Intents.BluetoothConnected)) { + LOG.debug("Bluetooth - Connected"); + // sendIPCNotification(RT2Const.IPC.MSG_note_FindingRileyLink); + ServiceTaskExecutor.startTask(new DiscoverGattServicesTask()); + + return true; + + } else if (action.equals(RileyLinkConst.Intents.BluetoothReconnected)) { + LOG.debug("Bluetooth - Reconnecting"); + // sendIPCNotification(RT2Const.IPC.MSG_note_FindingRileyLink); + serviceInstance.bluetoothInit(); + ServiceTaskExecutor.startTask(new DiscoverGattServicesTask(true)); + + return true; + } else if (action.equals(RileyLinkConst.Intents.BluetoothReconnected)) { + LOG.debug("Bluetooth - Reconnected"); + // sendIPCNotification(RT2Const.IPC.MSG_note_FindingRileyLink); + serviceInstance.bluetoothInit(); + ServiceTaskExecutor.startTask(new DiscoverGattServicesTask(true)); + + return true; + } else { + + return false; + } + + } + + + private boolean processTuneUpBroadcasts(String action) { + + if (this.broadcastIdentifiers.get("TuneUp").contains(action)) { + if (serviceInstance.getRileyLinkTargetDevice().isTuneUpEnabled()) { + ServiceTaskExecutor.startTask(new WakeAndTuneTask()); + } + return true; + } else { + return false; + } + } + + + public boolean processDeviceSpecificBroadcasts(String action, Intent intent) { + + if (this.deviceSpecificPrefix == null) { + return false; + } + + if (action.startsWith(this.deviceSpecificPrefix)) { + return this.serviceInstance.handleDeviceSpecificBroadcasts(intent); + } else + return false; + } + + + public boolean processApplicationSpecificBroadcasts(String action, Intent intent) { + // if (action.equals(RT2Const.serviceLocal.ipcBound)) { + // // If we still need permission for bluetooth, ask now. + // // if (needBluetoothPermission) { + // // sendBLERequestForAccess(); + // // } + // return true; + // } else if (RT2Const.IPC.MSG_ServiceCommand.equals(action)) { + // serviceInstance.handleIncomingServiceTransport(intent); + // return true; + // } else if (RT2Const.serviceLocal.INTENT_sessionCompleted.equals(action)) { + // Bundle bundle = intent.getBundleExtra(RT2Const.IPC.bundleKey); + // if (bundle != null) { + // ServiceTransport transport = new ServiceTransport(bundle); + // rileyLinkIPCConnection.sendTransport(transport, transport.getSenderHashcode()); + // } else { + // LOG.error("sessionCompleted: no bundle!"); + // } + // return true; + // } else { + // return false; + // } + return false; + } + + + public void sendIPCNotification(String notification) { + // rileyLinkIPCConnection.sendNotification(new ServiceNotification(notification), null); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkService.java index b1369717f3..c2a72f8e65 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/hw/rileylink/service/RileyLinkService.java @@ -48,7 +48,7 @@ public abstract class RileyLinkService extends Service { protected BluetoothAdapter bluetoothAdapter; protected RFSpy rfspy; // interface for RL xxx Mhz radio. protected Context context; - protected BroadcastReceiver mBroadcastReceiver; + protected RileyLinkBroadcastReceiver mBroadcastReceiver; protected RileyLinkServiceData rileyLinkServiceData; protected RileyLinkTargetFrequency rileyLinkTargetFrequency; @@ -121,173 +121,32 @@ public abstract class RileyLinkService extends Service { super.onCreate(); LOG.debug("onCreate"); - // rileyLinkIPCConnection = new RileyLinkIPCConnection(context); // TODO We might be able to remove this -- Andy - // RileyLinkUtil.setRileyLinkIPCConnection(rileyLinkIPCConnection); - - mBroadcastReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - - if (intent == null) { - LOG.error("onReceive: received null intent"); - return; - } - - String action = intent.getAction(); - if (action == null) { - LOG.error("onReceive: null action"); - } else { - - if (action.equals(RileyLinkConst.Intents.BluetoothConnected)) { - // rileyLinkIPCConnection.sendNotification(new - // ServiceNotification(RT2Const.IPC.MSG_note_FindingRileyLink), null); - ServiceTaskExecutor.startTask(new DiscoverGattServicesTask()); - } else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) { - if (BluetoothAdapter.getDefaultAdapter().isEnabled()) { - RileyLinkUtil.setServiceState(RileyLinkServiceState.RileyLinkError, - RileyLinkError.RileyLinkUnreachable); - } else { - RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothError, - RileyLinkError.BluetoothDisabled); - } - } else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) { - LOG.warn("BroadcastReceive: RileyLink Ready"); - - rileyLinkBLE.enableNotifications(); - rfspy.startReader(); // call startReader from outside? - - rfspy.initializeRileyLink(); - String bleVersion = rfspy.getBLEVersionCached(); - RileyLinkFirmwareVersion rlVersion = rfspy.getRLVersionCached(); - - LOG.debug("RfSpy version (BLE113): " + bleVersion); - rileyLinkServiceData.versionBLE113 = bleVersion; - - LOG.debug("RfSpy Radio version (CC110): " + rlVersion.name()); - rileyLinkServiceData.versionCC110 = rlVersion; - - ServiceTask task = new InitializePumpManagerTask(getRileyLinkTargetDevice()); - ServiceTaskExecutor.startTask(task); - LOG.info("Announcing RileyLink open For business"); - - } else if (action.equals(RileyLinkConst.Intents.BluetoothReconnected)) { - LOG.debug("BroadcastReceive: Reconnecting Bluetooth"); - // rileyLinkIPCConnection.sendNotification(new - // ServiceNotification(RT2Const.IPC.MSG_note_FindingRileyLink), null); - bluetoothInit(); - ServiceTaskExecutor.startTask(new DiscoverGattServicesTask(true)); - } else if (action.equals(RileyLinkConst.IPC.MSG_PUMP_tunePump) || // - action.equals(RileyLinkConst.IPC.MSG_PUMP_quickTune)) { - if (getRileyLinkTargetDevice().isTuneUpEnabled()) { - // doTuneUpDevice(); - ServiceTaskExecutor.startTask(new WakeAndTuneTask()); - } - } else if (action.startsWith("MSG_PUMP_")) { - handlePumpSpecificIntents(intent); - } else if (RileyLinkConst.IPC.MSG_ServiceCommand.equals(action)) { - handleIncomingServiceTransport(intent); - } else if (action.equals(RileyLinkConst.Intents.RileyLinkNewAddressSet)) { - String RileylinkBLEAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, ""); - if (RileylinkBLEAddress.equals("")) { - LOG.error("No Rileylink BLE Address saved in app"); - } else { - // showBusy("Configuring Service", 50); - // rileyLinkBLE.findRileyLink(RileylinkBLEAddress); - reconfigureRileyLink(RileylinkBLEAddress); - // MainApp.getServiceClientConnection().setThisRileylink(RileylinkBLEAddress); - } - } else if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnect)) { - disconnectRileyLink(); - } - - /* - * else if (RT2Const.serviceLocal.INTENT_sessionCompleted.equals(action)) { - * Bundle bundle = intent.getBundleExtra(RT2Const.IPC.bundleKey); - * if (bundle != null) { - * ServiceTransport transport = new ServiceTransport(bundle); - * //rileyLinkIPCConnection.sendTransport(transport, transport.getSenderHashcode()); - * //RileyLinkUtil.send - * } else { - * LOG.error("sessionCompleted: no bundle!"); - * } - * } - */ - - /* - * else - * - * if (case RT2Const.local.INTENT_serviceConnected: - * case RT2Const.local.INTENT_NEW_rileylinkAddressKey: - * showIdle(); - * /** - * Client MUST send a "UseThisRileylink" message because it asserts that - * the user has given explicit permission to use bluetooth. - * - * We can change the format so that it is a simple "bluetooth OK" message, - * rather than an explicit address of a Rileylink, and the Service can - * use the last known good value. But the kick-off of bluetooth ops must - * come from an Activity. - */ - /* - * String RileylinkBLEAddress = SP.getString(MedtronicConst.Prefs.RileyLinkAddress, ""); - * if (RileylinkBLEAddress.equals("")) { - * // TODO: 11/07/2016 @TIM UI message for user - * Log.e(TAG, "No Rileylink BLE Address saved in app"); - * } else { - * //showBusy("Configuring Service", 50); - * MainApp.getServiceClientConnection().setThisRileylink(RileylinkBLEAddress); - * } - * break; - * case RT2Const.local.INTENT_NEW_pumpIDKey: - * MainApp.getServiceClientConnection().sendPUMP_useThisDevice(SP.getString(MedtronicConst.Prefs. - * PumpSerial, "")); - * break; - */ - - else { - LOG.error("Unhandled broadcast: action=" + action); - } - - } - } - }; - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(RileyLinkConst.Intents.BluetoothConnected); - intentFilter.addAction(RileyLinkConst.Intents.BluetoothDisconnected); - intentFilter.addAction(RileyLinkConst.Intents.RileyLinkReady); - intentFilter.addAction(RileyLinkConst.Intents.RileyLinkDisconnected); - intentFilter.addAction(RileyLinkConst.Intents.BluetoothReconnected); - intentFilter.addAction(RileyLinkConst.Intents.RileyLinkNewAddressSet); - intentFilter.addAction(RileyLinkConst.Intents.RileyLinkDisconnect); - // intentFilter.addAction(RT2Const.serviceLocal.ipcBound); - // intentFilter.addAction(RT2Const.IPC.MSG_BLE_accessGranted); - // intentFilter.addAction(RT2Const.IPC.MSG_BLE_accessDenied); - // intentFilter.addAction(RT2Const.IPC.MSG_BLE_useThisDevice); - intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_tunePump); - // intentFilter.addAction(RT2Const.IPC.MSG_PUMP_useThisAddress); - intentFilter.addAction(RileyLinkConst.IPC.MSG_ServiceCommand); - // intentFilter.addAction(RileyLinkConst.serviceLocal.INTENT_sessionCompleted); - - addPumpSpecificIntents(intentFilter); - - LocalBroadcastManager.getInstance(context).registerReceiver(mBroadcastReceiver, intentFilter); + mBroadcastReceiver = new RileyLinkBroadcastReceiver(this, this.context); + mBroadcastReceiver.registerBroadcasts(); LOG.debug("onCreate(): It's ALIVE!"); } + /** + * Prefix for Device specific broadcast identifier prefix (for example MSG_PUMP_ for pump or + * MSG_POD_ for Omnipod) + * + * @return + */ + public abstract String getDeviceSpecificBroadcastsIdentifierPrefix(); + + + public abstract boolean handleDeviceSpecificBroadcasts(Intent intent); + + + public abstract void registerDeviceSpecificBroadcasts(IntentFilter intentFilter); + + public abstract RileyLinkCommunicationManager getDeviceCommunicationManager(); - public abstract void addPumpSpecificIntents(IntentFilter intentFilter); - - - public abstract void handlePumpSpecificIntents(Intent intent); - - - public abstract void handleIncomingServiceTransport(Intent intent); + public abstract boolean handleIncomingServiceTransport(Intent intent); // Here is where the wake-lock begins: @@ -300,7 +159,7 @@ public abstract class RileyLinkService extends Service { } - private boolean bluetoothInit() { + public boolean bluetoothInit() { LOG.debug("bluetoothInit: attempting to get an adapter"); RileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothInitializing); @@ -380,13 +239,6 @@ public abstract class RileyLinkService extends Service { } - public boolean sendNotification(ServiceNotification notification, Integer clientHashcode) { - // return rileyLinkIPCConnection.sendNotification(notification, clientHashcode); - LOG.error("sendNotification not implemented."); - return false; - } - - // FIXME: This needs to be run in a session so that is interruptable, has a separate thread, etc. public void doTuneUpDevice() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/LocationHelper.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/LocationHelper.java index e2d9ae2254..45ea6fc812 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/LocationHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/LocationHelper.java @@ -25,6 +25,7 @@ public class LocationHelper { */ public static boolean isLocationEnabled(Context context) { LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); + return (locationManager != null && // (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || // locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/MedtronicPumpPlugin.java index 0c5218070c..521c5fed45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/MedtronicPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/MedtronicPumpPlugin.java @@ -5,6 +5,8 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.Hours; import org.joda.time.LocalDateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,9 +41,12 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLink import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.MedtronicCommunicationManager; +import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.ui.MedtronicUIComm; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.ui.MedtronicUITask; import info.nightscout.androidaps.plugins.PumpMedtronic.data.MedtronicHistoryData; +import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BasalProfile; +import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BasalProfileEntry; import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.TempBasalPair; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicNotificationType; @@ -133,6 +138,11 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter } + private String getLogPrefix() { + return "MedtronicPumpPlugin::"; + } + + @Override public void initPumpStatusData() { @@ -141,6 +151,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter pumpStatusLocal.lastConnection = SP.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); pumpStatusLocal.lastDataTime = new LocalDateTime(pumpStatusLocal.lastConnection); + pumpStatusLocal.previousConnection = pumpStatusLocal.lastConnection; pumpStatusLocal.refreshConfiguration(); @@ -151,10 +162,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter pumpDescription.maxTempAbsolute = (pumpStatusLocal.maxBasal != null) ? pumpStatusLocal.maxBasal : 35.0d; // needs to be changed in configuration, after all functionalities are done - pumpDescription.isBolusCapable = true; + pumpDescription.isBolusCapable = true; // WIP pumpDescription.isTempBasalCapable = true; // WIP pumpDescription.isExtendedBolusCapable = false; - pumpDescription.isSetBasalProfileCapable = false; + pumpDescription.isSetBasalProfileCapable = true; // unchangable pumpDescription.tempBasalStyle = PumpDescription.PERCENT; @@ -852,11 +863,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter return new PumpEnactResult().success(response).enacted(response); } + // Gson gson = new Gson(); + PumpHistoryEntry lastPumpHistoryEntry; + private void readPumpHistory() { LOG.error("MedtronicPumpPlugin::readPumpHistory NOT IMPLEMENTED."); - // TODO read History + // readPumpHistoryLogic(); scheduleNextRefresh(MedtronicStatusRefreshType.PumpHistory); @@ -868,6 +882,50 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter } + private void readPumpHistoryLogic() { + + Long lastPumpHistoryEntryTime = null; + + // TODO read History + if (lastPumpHistoryEntry == null) { + lastPumpHistoryEntryTime = SP.getLong(MedtronicConst.Statistics.LastPumpHistoryEntry, null); + } + + if (firstRun) { + DateTime dt = new DateTime(); + dt.minus(Hours.hours(36)); + + if (lastPumpHistoryEntry == null && lastPumpHistoryEntryTime == null) { + + } else { + + } + + } + + // determine if first run, if yes detrmine how much of update do we need + // first run: + // get last hiostory entry, if not there download 1.5 days of data + // - there: check if last entry is older than 1.5 days + // - yes: download 1.5 days + // - no: download with last entry + // - not there: download 1.5 days + // + // upload all new entries to NightScout (TBR, Bolus) + // determine pump status + // + // save last entry + // + // not first run: + // update to last entry + // - save + // - determine pump status + + // + + } + + private void scheduleNextRefresh(MedtronicStatusRefreshType refreshType) { scheduleNextRefresh(refreshType, 0); } @@ -931,8 +989,19 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter @Override public PumpEnactResult cancelTempBasal(boolean enforceNew) { - LOG.info("cancelTempBasal - started"); + LOG.info("MedtronicPumpPlugin::cancelTempBasal - started"); + if (isPumpNotReachable()) { + + setRefreshButtonEnabled(true); + + return new PumpEnactResult() // + .success(false) // + .enacted(false) // + .comment(MainApp.gs(R.string.medtronic_pump_status_pump_unreachable)); + } + + MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable); setRefreshButtonEnabled(false); TempBasalPair tbrCurrent = readTBR(); @@ -969,12 +1038,89 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter @Override public PumpEnactResult setNewBasalProfile(Profile profile) { - LOG.warn("MedtronicPumpPlugin::setNewBasalProfile NOT IMPLEMENTED YET."); + LOG.error(getLogPrefix() + "setNewBasalProfile - WIP."); - // TODO implement this + setRefreshButtonEnabled(false); - return new PumpEnactResult().success(false).enacted(false) - .comment(MainApp.gs(R.string.medtronic_cmd_profile_not_set)); + if (isPumpNotReachable()) { + + setRefreshButtonEnabled(true); + + return new PumpEnactResult() // + .success(false) // + .enacted(false) // + .comment(MainApp.gs(R.string.medtronic_pump_status_pump_unreachable)); + } + + MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable); + + BasalProfile basalProfile = convertProfileToMedtronicProfile(profile); + + String profileInvalid = isProfileValid(basalProfile); + + if (profileInvalid != null) { + return new PumpEnactResult() // + .success(false) // + .enacted(false) // + .comment(MainApp.gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid)); + } + + MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBasalProfileSTD, + basalProfile); + + Boolean response = (Boolean)responseTask.returnData; + + LOG.info(getLogPrefix() + "Basal Profile was set: " + response); + + return new PumpEnactResult().success(response).enacted(response); + } + + + private String isProfileValid(BasalProfile basalProfile) { + + StringBuilder stringBuilder = new StringBuilder(); + + MedtronicPumpStatus pumpStatus = getMDTPumpStatus(); + + if (pumpStatusLocal.maxBasal == null) + return null; + + for (BasalProfileEntry profileEntry : basalProfile.getEntries()) { + + if (profileEntry.rate > pumpStatusLocal.maxBasal) { + + stringBuilder.append(profileEntry.startTime.toString("HH:mm") + "=" + profileEntry.rate); + + } + } + + return stringBuilder.length() == 0 ? null : stringBuilder.toString(); + + } + + + @NonNull + private BasalProfile convertProfileToMedtronicProfile(Profile profile) { + + MedtronicPumpStatus pumpStatus = getMDTPumpStatus(); + + PumpType pumpType = pumpStatus.pumpType; + + BasalProfile basalProfile = new BasalProfile(); + + for (int i = 0; i < 24; i++) { + double rate = profile.getBasalTimeFromMidnight(i * 60 * 60); + + double v = pumpType.determineCorrectBasalSize(rate); + + BasalProfileEntry basalEntry = new BasalProfileEntry(v, i, 0); + basalProfile.addEntry(basalEntry); + + } + + basalProfile.generateRawDataFromEntries(); + + return basalProfile; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicCommunicationManager.java index d67ad8ce6c..7d1e2f120d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicCommunicationManager.java @@ -343,15 +343,13 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager LOG.debug("Run command with Frames: Got ACK response for Attention packet"); } - int start = 0; int frameNr = 1; - int len = 0; for (List frame : frames) { byte[] frameData = MedtronicUtil.createByteArray(frame); - LOG.debug("Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData)); + // LOG.debug("Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData)); PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frameData)); @@ -375,10 +373,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) { - // int pageNumber = 0; - - // TODO multiple history pages - PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, targetDate); if (doWakeUpBeforeCommand) @@ -480,14 +474,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager return pumpTotalResult; - // Page page = new Page(); - // // page.parseFrom(rval.getData(),PumpModel.MM522); - // // FIXME - // page.parseFrom(rawHistoryPage.getData(), MedtronicDeviceType.Medtronic_522); - // - // // return page; - // - // return null; } @@ -774,40 +760,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // TODO remove not needed - probably - // @Deprecated - // private void executeSetCommand(MedtronicCommandType commandType, byte[] bodyData) { - // - // LOG.debug("Executing Set for {} - 1st call", commandType.name()); - // - // // first we send command without paramters and wait for ACK - // PumpMessage pumpMessage = sendAndGetACK(commandType, null, 4000); - // - // // FIXME check if ACK - // LOG.debug("Response 1 - {}", HexDump.toHexStringDisplayable(pumpMessage.getRawContent())); - // - // - // LOG.debug("Executing Set for {} - 2nd call", commandType.name()); - // // second we send command with parameters and full package 64 bits with zeroed empty places - // - // byte newBodyData[] = new byte[64]; - // for(int i = 0; i < 64; i++) { - // newBodyData[i] = 0x00; - // } - // - // newBodyData[0] = (byte) bodyData.length; - // - // for(int i = 0; i < bodyData.length; i++) { - // newBodyData[i + 1] = bodyData[i]; - // } - // - // PumpMessage pumpMessage2 = sendAndGetACK(commandType, newBodyData, 4000); - // - // - // LOG.debug("Response 2 - {}", HexDump.toHexStringDisplayable(pumpMessage.getRawContent())); - // - // } - // PUMP SPECIFIC COMMANDS public Float getRemainingInsulin() { @@ -830,14 +782,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - public BasalProfile getBasalProfile_Old() { - - Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetBasalProfileSTD); - - return responseObject == null ? null : (BasalProfile)responseObject; - } - - public BasalProfile getBasalProfile() { // wakeUp @@ -992,7 +936,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // TODO WIP test public boolean setTBR(TempBasalPair tbr) { if (this.doWakeUpBeforeCommand) @@ -1028,6 +971,19 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } + public Boolean setBasalProfile(BasalProfile basalProfile) { + + List> basalProfileFrames = MedtronicUtil.getBasalProfileFrames(basalProfile.getRawData()); + + PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileSTD, basalProfileFrames); + + // LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent())); + + return responseMessage.commandType == MedtronicCommandType.CommandACK; + + } + + // FIXME --- After this line commands in development --- REMOVE THIS COMMANDS // TODO test @@ -1061,146 +1017,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // TODO generateRawData (check if it works correctly) and test - public Boolean setBasalProfile(BasalProfile basalProfile) { - - // [RileyLinkDevice] ======================== Save Basal Profile =========================== - // [PumpMessageSender] getResponse(PumpMessage(carelink, setBasalProfileStandard, 3 bytes, 1 bytes), 0, - // 0.180000, 3) - // [PeripheralManager+RileyLink] RL Send: 19050000000000000000b4030000a9659a6b19b199c555b2c000 - // [PeripheralManager+RileyLink] RL Recv(single): bb - // [PeripheralManager+RileyLink] RileyLink response: PacketResponse(code: - // RileyLinkBLEKit.ResponseCode.commandInterrupted, packet: nil) - // [PeripheralManager+RileyLink] RL Recv(single): dd0dbca9659a6b19b156655534d500 - // [PumpMessageSender] getResponse(PumpMessage(carelink, setBasalProfileStandard, 3 bytes, 65 bytes), 0, - // 0.180000, 3) - // [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c571c9a555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556000 - // 2018-06-30 15:03:13.333962-0500 Loop[24609:13622692] [PeripheralManager+RileyLink] RL Recv(single): - // dd10bda9659a6b19b156655534d500 - // 2018-06-30 15:03:13.334927-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 65 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:13.337923-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c5725555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555ac000 - // 2018-06-30 15:03:14.114024-0500 Loop[24609:13622486] [PeripheralManager+RileyLink] RL Recv(single): - // dd0ebea9659a6b19b156655534d500 - // 2018-06-30 15:03:14.115017-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 65 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:14.117600-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c6a355555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555570e000 - // 2018-06-30 15:03:15.644502-0500 Loop[24609:13622692] [PeripheralManager+RileyLink] RL Recv(single): - // dd0ebfa9659a6b19b156655534d500 - // 2018-06-30 15:03:15.645388-0500 Loop[24609:13622484] [RileyLinkDevice] ------------------------ Save Basal - // Profile --------------------------- - - // 2018-06-30 15:03:12.167767-0500 Loop[24609:13622484] [RileyLinkDevice] ======================== Save Basal - // Profile =========================== - // 2018-06-30 15:03:12.168652-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 1 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:12.169518-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 19050000000000000000b4030000a9659a6b19b199c555b2c000 - // 2018-06-30 15:03:12.463546-0500 Loop[24609:13622486] [PeripheralManager+RileyLink] RL Recv(single): bb - // 2018-06-30 15:03:12.463954-0500 Loop[24609:13622486] [PeripheralManager+RileyLink] RileyLink response: - // PacketResponse(code: RileyLinkBLEKit.ResponseCode.commandInterrupted, packet: nil) - // 2018-06-30 15:03:12.554051-0500 Loop[24609:13622486] [PeripheralManager+RileyLink] RL Recv(single): - // dd0dbca9659a6b19b156655534d500 - // 2018-06-30 15:03:12.555175-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 65 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:12.557953-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c571c9a555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556000 - // 2018-06-30 15:03:13.333962-0500 Loop[24609:13622692] [PeripheralManager+RileyLink] RL Recv(single): - // dd10bda9659a6b19b156655534d500 - // 2018-06-30 15:03:13.334927-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 65 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:13.337923-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c5725555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555ac000 - // 2018-06-30 15:03:14.114024-0500 Loop[24609:13622486] [PeripheralManager+RileyLink] RL Recv(single): - // dd0ebea9659a6b19b156655534d500 - // 2018-06-30 15:03:14.115017-0500 Loop[24609:13622484] [PumpMessageSender] getResponse(PumpMessage(carelink, - // setBasalProfileStandard, 3 bytes, 65 bytes), 0, 0.180000, 3) - // 2018-06-30 15:03:14.117600-0500 Loop[24609:13622484] [PeripheralManager+RileyLink] RL Send: - // 79050000000000000000b4030000a9659a6b19b199c6a355555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555570e000 - // 2018-06-30 15:03:15.644502-0500 Loop[24609:13622692] [PeripheralManager+RileyLink] RL Recv(single): - // dd0ebfa9659a6b19b156655534d500 - // 2018-06-30 15:03:15.645388-0500 Loop[24609:13622484] [RileyLinkDevice] ------------------------ Save Basal - // Profile --------------------------- - - // byte[] body = basalProfile.generateRawData(); - - // byte[] body = new byte[] { 32, 0, 0, 38, 0, 13, 44, 0, 19, 38, 0, 28 }; - - byte[] body = ByteUtil - .createByteArray( - "06000052000178050202000304000402000504000602000704000802000904000a02000b04000c02000d02000e02000f040010020011040012020013040014020015040016020017040018020019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - 0); - - List> basalProfileFrames = MedtronicUtil.getBasalProfileFrames(body); - - PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileA, basalProfileFrames); - - // PumpMessage responseMessage; - // - // if (debugSetCommands) - // LOG.debug("Set Basal Profile: Body [{}] - {}", body.length, HexDump.toHexStringDisplayable(body)); - // - // for (List basalProfileFrame : basalProfileFrames) { - // - // PumpMessage msg = makePumpMessage(MedtronicCommandType.SetBasalProfileA, // - // new CarelinkLongMessageBody(ByteUtil.concat((byte)body.length, body))); - // - // responseMessage = runCommandWithArgs(msg); - // - // } - - // if (body.length <= 64) { - // - // PumpMessage msg = makePumpMessage(MedtronicCommandType.SetBasalProfileA, // - // new CarelinkLongMessageBody(ByteUtil.concat((byte) body.length, body))); - // - // responseMessage = runCommandWithArgs(msg); - // } else - // { - // - // responseMessage = runCommandWithArgsLong(MedtronicCommandType.SetBasalProfileA, body); - // } - - // if (debugSetCommands) - // LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent())); - - LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent())); - - return responseMessage.commandType == MedtronicCommandType.CommandACK; - - } - - - // public byte[] getFullMessageBody(byte[] bodyData, int length) { - // byte newBodyData[] = getEmptyMessage(length); - // - // newBodyData[0] = (byte) bodyData.length; - // - // for (int i = 0; i < bodyData.length; i++) { - // newBodyData[i + 1] = bodyData[i]; - // } - // - // return newBodyData; - // } - - // public byte[] getEmptyMessage(int length) { - // byte newBodyData[] = new byte[length]; - // for (int i = 0; i < length; i++) { - // newBodyData[i] = 0x00; - // } - // - // return newBodyData; - // } - public PumpMessage cancelBolus() { // ? maybe suspend and resume return null; } - // Set TBR 100% // Cancel TBR (set TBR 100%) 100% // Get Status (40%) @@ -1215,42 +1036,4 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager // Read History 60% // Load TDD ? - // FIXME remove - each part needs to be gotten manually - public void updatePumpManagerStatus() { - // Integer resp = getRemainingBattery(); - // pumpStatus.batteryRemaining = resp == null ? -1 : resp; - - // pumpStatus.remainUnits = getRemainingInsulin(); - - /* current basal */ - // TempBasalPair basalRate = getCurrentBasalRate(); - - // FIXME - // byte[] basalRateBytes = resp.getContents(); - // if (basalRateBytes != null) { - // if (basalRateBytes.length == 2) { - // /** - // * 0x98 0x06 - // * 0x98 is "basal rate" - // * 0x06 is what? Not currently running a temp basal, current basal is "standard" at 0 - // */ - // double basalRate = ByteUtil.asUINT8(basalRateBytes[1]); - // pumpStatus.currentBasal = basalRate; - // } - // } - // get last bolus amount - // get last bolus time - // get tempBasalInProgress - // get tempBasalRatio - // get tempBasalRemainMin - // get tempBasalStart - // get pump time - LocalDateTime clockResult = getPumpTime(); - if (clockResult != null) { - // pumpStatus.time = clockResult.toDate(); - } - // get last sync time - - } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryDecoder.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryDecoder.java index 2e54efcdc0..6dbfc8cc61 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryDecoder.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryDecoder.java @@ -119,11 +119,12 @@ public abstract class MedtronicHistoryDecoder { // public abstract List processPageAndCreateRecords(RawHistoryPage page, // boolean partial) throws Exception; - // - // - // public List processPageAndCreateRecords(RawHistoryPage page) throws Exception { - // return processPageAndCreateRecords(page, false); - // } + + public List processPageAndCreateRecords(RawHistoryPage rawHistoryPage, + Class clazz) throws Exception { + return processPageAndCreateRecords(rawHistoryPage, false, clazz); + } + protected void prepareStatistics() { if (!statisticsEnabled) @@ -212,12 +213,6 @@ public abstract class MedtronicHistoryDecoder { } - // public List processPageAndCreateRecords(RawHistoryPage rawHistoryPage, - // boolean partial) { - // return (processPageAndCreateRecords( - // rawHistoryPage, partial, clazz); - // } - public List processPageAndCreateRecords(RawHistoryPage rawHistoryPage, boolean partial, Class clazz) { List dataClear = checkPage(rawHistoryPage, partial); @@ -234,4 +229,5 @@ public abstract class MedtronicHistoryDecoder { protected abstract List createRecords(List dataClear, Class clazz); + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUIPostprocessor.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUIPostprocessor.java index 93cf5feaea..daba3704c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUIPostprocessor.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUIPostprocessor.java @@ -44,6 +44,17 @@ public class MedtronicUIPostprocessor { switch (uiTask.commandType) { + case SetBasalProfileSTD: { + Boolean response = (Boolean) uiTask.returnData; + + if (response) { + BasalProfile basalProfile = (BasalProfile) uiTask.getParameter(0); + + pumpStatus.basalsByHour = basalProfile.getProfilesByHour(); + } + } + break; + case GetBasalProfileSTD: { BasalProfile basalProfile = (BasalProfile)uiTask.returnData; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUITask.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUITask.java index 3f5eb2e74f..1dd15f9690 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUITask.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/ui/MedtronicUITask.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.MedtronicCommunicationManager; +import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BasalProfile; import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.TempBasalPair; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicUIResponseType; @@ -118,7 +119,9 @@ public class MedtronicUITask { case SetBasalProfileSTD: case SetBasalProfileA: { - // returnData = communicationManager.setBasalProfile(profile); + BasalProfile profile = (BasalProfile) parameters[0]; + + returnData = communicationManager.setBasalProfile(profile); // Float amount = getAmount(); // // if (amount != null) { @@ -227,4 +230,8 @@ public class MedtronicUITask { public boolean hasData() { return (responseType == MedtronicUIResponseType.Data); } + + public Object getParameter(int index) { + return parameters[index]; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfile.java index 76d73f6690..d1ae9be99f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfile.java @@ -69,7 +69,13 @@ public class BasalProfile { data = MedtronicUtil.createByteArray(data[0], (byte)0, (byte)0); } - mRawData = data; + if (data.length == MAX_RAW_DATA_SIZE) { + mRawData = data; + } else { + int len = Math.min(MAX_RAW_DATA_SIZE, data.length); + mRawData = new byte[MAX_RAW_DATA_SIZE]; + System.arraycopy(data, 0, mRawData, 0, len); + } return true; } @@ -190,7 +196,7 @@ public class BasalProfile { } - public byte[] generateRawData() { + public void generateRawDataFromEntries() { List outData = new ArrayList<>(); @@ -205,7 +211,7 @@ public class BasalProfile { this.setRawData(MedtronicUtil.createByteArray(outData)); - return this.mRawData; + // return this.mRawData; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfileEntry.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfileEntry.java index 09453480fb..71899ff486 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfileEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/data/dto/BasalProfileEntry.java @@ -25,6 +25,24 @@ public class BasalProfileEntry { } + public BasalProfileEntry(double rate, int hour, int minutes) { + byte[] data = MedtronicUtil.getBasalStrokes(rate, true); + + rate_raw = new byte[2]; + rate_raw[0] = data[1]; + rate_raw[1] = data[0]; + + int interval = hour * 2; + + if (minutes == 30) { + interval++; + } + + startTime_raw = (byte)interval; + startTime = new LocalTime(hour, minutes == 30 ? 30 : 0); + } + + public BasalProfileEntry(int rateStrokes, int startTimeInterval) { // rateByte is insulin delivery rate, U/hr, in 0.025 U increments // startTimeByte is time-of-day, in 30 minute increments diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/service/RileyLinkMedtronicService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/service/RileyLinkMedtronicService.java index 78f2a7b4a4..436c2cda52 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/service/RileyLinkMedtronicService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/service/RileyLinkMedtronicService.java @@ -1,13 +1,8 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.service; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; @@ -27,12 +22,10 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLink import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkService; import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkServiceData; -import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.data.ServiceNotification; import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTask; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpMedtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.MedtronicCommunicationManager; -import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.Page; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.PumpMedtronic.driver.MedtronicPumpStatus; import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicConst; @@ -74,119 +67,6 @@ public class RileyLinkMedtronicService extends RileyLinkService { } - public void addPumpSpecificIntents(IntentFilter intentFilter) { - //intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchHistory); - //intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory); - } - - - public void handlePumpSpecificIntents(Intent intent) { - String action = intent.getAction(); - - if (action.equals(RileyLinkConst.IPC.MSG_PUMP_fetchHistory)) { - - // mHistoryPages = medtronicCommunicationManager.getAllHistoryPages(); - // final boolean savePages = true; - // if (savePages) { - // for (int i = 0; i < mHistoryPages.size(); i++) { - // String filename = "PumpHistoryPage-" + i; - // LOG.warn("Saving history page to file " + filename); - // FileOutputStream outputStream; - // try { - // outputStream = openFileOutput(filename, 0); - // byte[] rawData = mHistoryPages.get(i).getRawData(); - // if (rawData != null) { - // outputStream.write(rawData); - // } - // outputStream.close(); - // } catch (FileNotFoundException fnf) { - // fnf.printStackTrace(); - // } catch (IOException ioe) { - // ioe.printStackTrace(); - // } catch (Exception e) { - // e.printStackTrace(); - // } - // - // } - // } - // - // Message msg = Message.obtain(null, RT2Const.IPC.MSG_IPC, 0, 0); - // // Create a bundle with the data - // Bundle bundle = new Bundle(); - // bundle.putString(RT2Const.IPC.messageKey, RT2Const.IPC.MSG_PUMP_history); - // ArrayList packedPages = new ArrayList<>(); - // for (Page page : mHistoryPages) { - // packedPages.add(page.pack()); - // } - // bundle.putParcelableArrayList(RT2Const.IPC.MSG_PUMP_history_key, packedPages); - // - // // save it to SQL. - // pumpHistoryManager.clearDatabase(); - // pumpHistoryManager.initFromPages(bundle); - // // write html page to documents folder - // pumpHistoryManager.writeHtmlPage(); - // - // // Set payload - // msg.setData(bundle); - // //rileyLinkIPCConnection.sendMessage(msg, null/*broadcast*/); - // LOG.debug("sendMessage: sent Full history report"); - } else if (RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory.equals(action)) { - LOG.info("Fetching saved history"); - // FileInputStream inputStream; - // ArrayList storedHistoryPages = new ArrayList<>(); - // for (int i = 0; i < 16; i++) { - // - // String filename = "PumpHistoryPage-" + i; - // try { - // inputStream = openFileInput(filename); - // byte[] buffer = new byte[1024]; - // int numRead = inputStream.read(buffer, 0, 1024); - // if (numRead == 1024) { - // Page p = new Page(); - // //p.parseFrom(buffer, PumpModel.MM522); - // // FIXME - // p.parseFrom(buffer, PumpModel.MM522); - // storedHistoryPages.add(p); - // } else { - // LOG.error(filename + " error: short file"); - // } - // } catch (FileNotFoundException fnf) { - // LOG.error("Failed to open " + filename + " for reading."); - // } catch (IOException e) { - // LOG.error("Failed to read " + filename); - // } catch (Exception e) { - // e.printStackTrace(); - // } - // } - // mHistoryPages = storedHistoryPages; - // if (storedHistoryPages.isEmpty()) { - // LOG.error("No stored history pages loaded"); - // } else { - // Message msg = Message.obtain(null, RT2Const.IPC.MSG_IPC, 0, 0); - // // Create a bundle with the data - // Bundle bundle = new Bundle(); - // bundle.putString(RT2Const.IPC.messageKey, RT2Const.IPC.MSG_PUMP_history); - // ArrayList packedPages = new ArrayList<>(); - // for (Page page : mHistoryPages) { - // packedPages.add(page.pack()); - // } - // bundle.putParcelableArrayList(RT2Const.IPC.MSG_PUMP_history_key, packedPages); - // - // // save it to SQL. - // pumpHistoryManager.clearDatabase(); - // pumpHistoryManager.initFromPages(bundle); - // // write html page to documents folder - // pumpHistoryManager.writeHtmlPage(); - // - // // Set payload - // msg.setData(bundle); - // //rileyLinkIPCConnection.sendMessage(msg, null/*broadcast*/); - // - // } - } - } - - @Override public void onConfigurationChanged(Configuration newConfig) { LOG.warn("onConfigurationChanged"); @@ -286,10 +166,166 @@ public class RileyLinkMedtronicService extends RileyLinkService { // LOG.info("setPumpIDString: saved pumpID " + idString); } + public class LocalBinder extends Binder { + + public RileyLinkMedtronicService getServiceInstance() { + return RileyLinkMedtronicService.this; + } + } + /* private functions */ - public void handleIncomingServiceTransport(Intent intent) { + // PumpInterface - REMOVE + + public boolean isInitialized() { + return RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); + } + + + public boolean isSuspended() { + return false; + } + + + public boolean isBusy() { + return false; + } + + + public boolean isConnected() { + return RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); + } + + + public boolean isConnecting() { + return !RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); + } + + + @Override + public String getDeviceSpecificBroadcastsIdentifierPrefix() { + + return null; + } + + + public boolean handleDeviceSpecificBroadcasts(Intent intent) { + // String action = intent.getAction(); + + // if (action.equals(RileyLinkConst.IPC.MSG_PUMP_fetchHistory)) { + + // mHistoryPages = medtronicCommunicationManager.getAllHistoryPages(); + // final boolean savePages = true; + // if (savePages) { + // for (int i = 0; i < mHistoryPages.size(); i++) { + // String filename = "PumpHistoryPage-" + i; + // LOG.warn("Saving history page to file " + filename); + // FileOutputStream outputStream; + // try { + // outputStream = openFileOutput(filename, 0); + // byte[] rawData = mHistoryPages.get(i).getRawData(); + // if (rawData != null) { + // outputStream.write(rawData); + // } + // outputStream.close(); + // } catch (FileNotFoundException fnf) { + // fnf.printStackTrace(); + // } catch (IOException ioe) { + // ioe.printStackTrace(); + // } catch (Exception e) { + // e.printStackTrace(); + // } + // + // } + // } + // + // Message msg = Message.obtain(null, RT2Const.IPC.MSG_IPC, 0, 0); + // // Create a bundle with the data + // Bundle bundle = new Bundle(); + // bundle.putString(RT2Const.IPC.messageKey, RT2Const.IPC.MSG_PUMP_history); + // ArrayList packedPages = new ArrayList<>(); + // for (Page page : mHistoryPages) { + // packedPages.add(page.pack()); + // } + // bundle.putParcelableArrayList(RT2Const.IPC.MSG_PUMP_history_key, packedPages); + // + // // save it to SQL. + // pumpHistoryManager.clearDatabase(); + // pumpHistoryManager.initFromPages(bundle); + // // write html page to documents folder + // pumpHistoryManager.writeHtmlPage(); + // + // // Set payload + // msg.setData(bundle); + // //rileyLinkIPCConnection.sendMessage(msg, null/*broadcast*/); + // LOG.debug("sendMessage: sent Full history report"); + // } else if (RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory.equals(action)) { + // LOG.info("Fetching saved history"); + // FileInputStream inputStream; + // ArrayList storedHistoryPages = new ArrayList<>(); + // for (int i = 0; i < 16; i++) { + // + // String filename = "PumpHistoryPage-" + i; + // try { + // inputStream = openFileInput(filename); + // byte[] buffer = new byte[1024]; + // int numRead = inputStream.read(buffer, 0, 1024); + // if (numRead == 1024) { + // Page p = new Page(); + // //p.parseFrom(buffer, PumpModel.MM522); + // + // p.parseFrom(buffer, PumpModel.MM522); + // storedHistoryPages.add(p); + // } else { + // LOG.error(filename + " error: short file"); + // } + // } catch (FileNotFoundException fnf) { + // LOG.error("Failed to open " + filename + " for reading."); + // } catch (IOException e) { + // LOG.error("Failed to read " + filename); + // } catch (Exception e) { + // e.printStackTrace(); + // } + // } + // mHistoryPages = storedHistoryPages; + // if (storedHistoryPages.isEmpty()) { + // LOG.error("No stored history pages loaded"); + // } else { + // Message msg = Message.obtain(null, RT2Const.IPC.MSG_IPC, 0, 0); + // // Create a bundle with the data + // Bundle bundle = new Bundle(); + // bundle.putString(RT2Const.IPC.messageKey, RT2Const.IPC.MSG_PUMP_history); + // ArrayList packedPages = new ArrayList<>(); + // for (Page page : mHistoryPages) { + // packedPages.add(page.pack()); + // } + // bundle.putParcelableArrayList(RT2Const.IPC.MSG_PUMP_history_key, packedPages); + // + // // save it to SQL. + // pumpHistoryManager.clearDatabase(); + // pumpHistoryManager.initFromPages(bundle); + // // write html page to documents folder + // pumpHistoryManager.writeHtmlPage(); + // + // // Set payload + // msg.setData(bundle); + // //rileyLinkIPCConnection.sendMessage(msg, null/*broadcast*/); + // + // } + // } + return false; + } + + + @Override + public void registerDeviceSpecificBroadcasts(IntentFilter intentFilter) { + // intentFilter.addAction(RT2Const.IPC.MSG_PUMP_fetchHistory); + // intentFilter.addAction(RT2Const.IPC.MSG_PUMP_fetchSavedHistory); + } + + + public boolean handleIncomingServiceTransport(Intent intent) { // Bundle bundle = intent.getBundleExtra(RT2Const.IPC.bundleKey); // @@ -368,6 +404,7 @@ public class RileyLinkMedtronicService extends RileyLinkService { // break; // } // } + return false; } @@ -385,62 +422,21 @@ public class RileyLinkMedtronicService extends RileyLinkService { */ } - - public void saveHistoryPage(int pagenumber, Page page) { - if ((page == null) || (page.getRawData() == null)) { - return; - } - String filename = "history-" + pagenumber; - FileOutputStream os; - try { - os = openFileOutput(filename, Context.MODE_PRIVATE); - os.write(page.getRawData()); - os.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - // PumpInterface - REMOVE - - public boolean isInitialized() { - return RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); - } - - - public boolean isSuspended() { - return false; - } - - - public boolean isBusy() { - return false; - } - - - public boolean isConnected() { - return RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); - } - - - public boolean isConnecting() { - return !RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState); - } - - - // FIXME remove - public void sendNotification(ServiceNotification serviceNotification, Object o) { - LOG.warn("Send Notification has no implementation."); - } - - public class LocalBinder extends Binder { - - public RileyLinkMedtronicService getServiceInstance() { - return RileyLinkMedtronicService.this; - } - } + // public void saveHistoryPage(int pagenumber, Page page) { + // if ((page == null) || (page.getRawData() == null)) { + // return; + // } + // String filename = "history-" + pagenumber; + // FileOutputStream os; + // try { + // os = openFileOutput(filename, Context.MODE_PRIVATE); + // os.write(page.getRawData()); + // os.close(); + // } catch (FileNotFoundException e) { + // e.printStackTrace(); + // } catch (IOException e) { + // e.printStackTrace(); + // } + // } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicConst.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicConst.java index 3f7085a0d2..9be61ef036 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicConst.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicConst.java @@ -27,6 +27,7 @@ public class MedtronicConst { public static final String TBRsSet = StatsPrefix + "tbrs_set"; public static final String StandardBoluses = StatsPrefix + "std_boluses_delivered"; public static final String SMBBoluses = StatsPrefix + "smb_boluses_delivered"; + public static final String LastPumpHistoryEntry = StatsPrefix + "pump_history_entry"; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicUtil.java index 01a9871a36..ab315176c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/util/MedtronicUtil.java @@ -318,8 +318,8 @@ public class MedtronicUtil extends RileyLinkUtil { if (isEmptyFrame(frameData)) { byte b = (byte)frame; // b |= 0x80; - // b |= 0b1000_0000; - b |= doneBit; + b |= 0b1000_0000; + // b |= doneBit; frameData.add(0, b); @@ -349,8 +349,8 @@ public class MedtronicUtil extends RileyLinkUtil { List frameData = new ArrayList<>(); byte b = (byte)frame; - // b |= 0b1000_0000; - b |= doneBit; + b |= 0b1000_0000; + // b |= doneBit; frameData.add(b); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 60a0fdc6de..2636147690 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1313,10 +1313,12 @@ Active Sleeping - Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually. + Remote cancel of Bolus is not supported. If you wish to cancel bolus, go to pump put it in suspend and then resume. This will cancel the bolus. Could not read current TBR. Could not cancel current TBR. Stopping operation. + Profile set failed, because following patterns, have too big basal rate: %1$s + No connection for %1$d hour(s) %2$d min No connection for %1$d day(s) %2$d hours diff --git a/docs/MedtronicRoadmap.md b/docs/MedtronicRoadmap.md new file mode 100644 index 0000000000..19a38cfb5d --- /dev/null +++ b/docs/MedtronicRoadmap.md @@ -0,0 +1,76 @@ +#Medtronic AAPS Roadmap +------------------------ + +## Phase 1: Create AAPS integration point +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Plugin | 100 | +| Base configuration (no RileyLink Discovery) | 100 | +| Basic pump configuration | 100 | +| Display Fragment | 90 | +| Pump Configuration | 70 | + + + + +## Phase 2: Implement commands within Roadtrip2 application +1. Base Bolus/Status commands + +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Set Bolus | 0 | +| Cancel Bolus | 0 | +| Get Status | 0 | + +2. TBR + +| Functionality | Done % | +| --- |:------:| +| Set TBR (Absolute) | 0 | +| Cancel TBR | 0 | + + +3. Basal Profile + +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Get Profile | 0 | +| Set Profile | 0 | + +4. History + +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Get History | 0 | +| Decde History | 0 | + +5. Extended Bolus + +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Set Extended Bolus | 0 | +| Cancel Extended Bolus | 0 | + + +6. Other commands + +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Load TDD | 0 | + + + +##Phase 3: Refactor RT2 code to split RileyLink and Medtronic parts +| Functionality | Done % | +| ----------------------------------------- |:------:| +| Refactor: Split RL and Medtronic code | 0 | +| Add RL code to AAPS | 0 | +| Start adding commands to AAPS | 0 | +| CMD: Base Bolus/Status commands | 0 | +| CMD: TBR | 0 | +| CMD: Basal Profile | 0 | +| CMD: History | 0 | +| CMD: Extended Bolus | 0 | + + + diff --git a/docs/MedtronicToDo.txt b/docs/MedtronicToDo.txt new file mode 100644 index 0000000000..a1793562e7 --- /dev/null +++ b/docs/MedtronicToDo.txt @@ -0,0 +1,129 @@ +RileyLinkAAPS +============= + + +Medtronic +- set basal profile (try to get to work - see new Loop code) +- read history + + +Bugs: + + +History: - parse pump history + + +Device search/scan refactor + + +CGMS [not in plan for now]: + - read history + + + +AAPS-Medtronic +============== + + +- history: - integrate + - basal change code + - settings change code + +- foolproofing: - bolus + - TBR + * connection (!!) + +- bolus: - progress + - cancel handling + +- What needs to be fixed: + button when clicked Refresh + x basal profile by 1/2 hour (not supported by AAPS) + +* disconnect + +- MedtronicUIResponseType integration + +- add fabric code for following errors + +- tuneup not working correctly + + +- BT Scan: + + display mac on calling Preference + + fix location problem + - fix start/stop of scan: + - remove toast button: + - Remove Refresh + - Add Scan Button + - Scan button is Stop button when search is running + - after change old error visible + +* Refresh button toggling + + +Pages (RL Info): +- Base: - display firmware version + - display current data (it doesn't work ATM) +- RL history +- Device page: - Add Commands: + - get model + - tune (with report) + - get time + - get remaining insulin + - Add Statistics: + - Bolus, + - TBR + - Bolus SMB + +- Pump Tab: - fix 3 buttons + +========================================================================================================== + +DONE - AAPS-Medtronic +===================== + ++ status time ++ status all scheduling ++ status config ++ status power + ++ Statistics in App: + + Bolus, + + TBR + + Bolus SMB + ++ status error display: + time + + basal profile enabled + + basal profile incorrect + + tbr type set + + max bolus + + max basal + + wrong pump selected + ++ Basal refactoring: - basal is read when history says there was a change ++ merge: bugs (3) ++ Code to determine number of users: + + +DONE - RileyLinkAAPS +===================== + +RileyLink ++ BT Disconnect and reconnect (change in RileyLinkBLE ??) ++ RL version + + +Medtronic +x extended bolus + + +Firmware Support: + + version 2 support: + V1 works + + V2 works + +Bugs: + + Bolus 554 + + TBR (554) ? + + Remaining Insulin [554] + + Get Basal profile returns just part of profile + + Set TBR problem (after Bolus fixes) \ No newline at end of file