From f228475617dd20640953ba2856ee7ae78d4756dc Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Wed, 24 Oct 2018 11:25:18 +0100 Subject: [PATCH] Merge the code from RileyLinkAAPS - First real results with Pump History (not complete yet) - Set Basal Profile changes (not complete yet) - version set to medtronic-0.4.0-SNAPSHOT --- app/build.gradle | 4 +- .../dialog/RileyLinkBLEScanActivity.java | 17 +- .../RileyLinkCommunicationManager.java | 5 +- .../hw/rileylink/RileyLinkUtil.java | 1 + .../plugins/PumpCommon/utils/ByteUtil.java | 30 + .../PumpCommon/utils/LocationHelper.java | 6 +- .../comm/MedtronicCommunicationManager.java | 255 +++++++-- .../comm/MedtronicConverter.java | 5 - .../comm/history/MedtronicHistoryDecoder.java | 92 ++- .../comm/history/MedtronicHistoryEntry.java | 2 +- .../cgms/MedtronicCGMSHistoryDecoder.java | 22 +- .../pump/MedtronicPumpHistoryDecoder.java | 35 +- .../comm/history/pump/PumpHistoryEntry.java | 46 ++ .../comm/history/pump/PumpHistoryResult.java | 130 +++++ .../comm/message/CarelinkLongMessageBody.java | 24 +- .../comm/message/PumpMessage.java | 2 +- .../defs/MedtronicCommandType.java | 2 + .../driver/MedtronicPumpStatus.java | 2 +- .../service/RileyLinkMedtronicService.java | 8 +- .../PumpMedtronic/util/MedtronicUtil.java | 102 ++++ .../layout/overview_wizard_dialog_compact.xml | 522 ++++++++++++++++++ 21 files changed, 1178 insertions(+), 134 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryResult.java create mode 100644 app/src/main/res/layout/overview_wizard_dialog_compact.xml diff --git a/app/build.gradle b/app/build.gradle index c78d2eb078..6a48a5c962 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,10 +71,12 @@ android { targetSdkVersion 25 multiDexEnabled true versionCode 1500 - version "2.0g-medtronic-0.3" + // dev_version: 2.0g + version "medtronic-0.4.0-snapshot" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"' + buildConfigField "String", "DEV_VERSION", '"2.0g"' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/dialog/RileyLinkBLEScanActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/dialog/RileyLinkBLEScanActivity.java index 3bf795d96b..ed24669ce4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/dialog/RileyLinkBLEScanActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/dialog/RileyLinkBLEScanActivity.java @@ -21,7 +21,6 @@ import android.bluetooth.le.ScanSettings; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -182,7 +181,7 @@ public class RileyLinkBLEScanActivity extends AppCompatActivity { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Will request that GPS be enabled for devices running Marshmallow or newer. - if (!isLocationEnabled(this)) { + if (!LocationHelper.isLocationEnabled(this)) { LocationHelper.requestLocationForBluetooth(this); } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -203,20 +202,6 @@ public class RileyLinkBLEScanActivity extends AppCompatActivity { } - public boolean isLocationEnabled(Context context) { - - final LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); - - if (manager != null - && (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) || manager - .isProviderEnabled(LocationManager.NETWORK_PROVIDER))) { - return true; - } - // otherwise return false - return false; - } - - @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); 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 4c6fa6a39e..85c0dad718 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 @@ -18,6 +18,8 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.Riley 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.RileyLinkServiceData; +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.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil; @@ -89,8 +91,7 @@ public abstract class RileyLinkCommunicationManager { RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.NoContactWithDevice); timeoutCount = 0; - tuneForDevice(); - // RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_quickTune); + ServiceTaskExecutor.startTask(new WakeAndTuneTask()); } } } 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 1f098dd3ad..2c8b4e4c00 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,6 +55,7 @@ public class RileyLinkUtil { private static RileyLinkTargetFrequency rileyLinkTargetFrequency; // Broadcasts: RileyLinkBLE, RileyLinkService, + //private static RileyLinkIPCConnection rileyLinkIPCConnection; private static RileyLinkTargetDevice targetDevice; private static RileyLinkEncodingType encoding; private static RileyLinkSelectPreference rileyLinkSelectPreference; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/ByteUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/ByteUtil.java index d3cdc9a46f..847a90c436 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/ByteUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/utils/ByteUtil.java @@ -345,4 +345,34 @@ public class ByteUtil { BIG_ENDIAN // 0 0 0 20 = normal - java } + + public static String getCompactString(byte[] data) { + String vval2 = ByteUtil.getHex(data); + vval2 = vval2.replace(" 0x", ""); + vval2 = vval2.replace("0x", ""); + return vval2; + } + + + public static byte[] createByteArray(String dataFull, int startIndex) { + return createByteArray(dataFull, startIndex, dataFull.length()); + } + + + public static byte[] createByteArray(String dataFull, int startIndex, int length) { + + String data = dataFull.substring(startIndex); + + data = data.substring(0, length); + + int len = data.length(); + byte[] outArray = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + outArray[i / 2] = (byte)((Character.digit(data.charAt(i), 16) << 4) + Character.digit(data.charAt(i + 1), + 16)); + } + + return outArray; + } + } 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 f00fe21c20..e2d9ae2254 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,7 +25,11 @@ public class LocationHelper { */ public static boolean isLocationEnabled(Context context) { LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); - return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + return (locationManager != null && // + (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || // + locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))); + + // return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } 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 39e7eac619..d67ad8ce6c 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 @@ -1,6 +1,7 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.comm; import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.joda.time.Instant; @@ -24,6 +25,9 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.Page; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.history_old.Record; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage; +import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder; +import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry; +import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryResult; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.ButtonPressCarelinkMessageBody; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkLongMessageBody; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkShortMessageBody; @@ -58,6 +62,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager String errorMessage; private MedtronicConverter medtronicConverter; private boolean debugSetCommands = true; + private MedtronicPumpHistoryDecoder pumpHistoryDecoder; private boolean doWakeUpBeforeCommand = true; private boolean firstConnection = true; @@ -66,6 +71,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager super(context, rfspy, targetFrequency); medtronicCommunicationManager = this; this.medtronicConverter = new MedtronicConverter(); + this.pumpHistoryDecoder = new MedtronicPumpHistoryDecoder(); MedtronicUtil.getPumpStatus().previousConnection = SP.getLong( RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); } @@ -231,6 +237,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager if (debugSetCommands) LOG.debug("Run command with Args: "); + PumpMessage rval; PumpMessage shortMessage = makePumpMessage(msg.commandType, new CarelinkShortMessageBody(new byte[] { 0 })); // look for ack from short message @@ -238,9 +245,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager if (shortResponse.commandType == MedtronicCommandType.CommandACK) { if (debugSetCommands) LOG.debug("Run command with Args: Got ACK response"); + rval = sendAndListen(msg); if (debugSetCommands) LOG.debug("2nd Response: {}", rval); + return rval; } else { LOG.error("runCommandWithArgs: Pump did not ack Attention packet"); @@ -249,6 +258,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } + @Deprecated private PumpMessage runCommandWithArgsLong(MedtronicCommandType commandType, byte[] content) { LOG.debug("Run command with Args (Long): {}", commandType.name()); @@ -316,7 +326,172 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // TODO fix this with new code, and new response (Page) + private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List> frames) { + + LOG.debug("Run command with Frames: {}", commandType.name()); + + PumpMessage rval = null; + PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[] { 0 })); + // look for ack from short message + PumpMessage shortResponse = sendAndListen(shortMessage); + + if (shortResponse.commandType != MedtronicCommandType.CommandACK) { + LOG.error("runCommandWithFrames: Pump did not ack Attention packet"); + + return new PumpMessage("No ACK after start message."); + } else { + 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)); + + PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frameData)); + + rval = sendAndListen(msg); + + if (rval.commandType != MedtronicCommandType.CommandACK) { + LOG.error("runCommandWithFrames: Pump did not ACK frame #{}", frameNr); + + return new PumpMessage("No ACK after frame #" + frameNr); + } else { + LOG.debug("Run command with Frames: Got ACK response for frame #{}", (frameNr)); + } + + frameNr++; + } + + return rval; + + } + + + public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) { + + // int pageNumber = 0; + + // TODO multiple history pages + + PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, targetDate); + + if (doWakeUpBeforeCommand) + wakeUp(receiverDeviceAwakeForMinutes, false); + + for (int pageNumber = 0; pageNumber < 16; pageNumber++) { + + RawHistoryPage rawHistoryPage = new RawHistoryPage(); + // wakeUp(receiverDeviceAwakeForMinutes, false); + PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData, + new GetHistoryPageCarelinkMessageBody(pageNumber)); + + LOG.info("getPumpHistory: Page {}", pageNumber); + // LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData())); + // Ask the pump to transfer history (we get first frame?) + PumpMessage firstResponse = runCommandWithArgs(getHistoryMsg); + // LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents())); + + PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody()); + GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse + .getMessageBody().getTxData()); + int expectedFrameNum = 1; + boolean done = false; + // while (expectedFrameNum == currentResponse.getFrameNumber()) { + + int failures = 0; + while (!done) { + // examine current response for problems. + byte[] frameData = currentResponse.getFrameData(); + if ((frameData != null) && (frameData.length > 0) + && currentResponse.getFrameNumber() == expectedFrameNum) { + // success! got a frame. + if (frameData.length != 64) { + LOG.warn("Expected frame of length 64, got frame of length " + frameData.length); + // but append it anyway? + } + // handle successful frame data + rawHistoryPage.appendData(currentResponse.getFrameData()); + // RileyLinkMedtronicService.getInstance().announceProgress( + // ((100 / 16) * currentResponse.getFrameNumber() + 1)); + + LOG.info("getPumpHistory: Got frame {} of Page {}", currentResponse.getFrameNumber(), pageNumber); + // Do we need to ask for the next frame? + if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722 + expectedFrameNum++; + } else { + done = true; // successful completion + } + } else { + if (frameData == null) { + LOG.error("null frame data, retrying"); + } else if (currentResponse.getFrameNumber() != expectedFrameNum) { + LOG.warn("Expected frame number {}, received {} (retrying)", expectedFrameNum, + currentResponse.getFrameNumber()); + } else if (frameData.length == 0) { + LOG.warn("Frame has zero length, retrying"); + } + failures++; + if (failures == 6) { + LOG.error( + "getPumpHistory: 6 failures in attempting to download frame {} of page {}, giving up.", + expectedFrameNum, pageNumber); + done = true; // failure completion. + } + } + if (!done) { + // ask for next frame + PumpMessage nextMsg = sendAndListen(ackMsg); + currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData()); + } + } + + if (rawHistoryPage.getLength() != 1024) { + LOG.warn("getPumpHistory: short page. Expected length of 1024, found length of " + + rawHistoryPage.getLength()); + } + + if (!rawHistoryPage.isChecksumOK()) { + LOG.error("getPumpHistory: checksum is wrong"); + } + + rawHistoryPage.dumpToDebug(); + + List medtronicHistoryEntries = pumpHistoryDecoder.processPageAndCreateRecords( + rawHistoryPage, false, PumpHistoryEntry.class); + + LOG.debug("getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size()); + + // PumpHistoryResult pumpHistoryResult = new PumpHistoryResult(lastEntry, targetDate); + pumpTotalResult.addHistoryEntries(medtronicHistoryEntries); + + LOG.debug("getPumpHistory: Search status: Search finished: {}", pumpTotalResult.isSearchFinished()); + + if (pumpTotalResult.isSearchFinished()) { + return pumpTotalResult; + } + + } + + return pumpTotalResult; + + // Page page = new Page(); + // // page.parseFrom(rval.getData(),PumpModel.MM522); + // // FIXME + // page.parseFrom(rawHistoryPage.getData(), MedtronicDeviceType.Medtronic_522); + // + // // return page; + // + // return null; + } + + + @Deprecated public Page getPumpHistoryPage(int pageNumber) { RawHistoryPage rval = new RawHistoryPage(); @@ -474,13 +649,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // protected PumpMessage makePumpMessage(byte[] typeAndBody) { - // PumpMessage msg = new PumpMessage(); - // msg.init(ByteUtil.concat(ByteUtil.concat(new byte[]{PacketType.Carelink.getValue()}, - // rileyLinkServiceData.pumpIDBytes), typeAndBody)); - // return msg; - // } - private PumpMessage sendAndGetResponse(MedtronicCommandType commandType) { return sendAndGetResponse(commandType, null, DEFAULT_TIMEOUT); @@ -531,24 +699,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // FIXME remove - // private PumpMessage sendAndGetACK(MedtronicCommandType commandType, byte[] bodyData, int timeoutMs) { - // // wakeUp - // wakeUp(receiverDeviceAwakeForMinutes, false); - // - // // create message - // PumpMessage msg; - // - // if (bodyData == null) - // msg = makePumpMessage(commandType); - // else - // msg = makePumpMessage(commandType, bodyData); - // - // // send and wait for ACK - // PumpMessage response = send(msg, timeoutMs); - // return response; - // } - protected PumpMessage sendAndListen(RLMessage msg) { return sendAndListen(msg, 4000); // 2000 } @@ -818,7 +968,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - // TODO test with values bigger than 30U public Boolean setBolus(double units) { LOG.info("setBolus: " + units); @@ -978,12 +1127,30 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager // byte[] body = basalProfile.generateRawData(); - byte[] body = new byte[] { 32, 0, 0, 38, 0, 13, 44, 0, 19, 38, 0, 28 }; + // byte[] body = new byte[] { 32, 0, 0, 38, 0, 13, 44, 0, 19, 38, 0, 28 }; - PumpMessage responseMessage; + byte[] body = ByteUtil + .createByteArray( + "06000052000178050202000304000402000504000602000704000802000904000a02000b04000c02000d02000e02000f040010020011040012020013040014020015040016020017040018020019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0); - if (debugSetCommands) - LOG.debug("Set Basal Profile: Body [{}] - {}", body.length, HexDump.toHexStringDisplayable(body)); + 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) { // @@ -992,13 +1159,15 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager // // responseMessage = runCommandWithArgs(msg); // } else - { + // { + // + // responseMessage = runCommandWithArgsLong(MedtronicCommandType.SetBasalProfileA, body); + // } - responseMessage = runCommandWithArgsLong(MedtronicCommandType.SetBasalProfileA, body); - } + // if (debugSetCommands) + // LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent())); - 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; @@ -1032,20 +1201,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager } - public PumpMessage setExtendedBolus(double units, int duration) { - // FIXME see decocare - PumpMessage response = sendAndGetResponse(MedtronicCommandType.SetBolus, MedtronicUtil.getBolusStrokes(units)); - - return response; - } - - - public PumpMessage cancelExtendedBolus() { - // set cancelBolus - return null; - } - - // Set TBR 100% // Cancel TBR (set TBR 100%) 100% // Get Status (40%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicConverter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicConverter.java index ee83680d2a..589535bf16 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicConverter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/MedtronicConverter.java @@ -38,11 +38,6 @@ public class MedtronicConverter { this.pumpModel = MedtronicUtil.getMedtronicPumpModel(); - // if (this.pumpModel == null) { - // LOG.warn("Pump model was not identified. Defaulting to 522."); - // this.pumpModel = MedtronicDeviceType.Medtronic_522; - // } - switch (commandType) { case PumpModel: { 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 e85ecde1eb..2e54efcdc0 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 @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil; +import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicDeviceType; import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil; /** @@ -43,6 +44,7 @@ public abstract class MedtronicHistoryDecoder { protected boolean statisticsEnabled = true; protected Map unknownOpCodes; protected Map> mapStatistics; + protected MedtronicDeviceType deviceType; public MedtronicHistoryDecoder() { @@ -57,42 +59,57 @@ public abstract class MedtronicHistoryDecoder { // public abstract void refreshOutputWriter(); - public boolean decodePage(RawHistoryPage dataPage) throws Exception { - // refreshOutputWriter(); - - List minimedHistoryRecords = processPageAndCreateRecords(dataPage); - - for (MedtronicHistoryEntry record : minimedHistoryRecords) { - decodeRecord(record); - } - - runPostDecodeTasks(); - - return true; - } + // public List decodePage(RawHistoryPage dataPage) throws Exception { + // // refreshOutputWriter(); + // + // List minimedHistoryRecords = processPageAndCreateRecords(dataPage); + // + // for (MedtronicHistoryEntry record : minimedHistoryRecords) { + // decodeRecord(record); + // } + // + // runPostDecodeTasks(); + // + // return minimedHistoryRecords; + // } + // public List decodePartialPage(RawHistoryPage dataPage) throws Exception { + // // refreshOutputWriter(); + // + // List minimedHistoryRecords = processPageAndCreateRecords(dataPage, true); + // + // for (MedtronicHistoryEntry record : minimedHistoryRecords) { + // decodeRecord(record); + // } + // + // runPostDecodeTasks(); + // + // return minimedHistoryRecords; + // } protected abstract void runPostDecodeTasks(); // TODO_ extend this to also use bigger pages (for now we support only 1024 // pages) - public List checkPage(RawHistoryPage page) throws RuntimeException { + public List checkPage(RawHistoryPage page, boolean partial) throws RuntimeException { List byteList = new ArrayList(); - if (page.getData().length != 1024 /* page.commandType.getRecordLength() */) { - LOG.error("Page size is not correct. Size should be {}, but it was {} instead.", 1024, - page.getData().length); - // throw exception perhaps - return byteList; - } + // if (!partial && page.getData().length != 1024 /* page.commandType.getRecordLength() */) { + // LOG.error("Page size is not correct. Size should be {}, but it was {} instead.", 1024, + // page.getData().length); + // // throw exception perhaps + // return byteList; + // } if (MedtronicUtil.getMedtronicPumpModel() == null) { LOG.error("Device Type is not defined."); return byteList; } - if (page.isChecksumOK()) { + if (page.getData().length != 1024) { + return ByteUtil.getListFromByteArray(page.getData()); + } else if (page.isChecksumOK()) { return ByteUtil.getListFromByteArray(page.getOnlyData()); } else { return null; @@ -100,9 +117,13 @@ public abstract class MedtronicHistoryDecoder { } - public abstract List processPageAndCreateRecords(RawHistoryPage page) - throws Exception; - + // public abstract List processPageAndCreateRecords(RawHistoryPage page, + // boolean partial) throws Exception; + // + // + // public List processPageAndCreateRecords(RawHistoryPage page) throws Exception { + // return processPageAndCreateRecords(page, false); + // } protected void prepareStatistics() { if (!statisticsEnabled) @@ -190,4 +211,27 @@ public abstract class MedtronicHistoryDecoder { return StringUtil.getFormatedValueUS(value, decimals); } + + // 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); + List records = createRecords(dataClear, clazz); + + for (MedtronicHistoryEntry record : records) { + decodeRecord(record); + } + + runPostDecodeTasks(); + + return records; + } + + + protected abstract List createRecords(List dataClear, Class clazz); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryEntry.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryEntry.java index 8aec6f638a..ca0c4da941 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/MedtronicHistoryEntry.java @@ -43,7 +43,7 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte protected LocalDateTime dateTime; // protected PumpTimeStampedRecord historyEntryDetails; - private Map decodedData; + protected Map decodedData; public void setData(List listRawData, boolean doNotProcess) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.java index 6b33888918..0bb554383f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/cgms/MedtronicCGMSHistoryDecoder.java @@ -11,7 +11,6 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryDecoder; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry; -import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus; /** @@ -111,14 +110,13 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder { } - @Override - public List processPageAndCreateRecords(RawHistoryPage page) throws Exception { - List dataClear = checkPage(page); - return createRecords(dataClear); - } + // @Override + // public List processPageAndCreateRecords(RawHistoryPage page) throws Exception { + // List dataClear = checkPage(page, false); + // return createRecords(dataClear); + // } - - private List createRecords(List dataClearInput) { + protected List createRecords(List dataClearInput, Class clazz) { // List listRecords = new // ArrayList(); @@ -134,7 +132,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder { int counter = 0; int record = 0; - List outList = new ArrayList(); + List outList = new ArrayList(); // create CGMS entries (without dates) do { @@ -164,7 +162,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder { // System.out.println("Record: " + pe); - outList.add(pe); + outList.add((E)pe); } else { List listRawData = new ArrayList(); listRawData.add((byte)opCode); @@ -182,7 +180,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder { // System.out.println("Record: " + pe); - outList.add(pe); + outList.add((E)pe); } } else { CGMSHistoryEntry pe = new CGMSHistoryEntry(); @@ -196,7 +194,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder { // System.out.println("Record: " + pe); - outList.add(pe); + outList.add((E)pe); } } while (counter < dataClear.size()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java index 07b7d25d5b..55e9dfb282 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java @@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump; import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryDecoder; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry; -import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus; import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusDTO; import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusWizardDTO; @@ -62,17 +61,22 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder { public MedtronicPumpHistoryDecoder() { - + super(); } - public List processPageAndCreateRecords(RawHistoryPage page) { - List dataClear = checkPage(page); - return createRecords(dataClear); - } + // public List processPageAndCreateRecords(RawHistoryPage page) { + // List dataClear = checkPage(page, false); + // return createRecords(dataClear); + // } + // public List processPageAndCreateRecords(RawHistoryPage rawHistoryPage, + // boolean partial, Class clazz) { + // + // return null; + // } - public List createRecords(List dataClear) { + public List createRecords(List dataClear, Class clazz) { prepareStatistics(); int counter = 0; @@ -80,7 +84,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder { boolean incompletePacket = false; deviceType = MedtronicUtil.getMedtronicPumpModel(); - List outList = new ArrayList(); + List outList = new ArrayList(); String skipped = null; int elementStart = 0; @@ -223,7 +227,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder { if (decoded == RecordDecodeStatus.OK) // we add only OK records, all others are ignored { - outList.add(pe); + outList.add((E)pe); } } @@ -249,6 +253,19 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder { } + public List getTypedList(List list, + Class clazz) { + + List listOut = new ArrayList<>(); + + for (MedtronicHistoryEntry medtronicHistoryEntry : list) { + listOut.add((E)medtronicHistoryEntry); + } + + return listOut; + } + + public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn, boolean x) { // FIXME // TODO diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryEntry.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryEntry.java index cf878ff424..9f7480eb37 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryEntry.java @@ -1,5 +1,11 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump; +import java.util.Objects; + +import org.joda.time.LocalDateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump; import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry; @@ -27,6 +33,8 @@ import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHi public class PumpHistoryEntry extends MedtronicHistoryEntry { + private static Logger LOG = LoggerFactory.getLogger(PumpHistoryEntry.class); + private PumpHistoryEntryType entryType; private Integer opCode; // this is set only when we have unknown entry... // private LocalDateTime timeOfEntry; @@ -98,4 +106,42 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry { public int getDateLength() { return this.entryType.getDateLength(); } + + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + + if (!(o instanceof PumpHistoryEntry)) + return false; + + PumpHistoryEntry that = (PumpHistoryEntry)o; + + return entryType == that.entryType && // + Objects.equals(this.dateTime, that.dateTime); // && // + // Objects.equals(this.decodedData, that.decodedData); + } + + + @Override + public int hashCode() { + return Objects.hash(entryType, opCode, offset); + } + + + public boolean isAfter(LocalDateTime dateTimeIn) { + // LOG.debug("Entry: " + this.dateTime); + // LOG.debug("Datetime: " + dateTimeIn); + // LOG.debug("Item after: " + this.dateTime.isAfter(dateTimeIn)); + return this.dateTime.isAfter(dateTimeIn); + } + + public static class Comparator implements java.util.Comparator { + + @Override + public int compare(PumpHistoryEntry o1, PumpHistoryEntry o2) { + return o2.dateTime.compareTo(o1.dateTime); + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryResult.java new file mode 100644 index 0000000000..267de42011 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/history/pump/PumpHistoryResult.java @@ -0,0 +1,130 @@ +package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.joda.time.LocalDateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by andy on 9/23/18. + */ + +/** + * History page contains data, sorted from oldest to newest + */ +public class PumpHistoryResult { + + private static final Logger LOG = LoggerFactory.getLogger(PumpHistoryResult.class); + + private boolean searchFinished = false; + private PumpHistoryEntry searchEntry = null; + private LocalDateTime searchDate = null; + private SearchType searchType = SearchType.None; + private List unprocessedEntries; + public List validEntries; + + + // private Object validValues; + + public PumpHistoryResult(PumpHistoryEntry searchEntry, LocalDateTime targetDate) { + if (searchEntry != null) { + this.searchEntry = searchEntry; + this.searchType = SearchType.LastEntry; + LOG.debug("PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.getLocalDateTime() + " type=" + + searchEntry.getEntryType().name()); + } else if (targetDate != null) { + this.searchDate = targetDate; + this.searchType = SearchType.Date; + LOG.debug("PumpHistoryResult. Search parameters: Date: " + targetDate); + } + + // this.unprocessedEntries = new ArrayList<>(); + this.validEntries = new ArrayList<>(); + } + + + public void addHistoryEntries(List entries) { + this.unprocessedEntries = entries; + LOG.debug("PumpHistoryResult. Unprocessed entries: {}", entries); + processEntries(); + } + + + public void processEntries() { + int olderEntries = 0; + + switch (searchType) { + case None: + this.validEntries.addAll(this.unprocessedEntries); + // this.unprocessedEntries = null; + break; + + case LastEntry: { + if (this.validEntries == null) + this.validEntries = new ArrayList<>(); + + Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator()); + + LOG.debug("PumpHistoryResult. Search entry date: " + searchEntry.getLocalDateTime()); + + for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) { + + if (unprocessedEntry.equals(searchEntry)) { + searchFinished = true; + break; + } + + this.validEntries.add(unprocessedEntry); + } + } + break; + case Date: { + if (this.validEntries == null) + this.validEntries = new ArrayList<>(); + + for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) { + if (unprocessedEntry.isAfter(this.searchDate)) { + this.validEntries.add(unprocessedEntry); + } else { + if (unprocessedEntry.getLocalDateTime().getYear() != 2000) + olderEntries++; + } + } + + if (olderEntries > 0) { + Collections.sort(this.validEntries, new PumpHistoryEntry.Comparator()); + + searchFinished = true; + } + } + break; + + } // switch + + } + + + public boolean isSearchRequired() { + return searchType != SearchType.None; + } + + + public boolean isSearchFinished() { + return searchFinished; + } + + + public List getValidEntries() { + return validEntries; + } + + enum SearchType { + None, // + LastEntry, // + Date + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/CarelinkLongMessageBody.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/CarelinkLongMessageBody.java index 54757c5bfc..4d6899f09d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/CarelinkLongMessageBody.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/CarelinkLongMessageBody.java @@ -1,5 +1,9 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.comm.message; +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil; + /** * Created by geoff on 6/2/16. */ @@ -19,13 +23,23 @@ public class CarelinkLongMessageBody extends MessageBody { } + public CarelinkLongMessageBody(List payload) { + init(MedtronicUtil.createByteArray(payload)); + } + + @Override public void init(byte[] rxData) { - data = new byte[LONG_MESSAGE_BODY_LENGTH]; - if (rxData != null) { - int size = rxData.length < LONG_MESSAGE_BODY_LENGTH ? rxData.length : LONG_MESSAGE_BODY_LENGTH; - for (int i = 0; i < size; i++) { - data[i] = rxData[i]; + + if (rxData != null && rxData.length == LONG_MESSAGE_BODY_LENGTH) { + data = rxData; + } else { + data = new byte[LONG_MESSAGE_BODY_LENGTH]; + if (rxData != null) { + int size = rxData.length < LONG_MESSAGE_BODY_LENGTH ? rxData.length : LONG_MESSAGE_BODY_LENGTH; + for (int i = 0; i < size; i++) { + data[i] = rxData[i]; + } } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/PumpMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/PumpMessage.java index 2c6e7c7022..64e9a2f9c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/PumpMessage.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/comm/message/PumpMessage.java @@ -126,7 +126,7 @@ public class PumpMessage implements RLMessage { System.arraycopy(messageBody.getTxData(), 1, arrayOut, 0, length); - Log.v("PumpMessage", "Length: " + length + ", Original Length: " + originalLength + ", CommandType: " + Log.d("PumpMessage", "Length: " + length + ", Original Length: " + originalLength + ", CommandType: " + commandType); return arrayOut; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/defs/MedtronicCommandType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/defs/MedtronicCommandType.java index b49017d058..9a3d5771b3 100755 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/defs/MedtronicCommandType.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/defs/MedtronicCommandType.java @@ -109,8 +109,10 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType GetBasalProfileSTD(146, "Get Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8, 1), // 146 GetBasalProfileA(147, "Get Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 9), // 147 + // FIXME GetBasalProfileB(148, "Get Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 10), // 148 + // FIXME SetBasalProfileSTD(0x6f, "Set Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 111 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/driver/MedtronicPumpStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/driver/MedtronicPumpStatus.java index 1d2916aded..f02e7612f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/driver/MedtronicPumpStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMedtronic/driver/MedtronicPumpStatus.java @@ -255,7 +255,7 @@ public class MedtronicPumpStatus extends PumpStatus { } if (val > defaultValueDouble) { - SP.putString(MedtronicConst.Prefs.MaxBolus, "25.0"); + SP.putString(MedtronicConst.Prefs.MaxBolus, defaultValue); val = defaultValueDouble; } 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 dcd0be30ee..78f2a7b4a4 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 @@ -75,8 +75,8 @@ public class RileyLinkMedtronicService extends RileyLinkService { public void addPumpSpecificIntents(IntentFilter intentFilter) { - intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchHistory); - intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory); + //intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchHistory); + //intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory); } @@ -431,10 +431,6 @@ public class RileyLinkMedtronicService extends RileyLinkService { } - // public MedtronicCommunicationManager getPumpManager() { - // return this.medtronicCommunicationManager; - // } - // FIXME remove public void sendNotification(ServiceNotification serviceNotification, Object o) { LOG.warn("Send Notification has no implementation."); 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 3b329cc4e6..01a9871a36 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 @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.util; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -45,6 +46,8 @@ public class MedtronicUtil extends RileyLinkUtil { private static MedtronicPumpStatus medtronicPumpStatus; private static MedtronicCommandType currentCommand; private static Map settings; + private static int BIG_FRAME_LENGTH = 65; + private static int doneBit = 1 << 7; public static LocalTime getTimeFrom30MinInterval(int interval) { @@ -285,6 +288,105 @@ public class MedtronicUtil extends RileyLinkUtil { } + // Note: at the moment supported only for 24 items, if you will use it for more than + // that you will need to add + public static List> getBasalProfileFrames(byte[] data) { + + boolean done = false; + int start = 0; + int frame = 1; + + List> frames = new ArrayList<>(); + boolean lastFrame = false; + + do { + int frameLength = BIG_FRAME_LENGTH - 1; + + if (start + frameLength > data.length) { + frameLength = data.length - start; + } + + // System.out.println("Framelength: " + frameLength); + + byte[] substring = ByteUtil.substring(data, start, frameLength); + + // System.out.println("Subarray: " + ByteUtil.getCompactString(substring)); + // System.out.println("Subarray Lenths: " + substring.length); + + List frameData = ByteUtil.getListFromByteArray(substring); + + if (isEmptyFrame(frameData)) { + byte b = (byte)frame; + // b |= 0x80; + // b |= 0b1000_0000; + b |= doneBit; + + frameData.add(0, b); + + checkAndAppenLastFrame(frameData); + + lastFrame = true; + + done = true; + } else { + frameData.add(0, (byte)frame); + } + + // System.out.println("Subarray: " + ByteUtil.getCompactString(substring)); + + frames.add(frameData); + + frame++; + start += (BIG_FRAME_LENGTH - 1); + + if (start == data.length) { + done = true; + } + + } while (!done); + + if (!lastFrame) { + List frameData = new ArrayList<>(); + + byte b = (byte)frame; + // b |= 0b1000_0000; + b |= doneBit; + + frameData.add(b); + + checkAndAppenLastFrame(frameData); + } + + return frames; + + } + + + private static void checkAndAppenLastFrame(List frameData) { + + if (frameData.size() == BIG_FRAME_LENGTH) + return; + + int missing = BIG_FRAME_LENGTH - frameData.size(); + + for (int i = 0; i < missing; i++) { + frameData.add((byte)0x00); + } + } + + + private static boolean isEmptyFrame(List frameData) { + + for (Byte frameDateEntry : frameData) { + if (frameDateEntry != 0x00) { + return false; + } + } + + return true; + } + + public static boolean isLowLevelDebug() { return lowLevelDebug; } diff --git a/app/src/main/res/layout/overview_wizard_dialog_compact.xml b/app/src/main/res/layout/overview_wizard_dialog_compact.xml new file mode 100644 index 0000000000..be0c1254af --- /dev/null +++ b/app/src/main/res/layout/overview_wizard_dialog_compact.xml @@ -0,0 +1,522 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file