diff --git a/app/src/main/java/com/cozmo/danar/util/BleCommandUtil.java b/app/src/main/java/com/cozmo/danar/util/BleCommandUtil.java index 65be0a57f4..a417b379e8 100644 --- a/app/src/main/java/com/cozmo/danar/util/BleCommandUtil.java +++ b/app/src/main/java/com/cozmo/danar/util/BleCommandUtil.java @@ -82,6 +82,10 @@ public class BleCommandUtil { public static final int DANAR_PACKET__OPCODE_OPTION__GET_USER_OPTION = 0x72; public static final int DANAR_PACKET__OPCODE_OPTION__SET_USER_OPTION = 0x73; + public static final int DANAR_PACKET__OPCODE_BASAL__APS_SET_TEMPORARY_BASAL = 0xC1; + public static final int DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS = 0xC2; + public static final int DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY = 0xC3; + public static final int DANAR_PACKET__OPCODE_ETC__SET_HISTORY_SAVE = 0xE0; public static final int DANAR_PACKET__OPCODE_ETC__KEEP_CONNECTION = 0xFF; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java index 8fdfc7840c..9f88011c96 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java @@ -54,6 +54,7 @@ public class DanaRPump { public static final int PRIME = 12; public static final int PROFILECHANGE = 13; public static final int CARBS = 14; + public static final int PRIMECANNULA = 15; public Date lastConnection = new Date(0); public Date lastSettingsRead = new Date(0); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java index f11b130fa8..5457bb4155 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java @@ -84,6 +84,11 @@ public class DanaRSMessageHashTable { put(new DanaRS_Packet_History_Suspend()); put(new DanaRS_Packet_History_Temporary()); + // APS + put(new DanaRS_Packet_APS_Basal_Set_Temporary_Basal()); + put(new DanaRS_Packet_APS_History_Events()); + put(new DanaRS_Packet_APS_Set_Event_History()); + Config.logDanaMessageDetail = savedState; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java index 18747b59ce..8ac5bfac13 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java @@ -14,11 +14,13 @@ public class DanaRS_Packet { protected static final int DATA_START = 2; private boolean received; + protected boolean failed; protected int type = BleCommandUtil.DANAR_PACKET__TYPE_RESPONSE; // most of the messages, should be changed for others protected int opCode; public DanaRS_Packet() { received = false; + failed = false; } public void setReceived() { @@ -98,6 +100,42 @@ public class DanaRS_Packet { return ret; } + public static Date dateTimeSecFromBuff(byte[] buff, int offset) { + Date date = + new Date( + 100 + intFromBuff(buff, offset, 1), + intFromBuff(buff, offset + 1, 1) - 1, + intFromBuff(buff, offset + 2, 1), + intFromBuff(buff, offset + 3, 1), + intFromBuff(buff, offset + 4, 1), + intFromBuff(buff, offset + 5, 1) + ); + return date; + } + + protected static int intFromBuff(byte[] b, int srcStart, int srcLength) { + int ret; + + switch (srcLength) { + case 1: + ret = b[DATA_START + srcStart + 0] & 0x000000FF; + break; + case 2: + ret = ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF); + break; + case 3: + ret = ((b[DATA_START + srcStart + 2] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF); + break; + case 4: + ret = ((b[DATA_START + srcStart + 3] & 0x000000FF) << 24) + ((b[DATA_START + srcStart + 2] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF); + break; + default: + ret = -1; + break; + } + return ret; + } + @TargetApi(Build.VERSION_CODES.KITKAT) public static String stringFromBuff(byte[] buff, int offset, int length) { byte[] strbuff = new byte[length]; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java new file mode 100644 index 0000000000..7ce847dc58 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java @@ -0,0 +1,67 @@ +package info.nightscout.androidaps.plugins.PumpDanaRS.comm; + +import com.cozmo.danar.util.BleCommandUtil; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.Config; + +public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { + private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Basal_Set_Temporary_Basal.class); + + private int temporaryBasalRatio; + private int temporaryBasalDuration; + public int error; + + public DanaRS_Packet_APS_Basal_Set_Temporary_Basal() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__APS_SET_TEMPORARY_BASAL; + } + + public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent) { + this(); + + //HARDCODED LIMITS + if (percent < 0) percent = 0; + if (percent > 500) percent = 500; + + temporaryBasalRatio = percent; + if (percent < 100) { + temporaryBasalDuration = 160; + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); + } else { + temporaryBasalDuration = 150; + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); + } + + } + + @Override + public byte[] getRequestParams() { + byte[] request = new byte[3]; + request[0] = (byte) (temporaryBasalRatio & 0xff); + request[1] = (byte) ((temporaryBasalRatio >>> 8) & 0xff); + request[2] = (byte) (temporaryBasalDuration & 0xff); + return request; + } + + @Override + public void handleMessage(byte[] data) { + int result = byteArrayToInt(getBytes(data, DATA_START, 1)); + if (result != 1) { + failed = true; + log.debug("Set APS temp basal start result: " + result + " FAILED!!!"); + } else { + if (Config.logDanaMessageDetail) + log.debug("Set APS temp basal start result: " + result); + } + } + + @Override + public String getFriendlyName() { + return "BASAL__APS_SET_TEMPORARY_BASAL"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java new file mode 100644 index 0000000000..e9945d2ceb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java @@ -0,0 +1,190 @@ +package info.nightscout.androidaps.plugins.PumpDanaRS.comm; + +import com.cozmo.danar.util.BleCommandUtil; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.db.DanaRHistoryRecord; +import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; +import info.nightscout.utils.DateUtil; + +public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { + private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_History_Events.class); + + private int year = 0; + private int month = 0; + private int day = 0; + private int hour = 0; + private int min = 0; + private int sec = 0; + + public boolean done; + public int totalCount; + + public static long lastEventTimeLoaded = 0; + + public DanaRS_Packet_APS_History_Events() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS; + done = false; + totalCount = 0; + } + + public DanaRS_Packet_APS_History_Events(long from) { + this(); + GregorianCalendar cal = new GregorianCalendar(); + if (from != 0) + cal.setTimeInMillis(from); + else + cal.set(2000, 0, 1, 0, 0, 0); + year = cal.get(Calendar.YEAR) - 1900 - 100; + month = cal.get(Calendar.MONTH) + 1; + day = cal.get(Calendar.DAY_OF_MONTH); + hour = cal.get(Calendar.HOUR_OF_DAY); + min = cal.get(Calendar.MINUTE); + sec = cal.get(Calendar.SECOND); + log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString()); + } + + @Override + public byte[] getRequestParams() { + byte[] request = new byte[6]; + request[0] = (byte) (year & 0xff); + request[1] = (byte) (month & 0xff); + request[2] = (byte) (day & 0xff); + request[3] = (byte) (hour & 0xff); + request[4] = (byte) (min & 0xff); + request[5] = (byte) (sec & 0xff); + return request; + } + + @Override + public void handleMessage(byte[] data) { + byte recordCode = (byte) intFromBuff(data, 0, 1); + + // Last record + if (recordCode == (byte) 0xFF) { + done = true; + return; + } + + Date datetime = dateTimeSecFromBuff(data, 1); // 6 bytes + int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF) + (intFromBuff(data, 8, 1) & 0xFF); + int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF) + (intFromBuff(data, 10, 1) & 0xFF); + + TemporaryBasal temporaryBasal = new TemporaryBasal(); + temporaryBasal.date = datetime.getTime(); + temporaryBasal.source = Source.PUMP; + temporaryBasal.pumpId = datetime.getTime(); + + ExtendedBolus extendedBolus = new ExtendedBolus(); + extendedBolus.date = datetime.getTime(); + extendedBolus.source = Source.PUMP; + extendedBolus.pumpId = datetime.getTime(); + + DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime.getTime()); + if (detailedBolusInfo == null) { + log.debug("DetailedBolusInfo not found for " + datetime.toLocaleString()); + detailedBolusInfo = new DetailedBolusInfo(); + } + detailedBolusInfo.date = datetime.getTime(); + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = datetime.getTime(); + + switch (recordCode) { + case DanaRPump.TEMPSTART: + log.debug("EVENT TEMPSTART (" + recordCode + ") " + datetime.toLocaleString() + " Ratio: " + param1 + "% Duration: " + param2 + "min"); + temporaryBasal.percentRate = param1; + temporaryBasal.durationInMinutes = param2; + MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); + break; + case DanaRPump.TEMPSTOP: + log.debug("EVENT TEMPSTOP (" + recordCode + ") " + datetime.toLocaleString()); + MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); + break; + case DanaRPump.EXTENDEDSTART: + log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + extendedBolus.insulin = param1 / 100d; + extendedBolus.durationInMinutes = param2; + MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus); + break; + case DanaRPump.EXTENDEDSTOP: + log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus); + break; + case DanaRPump.BOLUS: + detailedBolusInfo.insulin = param1 / 100d; + boolean newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + break; + case DanaRPump.DUALBOLUS: + detailedBolusInfo.insulin = param1 / 100d; + newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + break; + case DanaRPump.DUALEXTENDEDSTART: + log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + extendedBolus.insulin = param1 / 100d; + extendedBolus.durationInMinutes = param2; + MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus); + break; + case DanaRPump.DUALEXTENDEDSTOP: + log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus); + break; + case DanaRPump.SUSPENDON: + log.debug("EVENT SUSPENDON (" + recordCode + ") " + datetime.toLocaleString()); + break; + case DanaRPump.SUSPENDOFF: + log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + datetime.toLocaleString()); + break; + case DanaRPump.REFILL: + log.debug("EVENT REFILL (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + break; + case DanaRPump.PRIME: + log.debug("EVENT PRIME (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + break; + case DanaRPump.PROFILECHANGE: + log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); + break; + case DanaRPump.CARBS: + DetailedBolusInfo emptyCarbsInfo = new DetailedBolusInfo(); + emptyCarbsInfo.carbs = param1; + emptyCarbsInfo.date = datetime.getTime(); + emptyCarbsInfo.source = Source.PUMP; + emptyCarbsInfo.pumpId = datetime.getTime(); + newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(emptyCarbsInfo); + log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g"); + break; + case DanaRPump.PRIMECANNULA: + log.debug("EVENT PRIME CANNULA(" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + break; + default: + log.debug("Event: " + recordCode + " " + datetime.toLocaleString() + " Param1: " + param1 + " Param2: " + param2); + break; + } + + if (datetime.getTime() > lastEventTimeLoaded) + lastEventTimeLoaded = datetime.getTime(); + } + + @Override + public String getFriendlyName() { + return "APS_HISTORY_EVENTS"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java new file mode 100644 index 0000000000..0f102090a7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java @@ -0,0 +1,77 @@ +package info.nightscout.androidaps.plugins.PumpDanaRS.comm; + +import com.cozmo.danar.util.BleCommandUtil; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.GregorianCalendar; + +import info.nightscout.androidaps.Config; + +public class DanaRS_Packet_APS_Set_Event_History extends DanaRS_Packet { + private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Set_Event_History.class); + + private int type; + private long time; + public int param1; + public int param2; + + public DanaRS_Packet_APS_Set_Event_History() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY; + } + + public DanaRS_Packet_APS_Set_Event_History(int type, long time, int param1, int param2) { + this(); + + this.type = type; + this.time = time; + this.param1 = param1; + this.param2 = param2; + } + + @Override + public byte[] getRequestParams() { + GregorianCalendar cal = new GregorianCalendar(); + cal.setTimeInMillis(time); + int year = cal.get(Calendar.YEAR) - 1900 - 100; + int month = cal.get(Calendar.MONTH) + 1; + int day = cal.get(Calendar.DAY_OF_MONTH); + int hour = cal.get(Calendar.HOUR_OF_DAY); + int min = cal.get(Calendar.MINUTE); + int sec = cal.get(Calendar.SECOND); + + byte[] request = new byte[11]; + request[0] = (byte) (type & 0xff); + request[1] = (byte) (year & 0xff); + request[2] = (byte) (month & 0xff); + request[3] = (byte) (day & 0xff); + request[4] = (byte) (hour & 0xff); + request[5] = (byte) (min & 0xff); + request[6] = (byte) (sec & 0xff); + request[7] = (byte) ((param1 >>> 8) & 0xff); + request[8] = (byte) (param1 & 0xff); + request[9] = (byte) ((param2 >>> 8) & 0xff); + request[10] = (byte) (param2 & 0xff); + return request; + } + + @Override + public void handleMessage(byte[] data) { + int result = intFromBuff(data, 0, 1); + if (result != 1) { + failed = true; + log.debug("Set history entry result: " + result + " FAILED!!!"); + } else { + if (Config.logDanaMessageDetail) + log.debug("Set history entry result: " + result); + } + } + + @Override + public String getFriendlyName() { + return "APS_SET_EVENT_HISTORY"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java index 543b41d8f5..e1fa03ea4f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java @@ -31,6 +31,8 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet; +import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_APS_History_Events; +import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_APS_Set_Event_History; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Basal_Get_Basal_Rate; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Basal_Get_Profile_Number; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Basal_Get_Temporary_Basal_State; @@ -169,11 +171,25 @@ public class DanaRSService extends Service { } public boolean loadEvents() { + DanaRS_Packet_APS_History_Events msg; + if (lastHistoryFetched == 0) { + msg = new DanaRS_Packet_APS_History_Events(0); + log.debug("Loading complete event history"); + } else { + msg = new DanaRS_Packet_APS_History_Events(lastHistoryFetched); + log.debug("Loading event history from: " + new Date(lastHistoryFetched).toLocaleString()); + } + bleComm.sendMessage(msg); + while (!msg.done && bleComm.isConnected()) { + SystemClock.sleep(100); + } + SystemClock.sleep(200); + lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded; return true; } - public boolean bolus(double insulin, int carbs, long l, Treatment t) { + public boolean bolus(double insulin, int carbs, long carbtime, Treatment t) { bolusingTreatment = t; int speed = SP.getInt(R.string.key_danars_bolusspeed, 0); DanaRS_Packet_Bolus_Set_Step_Bolus_Start start = new DanaRS_Packet_Bolus_Set_Step_Bolus_Start(insulin, speed); @@ -185,9 +201,9 @@ public class DanaRSService extends Service { if (carbs > 0) { // MsgSetCarbsEntry msg = new MsgSetCarbsEntry(carbtime, carbs); #### // bleComm.sendMessage(msg); -// MsgSetHistoryEntry_v2 msgSetHistoryEntry_v2 = new MsgSetHistoryEntry_v2(DanaRPump.CARBS, carbtime, carbs, 0); -// bleComm.sendMessage(msgSetHistoryEntry_v2); -// lastHistoryFetched = carbtime - 60000; + DanaRS_Packet_APS_Set_Event_History msgSetHistoryEntry_v2 = new DanaRS_Packet_APS_Set_Event_History(DanaRPump.CARBS, carbtime, carbs, 0); + bleComm.sendMessage(msgSetHistoryEntry_v2); + lastHistoryFetched = carbtime - 60000; } if (insulin > 0) { DanaRS_Packet_Notify_Delivery_Rate_Display progress = new DanaRS_Packet_Notify_Delivery_Rate_Display(insulin, t); // initialize static variables