diff --git a/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_HistoryTest.kt b/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_HistoryTest.kt index cdd68df473..2bbb735ac2 100644 --- a/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_HistoryTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_HistoryTest.kt @@ -20,6 +20,7 @@ class DanaRS_Packet_APS_Set_Event_HistoryTest : DanaRSTestBase() { it.dateUtil = dateUtil } if (it is DanaRS_Packet_APS_Set_Event_History) { + it.danaPump = danaPump } } } diff --git a/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_TimeTest.kt b/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_TimeTest.kt index 0cda0fa06c..3a1a8e1256 100644 --- a/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_TimeTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_TimeTest.kt @@ -34,7 +34,7 @@ class DanaRS_Packet_Option_Get_Pump_TimeTest : DanaRSTestBase() { putByteToArray(array, 5, 35) // second 35 packet.handleMessage(array) - Assert.assertEquals(DateTime(2019, 2, 4, 20, 11, 35).millis, danaPump.pumpTime) + Assert.assertEquals(DateTime(2019, 2, 4, 20, 11, 35).millis, danaPump.getPumpTime()) Assert.assertEquals("OPTION__GET_PUMP_TIME", packet.friendlyName) } } \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt index f99a68d472..600768548f 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/pump/danaR/comm/MsgSettingPumpTimeTest.kt @@ -25,6 +25,6 @@ class MsgSettingPumpTimeTest : DanaRTestBase() { packet.intFromBuff(bytes, 0, 1) ).time packet.handleMessage(bytes) - Assert.assertEquals(time, danaPump.pumpTime) + Assert.assertEquals(time, danaPump.getPumpTime()) } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/Profile.java b/core/src/main/java/info/nightscout/androidaps/data/Profile.java index dc8e08b0df..4aaa5848fb 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/core/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -100,6 +100,7 @@ public class Profile { } protected void init(JSONObject json, int percentage, int timeshift) { + if (json == null) return; units = null; dia = Constants.defaultDIA; timeZone = TimeZone.getDefault(); @@ -404,6 +405,10 @@ public class Profile { return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units); } + public double getIsfMgdlTimeFromMidnight(int timeAsSeconds) { + return toMgdl(getIsfTimeFromMidnight(timeAsSeconds), units); + } + public double getIsfTimeFromMidnight(int timeAsSeconds) { if (isf_v == null) isf_v = convertToSparseArray(isf); diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt index 33f92910ac..e06f924215 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt @@ -3,10 +3,11 @@ package info.nightscout.androidaps.dana import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.interfaces.ProfileStore import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.db.Treatment +import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.sharedPreferences.SP import org.json.JSONArray import org.json.JSONException @@ -49,8 +50,32 @@ class DanaPump @Inject constructor( var bleModel = "" // RS v3: like BPN-1.0.1 var isNewPump = true // R only , providing model info var password = -1 // R, RSv1 - var pumpTime: Long = 0 + + // time + private var pumpTime: Long = 0 + var zoneOffset: Int = 0 // i (hw 7+) + + fun setPumpTime(value: Long) { + pumpTime = value + } + + fun setPumpTime(value: Long, zoneOffset: Int) { + pumpTime = value + T.hours(zoneOffset.toLong()).msecs() + this.zoneOffset = zoneOffset + } + + fun resetPumpTime() { + pumpTime = 0 + } + + fun getPumpTime() = pumpTime + var hwModel = 0 + val usingUTC + get() = hwModel >= 7 + val profile24 + get() = hwModel >= 7 + var protocol = 0 var productCode = 0 var errorState: ErrorState = ErrorState.NONE @@ -90,8 +115,9 @@ class DanaPump @Inject constructor( var extendedBolusRemainingMinutes = 0 var extendedBolusDeliveredSoFar = 0.0 //RS only = 0.0 - // Profile + // Profile R,RSv1 var units = 0 + var activeProfile = 0 var easyBasalMode = 0 var basal48Enable = false var currentCIR = 0 @@ -107,7 +133,10 @@ class DanaPump @Inject constructor( var eveningCF = 0.0 var nightCIR = 0 var nightCF = 0.0 - var activeProfile = 0 + + // Profile I + var cf24 = Array(24) { 0.0 } + var cir24 = Array(24) { 0.0 } //var pumpProfiles = arrayOf>() var pumpProfiles: Array>? = null @@ -151,6 +180,8 @@ class DanaPump @Inject constructor( var bolusDone = false // success end var lastEventTimeLoaded: Long = 0 // timestamp of last received event + val lastKnownHistoryId: Int = 0 // hwver 7+, 1-2000 + fun createConvertedProfile(): ProfileStore? { pumpProfiles?.let { val json = JSONObject() @@ -165,18 +196,30 @@ class DanaPump @Inject constructor( json.put("store", store) profile.put("dia", Constants.defaultDIA) val carbratios = JSONArray() - carbratios.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCIR)) - carbratios.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCIR)) - carbratios.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCIR)) - carbratios.put(JSONObject().put("time", "14:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCIR)) - carbratios.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCIR)) + if (!profile24) { + carbratios.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCIR)) + carbratios.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCIR)) + carbratios.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCIR)) + carbratios.put(JSONObject().put("time", "14:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCIR)) + carbratios.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCIR)) + } else { // 24 values + for (i in 0..23) { + carbratios.put(JSONObject().put("time", String.format("%02d", i) + ":00").put("timeAsSeconds", i * 3600).put("value", cir24[i])) + } + } profile.put("carbratio", carbratios) val sens = JSONArray() - sens.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCF)) - sens.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCF)) - sens.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCF)) - sens.put(JSONObject().put("time", "17:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCF)) - sens.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCF)) + if (!profile24) { + sens.put(JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCF)) + sens.put(JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCF)) + sens.put(JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCF)) + sens.put(JSONObject().put("time", "17:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCF)) + sens.put(JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCF)) + } else { // 24 values + for (i in 0..23) { + sens.put(JSONObject().put("time", String.format("%02d", i) + ":00").put("timeAsSeconds", i * 3600).put("value", cf24[i])) + } + } profile.put("sens", sens) val basals = JSONArray() val basalValues = if (basal48Enable) 48 else 24 @@ -270,6 +313,7 @@ class DanaPump @Inject constructor( const val PROFILECHANGE = 13 const val CARBS = 14 const val PRIMECANNULA = 15 + const val TIMECHANGE = 16 // Dana R btModel const val DOMESTIC_MODEL = 0x01 diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt index be38978236..fd9c50fb48 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt @@ -44,6 +44,8 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { private fun isDanaR() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaR private fun isDanaRv2() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRv2 + var minBacklight = 1 + @Synchronized override fun onResume() { super.onResume() @@ -65,6 +67,8 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { save_user_options.setOnClickListener { onSaveClick() } + minBacklight = if (danaPump.hwModel < 7) 1 else 0 // Dana-i allows zero + aapsLogger.debug(LTag.PUMP, "UserOptionsLoaded:" + (System.currentTimeMillis() - danaPump.lastConnection) / 1000 + " s ago" + "\ntimeDisplayType:" + danaPump.timeDisplayType @@ -76,7 +80,7 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { + "\nlowReservoir:" + danaPump.lowReservoirRate) danar_screentimeout.setParams(danaPump.lcdOnTimeSec.toDouble(), 5.0, 240.0, 5.0, DecimalFormat("1"), false, save_user_options) - danar_backlight.setParams(danaPump.backlightOnTimeSec.toDouble(), 1.0, 60.0, 1.0, DecimalFormat("1"), false, save_user_options) + danar_backlight.setParams(danaPump.backlightOnTimeSec.toDouble(), minBacklight.toDouble(), 60.0, 1.0, DecimalFormat("1"), false, save_user_options) danar_shutdown.setParams(danaPump.shutdownHour.toDouble(), 0.0, 24.0, 1.0, DecimalFormat("1"), true, save_user_options) danar_lowreservoir.setParams(danaPump.lowReservoirRate.toDouble(), 10.0, 60.0, 10.0, DecimalFormat("10"), false, save_user_options) when (danaPump.beepAndAlarm) { @@ -136,7 +140,7 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { // step is 5 seconds, 5 to 240 danaPump.lcdOnTimeSec = min(max(danar_screentimeout.value.toInt() / 5 * 5, 5), 240) // 1 to 60 - danaPump.backlightOnTimeSec = min(max(danar_backlight.value.toInt(), 1), 60) + danaPump.backlightOnTimeSec = min(max(danar_backlight.value.toInt(), minBacklight), 60) danaPump.units = if (danar_units.isChecked) 1 else 0 diff --git a/dana/src/main/res/values/strings.xml b/dana/src/main/res/values/strings.xml index b0fe53ee25..bf26707ffc 100644 --- a/dana/src/main/res/values/strings.xml +++ b/dana/src/main/res/values/strings.xml @@ -42,6 +42,9 @@ Pump Battery Discharged Occlusion Empty reservoir + Check shaft + Basal max + Daily max Blood sugar measurement alert Remaining insulin level Missed bolus diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt index 5fffb9cf71..d8d216c16e 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingPumpTime.kt @@ -1,10 +1,7 @@ package info.nightscout.androidaps.danar.comm import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.dana.DanaPump -import info.nightscout.androidaps.utils.DateUtil import org.joda.time.DateTime import java.util.* @@ -27,10 +24,10 @@ class MsgSettingPumpTime( intFromBuff(bytes, 0, 1) ).millis aapsLogger.debug(LTag.PUMPCOMM, "Pump time: " + dateUtil.dateAndTimeString(time) + " Phone time: " + Date()) - danaPump.pumpTime = time + danaPump.setPumpTime(time) } override fun handleMessageNotReceived() { - danaPump.pumpTime = 0 + danaPump.resetPumpTime() } } \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt index 9280187622..84e0dffa09 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRSMessageHashTable.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.Profile import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -37,6 +38,7 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) put(DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information(injector)) put(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) + put(DanaRS_Packet_Bolus_Get_24_CIR_CF_Array(injector)) put(DanaRS_Packet_Bolus_Get_Dual_Bolus(injector)) put(DanaRS_Packet_Bolus_Get_Extended_Bolus(injector)) put(DanaRS_Packet_Bolus_Get_Extended_Bolus_State(injector)) @@ -45,6 +47,7 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Bolus_Set_Bolus_Option(injector)) put(DanaRS_Packet_Bolus_Set_Initial_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_CIR_CF_Array(injector)) + put(DanaRS_Packet_Bolus_Set_24_CIR_CF_Array(injector, Profile(injector, null))) put(DanaRS_Packet_Bolus_Set_Dual_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_Extended_Bolus(injector)) put(DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel(injector)) @@ -60,8 +63,10 @@ class DanaRSMessageHashTable @Inject constructor( put(DanaRS_Packet_Notify_Delivery_Rate_Display(injector)) put(DanaRS_Packet_Notify_Missed_Bolus_Alarm(injector)) put(DanaRS_Packet_Option_Get_Pump_Time(injector)) + put(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) put(DanaRS_Packet_Option_Get_User_Option(injector)) put(DanaRS_Packet_Option_Set_Pump_Time(injector)) + put(DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(injector)) put(DanaRS_Packet_Option_Set_User_Option(injector)) //put(new DanaRS_Packet_History_(injector)); put(DanaRS_Packet_History_Alarm(injector)) diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java index cf10a2d95c..87ff77d0e6 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet.java @@ -151,6 +151,29 @@ public class DanaRS_Packet { return ret; } + protected static int intFromBuffMsbLsb(byte[] b, int srcStart, int srcLength) { + int ret; + + switch (srcLength) { + case 1: + ret = b[DATA_START + srcStart] & 0x000000FF; + break; + case 2: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 1] & 0x000000FF); + break; + case 3: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 2] & 0x000000FF); + break; + case 4: + ret = ((b[DATA_START + srcStart] & 0x000000FF) << 24) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 2] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 3] & 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/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt index d2e8bbc3dd..6c351210be 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt @@ -18,6 +18,8 @@ import info.nightscout.androidaps.danars.encryption.BleEncryption import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import org.joda.time.DateTime +import org.joda.time.DateTimeZone import java.util.* import javax.inject.Inject @@ -34,59 +36,67 @@ open class DanaRS_Packet_APS_History_Events( @Inject lateinit var sp: SP @Inject lateinit var nsUpload: NSUpload - private var year = 0 - private var month = 0 - private var day = 0 - private var hour = 0 - private var min = 0 - private var sec = 0 - init { opCode = BleEncryption.DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS - val cal = GregorianCalendar() if (from > DateUtil.now()) { aapsLogger.debug(LTag.PUMPCOMM, "Asked to load from the future") from = 0 } - if (from != 0L) cal.timeInMillis = from else cal[2000, 0, 1, 0, 0] = 0 - year = cal[Calendar.YEAR] - 1900 - 100 - month = cal[Calendar.MONTH] + 1 - day = cal[Calendar.DAY_OF_MONTH] - hour = cal[Calendar.HOUR_OF_DAY] - min = cal[Calendar.MINUTE] - sec = cal[Calendar.SECOND] - aapsLogger.debug(LTag.PUMPCOMM, "Loading event history from: " + dateUtil.dateAndTimeString(cal.timeInMillis)) + aapsLogger.debug(LTag.PUMPCOMM, "Loading event history from: " + dateUtil.dateAndTimeString(from)) danaPump.historyDoneReceived = false } override fun getRequestParams(): ByteArray { + val date = + if (danaPump.usingUTC) DateTime(from).withZone(DateTimeZone.UTC) + else DateTime(from) val request = ByteArray(6) - request[0] = (year and 0xff).toByte() - request[1] = (month and 0xff).toByte() - request[2] = (day and 0xff).toByte() - request[3] = (hour and 0xff).toByte() - request[4] = (min and 0xff).toByte() - request[5] = (sec and 0xff).toByte() + if (from == 0L) { + request[0] = 0 + request[1] = 1 + request[2] = 1 + request[3] = 0 + request[4] = 0 + request[5] = 0 + } else { + request[0] = (date.year - 2000 and 0xff).toByte() + request[1] = (date.monthOfYear and 0xff).toByte() + request[2] = (date.dayOfMonth and 0xff).toByte() + request[3] = (date.hourOfDay and 0xff).toByte() + request[4] = (date.minuteOfHour and 0xff).toByte() + request[5] = (date.secondOfMinute and 0xff).toByte() + } return request } override fun handleMessage(data: ByteArray) { - val recordCode = intFromBuff(data, 0, 1).toByte() + var recordCode = intFromBuff(data, 0, 1).toByte() // Last record if (recordCode == 0xFF.toByte()) { danaPump.historyDoneReceived = true aapsLogger.debug(LTag.PUMPCOMM, "Last record received") return } - val datetime = dateTimeSecFromBuff(data, 1) // 6 bytes - val param1 = (intFromBuff(data, 7, 1) shl 8 and 0xFF00) + (intFromBuff(data, 8, 1) and 0xFF) - val param2 = (intFromBuff(data, 9, 1) shl 8 and 0xFF00) + (intFromBuff(data, 10, 1) and 0xFF) - val temporaryBasal = TemporaryBasal(injector).date(datetime).source(Source.PUMP).pumpId(datetime) - val extendedBolus = ExtendedBolus(injector).date(datetime).source(Source.PUMP).pumpId(datetime) + val datetime: Long + val param1 = intFromBuffMsbLsb(data, 7, 2) + val param2 = intFromBuffMsbLsb(data, 9, 2) + val pumpId: Long + var id = 0 + if (!danaPump.usingUTC) { + datetime = dateTimeSecFromBuff(data, 1) // 6 bytes + pumpId = datetime + } else { + datetime = intFromBuffMsbLsb(data, 3, 4) * 1000L + recordCode = intFromBuff(data, 2, 1).toByte() + id = intFromBuffMsbLsb(data, 0, 2) // range only 1-2000 + pumpId = datetime shl 16 + id + } + val temporaryBasal = TemporaryBasal(injector).date(datetime).source(Source.PUMP).pumpId(pumpId) + val extendedBolus = ExtendedBolus(injector).date(datetime).source(Source.PUMP).pumpId(pumpId) val status: String when (recordCode.toInt()) { DanaPump.TEMPSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT TEMPSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TEMPSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min") temporaryBasal.percentRate = param1 temporaryBasal.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryTempBasal(temporaryBasal) @@ -94,13 +104,13 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.TEMPSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT TEMPSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime)) + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TEMPSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime)) activePlugin.activeTreatments.addToHistoryTempBasal(temporaryBasal) status = "TEMPSTOP " + dateUtil.timeString(datetime) } DanaPump.EXTENDEDSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT EXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT EXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") extendedBolus.insulin = param1 / 100.0 extendedBolus.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) @@ -108,7 +118,7 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.EXTENDEDSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT EXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT EXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) status = "EXTENDEDSTOP " + dateUtil.timeString(datetime) } @@ -121,7 +131,7 @@ open class DanaRS_Packet_APS_History_Events( detailedBolusInfo.pumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") status = "BOLUS " + dateUtil.timeString(datetime) } @@ -133,12 +143,12 @@ open class DanaRS_Packet_APS_History_Events( detailedBolusInfo.pumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") status = "DUALBOLUS " + dateUtil.timeString(datetime) } DanaPump.DUALEXTENDEDSTART -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT DUALEXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT DUALEXTENDEDSTART (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U Duration: " + param2 + "min") extendedBolus.insulin = param1 / 100.0 extendedBolus.durationInMinutes = param2 activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) @@ -146,37 +156,37 @@ open class DanaRS_Packet_APS_History_Events( } DanaPump.DUALEXTENDEDSTOP -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Delivered: " + param1 / 100.0 + "U RealDuration: " + param2 + "min") activePlugin.activeTreatments.addToHistoryExtendedBolus(extendedBolus) status = "DUALEXTENDEDSTOP " + dateUtil.timeString(datetime) } DanaPump.SUSPENDON -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT SUSPENDON (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT SUSPENDON (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") status = "SUSPENDON " + dateUtil.timeString(datetime) } DanaPump.SUSPENDOFF -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT SUSPENDOFF (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT SUSPENDOFF (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")") status = "SUSPENDOFF " + dateUtil.timeString(datetime) } DanaPump.REFILL -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT REFILL (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT REFILL (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") if (sp.getBoolean(R.string.key_rs_loginsulinchange, true)) nsUpload.generateCareportalEvent(CareportalEvent.INSULINCHANGE, datetime, resourceHelper.gs(R.string.danarspump)) status = "REFILL " + dateUtil.timeString(datetime) } DanaPump.PRIME -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PRIME (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PRIME (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") if (sp.getBoolean(R.string.key_rs_logcanulachange, true)) nsUpload.generateCareportalEvent(CareportalEvent.SITECHANGE, datetime, resourceHelper.gs(R.string.danarspump)) status = "PRIME " + dateUtil.timeString(datetime) } DanaPump.PROFILECHANGE -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PROFILECHANGE (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + param2 / 100.0 + "U/h") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PROFILECHANGE (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + param2 / 100.0 + "U/h") status = "PROFILECHANGE " + dateUtil.timeString(datetime) } @@ -187,17 +197,23 @@ open class DanaRS_Packet_APS_History_Events( emptyCarbsInfo.source = Source.PUMP emptyCarbsInfo.pumpId = datetime val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false) - aapsLogger.debug(LTag.PUMPCOMM, (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g") status = "CARBS " + dateUtil.timeString(datetime) } DanaPump.PRIMECANNULA -> { - aapsLogger.debug(LTag.PUMPCOMM, "EVENT PRIMECANNULA(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT PRIMECANNULA(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100.0 + "U") status = "PRIMECANNULA " + dateUtil.timeString(datetime) } - else -> { - aapsLogger.debug(LTag.PUMPCOMM, "Event: " + recordCode + " " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2) + DanaPump.TIMECHANGE -> { + val oldDateTime = intFromBuffMsbLsb(data, 7, 4) * 1000L + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "EVENT TIMECHANGE(" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Previous: " + dateUtil.dateAndTimeString(oldDateTime)) + status = "TIMECHANGE " + dateUtil.timeString(datetime) + } + + else -> { + aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + "Event: " + recordCode + " " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2) status = "UNKNOWN " + dateUtil.timeString(datetime) } } diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt index 67d4643064..802eb09b56 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_Set_Event_History.kt @@ -1,9 +1,12 @@ package info.nightscout.androidaps.danars.comm import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danars.encryption.BleEncryption -import java.util.* +import info.nightscout.androidaps.logging.LTag +import org.joda.time.DateTime +import org.joda.time.DateTimeZone +import javax.inject.Inject class DanaRS_Packet_APS_Set_Event_History( injector: HasAndroidInjector, @@ -13,29 +16,26 @@ class DanaRS_Packet_APS_Set_Event_History( private var param2: Int ) : DanaRS_Packet(injector) { + @Inject lateinit var danaPump: DanaPump + init { opCode = BleEncryption.DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY - if ((packetType == info.nightscout.androidaps.dana.DanaPump.CARBS || packetType == info.nightscout.androidaps.dana.DanaPump.BOLUS) && param1 <= 0) this.param1 = 0 + if ((packetType == DanaPump.CARBS || packetType == DanaPump.BOLUS) && param1 <= 0) this.param1 = 0 aapsLogger.debug(LTag.PUMPCOMM, "Set history entry: " + dateUtil.dateAndTimeString(time) + " type: " + packetType + " param1: " + param1 + " param2: " + param2) } override fun getRequestParams(): ByteArray { - val cal = GregorianCalendar() - cal.timeInMillis = time - val year = cal[Calendar.YEAR] - 1900 - 100 - val month = cal[Calendar.MONTH] + 1 - val day = cal[Calendar.DAY_OF_MONTH] - val hour = cal[Calendar.HOUR_OF_DAY] - val min = cal[Calendar.MINUTE] - val sec = cal[Calendar.SECOND] + val date = + if (danaPump.usingUTC) DateTime(time).withZone(DateTimeZone.UTC) + else DateTime(time) val request = ByteArray(11) request[0] = (packetType and 0xff).toByte() - request[1] = (year and 0xff).toByte() - request[2] = (month and 0xff).toByte() - request[3] = (day and 0xff).toByte() - request[4] = (hour and 0xff).toByte() - request[5] = (min and 0xff).toByte() - request[6] = (sec and 0xff).toByte() + request[1] = (date.year - 2000 and 0xff).toByte() + request[2] = (date.monthOfYear and 0xff).toByte() + request[3] = (date.dayOfMonth and 0xff).toByte() + request[4] = (date.hourOfDay and 0xff).toByte() + request[5] = (date.minuteOfHour and 0xff).toByte() + request[6] = (date.secondOfMinute and 0xff).toByte() request[7] = (param1 ushr 8 and 0xff).toByte() request[8] = (param1 and 0xff).toByte() request[9] = (param2 ushr 8 and 0xff).toByte() diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt new file mode 100644 index 0000000000..5f8be76b2e --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Get_24_CIR_CF_Array.kt @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import javax.inject.Inject + +class DanaRS_Packet_Bolus_Get_24_CIR_CF_Array( + injector: HasAndroidInjector +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__GET_24_CIR_CF_ARRAY + aapsLogger.debug(LTag.PUMPCOMM, "New message") + } + + override fun handleMessage(data: ByteArray) { + danaPump.units = byteArrayToInt(getBytes(data, DATA_START, 1)) + for (i in 0 .. 23) { + val cf = byteArrayToInt(getBytes(data, DATA_START + 1 + 2 * i, 2)).toDouble() + val cir = if (danaPump.units == DanaPump.UNITS_MGDL) + byteArrayToInt(getBytes(data, DATA_START + 1 + 48 + 2 * i, 2)).toDouble() + else + byteArrayToInt(getBytes(data, DATA_START + 1 + 48 + 2 * i, 2)) / 100.0 + danaPump.cir24[i] = cir + danaPump.cf24[i] = cf + aapsLogger.debug(LTag.PUMPCOMM, "$i: CIR: $cir CF: $cf") + } + if (danaPump.units < 0 || danaPump.units > 1) failed = true + aapsLogger.debug(LTag.PUMPCOMM, "Pump units: " + if (danaPump.units == DanaPump.UNITS_MGDL) "MGDL" else "MMOL") + } + + override fun getFriendlyName(): String { + return "BOLUS__GET_24_ CIR_CF_ARRAY" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt new file mode 100644 index 0000000000..7a0e925ab6 --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Bolus_Set_24_CIR_CF_Array.kt @@ -0,0 +1,52 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.logging.LTag +import javax.inject.Inject + +class DanaRS_Packet_Bolus_Set_24_CIR_CF_Array( + injector: HasAndroidInjector, + private val profile: Profile? +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_24_CIR_CF_ARRAY + aapsLogger.debug(LTag.PUMPCOMM, "New message") + } + + override fun getRequestParams(): ByteArray { + val request = ByteArray(96) + profile ?: return request // profile is null only in hash table + val cfStart = 24 * 2 + for (i in 0..23) { + var isf = profile.getIsfMgdlTimeFromMidnight(i * 3600) + if (danaPump.units == DanaPump.UNITS_MMOL) isf *= 10 + val ic = profile.getIcTimeFromMidnight(i * 3600) * 100 + request[2 * i] = (isf.toInt() and 0xff).toByte() + request[2 * i] = (isf.toInt() ushr 8 and 0xff).toByte() + request[cfStart + 2 * i] = (ic.toInt() and 0xff).toByte() + request[cfStart + 2 * i] = (ic.toInt() ushr 8 and 0xff).toByte() + } + return request + } + + override fun handleMessage(data: ByteArray) { + val result = intFromBuff(data, 0, 1) + if (result == 0) { + aapsLogger.debug(LTag.PUMPCOMM, "Result OK") + failed = false + } else { + aapsLogger.error("Result Error: $result") + failed = true + } + } + + override fun getFriendlyName(): String { + return "BOLUS__SET_24_CIR_CF_ARRAY" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt index c5a0b40ceb..538d9b0bf7 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_History_.kt @@ -193,11 +193,15 @@ abstract class DanaRS_Packet_History_( val datetimewihtsec = DateTime(2000 + historyYear, historyMonth, historyDay, historyHour, historyMinute, historySecond) danaRHistoryRecord.recordDate = datetimewihtsec.millis var strAlarm = "None" - when (paramByte8.toInt()) { - 67 -> strAlarm = "Check" - 79 -> strAlarm = "Occlusion" - 66 -> strAlarm = "Low Battery" - 83 -> strAlarm = "Shutdown" + when (paramByte8) { + 'P'.toByte() -> strAlarm = "Basal Compare" + 'R'.toByte() -> strAlarm = "Empty Reservoir" + 'C'.toByte() -> strAlarm = "Check" + 'O'.toByte() -> strAlarm = "Occlusion" + 'M'.toByte() -> strAlarm = "Basal max" + 'D'.toByte() -> strAlarm = "Daily max" + 'B'.toByte() -> strAlarm = "Low Battery" + 'S'.toByte() -> strAlarm = "Shutdown" } danaRHistoryRecord.recordAlarm = strAlarm danaRHistoryRecord.recordValue = value * 0.01 diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt index fe94033ea8..f397179185 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Notify_Alarm.kt @@ -41,12 +41,18 @@ class DanaRS_Packet_Notify_Alarm( errorString = resourceHelper.gs(R.string.lowbattery) 0x06 -> // Basal Compare errorString = resourceHelper.gs(R.string.basalcompare) - 0x09 -> // Empty Reservoir - errorString = resourceHelper.gs(R.string.emptyreservoir) 0x07, 0xFF -> // Blood sugar measurement alert errorString = resourceHelper.gs(R.string.bloodsugarmeasurementalert) 0x08, 0xFE -> // Remaining insulin level errorString = resourceHelper.gs(R.string.remaininsulinalert) + 0x09 -> // Empty Reservoir + errorString = resourceHelper.gs(R.string.emptyreservoir) + 0x0A -> // Check shaft + errorString = resourceHelper.gs(R.string.checkshaft) + 0x0B -> // Basal MAX + errorString = resourceHelper.gs(R.string.basalmax) + 0x0C -> // Daily MAX + errorString = resourceHelper.gs(R.string.dailymax) 0xFD -> // Blood sugar check miss alarm errorString = resourceHelper.gs(R.string.missedbolus) } diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt index 1b1daf30b7..11659879e3 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_Time.kt @@ -19,31 +19,19 @@ class DanaRS_Packet_Option_Get_Pump_Time( } override fun handleMessage(data: ByteArray) { - var dataIndex = DATA_START - var dataSize = 1 - val year = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val month = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val day = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val hour = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val min = byteArrayToInt(getBytes(data, dataIndex, dataSize)) - dataIndex += dataSize - dataSize = 1 - val sec = byteArrayToInt(getBytes(data, dataIndex, dataSize)) + val year = byteArrayToInt(getBytes(data, DATA_START, 1)) + val month = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) + val day = byteArrayToInt(getBytes(data, DATA_START + 2, 1)) + val hour = byteArrayToInt(getBytes(data, DATA_START + 3, 1)) + val min = byteArrayToInt(getBytes(data, DATA_START + 4, 1)) + val sec = byteArrayToInt(getBytes(data, DATA_START + 5, 1)) val time = DateTime(2000 + year, month, day, hour, min, sec) - danaPump.pumpTime = time.millis + danaPump.setPumpTime(time.millis) aapsLogger.debug(LTag.PUMPCOMM, "Pump time " + dateUtil.dateAndTimeString(time.millis)) } override fun handleMessageNotReceived() { - danaPump.pumpTime = 0 + danaPump.resetPumpTime() } override fun getFriendlyName(): String { diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt new file mode 100644 index 0000000000..9f35fcb82c --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone.kt @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.dana.DanaPump +import info.nightscout.androidaps.danars.encryption.BleEncryption +import org.joda.time.DateTime +import javax.inject.Inject + +class DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone( + injector: HasAndroidInjector +) : DanaRS_Packet(injector) { + + @Inject lateinit var danaPump: DanaPump + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_OPTION__GET_PUMP_UTC_AND_TIME_ZONE + aapsLogger.debug(LTag.PUMPCOMM, "Requesting pump UTC time") + } + + override fun handleMessage(data: ByteArray) { + val year = byteArrayToInt(getBytes(data, DATA_START, 1)) + val month = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) + val day = byteArrayToInt(getBytes(data, DATA_START + 2, 1)) + val hour = byteArrayToInt(getBytes(data, DATA_START + 3, 1)) + val min = byteArrayToInt(getBytes(data, DATA_START + 4, 1)) + val sec = byteArrayToInt(getBytes(data, DATA_START + 5, 1)) + val zoneOffset = getBytes(data, DATA_START + 6, 1)[0].toInt() + val time = DateTime(2000 + year, month, day, hour, min, sec) + danaPump.setPumpTime(time.millis, zoneOffset) + aapsLogger.debug(LTag.PUMPCOMM, "Pump time ${dateUtil.dateAndTimeString(danaPump.getPumpTime())} ZoneOffset: $zoneOffset") + } + + override fun handleMessageNotReceived() { + danaPump.resetPumpTime() + } + + override fun getFriendlyName(): String { + return "OPTION__GET_PUMP_UTC_AND_TIMEZONE" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt new file mode 100644 index 0000000000..3fbf79a388 --- /dev/null +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone.kt @@ -0,0 +1,49 @@ +package info.nightscout.androidaps.danars.comm + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.danars.encryption.BleEncryption +import org.joda.time.DateTime +import org.joda.time.DateTimeZone + +class DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone( + injector: HasAndroidInjector, + private var time: Long = 0, + private var zoneOffset: Int = 0 +) : DanaRS_Packet(injector) { + + var error = 0 + + init { + opCode = BleEncryption.DANAR_PACKET__OPCODE_OPTION__SET_PUMP_UTC_AND_TIME_ZONE + aapsLogger.debug(LTag.PUMPCOMM, "Setting UTC pump time ${dateUtil.dateAndTimeString(time)} ZoneOffset: $zoneOffset") + } + + override fun getRequestParams(): ByteArray { + val date = DateTime(time).withZone(DateTimeZone.UTC) + val request = ByteArray(7) + request[0] = (date.year - 2000 and 0xff).toByte() + request[1] = (date.monthOfYear and 0xff).toByte() + request[2] = (date.dayOfMonth and 0xff).toByte() + request[3] = (date.hourOfDay and 0xff).toByte() + request[4] = (date.minuteOfHour and 0xff).toByte() + request[5] = (date.secondOfMinute and 0xff).toByte() + request[6] = zoneOffset.toByte() + return request + } + + override fun handleMessage(data: ByteArray) { + val result = intFromBuff(data, 0, 1) + if (result == 0) { + aapsLogger.debug(LTag.PUMPCOMM, "Result OK") + failed = false + } else { + aapsLogger.error("Result Error: $result") + failed = true + } + } + + override fun getFriendlyName(): String { + return "OPTION__SET_PUMP_UTC_AND_TIMEZONE" + } +} \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt b/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt index cb7a0dcfcd..f239525f85 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/di/DanaRSCommModule.kt @@ -25,6 +25,7 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Calculation_Information(): DanaRS_Packet_Bolus_Get_Calculation_Information @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information(): DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_CIR_CF_Array(): DanaRS_Packet_Bolus_Get_CIR_CF_Array + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_24_CIR_CF_Array(): DanaRS_Packet_Bolus_Get_24_CIR_CF_Array @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Dual_Bolus(): DanaRS_Packet_Bolus_Get_Dual_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Extended_Bolus(): DanaRS_Packet_Bolus_Get_Extended_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Get_Extended_Bolus_State(): DanaRS_Packet_Bolus_Get_Extended_Bolus_State @@ -33,6 +34,7 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Bolus_Option(): DanaRS_Packet_Bolus_Set_Bolus_Option @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Initial_Bolus(): DanaRS_Packet_Bolus_Set_Initial_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_CIR_CF_Array(): DanaRS_Packet_Bolus_Set_CIR_CF_Array + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_24_CIR_CF_Array(): DanaRS_Packet_Bolus_Set_24_CIR_CF_Array @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Dual_Bolus(): DanaRS_Packet_Bolus_Set_Dual_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Extended_Bolus(): DanaRS_Packet_Bolus_Set_Extended_Bolus @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel(): DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel @@ -76,4 +78,6 @@ abstract class DanaRSCommModule { @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_APS_Set_Event_History(): DanaRS_Packet_APS_Set_Event_History @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_General_Get_Shipping_Version(): DanaRS_Packet_General_Get_Shipping_Version @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Review_Get_Pump_Dec_Ratio(): DanaRS_Packet_Review_Get_Pump_Dec_Ratio + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(): DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone + @ContributesAndroidInjector abstract fun contributesDanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(): DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone } \ No newline at end of file diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java b/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java index 418881d6df..fbb441e223 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java +++ b/danars/src/main/java/info/nightscout/androidaps/danars/encryption/BleEncryption.java @@ -75,6 +75,8 @@ public class BleEncryption { public static final int DANAR_PACKET__OPCODE_BOLUS__SET_CIR_CF_ARRAY = 0x4F; public static final int DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_OPTION = 0x50; public static final int DANAR_PACKET__OPCODE_BOLUS__SET_BOLUS_OPTION = 0x51; + public static final int DANAR_PACKET__OPCODE_BOLUS__GET_24_CIR_CF_ARRAY = 0x52; + public static final int DANAR_PACKET__OPCODE_BOLUS__SET_24_CIR_CF_ARRAY = 0x53; public static final int DANAR_PACKET__OPCODE_BASAL__SET_TEMPORARY_BASAL = 0x60; public static final int DANAR_PACKET__OPCODE_BASAL__TEMPORARY_BASAL_STATE = 0x61; @@ -104,6 +106,12 @@ public class BleEncryption { // Easy Mode public static final int DANAR_PACKET__OPCODE_OPTION__GET_EASY_MENU_OPTION = 0x74; public static final int DANAR_PACKET__OPCODE_OPTION__SET_EASY_MENU_OPTION = 0x75; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_EASY_MENU_STATUS = 0x76; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_EASY_MENU_STATUS = 0x77; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_PUMP_UTC_AND_TIME_ZONE = 0x78; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_PUMP_UTC_AND_TIME_ZONE = 0x79; + public static final int DANAR_PACKET__OPCODE_OPTION__GET_PUMP_TIME_ZONE = 0x7A; + public static final int DANAR_PACKET__OPCODE_OPTION__SET_PUMP_TIME_ZONE = 0x7B; 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/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt b/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt index ad5023a849..b1f472decf 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/services/DanaRSService.kt @@ -43,6 +43,9 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers +import org.joda.time.DateTime +import org.joda.time.DateTimeZone +import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.abs import kotlin.math.min @@ -110,6 +113,21 @@ class DanaRSService : DaggerService() { fun readPumpStatus() { try { + val now = System.currentTimeMillis() + val pump = activePlugin.activePump + if (danaPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized) { + rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) + sendMessage(DanaRS_Packet_General_Get_Shipping_Information(injector)) // serial no + sendMessage(DanaRS_Packet_General_Get_Pump_Check(injector)) // firmware + sendMessage(DanaRS_Packet_Basal_Get_Profile_Number(injector)) + sendMessage(DanaRS_Packet_Bolus_Get_Bolus_Option(injector)) // isExtendedEnabled + sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal + sendMessage(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) // target + if (danaPump.profile24) sendMessage(DanaRS_Packet_Bolus_Get_24_CIR_CF_Array(injector)) + else sendMessage(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) + sendMessage(DanaRS_Packet_Option_Get_User_Option(injector)) // Getting user options + danaPump.lastSettingsRead = now + } rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpstatus))) sendMessage(DanaRS_Packet_General_Initial_Screen_Information(injector)) rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingextendedbolusstatus))) @@ -120,7 +138,6 @@ class DanaRSService : DaggerService() { sendMessage(DanaRS_Packet_Basal_Get_Temporary_Basal_State(injector)) danaPump.lastConnection = System.currentTimeMillis() val profile = profileFunction.getProfile() - val pump = activePlugin.activePump if (profile != null && abs(danaPump.currentBasal - profile.basal) >= pump.pumpDescription.basalStep) { rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal @@ -129,9 +146,10 @@ class DanaRSService : DaggerService() { } } rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumptime))) - sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) - var timeDiff = (danaPump.pumpTime - System.currentTimeMillis()) / 1000L - if (danaPump.pumpTime == 0L) { + if (danaPump.usingUTC) sendMessage(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) + else sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) + var timeDiff = (danaPump.getPumpTime() - System.currentTimeMillis()) / 1000L + if (danaPump.getPumpTime() == 0L) { // initial handshake was not successful // de-initialize pump danaPump.reset() @@ -139,19 +157,6 @@ class DanaRSService : DaggerService() { rxBus.send(EventInitializationChanged()) return } - val now = System.currentTimeMillis() - if (danaPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized) { - rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.gettingpumpsettings))) - sendMessage(DanaRS_Packet_General_Get_Shipping_Information(injector)) // serial no - sendMessage(DanaRS_Packet_General_Get_Pump_Check(injector)) // firmware - sendMessage(DanaRS_Packet_Basal_Get_Profile_Number(injector)) - sendMessage(DanaRS_Packet_Bolus_Get_Bolus_Option(injector)) // isExtendedEnabled - sendMessage(DanaRS_Packet_Basal_Get_Basal_Rate(injector)) // basal profile, basalStep, maxBasal - sendMessage(DanaRS_Packet_Bolus_Get_Calculation_Information(injector)) // target - sendMessage(DanaRS_Packet_Bolus_Get_CIR_CF_Array(injector)) - sendMessage(DanaRS_Packet_Option_Get_User_Option(injector)) // Getting user options - danaPump.lastSettingsRead = now - } aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds") if (abs(timeDiff) > 3) { if (abs(timeDiff) > 60 * 60 * 1.5) { @@ -170,15 +175,22 @@ class DanaRSService : DaggerService() { rxBus.send(EventInitializationChanged()) return } else { - if (danaPump.protocol >= 6) { + if (danaPump.usingUTC) { + val tz = DateTimeZone.getDefault() + val instant = DateTime.now().millis + val offsetInMilliseconds = tz.getOffset(instant).toLong() + val hours = TimeUnit.MILLISECONDS.toHours(offsetInMilliseconds).toInt() + sendMessage(DanaRS_Packet_Option_Set_Pump_UTC_And_TimeZone(injector, DateUtil.now(), hours)) + } else if (danaPump.protocol >= 6) { // can set seconds sendMessage(DanaRS_Packet_Option_Set_Pump_Time(injector, DateUtil.now())) } else { waitForWholeMinute() // Dana can set only whole minute // add 10sec to be sure we are over minute (will be cut off anyway) sendMessage(DanaRS_Packet_Option_Set_Pump_Time(injector, DateUtil.now() + T.secs(10).msecs())) } - sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) - timeDiff = (danaPump.pumpTime - System.currentTimeMillis()) / 1000L + if (danaPump.usingUTC) sendMessage(DanaRS_Packet_Option_Get_Pump_UTC_And_TimeZone(injector)) + else sendMessage(DanaRS_Packet_Option_Get_Pump_Time(injector)) + timeDiff = (danaPump.getPumpTime() - System.currentTimeMillis()) / 1000L aapsLogger.debug(LTag.PUMPCOMM, "Pump time difference: $timeDiff seconds") } }