Configuration:
- added delay for Bolus delivery
- added choice for decoding (done on RL or in software)

Code:
- encoding DailyTotals for 522 and 523
- some minor fixes reported by Crashalytics
- refactoring history
- added history display
- changes to delivering Bolus (canceling)
- started adding 6b4b hardware decoding
This commit is contained in:
Andy Rozman 2019-01-04 14:02:10 +01:00
parent a9200e9e3e
commit 56eaacb3a2
38 changed files with 1506 additions and 1183 deletions

View file

@ -213,6 +213,7 @@
android:label="@string/title_activity_rileylink_settings" android:label="@string/title_activity_rileylink_settings"
android:theme="@style/Theme.AppCompat.NoTitle" /> android:theme="@style/Theme.AppCompat.NoTitle" />
<activity android:name=".plugins.PumpMedtronic.dialog.MedtronicHistoryActivity" />
</application> </application>

View file

@ -272,6 +272,8 @@ public class MainApp extends Application {
// SP.putDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, null); // SP.putDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, null);
SP.remove(MedtronicConst.Statistics.LastPumpHistoryEntry); // FIXME remove SP.remove(MedtronicConst.Statistics.LastPumpHistoryEntry); // FIXME remove
//SP.putString(MedtronicConst.Prefs.PumpFrequency, "US (916 MHz)");
// RileyLink framework needs to know, when BT was reconnected, so that we can reconnect to RL device // RileyLink framework needs to know, when BT was reconnected, so that we can reconnect to RL device
btReceiver = new BroadcastReceiver() { btReceiver = new BroadcastReceiver() {

View file

@ -78,15 +78,17 @@ public class RileyLinkUtil {
public static void setEncoding(RileyLinkEncodingType encoding) { public static void setEncoding(RileyLinkEncodingType encoding) {
RileyLinkUtil.encoding = encoding; RileyLinkUtil.encoding = encoding;
if (encoding == RileyLinkEncodingType.FourByteSixByte) { if (encoding == RileyLinkEncodingType.FourByteSixByteLocal) {
RileyLinkUtil.encoding4b6b = new Encoding4b6bGeoff(); RileyLinkUtil.encoding4b6b = new Encoding4b6bGeoff();
} }
} }
public static void sendBroadcastMessage(String message) { public static void sendBroadcastMessage(String message) {
Intent intent = new Intent(message); if (context != null) {
LocalBroadcastManager.getInstance(RileyLinkUtil.context).sendBroadcast(intent); Intent intent = new Intent(message);
LocalBroadcastManager.getInstance(RileyLinkUtil.context).sendBroadcast(intent);
}
} }

View file

@ -81,8 +81,8 @@ public class RFSpy {
// Here should go generic RL initialisation + protocol adjustments depending on // Here should go generic RL initialisation + protocol adjustments depending on
// firmware version // firmware version
public void initializeRileyLink() { public void initializeRileyLink() {
firmwareVersion = getFirmwareVersion();
bleVersion = getVersion(); bleVersion = getVersion();
firmwareVersion = getFirmwareVersion();
} }
@ -98,7 +98,9 @@ public class RFSpy {
public String getVersion() { public String getVersion() {
BLECommOperationResult result = rileyLinkBle.readCharacteristic_blocking(radioServiceUUID, radioVersionUUID); BLECommOperationResult result = rileyLinkBle.readCharacteristic_blocking(radioServiceUUID, radioVersionUUID);
if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) {
return StringUtil.fromBytes(result.value); String version = StringUtil.fromBytes(result.value);
LOG.debug("BLE Version: " + version);
return version;
} else { } else {
LOG.error("getVersion failed with code: " + result.resultCode); LOG.error("getVersion failed with code: " + result.resultCode);
return "(null)"; return "(null)";
@ -107,14 +109,22 @@ public class RFSpy {
public RileyLinkFirmwareVersion getFirmwareVersion() { public RileyLinkFirmwareVersion getFirmwareVersion() {
LOG.debug("Firmware Version. Get Version - Start");
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
// We have to call raw version of communication to get firmware version // We have to call raw version of communication to get firmware version
// So that we can adjust other commands accordingly afterwords // So that we can adjust other commands accordingly afterwords
byte[] getVersionRaw = getByteArray(RileyLinkCommandType.GetVersion.code); byte[] getVersionRaw = getByteArray(RileyLinkCommandType.GetVersion.code);
byte[] response = writeToDataRaw(getVersionRaw, 5000); byte[] response = writeToDataRaw(getVersionRaw, 5000);
LOG.debug("Firmware Version. GetVersion [response={}]", ByteUtil.getHex(response));
if (response != null) { // && response[0] == (byte) 0xDD) { if (response != null) { // && response[0] == (byte) 0xDD) {
String versionString = StringUtil.fromBytes(response); String versionString = StringUtil.fromBytes(response);
RileyLinkFirmwareVersion version = RileyLinkFirmwareVersion.getByVersionString(StringUtil RileyLinkFirmwareVersion version = RileyLinkFirmwareVersion.getByVersionString(StringUtil
.fromBytes(response)); .fromBytes(response));
@ -127,6 +137,12 @@ public class RFSpy {
} }
} }
LOG.error("Firmware Version can't be determined. Checking with BLE Version [{}].", bleVersion);
if (bleVersion.contains(" 2.")) {
return RileyLinkFirmwareVersion.Version_2_0;
}
return RileyLinkFirmwareVersion.UnknownVersion; return RileyLinkFirmwareVersion.UnknownVersion;
} }
@ -310,7 +326,7 @@ public class RFSpy {
updateRegister(CC111XRegister.mdmcfg1, 0x62); updateRegister(CC111XRegister.mdmcfg1, 0x62);
updateRegister(CC111XRegister.mdmcfg0, 0x1A); updateRegister(CC111XRegister.mdmcfg0, 0x1A);
updateRegister(CC111XRegister.deviatn, 0x13); updateRegister(CC111XRegister.deviatn, 0x13);
// RileyLinkUtil.setEncoding(RileyLinkEncodingType.FourByteSixByte); setMedtronicEncoding();
} }
break; break;
@ -322,10 +338,10 @@ public class RFSpy {
updateRegister(CC111XRegister.mdmcfg1, 0x61); updateRegister(CC111XRegister.mdmcfg1, 0x61);
updateRegister(CC111XRegister.mdmcfg0, 0x7E); updateRegister(CC111XRegister.mdmcfg0, 0x7E);
updateRegister(CC111XRegister.deviatn, 0x15); updateRegister(CC111XRegister.deviatn, 0x15);
// RileyLinkUtil.setEncoding(RileyLinkEncodingType.FourByteSixByte); setMedtronicEncoding();
} }
break; break;
case Omnipod: { case Omnipod: {
RFSpyResponse r = null; RFSpyResponse r = null;
// RL initialization for Omnipod is a copy/paste from OmniKit implementation. // RL initialization for Omnipod is a copy/paste from OmniKit implementation.
@ -369,6 +385,15 @@ public class RFSpy {
} }
private void setMedtronicEncoding() {
// FIXME
// check settings if RileyLink_4b6b is enabled, and then check if we have version 2.2 or higher, if both
// are yes then we set encoding on RileyLink and set it in RileyLinkUtil.
}
private RFSpyResponse setPreamble(int preamble) { private RFSpyResponse setPreamble(int preamble) {
RFSpyResponse resp = null; RFSpyResponse resp = null;
try { try {

View file

@ -25,7 +25,6 @@ public class RFSpyReader {
private static final Logger LOG = LoggerFactory.getLogger(RFSpyReader.class); private static final Logger LOG = LoggerFactory.getLogger(RFSpyReader.class);
private static AsyncTask<Void, Void, Void> readerTask; private static AsyncTask<Void, Void, Void> readerTask;
// private Context context;
private RileyLinkBLE rileyLinkBle; private RileyLinkBLE rileyLinkBle;
private Semaphore waitForRadioData = new Semaphore(0, true); private Semaphore waitForRadioData = new Semaphore(0, true);
private LinkedBlockingQueue<byte[]> mDataQueue = new LinkedBlockingQueue<>(); private LinkedBlockingQueue<byte[]> mDataQueue = new LinkedBlockingQueue<>();
@ -33,14 +32,12 @@ public class RFSpyReader {
private int releaseCount = 0; private int releaseCount = 0;
public RFSpyReader(/* Context context, */RileyLinkBLE rileyLinkBle) { public RFSpyReader(RileyLinkBLE rileyLinkBle) {
// this.context = context;
this.rileyLinkBle = rileyLinkBle; this.rileyLinkBle = rileyLinkBle;
} }
public void init(/* Context context, */RileyLinkBLE rileyLinkBLE) { public void init(RileyLinkBLE rileyLinkBLE) {
// this.context = context;
this.rileyLinkBle = rileyLinkBLE; this.rileyLinkBle = rileyLinkBLE;
} }

View file

@ -1,447 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
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 };
private static final Logger LOG = LoggerFactory.getLogger(RFTools.class);
private final static char[] HEX_DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/*
* CodeSymbols is an ordered list of translations
* 6bits -> 4 bits, in order from 0x0 to 0xF
* The 6 bit codes are what is used on the RF side of the RileyLink
* to communicate with a Medtronic pump.
*/
public static byte[] CodeSymbols = {
0x15, 0x31, 0x32, 0x23, 0x34, 0x25, 0x26, 0x16, 0x1a, 0x19, 0x2a, 0x0b, 0x2c, 0x0d, 0x0e, 0x1c };
public static byte[] appendChecksum(final byte[] input) {
if (input == null) {
return null;
}
if (input.length == 0) {
return null;
}
byte[] rval = new byte[input.length + 1];
System.arraycopy(input, 0, rval, 0, input.length);
byte mycrc = CRC.crc8(input);
LOG.debug(String.format("Adding checksum 0x%02X to %d byte array from 0x%02X to 0x%02X", mycrc, input.length,
input[0], input[input.length - 1]));
rval[input.length] = mycrc;
return rval;
}
/*
* + (NSData*)encode4b6b:(NSData*)data {
* NSMutableData *outData = [NSMutableData data];
* NSMutableData *dataPlusCrc = [data mutableCopy];
* unsigned char crc = [MinimedPacket crcForData:data];
* [dataPlusCrc appendBytes:&crc length:1];
* char codes[16] = {21,49,50,35,52,37,38,22,26,25,42,11,44,13,14,28};
* const unsigned char *inBytes = [dataPlusCrc bytes];
* unsigned int acc = 0x0;
* int bitcount = 0;
* for (int i=0; i < dataPlusCrc.length; i++) {
* acc <<= 6;
* acc |= codes[inBytes[i] >> 4];
* bitcount += 6;
*
* acc <<= 6;
* acc |= codes[inBytes[i] & 0x0f];
* bitcount += 6;
*
* while (bitcount >= 8) {
* unsigned char outByte = acc >> (bitcount-8) & 0xff;
* [outData appendBytes:&outByte length:1];
* bitcount -= 8;
* acc &= (0xffff >> (16-bitcount));
* }
* }
* if (bitcount > 0) {
* acc <<= (8-bitcount);
* unsigned char outByte = acc & 0xff;
* [outData appendBytes:&outByte length:1];
* }
* return outData;
* }
*/
public static ArrayList<Byte> fromBytes(byte[] data) {
ArrayList<Byte> rval = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
rval.add(data[i]);
}
return rval;
}
public static byte[] toBytes(ArrayList<Byte> data) {
byte[] rval = new byte[data.size()];
for (int i = 0; i < data.size(); i++) {
rval[i] = data.get(i);
}
return rval;
}
/* O(n) lookup. Run on an O(n) translation of a byte-stream, gives O(n**2) performance. Sigh. */
public static int codeIndex(byte b) {
for (int i = 0; i < codes.length; i++) {
if (b == codes[i]) {
return i;
}
}
return -1;
}
public static byte[] encode4b6b(byte[] data) {
if ((data.length % 2) != 0) {
// LOG.error("Warning: data is odd number of bytes");
}
// use arraylists because byte[] is annoying.
ArrayList<Byte> inData = fromBytes(data);
ArrayList<Byte> outData = new ArrayList<>();
int acc = 0;
int bitcount = 0;
int i;
for (i = 0; i < inData.size(); i++) {
acc <<= 6;
acc |= codes[(inData.get(i) >> 4) & 0x0f];
bitcount += 6;
acc <<= 6;
acc |= codes[inData.get(i) & 0x0f];
bitcount += 6;
while (bitcount >= 8) {
byte outByte = (byte)(acc >> (bitcount - 8) & 0xff);
outData.add(outByte);
bitcount -= 8;
acc &= (0xffff >> (16 - bitcount));
}
}
if (bitcount > 0) {
acc <<= 6;
acc |= 0x14; // marks uneven packet boundary.
bitcount += 6;
if (bitcount >= 8) {
byte outByte = (byte)((acc >> (bitcount - 8)) & 0xff);
outData.add(outByte);
bitcount -= 8;
// acc &= (0xffff >> (16 - bitcount));
}
while (bitcount >= 8) {
outData.add((byte)0);
bitcount -= 8;
}
}
// convert back to byte[]
byte[] rval = toBytes(outData);
return rval;
}
public static byte[] encode4b6b_newtest(byte[] data) {
List<Byte> buffer = new ArrayList<Byte>();
int bitAccumulator = 0x0;
int bitcount = 0;
for (byte element : data) {
bitAccumulator <<= 6;
bitAccumulator |= codes[element >> 4];
bitcount += 6;
bitAccumulator <<= 6;
bitAccumulator |= codes[element & 0x0f];
bitcount += 6;
while (bitcount >= 8) {
buffer.add((byte)((bitAccumulator >> (bitcount - 8)) & 0xff));
bitcount -= 8;
bitAccumulator &= (0xffff >> (16 - bitcount));
}
}
if (bitcount > 0) {
bitAccumulator <<= (8 - bitcount);
buffer.add((byte)((bitAccumulator) & 0xff));
}
return ByteUtil.getByteArrayFromList(buffer);
}
// public func encode4b6b() -> [UInt8] {
// var buffer = [UInt8]()
// var bitAccumulator = 0x0
// var bitcount = 0
// for byte in self {
// bitAccumulator <<= 6
// bitAccumulator |= codes[Int(byte >> 4)]
// bitcount += 6
//
// bitAccumulator <<= 6
// bitAccumulator |= codes[Int(byte & 0x0f)]
// bitcount += 6
//
// while bitcount >= 8 {
// buffer.append(UInt8(bitAccumulator >> (bitcount-8)) & 0xff)
// bitcount -= 8
// bitAccumulator &= (0xffff >> (16-bitcount))
// }
// }
// if bitcount > 0 {
// bitAccumulator <<= (8-bitcount)
// buffer.append(UInt8(bitAccumulator) & 0xff)
// }
// return buffer
// }
public static void test() {
/*
* {0xa7} -> {0xa9, 0x60}
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
*/
/* test compare */
byte[] s1 = { 0, 1, 2 };
byte[] s2 = { 2, 1, 0, 3 };
byte[] s3 = { 0, 1, 2, 3 };
if (ByteUtil.compare(s1, s1) != 0) {
LOG.error("test: compare failed.");
}
if (ByteUtil.compare(s1, s2) >= 0) {
LOG.error("test: compare failed.");
}
if (ByteUtil.compare(s2, s1) <= 0) {
LOG.error("test: compare failed.");
}
if (ByteUtil.compare(s1, s3) >= 0) {
LOG.error("test: compare failed.");
}
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
if (ByteUtil.compare(bs, out) != 0) {
LOG.error("encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
}
bs = encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) {
LOG.error("encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
}
bs = encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) {
LOG.error("encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
}
return;
}
public static byte[] decode4b6b(byte[] raw) throws NumberFormatException {
/*
* if ((raw.length % 2) != 0) {
* LOG.error("Warning: data is odd number of bytes");
* }
*/
byte[] rval = new byte[] {};
int availableBits = 0;
int codingErrors = 0;
int x = 0;
// Log.w(TAG,"decode4b6b: untested code");
// Log.w(TAG,String.format("Decoding %d bytes: %s",raw.length,ByteUtil.shortHexString(raw)));
for (int i = 0; i < raw.length; i++) {
int unsignedValue = raw[i];
if (unsignedValue < 0) {
unsignedValue += 256;
}
x = (x << 8) + unsignedValue;
availableBits += 8;
if (availableBits >= 12) {
// take top six
int highcode = (x >> (availableBits - 6)) & 0x3F;
int highIndex = codeIndex((byte)(highcode));
// take bottom six
int lowcode = (x >> (availableBits - 12)) & 0x3F;
int lowIndex = codeIndex((byte)(lowcode));
// special case at end of transmission on uneven boundaries:
if ((highIndex >= 0) && (lowIndex >= 0)) {
byte decoded = (byte)((highIndex << 4) + lowIndex);
rval = ByteUtil.concat(rval, decoded);
/*
* LOG.debug(String.format(
* "i=%d,x=0x%08X,0x%02X->0x%02X, 0x%02X->0x%02X, result: 0x%02X, %d bits remaining, errors %d, bytes remaining: %s"
* ,
* i,x,highcode,highIndex, lowcode,
* lowIndex,decoded,availableBits,codingErrors,ByteUtil.shortHexString
* (ByteUtil.substring(raw,i+1,raw.length-i-1))));
*/
} else {
// LOG.debug(String.format("i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining",i,x,highcode,lowcode,availableBits));
codingErrors++;
}
availableBits -= 12;
x = x & (0x0000ffff >> (16 - availableBits));
} else {
// LOG.debug(String.format("i=%d, skip: x=0x%08X, available bits %d",i,x,availableBits));
}
}
if (availableBits != 0) {
if ((availableBits == 4) && (x == 0x05)) {
// normal end
} else {
LOG.error("decode4b6b: failed clean decode -- extra bits available (not marker)(" + availableBits + ")");
codingErrors++;
}
} else {
// also normal end.
}
if (codingErrors > 0) {
LOG.error("decode4b6b: " + codingErrors + " coding errors encountered.");
throw new NumberFormatException();
}
return rval;
}
public static DecodeResponseDto decode4b6bWithoutException(byte[] raw) {
/*
* if ((raw.length % 2) != 0) {
* LOG.error("Warning: data is odd number of bytes");
* }
*/
DecodeResponseDto response = new DecodeResponseDto();
StringBuilder errorMessageBuilder = new StringBuilder();
errorMessageBuilder.append("Input data: " + ByteUtil.getHex(raw) + "\n");
if ((raw.length % 2) != 0) {
errorMessageBuilder.append("Warn: odd number of bytes.");
}
byte[] rval = new byte[] {};
int availableBits = 0;
int codingErrors = 0;
int x = 0;
// Log.w(TAG,"decode4b6b: untested code");
// Log.w(TAG,String.format("Decoding %d bytes: %s",raw.length,ByteUtil.shortHexString(raw)));
for (int i = 0; i < raw.length; i++) {
int unsignedValue = raw[i];
if (unsignedValue < 0) {
unsignedValue += 256;
}
x = (x << 8) + unsignedValue;
availableBits += 8;
if (availableBits >= 12) {
// take top six
int highcode = (x >> (availableBits - 6)) & 0x3F;
int highIndex = codeIndex((byte)(highcode));
// take bottom six
int lowcode = (x >> (availableBits - 12)) & 0x3F;
int lowIndex = codeIndex((byte)(lowcode));
// special case at end of transmission on uneven boundaries:
if ((highIndex >= 0) && (lowIndex >= 0)) {
byte decoded = (byte)((highIndex << 4) + lowIndex);
rval = ByteUtil.concat(rval, decoded);
/*
* LOG.debug(String.format(
* "i=%d,x=0x%08X,0x%02X->0x%02X, 0x%02X->0x%02X, result: 0x%02X, %d bits remaining, errors %d, bytes remaining: %s"
* ,
* i,x,highcode,highIndex, lowcode,
* lowIndex,decoded,availableBits,codingErrors,ByteUtil.shortHexString
* (ByteUtil.substring(raw,i+1,raw.length-i-1))));
*/
} else {
// LOG.debug(String.format("i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining",i,x,highcode,lowcode,availableBits));
errorMessageBuilder.append(String.format(
"decode4b6b: i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining.\n",
i, x, highcode, lowcode, availableBits));
codingErrors++;
}
availableBits -= 12;
x = x & (0x0000ffff >> (16 - availableBits));
} else {
// LOG.debug(String.format("i=%d, skip: x=0x%08X, available bits %d",i,x,availableBits));
}
}
if (availableBits != 0) {
if ((availableBits == 4) && (x == 0x05)) {
// normal end
} else {
LOG.error("decode4b6b: failed clean decode -- extra bits available (not marker)(" + availableBits + ")");
errorMessageBuilder.append("decode4b6b: failed clean decode -- extra bits available (not marker)("
+ availableBits + ")\n");
codingErrors++;
}
} else {
// also normal end.
}
if (codingErrors > 0) {
LOG.error("decode4b6b: " + codingErrors + " coding errors encountered.");
errorMessageBuilder.append("decode4b6b: " + codingErrors + " coding errors encountered.");
response.errorData = errorMessageBuilder.toString();
} else {
response.data = rval;
}
return response;
}
public static String toHexString(byte[] array) {
return toHexString(array, 0, array.length);
}
public static String toHexString(byte[] array, int offset, int length) {
char[] buf = new char[length * 2];
int bufIndex = 0;
for (int i = offset; i < offset + length; i++) {
byte b = array[i];
buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
}
return new String(buf);
}
public static class DecodeResponseDto {
public byte[] data;
public String errorData;
}
}

View file

@ -316,7 +316,6 @@ public class RileyLinkBLE {
debugService(serviceI, indentCount + 4); debugService(serviceI, indentCount + 4);
} }
} }
// }
} }

View file

@ -6,7 +6,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.Riley
* Created by andy on 11/23/18. * Created by andy on 11/23/18.
*/ */
public class RileyLinkCommunicationException extends Throwable { public class RileyLinkCommunicationException extends Exception {
String extendedErrorText; String extendedErrorText;
private RileyLinkBLEError errorCode; private RileyLinkBLEError errorCode;

View file

@ -38,13 +38,17 @@ public class RadioPacket {
return pkt; return pkt;
} }
case FourByteSixByte: { case FourByteSixByteLocal: {
byte[] withCRC = getWithCRC(); byte[] withCRC = getWithCRC();
byte[] encoded = RileyLinkUtil.getEncoding4b6b().encode4b6b(withCRC); byte[] encoded = RileyLinkUtil.getEncoding4b6b().encode4b6b(withCRC);
return ByteUtil.concat(encoded, (byte)0); return ByteUtil.concat(encoded, (byte)0);
} }
case FourByteSixByteRileyLink: {
return pkt;
}
default: default:
throw new NotImplementedException(("Encoding not supported: " + RileyLinkUtil.getEncoding().toString())); throw new NotImplementedException(("Encoding not supported: " + RileyLinkUtil.getEncoding().toString()));
} }

View file

@ -94,11 +94,15 @@ public class RadioResponse {
} }
switch (RileyLinkUtil.getEncoding()) { switch (RileyLinkUtil.getEncoding()) {
case Manchester: case Manchester:
case FourByteSixByteRileyLink: {
decodedOK = true; decodedOK = true;
decodedPayload = encodedPayload; decodedPayload = encodedPayload;
}
break; break;
case FourByteSixByte:
case FourByteSixByteLocal: {
byte[] decodeThis = RileyLinkUtil.getEncoding4b6b().decode4b6b(encodedPayload); byte[] decodeThis = RileyLinkUtil.getEncoding4b6b().decode4b6b(encodedPayload);
decodedOK = true; decodedOK = true;
@ -109,7 +113,9 @@ public class RadioResponse {
LOG.error(String.format("RadioResponse: CRC mismatch, calculated 0x%02x, received 0x%02x", LOG.error(String.format("RadioResponse: CRC mismatch, calculated 0x%02x, received 0x%02x",
calculatedCRC, receivedCRC)); calculatedCRC, receivedCRC));
} }
}
break; break;
default: default:
throw new NotImplementedException("this {" + RileyLinkUtil.getEncoding().toString() throw new NotImplementedException("this {" + RileyLinkUtil.getEncoding().toString()
+ "} encoding is not supported"); + "} encoding is not supported");

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs; package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs;
public enum RileyLinkEncodingType { public enum RileyLinkEncodingType {
None(0x00), //
Manchester(0x01), // None(0x00), // No encoding on RL
FourByteSixByte(0x02), // Manchester(0x01), // Manchester encoding on RL (for Omnipod)
FourByteSixByteRileyLink(0x02), // 4b6b encoding on RL (for Medtronic)
FourByteSixByteLocal(0x00), // No encoding on RL, but 4b6b encoding in code
; ;
public byte value; public byte value;

View file

@ -4,6 +4,9 @@ package info.nightscout.androidaps.plugins.PumpCommon.utils;
* Created by andy on 10/25/18. * Created by andy on 10/25/18.
*/ */
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
/** /**
@ -53,6 +56,20 @@ public class DateTimeUtil {
} }
public static long toATechDate(GregorianCalendar gc) {
long atechDateTime = 0L;
atechDateTime += gc.get(Calendar.YEAR) * 10000000000L;
atechDateTime += (gc.get(Calendar.MONTH) + 1) * 100000000L;
atechDateTime += gc.get(Calendar.DAY_OF_MONTH) * 1000000L;
atechDateTime += gc.get(Calendar.HOUR_OF_DAY) * 10000L;
atechDateTime += gc.get(Calendar.MINUTE) * 100L;
atechDateTime += gc.get(Calendar.SECOND);
return atechDateTime;
}
public static boolean isSameDay(LocalDateTime ldt1, LocalDateTime ldt2) { public static boolean isSameDay(LocalDateTime ldt1, LocalDateTime ldt2) {
return (ldt1.getYear() == ldt2.getYear() && // return (ldt1.getYear() == ldt2.getYear() && //
@ -62,6 +79,15 @@ public class DateTimeUtil {
} }
public static boolean isSameDay(long ldt1, long ldt2) {
long day1 = ldt1 / 10000L;
long day2 = ldt2 / 10000L;
return day1 == day2;
}
public static long toATechDate(int year, int month, int dayOfMonth, int hour, int minutes, int seconds) { public static long toATechDate(int year, int month, int dayOfMonth, int hour, int minutes, int seconds) {
long atechDateTime = 0L; long atechDateTime = 0L;
@ -104,4 +130,10 @@ public class DateTimeUtil {
return (number < 10) ? "0" + number : "" + number; return (number < 10) ? "0" + number : "" + number;
} }
public static int getYear(long atechDateTime) {
int year = (int)(atechDateTime / 10000000000L);
return year;
}
} }

View file

@ -40,6 +40,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLink
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.dialog.RileyLinkStatusActivity; import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.dialog.RileyLinkStatusActivity;
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicCommandType; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicCommandType;
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.PumpMedtronic.dialog.MedtronicHistoryActivity;
import info.nightscout.androidaps.plugins.PumpMedtronic.driver.MedtronicPumpStatus; import info.nightscout.androidaps.plugins.PumpMedtronic.driver.MedtronicPumpStatus;
import info.nightscout.androidaps.plugins.PumpMedtronic.events.EventMedtronicDeviceStatusChange; import info.nightscout.androidaps.plugins.PumpMedtronic.events.EventMedtronicDeviceStatusChange;
import info.nightscout.androidaps.plugins.PumpMedtronic.events.EventMedtronicPumpConfigurationChanged; import info.nightscout.androidaps.plugins.PumpMedtronic.events.EventMedtronicPumpConfigurationChanged;
@ -146,13 +147,15 @@ public class MedtronicFragment extends SubscriberFragment {
@OnClick(R.id.medtronic_history) @OnClick(R.id.medtronic_history)
void onHistoryClick() { void onHistoryClick() {
// startActivity(new Intent(getContext(), DanaRHistoryActivity.class)); startActivity(new Intent(getContext(), MedtronicHistoryActivity.class));
} }
@OnClick(R.id.medtronic_refresh) @OnClick(R.id.medtronic_refresh)
void onRefreshClick() { void onRefreshClick() {
refreshButton.setEnabled(false); if (refreshButtonStatic != null)
refreshButtonStatic.setEnabled(false);
MedtronicPumpPlugin.getPlugin().resetStatusState(); MedtronicPumpPlugin.getPlugin().resetStatusState();
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked refresh", new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked refresh", new Callback() {
@ -163,7 +166,8 @@ public class MedtronicFragment extends SubscriberFragment {
if (activity != null) { if (activity != null) {
activity.runOnUiThread(() -> { activity.runOnUiThread(() -> {
refreshButton.setEnabled(true); if (refreshButtonStatic != null)
refreshButtonStatic.setEnabled(true);
}); });
} }
} }
@ -219,7 +223,7 @@ public class MedtronicFragment extends SubscriberFragment {
pumpStatus.rileyLinkServiceState = (RileyLinkServiceState)checkStatusSet(pumpStatus.rileyLinkServiceState, pumpStatus.rileyLinkServiceState = (RileyLinkServiceState)checkStatusSet(pumpStatus.rileyLinkServiceState,
RileyLinkUtil.getServiceState()); RileyLinkUtil.getServiceState());
if (pumpStatus.rileyLinkServiceState != null) { if (pumpStatus.rileyLinkServiceState != null && rileyLinkStatus != null) {
int resourceId = pumpStatus.rileyLinkServiceState.getResourceId(getTargetDevice()); int resourceId = pumpStatus.rileyLinkServiceState.getResourceId(getTargetDevice());
rileyLinkStatus.setTextColor(Color.WHITE); rileyLinkStatus.setTextColor(Color.WHITE);
@ -271,7 +275,7 @@ public class MedtronicFragment extends SubscriberFragment {
case ErrorWhenCommunicating: case ErrorWhenCommunicating:
case TimeoutWhenCommunicating: case TimeoutWhenCommunicating:
case InvalidConfiguration: case InvalidConfiguration:
pumpStatusIconView.setText(" " + getTranslation(pumpStatus.pumpDeviceState.getResourceId())); pumpStatusIconView.setText(" " + getTranslation(pumpStatus.pumpDeviceState.getResourceId()));
break; break;
// FIXME // FIXME
@ -281,24 +285,25 @@ public class MedtronicFragment extends SubscriberFragment {
LOG.debug("Command: " + cmd); LOG.debug("Command: " + cmd);
if (cmd == null) if (cmd == null)
pumpStatusIconView.setText(" " + MainApp.gs(pumpStatus.pumpDeviceState.getResourceId())); pumpStatusIconView.setText(" " + MainApp.gs(pumpStatus.pumpDeviceState.getResourceId()));
else { else {
Integer resourceId = cmd.getResourceId(); Integer resourceId = cmd.getResourceId();
if (cmd == MedtronicCommandType.GetHistoryData) { if (cmd == MedtronicCommandType.GetHistoryData) {
if (resourceId == null) { if (MedtronicUtil.frameNumber == null) {
pumpStatusIconView.setText(String.format(" Get History - Page %d (%d/16)", pumpStatusIconView.setText(MainApp.gs(R.string.medtronic_cmd_desc_get_history_request,
MedtronicUtil.pageNumber, MedtronicUtil.frameNumber)); MedtronicUtil.pageNumber));
} else { } else {
pumpStatusIconView.setText(MainApp.gs(resourceId, MedtronicUtil.pageNumber, pumpStatusIconView.setText(MainApp.gs(resourceId, MedtronicUtil.pageNumber,
MedtronicUtil.frameNumber)); MedtronicUtil.frameNumber));
} }
} else { } else {
if (resourceId == null) { if (resourceId == null) {
pumpStatusIconView.setText(" " + cmd.name()); pumpStatusIconView.setText(" " + cmd.name());
} else { } else {
pumpStatusIconView.setText(" " + getTranslation(resourceId)); pumpStatusIconView.setText(" " + getTranslation(resourceId));
} }
} }
@ -338,7 +343,7 @@ public class MedtronicFragment extends SubscriberFragment {
public Object checkStatusSet(Object object1, Object object2) { public Object checkStatusSet(Object object1, Object object2) {
if (object1 == null) { if (object1 == null) {
return object1; return object2;
} else { } else {
if (!object1.equals(object2)) { if (!object1.equals(object2)) {
return object2; return object2;

View file

@ -14,6 +14,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.IBinder; import android.os.IBinder;
import android.os.SystemClock; import android.os.SystemClock;
@ -39,6 +40,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Actions.defs.CustomAction; import info.nightscout.androidaps.plugins.Actions.defs.CustomAction;
import info.nightscout.androidaps.plugins.Actions.defs.CustomActionType; import info.nightscout.androidaps.plugins.Actions.defs.CustomActionType;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.PumpCommon.PumpPluginAbstract; import info.nightscout.androidaps.plugins.PumpCommon.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpDriverState; import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpDriverState;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
@ -161,6 +163,11 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
public MedtronicHistoryData getMedtronicHistoryData() {
return this.medtronicHistoryData;
}
@Override @Override
public void initPumpStatusData() { public void initPumpStatusData() {
@ -460,7 +467,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20); scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20);
// configuration (once and then if history shows config changes) // configuration (once and then if history shows config changes)
// medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel())); medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel()));
// time (1h) // time (1h)
medtronicUIComm.executeCommand(MedtronicCommandType.RealTimeClock); medtronicUIComm.executeCommand(MedtronicCommandType.RealTimeClock);
@ -506,8 +513,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return true; return true;
} }
if (!basalProfileChanged && getMDTPumpStatus().basalsByHour != null) { LOG.info("isThisProfileSet: check");
return (!isBasalProfileInvalid);
if (!basalProfileChanged && getMDTPumpStatus().basalsByHour != null && !isBasalProfileInvalid) {
if (isLoggingEnabled())
LOG.debug("isThisProfileSet: profile has not changed and is not invalid.");
return isProfileSame(profile);
} }
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
@ -521,57 +533,78 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable); MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable);
if (isLoggingEnabled())
LOG.debug("isThisProfileSet: profile possible changed, reading from Pump.");
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD); MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
boolean invalid = false; boolean valid = false;
boolean noData = false;
if (responseTask.haveData()) { if (responseTask.haveData()) {
Double[] basalsByHour = getMDTPumpStatus().basalsByHour; valid = isProfileSame(profile);
LOG.debug("Basals by hour: " + (basalsByHour == null ? "null" : StringUtils.join(basalsByHour, " "))); if (valid) {
int index = 0;
if (basalsByHour == null)
return true; // we don't want to set profile again, unless we are sure
for (Profile.BasalValue basalValue : profile.getBasalValues()) {
int hour = basalValue.timeAsSeconds / (60 * 60);
if (MedtronicUtil.isSame(basalsByHour[index], basalValue.value)) {
if (index != hour) {
invalid = true;
break;
}
} else {
invalid = true;
break;
}
index++;
}
if (!invalid) {
if (isLoggingEnabled())
LOG.debug("Basal profile is same as AAPS one.");
basalProfileChanged = false; basalProfileChanged = false;
} else {
if (isLoggingEnabled())
LOG.debug("Basal profile on Pump is different than the AAPS one.");
} }
} else { } else {
invalid = true; noData = true;
if (isLoggingEnabled()) if (isLoggingEnabled())
LOG.debug("Basal profile NO DATA"); LOG.debug("Basal profile NO DATA");
} }
isBasalProfileInvalid = invalid; isBasalProfileInvalid = !valid;
setRefreshButtonEnabled(true); setRefreshButtonEnabled(true);
// we don't want to force set profile if we couldn't read the profile (noData)
return (noData || valid);
}
private boolean isProfileSame(Profile profile) {
boolean invalid = false;
Double[] basalsByHour = getMDTPumpStatus().basalsByHour;
if (isLoggingEnabled())
LOG.debug("Current Basals (h): " + (basalsByHour == null ? "null" : StringUtils.join(basalsByHour, " ")));
int index = 0;
if (basalsByHour == null)
return true; // we don't want to set profile again, unless we are sure
StringBuilder stringBuilder = new StringBuilder("Requested Basals (h): ");
for (Profile.BasalValue basalValue : profile.getBasalValues()) {
int hour = basalValue.timeAsSeconds / (60 * 60);
if (!MedtronicUtil.isSame(basalsByHour[hour], basalValue.value)) {
invalid = true;
}
stringBuilder.append(basalValue.value);
stringBuilder.append(" ");
}
if (isLoggingEnabled())
LOG.debug(stringBuilder.toString());
if (!invalid) {
if (isLoggingEnabled())
LOG.debug("Basal profile is same as AAPS one.");
// basalProfileChanged = false;
} else {
if (isLoggingEnabled())
LOG.debug("Basal profile on Pump is different than the AAPS one.");
}
return (!invalid); return (!invalid);
} }
@ -610,25 +643,53 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
MainApp.bus().post(new EventMedtronicPumpValuesChanged()); MainApp.bus().post(new EventMedtronicPumpValuesChanged());
} }
private BolusDeliveryType bolusDeliveryType = BolusDeliveryType.Idle;
private enum BolusDeliveryType {
Idle, //
DeliveryPrepared, //
Delivering, //
CancelDelivery
}
@NonNull @NonNull
protected PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) { protected PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) {
LOG.info("MedtronicPumpPlugin::deliverBolus - {}", BolusDeliveryType.DeliveryPrepared);
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
bolusDeliveryType = BolusDeliveryType.DeliveryPrepared;
if (isPumpNotReachable()) { if (isPumpNotReachable()) {
setRefreshButtonEnabled(true); LOG.debug("MedtronicPumpPlugin::deliverBolus - Pump Unreachable.");
return new PumpEnactResult() // return setNotReachable(true, false);
.success(false) //
.enacted(false) //
.comment(MainApp.gs(R.string.medtronic_pump_status_pump_unreachable));
} }
MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable); MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable);
if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled.");
return setNotReachable(true, true);
}
LOG.debug("MedtronicPumpPlugin::deliverBolus - Starting wait period.");
SystemClock.sleep(10000);
if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled, before wait period.");
return setNotReachable(true, true);
}
LOG.debug("MedtronicPumpPlugin::deliverBolus - End wait period. Start delivery");
try { try {
LOG.error("MedtronicPumpPlugin::deliverBolus Not fully implemented - Just base command."); bolusDeliveryType = BolusDeliveryType.Delivering;
// LOG.error("MedtronicPumpPlugin::deliverBolus Not fully implemented - Just base command.");
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus, MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus,
detailedBolusInfo.insulin); detailedBolusInfo.insulin);
@ -637,28 +698,65 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// TODO display bolus // TODO display bolus
// setRefreshButtonEnabled(true);
setRefreshButtonEnabled(true); setRefreshButtonEnabled(true);
bolusDeliveryType = BolusDeliveryType.Idle;
if (response) { if (response) {
if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled after Bolus started.");
new Thread(() -> {
// Looper.prepare();
LOG.debug("MedtronicPumpPlugin::deliverBolus - Show dialog - before");
SystemClock.sleep(2000);
LOG.debug("MedtronicPumpPlugin::deliverBolus - Show dialog. Context: "
+ MainApp.instance().getApplicationContext());
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
// i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", MainApp.gs(R.string.medtronic_cmd_cancel_bolus_not_supported));
i.putExtra("title", MainApp.gs(R.string.combo_warning));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
// OKDialog.show(MainApp.instance().getApplicationContext(), //
// MainApp.gs(R.string.combo_warning), //
// MainApp.gs(R.string.medtronic_cmd_cancel_bolus_not_supported), null);
}).start();
}
// FIXME this needs to be fixed to read info from history // FIXME this needs to be fixed to read info from history
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
getMDTPumpStatus().reservoirRemainingUnits -= detailedBolusInfo.insulin; // we subtract insulin, exact // we subtract insulin, exact amount will be visible with next remainingInsulin update.
// amount will be visible with getMDTPumpStatus().reservoirRemainingUnits -= detailedBolusInfo.insulin;
// next remainingInsulin
// update.
incrementStatistics(detailedBolusInfo.isSMB ? MedtronicConst.Statistics.SMBBoluses incrementStatistics(detailedBolusInfo.isSMB ? MedtronicConst.Statistics.SMBBoluses
: MedtronicConst.Statistics.StandardBoluses); : MedtronicConst.Statistics.StandardBoluses);
return new PumpEnactResult().success(response) // if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
.enacted(response) // return new PumpEnactResult() //
.bolusDelivered(detailedBolusInfo.insulin) // .success(false) //
.carbsDelivered(detailedBolusInfo.carbs); .enacted(response) //
.bolusDelivered(detailedBolusInfo.insulin) //
.carbsDelivered(detailedBolusInfo.carbs) //
.comment(MainApp.gs(R.string.medtronic_cmd_cancel_bolus_not_supported));
} else {
return new PumpEnactResult().success(response) //
.enacted(response) //
.bolusDelivered(detailedBolusInfo.insulin) //
.carbsDelivered(detailedBolusInfo.carbs);
}
} else { } else {
return new PumpEnactResult().success(false).enacted(false) // return new PumpEnactResult() //
.success(bolusDeliveryType == BolusDeliveryType.CancelDelivery) //
.enacted(false) //
.comment(MainApp.gs(R.string.medtronic_cmd_bolus_could_not_be_delivered)); .comment(MainApp.gs(R.string.medtronic_cmd_bolus_could_not_be_delivered));
} }
// pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin); // pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin);
@ -780,6 +878,35 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
} }
private PumpEnactResult setNotReachable(boolean isBolus, boolean success) {
setRefreshButtonEnabled(true);
if (isBolus) {
bolusDeliveryType = BolusDeliveryType.Idle;
}
if (success) {
return new PumpEnactResult() //
.success(true) //
.enacted(false);
} else {
return new PumpEnactResult() //
.success(false) //
.enacted(false) //
.comment(MainApp.gs(R.string.medtronic_pump_status_pump_unreachable));
}
}
public void stopBolusDelivering() {
this.bolusDeliveryType = BolusDeliveryType.CancelDelivery;
// if (isLoggingEnabled())
LOG.warn("MedtronicPumpPlugin::deliverBolus - Stop Bolus Delivery.");
}
private void incrementStatistics(String statsKey) { private void incrementStatistics(String statsKey) {
long currentCount = SP.getLong(statsKey, 0L); long currentCount = SP.getLong(statsKey, 0L);
currentCount++; currentCount++;
@ -1027,13 +1154,15 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
+ targetDate); + targetDate);
targetDate = timeMinus36h; targetDate = timeMinus36h;
} else { } else {
LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime); // LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime);
if (isLoggingEnabled()) if (isLoggingEnabled())
LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: {} - targetDate: {}", LOG.debug(getLogPrefix() + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: {} - targetDate: {}",
lastHistoryRecordTime, targetDate); lastPumpHistoryEntryTime, targetDate);
medtronicHistoryData.setLastHistoryRecordTime(DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime)); medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntryTime);
LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime);
lastHistoryRecordTime = lastHistoryRecordTime.minusHours(12); // we get last 12 hours of history to lastHistoryRecordTime = lastHistoryRecordTime.minusHours(12); // we get last 12 hours of history to
// determine pump state // determine pump state
@ -1070,8 +1199,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return; return;
this.lastPumpHistoryEntry = latestEntry; this.lastPumpHistoryEntry = latestEntry;
SP.putLong(MedtronicConst.Statistics.LastPumpHistoryEntry, SP.putLong(MedtronicConst.Statistics.LastPumpHistoryEntry, latestEntry.atechDateTime);
DateTimeUtil.toATechDate(latestEntry.getLocalDateTime()));
this.medtronicHistoryData.addNewHistory(historyResult); this.medtronicHistoryData.addNewHistory(historyResult);
this.medtronicHistoryData.filterNewEntries(); this.medtronicHistoryData.filterNewEntries();
@ -1260,6 +1388,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
if (isLoggingEnabled()) if (isLoggingEnabled())
LOG.info(getLogPrefix() + "setNewBasalProfile"); LOG.info(getLogPrefix() + "setNewBasalProfile");
// this shouldn't be needed, but let's do check if profile setting we are setting is same as current one
if (isProfileSame(profile)) {
return new PumpEnactResult() //
.success(true) //
.enacted(false) //
.comment(MainApp.gs(R.string.medtronic_cmd_basal_profile_not_set_is_same));
}
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
if (isPumpNotReachable()) { if (isPumpNotReachable()) {
@ -1294,6 +1430,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
LOG.info(getLogPrefix() + "Basal Profile was set: " + response); LOG.info(getLogPrefix() + "Basal Profile was set: " + response);
if (response) { if (response) {
medtronicHistoryData.setBasalProfileChanged();
return new PumpEnactResult().success(response).enacted(response); return new PumpEnactResult().success(response).enacted(response);
} else { } else {
return new PumpEnactResult().success(response).enacted(response) // return new PumpEnactResult().success(response).enacted(response) //
@ -1348,36 +1485,8 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
return basalProfile; return basalProfile;
} }
// OPERATIONS not supported by Pump or Plugin // OPERATIONS not supported by Pump or Plugin
// @Override
// public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
// LOG.error("MedtronicPumpPlugin::setExtendedBolus NOT SUPPORTED.");
// return OPERATION_NOT_SUPPORTED;
// }
//
//
// @Override
// public PumpEnactResult cancelExtendedBolus() {
// LOG.warn("cancelExtendedBolus - operation not supported.");
// return getOperationNotSupportedWithCustomText(R.string.medtronic_cmd_cancel_bolus_not_supported);
// }
// @Override
// public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
// boolean enforceNew) {
// LOG.error("setTempBasalPercent NOT IMPLEMENTED.");
// // we will never come here unless somebody has played with configuration in PumpType
// return OPERATION_NOT_SUPPORTED;
// }
// // we don't loadTDD. TDD is read from Pump History
// @Override
// public PumpEnactResult loadTDDs() {
// return OPERATION_NOT_SUPPORTED;
// }
// public void connect(String reason) { // public void connect(String reason) {
// // we don't use this. // // we don't use this.
// // we connect to RileyLink on startup and keep connection opened, then connection to pump // // we connect to RileyLink on startup and keep connection opened, then connection to pump
@ -1399,11 +1508,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
// LOG.debug("MedtronicPumpPlugin::stopConnecting"); // LOG.debug("MedtronicPumpPlugin::stopConnecting");
// } // }
@Override
public void stopBolusDelivering() {
// Medtronic doesn't have Bolus cancel, so we fake it.
}
List<CustomAction> customActions = null; List<CustomAction> customActions = null;

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RLMes
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor; 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.hw.rileylink.service.tasks.WakeAndTuneTask;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump; import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage; 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.MedtronicPumpHistoryDecoder;
@ -411,7 +412,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) { public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) {
PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, targetDate); PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, DateTimeUtil.toATechDate(targetDate));
if (doWakeUpBeforeCommand) if (doWakeUpBeforeCommand)
wakeUp(receiverDeviceAwakeForMinutes, false); wakeUp(receiverDeviceAwakeForMinutes, false);
@ -435,6 +436,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage firstResponse = null; PumpMessage firstResponse = null;
boolean failed = false; boolean failed = false;
MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber, null);
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
try { try {
@ -474,8 +477,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
// handle successful frame data // handle successful frame data
rawHistoryPage.appendData(currentResponse.getFrameData()); rawHistoryPage.appendData(currentResponse.getFrameData());
// RileyLinkMedtronicService.getInstance().announceProgress( // RileyLinkMedtronicService.getInstance().announceProgress(((100 / 16) *
// ((100 / 16) * currentResponse.getFrameNumber() + 1)); // currentResponse.getFrameNumber() + 1));
MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber, MedtronicUtil.setCurrentCommand(MedtronicCommandType.GetHistoryData, pageNumber,
currentResponse.getFrameNumber()); currentResponse.getFrameNumber());
@ -707,18 +710,18 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
protected PumpMessage makePumpMessage(MedtronicCommandType messageType, byte[] body) { private PumpMessage makePumpMessage(MedtronicCommandType messageType, byte[] body) {
return makePumpMessage(messageType, body == null ? new CarelinkShortMessageBody() return makePumpMessage(messageType, body == null ? new CarelinkShortMessageBody()
: new CarelinkShortMessageBody(body)); : new CarelinkShortMessageBody(body));
} }
protected PumpMessage makePumpMessage(MedtronicCommandType messageType) { private PumpMessage makePumpMessage(MedtronicCommandType messageType) {
return makePumpMessage(messageType, (byte[])null); return makePumpMessage(messageType, (byte[])null);
} }
protected PumpMessage makePumpMessage(MedtronicCommandType messageType, MessageBody messageBody) { private PumpMessage makePumpMessage(MedtronicCommandType messageType, MessageBody messageBody) {
PumpMessage msg = new PumpMessage(); PumpMessage msg = new PumpMessage();
msg.init(PacketType.Carelink, rileyLinkServiceData.pumpIDBytes, messageType, messageBody); msg.init(PacketType.Carelink, rileyLinkServiceData.pumpIDBytes, messageType, messageBody);
return msg; return msg;
@ -731,17 +734,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
// private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, int timeoutMs) {
//
// return sendAndGetResponse(commandType, null, timeoutMs);
// }
//
//
// private PumpMessage sendAndGetResponse(MedtronicCommandType commandType, byte[] bodyData) {
//
// return sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT);
// }
/** /**
* Main wrapper method for sending data - (for getting responses) * Main wrapper method for sending data - (for getting responses)
* *
@ -775,13 +767,13 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
protected PumpMessage sendAndListen(RLMessage msg) throws RileyLinkCommunicationException { private PumpMessage sendAndListen(RLMessage msg) throws RileyLinkCommunicationException {
return sendAndListen(msg, 4000); // 2000 return sendAndListen(msg, 4000); // 2000
} }
// All pump communications go through this function. // All pump communications go through this function.
protected PumpMessage sendAndListen(RLMessage msg, int timeout_ms) throws RileyLinkCommunicationException { private PumpMessage sendAndListen(RLMessage msg, int timeout_ms) throws RileyLinkCommunicationException {
return sendAndListen(msg, timeout_ms, PumpMessage.class); return sendAndListen(msg, timeout_ms, PumpMessage.class);
} }
@ -794,6 +786,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
private Object sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData) { private Object sendAndGetResponseWithCheck(MedtronicCommandType commandType, byte[] bodyData) {
LOG.debug("getDataFromPump: {}", commandType);
for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries < MAX_COMMAND_TRIES; retries++) {
try { try {
@ -885,10 +879,14 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
if (doWakeUpBeforeCommand) if (doWakeUpBeforeCommand)
wakeUp(receiverDeviceAwakeForMinutes, false); wakeUp(receiverDeviceAwakeForMinutes, false);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active);
MedtronicCommandType commandType = MedtronicCommandType.GetBasalProfileSTD; MedtronicCommandType commandType = MedtronicCommandType.GetBasalProfileSTD;
LOG.debug("getDataFromPump: {}", commandType);
MedtronicUtil.setCurrentCommand(commandType);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Active);
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) { for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
try { try {
@ -903,11 +901,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries)); response = sendAndListen(msg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent())); LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
// LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData())); LOG.debug("1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
String check = checkResponseContent(response, commandType.commandDescription, String check = checkResponseContent(response, commandType.commandDescription,
commandType.expectedLength); commandType.getRecordLength());
byte[] data = null; byte[] data = null;
@ -925,20 +923,20 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
PumpMessage response2 = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries)); PumpMessage response2 = sendAndListen(ackMsg, DEFAULT_TIMEOUT + (DEFAULT_TIMEOUT * retries));
// LOG.debug("{} Response: {}", runs, LOG.debug("{} Response: {}", runs, HexDump.toHexStringDisplayable(response2.getRawContent()));
// HexDump.toHexStringDisplayable(response2.getRawContent())); LOG.debug("{} Response: {}", runs,
// LOG.debug("{} Response: {}", runs, HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
// HexDump.toHexStringDisplayable(response2.getMessageBody().getTxData()));
String check2 = checkResponseContent(response2, commandType.commandDescription, String check2 = checkResponseContent(response2, commandType.commandDescription,
commandType.expectedLength); commandType.getRecordLength());
if (check2 == null) { if (check2 == null) {
data = ByteUtil.concat(data, ByteUtil.substring(response2.getMessageBody().getTxData(), 1)); data = ByteUtil.concat(data, ByteUtil.substring(response2.getMessageBody().getTxData(), 1));
} else { } else {
this.errorMessage = check; this.errorMessage = check2;
LOG.debug("Error message: " + check2);
} }
} }
@ -950,6 +948,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
LOG.debug("Converted response for {} is {}.", commandType.name(), basalProfile); LOG.debug("Converted response for {} is {}.", commandType.name(), basalProfile);
MedtronicUtil.setCurrentCommand(null);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
return basalProfile; return basalProfile;
@ -960,6 +959,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
} }
LOG.warn("Error reading profile in max retries."); LOG.warn("Error reading profile in max retries.");
MedtronicUtil.setCurrentCommand(null);
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping); MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
return null; return null;

View file

@ -4,7 +4,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
@ -47,7 +46,7 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
protected byte[] datetime; protected byte[] datetime;
protected byte[] body; protected byte[] body;
protected LocalDateTime dateTime; // protected LocalDateTime dateTime;
@Expose @Expose
public String DT; public String DT;
@ -93,6 +92,11 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
} }
public String getDateTimeString() {
return this.DT;
}
public String getDecodedData() { public String getDecodedData() {
if (decodedData == null) if (decodedData == null)
if (isNoDataEntry()) if (isNoDataEntry())
@ -139,9 +143,7 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(getToStringStart()); sb.append(getToStringStart());
sb.append(", DT: " sb.append(", DT: " + StringUtil.getStringInLength(this.DT, 19));
+ StringUtil.getStringInLength((this.dateTime == null) ? "x" : StringUtil.toDateTimeString(this.dateTime),
19));
sb.append(", length="); sb.append(", length=");
sb.append(getHeadLength()); sb.append(getHeadLength());
sb.append(","); sb.append(",");
@ -237,16 +239,15 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
} }
public LocalDateTime getLocalDateTime() { // public LocalDateTime getLocalDateTime() {
return this.dateTime; // return this.dateTime;
} // }
//
//
public void setLocalDateTime(LocalDateTime atdate) { // public void setLocalDateTime(LocalDateTime atdate) {
this.dateTime = atdate; // this.dateTime = atdate;
// this.DT = atdate.toString(dateTimeFormatter); // // this.DT = atdate.toString(dateTimeFormatter);
} // }
public void setAtechDateTime(long dt) { public void setAtechDateTime(long dt) {
this.atechDateTime = dt; this.atechDateTime = dt;

View file

@ -4,11 +4,11 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryDecoder; 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.MedtronicHistoryEntry;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
@ -63,7 +63,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
// CGMSHistoryEntry entry = (CGMSHistoryEntry) entryIn; // CGMSHistoryEntry entry = (CGMSHistoryEntry) entryIn;
if (entry.getDateTimeLength() > 0) { if (entry.getDateTimeLength() > 0) {
LocalDateTime dt = parseDate(entry); Long dt = parseDate(entry);
System.out.println("DT: " + dt); System.out.println("DT: " + dt);
} }
@ -292,7 +292,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
} }
private LocalDateTime parseDate(CGMSHistoryEntry entry) { private Long parseDate(CGMSHistoryEntry entry) {
if (entry.getEntryType().hasDate()) if (entry.getEntryType().hasDate())
return null; return null;
@ -323,17 +323,18 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
// date is reversed // date is reversed
if (entry.getEntryType().getDateType() == CGMSHistoryEntryType.DateType.MinuteSpecific) { if (entry.getEntryType().getDateType() == CGMSHistoryEntryType.DateType.MinuteSpecific) {
LocalDateTime date = new LocalDateTime(parseDay(data[2]), parseMonths(data[0], data[1]), // LocalDateTime date = new LocalDateTime(parseDay(data[2]), parseMonths(data[0], data[1]),
parseYear(data[3]), parseHours(data[0]), parseMinutes(data[1]), 0); // parseHours(data[0]), parseMinutes(data[1]), 0);
// ATechDate date = new ATechDate(parseDay(data[0]), // ATechDate date = new ATechDate(parseDay(data[0]),
// parseMonths(data[2], data[1]), parseYear(data[2]), // parseMonths(data[2], data[1]), parseYear(data[2]),
// parseHours(data[2]), parseMinutes(data[1]), 0, // parseHours(data[2]), parseMinutes(data[1]), 0,
// ATechDateType.DateAndTimeSec); // ATechDateType.DateAndTimeSec);
entry.setLocalDateTime(date); entry.atechDateTime = DateTimeUtil.toATechDate(parseYear(data[3]), parseMonths(data[0], data[1]),
parseDay(data[2]), parseHours(data[0]), parseMinutes(data[1]), 0);
return date; return entry.atechDateTime;
} else if (entry.getEntryType().getDateType() == CGMSHistoryEntryType.DateType.SecondSpecific) { } else if (entry.getEntryType().getDateType() == CGMSHistoryEntryType.DateType.SecondSpecific) {
LOG.warn("parseDate for SecondSpecific type is not implemented."); LOG.warn("parseDate for SecondSpecific type is not implemented.");

View file

@ -12,7 +12,6 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump; 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.MedtronicHistoryDecoder;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
@ -247,7 +246,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case DailyTotals515: case DailyTotals515:
return decodeDailyTotals(entry); // Not supported at the moment return decodeDailyTotals(entry); // Not supported at the moment
case SelectBasalProfile: case ChangeBasalPattern:
return RecordDecodeStatus.OK; // Not supported at the moment return RecordDecodeStatus.OK; // Not supported at the moment
// WORK IN PROGRESS // WORK IN PROGRESS
@ -294,7 +293,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case ChangeBGReminderOffset: case ChangeBGReminderOffset:
case ChangeAlarmClockTime: case ChangeAlarmClockTime:
case ChangeMeterId: case ChangeMeterId:
case ChangeParadigmLinkID: case ChangeParadigmID:
case JournalEntryMealMarker: case JournalEntryMealMarker:
case JournalEntryExerciseMarker: case JournalEntryExerciseMarker:
case DeleteBolusReminderTime: case DeleteBolusReminderTime:
@ -304,11 +303,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case JournalEntryOtherMarker: case JournalEntryOtherMarker:
case ChangeBolusWizardSetup: case ChangeBolusWizardSetup:
case ChangeSensorSetup2: case ChangeSensorSetup2:
case RestoreMystery51:
case RestoreMystery52:
case ChangeSensorAlarmSilenceConfig: case ChangeSensorAlarmSilenceConfig:
case RestoreMystery54:
case RestoreMystery55:
case ChangeSensorRateOfChangeAlertSetup: case ChangeSensorRateOfChangeAlertSetup:
case ChangeBolusScrollStepSize: case ChangeBolusScrollStepSize:
case BolusWizardChange: case BolusWizardChange:
@ -321,9 +316,22 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case ChangeCarbUnits: case ChangeCarbUnits:
case ChangeWatchdogEnable: case ChangeWatchdogEnable:
case ChangeOtherDeviceID: case ChangeOtherDeviceID:
case ReadOtherDevicesIDs:
case BolusWizard512:
case BGReceived512:
case SensorStatus:
case ReadCaptureEventEnabled:
case ChangeCaptureEventEnable:
case ReadOtherDevicesStatus:
return RecordDecodeStatus.OK;
// case ChangeWatchdogMarriageProfile: // case ChangeWatchdogMarriageProfile:
// case DeleteOtherDeviceID: // case DeleteOtherDeviceID:
// case ChangeCaptureEventEnable: // case ChangeCaptureEventEnable:
case Sensor54:
case Sensor55:
case Sensor51:
case Sensor52:
case EventUnknown_MM522_0x45: case EventUnknown_MM522_0x45:
case EventUnknown_MM522_0x46: case EventUnknown_MM522_0x46:
case EventUnknown_MM522_0x47: case EventUnknown_MM522_0x47:
@ -334,11 +342,10 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case EventUnknown_MM522_0x4c: case EventUnknown_MM522_0x4c:
case EventUnknown_MM512_0x10: case EventUnknown_MM512_0x10:
case EventUnknown_MM512_0x2e: case EventUnknown_MM512_0x2e:
case EventUnknown_MM512_0x2f:
case EventUnknown_MM512_0x37: case EventUnknown_MM512_0x37:
case EventUnknown_MM512_0x38: case EventUnknown_MM512_0x38:
case EventUnknown_MM512_0x39:
case EventUnknown_MM512_0x3b:
case EventUnknown_MM512_0x4e: case EventUnknown_MM512_0x4e:
case EventUnknown_MM522_0x70: case EventUnknown_MM522_0x70:
case EventUnknown_MM512_0x88: case EventUnknown_MM512_0x88:
@ -346,7 +353,8 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
case EventUnknown_MM522_0xE8: case EventUnknown_MM522_0xE8:
case EventUnknown_0x4d: case EventUnknown_0x4d:
case EventUnknown_MM522_0x25: case EventUnknown_MM522_0x25:
// LOG.debug(" -- ignored Pump Entry: " + entry.getEntryType().name()); case EventUnknown_MM522_0x05:
LOG.debug(" -- ignored Pump Entry: " + entry);
return RecordDecodeStatus.Ignored; return RecordDecodeStatus.Ignored;
// **** Implemented records **** // **** Implemented records ****
@ -375,7 +383,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
decodeEndResultTotals(entry); decodeEndResultTotals(entry);
return RecordDecodeStatus.OK; return RecordDecodeStatus.OK;
case BatteryActivity: case BatteryChange:
decodeBatteryActivity(entry); decodeBatteryActivity(entry);
return RecordDecodeStatus.OK; return RecordDecodeStatus.OK;
@ -411,9 +419,6 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
decodePrime(entry); decodePrime(entry);
return RecordDecodeStatus.OK; return RecordDecodeStatus.OK;
case EventUnknown_MM522_0x05:
return RecordDecodeStatus.Ignored;
case TempBasalCombined: case TempBasalCombined:
return RecordDecodeStatus.Ignored; return RecordDecodeStatus.Ignored;
@ -482,6 +487,8 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
// //
// } // }
System.out.println("" + totals.toString());
return RecordDecodeStatus.WIP; return RecordDecodeStatus.WIP;
} }
@ -608,7 +615,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
dto.correctionEstimate = (body[7] + (body[5] & 0x0F)) / 10.0f; dto.correctionEstimate = (body[7] + (body[5] & 0x0F)) / 10.0f;
} }
dto.localDateTime = entry.getLocalDateTime(); dto.atechDateTime = entry.atechDateTime;
entry.addDecodedData("Object", dto); entry.addDecodedData("Object", dto);
// entry.setHistoryEntryDetails(dto); // entry.setHistoryEntryDetails(dto);
@ -676,9 +683,9 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
bolus.setBolusType((bolus.getDuration() != null && (bolus.getDuration() > 0)) ? PumpBolusType.Extended bolus.setBolusType((bolus.getDuration() != null && (bolus.getDuration() > 0)) ? PumpBolusType.Extended
: PumpBolusType.Normal); : PumpBolusType.Normal);
bolus.setLocalDateTime(entry.getLocalDateTime()); bolus.setAtechDateTime(entry.atechDateTime);
String dateTime = StringUtil.toDateTimeString(entry.getLocalDateTime()); String dateTime = entry.DT;
if (bolus.getBolusType() == PumpBolusType.Extended) { if (bolus.getBolusType() == PumpBolusType.Extended) {
// we check if we have coresponding normal entry // we check if we have coresponding normal entry
@ -770,7 +777,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
LocalDateTime atdate = new LocalDateTime(year, month, dayOfMonth, hour, minutes, seconds); LocalDateTime atdate = new LocalDateTime(year, month, dayOfMonth, hour, minutes, seconds);
entry.setLocalDateTime(atdate); // TODO remove // entry.setLocalDateTime(atdate); // TODO remove
entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds)); entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds));
} else if (entry.getDateTimeLength() == 2) { } else if (entry.getDateTimeLength() == 2) {
@ -811,7 +818,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
atdate = new LocalDateTime(year, month, dayOfMonth, 0, 0); atdate = new LocalDateTime(year, month, dayOfMonth, 0, 0);
} }
entry.setLocalDateTime(atdate); // entry.setLocalDateTime(atdate);
entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds)); entry.setAtechDateTime(DateTimeUtil.toATechDate(year, month, dayOfMonth, hour, minutes, seconds));
} else { } else {

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
import java.util.Objects; import java.util.Objects;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -41,6 +40,7 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
private PumpHistoryEntryType entryType; private PumpHistoryEntryType entryType;
private Integer opCode; // this is set only when we have unknown entry... private Integer opCode; // this is set only when we have unknown entry...
private int offset; private int offset;
private String displayableValue = "";
public PumpHistoryEntryType getEntryType() { public PumpHistoryEntryType getEntryType() {
@ -112,7 +112,7 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
PumpHistoryEntry that = (PumpHistoryEntry)o; PumpHistoryEntry that = (PumpHistoryEntry)o;
return entryType == that.entryType && // return entryType == that.entryType && //
Objects.equals(this.dateTime, that.dateTime); // && // this.atechDateTime == that.atechDateTime; // && //
// Objects.equals(this.decodedData, that.decodedData); // Objects.equals(this.decodedData, that.decodedData);
} }
@ -123,13 +123,12 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
} }
public boolean isAfter(LocalDateTime dateTimeIn) { // public boolean isAfter(LocalDateTime dateTimeIn) {
// LOG.debug("Entry: " + this.dateTime); // // LOG.debug("Entry: " + this.dateTime);
// LOG.debug("Datetime: " + dateTimeIn); // // LOG.debug("Datetime: " + dateTimeIn);
// LOG.debug("Item after: " + this.dateTime.isAfter(dateTimeIn)); // // LOG.debug("Item after: " + this.dateTime.isAfter(dateTimeIn));
return this.dateTime.isAfter(dateTimeIn); // return this.dateTime.isAfter(dateTimeIn);
} // }
public boolean isAfter(long atechDateTime) { public boolean isAfter(long atechDateTime) {
return atechDateTime > this.atechDateTime; return atechDateTime > this.atechDateTime;
@ -142,4 +141,9 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
return (int)(o2.atechDateTime - o1.atechDateTime); return (int)(o2.atechDateTime - o1.atechDateTime);
} }
} }
public String getDisplayableValue() {
return displayableValue;
}
} }

View file

@ -0,0 +1,59 @@
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.R;
/**
* Created by andy on 12/23/18.
*/
public enum PumpHistoryEntryGroup {
All(R.string.medtronic_history_group_all), //
Bolus(R.string.danar_history_bolus), //
Basal(R.string.medtronic_history_group_basal), //
Prime(R.string.danar_history_prime), //
Configuration(R.string.medtronic_history_group_configuration), //
Alarm(R.string.danar_history_alarm), //
Glucose(R.string.danar_history_glucose), //
Notification(R.string.medtronic_history_group_notification), //
Statistic(R.string.medtronic_history_group_statistic),
Unknown(R.string.medtronic_history_group_unknown), //
;
private int resourceId;
private String translated;
private static List<PumpHistoryEntryGroup> list;
static {
list = new ArrayList<>();
for (PumpHistoryEntryGroup pumpHistoryEntryGroup : values()) {
list.add(pumpHistoryEntryGroup);
}
}
PumpHistoryEntryGroup(int resourceId) {
this.resourceId = resourceId;
// this.translated = MainApp.gs(resourceId);
}
public static List<PumpHistoryEntryGroup> getList() {
return list;
}
public int getResourceId() {
return resourceId;
}
public String toString() {
return this.translated;
}
}

View file

@ -35,124 +35,130 @@ import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
public enum PumpHistoryEntryType // implements CodeEnum public enum PumpHistoryEntryType // implements CodeEnum
{ {
None(0, "None", 1, 0, 0), // Bolus(0x01, "Bolus", 4, 5, 4), // 4,5,0 -> 4,5,4 Bolus(0x01, "Bolus", 2, 5, 4), None(0, "None", PumpHistoryEntryGroup.Unknown, 1, 0, 0), // Bolus(0x01, "Bolus", 4, 5, 4), // 4,5,0 -> 4,5,4
// Bolus(0x01, "Bolus", 2, 5, 4),
Bolus(0x01, "Bolus", 4, DateFormat.LongDate, 0), // 523+[H=8] Bolus(0x01, "Bolus", PumpHistoryEntryGroup.Bolus, 4, 5, 0), // 523+[H=8]
Prime(0x03, "Prime", 5, 5, 0), // Prime(0x03, "Prime", PumpHistoryEntryGroup.Prime, 5, 5, 0), //
EventUnknown_MM522_0x05((byte)0x05, 2, 5, 28), // /**/EventUnknown_MM522_0x05((byte)0x05, PumpHistoryEntryGroup.Unknown, 2, 5, 28), //
NoDeliveryAlarm(0x06, "NoDelivery", PumpHistoryEntryGroup.Alarm, 4, 5, 0), //
NoDeliveryAlarm(0x06, "NoDelivery", 4, 5, 0), // EndResultTotals(0x07, "ResultTotals", PumpHistoryEntryGroup.Statistic, 5, 2, 0), // V1: 5/5/41 V2: 5,2,3 V3, 5,2,0
EndResultTotals(0x07, "ResultTotals", 5, 2, 0), // V1: 5/5/41 V2: 5,2,3 V3, 5,2,0 V5: 7/10(523) // V5: 7/10(523)
ChangeBasalProfile_OldProfile(0x08, 2, 5, 145), // // V1: 2,5,42 V2:2,5,145; V4: V5 ChangeBasalProfile_OldProfile(0x08, PumpHistoryEntryGroup.Basal, 2, 5, 145), // // V1: 2,5,42 V2:2,5,145; V4: V5
ChangeBasalProfile_NewProfile(0x09, 2, 5, 145), // ChangeBasalProfile_NewProfile(0x09, PumpHistoryEntryGroup.Basal, 2, 5, 145), //
EventUnknown_MM512_0x10(0x10), // 29, 5, 0 /**/EventUnknown_MM512_0x10(0x10, PumpHistoryEntryGroup.Unknown), // 29, 5, 0
CalBGForPH(0x0a, "CalBGForPH"), // CalBGForPH(0x0a, "BG Capture", PumpHistoryEntryGroup.Glucose), //
SensorAlert(0x0b, "SensorAlert", 3, 5, 0), // Ian08 SensorAlert(0x0b, "SensorAlert", PumpHistoryEntryGroup.Alarm, 3, 5, 0), // Ian08
ClearAlarm(0x0c, "ClearAlarm", 2, 5, 0), // 2,5,4 ClearAlarm(0x0c, "ClearAlarm", PumpHistoryEntryGroup.Alarm, 2, 5, 0), // 2,5,4
// Andy0d(0x0d, "Unknown", 2, 5, 0), // Andy0d(0x0d, "Unknown", 2, 5, 0),
SelectBasalProfile(0x14, "SelectBasalProfile"), // ChangeBasalPattern(0x14, "Change Basal Pattern", PumpHistoryEntryGroup.Basal), //
TempBasalDuration(0x16, "TempBasalDuration"), // TempBasalDuration(0x16, "TempBasalDuration", PumpHistoryEntryGroup.Basal), //
ChangeTime(0x17, "ChangeTime"), // ChangeTime(0x17, "ChangeTime", PumpHistoryEntryGroup.Configuration), //
NewTimeSet(0x18, "NewTimeSet"), // NewTimeSet(0x18, "NewTimeSet", PumpHistoryEntryGroup.Notification), //
LowBattery(0x19, "LowBattery"), // LowBattery(0x19, "LowBattery", PumpHistoryEntryGroup.Notification), //
BatteryActivity(0x1a, "Battery Activity"), // BatteryChange(0x1a, "Battery Change", PumpHistoryEntryGroup.Notification), //
SetAutoOff(0x1b, "SetAutoOff"), // SetAutoOff(0x1b, "SetAutoOff", PumpHistoryEntryGroup.Configuration), //
PumpSuspend(0x1e, "Pump Suspend"), // PumpSuspend(0x1e, "Pump Suspend", PumpHistoryEntryGroup.Basal), //
PumpResume(0x1f, "Pump Resume"), // PumpResume(0x1f, "Pump Resume", PumpHistoryEntryGroup.Basal), //
SelfTest(0x20, "SelfTest"), //
Rewind(0x21, "Rewind"), //
ClearSettings(0x22, "ClearSettings"), // 8?
ChangeChildBlockEnable(0x23, "ChangeChildBlockEnable"), // 8?
ChangeMaxBolus(0x24), // 8?
EventUnknown_MM522_0x25(0x25), // 8?
ToggleRemote(0x26, "EnableDisableRemote", 2, 5, 14), // 2, 5, 14 V6:2,5,14
ChangeRemoteId(0x27, "ChangeRemoteID"), // ??
ChangeMaxBasal(0x2c), // SelfTest(0x20, "SelfTest", PumpHistoryEntryGroup.Statistic), //
BolusWizardEnabled(0x2d), // V3 ? Rewind(0x21, "Rewind", PumpHistoryEntryGroup.Prime), //
EventUnknown_MM512_0x2e(0x2e), // ClearSettings(0x22, "ClearSettings", PumpHistoryEntryGroup.Configuration), // 8?
EventUnknown_MM512_0x2f(0x2f), // ChangeChildBlockEnable(0x23, "ChangeChildBlockEnable", PumpHistoryEntryGroup.Configuration), // 8?
ChangeBGReminderOffset(0x31), // ChangeMaxBolus(0x24, PumpHistoryEntryGroup.Configuration), // 8?
ChangeAlarmClockTime(0x32), // /**/EventUnknown_MM522_0x25(0x25, PumpHistoryEntryGroup.Unknown), // 8?
TempBasalRate(0x33, "Temp Basal Rate", 2, 5, 1), // ToggleRemote(0x26, "EnableDisableRemote", PumpHistoryEntryGroup.Configuration, 2, 5, 14), // 2, 5, 14 V6:2,5,14
LowReservoir(0x34), // ChangeRemoteId(0x27, "ChangeRemoteID", PumpHistoryEntryGroup.Configuration), // ??
ChangeMeterId(0x36), // ChangeMaxBasal(0x2c, PumpHistoryEntryGroup.Configuration), //
EventUnknown_MM512_0x37(0x37), // V:MM512 BolusWizardEnabled(0x2d, PumpHistoryEntryGroup.Configuration), // V3 ?
EventUnknown_MM512_0x38(0x38), // /**/EventUnknown_MM512_0x2e(0x2e, PumpHistoryEntryGroup.Unknown), //
EventUnknown_MM512_0x39(0x39), // /**/BolusWizard512(0x2f, PumpHistoryEntryGroup.Configuration), //
EventUnknown_MM512_0x3b(0x3b), // UnabsorbedInsulin512(0x30, PumpHistoryEntryGroup.Statistic), //
ChangeParadigmLinkID(0x3c, 2, 5, 14), // V3 ? V6: 2,5,14 ChangeBGReminderOffset(0x31, PumpHistoryEntryGroup.Configuration), //
ChangeAlarmClockTime(0x32, PumpHistoryEntryGroup.Configuration), //
TempBasalRate(0x33, "Temp Basal Rate", PumpHistoryEntryGroup.Basal, 2, 5, 1), //
LowReservoir(0x34, PumpHistoryEntryGroup.Notification), //
ChangeAlarmClock(0x35, "Change Alarm Clock", PumpHistoryEntryGroup.Configuration), //
ChangeMeterId(0x36, PumpHistoryEntryGroup.Configuration), //
/**/EventUnknown_MM512_0x37(0x37, PumpHistoryEntryGroup.Unknown), // V:MM512
/**/EventUnknown_MM512_0x38(0x38, PumpHistoryEntryGroup.Unknown), //
BGReceived512(0x39, PumpHistoryEntryGroup.Glucose), //
SensorStatus(0x3b, PumpHistoryEntryGroup.Glucose), //
ChangeParadigmID(0x3c, PumpHistoryEntryGroup.Configuration, 2, 5, 14), // V3 ? V6: 2,5,14
BGReceived(0x3f, "BG Received", 2, 5, 3), // Ian3F BGReceived(0x3f, "BG Received", PumpHistoryEntryGroup.Glucose, 2, 5, 3), // Ian3F
JournalEntryMealMarker(0x40, 2, 5, 2), // JournalEntryMealMarker(0x40, PumpHistoryEntryGroup.Bolus, 2, 5, 2), //
JournalEntryExerciseMarker(0x41, 2, 5, 1), // ?? JournalEntryExerciseMarkerPumpEvent JournalEntryExerciseMarker(0x41, PumpHistoryEntryGroup.Bolus, 2, 5, 1), // ?? JournalEntryExerciseMarkerPumpEvent
JournalEntryInsulinMarker(0x42, 2, 5, 1), // ?? InsulinMarkerEvent JournalEntryInsulinMarker(0x42, PumpHistoryEntryGroup.Bolus, 2, 5, 1), // ?? InsulinMarkerEvent
JournalEntryOtherMarker(0x43), // JournalEntryOtherMarker(0x43, PumpHistoryEntryGroup.Bolus), //
EventUnknown_MM522_0x45(0x45, 2, 5, 1), // EnableSensorAutoCal(0x44, PumpHistoryEntryGroup.Glucose), //
EventUnknown_MM522_0x46(0x46, 2, 5, 1), // /**/EventUnknown_MM522_0x45(0x45, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x47(0x47, 2, 5, 1), // /**/EventUnknown_MM522_0x46(0x46, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x48(0x48, 2, 5, 1), // /**/EventUnknown_MM522_0x47(0x47, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x49(0x49, 2, 5, 1), // /**/EventUnknown_MM522_0x48(0x48, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x4a(0x4a, 2, 5, 1), // /**/EventUnknown_MM522_0x49(0x49, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x4b(0x4b, 2, 5, 1), // /**/EventUnknown_MM522_0x4a(0x4a, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x4c(0x4c, 2, 5, 1), // /**/EventUnknown_MM522_0x4b(0x4b, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
/**/EventUnknown_MM522_0x4c(0x4c, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_0x4d(0x4d), // V5: 512: 7, 522: 8 ????NS /**/EventUnknown_0x4d(0x4d, PumpHistoryEntryGroup.Unknown), // V5: 512: 7, 522: 8 ????NS
EventUnknown_MM512_0x4e(0x4e), // /**/EventUnknown_MM512_0x4e(0x4e, PumpHistoryEntryGroup.Unknown), // /**/
ChangeBolusWizardSetup(0x4f, PumpHistoryEntryGroup.Configuration, 2, 5, 32), //
ChangeBolusWizardSetup(0x4f, 2, 5, 32), // ChangeSensorSetup2(0x50, PumpHistoryEntryGroup.Configuration, 2, 5, 30), // Ian50
ChangeSensorSetup2(0x50, 2, 5, 30), // Ian50 /**/Sensor51(0x51, PumpHistoryEntryGroup.Unknown), //
RestoreMystery51(0x51), // /**/Sensor52(0x52, PumpHistoryEntryGroup.Unknown), //
RestoreMystery52(0x52), // ChangeSensorAlarmSilenceConfig(0x53, PumpHistoryEntryGroup.Configuration, 2, 5, 1), // 8 -
ChangeSensorAlarmSilenceConfig(0x53, 2, 5, 1), // 8 // ChangeSensorAlarmSilenceConfig
RestoreMystery54(0x54), // Ian54 /**/Sensor54(0x54, PumpHistoryEntryGroup.Unknown), // Ian54
RestoreMystery55(0x55), // /**/Sensor55(0x55, PumpHistoryEntryGroup.Unknown), //
ChangeSensorRateOfChangeAlertSetup(0x56, 2, 5, 5), // 12 ChangeSensorRateOfChangeAlertSetup(0x56, PumpHistoryEntryGroup.Configuration, 2, 5, 5), // 12
ChangeBolusScrollStepSize(0x57), // // ChangeSensorRateOfChangeAlertSetup
ChangeBolusScrollStepSize(0x57, PumpHistoryEntryGroup.Configuration), //
// V4 // V4
// Andy58(0x58, "Unknown", 13, 5, 0), // TO DO is this one really there ??? // Andy58(0x58, "Unknown", 13, 5, 0), // TO DO is this one really there ???
BolusWizardChange(0x5a, "BolusWizard", 2, 5, 117), // V2: 522+[B=143] BolusWizardChange(0x5a, "BolusWizard", PumpHistoryEntryGroup.Configuration, 2, 5, 117), // V2: 522+[B=143]
BolusWizardBolusEstimate(0x5b, "BolusWizardBolusEstimate", 2, 5, 13), // 15 // V2: 523+[B=15] BolusWizardBolusEstimate(0x5b, "BolusWizardBolusEstimate", PumpHistoryEntryGroup.Configuration, 2, 5, 13), // 15 //
UnabsorbedInsulin(0x5c, "UnabsorbedInsulinBolus", 5, 0, 0), // head[1] -> body length UnabsorbedInsulin(0x5c, "UnabsorbedInsulinBolus", PumpHistoryEntryGroup.Statistic, 5, 0, 0), // head[1] -> body
SaveSettings(0x5d), // // length
ChangeVariableBolus(0x5e), // SaveSettings(0x5d, PumpHistoryEntryGroup.Configuration), //
ChangeAudioBolus(0x5f, "EasyBolusEnabled"), // V3 ? ChangeVariableBolus(0x5e, PumpHistoryEntryGroup.Configuration), //
ChangeBGReminderEnable(0x60), // questionable60 ChangeAudioBolus(0x5f, "EasyBolusEnabled", PumpHistoryEntryGroup.Configuration), // V3 ?
ChangeAlarmClockEnable(0x61), // ChangeBGReminderEnable(0x60, PumpHistoryEntryGroup.Configuration), // questionable60
ChangeTempBasalType((byte)0x62), // ChangeTempBasalTypePumpEvent ChangeAlarmClockEnable(0x61, PumpHistoryEntryGroup.Configuration), //
ChangeAlarmNotifyMode(0x63), // ChangeTempBasalType((byte)0x62, PumpHistoryEntryGroup.Configuration), // ChangeTempBasalTypePumpEvent
ChangeTimeFormat(0x64), // ChangeAlarmNotifyMode(0x63, PumpHistoryEntryGroup.Configuration), //
ChangeReservoirWarningTime((byte)0x65), // ChangeTimeFormat(0x64, PumpHistoryEntryGroup.Configuration), //
ChangeBolusReminderEnable(0x66, 2, 5, 2), // 9 ChangeReservoirWarningTime((byte)0x65, PumpHistoryEntryGroup.Configuration), //
ChangeBolusReminderTime((byte)0x67, 2, 5, 2), // 9 ChangeBolusReminderEnable(0x66, PumpHistoryEntryGroup.Configuration, 2, 5, 2), // 9
DeleteBolusReminderTime((byte)0x68, 2, 5, 2), // 9 ChangeBolusReminderTime((byte)0x67, PumpHistoryEntryGroup.Configuration, 2, 5, 2), // 9
BolusReminder(0x69, 2, 5, 0), // Ian69 DeleteBolusReminderTime((byte)0x68, PumpHistoryEntryGroup.Configuration, 2, 5, 2), // 9
DeleteAlarmClockTime(0x6a, "Delete Alarm Clock Time", 2, 5, 7), // 14 BolusReminder(0x69, PumpHistoryEntryGroup.Configuration, 2, 5, 0), // Ian69
DeleteAlarmClockTime(0x6a, "Delete Alarm Clock Time", PumpHistoryEntryGroup.Configuration, 2, 5, 7), // 14
DailyTotals515(0x6c, "Daily Totals 515", 0, 0, 36), // DailyTotals515(0x6c, "Daily Totals 515", PumpHistoryEntryGroup.Statistic, 0, 0, 36), //
DailyTotals522(0x6d, "Daily Totals 522", 1, 2, 41), // // hack1(0x6d, "hack1", 46, 5, 0), // 1,2,41 DailyTotals522(0x6d, "Daily Totals 522", PumpHistoryEntryGroup.Statistic, 1, 2, 41), // // hack1(0x6d, "hack1", 46,
DailyTotals523(0x6e, "Daily Totals 523", 1, 2, 49), // 1102014-03-17T00:00:00 // 5, 0), // 1,2,41
ChangeCarbUnits((byte)0x6f), // DailyTotals523(0x6e, "Daily Totals 523", PumpHistoryEntryGroup.Statistic, 1, 2, 49), // 1102014-03-17T00:00:00
ChangeCarbUnits((byte)0x6f, PumpHistoryEntryGroup.Configuration), //
/**/EventUnknown_MM522_0x70((byte)0x70, PumpHistoryEntryGroup.Unknown, 2, 5, 1), //
EventUnknown_MM522_0x70((byte)0x70, 2, 5, 1), // BasalProfileStart(0x7b, PumpHistoryEntryGroup.Basal, 2, 5, 3), // // 722
ChangeWatchdogEnable((byte)0x7c, PumpHistoryEntryGroup.Configuration), //
ChangeOtherDeviceID((byte)0x7d, PumpHistoryEntryGroup.Configuration, 2, 5, 30), //
BasalProfileStart(0x7b, 2, 5, 3), // // 722 ChangeWatchdogMarriageProfile(0x81, PumpHistoryEntryGroup.Configuration, 2, 5, 5), // 12
ChangeWatchdogEnable((byte)0x7c), // DeleteOtherDeviceID(0x82, PumpHistoryEntryGroup.Configuration, 2, 5, 5), //
ChangeOtherDeviceID((byte)0x7d, 2, 5, 30), // ChangeCaptureEventEnable(0x83, PumpHistoryEntryGroup.Configuration), //
// ChangeWatchdogMarriageProfile(0x81, 2, 5, 5), // 12 /**/EventUnknown_MM512_0x88(0x88, PumpHistoryEntryGroup.Unknown), //
// DeleteOtherDeviceID(0x82, 2, 5, 5), //
// ChangeCaptureEventEnable(0x83), //
EventUnknown_MM512_0x88(0x88), // /**/EventUnknown_MM512_0x94(0x94, PumpHistoryEntryGroup.Unknown), //
EventUnknown_MM512_0x94(0x94), //
// IanA8(0xA8, "xx", 10, 5, 0), // // IanA8(0xA8, "xx", 10, 5, 0), //
// Andy90(0x90, "Unknown", 7, 5, 0), // Andy90(0x90, "Unknown", 7, 5, 0),
@ -163,21 +169,15 @@ public enum PumpHistoryEntryType // implements CodeEnum
// head[1], // head[1],
// body[49] op[0x6e] // body[49] op[0x6e]
EventUnknown_MM522_0xE8(0xe8, 2, 5, 25), // /**/EventUnknown_MM522_0xE8(0xe8, PumpHistoryEntryGroup.Unknown, 2, 5, 25), //
ReadOtherDevicesIDs(0xF0, ""), // ? ReadOtherDevicesIDs(0xf0, "", PumpHistoryEntryGroup.Configuration), // ?
readCaptureEventEnabled(0xF1), // ? ReadCaptureEventEnabled(0xf1, PumpHistoryEntryGroup.Configuration), // ?
changeCaptureEventEnable(0xF2), // ? ChangeCaptureEventEnable2(0xf2, PumpHistoryEntryGroup.Configuration), // ?
readOtherDevicesStatus(0xF3), // ? ReadOtherDevicesStatus(0xf3, PumpHistoryEntryGroup.Configuration), // ?
TempBasalCombined(0xFE, "TempBasalCombined"), // TempBasalCombined(0xfe, "TempBasalCombined", PumpHistoryEntryGroup.Basal), //
UnknownBasePacket(0xFF, "Unknown Base Packet"); UnknownBasePacket(0xff, "Unknown Base Packet", PumpHistoryEntryGroup.Unknown);
// private PumpHistoryEntryType(String description, List<Integer> opCode,
// byte length)
// {
//
// }
private static Map<Integer, PumpHistoryEntryType> opCodeMap = new HashMap<Integer, PumpHistoryEntryType>(); private static Map<Integer, PumpHistoryEntryType> opCodeMap = new HashMap<Integer, PumpHistoryEntryType>();
@ -201,35 +201,62 @@ public enum PumpHistoryEntryType // implements CodeEnum
private List<SpecialRule> specialRulesHead; private List<SpecialRule> specialRulesHead;
private List<SpecialRule> specialRulesBody; private List<SpecialRule> specialRulesBody;
private boolean hasSpecialRules = false; private boolean hasSpecialRules = false;
private PumpHistoryEntryGroup group = PumpHistoryEntryGroup.Unknown;
PumpHistoryEntryType(int opCode, String name) { // @Deprecated
this(opCode, name, 2, 5, 0); // PumpHistoryEntryType(int opCode, String name) {
// this(opCode, name, 2, 5, 0);
// }
PumpHistoryEntryType(int opCode, String name, PumpHistoryEntryGroup group) {
this(opCode, name, group, 2, 5, 0);
} }
PumpHistoryEntryType(int opCode) { // @Deprecated
this(opCode, null, 2, 5, 0); // PumpHistoryEntryType(int opCode) {
// this(opCode, null, null, 2, 5, 0);
// }
PumpHistoryEntryType(int opCode, PumpHistoryEntryGroup group) {
this(opCode, null, group, 2, 5, 0);
} }
PumpHistoryEntryType(int opCode, int head, int date, int body) { // @Deprecated
this(opCode, null, head, date, body); // PumpHistoryEntryType(int opCode, int head, int date, int body) {
// this(opCode, null, null, head, date, body);
// }
PumpHistoryEntryType(int opCode, PumpHistoryEntryGroup group, int head, int date, int body) {
this(opCode, null, group, head, date, body);
} }
PumpHistoryEntryType(int opCode, String name, int head, DateFormat dateFormat, int body) { // @Deprecated
this(opCode, name, head, dateFormat.getLength(), body); // PumpHistoryEntryType(int opCode, String name, int head, DateFormat dateFormat, int body) {
} // this(opCode, name, head, dateFormat.getLength(), body);
// }
// @Deprecated
// PumpHistoryEntryType(int opCode, String name, int head, int date, int body) {
// this.opCode = (byte)opCode;
// this.description = name;
// this.headLength = head;
// this.dateLength = date;
// this.bodyLength = body;
// this.totalLength = (head + date + body);
// }
PumpHistoryEntryType(int opCode, String name, int head, int date, int body) { PumpHistoryEntryType(int opCode, String name, PumpHistoryEntryGroup group, int head, int date, int body) {
this.opCode = (byte)opCode; this.opCode = (byte)opCode;
this.description = name; this.description = name;
this.headLength = head; this.headLength = head;
this.dateLength = date; this.dateLength = date;
this.bodyLength = body; this.bodyLength = body;
this.totalLength = (head + date + body); this.totalLength = (head + date + body);
this.group = group;
} }
@ -284,7 +311,7 @@ public enum PumpHistoryEntryType // implements CodeEnum
entryType == PumpHistoryEntryType.ChangeTime || // Time Change entryType == PumpHistoryEntryType.ChangeTime || // Time Change
entryType == PumpHistoryEntryType.NewTimeSet || // entryType == PumpHistoryEntryType.NewTimeSet || //
entryType == PumpHistoryEntryType.SelectBasalProfile || // Settings entryType == PumpHistoryEntryType.ChangeBasalPattern || // Configuration
entryType == PumpHistoryEntryType.ClearSettings || // entryType == PumpHistoryEntryType.ClearSettings || //
entryType == PumpHistoryEntryType.SaveSettings || // entryType == PumpHistoryEntryType.SaveSettings || //
entryType == PumpHistoryEntryType.ChangeMaxBolus || // entryType == PumpHistoryEntryType.ChangeMaxBolus || //
@ -410,6 +437,12 @@ public enum PumpHistoryEntryType // implements CodeEnum
return size; return size;
} }
public PumpHistoryEntryGroup getGroup() {
return group;
}
enum DateFormat { enum DateFormat {
None(0), // None(0), //
LongDate(5), // LongDate(5), //

View file

@ -4,10 +4,10 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.PumpMedtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.PumpMedtronic.MedtronicPumpPlugin;
/** /**
@ -23,7 +23,7 @@ public class PumpHistoryResult {
private boolean searchFinished = false; private boolean searchFinished = false;
private PumpHistoryEntry searchEntry = null; private PumpHistoryEntry searchEntry = null;
private LocalDateTime searchDate = null; private Long searchDate = null;
private SearchType searchType = SearchType.None; private SearchType searchType = SearchType.None;
private List<PumpHistoryEntry> unprocessedEntries; private List<PumpHistoryEntry> unprocessedEntries;
public List<PumpHistoryEntry> validEntries; public List<PumpHistoryEntry> validEntries;
@ -31,11 +31,11 @@ public class PumpHistoryResult {
// private Object validValues; // private Object validValues;
public PumpHistoryResult(PumpHistoryEntry searchEntry, LocalDateTime targetDate) { public PumpHistoryResult(PumpHistoryEntry searchEntry, Long targetDate) {
if (searchEntry != null) { if (searchEntry != null) {
this.searchEntry = searchEntry; this.searchEntry = searchEntry;
this.searchType = SearchType.LastEntry; this.searchType = SearchType.LastEntry;
LOG.debug("PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.getLocalDateTime() + " type=" LOG.debug("PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.atechDateTime + " type="
+ searchEntry.getEntryType().name()); + searchEntry.getEntryType().name());
} else if (targetDate != null) { } else if (targetDate != null) {
this.searchDate = targetDate; this.searchDate = targetDate;
@ -70,7 +70,7 @@ public class PumpHistoryResult {
Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator()); Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
LOG.debug("PumpHistoryResult. Search entry date: " + searchEntry.getLocalDateTime()); LOG.debug("PumpHistoryResult. Search entry date: " + searchEntry.atechDateTime);
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) { for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
@ -91,7 +91,7 @@ public class PumpHistoryResult {
if (unprocessedEntry.isAfter(this.searchDate)) { if (unprocessedEntry.isAfter(this.searchDate)) {
this.validEntries.add(unprocessedEntry); this.validEntries.add(unprocessedEntry);
} else { } else {
if (unprocessedEntry.getLocalDateTime().getYear() != 2000) if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) != 2000)
olderEntries++; olderEntries++;
} }
} }

View file

@ -2,11 +2,11 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -32,11 +32,14 @@ public class MedtronicHistoryData {
private List<PumpHistoryEntry> allHistory = null; private List<PumpHistoryEntry> allHistory = null;
private List<PumpHistoryEntry> newHistory = null; private List<PumpHistoryEntry> newHistory = null;
private LocalDateTime lastHistoryRecordTime; // private LocalDateTime previousLastHistoryRecordTime;
private Long lastHistoryRecordTime;
private boolean isInit = false; private boolean isInit = false;
private static final int OLD_HISTORY_SIZE = 50; private static final int OLD_HISTORY_SIZE = 50;
private int basalProfileChangedInternally = 0;
public MedtronicHistoryData() { public MedtronicHistoryData() {
this.allHistory = new ArrayList<>(); this.allHistory = new ArrayList<>();
@ -67,32 +70,38 @@ public class MedtronicHistoryData {
} }
public List<PumpHistoryEntry> getAllHistory() {
return this.allHistory;
}
public void filterNewEntries() { public void filterNewEntries() {
List<PumpHistoryEntry> newHistory2 = new ArrayList<>(); List<PumpHistoryEntry> newHistory2 = new ArrayList<>();
List<PumpHistoryEntry> TBRs = new ArrayList<>(); List<PumpHistoryEntry> TBRs = new ArrayList<>();
LocalDateTime localDateTime = new LocalDateTime(); // LocalDateTime localDateTime = new LocalDateTime();
long atechDate = DateTimeUtil.toATechDate(new GregorianCalendar());
for (PumpHistoryEntry pumpHistoryEntry : newHistory) { for (PumpHistoryEntry pumpHistoryEntry : newHistory) {
PumpHistoryEntryType type = pumpHistoryEntry.getEntryType(); PumpHistoryEntryType type = pumpHistoryEntry.getEntryType();
if (PumpHistoryEntryType.isAAPSRelevantEntry(type)) { // if (PumpHistoryEntryType.isAAPSRelevantEntry(type)) {
if (type == PumpHistoryEntryType.TempBasalRate || type == PumpHistoryEntryType.TempBasalDuration) { if (type == PumpHistoryEntryType.TempBasalRate || type == PumpHistoryEntryType.TempBasalDuration) {
TBRs.add(pumpHistoryEntry); TBRs.add(pumpHistoryEntry);
} else { } else {
if (type == PumpHistoryEntryType.EndResultTotals) { if (type == PumpHistoryEntryType.EndResultTotals) {
if (!DateTimeUtil.isSameDay(localDateTime, pumpHistoryEntry.getLocalDateTime())) { if (!DateTimeUtil.isSameDay(atechDate, pumpHistoryEntry.atechDateTime)) {
newHistory2.add(pumpHistoryEntry);
}
} else {
newHistory2.add(pumpHistoryEntry); newHistory2.add(pumpHistoryEntry);
} }
} else {
newHistory2.add(pumpHistoryEntry);
} }
} }
// }
} }
TBRs = processTBRs(TBRs); TBRs = processTBRs(TBRs);
@ -114,17 +123,26 @@ public class MedtronicHistoryData {
List<PumpHistoryEntry> filteredListByLastRecord = getFilteredListByLastRecord((PumpHistoryEntryType)null); List<PumpHistoryEntry> filteredListByLastRecord = getFilteredListByLastRecord((PumpHistoryEntryType)null);
LOG.debug("New records: " + filteredListByLastRecord.size());
if (filteredListByLastRecord.size() == 0) if (filteredListByLastRecord.size() == 0)
return; return;
List<PumpHistoryEntry> outList = new ArrayList<>(); List<PumpHistoryEntry> outList = new ArrayList<>();
if (allHistory.size() > OLD_HISTORY_SIZE) { // if (allHistory.size() > OLD_HISTORY_SIZE) {
for (int i = 0; i < OLD_HISTORY_SIZE; i++) { // for (int i = 0; i < OLD_HISTORY_SIZE; i++) {
outList.add(allHistory.get(i)); // outList.add(allHistory.get(i));
} // }
} // } else {
//
// }
// FIXME keep 24h only
LOG.debug("All History records (before): " + allHistory.size());
outList.addAll(this.allHistory);
outList.addAll(filteredListByLastRecord); outList.addAll(filteredListByLastRecord);
this.allHistory.clear(); this.allHistory.clear();
@ -133,13 +151,15 @@ public class MedtronicHistoryData {
this.sort(this.allHistory); this.sort(this.allHistory);
LOG.debug("All History records (after): " + allHistory.size());
} }
public boolean hasRelevantConfigurationChanged() { public boolean hasRelevantConfigurationChanged() {
return getStateFromFilteredList( // return getStateFromFilteredList( //
PumpHistoryEntryType.SelectBasalProfile, // PumpHistoryEntryType.ChangeBasalPattern, //
PumpHistoryEntryType.ClearSettings, // PumpHistoryEntryType.ClearSettings, //
PumpHistoryEntryType.SaveSettings, // PumpHistoryEntryType.SaveSettings, //
PumpHistoryEntryType.ChangeMaxBolus, // PumpHistoryEntryType.ChangeMaxBolus, //
@ -159,6 +179,8 @@ public class MedtronicHistoryData {
newAndAll.addAll(this.allHistory); newAndAll.addAll(this.allHistory);
newAndAll.addAll(this.newHistory); newAndAll.addAll(this.newHistory);
this.sort(newAndAll);
if (wasPumpSuspended == null) { // suspension status not known if (wasPumpSuspended == null) { // suspension status not known
List<PumpHistoryEntry> items = getFilteredItems(PumpHistoryEntryType.Bolus, // List<PumpHistoryEntry> items = getFilteredItems(PumpHistoryEntryType.Bolus, //
@ -268,7 +290,7 @@ public class MedtronicHistoryData {
* entryType == PumpHistoryEntryType.ChangeTime || // Time Change * entryType == PumpHistoryEntryType.ChangeTime || // Time Change
* entryType == PumpHistoryEntryType.NewTimeSet || // * entryType == PumpHistoryEntryType.NewTimeSet || //
* *
* entryType == PumpHistoryEntryType.SelectBasalProfile || // Settings * entryType == PumpHistoryEntryType.SelectBasalProfile || // Configuration
* entryType == PumpHistoryEntryType.ClearSettings || // * entryType == PumpHistoryEntryType.ClearSettings || //
* entryType == PumpHistoryEntryType.SaveSettings || // * entryType == PumpHistoryEntryType.SaveSettings || //
* entryType == PumpHistoryEntryType.ChangeMaxBolus || // * entryType == PumpHistoryEntryType.ChangeMaxBolus || //
@ -285,7 +307,17 @@ public class MedtronicHistoryData {
public boolean hasBasalProfileChanged() { public boolean hasBasalProfileChanged() {
return getStateFromFilteredList(PumpHistoryEntryType.ChangeBasalProfile_NewProfile); List<PumpHistoryEntry> filteredItems = getFilteredItems(PumpHistoryEntryType.ChangeBasalProfile_NewProfile);
LOG.debug("Items: " + filteredItems);
boolean profileChanged = ((filteredItems.size() - basalProfileChangedInternally) > 0);
LOG.error("Profile changed:" + profileChanged);
this.basalProfileChangedInternally = 0;
return profileChanged;
} }
@ -298,8 +330,9 @@ public class MedtronicHistoryData {
} }
public void setLastHistoryRecordTime(LocalDateTime lastHistoryRecordTime) { public void setLastHistoryRecordTime(Long lastHistoryRecordTime) {
// this.previousLastHistoryRecordTime = this.lastHistoryRecordTime;
this.lastHistoryRecordTime = lastHistoryRecordTime; this.lastHistoryRecordTime = lastHistoryRecordTime;
} }
@ -343,11 +376,20 @@ public class MedtronicHistoryData {
} }
// private List<PumpHistoryEntry> getFilteredListByPreviousLastRecord(PumpHistoryEntryType... entryTypes) {
// return getFilteredListByTime(this.previousLastHistoryRecordTime, entryTypes);
// }
private List<PumpHistoryEntry> getFilteredListByLastRecord(PumpHistoryEntryType... entryTypes) { private List<PumpHistoryEntry> getFilteredListByLastRecord(PumpHistoryEntryType... entryTypes) {
if (this.lastHistoryRecordTime == null) { return getFilteredListByTime(this.lastHistoryRecordTime, entryTypes);
}
private List<PumpHistoryEntry> getFilteredListByTime(Long lastRecordTime, PumpHistoryEntryType... entryTypes) {
if (lastRecordTime == null) {
return getFilteredItems(entryTypes); return getFilteredItems(entryTypes);
} else { } else {
return getFilteredItems(this.lastHistoryRecordTime, entryTypes); return getFilteredItems(lastRecordTime, entryTypes);
} }
} }
@ -358,12 +400,14 @@ public class MedtronicHistoryData {
} else { } else {
List<PumpHistoryEntry> filteredItems = getFilteredItems(entryTypes); List<PumpHistoryEntry> filteredItems = getFilteredItems(entryTypes);
LOG.debug("Items: " + filteredItems);
return filteredItems.size() > 0; return filteredItems.size() > 0;
} }
} }
private List<PumpHistoryEntry> getFilteredItems(LocalDateTime dateTime, PumpHistoryEntryType... entryTypes) { private List<PumpHistoryEntry> getFilteredItems(Long dateTime, PumpHistoryEntryType... entryTypes) {
PumpHistoryResult phr = new PumpHistoryResult(null, dateTime); PumpHistoryResult phr = new PumpHistoryResult(null, dateTime);
return getFilteredItems(phr.getValidEntries(), entryTypes); return getFilteredItems(phr.getValidEntries(), entryTypes);
@ -379,7 +423,7 @@ public class MedtronicHistoryData {
if (inList != null && inList.size() > 0) { if (inList != null && inList.size() > 0) {
for (PumpHistoryEntry pumpHistoryEntry : inList) { for (PumpHistoryEntry pumpHistoryEntry : inList) {
if (entryTypes != null) { if (!isEmpty(entryTypes)) {
for (PumpHistoryEntryType pumpHistoryEntryType : entryTypes) { for (PumpHistoryEntryType pumpHistoryEntryType : entryTypes) {
if (pumpHistoryEntry.getEntryType() == pumpHistoryEntryType) { if (pumpHistoryEntry.getEntryType() == pumpHistoryEntryType) {
@ -400,7 +444,17 @@ public class MedtronicHistoryData {
} }
private boolean isEmpty(PumpHistoryEntryType... entryTypes) {
return (entryTypes == null || (entryTypes.length == 1 && entryTypes[0] == null));
}
public List<PumpHistoryEntry> getNewHistoryEntries() { public List<PumpHistoryEntry> getNewHistoryEntries() {
return this.newHistory; return this.newHistory;
} }
public void setBasalProfileChanged() {
this.basalProfileChangedInternally++;
}
} }

View file

@ -1,8 +1,6 @@
package info.nightscout.androidaps.plugins.PumpMedtronic.data.dto; package info.nightscout.androidaps.plugins.PumpMedtronic.data.dto;
import org.joda.time.LocalDateTime; import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
/** /**
* Created by andy on 18.05.15. * Created by andy on 18.05.15.
@ -22,9 +20,11 @@ public class BolusWizardDTO extends PumpTimeStampedRecord {
public Float correctionEstimate = 0.0f; public Float correctionEstimate = 0.0f;
public Float foodEstimate = 0.0f; public Float foodEstimate = 0.0f;
public Float unabsorbedInsulin = 0.0f; public Float unabsorbedInsulin = 0.0f;
public LocalDateTime localDateTime;
// public LocalDateTime localDateTime;
// public long atechDateTime;
public String getValue() { public String getValue() {
return String.format("BG=%d;CH=%d;CH_UNIT=%s;CH_INS_RATIO=%5.3f;BG_INS_RATIO=%5.3f;" return String.format("BG=%d;CH=%d;CH_UNIT=%s;CH_INS_RATIO=%5.3f;BG_INS_RATIO=%5.3f;"
+ "BG_TARGET_LOW=%d;BG_TARGET_HIGH=%d;BOLUS_TOTAL=%5.3f;" + "BG_TARGET_LOW=%d;BG_TARGET_HIGH=%d;BOLUS_TOTAL=%5.3f;"
@ -35,6 +35,6 @@ public class BolusWizardDTO extends PumpTimeStampedRecord {
public String toString() { public String toString() {
return "BolusWizardDTO [dateTime=" + StringUtil.toDateTimeString(localDateTime) + ", " + getValue() + "]"; return "BolusWizardDTO [dateTime=" + DateTimeUtil.toString(atechDateTime) + ", " + getValue() + "]";
} }
} }

View file

@ -39,6 +39,7 @@ public class DailyTotalsDTO {
Double bolusTotal; Double bolusTotal;
Double bolusFood; Double bolusFood;
Double bolusFoodAndCorr;
Double bolusCorrection; Double bolusCorrection;
Double bolusManual; Double bolusManual;
@ -47,20 +48,22 @@ public class DailyTotalsDTO {
// Integer bolusCountCorr; // Integer bolusCountCorr;
Integer bolusCountFoodAndCorr; Integer bolusCountFoodAndCorr;
Integer bolusCountManual; Integer bolusCountManual;
private Integer bolusCountFood;
private Integer bolusCountCorr;
public DailyTotalsDTO(PumpHistoryEntryType entryType, byte[] data) { public DailyTotalsDTO(PumpHistoryEntryType entryType, byte[] data) {
switch (entryType) { switch (entryType) {
case DailyTotals515: case DailyTotals515:
decodeData512(data); decodeDailyTotals515(data);
break; break;
case DailyTotals522: case DailyTotals522:
decodeData522(data); decodeDailyTotals522(data);
break; break;
case DailyTotals523: case DailyTotals523:
decodeData523(data); decodeDailyTotals523(data);
break; break;
default: default:
@ -69,33 +72,45 @@ public class DailyTotalsDTO {
} }
private void decodeData512(byte[] data) { private void testDecode(byte[] data) {
LOG.debug("Can't decode DailyTotals512: Body={}", ByteUtil.getHex(data));
// Daily
byte body[] = data; // entry.getBody();
System.out.println("Totoals 522");
for (int i = 0; i < body.length - 2; i++) {
int j = ByteUtil.toInt(body[i], body[i + 1]);
int k = ByteUtil.toInt(body[i], body[i + 1], body[i + 2]);
int j1 = ByteUtil.toInt(body[i + 1], body[i]);
int k1 = ByteUtil.toInt(body[i + 2], body[i + 1], body[i]);
System.out.println(String.format(
"index: %d, number=%d, del/40=%.3f, del/10=%.3f, singular=%d, sing_hex=%s", i, j, j / 40.0d, j / 10.0d,
body[i], ByteUtil.getHex(body[i])));
System.out.println(String.format(" number[k,j1,k1]=%d / %d /%d, del/40=%.3f, del/40=%.3f, del/40=%.3f",
k, j1, k1, k / 40.0d, j1 / 40.0d, k1 / 40.0d));
}
} }
// bg avg, bg low hi, number Bgs, private void decodeDailyTotals515(byte[] data) {
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0, LOG.debug("Can't decode DailyTotals515: Body={}", ByteUtil.getHex(data));
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
// Bolus=1.7[18,19], Fodd, Corr, Manual=1.7[27,28],
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
private void decodeData522(byte[] data) {
// Double bgAvg; testDecode(data);
// Double bgLow; }
// Double bgHigh;
// Integer bgCount;
// private void decodeDailyTotals522(byte[] data) {
// Double sensorAvg;
// Double sensorMin;
// Double sensorMax;
// Integer sensorCalcCount;
// Integer sensorDataCount;
this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d; this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d;
this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d; this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d;
this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d; this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d;
// Double insulinCarbs;
this.bolusTotal = ByteUtil.toInt(data[17], data[18], data[19]) / 40.0d; this.bolusTotal = ByteUtil.toInt(data[17], data[18], data[19]) / 40.0d;
this.bolusFood = ByteUtil.toInt(data[21], data[22]) / 40.0d; this.bolusFood = ByteUtil.toInt(data[21], data[22]) / 40.0d;
@ -104,72 +119,45 @@ public class DailyTotalsDTO {
bolusCount = ByteUtil.asUINT8(data[30]); bolusCount = ByteUtil.asUINT8(data[30]);
bolusCountFoodOrCorr = ByteUtil.asUINT8(data[31]); bolusCountFoodOrCorr = ByteUtil.asUINT8(data[31]);
// Integer bolusCountCorr;
bolusCountFoodAndCorr = ByteUtil.asUINT8(data[32]); bolusCountFoodAndCorr = ByteUtil.asUINT8(data[32]);
bolusCountManual = ByteUtil.asUINT8(data[33]); bolusCountManual = ByteUtil.asUINT8(data[33]);
LOG.debug("{}", toString()); // bg avg, bg low hi, number Bgs,
// Sen Avg, Sen Lo/Hi, Sens Cal/Data = 0/0,
// Insulin=19.8[8,9], Basal[10,11], Bolus[13,14], Carbs,
// Bolus=1.7[18,19], Fodd, Corr, Manual=1.7[27,28],
// Num bOlus=1, food/corr, Food+corr, manual bolus=1
LOG.debug("522: {}", toString());
} }
private void decodeData523(byte[] data) { private void decodeDailyTotals523(byte[] data) {
LOG.debug("Can't decode DailyTotals523: Body={}", ByteUtil.getHex(data));
// 0x6E 0xB1 0x92 this.insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0d;
// 0x05 0x00 0x80 0x00 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 this.insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0d;
// 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 this.insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0d;
// 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 this.insulinCarbs = ByteUtil.toInt(data[16], data[17]) * 1.0d;
// 0x05 0x00 0x80 0x00 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 this.bolusFood = ByteUtil.toInt(data[18], data[19]) / 40.0d;
// 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00 this.bolusCorrection = ByteUtil.toInt(data[20], data[21]) / 40.0d;
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 this.bolusFoodAndCorr = ByteUtil.toInt(data[22], data[23]) / 40.0d;
this.bolusManual = ByteUtil.toInt(data[24], data[25]) / 40.0d;
this.bolusCountFood = ByteUtil.asUINT8(data[26]);
this.bolusCountCorr = ByteUtil.asUINT8(data[27]);
this.bolusCountFoodAndCorr = ByteUtil.asUINT8(data[28]);
this.bolusCountManual = ByteUtil.asUINT8(data[29]); // +
// Delivery Stats: Carbs=11, Total Insulin=3.850, Basal=2.000
// Delivery Stats: Basal 52,Bolus 1.850, Bolus=48%o
// Delivery Stats: Food only=0.9, Food only#=1, Corr only = 0.0
// Delivery Stats: #Corr_only=0,Food+Corr=0.000, #Food+Corr=0
// Delivery Stats: Manual = 0.95, #Manual=5
LOG.debug("523: {}", toString());
// 19:31:40.314 [Thread-47]
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():447]: PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
// DT: 16.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB0 0x92 0x05 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
// 19:31:40.318 [Thread-47] D/info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.DailyTotalsDTO:
// [DailyTotalsDTO.decodeData523():117]: Can't decode DailyTotals523: Body=0x05 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 19:31:40.320 [Thread-47]
// W/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.createRecords():181]: #0 WIP PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
// DT: 16.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB0 0x92 0x05 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x55 0x00 0x55 0x64 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
// 19:31:40.341 [Thread-47]
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.decodeDateTime():793]: DT: 2018 11 17
// 19:31:40.342 [Thread-47]
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.decodeDateTime():793]: DT: 2018 11 17
// 19:31:40.342 [Thread-47]
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():446]: DailyTotals523 - 0x6E 0xB1 0x92 0x05 0x00 0x80 0x00
// 0x00 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26
// 0x01 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00
// 19:31:40.343 [Thread-47]
// D/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.decodeDailyTotals():447]: PumpHistoryRecord [type=DailyTotals523 [110, 0x6E],
// DT: 17.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB1 0x92 0x05 0x00 0x80 0x00 0x00 0x01 0x00
// 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}]
// 19:31:40.343 [Thread-47] D/info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.DailyTotalsDTO:
// [DailyTotalsDTO.decodeData523():117]: Can't decode DailyTotals523: Body=0x05 0x00 0x80 0x00 0x00 0x01 0x00
// 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01 0x00 0x00
// 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 19:31:40.344 [Thread-47]
// W/info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder:
// [MedtronicPumpHistoryDecoder.createRecords():181]: #60 WIP PumpHistoryRecord [type=DailyTotals523 [110,
// 0x6E], DT: 17.11.2018 00:00:00, length=1,2,49(52), data={Raw Data=0x6E 0xB1 0x92 0x05 0x00 0x80 0x00 0x00
// 0x01 0x00 0x00 0x00 0x9A 0x00 0x50 0x34 0x00 0x4A 0x30 0x00 0x0B 0x00 0x24 0x00 0x00 0x00 0x00 0x00 0x26 0x01
// 0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
// 0x00}]
} }
@ -196,7 +184,10 @@ public class DailyTotalsDTO {
.add("bolusCount", bolusCount) // .add("bolusCount", bolusCount) //
.add("bolusCountFoodOrCorr", bolusCountFoodOrCorr) // .add("bolusCountFoodOrCorr", bolusCountFoodOrCorr) //
.add("bolusCountFoodAndCorr", bolusCountFoodAndCorr) // .add("bolusCountFoodAndCorr", bolusCountFoodAndCorr) //
.add("bolusCountFood", bolusCountFood) //
.add("bolusCountCorr", bolusCountCorr) //
.add("bolusCountManual", bolusCountManual) // .add("bolusCountManual", bolusCountManual) //
.omitNullValues() //
.toString(); .toString();
} }
} }

View file

@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.PumpMedtronic.data.dto; package info.nightscout.androidaps.plugins.PumpMedtronic.data.dto;
import org.joda.time.LocalDateTime;
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
/** /**
@ -10,20 +8,30 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
@Deprecated @Deprecated
public class PumpTimeStampedRecord { public class PumpTimeStampedRecord {
protected LocalDateTime localDateTime; // protected LocalDateTime localDateTime;
protected int decimalPrecission = 2; protected int decimalPrecission = 2;
public long atechDateTime;
public LocalDateTime getLocalDateTime() { public long getAtechDateTime() {
return localDateTime; return this.atechDateTime;
} }
public void setLocalDateTime(LocalDateTime ATechDate) { public void setAtechDateTime(long atechDateTime) {
this.localDateTime = ATechDate; this.atechDateTime = atechDateTime;
} }
// public LocalDateTime getLocalDateTime() {
// return localDateTime;
// }
//
//
// public void setLocalDateTime(LocalDateTime ATechDate) {
// this.localDateTime = ATechDate;
// }
public String getFormattedDecimal(double value) { public String getFormattedDecimal(double value) {
return StringUtil.getFormatedValueUS(value, this.decimalPrecission); return StringUtil.getFormatedValueUS(value, this.decimalPrecission);
} }

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.data.dto;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -144,17 +145,11 @@ public class TempBasalPair {
public String getDescription() { public String getDescription() {
String desc = "";
if (isPercent) { if (isPercent) {
desc = "Rate=" + insulinRate + "%"; return String.format(Locale.ENGLISH, "Rate=%.0f%%, Duration=%d min", insulinRate, durationMinutes);
} else { } else {
desc = "Rate=" + insulinRate + " U"; return String.format(Locale.ENGLISH, "Rate=%.3f U, Duration=%d min", insulinRate, durationMinutes);
} }
desc += ", Duration=" + durationMinutes + " min";
return desc;
} }

View file

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.MessageBody; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.MessageBody;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.PumpAckMessageBody; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.PumpAckMessageBody;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.UnknownMessageBody; import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.UnknownMessageBody;
@ -43,14 +44,16 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
PushButton(0x5b, "Push Button", MinimedTargetType.ActionCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 91 PushButton(0x5b, "Push Button", MinimedTargetType.ActionCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 91
RFPowerOn(93, "RF Power On", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray( RFPowerOn(93, "RF Power On", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
1, 10)), // 1, 10)), //
RFPowerOff(93, "RF Power Off", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray( RFPowerOff(93, "RF Power Off", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(
0, 0)), // 0, 0)), //
SetSuspend(77, "Set Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(1)), // // SetSuspend(77, "Set Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
// MinimedCommandParameterType.FixedParameters, getByteArray(1)), //
CancelSuspend(77, "Cancel Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.FixedParameters, getByteArray(0)), // // CancelSuspend(77, "Cancel Suspend", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
// MinimedCommandParameterType.FixedParameters, getByteArray(0)), //
PumpState(131, "Pump State", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // PumpState(131, "Pump State", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
@ -58,78 +61,98 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
// 511 (InitCommand = 2, Config 7, Data = 1(+3) // 511 (InitCommand = 2, Config 7, Data = 1(+3)
DetectBolus(75, "Detect Bolus", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_511, MinimedCommandParameterType.FixedParameters, getByteArray( DetectBolus(75, "Detect Bolus", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_511, MinimedCommandParameterType.FixedParameters, getByteArray(
0, 0, 0)), // 0, 0, 0)), //
RemoteControlIds(118, "Remote Control Ids", MinimedTargetType.PumpConfiguration_NA, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // // RemoteControlIds(118, "Remote Control Ids", MinimedTargetType.PumpConfiguration_NA, MedtronicDeviceType.All,
// MinimedCommandParameterType.NoParameters), //
FirmwareVersion(116, "Firmware Version", MinimedTargetType.InitCommand, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // // FirmwareVersion(116, "Firmware Version", MinimedTargetType.InitCommand, MedtronicDeviceType.All,
// MinimedCommandParameterType.NoParameters), //
PumpId(113, "Pump Id", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // init // PumpId(113, "Pump Id", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All,
// MinimedCommandParameterType.NoParameters), // init
RealTimeClock(112, "Real Time Clock", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 7), // 0x70 RealTimeClock(112, "Real Time Clock", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
7, R.string.medtronic_cmd_desc_get_time), // 0x70
GetBatteryStatus(0x72, "Get Battery Status", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // GetBatteryStatus(0x72, "Get Battery Status", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), //
// GetBattery((byte) 0x72), // // GetBattery((byte) 0x72), //
GetRemainingInsulin(0x73, "Read Remaining Insulin", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 2), // 115 GetRemainingInsulin(0x73, "Read Remaining Insulin", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, 2), // 115
SetBolus(0x42, "Set Bolus", MinimedTargetType.PumpSetData, MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters), // 66 SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
0, R.string.medtronic_cmd_desc_set_bolus), // 66
// 512 // 512
ReadTemporaryBasal(0x98, "Read Temporary Basal", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 5), // 152 ReadTemporaryBasal(0x98, "Read Temporary Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
5, R.string.medtronic_cmd_desc_get_tbr), // 152
SetTemporaryBasal(76, "Set Temp Basal Rate (bolus detection only)", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, getByteArray( SetTemporaryBasal(76, "Set Temporay Basal", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
0, 0, 0)), 0, R.string.medtronic_cmd_desc_set_tbr),
// util.getCommand(MinimedCommand.SET_TEMPORARY_BASAL).allowedRetries
// = 0;
// 512 Config // 512 Config
PumpModel(141, "Pump Model", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 5), // 0x8D PumpModel(141, "Pump Model", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
5, R.string.medtronic_cmd_desc_get_model), // 0x8D
BGTargets_512(140, "BG Targets", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters), // // BGTargets_512(140, "BG Targets", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512_712,
// MinimedCommandParameterType.NoParameters), //
BGUnits(137, "BG Units", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // // BGUnits(137, "BG Units", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
// MinimedCommandParameterType.NoParameters), //
Language(134, "Language", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // // Language(134, "Language", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher,
// MinimedCommandParameterType.NoParameters), //
Settings_512(145, "Settings", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters), // Settings_512(145, "Configuration", MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters, //
64, 1, 0, R.string.medtronic_cmd_desc_get_settings), //
BGAlarmClocks(142, "BG Alarm Clocks", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // // BGAlarmClocks(142, "BG Alarm Clocks", MinimedTargetType.PumpConfiguration,
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
BGAlarmEnable(151, "BG Alarm Enable", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // // BGAlarmEnable(151, "BG Alarm Enable", MinimedTargetType.PumpConfiguration,
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
BGReminderEnable(144, "BG Reminder Enable", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // // BGReminderEnable(144, "BG Reminder Enable", MinimedTargetType.PumpConfiguration,
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
ReadInsulinSensitivities(0x8b, "Read Insulin Sensitivities", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // 139 // ReadInsulinSensitivities(0x8b, "Read Insulin Sensitivities", MinimedTargetType.PumpConfiguration,
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), // 139
// 512 Data // 512 Data
GetHistoryData(128, "History data", MinimedTargetType.PumpData, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.SubCommands, 1024, 36, 0), // 0x80 GetHistoryData(128, "Get History", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.SubCommands, //
// new MinimedCommandHistoryData(36) 1024, 16, 1024, R.string.medtronic_cmd_desc_get_history), // 0x80
GetBasalProfileSTD(146, "Get Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8, 1), // 146 GetBasalProfileSTD(146, "Get Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 146
GetBasalProfileA(147, "Get Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 9), // 147 GetBasalProfileA(147, "Get Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
// FIXME 64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile),
GetBasalProfileB(148, "Get Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 10), // 148 GetBasalProfileB(148, "Get Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
// FIXME 64, 3, 192, R.string.medtronic_cmd_desc_get_basal_profile), // 148
SetBasalProfileSTD(0x6f, "Set Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 111 SetBasalProfileSTD(0x6f, "Set Profile Standard", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 111
SetBasalProfileA(0x30, "Set Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 48 SetBasalProfileA(0x30, "Set Profile A", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 48
SetBasalProfileB(0x31, "Set Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 49 SetBasalProfileB(0x31, "Set Profile B", MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, //
64, 3, 192, R.string.medtronic_cmd_desc_set_basal_profile), // 49
// 515 // 515
PumpStatus(206, "Pump Status", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), // PumpConfiguration PumpStatus(206, "Pump Status", MinimedTargetType.InitCommand, MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), // PumpConfiguration
Settings(192, "Settings", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), //
Settings(192, "Configuration", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters, //
64, 1, 0, R.string.medtronic_cmd_desc_get_settings), //
// 522 // 522
SensorSettings_522(153, "Sensor Settings", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.NoParameters), // SensorSettings_522(153, "Sensor Configuration", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.NoParameters), //
GlucoseHistory(154, "Glucose History", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.SubCommands, 1024, 32, 0, null), // GlucoseHistory(154, "Glucose History", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.SubCommands, 1024, 32, 0, null), //
// 523 // 523
SensorSettings(207, "Sensor Settings", MinimedTargetType.CGMSConfiguration, MedtronicDeviceType.Medtronic_523andHigher, MinimedCommandParameterType.NoParameters), // SensorSettings(207, "Sensor Configuration", MinimedTargetType.CGMSConfiguration, MedtronicDeviceType.Medtronic_523andHigher, MinimedCommandParameterType.NoParameters), //
// 553 // 553
// 554 // 554
@ -154,7 +177,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
// Fake Commands // Fake Commands
CancelTBR(),; CancelTBR(), ;
static Map<Byte, MedtronicCommandType> mapByCode; static Map<Byte, MedtronicCommandType> mapByCode;
@ -194,33 +217,33 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType) { MinimedCommandParameterType parameterType) {
this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, 0); this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, 0);
} }
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, int expectedLength) { MinimedCommandParameterType parameterType, int expectedLength) {
this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, expectedLength); this(code, description, targetType, devices, parameterType, 64, 1, 0, 0, 0, expectedLength);
} }
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) { MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType, 0); this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType, 0);
} }
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType, MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType,
int expectedLength) { int expectedLength) {
this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType, this(code, description, targetType, devices, parameterType, recordLength, maxRecords, 0, 0, commandType,
expectedLength); expectedLength);
} }
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, byte[] cmd_params) { MinimedCommandParameterType parameterType, byte[] cmd_params) {
this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, 0); this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, 0);
this.commandParameters = cmd_params; this.commandParameters = cmd_params;
@ -228,17 +251,16 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
} }
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, // MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, byte[] cmd_params, int expectedLength) { // MinimedCommandParameterType parameterType, byte[] cmd_params, int expectedLength) {
this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, expectedLength); // this(code, description, targetType, devices, parameterType, 0, 1, 0, 0, 11, expectedLength);
//
this.commandParameters = cmd_params; // this.commandParameters = cmd_params;
this.commandParametersCount = cmd_params.length; // this.commandParametersCount = cmd_params.length;
} // }
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, // MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
MinimedCommandParameterType parameterType) { MinimedCommandParameterType parameterType) {
this(code, description, devices, parameterType, 64, 1, 0, null); this(code, description, devices, parameterType, 64, 1, 0, null);
} }
@ -246,31 +268,31 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
// NEW // NEW
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, MedtronicCommandType(int code, String description, MedtronicDeviceType devices,
MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) { MinimedCommandParameterType parameterType, int recordLength, int maxRecords, int commandType) {
this(code, description, devices, parameterType, recordLength, maxRecords, 0, null); this(code, description, devices, parameterType, recordLength, maxRecords, 0, null);
} }
// NEW // NEW
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, // MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
MinimedCommandParameterType parameterType, int expectedLength) { MinimedCommandParameterType parameterType, int expectedLength) {
this(code, description, devices, parameterType, 64, 1, expectedLength, null); this(code, description, devices, parameterType, 64, 1, expectedLength, null);
} }
// NEW // NEW
MedtronicCommandType(int code, String description, MedtronicDeviceType devices, // MedtronicCommandType(int code, String description, MedtronicDeviceType devices, //
MinimedCommandParameterType parameterType, int expectedLength, int resourceId) { MinimedCommandParameterType parameterType, int expectedLength, int resourceId) {
this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId); this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId);
} }
// NEW // NEW
MedtronicCommandType(int code, String description, MedtronicCommandType(int code, String description,
MedtronicDeviceType devices, // MedtronicDeviceType devices, //
MinimedCommandParameterType parameterType, int recordLength, int max_recs, int expectedLength, MinimedCommandParameterType parameterType, int recordLength, int max_recs, int expectedLength,
Integer resourceId) { Integer resourceId) {
this.commandCode = (byte) code; this.commandCode = (byte)code;
this.commandDescription = description; this.commandDescription = description;
this.devices = devices; this.devices = devices;
this.recordLength = recordLength; this.recordLength = recordLength;
@ -285,15 +307,14 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
if (this.parameterType == MinimedCommandParameterType.SubCommands) { if (this.parameterType == MinimedCommandParameterType.SubCommands) {
this.minimalBufferSizeToStartReading = 200; this.minimalBufferSizeToStartReading = 200;
} }
} }
@Deprecated @Deprecated
MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, // MedtronicCommandType(int code, String description, MinimedTargetType targetType, MedtronicDeviceType devices, //
MinimedCommandParameterType parameterType, int recordLength, int max_recs, int addy, // MinimedCommandParameterType parameterType, int recordLength, int max_recs, int addy, //
int addy_len, int cmd_type, int expectedLength) { int addy_len, int cmd_type, int expectedLength) {
this.commandCode = (byte) code; this.commandCode = (byte)code;
this.commandDescription = description; this.commandDescription = description;
this.targetType = targetType; this.targetType = targetType;
this.devices = devices; this.devices = devices;
@ -328,7 +349,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
byte[] array = new byte[data.length]; byte[] array = new byte[data.length];
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
array[i] = (byte) data[i]; array[i] = (byte)data[i];
} }
return array; return array;
@ -400,7 +421,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
*/ */
public String getFullCommandDescription() { public String getFullCommandDescription() {
return "Command [name=" + this.name() + ", id=" + this.commandCode + ",description=" + this.commandDescription return "Command [name=" + this.name() + ", id=" + this.commandCode + ",description=" + this.commandDescription
+ "] "; + "] ";
} }
@ -453,6 +474,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
return this.commandDescription; return this.commandDescription;
} }
public Integer getResourceId() { public Integer getResourceId() {
return resourceId; return resourceId;
} }

View file

@ -0,0 +1,237 @@
package info.nightscout.androidaps.plugins.PumpMedtronic.dialog;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpMedtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry;
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntryGroup;
public class MedtronicHistoryActivity extends Activity {
private static Logger LOG = LoggerFactory.getLogger(L.PUMP);
private Handler mHandler;
static Profile profile = null;
Spinner historyTypeSpinner;
TextView statusView;
// Button reloadButton;
// Button syncButton;
RecyclerView recyclerView;
LinearLayoutManager llm;
static PumpHistoryEntryGroup showingType = PumpHistoryEntryGroup.All;
// List<PumpHistoryEntry> fullHistoryList = null;
List<PumpHistoryEntry> filteredHistoryList = new ArrayList<>();
// public static class TypeList {
//
// public byte type;
// String name;
//
//
// TypeList(byte type, String name) {
// this.type = type;
// this.name = name;
// }
//
//
// @Override
// public String toString() {
// return name;
// }
// }
public MedtronicHistoryActivity() {
super();
HandlerThread mHandlerThread = new HandlerThread(MedtronicHistoryActivity.class.getSimpleName());
mHandlerThread.start();
// this.fullHistoryList = MedtronicPumpPlugin.getPlugin().getMedtronicHistoryData().getAllHistory();
filterHistory(this.showingType);
this.mHandler = new Handler(mHandlerThread.getLooper());
}
private void filterHistory(PumpHistoryEntryGroup group) {
this.filteredHistoryList.clear();
List<PumpHistoryEntry> list = new ArrayList<>();
list.addAll(MedtronicPumpPlugin.getPlugin().getMedtronicHistoryData().getAllHistory());
LOG.debug("Items on full list: {}", list.size());
if (group == PumpHistoryEntryGroup.All) {
this.filteredHistoryList.addAll(list);
} else {
for (PumpHistoryEntry pumpHistoryEntry : list) {
if (pumpHistoryEntry.getEntryType().getGroup() == group) {
this.filteredHistoryList.add(pumpHistoryEntry);
}
}
}
LOG.debug("Items on filtered list: {}", filteredHistoryList.size());
}
@Override
protected void onResume() {
super.onResume();
MainApp.bus().register(this);
filterHistory(showingType);
}
@Override
protected void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.medtronic_history_activity);
historyTypeSpinner = (Spinner)findViewById(R.id.medtronic_historytype);
statusView = (TextView)findViewById(R.id.medtronic_historystatus);
// reloadButton = (Button)findViewById(R.id.medtronic_historyreload);
// syncButton = (Button)findViewById(R.id.medtronic_historysync);
recyclerView = (RecyclerView)findViewById(R.id.medtronic_history_recyclerview);
recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(filteredHistoryList);
recyclerView.setAdapter(adapter);
statusView.setVisibility(View.GONE);
boolean isKorean = DanaRKoreanPlugin.getPlugin().isEnabled(PluginType.PUMP);
boolean isRS = DanaRSPlugin.getPlugin().isEnabled(PluginType.PUMP);
// Types
// ArrayList<TypeList> typeList = new ArrayList<>();
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ALARM, MainApp.gs(R.string.danar_history_alarm)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BASALHOUR, MainApp.gs(R.string.danar_history_basalhours)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BOLUS, MainApp.gs(R.string.danar_history_bolus)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_CARBO, MainApp.gs(R.string.danar_history_carbohydrates)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_DAILY, MainApp.gs(R.string.danar_history_dailyinsulin)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_GLUCOSE, MainApp.gs(R.string.danar_history_glucose)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ERROR, MainApp.gs(R.string.danar_history_errors)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_PRIME, MainApp.gs(R.string.danar_history_prime)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_REFILL, MainApp.gs(R.string.danar_history_refill)));
// typeList.add(new TypeList(RecordTypes.RECORD_TYPE_SUSPEND, MainApp.gs(R.string.danar_history_syspend)));
ArrayAdapter<PumpHistoryEntryGroup> spinnerAdapter = new ArrayAdapter<>(this, R.layout.spinner_centered,
PumpHistoryEntryGroup.getList());
historyTypeSpinner.setAdapter(spinnerAdapter);
historyTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
PumpHistoryEntryGroup selected = (PumpHistoryEntryGroup)historyTypeSpinner.getSelectedItem();
showingType = selected;
filterHistory(selected);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
filterHistory(showingType);
}
});
}
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> {
List<PumpHistoryEntry> historyList;
RecyclerViewAdapter(List<PumpHistoryEntry> historyList) {
this.historyList = historyList;
}
@Override
public HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rileylink_status_history_item, //
viewGroup, false);
return new HistoryViewHolder(v);
}
@Override
public void onBindViewHolder(HistoryViewHolder holder, int position) {
PumpHistoryEntry record = historyList.get(position);
holder.timeView.setText(record.getDateTimeString());
holder.typeView.setText(record.getEntryType().getDescription());
holder.valueView.setText(record.getDisplayableValue());
}
@Override
public int getItemCount() {
return historyList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
static class HistoryViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView timeView;
TextView typeView;
TextView valueView;
HistoryViewHolder(View itemView) {
super(itemView);
// cv = (CardView)itemView.findViewById(R.id.rileylink_history_item);
timeView = (TextView)itemView.findViewById(R.id.rileylink_history_time);
typeView = (TextView)itemView.findViewById(R.id.rileylink_history_source);
valueView = (TextView)itemView.findViewById(R.id.rileylink_history_description);
}
}
}
}

View file

@ -80,7 +80,7 @@ public class RileyLinkMedtronicService extends RileyLinkService {
@Override @Override
public RileyLinkEncodingType getEncoding() { public RileyLinkEncodingType getEncoding() {
return RileyLinkEncodingType.FourByteSixByte; return RileyLinkEncodingType.FourByteSixByteLocal;
} }

View file

@ -449,9 +449,10 @@ public class MedtronicUtil extends RileyLinkUtil {
} }
public static int pageNumber; public static int pageNumber;
public static int frameNumber; public static Integer frameNumber;
public static void setCurrentCommand(MedtronicCommandType currentCommand, int pageNumber_, int frameNumber_) {
public static void setCurrentCommand(MedtronicCommandType currentCommand, int pageNumber_, Integer frameNumber_) {
pageNumber = pageNumber_; pageNumber = pageNumber_;
frameNumber = frameNumber_; frameNumber = frameNumber_;

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".plugins.PumpMedtronic.dialog.MedtronicHistoryActivity">
<LinearLayout
android:id="@+id/medtronic_historytop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:text="Type:"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
android:id="@+id/medtronic_historytype"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="@drawable/pillborder"
android:gravity="center_horizontal"
android:text="DanaR History" />
</LinearLayout>
<TextView
android:id="@+id/medtronic_historystatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/medtronic_historytop"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal" />
<android.support.v7.widget.RecyclerView
android:id="@+id/medtronic_history_recyclerview"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/medtronic_historystatus" />
</RelativeLayout>

View file

@ -162,5 +162,15 @@
<item>@string/medtronic_pump_frequency_worldwide</item> <item>@string/medtronic_pump_frequency_worldwide</item>
</string-array> </string-array>
<string-array name="medtronicBolusDelay">
<item>5</item>
<item>10</item>
<item>15</item>
</string-array>
<string-array name="medtronicEncoding">
<item>@string/medtronic_pump_encoding_4b6b_local</item>
<item>@string/medtronic_pump_encoding_4b6b_rileylink</item>
</string-array>
</resources> </resources>

View file

@ -1224,15 +1224,18 @@
<string name="medtronic_name_short" translatable="false">MDT</string> <string name="medtronic_name_short" translatable="false">MDT</string>
<string name="description_pump_medtronic">Pump integration for Medtronic, requires RileyLink device and specific Pump Model</string> <string name="description_pump_medtronic">Pump integration for Medtronic, requires RileyLink device and specific Pump Model</string>
<!-- MDT Configuration --> <!-- MDT Configuration -->
<string name="medtronic_serial_number">Pump Serial Number</string> <string name="medtronic_serial_number">Pump Serial Number</string>
<string name="medtronic_pump_type">Pump Type</string> <string name="medtronic_pump_type">Pump Type</string>
<string name="medtronic_pump_frequency">Pump Frequency</string> <string name="medtronic_pump_frequency">Pump Frequency</string>
<string name="medtronic_pump_bolus_delay">Delay before Bolus is started (s)</string>
<string name="medtronic_pump_max_bolus">Max Bolus on Pump</string> <string name="medtronic_pump_max_bolus">Max Bolus on Pump</string>
<string name="medtronic_pump_max_basal">Max Basal on Pump</string> <string name="medtronic_pump_max_basal">Max Basal on Pump</string>
<string name="medtronic_pump_encoding">Medtronic Encoding</string>
<string name="medtronic_pump_frequency_us_ca">US &amp; Canada (916 MHz)</string> <string name="medtronic_pump_frequency_us_ca">US &amp; Canada (916 MHz)</string>
<string name="medtronic_pump_frequency_worldwide">Worldwide (868 Mhz)</string> <string name="medtronic_pump_frequency_worldwide">Worldwide (868 Mhz)</string>
<string name="medtronic_pump_encoding_4b6b_local">Local 4b6b Encoding</string>
<string name="medtronic_pump_encoding_4b6b_rileylink">RileyLink 4b6b Encoding</string>
<string name="rileylink_mac_address">RileyLink MAC Address</string> <string name="rileylink_mac_address">RileyLink MAC Address</string>
<string name="rileylink_scanner_selected_device">Selected</string> <string name="rileylink_scanner_selected_device">Selected</string>
<string name="rileylink_scanner_scan">Scan</string> <string name="rileylink_scanner_scan">Scan</string>
@ -1302,6 +1305,14 @@
<string name="medtronic_error_pump_wrong_max_basal_set" formatted="false">Wrong Max Basal set on Pump (must be %.2f).</string> <string name="medtronic_error_pump_wrong_max_basal_set" formatted="false">Wrong Max Basal set on Pump (must be %.2f).</string>
<string name="xxx">xxx</string> <string name="xxx">xxx</string>
<!-- MDT History -->
<string name="medtronic_history_group_basal">Basals</string>
<string name="medtronic_history_group_configuration">Configurations</string>
<string name="medtronic_history_group_notification">Notifications</string>
<string name="medtronic_history_group_statistic">Statistics</string>
<string name="medtronic_history_group_unknown">Unknowns</string>
<string name="medtronic_history_group_all">All</string>
<!-- MDT Pump Status --> <!-- MDT Pump Status -->
<string name="medtronic_pump_status_never_contacted">Never contacted</string> <string name="medtronic_pump_status_never_contacted">Never contacted</string>
@ -1315,7 +1326,7 @@
<string name="medtronic_pump_status_sleeping">Sleeping</string> <string name="medtronic_pump_status_sleeping">Sleeping</string>
<!-- <string name="medtronic_cmd_profile_not_set">Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually.</string> --> <!-- <string name="medtronic_cmd_profile_not_set">Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually.</string> -->
<string name="medtronic_cmd_cancel_bolus_not_supported">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.</string> <string name="medtronic_cmd_cancel_bolus_not_supported">You cancelled Bolus, after it was already sent to Pump. Since Medtronic Pumps don&#44;t support cancel, you need to get Pump and put it into Suspend mode and then do Resume. Application will pick up changes, on next update.</string>
<string name="medtronic_cmd_cant_read_tbr">Could not read current TBR.</string> <string name="medtronic_cmd_cant_read_tbr">Could not read current TBR.</string>
<string name="medtronic_cmd_cant_cancel_tbr_stop_op">Could not cancel current TBR. Stopping operation.</string> <string name="medtronic_cmd_cant_cancel_tbr_stop_op">Could not cancel current TBR. Stopping operation.</string>
<string name="medtronic_cmd_set_profile_pattern_overflow">Profile set failed, because following patterns, have too big basal rate: %1$s</string> <string name="medtronic_cmd_set_profile_pattern_overflow">Profile set failed, because following patterns, have too big basal rate: %1$s</string>
@ -1323,6 +1334,19 @@
<string name="medtronic_cmd_tbr_could_not_be_delivered">TBR could not be set.</string> <string name="medtronic_cmd_tbr_could_not_be_delivered">TBR could not be set.</string>
<string name="medtronic_cmd_cant_cancel_tbr">Could not cancel current TBR.</string> <string name="medtronic_cmd_cant_cancel_tbr">Could not cancel current TBR.</string>
<string name="medtronic_cmd_basal_profile_could_not_be_set">Basal profile could not be set.</string> <string name="medtronic_cmd_basal_profile_could_not_be_set">Basal profile could not be set.</string>
<string name="medtronic_cmd_basal_profile_not_set_is_same">Basal profile is the same, so it will not be set again.</string>
<string name="medtronic_cmd_desc_get_history">Get History - Page %1$d (%2$d/16)</string>
<string name="medtronic_cmd_desc_get_history_request">Get History - Page %1$d</string>
<string name="medtronic_cmd_desc_get_history_base">Get History - Page %1$d</string>
<string name="medtronic_cmd_desc_get_time">Get Pump Time</string>
<string name="medtronic_cmd_desc_get_settings">Get Settings</string>
<string name="medtronic_cmd_desc_get_model">Get Pump Model</string>
<string name="medtronic_cmd_desc_get_basal_profile">Get Basal Profile</string>
<string name="medtronic_cmd_desc_set_basal_profile">Set Basal Profile</string>
<string name="medtronic_cmd_desc_get_tbr">Get Temporary Basal</string>
<string name="medtronic_cmd_desc_set_tbr">Set Temporary Basal</string>
<string name="medtronic_cmd_desc_set_bolus">Set Bolus</string>
<string name="pump_no_connection_h">No connection for %1$d hour(s) %2$d min</string> <string name="pump_no_connection_h">No connection for %1$d hour(s) %2$d min</string>

View file

@ -44,6 +44,22 @@
android:digits="0123456789." android:digits="0123456789."
android:title="@string/medtronic_pump_max_bolus" /> android:title="@string/medtronic_pump_max_bolus" />
<ListPreference
android:defaultValue="10"
android:entries="@array/medtronicBolusDelay"
android:entryValues="@array/medtronicBolusDelay"
android:key="pref_medtronic_bolus_delay"
android:selectable="true"
android:title="@string/medtronic_pump_bolus_delay" />
<ListPreference
android:defaultValue="@string/medtronic_pump_encoding_4b6b_rileylink"
android:entries="@array/medtronicEncoding"
android:entryValues="@array/medtronicEncoding"
android:key="pref_medtronic_encoding"
android:selectable="true"
android:title="@string/medtronic_pump_encoding" />
<info.nightscout.androidaps.plugins.PumpCommon.ui.RileyLinkSelectPreference <info.nightscout.androidaps.plugins.PumpCommon.ui.RileyLinkSelectPreference
android:id="@+id/rileylink_mac_address_mdt" android:id="@+id/rileylink_mac_address_mdt"
android:enabled="true" android:enabled="true"

View file

@ -10,6 +10,9 @@ import org.junit.runners.Parameterized;
import android.util.Log; import android.util.Log;
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding.Encoding4b6bGeoff;
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding.Encoding4b6bGo;
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.data.encoding.Encoding4b6bLoop;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
/** /**
@ -62,6 +65,9 @@ public class RFToolsParametrizedUTest {
// @Test // @Test
public void testEncodeGeoff() { public void testEncodeGeoff() {
Encoding4b6bGeoff decoder = new Encoding4b6bGeoff();
/* /*
* {0xa7} -> {0xa9, 0x60} * {0xa7} -> {0xa9, 0x60}
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72} * {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
@ -84,7 +90,7 @@ public class RFToolsParametrizedUTest {
// LOG.error("test: compare failed."); // LOG.error("test: compare failed.");
// } // }
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7}); // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 }); byte[] bs = decoder.encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 }; byte[] out = new byte[] { (byte)(0xa9), 0x65 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -93,7 +99,7 @@ public class RFToolsParametrizedUTest {
+ ByteUtil.shortHexString(bs)); + ByteUtil.shortHexString(bs));
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -102,7 +108,7 @@ public class RFToolsParametrizedUTest {
+ ByteUtil.shortHexString(bs)); + ByteUtil.shortHexString(bs));
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -117,6 +123,9 @@ public class RFToolsParametrizedUTest {
// @Test // @Test
public void testEncodeGo() { public void testEncodeGo() {
Encoding4b6bGo decoder = new Encoding4b6bGo();
/* /*
* {0xa7} -> {0xa9, 0x60} * {0xa7} -> {0xa9, 0x60}
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72} * {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
@ -139,7 +148,7 @@ public class RFToolsParametrizedUTest {
// LOG.error("test: compare failed."); // LOG.error("test: compare failed.");
// } // }
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7}); // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7 }); byte[] bs = decoder.encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 }; byte[] out = new byte[] { (byte)(0xa9), 0x65 };
System.out.println("EncodeGo: " + ByteUtil.getHex(bs)); System.out.println("EncodeGo: " + ByteUtil.getHex(bs));
@ -152,7 +161,7 @@ public class RFToolsParametrizedUTest {
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -162,7 +171,7 @@ public class RFToolsParametrizedUTest {
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -176,10 +185,12 @@ public class RFToolsParametrizedUTest {
// @Test // @Test
public void testDecodeGo() { public void testDecodeGo() throws Exception {
Encoding4b6bGo decoder = new Encoding4b6bGo();
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7}); // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 }); byte[] bs = decoder.encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 }; byte[] out = new byte[] { (byte)(0xa9), 0x65 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -188,7 +199,7 @@ public class RFToolsParametrizedUTest {
+ ByteUtil.shortHexString(bs)); + ByteUtil.shortHexString(bs));
} }
byte[] back = RFTools.decode4b6b(out); byte[] back = decoder.decode4b6b(out);
if (ByteUtil.compare(back, bs) != 0) { if (ByteUtil.compare(back, bs) != 0) {
Log.e( Log.e(
@ -198,7 +209,7 @@ public class RFToolsParametrizedUTest {
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -207,7 +218,7 @@ public class RFToolsParametrizedUTest {
+ ByteUtil.shortHexString(bs)); + ByteUtil.shortHexString(bs));
} }
back = RFTools.decode4b6b(out); back = decoder.decode4b6b(out);
if (ByteUtil.compare(back, bs) != 0) { if (ByteUtil.compare(back, bs) != 0) {
Log.e( Log.e(
@ -217,7 +228,7 @@ public class RFToolsParametrizedUTest {
Assert.fail(); Assert.fail();
} }
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 }); bs = decoder.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 }; out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) { if (ByteUtil.compare(bs, out) != 0) {
Log.e( Log.e(
@ -226,7 +237,7 @@ public class RFToolsParametrizedUTest {
+ ByteUtil.shortHexString(bs)); + ByteUtil.shortHexString(bs));
} }
back = RFTools.decode4b6b(out); back = decoder.decode4b6b(out);
if (ByteUtil.compare(back, bs) != 0) { if (ByteUtil.compare(back, bs) != 0) {
Log.e( Log.e(
@ -258,7 +269,10 @@ public class RFToolsParametrizedUTest {
// @Test // @Test
public void testParametrizedGeoffEncode() { public void testParametrizedGeoffEncode() {
byte[] encodedX = RFTools.encode4b6b(this.decoded);
Encoding4b6bGeoff decoder = new Encoding4b6bGeoff();
byte[] encodedX = decoder.encode4b6b(this.decoded);
// if (ByteUtil.compare(encodedX, this.encoded) != 0) { // if (ByteUtil.compare(encodedX, this.encoded) != 0) {
// Assert.assertEquals(encodedX, encoded); // Assert.assertEquals(encodedX, encoded);
@ -269,8 +283,10 @@ public class RFToolsParametrizedUTest {
@Test @Test
public void geoffDecode() { public void geoffDecode() throws Exception {
byte[] decodedX = RFTools.decode4b6b(this.encoded); Encoding4b6bGeoff decoder = new Encoding4b6bGeoff();
byte[] decodedX = decoder.decode4b6b(this.encoded);
Assert.assertArrayEquals(decoded, decodedX); Assert.assertArrayEquals(decoded, decodedX);
} }
@ -278,31 +294,38 @@ public class RFToolsParametrizedUTest {
@Test @Test
public void goDecode() { public void goDecode() {
RFTools.DecodeResponseDto decodeResponseDto = RFTools.decode4b6b_go(this.encoded); // Encoding4b6bGo decoder = new Encoding4b6bGo();
//
Assert.assertNull(decodeResponseDto.errorData); // DecodeResponseDto decodeResponseDto = decoder.decode4b6b(this.encoded);
System.out.println("Result: " + ByteUtil.getHex(decodeResponseDto.data)); //
System.out.println("Expected: " + ByteUtil.getHex(decoded)); // Assert.assertNull(decodeResponseDto.errorData);
Assert.assertArrayEquals(decoded, decodeResponseDto.data); // System.out.println("Result: " + ByteUtil.getHex(decodeResponseDto.data));
// System.out.println("Expected: " + ByteUtil.getHex(decoded));
// Assert.assertArrayEquals(decoded, decodeResponseDto.data);
} }
// @Test // @Test
public void loopDecode() { public void loopDecode() {
byte[] data = RFTools.decode4b6b_loop(this.encoded); // Encoding4b6bLoop decoder = new Encoding4b6bLoop();
//
// RFTools.DecodeResponseDto decodeResponseDto // byte[] data = decoder.decode4b6b(this.encoded);
//
// Assert.assertNull(decodeResponseDto.errorData); // // RFTools.DecodeResponseDto decodeResponseDto
System.out.println("Result: " + ByteUtil.getHex(data)); //
System.out.println("Expected: " + ByteUtil.getHex(decoded)); // // Assert.assertNull(decodeResponseDto.errorData);
Assert.assertArrayEquals(decoded, data); // System.out.println("Result: " + ByteUtil.getHex(data));
// System.out.println("Expected: " + ByteUtil.getHex(decoded));
// Assert.assertArrayEquals(decoded, data);
} }
@Test @Test
public void geoffEncode() { public void geoffEncode() {
byte[] encodedX = RFTools.encode4b6b(this.decoded);
Encoding4b6bGeoff decoder = new Encoding4b6bGeoff();
byte[] encodedX = decoder.encode4b6b(this.decoded);
Assert.assertArrayEquals(encoded, encodedX); Assert.assertArrayEquals(encoded, encodedX);
} }
@ -310,7 +333,9 @@ public class RFToolsParametrizedUTest {
@Test @Test
public void goEncode() { public void goEncode() {
byte[] encodedX = RFTools.encode4b6b_go(this.decoded); Encoding4b6bGo decoder = new Encoding4b6bGo();
byte[] encodedX = decoder.encode4b6b(this.decoded);
System.out.println("Result: " + ByteUtil.getHex(encodedX)); System.out.println("Result: " + ByteUtil.getHex(encodedX));
System.out.println("Expected: " + ByteUtil.getHex(encoded)); System.out.println("Expected: " + ByteUtil.getHex(encoded));
Assert.assertArrayEquals(encoded, encodedX); Assert.assertArrayEquals(encoded, encodedX);
@ -319,7 +344,9 @@ public class RFToolsParametrizedUTest {
@Test @Test
public void loopEncode() { public void loopEncode() {
byte[] encodedX = RFTools.encode4b6b_loop(this.decoded); Encoding4b6bLoop decoder = new Encoding4b6bLoop();
byte[] encodedX = decoder.encode4b6b(this.decoded);
System.out.println("Result: " + ByteUtil.getHex(encodedX)); System.out.println("Result: " + ByteUtil.getHex(encodedX));
System.out.println("Expected: " + ByteUtil.getHex(encoded)); System.out.println("Expected: " + ByteUtil.getHex(encoded));
Assert.assertArrayEquals(encoded, encodedX); Assert.assertArrayEquals(encoded, encodedX);

View file

@ -1,13 +1,7 @@
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble; package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
import junit.framework.Assert;
import org.junit.Test; import org.junit.Test;
import android.util.Log;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
/** /**
* Created by andy on 11/21/18. * Created by andy on 11/21/18.
*/ */
@ -19,115 +13,115 @@ public class RFToolsUTest {
@Test @Test
public void testEncodeGeoff() { public void testEncodeGeoff() {
/* // /*
* {0xa7} -> {0xa9, 0x60} // * {0xa7} -> {0xa9, 0x60}
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72} // * {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60} // * {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
*/ // */
/* test compare */ // /* test compare */
// byte[] s1 = { 0, 1, 2 }; // // byte[] s1 = { 0, 1, 2 };
// byte[] s2 = { 2, 1, 0, 3 }; // // byte[] s2 = { 2, 1, 0, 3 };
// byte[] s3 = { 0, 1, 2, 3 }; // // byte[] s3 = { 0, 1, 2, 3 };
// if (ByteUtil.compare(s1, s1) != 0) { // // if (ByteUtil.compare(s1, s1) != 0) {
// LOG.error("test: compare failed."); // // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s1, s2) >= 0) {
// // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s2, s1) <= 0) {
// // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s1, s3) >= 0) {
// // LOG.error("test: compare failed.");
// // }
// // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
// byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
// byte[] out = new byte[] { (byte)(0xa9), 0x65 };
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s1, s2) >= 0) { // bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
// LOG.error("test: compare failed."); // out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s2, s1) <= 0) { // bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
// LOG.error("test: compare failed."); // out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s1, s3) >= 0) {
// LOG.error("test: compare failed.");
// }
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
} }
@Test @Test
public void testEncodeGo() { public void testEncodeGo() {
/* // /*
* {0xa7} -> {0xa9, 0x60} // * {0xa7} -> {0xa9, 0x60}
* {0xa7, 0x12} -> {0xa9, 0x6c, 0x72} // * {0xa7, 0x12} -> {0xa9, 0x6c, 0x72}
* {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60} // * {0xa7, 0x12, 0xa7} -> {0xa9, 0x6c, 0x72, 0xa9, 0x60}
*/ // */
/* test compare */ // /* test compare */
// byte[] s1 = { 0, 1, 2 }; // // byte[] s1 = { 0, 1, 2 };
// byte[] s2 = { 2, 1, 0, 3 }; // // byte[] s2 = { 2, 1, 0, 3 };
// byte[] s3 = { 0, 1, 2, 3 }; // // byte[] s3 = { 0, 1, 2, 3 };
// if (ByteUtil.compare(s1, s1) != 0) { // // if (ByteUtil.compare(s1, s1) != 0) {
// LOG.error("test: compare failed."); // // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s1, s2) >= 0) {
// // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s2, s1) <= 0) {
// // LOG.error("test: compare failed.");
// // }
// // if (ByteUtil.compare(s1, s3) >= 0) {
// // LOG.error("test: compare failed.");
// // }
// // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
// byte[] bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7 });
// byte[] out = new byte[] { (byte)(0xa9), 0x65 };
//
// System.out.println("EncodeGo: " + ByteUtil.getHex(bs));
//
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s1, s2) >= 0) { //
// LOG.error("test: compare failed."); // bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12 });
// out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s2, s1) <= 0) { //
// LOG.error("test: compare failed."); // bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
// out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
// if (ByteUtil.compare(bs, out) != 0) {
// Log.e(
// TAG,
// "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
// + ByteUtil.shortHexString(bs));
// Assert.fail();
// } // }
// if (ByteUtil.compare(s1, s3) >= 0) {
// LOG.error("test: compare failed.");
// }
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 };
System.out.println("EncodeGo: " + ByteUtil.getHex(bs));
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
bs = RFTools.encode4b6b_go(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) {
Log.e(
TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs));
Assert.fail();
}
} }
@ -135,63 +129,63 @@ public class RFToolsUTest {
@Test @Test
public void testDecodeGo() { public void testDecodeGo() {
// testCompose(new byte[] {(byte)0xa7, (byte)0xa7}); // // testCompose(new byte[] {(byte)0xa7, (byte)0xa7});
byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 }); // byte[] bs = RFTools.encode4b6b(new byte[] { (byte)0xa7 });
byte[] out = new byte[] { (byte)(0xa9), 0x65 }; // byte[] out = new byte[] { (byte)(0xa9), 0x65 };
if (ByteUtil.compare(bs, out) != 0) { // if (ByteUtil.compare(bs, out) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
} // }
//
byte[] back = RFTools.decode4b6b(out); // byte[] back = RFTools.decode4b6b(out);
//
if (ByteUtil.compare(back, bs) != 0) { // if (ByteUtil.compare(back, bs) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
Assert.fail(); // Assert.fail();
} // }
//
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 }); // bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72 }; // out = new byte[] { (byte)(0xa9), 0x6c, 0x72 };
if (ByteUtil.compare(bs, out) != 0) { // if (ByteUtil.compare(bs, out) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
} // }
//
back = RFTools.decode4b6b(out); // back = RFTools.decode4b6b(out);
//
if (ByteUtil.compare(back, bs) != 0) { // if (ByteUtil.compare(back, bs) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
Assert.fail(); // Assert.fail();
} // }
//
bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 }); // bs = RFTools.encode4b6b(new byte[] { (byte)0xa7, 0x12, (byte)0xa7 });
out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 }; // out = new byte[] { (byte)(0xa9), 0x6c, 0x72, (byte)0xa9, 0x65 };
if (ByteUtil.compare(bs, out) != 0) { // if (ByteUtil.compare(bs, out) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "encode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
} // }
//
back = RFTools.decode4b6b(out); // back = RFTools.decode4b6b(out);
//
if (ByteUtil.compare(back, bs) != 0) { // if (ByteUtil.compare(back, bs) != 0) {
Log.e( // Log.e(
TAG, // TAG,
"decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got " // "decode Data failed: expected " + ByteUtil.shortHexString(out) + " but got "
+ ByteUtil.shortHexString(bs)); // + ByteUtil.shortHexString(bs));
Assert.fail(); // Assert.fail();
} // }
return; return;
} }
@ -200,25 +194,25 @@ public class RFToolsUTest {
@Test @Test
public void ttt_decodeGo() { public void ttt_decodeGo() {
RFTools.DecodeResponseDto decodeResponseDto = RFTools // RFTools.DecodeResponseDto decodeResponseDto = RFTools
.decode4b6b_go(new byte[] { // .decode4b6b_go(new byte[] {
(byte)0xF9, (byte)0xE9, 0x63, (byte)0x9E, 0x7F, (byte)0xE6, 0x79, 0x5F, (byte)0xFF, (byte)0xCF, // (byte)0xF9, (byte)0xE9, 0x63, (byte)0x9E, 0x7F, (byte)0xE6, 0x79, 0x5F, (byte)0xFF, (byte)0xCF,
(byte)0xF0 }); // (byte)0xF0 });
//
if (decodeResponseDto.errorData != null) { // if (decodeResponseDto.errorData != null) {
Log.e(TAG, decodeResponseDto.errorData); // Log.e(TAG, decodeResponseDto.errorData);
Assert.assertTrue(false); // Assert.assertTrue(false);
} else { // } else {
Assert.assertTrue(true); // Assert.assertTrue(true);
System.out.println("Response: " + ByteUtil.getHex(decodeResponseDto.data)); // System.out.println("Response: " + ByteUtil.getHex(decodeResponseDto.data));
} // }
} }
@Test @Test
public void goTest() { public void goTest() {
System.out.println(RFTools.hi(4, (short)0xa7)); // System.out.println(RFTools.hi(4, (short)0xa7));
} }
} }

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump; package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
import org.junit.Before; import org.junit.Before;
import org.junit.Test;
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil; import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
@ -70,6 +71,52 @@ public class MedtronicPumpHistoryDecoderUTest {
} }
@Test
public void decodeDailyTotals515() {
byte[] data = new byte[] {
0x6E, (byte)0xB1, (byte)0x92, 0x05, 0x00, (byte)0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, (byte)0x9A, 0x00,
0x50, 0x34, 0x00, 0x4A, 0x30, 0x00, 0x0B, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80, (byte)0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
// Carbs=11, total=3.850,basal=2.000, bolus=1.850, basal 52%, blus=48%, Manual=0.95, #manual=5,
// Food only=0.9, #Food Only=1,Corr Only =0, #Corr only=0,Food+Corr=0
// Delivery Stats: Carbs=11, Total Insulin=3.850, Basal=2.000
// Delivery Stats: Basal 52,Bolus 1.850, Bolus=48%o
// Delivery Stats: Food only=0.9, Food only#=1, Corr only = 0.0
// Delivery Stats: #Corr_only=0,Food+Corr=0.000, #Food+Corr=0
// Delivery Stats: Manual = 0.95, #Manual=5
testRecord(data);
}
@Test
public void decodeDailyTotals523() {
byte[] data = new byte[] {
0x6E, (byte)0xB1, (byte)0x92, 0x05, 0x00, (byte)0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, (byte)0x9A, 0x00,
0x50, 0x34, 0x00, 0x4A, 0x30, 0x00, 0x0B, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0x80, (byte)0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
// Carbs=11, total=3.850,basal=2.000, bolus=1.850, basal 52%, blus=48%, Manual=0.95, #manual=5,
// Food only=0.9, #Food Only=1,Corr Only =0, #Corr only=0,Food+Corr=0
// Delivery Stats: Carbs=11, Total Insulin=3.850, Basal=2.000
// Delivery Stats: Basal 52,Bolus 1.850, Bolus=48%o
// Delivery Stats: Food only=0.9, Food only#=1, Corr only = 0.0
// Delivery Stats: #Corr_only=0,Food+Corr=0.000, #Food+Corr=0
// Delivery Stats: Manual = 0.95, #Manual=5
testRecord(data);
}
private void testRecord(byte[] data) { private void testRecord(byte[] data) {
// byte[] data = new byte[] { 0x07, 0x00, 0x00, 0x05, (byte)0xFA, (byte)0xBF, 0x12 }; // byte[] data = new byte[] { 0x07, 0x00, 0x00, 0x05, (byte)0xFA, (byte)0xBF, 0x12 };