Merge the code from RileyLinkAAPS
- First real results with Pump History (not complete yet) - Set Basal Profile changes (not complete yet) - version set to medtronic-0.4.0-SNAPSHOT
This commit is contained in:
parent
88b75d3496
commit
f228475617
|
@ -71,10 +71,12 @@ android {
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "2.0g-medtronic-0.3"
|
// dev_version: 2.0g
|
||||||
|
version "medtronic-0.4.0-snapshot"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||||
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||||
|
buildConfigField "String", "DEV_VERSION", '"2.0g"'
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import android.bluetooth.le.ScanSettings;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.LocationManager;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -182,7 +181,7 @@ public class RileyLinkBLEScanActivity extends AppCompatActivity {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
// Will request that GPS be enabled for devices running Marshmallow or newer.
|
// Will request that GPS be enabled for devices running Marshmallow or newer.
|
||||||
if (!isLocationEnabled(this)) {
|
if (!LocationHelper.isLocationEnabled(this)) {
|
||||||
LocationHelper.requestLocationForBluetooth(this);
|
LocationHelper.requestLocationForBluetooth(this);
|
||||||
}
|
}
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
@ -203,20 +202,6 @@ public class RileyLinkBLEScanActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isLocationEnabled(Context context) {
|
|
||||||
|
|
||||||
final LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
|
|
||||||
|
|
||||||
if (manager != null
|
|
||||||
&& (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) || manager
|
|
||||||
.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// otherwise return false
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
|
@ -18,6 +18,8 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.Riley
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkError;
|
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkError;
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkServiceData;
|
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.RileyLinkServiceData;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||||
|
@ -89,8 +91,7 @@ public abstract class RileyLinkCommunicationManager {
|
||||||
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorError,
|
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorError,
|
||||||
RileyLinkError.NoContactWithDevice);
|
RileyLinkError.NoContactWithDevice);
|
||||||
timeoutCount = 0;
|
timeoutCount = 0;
|
||||||
tuneForDevice();
|
ServiceTaskExecutor.startTask(new WakeAndTuneTask());
|
||||||
// RileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_quickTune);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ public class RileyLinkUtil {
|
||||||
private static RileyLinkTargetFrequency rileyLinkTargetFrequency;
|
private static RileyLinkTargetFrequency rileyLinkTargetFrequency;
|
||||||
|
|
||||||
// Broadcasts: RileyLinkBLE, RileyLinkService,
|
// Broadcasts: RileyLinkBLE, RileyLinkService,
|
||||||
|
//private static RileyLinkIPCConnection rileyLinkIPCConnection;
|
||||||
private static RileyLinkTargetDevice targetDevice;
|
private static RileyLinkTargetDevice targetDevice;
|
||||||
private static RileyLinkEncodingType encoding;
|
private static RileyLinkEncodingType encoding;
|
||||||
private static RileyLinkSelectPreference rileyLinkSelectPreference;
|
private static RileyLinkSelectPreference rileyLinkSelectPreference;
|
||||||
|
|
|
@ -345,4 +345,34 @@ public class ByteUtil {
|
||||||
BIG_ENDIAN // 0 0 0 20 = normal - java
|
BIG_ENDIAN // 0 0 0 20 = normal - java
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getCompactString(byte[] data) {
|
||||||
|
String vval2 = ByteUtil.getHex(data);
|
||||||
|
vval2 = vval2.replace(" 0x", "");
|
||||||
|
vval2 = vval2.replace("0x", "");
|
||||||
|
return vval2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] createByteArray(String dataFull, int startIndex) {
|
||||||
|
return createByteArray(dataFull, startIndex, dataFull.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] createByteArray(String dataFull, int startIndex, int length) {
|
||||||
|
|
||||||
|
String data = dataFull.substring(startIndex);
|
||||||
|
|
||||||
|
data = data.substring(0, length);
|
||||||
|
|
||||||
|
int len = data.length();
|
||||||
|
byte[] outArray = new byte[len / 2];
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
outArray[i / 2] = (byte)((Character.digit(data.charAt(i), 16) << 4) + Character.digit(data.charAt(i + 1),
|
||||||
|
16));
|
||||||
|
}
|
||||||
|
|
||||||
|
return outArray;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,11 @@ public class LocationHelper {
|
||||||
*/
|
*/
|
||||||
public static boolean isLocationEnabled(Context context) {
|
public static boolean isLocationEnabled(Context context) {
|
||||||
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
|
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
return (locationManager != null && //
|
||||||
|
(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || //
|
||||||
|
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)));
|
||||||
|
|
||||||
|
// return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpMedtronic.comm;
|
package info.nightscout.androidaps.plugins.PumpMedtronic.comm;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.joda.time.Instant;
|
import org.joda.time.Instant;
|
||||||
|
@ -24,6 +25,9 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.Page;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.Page;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.history_old.Record;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.data.history_old.Record;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RawHistoryPage;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.MedtronicPumpHistoryDecoder;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryResult;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.ButtonPressCarelinkMessageBody;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.ButtonPressCarelinkMessageBody;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkLongMessageBody;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkLongMessageBody;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkShortMessageBody;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.message.CarelinkShortMessageBody;
|
||||||
|
@ -58,6 +62,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
private MedtronicConverter medtronicConverter;
|
private MedtronicConverter medtronicConverter;
|
||||||
private boolean debugSetCommands = true;
|
private boolean debugSetCommands = true;
|
||||||
|
private MedtronicPumpHistoryDecoder pumpHistoryDecoder;
|
||||||
private boolean doWakeUpBeforeCommand = true;
|
private boolean doWakeUpBeforeCommand = true;
|
||||||
private boolean firstConnection = true;
|
private boolean firstConnection = true;
|
||||||
|
|
||||||
|
@ -66,6 +71,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
super(context, rfspy, targetFrequency);
|
super(context, rfspy, targetFrequency);
|
||||||
medtronicCommunicationManager = this;
|
medtronicCommunicationManager = this;
|
||||||
this.medtronicConverter = new MedtronicConverter();
|
this.medtronicConverter = new MedtronicConverter();
|
||||||
|
this.pumpHistoryDecoder = new MedtronicPumpHistoryDecoder();
|
||||||
MedtronicUtil.getPumpStatus().previousConnection = SP.getLong(
|
MedtronicUtil.getPumpStatus().previousConnection = SP.getLong(
|
||||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||||
}
|
}
|
||||||
|
@ -231,6 +237,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
|
|
||||||
if (debugSetCommands)
|
if (debugSetCommands)
|
||||||
LOG.debug("Run command with Args: ");
|
LOG.debug("Run command with Args: ");
|
||||||
|
|
||||||
PumpMessage rval;
|
PumpMessage rval;
|
||||||
PumpMessage shortMessage = makePumpMessage(msg.commandType, new CarelinkShortMessageBody(new byte[] { 0 }));
|
PumpMessage shortMessage = makePumpMessage(msg.commandType, new CarelinkShortMessageBody(new byte[] { 0 }));
|
||||||
// look for ack from short message
|
// look for ack from short message
|
||||||
|
@ -238,9 +245,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
if (shortResponse.commandType == MedtronicCommandType.CommandACK) {
|
if (shortResponse.commandType == MedtronicCommandType.CommandACK) {
|
||||||
if (debugSetCommands)
|
if (debugSetCommands)
|
||||||
LOG.debug("Run command with Args: Got ACK response");
|
LOG.debug("Run command with Args: Got ACK response");
|
||||||
|
|
||||||
rval = sendAndListen(msg);
|
rval = sendAndListen(msg);
|
||||||
if (debugSetCommands)
|
if (debugSetCommands)
|
||||||
LOG.debug("2nd Response: {}", rval);
|
LOG.debug("2nd Response: {}", rval);
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
} else {
|
} else {
|
||||||
LOG.error("runCommandWithArgs: Pump did not ack Attention packet");
|
LOG.error("runCommandWithArgs: Pump did not ack Attention packet");
|
||||||
|
@ -249,6 +258,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private PumpMessage runCommandWithArgsLong(MedtronicCommandType commandType, byte[] content) {
|
private PumpMessage runCommandWithArgsLong(MedtronicCommandType commandType, byte[] content) {
|
||||||
|
|
||||||
LOG.debug("Run command with Args (Long): {}", commandType.name());
|
LOG.debug("Run command with Args (Long): {}", commandType.name());
|
||||||
|
@ -316,7 +326,172 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO fix this with new code, and new response (Page)
|
private PumpMessage runCommandWithFrames(MedtronicCommandType commandType, List<List<Byte>> frames) {
|
||||||
|
|
||||||
|
LOG.debug("Run command with Frames: {}", commandType.name());
|
||||||
|
|
||||||
|
PumpMessage rval = null;
|
||||||
|
PumpMessage shortMessage = makePumpMessage(commandType, new CarelinkShortMessageBody(new byte[] { 0 }));
|
||||||
|
// look for ack from short message
|
||||||
|
PumpMessage shortResponse = sendAndListen(shortMessage);
|
||||||
|
|
||||||
|
if (shortResponse.commandType != MedtronicCommandType.CommandACK) {
|
||||||
|
LOG.error("runCommandWithFrames: Pump did not ack Attention packet");
|
||||||
|
|
||||||
|
return new PumpMessage("No ACK after start message.");
|
||||||
|
} else {
|
||||||
|
LOG.debug("Run command with Frames: Got ACK response for Attention packet");
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
int frameNr = 1;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
for (List<Byte> frame : frames) {
|
||||||
|
|
||||||
|
byte[] frameData = MedtronicUtil.createByteArray(frame);
|
||||||
|
|
||||||
|
LOG.debug("Frame {} data:\n{}", frameNr, ByteUtil.getCompactString(frameData));
|
||||||
|
|
||||||
|
PumpMessage msg = makePumpMessage(commandType, new CarelinkLongMessageBody(frameData));
|
||||||
|
|
||||||
|
rval = sendAndListen(msg);
|
||||||
|
|
||||||
|
if (rval.commandType != MedtronicCommandType.CommandACK) {
|
||||||
|
LOG.error("runCommandWithFrames: Pump did not ACK frame #{}", frameNr);
|
||||||
|
|
||||||
|
return new PumpMessage("No ACK after frame #" + frameNr);
|
||||||
|
} else {
|
||||||
|
LOG.debug("Run command with Frames: Got ACK response for frame #{}", (frameNr));
|
||||||
|
}
|
||||||
|
|
||||||
|
frameNr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PumpHistoryResult getPumpHistory(PumpHistoryEntry lastEntry, LocalDateTime targetDate) {
|
||||||
|
|
||||||
|
// int pageNumber = 0;
|
||||||
|
|
||||||
|
// TODO multiple history pages
|
||||||
|
|
||||||
|
PumpHistoryResult pumpTotalResult = new PumpHistoryResult(lastEntry, targetDate);
|
||||||
|
|
||||||
|
if (doWakeUpBeforeCommand)
|
||||||
|
wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||||
|
|
||||||
|
for (int pageNumber = 0; pageNumber < 16; pageNumber++) {
|
||||||
|
|
||||||
|
RawHistoryPage rawHistoryPage = new RawHistoryPage();
|
||||||
|
// wakeUp(receiverDeviceAwakeForMinutes, false);
|
||||||
|
PumpMessage getHistoryMsg = makePumpMessage(MedtronicCommandType.GetHistoryData,
|
||||||
|
new GetHistoryPageCarelinkMessageBody(pageNumber));
|
||||||
|
|
||||||
|
LOG.info("getPumpHistory: Page {}", pageNumber);
|
||||||
|
// LOG.info("getPumpHistoryPage("+pageNumber+"): "+ByteUtil.shortHexString(getHistoryMsg.getTxData()));
|
||||||
|
// Ask the pump to transfer history (we get first frame?)
|
||||||
|
PumpMessage firstResponse = runCommandWithArgs(getHistoryMsg);
|
||||||
|
// LOG.info("getPumpHistoryPage("+pageNumber+"): " + ByteUtil.shortHexString(firstResponse.getContents()));
|
||||||
|
|
||||||
|
PumpMessage ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, new PumpAckMessageBody());
|
||||||
|
GetHistoryPageCarelinkMessageBody currentResponse = new GetHistoryPageCarelinkMessageBody(firstResponse
|
||||||
|
.getMessageBody().getTxData());
|
||||||
|
int expectedFrameNum = 1;
|
||||||
|
boolean done = false;
|
||||||
|
// while (expectedFrameNum == currentResponse.getFrameNumber()) {
|
||||||
|
|
||||||
|
int failures = 0;
|
||||||
|
while (!done) {
|
||||||
|
// examine current response for problems.
|
||||||
|
byte[] frameData = currentResponse.getFrameData();
|
||||||
|
if ((frameData != null) && (frameData.length > 0)
|
||||||
|
&& currentResponse.getFrameNumber() == expectedFrameNum) {
|
||||||
|
// success! got a frame.
|
||||||
|
if (frameData.length != 64) {
|
||||||
|
LOG.warn("Expected frame of length 64, got frame of length " + frameData.length);
|
||||||
|
// but append it anyway?
|
||||||
|
}
|
||||||
|
// handle successful frame data
|
||||||
|
rawHistoryPage.appendData(currentResponse.getFrameData());
|
||||||
|
// RileyLinkMedtronicService.getInstance().announceProgress(
|
||||||
|
// ((100 / 16) * currentResponse.getFrameNumber() + 1));
|
||||||
|
|
||||||
|
LOG.info("getPumpHistory: Got frame {} of Page {}", currentResponse.getFrameNumber(), pageNumber);
|
||||||
|
// Do we need to ask for the next frame?
|
||||||
|
if (expectedFrameNum < 16) { // This number may not be correct for pumps other than 522/722
|
||||||
|
expectedFrameNum++;
|
||||||
|
} else {
|
||||||
|
done = true; // successful completion
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (frameData == null) {
|
||||||
|
LOG.error("null frame data, retrying");
|
||||||
|
} else if (currentResponse.getFrameNumber() != expectedFrameNum) {
|
||||||
|
LOG.warn("Expected frame number {}, received {} (retrying)", expectedFrameNum,
|
||||||
|
currentResponse.getFrameNumber());
|
||||||
|
} else if (frameData.length == 0) {
|
||||||
|
LOG.warn("Frame has zero length, retrying");
|
||||||
|
}
|
||||||
|
failures++;
|
||||||
|
if (failures == 6) {
|
||||||
|
LOG.error(
|
||||||
|
"getPumpHistory: 6 failures in attempting to download frame {} of page {}, giving up.",
|
||||||
|
expectedFrameNum, pageNumber);
|
||||||
|
done = true; // failure completion.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!done) {
|
||||||
|
// ask for next frame
|
||||||
|
PumpMessage nextMsg = sendAndListen(ackMsg);
|
||||||
|
currentResponse = new GetHistoryPageCarelinkMessageBody(nextMsg.getMessageBody().getTxData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawHistoryPage.getLength() != 1024) {
|
||||||
|
LOG.warn("getPumpHistory: short page. Expected length of 1024, found length of "
|
||||||
|
+ rawHistoryPage.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rawHistoryPage.isChecksumOK()) {
|
||||||
|
LOG.error("getPumpHistory: checksum is wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
rawHistoryPage.dumpToDebug();
|
||||||
|
|
||||||
|
List<PumpHistoryEntry> medtronicHistoryEntries = pumpHistoryDecoder.processPageAndCreateRecords(
|
||||||
|
rawHistoryPage, false, PumpHistoryEntry.class);
|
||||||
|
|
||||||
|
LOG.debug("getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size());
|
||||||
|
|
||||||
|
// PumpHistoryResult pumpHistoryResult = new PumpHistoryResult(lastEntry, targetDate);
|
||||||
|
pumpTotalResult.addHistoryEntries(medtronicHistoryEntries);
|
||||||
|
|
||||||
|
LOG.debug("getPumpHistory: Search status: Search finished: {}", pumpTotalResult.isSearchFinished());
|
||||||
|
|
||||||
|
if (pumpTotalResult.isSearchFinished()) {
|
||||||
|
return pumpTotalResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return pumpTotalResult;
|
||||||
|
|
||||||
|
// Page page = new Page();
|
||||||
|
// // page.parseFrom(rval.getData(),PumpModel.MM522);
|
||||||
|
// // FIXME
|
||||||
|
// page.parseFrom(rawHistoryPage.getData(), MedtronicDeviceType.Medtronic_522);
|
||||||
|
//
|
||||||
|
// // return page;
|
||||||
|
//
|
||||||
|
// return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Page getPumpHistoryPage(int pageNumber) {
|
public Page getPumpHistoryPage(int pageNumber) {
|
||||||
RawHistoryPage rval = new RawHistoryPage();
|
RawHistoryPage rval = new RawHistoryPage();
|
||||||
|
|
||||||
|
@ -474,13 +649,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// protected PumpMessage makePumpMessage(byte[] typeAndBody) {
|
|
||||||
// PumpMessage msg = new PumpMessage();
|
|
||||||
// msg.init(ByteUtil.concat(ByteUtil.concat(new byte[]{PacketType.Carelink.getValue()},
|
|
||||||
// rileyLinkServiceData.pumpIDBytes), typeAndBody));
|
|
||||||
// return msg;
|
|
||||||
// }
|
|
||||||
|
|
||||||
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType) {
|
private PumpMessage sendAndGetResponse(MedtronicCommandType commandType) {
|
||||||
|
|
||||||
return sendAndGetResponse(commandType, null, DEFAULT_TIMEOUT);
|
return sendAndGetResponse(commandType, null, DEFAULT_TIMEOUT);
|
||||||
|
@ -531,24 +699,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME remove
|
|
||||||
// private PumpMessage sendAndGetACK(MedtronicCommandType commandType, byte[] bodyData, int timeoutMs) {
|
|
||||||
// // wakeUp
|
|
||||||
// wakeUp(receiverDeviceAwakeForMinutes, false);
|
|
||||||
//
|
|
||||||
// // create message
|
|
||||||
// PumpMessage msg;
|
|
||||||
//
|
|
||||||
// if (bodyData == null)
|
|
||||||
// msg = makePumpMessage(commandType);
|
|
||||||
// else
|
|
||||||
// msg = makePumpMessage(commandType, bodyData);
|
|
||||||
//
|
|
||||||
// // send and wait for ACK
|
|
||||||
// PumpMessage response = send(msg, timeoutMs);
|
|
||||||
// return response;
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected PumpMessage sendAndListen(RLMessage msg) {
|
protected PumpMessage sendAndListen(RLMessage msg) {
|
||||||
return sendAndListen(msg, 4000); // 2000
|
return sendAndListen(msg, 4000); // 2000
|
||||||
}
|
}
|
||||||
|
@ -818,7 +968,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO test with values bigger than 30U
|
|
||||||
public Boolean setBolus(double units) {
|
public Boolean setBolus(double units) {
|
||||||
|
|
||||||
LOG.info("setBolus: " + units);
|
LOG.info("setBolus: " + units);
|
||||||
|
@ -978,12 +1127,30 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
|
|
||||||
// byte[] body = basalProfile.generateRawData();
|
// byte[] body = basalProfile.generateRawData();
|
||||||
|
|
||||||
byte[] body = new byte[] { 32, 0, 0, 38, 0, 13, 44, 0, 19, 38, 0, 28 };
|
// byte[] body = new byte[] { 32, 0, 0, 38, 0, 13, 44, 0, 19, 38, 0, 28 };
|
||||||
|
|
||||||
PumpMessage responseMessage;
|
byte[] body = ByteUtil
|
||||||
|
.createByteArray(
|
||||||
|
"06000052000178050202000304000402000504000602000704000802000904000a02000b04000c02000d02000e02000f040010020011040012020013040014020015040016020017040018020019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
0);
|
||||||
|
|
||||||
if (debugSetCommands)
|
List<List<Byte>> basalProfileFrames = MedtronicUtil.getBasalProfileFrames(body);
|
||||||
LOG.debug("Set Basal Profile: Body [{}] - {}", body.length, HexDump.toHexStringDisplayable(body));
|
|
||||||
|
PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileA, basalProfileFrames);
|
||||||
|
|
||||||
|
// PumpMessage responseMessage;
|
||||||
|
//
|
||||||
|
// if (debugSetCommands)
|
||||||
|
// LOG.debug("Set Basal Profile: Body [{}] - {}", body.length, HexDump.toHexStringDisplayable(body));
|
||||||
|
//
|
||||||
|
// for (List<Byte> basalProfileFrame : basalProfileFrames) {
|
||||||
|
//
|
||||||
|
// PumpMessage msg = makePumpMessage(MedtronicCommandType.SetBasalProfileA, //
|
||||||
|
// new CarelinkLongMessageBody(ByteUtil.concat((byte)body.length, body)));
|
||||||
|
//
|
||||||
|
// responseMessage = runCommandWithArgs(msg);
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
// if (body.length <= 64) {
|
// if (body.length <= 64) {
|
||||||
//
|
//
|
||||||
|
@ -992,12 +1159,14 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
//
|
//
|
||||||
// responseMessage = runCommandWithArgs(msg);
|
// responseMessage = runCommandWithArgs(msg);
|
||||||
// } else
|
// } else
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
|
// responseMessage = runCommandWithArgsLong(MedtronicCommandType.SetBasalProfileA, body);
|
||||||
|
// }
|
||||||
|
|
||||||
responseMessage = runCommandWithArgsLong(MedtronicCommandType.SetBasalProfileA, body);
|
// if (debugSetCommands)
|
||||||
}
|
// LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
||||||
|
|
||||||
if (debugSetCommands)
|
|
||||||
LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
||||||
|
|
||||||
return responseMessage.commandType == MedtronicCommandType.CommandACK;
|
return responseMessage.commandType == MedtronicCommandType.CommandACK;
|
||||||
|
@ -1032,20 +1201,6 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PumpMessage setExtendedBolus(double units, int duration) {
|
|
||||||
// FIXME see decocare
|
|
||||||
PumpMessage response = sendAndGetResponse(MedtronicCommandType.SetBolus, MedtronicUtil.getBolusStrokes(units));
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PumpMessage cancelExtendedBolus() {
|
|
||||||
// set cancelBolus
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set TBR 100%
|
// Set TBR 100%
|
||||||
// Cancel TBR (set TBR 100%) 100%
|
// Cancel TBR (set TBR 100%) 100%
|
||||||
// Get Status (40%)
|
// Get Status (40%)
|
||||||
|
|
|
@ -38,11 +38,6 @@ public class MedtronicConverter {
|
||||||
|
|
||||||
this.pumpModel = MedtronicUtil.getMedtronicPumpModel();
|
this.pumpModel = MedtronicUtil.getMedtronicPumpModel();
|
||||||
|
|
||||||
// if (this.pumpModel == null) {
|
|
||||||
// LOG.warn("Pump model was not identified. Defaulting to 522.");
|
|
||||||
// this.pumpModel = MedtronicDeviceType.Medtronic_522;
|
|
||||||
// }
|
|
||||||
|
|
||||||
switch (commandType) {
|
switch (commandType) {
|
||||||
|
|
||||||
case PumpModel: {
|
case PumpModel: {
|
||||||
|
|
|
@ -11,6 +11,7 @@ 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.StringUtil;
|
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.MedtronicDeviceType;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +44,7 @@ public abstract class MedtronicHistoryDecoder {
|
||||||
protected boolean statisticsEnabled = true;
|
protected boolean statisticsEnabled = true;
|
||||||
protected Map<Integer, Integer> unknownOpCodes;
|
protected Map<Integer, Integer> unknownOpCodes;
|
||||||
protected Map<RecordDecodeStatus, Map<String, String>> mapStatistics;
|
protected Map<RecordDecodeStatus, Map<String, String>> mapStatistics;
|
||||||
|
protected MedtronicDeviceType deviceType;
|
||||||
|
|
||||||
|
|
||||||
public MedtronicHistoryDecoder() {
|
public MedtronicHistoryDecoder() {
|
||||||
|
@ -57,42 +59,57 @@ public abstract class MedtronicHistoryDecoder {
|
||||||
|
|
||||||
// public abstract void refreshOutputWriter();
|
// public abstract void refreshOutputWriter();
|
||||||
|
|
||||||
public boolean decodePage(RawHistoryPage dataPage) throws Exception {
|
// public List<? extends MedtronicHistoryEntry> decodePage(RawHistoryPage dataPage) throws Exception {
|
||||||
// refreshOutputWriter();
|
// // refreshOutputWriter();
|
||||||
|
//
|
||||||
List<? extends MedtronicHistoryEntry> minimedHistoryRecords = processPageAndCreateRecords(dataPage);
|
// List<? extends MedtronicHistoryEntry> minimedHistoryRecords = processPageAndCreateRecords(dataPage);
|
||||||
|
//
|
||||||
for (MedtronicHistoryEntry record : minimedHistoryRecords) {
|
// for (MedtronicHistoryEntry record : minimedHistoryRecords) {
|
||||||
decodeRecord(record);
|
// decodeRecord(record);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
runPostDecodeTasks();
|
// runPostDecodeTasks();
|
||||||
|
//
|
||||||
return true;
|
// return minimedHistoryRecords;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// public List<? extends MedtronicHistoryEntry> decodePartialPage(RawHistoryPage dataPage) throws Exception {
|
||||||
|
// // refreshOutputWriter();
|
||||||
|
//
|
||||||
|
// List<? extends MedtronicHistoryEntry> minimedHistoryRecords = processPageAndCreateRecords(dataPage, true);
|
||||||
|
//
|
||||||
|
// for (MedtronicHistoryEntry record : minimedHistoryRecords) {
|
||||||
|
// decodeRecord(record);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// runPostDecodeTasks();
|
||||||
|
//
|
||||||
|
// return minimedHistoryRecords;
|
||||||
|
// }
|
||||||
|
|
||||||
protected abstract void runPostDecodeTasks();
|
protected abstract void runPostDecodeTasks();
|
||||||
|
|
||||||
|
|
||||||
// TODO_ extend this to also use bigger pages (for now we support only 1024
|
// TODO_ extend this to also use bigger pages (for now we support only 1024
|
||||||
// pages)
|
// pages)
|
||||||
public List<Byte> checkPage(RawHistoryPage page) throws RuntimeException {
|
public List<Byte> checkPage(RawHistoryPage page, boolean partial) throws RuntimeException {
|
||||||
List<Byte> byteList = new ArrayList<Byte>();
|
List<Byte> byteList = new ArrayList<Byte>();
|
||||||
|
|
||||||
if (page.getData().length != 1024 /* page.commandType.getRecordLength() */) {
|
// if (!partial && page.getData().length != 1024 /* page.commandType.getRecordLength() */) {
|
||||||
LOG.error("Page size is not correct. Size should be {}, but it was {} instead.", 1024,
|
// LOG.error("Page size is not correct. Size should be {}, but it was {} instead.", 1024,
|
||||||
page.getData().length);
|
// page.getData().length);
|
||||||
// throw exception perhaps
|
// // throw exception perhaps
|
||||||
return byteList;
|
// return byteList;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (MedtronicUtil.getMedtronicPumpModel() == null) {
|
if (MedtronicUtil.getMedtronicPumpModel() == null) {
|
||||||
LOG.error("Device Type is not defined.");
|
LOG.error("Device Type is not defined.");
|
||||||
return byteList;
|
return byteList;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page.isChecksumOK()) {
|
if (page.getData().length != 1024) {
|
||||||
|
return ByteUtil.getListFromByteArray(page.getData());
|
||||||
|
} else if (page.isChecksumOK()) {
|
||||||
return ByteUtil.getListFromByteArray(page.getOnlyData());
|
return ByteUtil.getListFromByteArray(page.getOnlyData());
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -100,9 +117,13 @@ public abstract class MedtronicHistoryDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page)
|
// public abstract List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page,
|
||||||
throws Exception;
|
// boolean partial) throws Exception;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// public List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page) throws Exception {
|
||||||
|
// return processPageAndCreateRecords(page, false);
|
||||||
|
// }
|
||||||
|
|
||||||
protected void prepareStatistics() {
|
protected void prepareStatistics() {
|
||||||
if (!statisticsEnabled)
|
if (!statisticsEnabled)
|
||||||
|
@ -190,4 +211,27 @@ public abstract class MedtronicHistoryDecoder {
|
||||||
return StringUtil.getFormatedValueUS(value, decimals);
|
return StringUtil.getFormatedValueUS(value, decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public <E extends MedtronicHistoryEntry> List<E> processPageAndCreateRecords(RawHistoryPage rawHistoryPage,
|
||||||
|
// boolean partial) {
|
||||||
|
// return (processPageAndCreateRecords(
|
||||||
|
// rawHistoryPage, partial, clazz);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public <E extends MedtronicHistoryEntry> List<E> processPageAndCreateRecords(RawHistoryPage rawHistoryPage,
|
||||||
|
boolean partial, Class<E> clazz) {
|
||||||
|
List<Byte> dataClear = checkPage(rawHistoryPage, partial);
|
||||||
|
List<E> records = createRecords(dataClear, clazz);
|
||||||
|
|
||||||
|
for (MedtronicHistoryEntry record : records) {
|
||||||
|
decodeRecord(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
runPostDecodeTasks();
|
||||||
|
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClear, Class<E> clazz);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
|
||||||
protected LocalDateTime dateTime;
|
protected LocalDateTime dateTime;
|
||||||
// protected PumpTimeStampedRecord historyEntryDetails;
|
// protected PumpTimeStampedRecord historyEntryDetails;
|
||||||
|
|
||||||
private Map<String, Object> decodedData;
|
protected Map<String, Object> decodedData;
|
||||||
|
|
||||||
|
|
||||||
public void setData(List<Byte> listRawData, boolean doNotProcess) {
|
public void setData(List<Byte> listRawData, boolean doNotProcess) {
|
||||||
|
|
|
@ -11,7 +11,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.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.RawHistoryPage;
|
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,14 +110,13 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page) throws Exception {
|
// public List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page) throws Exception {
|
||||||
List<Byte> dataClear = checkPage(page);
|
// List<Byte> dataClear = checkPage(page, false);
|
||||||
return createRecords(dataClear);
|
// return createRecords(dataClear);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
protected <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClearInput, Class<E> clazz) {
|
||||||
private List<? extends MedtronicHistoryEntry> createRecords(List<Byte> dataClearInput) {
|
|
||||||
// List<MinimedHistoryEntry> listRecords = new
|
// List<MinimedHistoryEntry> listRecords = new
|
||||||
// ArrayList<MinimedHistoryEntry>();
|
// ArrayList<MinimedHistoryEntry>();
|
||||||
|
|
||||||
|
@ -134,7 +132,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int record = 0;
|
int record = 0;
|
||||||
|
|
||||||
List<MedtronicHistoryEntry> outList = new ArrayList<MedtronicHistoryEntry>();
|
List<E> outList = new ArrayList<E>();
|
||||||
|
|
||||||
// create CGMS entries (without dates)
|
// create CGMS entries (without dates)
|
||||||
do {
|
do {
|
||||||
|
@ -164,7 +162,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
|
|
||||||
// System.out.println("Record: " + pe);
|
// System.out.println("Record: " + pe);
|
||||||
|
|
||||||
outList.add(pe);
|
outList.add((E)pe);
|
||||||
} else {
|
} else {
|
||||||
List<Byte> listRawData = new ArrayList<Byte>();
|
List<Byte> listRawData = new ArrayList<Byte>();
|
||||||
listRawData.add((byte)opCode);
|
listRawData.add((byte)opCode);
|
||||||
|
@ -182,7 +180,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
|
|
||||||
// System.out.println("Record: " + pe);
|
// System.out.println("Record: " + pe);
|
||||||
|
|
||||||
outList.add(pe);
|
outList.add((E)pe);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CGMSHistoryEntry pe = new CGMSHistoryEntry();
|
CGMSHistoryEntry pe = new CGMSHistoryEntry();
|
||||||
|
@ -196,7 +194,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
|
|
||||||
// System.out.println("Record: " + pe);
|
// System.out.println("Record: " + pe);
|
||||||
|
|
||||||
outList.add(pe);
|
outList.add((E)pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (counter < dataClear.size());
|
} while (counter < dataClear.size());
|
||||||
|
|
|
@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
|
import info.nightscout.androidaps.plugins.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.RawHistoryPage;
|
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.RecordDecodeStatus;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusDTO;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusDTO;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusWizardDTO;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.data.dto.BolusWizardDTO;
|
||||||
|
@ -62,17 +61,22 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
|
|
||||||
|
|
||||||
public MedtronicPumpHistoryDecoder() {
|
public MedtronicPumpHistoryDecoder() {
|
||||||
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page) {
|
// public List<? extends MedtronicHistoryEntry> processPageAndCreateRecords(RawHistoryPage page) {
|
||||||
List<Byte> dataClear = checkPage(page);
|
// List<Byte> dataClear = checkPage(page, false);
|
||||||
return createRecords(dataClear);
|
// return createRecords(dataClear);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// public <E extends MedtronicHistoryEntry> List<E> processPageAndCreateRecords(RawHistoryPage rawHistoryPage,
|
||||||
|
// boolean partial, Class<E> clazz) {
|
||||||
|
//
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
public List<? extends MedtronicHistoryEntry> createRecords(List<Byte> dataClear) {
|
public <E extends MedtronicHistoryEntry> List<E> createRecords(List<Byte> dataClear, Class<E> clazz) {
|
||||||
prepareStatistics();
|
prepareStatistics();
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
@ -80,7 +84,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
boolean incompletePacket = false;
|
boolean incompletePacket = false;
|
||||||
deviceType = MedtronicUtil.getMedtronicPumpModel();
|
deviceType = MedtronicUtil.getMedtronicPumpModel();
|
||||||
|
|
||||||
List<MedtronicHistoryEntry> outList = new ArrayList<MedtronicHistoryEntry>();
|
List<E> outList = new ArrayList<E>();
|
||||||
String skipped = null;
|
String skipped = null;
|
||||||
int elementStart = 0;
|
int elementStart = 0;
|
||||||
|
|
||||||
|
@ -223,7 +227,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
|
|
||||||
if (decoded == RecordDecodeStatus.OK) // we add only OK records, all others are ignored
|
if (decoded == RecordDecodeStatus.OK) // we add only OK records, all others are ignored
|
||||||
{
|
{
|
||||||
outList.add(pe);
|
outList.add((E)pe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +253,19 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public <E extends MedtronicHistoryEntry> List<E> getTypedList(List<? extends MedtronicHistoryEntry> list,
|
||||||
|
Class<E> clazz) {
|
||||||
|
|
||||||
|
List<E> listOut = new ArrayList<>();
|
||||||
|
|
||||||
|
for (MedtronicHistoryEntry medtronicHistoryEntry : list) {
|
||||||
|
listOut.add((E)medtronicHistoryEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn, boolean x) {
|
public RecordDecodeStatus decodeRecord(MedtronicHistoryEntry entryIn, boolean x) {
|
||||||
// FIXME
|
// FIXME
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
|
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
|
import info.nightscout.androidaps.plugins.PumpCommon.utils.HexDump;
|
||||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
|
import info.nightscout.androidaps.plugins.PumpCommon.utils.StringUtil;
|
||||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry;
|
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHistoryEntry;
|
||||||
|
@ -27,6 +33,8 @@ import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.MedtronicHi
|
||||||
|
|
||||||
public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
||||||
|
|
||||||
|
private static Logger LOG = LoggerFactory.getLogger(PumpHistoryEntry.class);
|
||||||
|
|
||||||
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 LocalDateTime timeOfEntry;
|
// private LocalDateTime timeOfEntry;
|
||||||
|
@ -98,4 +106,42 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
||||||
public int getDateLength() {
|
public int getDateLength() {
|
||||||
return this.entryType.getDateLength();
|
return this.entryType.getDateLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!(o instanceof PumpHistoryEntry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PumpHistoryEntry that = (PumpHistoryEntry)o;
|
||||||
|
|
||||||
|
return entryType == that.entryType && //
|
||||||
|
Objects.equals(this.dateTime, that.dateTime); // && //
|
||||||
|
// Objects.equals(this.decodedData, that.decodedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(entryType, opCode, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isAfter(LocalDateTime dateTimeIn) {
|
||||||
|
// LOG.debug("Entry: " + this.dateTime);
|
||||||
|
// LOG.debug("Datetime: " + dateTimeIn);
|
||||||
|
// LOG.debug("Item after: " + this.dateTime.isAfter(dateTimeIn));
|
||||||
|
return this.dateTime.isAfter(dateTimeIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Comparator implements java.util.Comparator<PumpHistoryEntry> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(PumpHistoryEntry o1, PumpHistoryEntry o2) {
|
||||||
|
return o2.dateTime.compareTo(o1.dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by andy on 9/23/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* History page contains data, sorted from oldest to newest
|
||||||
|
*/
|
||||||
|
public class PumpHistoryResult {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(PumpHistoryResult.class);
|
||||||
|
|
||||||
|
private boolean searchFinished = false;
|
||||||
|
private PumpHistoryEntry searchEntry = null;
|
||||||
|
private LocalDateTime searchDate = null;
|
||||||
|
private SearchType searchType = SearchType.None;
|
||||||
|
private List<PumpHistoryEntry> unprocessedEntries;
|
||||||
|
public List<PumpHistoryEntry> validEntries;
|
||||||
|
|
||||||
|
|
||||||
|
// private Object validValues;
|
||||||
|
|
||||||
|
public PumpHistoryResult(PumpHistoryEntry searchEntry, LocalDateTime targetDate) {
|
||||||
|
if (searchEntry != null) {
|
||||||
|
this.searchEntry = searchEntry;
|
||||||
|
this.searchType = SearchType.LastEntry;
|
||||||
|
LOG.debug("PumpHistoryResult. Search parameters: Last Entry: " + searchEntry.getLocalDateTime() + " type="
|
||||||
|
+ searchEntry.getEntryType().name());
|
||||||
|
} else if (targetDate != null) {
|
||||||
|
this.searchDate = targetDate;
|
||||||
|
this.searchType = SearchType.Date;
|
||||||
|
LOG.debug("PumpHistoryResult. Search parameters: Date: " + targetDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.unprocessedEntries = new ArrayList<>();
|
||||||
|
this.validEntries = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addHistoryEntries(List<PumpHistoryEntry> entries) {
|
||||||
|
this.unprocessedEntries = entries;
|
||||||
|
LOG.debug("PumpHistoryResult. Unprocessed entries: {}", entries);
|
||||||
|
processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void processEntries() {
|
||||||
|
int olderEntries = 0;
|
||||||
|
|
||||||
|
switch (searchType) {
|
||||||
|
case None:
|
||||||
|
this.validEntries.addAll(this.unprocessedEntries);
|
||||||
|
// this.unprocessedEntries = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LastEntry: {
|
||||||
|
if (this.validEntries == null)
|
||||||
|
this.validEntries = new ArrayList<>();
|
||||||
|
|
||||||
|
Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
|
||||||
|
|
||||||
|
LOG.debug("PumpHistoryResult. Search entry date: " + searchEntry.getLocalDateTime());
|
||||||
|
|
||||||
|
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
|
||||||
|
|
||||||
|
if (unprocessedEntry.equals(searchEntry)) {
|
||||||
|
searchFinished = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.validEntries.add(unprocessedEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Date: {
|
||||||
|
if (this.validEntries == null)
|
||||||
|
this.validEntries = new ArrayList<>();
|
||||||
|
|
||||||
|
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
|
||||||
|
if (unprocessedEntry.isAfter(this.searchDate)) {
|
||||||
|
this.validEntries.add(unprocessedEntry);
|
||||||
|
} else {
|
||||||
|
if (unprocessedEntry.getLocalDateTime().getYear() != 2000)
|
||||||
|
olderEntries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (olderEntries > 0) {
|
||||||
|
Collections.sort(this.validEntries, new PumpHistoryEntry.Comparator());
|
||||||
|
|
||||||
|
searchFinished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isSearchRequired() {
|
||||||
|
return searchType != SearchType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isSearchFinished() {
|
||||||
|
return searchFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<PumpHistoryEntry> getValidEntries() {
|
||||||
|
return validEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SearchType {
|
||||||
|
None, //
|
||||||
|
LastEntry, //
|
||||||
|
Date
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.message;
|
package info.nightscout.androidaps.plugins.PumpMedtronic.comm.message;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by geoff on 6/2/16.
|
* Created by geoff on 6/2/16.
|
||||||
*/
|
*/
|
||||||
|
@ -19,8 +23,17 @@ public class CarelinkLongMessageBody extends MessageBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CarelinkLongMessageBody(List<Byte> payload) {
|
||||||
|
init(MedtronicUtil.createByteArray(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(byte[] rxData) {
|
public void init(byte[] rxData) {
|
||||||
|
|
||||||
|
if (rxData != null && rxData.length == LONG_MESSAGE_BODY_LENGTH) {
|
||||||
|
data = rxData;
|
||||||
|
} else {
|
||||||
data = new byte[LONG_MESSAGE_BODY_LENGTH];
|
data = new byte[LONG_MESSAGE_BODY_LENGTH];
|
||||||
if (rxData != null) {
|
if (rxData != null) {
|
||||||
int size = rxData.length < LONG_MESSAGE_BODY_LENGTH ? rxData.length : LONG_MESSAGE_BODY_LENGTH;
|
int size = rxData.length < LONG_MESSAGE_BODY_LENGTH ? rxData.length : LONG_MESSAGE_BODY_LENGTH;
|
||||||
|
@ -29,6 +42,7 @@ public class CarelinkLongMessageBody extends MessageBody {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class PumpMessage implements RLMessage {
|
||||||
|
|
||||||
System.arraycopy(messageBody.getTxData(), 1, arrayOut, 0, length);
|
System.arraycopy(messageBody.getTxData(), 1, arrayOut, 0, length);
|
||||||
|
|
||||||
Log.v("PumpMessage", "Length: " + length + ", Original Length: " + originalLength + ", CommandType: "
|
Log.d("PumpMessage", "Length: " + length + ", Original Length: " + originalLength + ", CommandType: "
|
||||||
+ commandType);
|
+ commandType);
|
||||||
|
|
||||||
return arrayOut;
|
return arrayOut;
|
||||||
|
|
|
@ -109,8 +109,10 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
||||||
GetBasalProfileSTD(146, "Get Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8, 1), // 146
|
GetBasalProfileSTD(146, "Get Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8, 1), // 146
|
||||||
|
|
||||||
GetBasalProfileA(147, "Get Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 9), // 147
|
GetBasalProfileA(147, "Get Profile A", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 9), // 147
|
||||||
|
// FIXME
|
||||||
|
|
||||||
GetBasalProfileB(148, "Get Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 10), // 148
|
GetBasalProfileB(148, "Get Profile B", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 10), // 148
|
||||||
|
// FIXME
|
||||||
|
|
||||||
SetBasalProfileSTD(0x6f, "Set Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 111
|
SetBasalProfileSTD(0x6f, "Set Profile Standard", MinimedTargetType.PumpConfiguration, MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters, 192, 1, 8), // 111
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ public class MedtronicPumpStatus extends PumpStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val > defaultValueDouble) {
|
if (val > defaultValueDouble) {
|
||||||
SP.putString(MedtronicConst.Prefs.MaxBolus, "25.0");
|
SP.putString(MedtronicConst.Prefs.MaxBolus, defaultValue);
|
||||||
val = defaultValueDouble;
|
val = defaultValueDouble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,8 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
|
|
||||||
|
|
||||||
public void addPumpSpecificIntents(IntentFilter intentFilter) {
|
public void addPumpSpecificIntents(IntentFilter intentFilter) {
|
||||||
intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchHistory);
|
//intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchHistory);
|
||||||
intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory);
|
//intentFilter.addAction(RileyLinkConst.IPC.MSG_PUMP_fetchSavedHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -431,10 +431,6 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// public MedtronicCommunicationManager getPumpManager() {
|
|
||||||
// return this.medtronicCommunicationManager;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// FIXME remove
|
// FIXME remove
|
||||||
public void sendNotification(ServiceNotification serviceNotification, Object o) {
|
public void sendNotification(ServiceNotification serviceNotification, Object o) {
|
||||||
LOG.warn("Send Notification has no implementation.");
|
LOG.warn("Send Notification has no implementation.");
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.util;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -45,6 +46,8 @@ public class MedtronicUtil extends RileyLinkUtil {
|
||||||
private static MedtronicPumpStatus medtronicPumpStatus;
|
private static MedtronicPumpStatus medtronicPumpStatus;
|
||||||
private static MedtronicCommandType currentCommand;
|
private static MedtronicCommandType currentCommand;
|
||||||
private static Map<String, PumpSettingDTO> settings;
|
private static Map<String, PumpSettingDTO> settings;
|
||||||
|
private static int BIG_FRAME_LENGTH = 65;
|
||||||
|
private static int doneBit = 1 << 7;
|
||||||
|
|
||||||
|
|
||||||
public static LocalTime getTimeFrom30MinInterval(int interval) {
|
public static LocalTime getTimeFrom30MinInterval(int interval) {
|
||||||
|
@ -285,6 +288,105 @@ public class MedtronicUtil extends RileyLinkUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Note: at the moment supported only for 24 items, if you will use it for more than
|
||||||
|
// that you will need to add
|
||||||
|
public static List<List<Byte>> getBasalProfileFrames(byte[] data) {
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
int start = 0;
|
||||||
|
int frame = 1;
|
||||||
|
|
||||||
|
List<List<Byte>> frames = new ArrayList<>();
|
||||||
|
boolean lastFrame = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
int frameLength = BIG_FRAME_LENGTH - 1;
|
||||||
|
|
||||||
|
if (start + frameLength > data.length) {
|
||||||
|
frameLength = data.length - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Framelength: " + frameLength);
|
||||||
|
|
||||||
|
byte[] substring = ByteUtil.substring(data, start, frameLength);
|
||||||
|
|
||||||
|
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||||
|
// System.out.println("Subarray Lenths: " + substring.length);
|
||||||
|
|
||||||
|
List<Byte> frameData = ByteUtil.getListFromByteArray(substring);
|
||||||
|
|
||||||
|
if (isEmptyFrame(frameData)) {
|
||||||
|
byte b = (byte)frame;
|
||||||
|
// b |= 0x80;
|
||||||
|
// b |= 0b1000_0000;
|
||||||
|
b |= doneBit;
|
||||||
|
|
||||||
|
frameData.add(0, b);
|
||||||
|
|
||||||
|
checkAndAppenLastFrame(frameData);
|
||||||
|
|
||||||
|
lastFrame = true;
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
} else {
|
||||||
|
frameData.add(0, (byte)frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Subarray: " + ByteUtil.getCompactString(substring));
|
||||||
|
|
||||||
|
frames.add(frameData);
|
||||||
|
|
||||||
|
frame++;
|
||||||
|
start += (BIG_FRAME_LENGTH - 1);
|
||||||
|
|
||||||
|
if (start == data.length) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (!done);
|
||||||
|
|
||||||
|
if (!lastFrame) {
|
||||||
|
List<Byte> frameData = new ArrayList<>();
|
||||||
|
|
||||||
|
byte b = (byte)frame;
|
||||||
|
// b |= 0b1000_0000;
|
||||||
|
b |= doneBit;
|
||||||
|
|
||||||
|
frameData.add(b);
|
||||||
|
|
||||||
|
checkAndAppenLastFrame(frameData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void checkAndAppenLastFrame(List<Byte> frameData) {
|
||||||
|
|
||||||
|
if (frameData.size() == BIG_FRAME_LENGTH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int missing = BIG_FRAME_LENGTH - frameData.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < missing; i++) {
|
||||||
|
frameData.add((byte)0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isEmptyFrame(List<Byte> frameData) {
|
||||||
|
|
||||||
|
for (Byte frameDateEntry : frameData) {
|
||||||
|
if (frameDateEntry != 0x00) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isLowLevelDebug() {
|
public static boolean isLowLevelDebug() {
|
||||||
return lowLevelDebug;
|
return lowLevelDebug;
|
||||||
}
|
}
|
||||||
|
|
522
app/src/main/res/layout/overview_wizard_dialog_compact.xml
Normal file
522
app/src/main/res/layout/overview_wizard_dialog_compact.xml
Normal file
|
@ -0,0 +1,522 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:minWidth="300dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:id="@+id/toggleButton"
|
||||||
|
android:layout_width="90dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="ToggleButton"
|
||||||
|
android:textOff="@string/treatments_wizard_bg_label"
|
||||||
|
android:textOn="@string/treatments_wizard_bg_label" />
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:layout_width="90dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="ToggleButton"
|
||||||
|
android:checked="true"
|
||||||
|
android:textOff="@string/treatments_wizard_carbs_label"
|
||||||
|
android:textOn="@string/treatments_wizard_carbs_label" />
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:layout_width="90dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="ToggleButton"
|
||||||
|
android:textOff="@string/treatments_wizard_correction_label"
|
||||||
|
android:textOn="@string/treatments_wizard_correction_label" />
|
||||||
|
|
||||||
|
<ToggleButton
|
||||||
|
android:layout_width="90dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="ToggleButton"
|
||||||
|
android:textOff="@string/careportal_newnstreatment_carbtime_label"
|
||||||
|
android:textOn="@string/careportal_newnstreatment_carbtime_label" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="0.0 mmol" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="0 g" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="0.00 U" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView3"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textAlignment="center"
|
||||||
|
|
||||||
|
android:text="0 min" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/treatments_wizard_carbtime_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="70dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="92dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:width="120dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:text="@string/treatments_wizard_carbs_label"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Small"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<info.nightscout.utils.NumberPicker
|
||||||
|
android:id="@+id/treatments_wizard_carbtimeinput"
|
||||||
|
android:layout_width="193dp"
|
||||||
|
android:layout_height="74dp"
|
||||||
|
android:layout_gravity="center_horizontal" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="31dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:minWidth="45dp"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:text="U"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/treatments_wizard_profile_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:text="@string/careportal_newnstreatment_profile_label"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Small"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/treatments_wizard_profile"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|center_horizontal"
|
||||||
|
android:layout_weight="0.5" />
|
||||||
|
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_sbcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:checked="false"
|
||||||
|
android:text="Super\nbolus" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_total"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/background_darkgray"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:text="2.35U 28g"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/treatments_wizard_notes_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:width="120dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:text="@string/careportal_newnstreatment_notes_label"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Small"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/treatment_wizard_notes"
|
||||||
|
android:layout_width="155dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="left"
|
||||||
|
android:inputType="text|textCapSentences"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/mdtp_done_button" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:layout_marginLeft="20dp"
|
||||||
|
android:layout_marginTop="-15dp"
|
||||||
|
android:background="@color/listdelimiter" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_bgcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="24dp"
|
||||||
|
android:text="@string/treatments_wizard_bg_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_ttcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="false" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="30dp"
|
||||||
|
android:text="@string/treatments_wizard_tt_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bg"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bginsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_bgtrendcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="false" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="86dp"
|
||||||
|
android:text="@string/treatments_wizard_bgtrend_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bgtrend"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bgtrendinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/treatments_wizard_cob_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_cobcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="false" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="86dp"
|
||||||
|
android:text="@string/treatments_wizard_cob_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_cob"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_cobinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_bolusiobcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="130dp"
|
||||||
|
android:text="@string/treatments_wizard_bolusiob_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bolusiob"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_bolusiobinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/treatments_wizard_basaliobcheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp"
|
||||||
|
android:checked="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="130dp"
|
||||||
|
android:text="@string/treatments_wizard_basaliob_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_basaliob"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_basaliobinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="86dp"
|
||||||
|
android:text="@string/treatments_wizard_carbs_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_carbs"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_carbsinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="86dp"
|
||||||
|
android:text="@string/superbolus"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_sb"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_sbinsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="32dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="86dp"
|
||||||
|
android:text="@string/treatments_wizard_correction_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_correction"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="94dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/treatments_wizard_correctioninsulin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:width="50dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
Loading…
Reference in a new issue