- all files kotlinized

- started some refactoring
- added adrians refactoring of MedtronicCommunicationManager
This commit is contained in:
Andy Rozman 2021-04-24 19:11:01 +01:00
parent 08a5c50037
commit 28c0f1b894
17 changed files with 1409 additions and 1835 deletions

View file

@ -2,6 +2,6 @@ package info.nightscout.androidaps.db
interface DbObjectBase { interface DbObjectBase {
val date: Long fun getDate(): Long
val pumpId: Long fun getPumpId(): Long
} }

View file

@ -12,9 +12,6 @@ android {
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
} }
dataBinding {
enabled = true
}
} }
dependencies { dependencies {

View file

@ -364,13 +364,13 @@ class MedtronicPumpPlugin @Inject constructor(
} }
MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.RemainingInsulin -> { MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.RemainingInsulin -> {
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
refreshTypesNeededToReschedule.add(key) refreshTypesNeededToReschedule.add(key)
resetTime = true resetTime = true
} }
MedtronicStatusRefreshType.Configuration -> { MedtronicStatusRefreshType.Configuration -> {
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
resetTime = true resetTime = true
} }
} }
@ -415,7 +415,7 @@ class MedtronicPumpPlugin @Inject constructor(
// model (once) // model (once)
if (medtronicUtil.medtronicPumpModel == null) { if (medtronicUtil.medtronicPumpModel == null) {
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.PumpModel) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel)
} else { } else {
if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) { if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) {
aapsLogger.warn(LTag.PUMP, logPrefix + "Configured pump is not the same as one detected.") aapsLogger.warn(LTag.PUMP, logPrefix + "Configured pump is not the same as one detected.")
@ -429,19 +429,19 @@ class MedtronicPumpPlugin @Inject constructor(
readPumpHistory() readPumpHistory()
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m) // remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetRemainingInsulin) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin)
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10) scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10)
// remaining power (1h) // remaining power (1h)
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetBatteryStatus) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus)
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20) scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20)
// configuration (once and then if history shows config changes) // configuration (once and then if history shows config changes)
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(getSettings(medtronicUtil.medtronicPumpModel)) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(getSettings(medtronicUtil.medtronicPumpModel))
// read profile (once, later its controlled by isThisProfileSet method) // read profile (once, later its controlled by isThisProfileSet method)
basalProfiles basalProfiles
val errorCount = rileyLinkMedtronicService!!.medtronicUIComm!!.invalidResponsesCount val errorCount = rileyLinkMedtronicService!!.medtronicUIComm.invalidResponsesCount
if (errorCount >= 5) { if (errorCount >= 5) {
aapsLogger.error("Number of error counts was 5 or more. Starting tunning.") aapsLogger.error("Number of error counts was 5 or more. Starting tunning.")
setRefreshButtonEnabled(true) setRefreshButtonEnabled(true)
@ -461,9 +461,9 @@ class MedtronicPumpPlugin @Inject constructor(
private val basalProfiles: Unit private val basalProfiles: Unit
private get() { private get() {
val medtronicUITask = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetBasalProfileSTD) val medtronicUITask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
if (medtronicUITask.responseType === MedtronicUIResponseType.Error) { if (medtronicUITask.responseType === MedtronicUIResponseType.Error) {
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetBasalProfileSTD) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
} }
} }
@ -492,7 +492,7 @@ class MedtronicPumpPlugin @Inject constructor(
for (basalValue in profile.basalValues) { for (basalValue in profile.basalValues) {
val basalValueValue = pumpDescription.pumpType.determineCorrectBasalSize(basalValue.value) val basalValueValue = pumpDescription.pumpType.determineCorrectBasalSize(basalValue.value)
val hour = basalValue.timeAsSeconds / (60 * 60) val hour = basalValue.timeAsSeconds / (60 * 60)
if (!isSame(basalsByHour[hour]!!, basalValueValue)) { if (!isSame(basalsByHour[hour], basalValueValue)) {
invalid = true invalid = true
} }
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue)) stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
@ -551,10 +551,10 @@ class MedtronicPumpPlugin @Inject constructor(
return return
} }
medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus) medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus)
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetRealTimeClock) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
var clock = medtronicUtil.pumpTime var clock = medtronicUtil.pumpTime
if (clock == null) { // retry if (clock == null) { // retry
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetRealTimeClock) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
clock = medtronicUtil.pumpTime clock = medtronicUtil.pumpTime
} }
if (clock == null) return if (clock == null) return
@ -562,7 +562,7 @@ class MedtronicPumpPlugin @Inject constructor(
if (timeDiff > 20) { if (timeDiff > 20) {
if (clock.localDeviceTime!!.year <= 2015 || timeDiff <= 24 * 60 * 60) { if (clock.localDeviceTime!!.year <= 2015 || timeDiff <= 24 * 60 * 60) {
aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is %d s. Set time on pump.", timeDiff)) aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is %d s. Set time on pump.", timeDiff))
rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.SetRealTimeClock) rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock)
if (clock.timeDifference == 0) { if (clock.timeDifference == 0) {
val notification = Notification(Notification.INSIGHT_DATE_TIME_UPDATED, resourceHelper.gs(R.string.pump_time_updated), Notification.INFO, 60) val notification = Notification(Notification.INSIGHT_DATE_TIME_UPDATED, resourceHelper.gs(R.string.pump_time_updated), Notification.INFO, 60)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
@ -611,8 +611,8 @@ class MedtronicPumpPlugin @Inject constructor(
bolusDeliveryType = BolusDeliveryType.Delivering bolusDeliveryType = BolusDeliveryType.Delivering
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery"); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.SetBolus, val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus,
Arrays.asList(detailedBolusInfo.insulin)) arrayListOf(detailedBolusInfo.insulin))
val response = responseTask.result as Boolean? val response = responseTask.result as Boolean?
setRefreshButtonEnabled(true) setRefreshButtonEnabled(true)
@ -621,12 +621,7 @@ class MedtronicPumpPlugin @Inject constructor(
if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) { if (bolusDeliveryType == BolusDeliveryType.CancelDelivery) {
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled after Bolus started."); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Delivery Canceled after Bolus started.");
Thread(Runnable { Thread(Runnable {
// Looper.prepare();
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Show dialog - before");
SystemClock.sleep(2000) SystemClock.sleep(2000)
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Show dialog. Context: "
// + MainApp.instance().getApplicationContext());
runAlarm(context, resourceHelper.gs(R.string.medtronic_cmd_cancel_bolus_not_supported), resourceHelper.gs(R.string.medtronic_warning), R.raw.boluserror) runAlarm(context, resourceHelper.gs(R.string.medtronic_cmd_cancel_bolus_not_supported), resourceHelper.gs(R.string.medtronic_warning), R.raw.boluserror)
}).start() }).start()
} }
@ -743,7 +738,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - TBR running - so canceling it.") aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - TBR running - so canceling it.")
// CANCEL // CANCEL
val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.CancelTBR) val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR)
val response = responseTask2.result as Boolean? val response = responseTask2.result as Boolean?
if (response!!) { if (response!!) {
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.") aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.")
@ -756,8 +751,8 @@ class MedtronicPumpPlugin @Inject constructor(
} }
// now start new TBR // now start new TBR
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.SetTemporaryBasal, val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal,
Arrays.asList(absoluteRate, durationInMinutes)) arrayListOf(absoluteRate, durationInMinutes))
val response = responseTask.result as Boolean? val response = responseTask.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - setTBR. Response: " + response) aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - setTBR. Response: " + response)
return if (response!!) { return if (response!!) {
@ -853,7 +848,7 @@ class MedtronicPumpPlugin @Inject constructor(
} else { } else {
// LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime); // LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime);
if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: " + lastPumpHistoryEntryTime + " - targetDate: " + targetDate) if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "readPumpHistoryLogic(): lastPumpHistoryEntryTime: " + lastPumpHistoryEntryTime + " - targetDate: " + targetDate)
medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntryTime) //medtronicHistoryData.setLastHistoryRecordTime(lastPumpHistoryEntryTime)
var lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime) var lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime)
lastHistoryRecordTime = lastHistoryRecordTime.minusHours(12) // we get last 12 hours of history to lastHistoryRecordTime = lastHistoryRecordTime.minusHours(12) // we get last 12 hours of history to
// determine pump state // determine pump state
@ -873,8 +868,8 @@ class MedtronicPumpPlugin @Inject constructor(
} }
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate); //aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.GetHistoryData, val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData,
Arrays.asList(lastPumpHistoryEntry, targetDate) as List<Any>?) arrayListOf(lastPumpHistoryEntry, targetDate) as ArrayList<Any>?)
if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: After task") if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: After task")
val historyResult = responseTask2.result as PumpHistoryResult? val historyResult = responseTask2.result as PumpHistoryResult?
if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString()) if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString())
@ -971,7 +966,7 @@ class MedtronicPumpPlugin @Inject constructor(
} }
private fun readTBR(): TempBasalPair? { private fun readTBR(): TempBasalPair? {
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.ReadTemporaryBasal) val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal)
return if (responseTask.hasData()) { return if (responseTask.hasData()) {
val tbr = responseTask.result as TempBasalPair? val tbr = responseTask.result as TempBasalPair?
@ -1009,7 +1004,7 @@ class MedtronicPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(false).enacted(false) return PumpEnactResult(injector).success(false).enacted(false)
.comment(R.string.medtronic_cmd_cant_read_tbr) .comment(R.string.medtronic_cmd_cant_read_tbr)
} }
val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.CancelTBR) val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR)
val response = responseTask2.result as Boolean? val response = responseTask2.result as Boolean?
finishAction("TBR") finishAction("TBR")
return if (response!!) { return if (response!!) {
@ -1070,8 +1065,8 @@ class MedtronicPumpPlugin @Inject constructor(
.enacted(false) // .enacted(false) //
.comment(resourceHelper.gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid)) .comment(resourceHelper.gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid))
} }
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm!!.executeCommand(MedtronicCommandType.SetBasalProfileSTD, val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetBasalProfileSTD,
Arrays.asList(basalProfile)) arrayListOf(basalProfile))
val response = responseTask.result as Boolean? val response = responseTask.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "Basal Profile was set: " + response) aapsLogger.info(LTag.PUMP, logPrefix + "Basal Profile was set: " + response)
return if (response!!) { return if (response!!) {

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm
import android.os.SystemClock import android.os.SystemClock
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException
@ -64,7 +65,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
private var doWakeUpBeforeCommand = true private var doWakeUpBeforeCommand = true
@Inject @Inject
open fun onInit(): Unit { fun onInit(): Unit {
// we can't do this in the constructor, as sp only gets injected after the constructor has returned // we can't do this in the constructor, as sp only gets injected after the constructor has returned
medtronicPumpStatus.previousConnection = sp.getLong( medtronicPumpStatus.previousConnection = sp.getLong(
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L) RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L)
@ -133,8 +134,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
} else { } else {
// radioResponse.rssi; // radioResponse.rssi;
val dataResponse = medtronicConverter!!.convertResponse(medtronicPumpStatus.pumpType, MedtronicCommandType.PumpModel, val dataResponse = medtronicConverter.decodeModel(pumpResponse.rawContent)
pumpResponse.rawContent)
val pumpModel = dataResponse as MedtronicDeviceType? val pumpModel = dataResponse as MedtronicDeviceType?
val valid = pumpModel !== MedtronicDeviceType.Unknown_Device val valid = pumpModel !== MedtronicDeviceType.Unknown_Device
if (medtronicUtil.medtronicPumpModel == null && valid) { if (medtronicUtil.medtronicPumpModel == null && valid) {
@ -350,11 +350,11 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
return when (type) { return when (type) {
RLMessageType.PowerOn -> medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.RFPowerOn, byteArrayOf(2, 1, receiverDeviceAwakeForMinutes.toByte())) // maybe this is better FIXME RLMessageType.PowerOn -> medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.RFPowerOn, byteArrayOf(2, 1, receiverDeviceAwakeForMinutes.toByte())) // maybe this is better FIXME
RLMessageType.ReadSimpleData -> medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.PumpModel, null) RLMessageType.ReadSimpleData -> medtronicUtil.buildCommandPayload(rileyLinkServiceData, MedtronicCommandType.PumpModel, null)
else -> ByteArray(0)
} }
return ByteArray(0)
} }
private fun makePumpMessage(messageType: MedtronicCommandType, body: ByteArray? = null as ByteArray?): PumpMessage { private fun makePumpMessage(messageType: MedtronicCommandType, body: ByteArray? = null): PumpMessage {
return makePumpMessage(messageType, body?.let { CarelinkShortMessageBody(it) } return makePumpMessage(messageType, body?.let { CarelinkShortMessageBody(it) }
?: CarelinkShortMessageBody()) ?: CarelinkShortMessageBody())
} }
@ -400,14 +400,21 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
return super.sendAndListen(msg, timeout_ms)!! return super.sendAndListen(msg, timeout_ms)!!
} }
private fun sendAndGetResponseWithCheck(commandType: MedtronicCommandType, bodyData: ByteArray? = null): Any? { private inline fun <reified T> sendAndGetResponseWithCheck(
commandType: MedtronicCommandType,
bodyData: ByteArray? = null,
decode: (pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray?) -> T
): T? {
aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: $commandType") aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: $commandType")
for (retries in 0 until MAX_COMMAND_TRIES) { for (retries in 0 until MAX_COMMAND_TRIES) {
try { try {
val response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + DEFAULT_TIMEOUT * retries) val response = sendAndGetResponse(commandType, bodyData, DEFAULT_TIMEOUT + DEFAULT_TIMEOUT * retries)
val check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength) val check = checkResponseContent(response, commandType.commandDescription, commandType.expectedLength)
if (check == null) { if (check == null) {
val dataResponse = medtronicConverter.convertResponse(medtronicPumpStatus.pumpType, commandType, response.rawContent)
checkResponseRawContent(response.rawContent, commandType) { return@sendAndGetResponseWithCheck null }
val dataResponse = decode(medtronicPumpStatus.pumpType, commandType, response.rawContent)
if (dataResponse != null) { if (dataResponse != null) {
errorResponse = null errorResponse = null
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, dataResponse)) aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, dataResponse))
@ -426,6 +433,16 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
return null return null
} }
private inline fun checkResponseRawContent(rawContent: ByteArray?, commandType: MedtronicCommandType, errorCase: () -> Unit) {
if (rawContent?.isEmpty() != false && commandType != MedtronicCommandType.PumpModel) {
aapsLogger.warn(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Content is empty or too short, no data to convert (type=%s,isNull=%b,length=%s)",
commandType.name, rawContent == null, rawContent?.size ?: "-"))
errorCase.invoke()
} else {
aapsLogger.debug(LTag.PUMPCOMM, "Raw response before convert: " + ByteUtil.shortHexString(rawContent))
}
}
// private fun <T> sendAndGetResponseWithCheck(commandType: MedtronicCommandType, bodyData: ByteArray, clazz: Class<T>): T? { // private fun <T> sendAndGetResponseWithCheck(commandType: MedtronicCommandType, bodyData: ByteArray, clazz: Class<T>): T? {
// aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: $commandType") // aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: $commandType")
// for (retries in 0 until MAX_COMMAND_TRIES) { // for (retries in 0 until MAX_COMMAND_TRIES) {
@ -479,13 +496,15 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
// PUMP SPECIFIC COMMANDS // PUMP SPECIFIC COMMANDS
fun getRemainingInsulin(): Double? { fun getRemainingInsulin(): Double? {
val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRemainingInsulin) return sendAndGetResponseWithCheck(MedtronicCommandType.GetRemainingInsulin) { _, _, rawContent ->
return if (responseObject == null) null else responseObject as Double? medtronicConverter.decodeRemainingInsulin(rawContent)
}
} }
fun getPumpModel(): MedtronicDeviceType? { fun getPumpModel(): MedtronicDeviceType? {
val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.PumpModel) return sendAndGetResponseWithCheck(MedtronicCommandType.PumpModel) { _, _, rawContent ->
return if (responseObject == null) null else responseObject as MedtronicDeviceType? medtronicConverter.decodeModel(rawContent)
}
} }
@ -531,7 +550,12 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
} else { } else {
errorResponse = check errorResponse = check
} }
val basalProfile = medtronicConverter.convertResponse(medtronicPumpPlugin.pumpType, commandType, data) as BasalProfile?
var basalProfile: BasalProfile? = null
checkResponseRawContent(data, commandType) {
basalProfile = medtronicConverter.decodeBasalProfile(medtronicPumpPlugin.pumpDescription.pumpType, data)
}
if (basalProfile != null) { if (basalProfile != null) {
aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, basalProfile)) aapsLogger.debug(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Converted response for %s is %s.", commandType.name, basalProfile))
medtronicUtil.setCurrentCommand(null) medtronicUtil.setCurrentCommand(null)
@ -568,22 +592,24 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
fun getPumpTime(): ClockDTO? { fun getPumpTime(): ClockDTO? {
val clockDTO = ClockDTO() val clockDTO = ClockDTO()
clockDTO.localDeviceTime = LocalDateTime() clockDTO.localDeviceTime = LocalDateTime()
val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRealTimeClock) val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetRealTimeClock) { _, _, rawContent ->
medtronicConverter.decodeTime(rawContent)
}
if (responseObject != null) { if (responseObject != null) {
clockDTO.pumpTime = responseObject as LocalDateTime? clockDTO.pumpTime = responseObject
return clockDTO return clockDTO
} }
return null return null
} }
fun getTemporaryBasal(): TempBasalPair? { fun getTemporaryBasal(): TempBasalPair? {
val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.ReadTemporaryBasal) return sendAndGetResponseWithCheck(MedtronicCommandType.ReadTemporaryBasal) { _, _, rawContent ->
return if (responseObject == null) null else responseObject as TempBasalPair? TempBasalPair(aapsLogger, rawContent!!) }
} }
fun getPumpSettings(): Map<String, PumpSettingDTO>? { fun getPumpSettings(): Map<String, PumpSettingDTO>? {
val responseObject = sendAndGetResponseWithCheck(getSettings(medtronicUtil.medtronicPumpModel)) return sendAndGetResponseWithCheck(getSettings(medtronicUtil.medtronicPumpModel)) { _, _, rawContent ->
return if (responseObject == null) null else responseObject as Map<String, PumpSettingDTO>? medtronicConverter.decodeSettingsLoop(rawContent) }
} }
fun setBolus(units: Double): Boolean { fun setBolus(units: Double): Boolean {
@ -600,20 +626,32 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
val gc = GregorianCalendar() val gc = GregorianCalendar()
gc.add(Calendar.SECOND, 5) gc.add(Calendar.SECOND, 5)
aapsLogger.info(LTag.PUMPCOMM, "setPumpTime: " + DateTimeUtil.toString(gc)) aapsLogger.info(LTag.PUMPCOMM, "setPumpTime: " + DateTimeUtil.toString(gc))
val i = 1
val data = ByteArray(8)
data[0] = 7
data[i] = gc[Calendar.HOUR_OF_DAY].toByte()
data[i + 1] = gc[Calendar.MINUTE].toByte()
data[i + 2] = gc[Calendar.SECOND].toByte()
val yearByte = getByteArrayFromUnsignedShort(gc[Calendar.YEAR], true) val yearByte = getByteArrayFromUnsignedShort(gc[Calendar.YEAR], true)
data[i + 3] = yearByte[0] // val i = 1
data[i + 4] = yearByte[1] // val data = ByteArray(8)
data[i + 5] = (gc[Calendar.MONTH] + 1).toByte() // data[0] = 7
data[i + 6] = gc[Calendar.DAY_OF_MONTH].toByte() // data[i] = gc[Calendar.HOUR_OF_DAY].toByte()
// data[i + 1] = gc[Calendar.MINUTE].toByte()
// data[i + 2] = gc[Calendar.SECOND].toByte()
// val yearByte = getByteArrayFromUnsignedShort(gc[Calendar.YEAR], true)
// data[i + 3] = yearByte[0]
// data[i + 4] = yearByte[1]
// data[i + 5] = (gc[Calendar.MONTH] + 1).toByte()
// data[i + 6] = gc[Calendar.DAY_OF_MONTH].toByte()
val timeData = byteArrayOf(
7,
gc[Calendar.HOUR_OF_DAY].toByte(),
gc[Calendar.MINUTE].toByte(),
gc[Calendar.SECOND].toByte(),
yearByte[0],
yearByte[1],
(gc[Calendar.MONTH] + 1).toByte(),
gc[Calendar.DAY_OF_MONTH].toByte()
)
//aapsLogger.info(LTag.PUMPCOMM,"setPumpTime: Body: " + ByteUtil.getHex(data)); //aapsLogger.info(LTag.PUMPCOMM,"setPumpTime: Body: " + ByteUtil.getHex(data));
return setCommand(MedtronicCommandType.SetRealTimeClock, data) return setCommand(MedtronicCommandType.SetRealTimeClock, timeData)
} }
private fun setCommand(commandType: MedtronicCommandType, body: ByteArray): Boolean { private fun setCommand(commandType: MedtronicCommandType, body: ByteArray): Boolean {
@ -642,8 +680,9 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
} }
fun getRemainingBattery(): BatteryStatusDTO? { fun getRemainingBattery(): BatteryStatusDTO? {
val responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.GetBatteryStatus) return sendAndGetResponseWithCheck(MedtronicCommandType.GetBatteryStatus) { _, _, rawContent ->
return if (responseObject == null) null else responseObject as BatteryStatusDTO? medtronicConverter.decodeBatteryStatus(rawContent)
}
} }
fun setBasalProfile(basalProfile: BasalProfile): Boolean { fun setBasalProfile(basalProfile: BasalProfile): Boolean {

View file

@ -29,62 +29,62 @@ class MedtronicConverter @Inject constructor(
private val medtronicUtil: MedtronicUtil private val medtronicUtil: MedtronicUtil
) { ) {
fun convertResponse(pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray?): Any? { // fun convertResponse(pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray?): Any? {
if ((rawContent == null || rawContent.size < 1) && commandType != MedtronicCommandType.PumpModel) { // if ((rawContent == null || rawContent.size < 1) && commandType != MedtronicCommandType.PumpModel) {
aapsLogger.warn(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Content is empty or too short, no data to convert (type=%s,isNull=%b,length=%s)", // aapsLogger.warn(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Content is empty or too short, no data to convert (type=%s,isNull=%b,length=%s)",
commandType.name, rawContent == null, rawContent?.size ?: "-")) // commandType.name, rawContent == null, rawContent?.size ?: "-"))
return null // return null
} // }
aapsLogger.debug(LTag.PUMPCOMM, "Raw response before convert: " + ByteUtil.shortHexString(rawContent)) // aapsLogger.debug(LTag.PUMPCOMM, "Raw response before convert: " + ByteUtil.shortHexString(rawContent))
return when (commandType) { // return when (commandType) {
MedtronicCommandType.PumpModel -> { // MedtronicCommandType.PumpModel -> {
decodeModel(rawContent) // decodeModel(rawContent)
} // }
//
// MedtronicCommandType.GetRealTimeClock -> {
// decodeTime(rawContent)
// }
//
// MedtronicCommandType.GetRemainingInsulin -> {
// decodeRemainingInsulin(rawContent)
// }
//
// MedtronicCommandType.GetBatteryStatus -> {
// decodeBatteryStatus(rawContent) // 1
// }
//
// MedtronicCommandType.GetBasalProfileSTD, MedtronicCommandType.GetBasalProfileA, MedtronicCommandType.GetBasalProfileB -> {
// decodeBasalProfile(pumpType, rawContent)
// }
//
// MedtronicCommandType.ReadTemporaryBasal -> {
// TempBasalPair(aapsLogger, rawContent!!) // 5
// }
//
// MedtronicCommandType.Settings_512 -> {
// decodeSettingsLoop(rawContent)
// }
//
// MedtronicCommandType.Settings -> {
// decodeSettingsLoop(rawContent)
// }
//
// MedtronicCommandType.SetBolus -> {
// rawContent // 1
// }
//
// else -> {
// throw RuntimeException("Unsupported command Type: $commandType")
// }
// }
// }
MedtronicCommandType.GetRealTimeClock -> { fun decodeBasalProfile(pumpType: PumpType, rawContent: ByteArray?): BasalProfile? {
decodeTime(rawContent)
}
MedtronicCommandType.GetRemainingInsulin -> {
decodeRemainingInsulin(rawContent)
}
MedtronicCommandType.GetBatteryStatus -> {
decodeBatteryStatus(rawContent) // 1
}
MedtronicCommandType.GetBasalProfileSTD, MedtronicCommandType.GetBasalProfileA, MedtronicCommandType.GetBasalProfileB -> {
decodeBasalProfile(pumpType, rawContent)
}
MedtronicCommandType.ReadTemporaryBasal -> {
TempBasalPair(aapsLogger, rawContent!!) // 5
}
MedtronicCommandType.Settings_512 -> {
decodeSettingsLoop(rawContent)
}
MedtronicCommandType.Settings -> {
decodeSettingsLoop(rawContent)
}
MedtronicCommandType.SetBolus -> {
rawContent // 1
}
else -> {
throw RuntimeException("Unsupported command Type: $commandType")
}
}
}
private fun decodeBasalProfile(pumpType: PumpType, rawContent: ByteArray?): BasalProfile? {
val basalProfile = BasalProfile(aapsLogger, rawContent!!) val basalProfile = BasalProfile(aapsLogger, rawContent!!)
return if (basalProfile.verify(pumpType)) basalProfile else null return if (basalProfile.verify(pumpType)) basalProfile else null
} }
private fun decodeModel(rawContent: ByteArray?): MedtronicDeviceType { fun decodeModel(rawContent: ByteArray?): MedtronicDeviceType {
if (rawContent == null || rawContent.size < 4) { if (rawContent == null || rawContent.size < 4) {
aapsLogger.warn(LTag.PUMPCOMM, "Error reading PumpModel, returning Unknown_Device") aapsLogger.warn(LTag.PUMPCOMM, "Error reading PumpModel, returning Unknown_Device")
return MedtronicDeviceType.Unknown_Device return MedtronicDeviceType.Unknown_Device
@ -100,7 +100,7 @@ class MedtronicConverter @Inject constructor(
return pumpModel return pumpModel
} }
private fun decodeBatteryStatus(rawData: ByteArray?): BatteryStatusDTO { fun decodeBatteryStatus(rawData: ByteArray?): BatteryStatusDTO {
// 00 7C 00 00 // 00 7C 00 00
val batteryStatus = BatteryStatusDTO() val batteryStatus = BatteryStatusDTO()
val status = rawData!![0].toInt() val status = rawData!![0].toInt()
@ -126,7 +126,7 @@ class MedtronicConverter @Inject constructor(
return batteryStatus return batteryStatus
} }
private fun decodeRemainingInsulin(rawData: ByteArray?): Double { public fun decodeRemainingInsulin(rawData: ByteArray?): Double {
var startIdx = 0 var startIdx = 0
val pumpModel = medtronicUtil.medtronicPumpModel val pumpModel = medtronicUtil.medtronicPumpModel
val strokes = pumpModel?.bolusStrokes ?: 10 val strokes = pumpModel?.bolusStrokes ?: 10
@ -134,7 +134,7 @@ class MedtronicConverter @Inject constructor(
startIdx = 2 startIdx = 2
} }
val reqLength = startIdx + 1 val reqLength = startIdx + 1
var value = 0.0 val value : Double
value = if (reqLength >= rawData!!.size) { value = if (reqLength >= rawData!!.size) {
rawData[startIdx] / (1.0 * strokes) rawData[startIdx] / (1.0 * strokes)
} else { } else {
@ -144,7 +144,7 @@ class MedtronicConverter @Inject constructor(
return value return value
} }
private fun decodeTime(rawContent: ByteArray?): LocalDateTime? { public fun decodeTime(rawContent: ByteArray?): LocalDateTime? {
val hours = ByteUtil.asUINT8(rawContent!![0]) val hours = ByteUtil.asUINT8(rawContent!![0])
val minutes = ByteUtil.asUINT8(rawContent[1]) val minutes = ByteUtil.asUINT8(rawContent[1])
val seconds = ByteUtil.asUINT8(rawContent[2]) val seconds = ByteUtil.asUINT8(rawContent[2])
@ -160,7 +160,7 @@ class MedtronicConverter @Inject constructor(
} }
} }
private fun decodeSettingsLoop(rd: ByteArray?): Map<String, PumpSettingDTO> { public fun decodeSettingsLoop(rd: ByteArray?): Map<String, PumpSettingDTO> {
val map: MutableMap<String, PumpSettingDTO> = HashMap() val map: MutableMap<String, PumpSettingDTO> = HashMap()
addSettingToMap("PCFG_MAX_BOLUS", "" + decodeMaxBolus(rd), PumpConfigurationGroup.Bolus, map) addSettingToMap("PCFG_MAX_BOLUS", "" + decodeMaxBolus(rd), PumpConfigurationGroup.Bolus, map)
addSettingToMap( addSettingToMap(

View file

@ -35,19 +35,19 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
// TODO_ extend this to also use bigger pages (for now we support only 1024 pages) // TODO_ extend this to also use bigger pages (for now we support only 1024 pages)
@Throws(RuntimeException::class) @Throws(RuntimeException::class)
private fun checkPage(page: RawHistoryPage, partial: Boolean): List<Byte> { private fun checkPage(page: RawHistoryPage, partial: Boolean): MutableList<Byte> {
val byteList: List<Byte> = ArrayList() //val byteList: MutableList<Byte> = mutableListOf()
if (medtronicUtil.medtronicPumpModel == null) { if (medtronicUtil.medtronicPumpModel == null) {
aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.") aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.")
return byteList return mutableListOf()
} }
return if (page.data.size != 1024) { return if (page.data.size != 1024) {
ByteUtil.getListFromByteArray(page.data) page.data.toMutableList()
} else if (page.isChecksumOK) { } else if (page.isChecksumOK) {
ByteUtil.getListFromByteArray(page.onlyData) page.onlyData.toMutableList()
} else { } else {
byteList mutableListOf()
} }
} }
@ -117,9 +117,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
return StringUtil.getFormatedValueUS(value, decimals) return StringUtil.getFormatedValueUS(value, decimals)
} }
private fun processPageAndCreateRecords(rawHistoryPage: RawHistoryPage, partial: Boolean): List<T> { private fun processPageAndCreateRecords(rawHistoryPage: RawHistoryPage, partial: Boolean): MutableList<T> {
val dataClear = checkPage(rawHistoryPage, partial) val dataClear = checkPage(rawHistoryPage, partial)
val records: List<T> = createRecords(dataClear) val records: MutableList<T> = createRecords(dataClear)
for (record in records) { for (record in records) {
decodeRecord(record) decodeRecord(record)
} }

View file

@ -6,5 +6,5 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm.history
interface MedtronicHistoryDecoderInterface<T> { interface MedtronicHistoryDecoderInterface<T> {
fun decodeRecord(record: T): RecordDecodeStatus? fun decodeRecord(record: T): RecordDecodeStatus?
fun createRecords(dataClear: List<Byte>): List<T> fun createRecords(dataClear: MutableList<Byte>): MutableList<T>
} }

View file

@ -63,11 +63,12 @@ class MedtronicCGMSHistoryDecoder : MedtronicHistoryDecoder<CGMSHistoryEntry>()
override fun postProcess() {} override fun postProcess() {}
override fun createRecords(dataClearInput: List<Byte>): List<CGMSHistoryEntry> { override fun createRecords(dataClearInput: MutableList<Byte>): MutableList<CGMSHistoryEntry> {
val dataClear = reverseList(dataClearInput, Byte::class.java) dataClearInput.reverse()
val dataClear = dataClearInput //reverseList(dataClearInput, Byte::class.java)
prepareStatistics() prepareStatistics()
var counter = 0 var counter = 0
val outList: MutableList<CGMSHistoryEntry> = ArrayList() val outList: MutableList<CGMSHistoryEntry> = mutableListOf()
// create CGMS entries (without dates) // create CGMS entries (without dates)
do { do {
@ -109,7 +110,8 @@ class MedtronicCGMSHistoryDecoder : MedtronicHistoryDecoder<CGMSHistoryEntry>()
outList.add(pe) outList.add(pe)
} }
} while (counter < dataClear.size) } while (counter < dataClear.size)
val reversedOutList = reverseList(outList, CGMSHistoryEntry::class.java) outList.reverse()
val reversedOutList = outList // reverseList(outList, CGMSHistoryEntry::class.java)
var timeStamp: Long? = null var timeStamp: Long? = null
var dateTime: LocalDateTime? = null var dateTime: LocalDateTime? = null
var getIndex = 0 var getIndex = 0
@ -119,7 +121,7 @@ class MedtronicCGMSHistoryDecoder : MedtronicHistoryDecoder<CGMSHistoryEntry>()
timeStamp = entry.atechDateTime timeStamp = entry.atechDateTime
dateTime = DateTimeUtil.toLocalDateTime(timeStamp!!) dateTime = DateTimeUtil.toLocalDateTime(timeStamp!!)
getIndex = 0 getIndex = 0
} else if (entry.entryType === CGMSHistoryEntryType.GlucoseSensorData) { } else if (entry.entryType == CGMSHistoryEntryType.GlucoseSensorData) {
getIndex++ getIndex++
if (dateTime != null) entry.setDateTime(dateTime, getIndex) if (dateTime != null) entry.setDateTime(dateTime, getIndex)
} else { } else {
@ -130,13 +132,13 @@ class MedtronicCGMSHistoryDecoder : MedtronicHistoryDecoder<CGMSHistoryEntry>()
return reversedOutList return reversedOutList
} }
private fun <E> reverseList(dataClearInput: List<E>, clazz: Class<E>): List<E> { // private fun <E> reverseList(dataClearInput: List<E>, clazz: Class<E>): List<E> {
val outList: MutableList<E> = ArrayList() // val outList: MutableList<E> = ArrayList()
for (i in dataClearInput.size - 1 downTo 1) { // for (i in dataClearInput.size - 1 downTo 1) {
outList.add(dataClearInput[i]) // outList.add(dataClearInput[i])
} // }
return outList // return outList
} // }
private fun parseMinutes(one: Int): Int { private fun parseMinutes(one: Int): Int {
return one and "0111111".toInt(2) return one and "0111111".toInt(2)

View file

@ -37,12 +37,12 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
private var tbrPreviousRecord: PumpHistoryEntry? = null private var tbrPreviousRecord: PumpHistoryEntry? = null
private var changeTimeRecord: PumpHistoryEntry? = null private var changeTimeRecord: PumpHistoryEntry? = null
override fun createRecords(dataClear: List<Byte>): List<PumpHistoryEntry> { override fun createRecords(dataClear: MutableList<Byte>): MutableList<PumpHistoryEntry> {
prepareStatistics() prepareStatistics()
var counter = 0 var counter = 0
var record = 0 var record = 0
var incompletePacket: Boolean var incompletePacket: Boolean
val outList: MutableList<PumpHistoryEntry> = ArrayList() val outList: MutableList<PumpHistoryEntry> = mutableListOf()
var skipped: String? = null var skipped: String? = null
if (dataClear.size == 0) { if (dataClear.size == 0) {
aapsLogger.error(LTag.PUMPBTCOMM, "Empty page.") aapsLogger.error(LTag.PUMPBTCOMM, "Empty page.")

View file

@ -6,16 +6,17 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
import javax.inject.Inject
/** /**
* Created by andy on 6/14/18. * Created by andy on 6/14/18.
*/ */
class MedtronicUIComm( class MedtronicUIComm @Inject constructor(
private val injector: HasAndroidInjector, private val injector: HasAndroidInjector,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val medtronicUtil: MedtronicUtil, private val medtronicUtil: MedtronicUtil,
private val medtronicUIPostprocessor: MedtronicUIPostprocessor, private val medtronicUIPostprocessor: MedtronicUIPostprocessor,
private val medtronicCommunicationManager: MedtronicCommunicationManager private val medtronicCommunicationManager: MedtronicCommunicationManager
) { ) {
fun executeCommand(commandType: MedtronicCommandType): MedtronicUITask { fun executeCommand(commandType: MedtronicCommandType): MedtronicUITask {
@ -23,7 +24,7 @@ class MedtronicUIComm(
} }
@Synchronized @Synchronized
fun executeCommand(commandType: MedtronicCommandType, parameters: List<Any>?): MedtronicUITask { fun executeCommand(commandType: MedtronicCommandType, parameters: ArrayList<Any>?): MedtronicUITask {
aapsLogger.info(LTag.PUMP, "Execute Command: " + commandType.name) aapsLogger.info(LTag.PUMP, "Execute Command: " + commandType.name)
val task = MedtronicUITask(injector, commandType, parameters) val task = MedtronicUITask(injector, commandType, parameters)

View file

@ -54,10 +54,10 @@ class BasalProfile {
private fun setRawData(data: ByteArray): Boolean { private fun setRawData(data: ByteArray): Boolean {
var dataInternal: ByteArray = data var dataInternal: ByteArray = data
if (dataInternal == null) { // if (dataInternal == null) {
aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!") // aapsLogger.error(LTag.PUMPCOMM, "setRawData: buffer is null!")
return false // return false
} // }
// if we have just one entry through all day it looks like just length 1 // if we have just one entry through all day it looks like just length 1
if (dataInternal.size == 1) { if (dataInternal.size == 1) {
@ -219,7 +219,7 @@ class BasalProfile {
fun generateRawDataFromEntries() { fun generateRawDataFromEntries() {
val outData: MutableList<Byte> = ArrayList() val outData: MutableList<Byte> = ArrayList()
for (profileEntry in listEntries!!) { for (profileEntry in listEntries!!) {
val strokes = MedtronicUtil.getBasalStrokes(profileEntry.rate, true) //val strokes = MedtronicUtil.getBasalStrokes(profileEntry.rate, true)
outData.add(profileEntry.rate_raw[0]) outData.add(profileEntry.rate_raw[0])
outData.add(profileEntry.rate_raw[1]) outData.add(profileEntry.rate_raw[1])
outData.add(profileEntry.startTime_raw) outData.add(profileEntry.startTime_raw)
@ -238,17 +238,17 @@ class BasalProfile {
aapsLogger.error(LTag.PUMPCOMM, " Error generating entries. Ex.: $ex", ex) aapsLogger.error(LTag.PUMPCOMM, " Error generating entries. Ex.: $ex", ex)
aapsLogger.error(LTag.PUMPCOMM, " rawBasalValues: " + ByteUtil.shortHexString(rawData)) aapsLogger.error(LTag.PUMPCOMM, " rawBasalValues: " + ByteUtil.shortHexString(rawData))
aapsLogger.error(LTag.PUMPCOMM, "=============================================================================") aapsLogger.error(LTag.PUMPCOMM, "=============================================================================")
//FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null); //FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
} }
val basalByHour = arrayOf<Double>()
if (entriesCopy == null || entriesCopy.size == 0) { if (entriesCopy == null || entriesCopy.size == 0) {
val basalByHour = arrayOfNulls<Double>(24)
for (i in 0..23) { for (i in 0..23) {
basalByHour[i] = 0.0 basalByHour[i] = 0.0
} }
return basalByHour as Array<Double> return basalByHour
} }
val basalByHour = arrayOfNulls<Double>(24)
for (i in entriesCopy.indices) { for (i in entriesCopy.indices) {
val current = entriesCopy[i] val current = entriesCopy[i]
var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1 var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
@ -264,13 +264,13 @@ class BasalProfile {
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour); // System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
for (j in currentTime until lastHour) { for (j in currentTime until lastHour) {
if (pumpType == null) // if (pumpType == null)
basalByHour[j] = current.rate // basalByHour[j] = current.rate
else // else
basalByHour[j] = pumpType.determineCorrectBasalSize(current.rate) basalByHour[j] = pumpType.determineCorrectBasalSize(current.rate)
} }
} }
return basalByHour as Array<Double> return basalByHour
} }
override fun toString(): String { override fun toString(): String {
@ -285,7 +285,7 @@ class BasalProfile {
} }
val profilesByHour = getProfilesByHour(pumpType) val profilesByHour = getProfilesByHour(pumpType)
for (aDouble in profilesByHour) { for (aDouble in profilesByHour) {
if (aDouble!! > 35.0) return false if (aDouble > 35.0) return false
} }
return true return true
} }
@ -296,7 +296,6 @@ class BasalProfile {
const val MAX_RAW_DATA_SIZE = 48 * 3 + 1 const val MAX_RAW_DATA_SIZE = 48 * 3 + 1
private const val DEBUG_BASALPROFILE = false private const val DEBUG_BASALPROFILE = false
// this asUINT8 should be combined with Record.asUINT8, and placed in a new util class.
private fun readUnsignedByte(b: Byte): Int { private fun readUnsignedByte(b: Byte): Int {
return if (b < 0) b + 256 else b.toInt() return if (b < 0) b + 256 else b.toInt()
} }

View file

@ -4,9 +4,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.R
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.MessageBody import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.MessageBody
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.PumpAckMessageBody import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.PumpAckMessageBody
import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.UnknownMessageBody import info.nightscout.androidaps.plugins.pump.medtronic.comm.message.UnknownMessageBody
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType.Companion.isSameDevice import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType.Companion.isSameDevice
import java.io.Serializable
import java.util.* import java.util.*
/** /**
@ -136,35 +134,14 @@ enum class MedtronicCommandType
companion object { companion object {
var mapByCode: MutableMap<Byte, MedtronicCommandType> = HashMap() var mapByCode: MutableMap<Byte, MedtronicCommandType> = HashMap()
private fun getDeviceTypesArray(vararg types: MedtronicDeviceType): HashMap<MedtronicDeviceType, String?> { // private fun getDeviceTypesArray(vararg types: MedtronicDeviceType): HashMap<MedtronicDeviceType, String?> {
val hashMap = HashMap<MedtronicDeviceType, String?>() // val hashMap = HashMap<MedtronicDeviceType, String?>()
for (type in types) { // for (type in types) {
hashMap[type] = null // hashMap[type] = null
}
return hashMap
}
// @JvmStatic
// fun getByteArray(vararg data: Int): ByteArray {
// val array = ByteArray(data.size)
// for (i in 0 until data.size) {
// array[i] = data[i].toByte()
// } // }
// return array // return hashMap
// } // }
// private fun getByteArray(vararg data: Int): ByteArray {
// val array = ByteArray(data.size)
// for (i in 0 until data.size) {
// array[i] = data[i].toByte()
// }
// return array
// }
private fun getIntArray(vararg data: Int): IntArray {
return data
}
fun getByCode(code: Byte): MedtronicCommandType? { fun getByCode(code: Byte): MedtronicCommandType? {
return if (mapByCode.containsKey(code)) { return if (mapByCode.containsKey(code)) {
mapByCode[code] mapByCode[code]
@ -203,7 +180,6 @@ enum class MedtronicCommandType
var maxRecords = 1 var maxRecords = 1
var resourceId: Int? = null var resourceId: Int? = null
private set private set
var command_type = 0
var allowedRetries = 2 var allowedRetries = 2
var maxAllowedTime = 2000 var maxAllowedTime = 2000
var parameterType: MinimedCommandParameterType? = null var parameterType: MinimedCommandParameterType? = null
@ -217,7 +193,7 @@ enum class MedtronicCommandType
} }
constructor(code: Int, description: String, devices: MedtronicDeviceType?, constructor(code: Int, description: String, devices: MedtronicDeviceType?,
parameterType: MinimedCommandParameterType?, cmd_params: ByteArray) : this(code, description, devices, parameterType, 0, 1, 0, 0, 11, 0) { parameterType: MinimedCommandParameterType?, cmd_params: ByteArray) : this(code, description, devices, parameterType) {
commandParameters = cmd_params commandParameters = cmd_params
commandParametersCount = cmd_params.size commandParametersCount = cmd_params.size
} }
@ -233,10 +209,14 @@ enum class MedtronicCommandType
} }
// NEW // NEW
constructor(code: Int, description: String, constructor(code: Int,
devices: MedtronicDeviceType?, // description: String,
parameterType: MinimedCommandParameterType?, recordLength: Int = 64, max_recs: Int = 1, expectedLength: Int = 0, devices: MedtronicDeviceType?, //
resourceId: Int? = null) { parameterType: MinimedCommandParameterType?,
recordLength: Int = 64,
max_recs: Int = 1,
expectedLength: Int = 0,
resourceId: Int? = null) {
commandCode = code.toByte() commandCode = code.toByte()
commandDescription = description commandDescription = description
this.devices = devices this.devices = devices
@ -252,25 +232,25 @@ enum class MedtronicCommandType
} }
} }
@Deprecated("") // @Deprecated("")
constructor(code: Int, description: String, devices: MedtronicDeviceType?, // // constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
parameterType: MinimedCommandParameterType?, recordLength: Int, max_recs: Int, addy: Int, // // parameterType: MinimedCommandParameterType?, recordLength: Int, max_recs: Int, addy: Int, //
addy_len: Int, cmd_type: Int, expectedLength: Int) { // addy_len: Int, cmd_type: Int, expectedLength: Int) {
commandCode = code.toByte() // commandCode = code.toByte()
commandDescription = description // commandDescription = description
//this.targetType = targetType; // //this.targetType = targetType;
this.devices = devices // this.devices = devices
this.recordLength = recordLength // this.recordLength = recordLength
maxRecords = max_recs // maxRecords = max_recs
command_type = cmd_type // command_type = cmd_type
commandParametersCount = 0 // commandParametersCount = 0
allowedRetries = 2 // allowedRetries = 2
this.parameterType = parameterType // this.parameterType = parameterType
this.expectedLength = expectedLength // this.expectedLength = expectedLength
if (this.parameterType == MinimedCommandParameterType.SubCommands) { // if (this.parameterType == MinimedCommandParameterType.SubCommands) {
minimalBufferSizeToStartReading = 200 // minimalBufferSizeToStartReading = 200
} // }
} // }
override fun toString(): String { override fun toString(): String {

View file

@ -16,28 +16,28 @@ enum class MedtronicDeviceType {
Medtronic_511("511"), // Medtronic_511("511"), //
Medtronic_512("512"), // Medtronic_512("512"), //
Medtronic_712("712"), // Medtronic_712("712"), //
Medtronic_512_712(Medtronic_512, Medtronic_712), // Medtronic_512_712(listOf(Medtronic_512, Medtronic_712)), //
Medtronic_515("515"), // Medtronic_515("515"), //
Medtronic_715("715"), // Medtronic_715("715"), //
Medtronic_515_715(Medtronic_515, Medtronic_715), // Medtronic_515_715(listOf(Medtronic_515, Medtronic_715)), //
Medtronic_522("522"), // Medtronic_522("522"), //
Medtronic_722("722"), // Medtronic_722("722"), //
Medtronic_522_722(Medtronic_522, Medtronic_722), // Medtronic_522_722(listOf(Medtronic_522, Medtronic_722)), //
Medtronic_523_Revel("523"), // Medtronic_523_Revel("523"), //
Medtronic_723_Revel("723"), // Medtronic_723_Revel("723"), //
Medtronic_554_Veo("554"), // Medtronic_554_Veo("554"), //
Medtronic_754_Veo("754"), // Medtronic_754_Veo("754"), //
Medtronic_512andHigher(Medtronic_512, Medtronic_712, Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), // Medtronic_512andHigher(listOf(Medtronic_512, Medtronic_712, Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo)), //
Medtronic_515andHigher(Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), // Medtronic_515andHigher(listOf(Medtronic_515, Medtronic_715, Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo)), //
Medtronic_522andHigher(Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), // Medtronic_522andHigher(listOf(Medtronic_522, Medtronic_722, Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo)), //
Medtronic_523andHigher(Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo), // Medtronic_523andHigher(listOf(Medtronic_523_Revel, Medtronic_723_Revel, Medtronic_554_Veo, Medtronic_754_Veo)), //
Medtronic_554andHigher(Medtronic_554_Veo, Medtronic_754_Veo), // Medtronic_554andHigher(listOf(Medtronic_554_Veo, Medtronic_754_Veo)), //
// //
All; All;
companion object { companion object {
var mapByDescription: MutableMap<String, MedtronicDeviceType>? = null var mapByDescription: MutableMap<String, MedtronicDeviceType> = mutableMapOf()
@JvmStatic @JvmStatic
fun isSameDevice(deviceWeCheck: MedtronicDeviceType, deviceSources: MedtronicDeviceType): Boolean { fun isSameDevice(deviceWeCheck: MedtronicDeviceType, deviceSources: MedtronicDeviceType): Boolean {
@ -52,20 +52,17 @@ enum class MedtronicDeviceType {
} }
fun getByDescription(desc: String): MedtronicDeviceType { fun getByDescription(desc: String): MedtronicDeviceType {
return if (mapByDescription==null) { return if (mapByDescription.containsKey(desc)) {
Unknown_Device mapByDescription[desc]!!
} else if (mapByDescription!!.containsKey(desc)) {
mapByDescription!![desc]!!
} else { } else {
Unknown_Device Unknown_Device
} }
} }
init { init {
mapByDescription = HashMap()
for (minimedDeviceType in values()) { for (minimedDeviceType in values()) {
if (!minimedDeviceType.isFamily) { if (!minimedDeviceType.isFamily && minimedDeviceType.pumpModel!=null) {
mapByDescription!![minimedDeviceType.pumpModel!!] = minimedDeviceType mapByDescription[minimedDeviceType.pumpModel!!] = minimedDeviceType
} }
} }
} }
@ -78,16 +75,20 @@ enum class MedtronicDeviceType {
// return isSameDevice(model, Medtronic_523andHigher); // return isSameDevice(model, Medtronic_523andHigher);
// } // }
val isFamily: Boolean val isFamily: Boolean
var familyMembers: Array<MedtronicDeviceType>? = null var familyMembers: List<MedtronicDeviceType>? = null
private set private set
constructor() {
isFamily = false
}
constructor(pumpModel: String?) { constructor(pumpModel: String?) {
isFamily = false isFamily = false
this.pumpModel = pumpModel this.pumpModel = pumpModel
} }
constructor(vararg familyMembers: MedtronicDeviceType) { constructor(familyMembers: List<MedtronicDeviceType>) {
this.familyMembers = familyMembers as Array<MedtronicDeviceType>? this.familyMembers = familyMembers
isFamily = true isFamily = true
} }

View file

@ -6,6 +6,7 @@ import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.MedtronicHistoryActivity import info.nightscout.androidaps.plugins.pump.medtronic.dialog.MedtronicHistoryActivity
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic
@ -22,6 +23,8 @@ abstract class MedtronicModule {
@ContributesAndroidInjector abstract fun medtronicCommunicationManagerProvider(): MedtronicCommunicationManager @ContributesAndroidInjector abstract fun medtronicCommunicationManagerProvider(): MedtronicCommunicationManager
@ContributesAndroidInjector abstract fun medtronicUITaskProvider(): MedtronicUITask @ContributesAndroidInjector abstract fun medtronicUITaskProvider(): MedtronicUITask
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic @ContributesAndroidInjector abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic
@ContributesAndroidInjector abstract fun medtronicUICommProvider(): MedtronicUIComm
companion object { companion object {
@Provides @Provides

View file

@ -17,9 +17,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.R import info.nightscout.androidaps.plugins.pump.medtronic.R
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIPostprocessor
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
import javax.inject.Inject import javax.inject.Inject
@ -34,13 +32,11 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
@Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin @Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin
@Inject lateinit var medtronicUtil: MedtronicUtil @Inject lateinit var medtronicUtil: MedtronicUtil
@Inject lateinit var medtronicUIPostprocessor: MedtronicUIPostprocessor
@Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus @Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus
@Inject lateinit var rfSpy: RFSpy @Inject lateinit var rfSpy: RFSpy
@Inject lateinit var medtronicCommunicationManager: MedtronicCommunicationManager @Inject lateinit var medtronicCommunicationManager: MedtronicCommunicationManager
@Inject lateinit var medtronicUIComm: MedtronicUIComm
var medtronicUIComm: MedtronicUIComm? = null
private set
private val mBinder: IBinder = LocalBinder() private val mBinder: IBinder = LocalBinder()
private var serialChanged = false private var serialChanged = false
private var frequencies: Array<String?>? = null private var frequencies: Array<String?>? = null
@ -82,7 +78,6 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
rileyLinkServiceData.rileyLinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "") rileyLinkServiceData.rileyLinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "")
rileyLinkServiceData.rileyLinkName = sp.getString(RileyLinkConst.Prefs.RileyLinkName, "") rileyLinkServiceData.rileyLinkName = sp.getString(RileyLinkConst.Prefs.RileyLinkName, "")
rfspy.startReader() rfspy.startReader()
medtronicUIComm = MedtronicUIComm(injector, aapsLogger, medtronicUtil, medtronicUIPostprocessor, medtronicCommunicationManager)
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed") aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed")
} }