- kotlin refactoring !!

This commit is contained in:
Andy Rozman 2021-05-22 23:46:32 +01:00
parent d0f46d6745
commit fb5ff409f8
22 changed files with 385 additions and 450 deletions

View file

@ -1,54 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.utils;
import java.util.Locale;
import info.nightscout.androidaps.interfaces.Profile;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
public class ProfileUtil {
public static String getProfileDisplayable(Profile profile, PumpType pumpType) {
StringBuilder stringBuilder = new StringBuilder();
for (Profile.ProfileValue basalValue : profile.getBasalValues()) {
double basalValueValue = pumpType.determineCorrectBasalSize(basalValue.getValue());
int hour = basalValue.getTimeAsSeconds() / (60 * 60);
stringBuilder.append((hour < 10 ? "0" : "") + hour + ":00");
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue));
stringBuilder.append(", ");
}
if (stringBuilder.length() > 3)
return stringBuilder.substring(0, stringBuilder.length() - 2);
else
return stringBuilder.toString();
}
public static String getBasalProfilesDisplayable(Profile.ProfileValue[] profiles, PumpType pumpType) {
StringBuilder stringBuilder = new StringBuilder();
for (Profile.ProfileValue basalValue : profiles) {
double basalValueValue = pumpType.determineCorrectBasalSize(basalValue.getValue());
int hour = basalValue.getTimeAsSeconds() / (60 * 60);
stringBuilder.append((hour < 10 ? "0" : "") + hour + ":00");
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue));
stringBuilder.append(", ");
}
if (stringBuilder.length() > 3)
return stringBuilder.substring(0, stringBuilder.length() - 2);
else
return stringBuilder.toString();
}
}

View file

@ -0,0 +1,81 @@
package info.nightscout.androidaps.plugins.pump.common.utils
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.Profile.ProfileValue
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import java.util.*
object ProfileUtil {
fun getProfileDisplayable(profile: Profile, pumpType: PumpType): String {
val stringBuilder = StringBuilder()
for (basalValue in profile.getBasalValues()) {
val basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value)
val hour = basalValue.timeAsSeconds / (60 * 60)
stringBuilder.append((if (hour < 10) "0" else "") + hour + ":00")
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
stringBuilder.append(", ")
}
return if (stringBuilder.length > 3) stringBuilder.substring(0, stringBuilder.length - 2) else stringBuilder.toString()
}
@JvmStatic
fun getBasalProfilesDisplayable(profiles: Array<ProfileValue>, pumpType: PumpType): String {
val stringBuilder = StringBuilder()
for (basalValue in profiles) {
val basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value)
val hour = basalValue.timeAsSeconds / (60 * 60)
stringBuilder.append((if (hour < 10) "0" else "") + hour + ":00")
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
stringBuilder.append(", ")
}
return if (stringBuilder.length > 3) stringBuilder.substring(0, stringBuilder.length - 2) else stringBuilder.toString()
}
@JvmStatic
fun getBasalProfilesDisplayableAsStringOfArray(profile: Profile, pumpType: PumpType): String? {
val stringBuilder = java.lang.StringBuilder()
// for (basalValue in profiles) {
// val basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value)
// val hour = basalValue.timeAsSeconds / (60 * 60)
// stringBuilder.append((if (hour < 10) "0" else "") + hour + ":00")
// stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
// stringBuilder.append(", ")
// }
// return if (stringBuilder.length > 3) stringBuilder.substring(0, stringBuilder.length - 2) else stringBuilder.toString()
var entriesCopy = profile.getBasalValues()
for (i in entriesCopy.indices) {
val current = entriesCopy[i]
// var currentTime = if (current.startTime_raw % 2 == 0) current.startTime_raw.toInt() else current.startTime_raw - 1
// currentTime = currentTime * 30 / 60
val currentTime = current.timeAsSeconds / (60 * 60)
var lastHour: Int
lastHour = if (i + 1 == entriesCopy.size) {
24
} else {
val basalProfileEntry = entriesCopy[i + 1]
//val rawTime = if (basalProfileEntry.startTime_raw % 2 == 0) basalProfileEntry.startTime_raw.toInt() else basalProfileEntry.startTime_raw - 1
//rawTime * 30 / 60
basalProfileEntry.timeAsSeconds / (60 * 60)
}
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
for (j in currentTime until lastHour) {
// if (pumpType == null)
// basalByHour[j] = current.rate
// else
//basalByHour[j] = pumpType.determineCorrectBasalSize(current.value)
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", pumpType.determineCorrectBasalSize(current.value)))
stringBuilder.append(" ")
}
}
return stringBuilder.toString().trim()
}
}

View file

@ -38,6 +38,7 @@ import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncEntriesCreator
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData
@ -102,12 +103,12 @@ class MedtronicPumpPlugin @Inject constructor(
injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers, pumpSync, pumpSyncStorage
), Pump, RileyLinkPumpDevice, PumpSyncEntriesCreator {
private var rileyLinkMedtronicService: RileyLinkMedtronicService? = null
private lateinit var rileyLinkMedtronicService: RileyLinkMedtronicService
// variables for handling statuses and history
private var firstRun = true
private var isRefresh = false
private val statusRefreshMap: MutableMap<MedtronicStatusRefreshType?, Long?> = HashMap()
private val statusRefreshMap: MutableMap<MedtronicStatusRefreshType, Long> = mutableMapOf()
private var isInitialized = false
private var lastPumpHistoryEntry: PumpHistoryEntry? = null
private val busyTimestamps: MutableList<Long> = ArrayList()
@ -119,19 +120,20 @@ class MedtronicPumpPlugin @Inject constructor(
serviceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) {
aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is disconnected")
rileyLinkMedtronicService = null
//rileyLinkMedtronicService = null
}
override fun onServiceConnected(name: ComponentName, service: IBinder) {
aapsLogger.debug(LTag.PUMP, "RileyLinkMedtronicService is connected")
val mLocalBinder = service as RileyLinkMedtronicService.LocalBinder
rileyLinkMedtronicService = mLocalBinder.serviceInstance
rileyLinkMedtronicService!!.verifyConfiguration()
isServiceSet = true
rileyLinkMedtronicService.verifyConfiguration()
Thread(Runnable {
for (i in 0..19) {
SystemClock.sleep(5000)
aapsLogger.debug(LTag.PUMP, "Starting Medtronic-RileyLink service")
if (rileyLinkMedtronicService!!.setNotInPreInit()) {
if (rileyLinkMedtronicService.setNotInPreInit()) {
break
}
}
@ -227,10 +229,9 @@ class MedtronicPumpPlugin @Inject constructor(
}
// Pump Plugin
private val isServiceSet: Boolean
get() = rileyLinkMedtronicService != null
private var isServiceSet: Boolean = false
override fun getRileyLinkService(): RileyLinkMedtronicService? {
override fun getRileyLinkService(): RileyLinkMedtronicService {
return rileyLinkMedtronicService
}
@ -292,12 +293,12 @@ class MedtronicPumpPlugin @Inject constructor(
override fun isConnected(): Boolean {
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnected")
return isServiceSet && rileyLinkMedtronicService!!.isInitialized
return isServiceSet && rileyLinkMedtronicService.isInitialized
}
override fun isConnecting(): Boolean {
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnecting")
return !isServiceSet || !rileyLinkMedtronicService!!.isInitialized
return !isServiceSet || !rileyLinkMedtronicService.isInitialized
}
override fun getPumpStatus(reason: String) {
@ -328,7 +329,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.")
return false
}
return !rileyLinkMedtronicService!!.deviceCommunicationManager.isDeviceReachable
return !rileyLinkMedtronicService.deviceCommunicationManager.isDeviceReachable
}
private fun refreshAnyStatusThatNeedsToBeRefreshed() {
@ -352,9 +353,9 @@ class MedtronicPumpPlugin @Inject constructor(
}
// execute
val refreshTypesNeededToReschedule: MutableSet<MedtronicStatusRefreshType?> = mutableSetOf()
val refreshTypesNeededToReschedule: MutableSet<MedtronicStatusRefreshType> = mutableSetOf()
for ((key, value) in statusRefresh!!) {
if (value!! > 0 && System.currentTimeMillis() > value) {
if (value > 0 && System.currentTimeMillis() > value) {
when (key) {
MedtronicStatusRefreshType.PumpHistory -> {
readPumpHistory()
@ -367,13 +368,13 @@ class MedtronicPumpPlugin @Inject constructor(
}
MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.RemainingInsulin -> {
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
refreshTypesNeededToReschedule.add(key)
resetTime = true
}
MedtronicStatusRefreshType.Configuration -> {
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
resetTime = true
}
}
@ -388,9 +389,9 @@ class MedtronicPumpPlugin @Inject constructor(
if (resetTime) medtronicPumpStatus.setLastCommunicationToNow()
}
private fun doWeHaveAnyStatusNeededRefereshing(statusRefresh: Map<MedtronicStatusRefreshType?, Long?>?): Boolean {
private fun doWeHaveAnyStatusNeededRefereshing(statusRefresh: Map<MedtronicStatusRefreshType, Long>?): Boolean {
for ((_, value) in statusRefresh!!) {
if (value!! > 0 && System.currentTimeMillis() > value) {
if (value > 0 && System.currentTimeMillis() > value) {
return true
}
}
@ -402,9 +403,9 @@ class MedtronicPumpPlugin @Inject constructor(
}
private fun initializePump(): Boolean {
if (rileyLinkMedtronicService == null) return false
if (!isServiceSet) return false
aapsLogger.info(LTag.PUMP, logPrefix + "initializePump - start")
rileyLinkMedtronicService!!.deviceCommunicationManager.setDoWakeUpBeforeCommand(false)
rileyLinkMedtronicService.deviceCommunicationManager.setDoWakeUpBeforeCommand(false)
setRefreshButtonEnabled(false)
if (isRefresh) {
if (isPumpNotReachable) {
@ -418,7 +419,7 @@ class MedtronicPumpPlugin @Inject constructor(
// model (once)
if (!medtronicUtil.isModelSet) {
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel)
} else {
if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) {
aapsLogger.warn(LTag.PUMP, logPrefix + "Configured pump is not the same as one detected.")
@ -432,19 +433,19 @@ class MedtronicPumpPlugin @Inject constructor(
readPumpHistory()
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin)
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10)
// remaining power (1h)
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus)
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20)
// 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)
basalProfiles
val errorCount = rileyLinkMedtronicService!!.medtronicUIComm.invalidResponsesCount
val errorCount = rileyLinkMedtronicService.medtronicUIComm.invalidResponsesCount
if (errorCount >= 5) {
aapsLogger.error("Number of error counts was 5 or more. Starting tunning.")
setRefreshButtonEnabled(true)
@ -464,9 +465,9 @@ class MedtronicPumpPlugin @Inject constructor(
private val basalProfiles: Unit
get() {
val medtronicUITask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
val medtronicUITask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
if (medtronicUITask.responseType === MedtronicUIResponseType.Error) {
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
}
}
@ -492,14 +493,16 @@ class MedtronicPumpPlugin @Inject constructor(
// int index = 0;
if (basalsByHour == null) return true // we don't want to set profile again, unless we are sure
val stringBuilder = StringBuilder("Requested Basals (h): ")
stringBuilder.append(ProfileUtil.getBasalProfilesDisplayableAsStringOfArray(profile, this.pumpType))
for (basalValue in profile.getBasalValues()) {
val basalValueValue = pumpDescription.pumpType.determineCorrectBasalSize(basalValue.value)
val hour = basalValue.timeAsSeconds / (60 * 60)
if (!isSame(basalsByHour[hour], basalValueValue)) {
invalid = true
}
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
stringBuilder.append(" ")
// stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
// stringBuilder.append(" ")
}
aapsLogger.debug(LTag.PUMP, stringBuilder.toString())
if (!invalid) {
@ -552,10 +555,10 @@ class MedtronicPumpPlugin @Inject constructor(
return
}
medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus)
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
var clock = medtronicUtil.pumpTime
if (clock == null) { // retry
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock)
clock = medtronicUtil.pumpTime
}
if (clock == null) return
@ -563,7 +566,7 @@ class MedtronicPumpPlugin @Inject constructor(
if (timeDiff > 20) {
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))
rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock)
if (clock.timeDifference == 0) {
val notification = Notification(Notification.INSIGHT_DATE_TIME_UPDATED, resourceHelper.gs(R.string.pump_time_updated), Notification.INFO, 60)
rxBus.send(EventNewNotification(notification))
@ -612,7 +615,7 @@ class MedtronicPumpPlugin @Inject constructor(
bolusDeliveryType = BolusDeliveryType.Delivering
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus,
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus,
arrayListOf(detailedBolusInfo.insulin))
val response = responseTask.result as Boolean?
setRefreshButtonEnabled(true)
@ -734,7 +737,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - TBR running - so canceling it.")
// CANCEL
val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR)
val responseTask2 = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR)
val response = responseTask2.result as Boolean?
if (response!!) {
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - Current TBR cancelled.")
@ -747,21 +750,18 @@ class MedtronicPumpPlugin @Inject constructor(
}
// now start new TBR
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal,
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal,
arrayListOf(absoluteRate, durationInMinutes))
val response = responseTask.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - setTBR. Response: " + response)
return if (response!!) {
return if (response == null || !response) {
finishAction("TBR")
PumpEnactResult(injector).success(false).enacted(false) //
.comment(R.string.medtronic_cmd_tbr_could_not_be_delivered)
} else {
medtronicPumpStatus.tempBasalStart = Date()
medtronicPumpStatus.tempBasalAmount = absoluteRate
medtronicPumpStatus.tempBasalLength = durationInMinutes
// val tempStart = TemporaryBasal(injector) //
// .date(System.currentTimeMillis()) //
// .duration(durationInMinutes) //
// .absolute(absoluteRate) //
// .source(Source.USER)
//
// activePlugin.activeTreatments.addToHistoryTempBasal(tempStart)
val tempData = PumpDbEntryTBR(absoluteRate, true, durationInMinutes, tbrType)
@ -771,10 +771,6 @@ class MedtronicPumpPlugin @Inject constructor(
finishAction("TBR")
PumpEnactResult(injector).success(true).enacted(true) //
.absolute(absoluteRate).duration(durationInMinutes)
} else {
finishAction("TBR")
PumpEnactResult(injector).success(false).enacted(false) //
.comment(R.string.medtronic_cmd_tbr_could_not_be_delivered)
}
}
@ -858,7 +854,7 @@ class MedtronicPumpPlugin @Inject constructor(
}
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
val responseTask2 = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData,
val responseTask2 = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData,
arrayListOf(/*lastPumpHistoryEntry*/ null, targetDate) as ArrayList<Any>?)
if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: After task")
val historyResult = responseTask2.result as PumpHistoryResult?
@ -932,10 +928,10 @@ class MedtronicPumpPlugin @Inject constructor(
@Synchronized
private fun workWithStatusRefresh(action: StatusRefreshAction, //
statusRefreshType: MedtronicStatusRefreshType?, //
time: Long?): Map<MedtronicStatusRefreshType?, Long?>? {
time: Long?): Map<MedtronicStatusRefreshType, Long>? {
return when (action) {
StatusRefreshAction.Add -> {
statusRefreshMap[statusRefreshType] = time
statusRefreshMap[statusRefreshType!!] = time!!
null
}
@ -955,7 +951,7 @@ class MedtronicPumpPlugin @Inject constructor(
}
private fun readTBR(): TempBasalPair? {
val responseTask = rileyLinkMedtronicService!!.medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal)
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal)
return if (responseTask.hasData()) {
val tbr = responseTask.result as TempBasalPair?
@ -993,7 +989,7 @@ class MedtronicPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(false).enacted(false)
.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?
finishAction("TBR")
return if (response!!) {
@ -1020,9 +1016,9 @@ class MedtronicPumpPlugin @Inject constructor(
val differenceTimeMin = Math.floor(differenceTime / (60.0 * 1000.0))
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "canceling running TBR - syncTemporaryBasalWithPumpId [date=%d, pumpId=%d, rate=%.2f U, duration=%d, pumpSerial=%s] - Result: %b",
runningTBR.date, runningTBR.pumpId!!,
runningTBR.date, runningTBR.pumpId,
tbrData.rate, differenceTimeMin.toInt(),
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
}
}
@ -1046,7 +1042,7 @@ class MedtronicPumpPlugin @Inject constructor(
}
override fun serialNumber(): String {
return medtronicPumpStatus.serialNumber!!
return medtronicPumpStatus.serialNumber
}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
@ -1077,15 +1073,15 @@ class MedtronicPumpPlugin @Inject constructor(
.enacted(false) //
.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,
arrayListOf(basalProfile))
val response = responseTask.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "Basal Profile was set: " + response)
return if (response!!) {
PumpEnactResult(injector).success(true).enacted(true)
} else {
PumpEnactResult(injector).success(response).enacted(response) //
return if (response == null || !response) {
PumpEnactResult(injector).success(false).enacted(false) //
.comment(R.string.medtronic_cmd_basal_profile_could_not_be_set)
} else {
PumpEnactResult(injector).success(true).enacted(true)
}
}
@ -1136,7 +1132,7 @@ class MedtronicPumpPlugin @Inject constructor(
val mcat = customActionType as MedtronicCustomActionType
when (mcat) {
MedtronicCustomActionType.WakeUpAndTune -> {
if (rileyLinkMedtronicService!!.verifyConfiguration()) {
if (rileyLinkMedtronicService.verifyConfiguration()) {
serviceTaskExecutor.startTask(WakeAndTuneTask(injector))
} else {
runAlarm(context, resourceHelper.gs(R.string.medtronic_error_operation_not_possible_no_configuration), resourceHelper.gs(R.string.medtronic_warning), R.raw.boluserror)

View file

@ -402,7 +402,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
private inline fun <reified T> sendAndGetResponseWithCheck(
commandType: MedtronicCommandType,
bodyData: ByteArray? = null,
decode: (pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray?) -> T
decode: (pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray) -> T
): T? {
aapsLogger.debug(LTag.PUMPCOMM, "getDataFromPump: $commandType")
for (retries in 0 until MAX_COMMAND_TRIES) {
@ -526,7 +526,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
// aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getRawContent()));
// aapsLogger.debug(LTag.PUMPCOMM,"1st Response: " + HexDump.toHexStringDisplayable(response.getMessageBody().getTxData()));
val check = checkResponseContent(response, commandType.commandDescription, 1)
var data: ByteArray? = null
var data: ByteArray = byteArrayOf()
if (check == null) {
data = response.rawContentOfFrame
val ackMsg = makePumpMessage(MedtronicCommandType.CommandACK, PumpAckMessageBody())
@ -572,13 +572,13 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
return null
}
private fun checkIfWeHaveMoreData(commandType: MedtronicCommandType, response: PumpMessage, data: ByteArray?): Boolean {
private fun checkIfWeHaveMoreData(commandType: MedtronicCommandType, response: PumpMessage, data: ByteArray): Boolean {
if (commandType === MedtronicCommandType.GetBasalProfileSTD || //
commandType === MedtronicCommandType.GetBasalProfileA || //
commandType === MedtronicCommandType.GetBasalProfileB) {
val responseRaw = response.rawContentOfFrame
val last = responseRaw.size - 1
aapsLogger.debug(LTag.PUMPCOMM, "Length: " + data!!.size)
aapsLogger.debug(LTag.PUMPCOMM, "Length: " + data.size)
if (data.size >= BasalProfile.MAX_RAW_DATA_SIZE) {
return false
}

View file

@ -27,63 +27,13 @@ class MedtronicConverter @Inject constructor(
private val medtronicUtil: MedtronicUtil
) {
// fun convertResponse(pumpType: PumpType, commandType: MedtronicCommandType, rawContent: ByteArray?): Any? {
// 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)",
// commandType.name, rawContent == null, rawContent?.size ?: "-"))
// return null
// }
// aapsLogger.debug(LTag.PUMPCOMM, "Raw response before convert: " + ByteUtil.shortHexString(rawContent))
// return when (commandType) {
// MedtronicCommandType.PumpModel -> {
// 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")
// }
// }
// }
fun decodeBasalProfile(pumpType: PumpType, rawContent: ByteArray?): BasalProfile? {
val basalProfile = BasalProfile(aapsLogger, rawContent!!)
fun decodeBasalProfile(pumpType: PumpType, rawContent: ByteArray): BasalProfile? {
val basalProfile = BasalProfile(aapsLogger, rawContent)
return if (basalProfile.verify(pumpType)) basalProfile else null
}
fun decodeModel(rawContent: ByteArray?): MedtronicDeviceType {
if (rawContent == null || rawContent.size < 4) {
fun decodeModel(rawContent: ByteArray): MedtronicDeviceType {
if (rawContent.size < 4) {
aapsLogger.warn(LTag.PUMPCOMM, "Error reading PumpModel, returning Unknown_Device")
return MedtronicDeviceType.Unknown_Device
}
@ -99,10 +49,10 @@ class MedtronicConverter @Inject constructor(
return pumpModel
}
fun decodeBatteryStatus(rawData: ByteArray?): BatteryStatusDTO {
fun decodeBatteryStatus(rawData: ByteArray): BatteryStatusDTO {
// 00 7C 00 00
val batteryStatus = BatteryStatusDTO()
val status = rawData!![0].toInt()
val status = rawData[0].toInt()
if (status == 0) {
batteryStatus.batteryStatusType = BatteryStatusDTO.BatteryStatusType.Normal
} else if (status == 1) {
@ -125,7 +75,7 @@ class MedtronicConverter @Inject constructor(
return batteryStatus
}
public fun decodeRemainingInsulin(rawData: ByteArray?): Double {
fun decodeRemainingInsulin(rawData: ByteArray): Double {
var startIdx = 0
val pumpModel = medtronicUtil.medtronicPumpModel
val strokes = pumpModel.bolusStrokes //?: 10
@ -134,7 +84,7 @@ class MedtronicConverter @Inject constructor(
}
val reqLength = startIdx + 1
val value: Double
value = if (reqLength >= rawData!!.size) {
value = if (reqLength >= rawData.size) {
rawData[startIdx] / (1.0 * strokes)
} else {
ByteUtil.toInt(rawData[startIdx], rawData[startIdx + 1]) / (1.0 * strokes)
@ -143,8 +93,8 @@ class MedtronicConverter @Inject constructor(
return value
}
public fun decodeTime(rawContent: ByteArray?): LocalDateTime? {
val hours = ByteUtil.asUINT8(rawContent!![0])
fun decodeTime(rawContent: ByteArray): LocalDateTime? {
val hours = ByteUtil.asUINT8(rawContent[0])
val minutes = ByteUtil.asUINT8(rawContent[1])
val seconds = ByteUtil.asUINT8(rawContent[2])
val year = (ByteUtil.asUINT8(rawContent[4]) and 0x3f) + 1984
@ -159,12 +109,12 @@ class MedtronicConverter @Inject constructor(
}
}
public fun decodeSettingsLoop(rd: ByteArray?): Map<String, PumpSettingDTO> {
public fun decodeSettingsLoop(rd: ByteArray): Map<String, PumpSettingDTO> {
val map: MutableMap<String, PumpSettingDTO> = HashMap()
addSettingToMap("PCFG_MAX_BOLUS", "" + decodeMaxBolus(rd), PumpConfigurationGroup.Bolus, map)
addSettingToMap(
"PCFG_MAX_BASAL", ""
+ decodeBasalInsulin(ByteUtil.makeUnsignedShort(rd!![settingIndexMaxBasal].toInt(),
+ decodeBasalInsulin(ByteUtil.makeUnsignedShort(rd[settingIndexMaxBasal].toInt(),
rd[settingIndexMaxBasal + 1].toInt())), PumpConfigurationGroup.Basal, map)
addSettingToMap("CFG_BASE_CLOCK_MODE", if (rd[settingIndexTimeDisplayFormat].toInt() == 0) "12h" else "24h",
PumpConfigurationGroup.General, map)
@ -301,9 +251,11 @@ class MedtronicConverter @Inject constructor(
private val settingIndexTimeDisplayFormat: Int
get() = if (is523orHigher()) 9 else 8
private fun decodeMaxBolus(ai: ByteArray?): Double {
return if (is523orHigher()) decodeBolusInsulin(ByteUtil.toInt(ai!![5], ai[6])) else decodeBolusInsulin(ByteUtil
.asUINT8(ai!![5]))
private fun decodeMaxBolus(ai: ByteArray): Double {
return if (is523orHigher())
decodeBolusInsulin(ByteUtil.toInt(ai[5], ai[6]))
else
decodeBolusInsulin(ByteUtil.asUINT8(ai[5]))
}
private fun is523orHigher(): Boolean {

View file

@ -6,7 +6,6 @@ import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil
import org.apache.commons.lang3.StringUtils
import java.util.*
/**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
@ -15,35 +14,21 @@ import java.util.*
*
* Author: Andy {andy.rozman@gmail.com}
*/
abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHistoryDecoderInterface<T> {
constructor(aapsLogger: AAPSLogger,
medtronicUtil: MedtronicUtil,
bitUtils: ByteUtil) {
this.aapsLogger = aapsLogger
this.medtronicUtil = medtronicUtil
this.bitUtils = bitUtils
}
var aapsLogger: AAPSLogger
var medtronicUtil: MedtronicUtil
var bitUtils: ByteUtil
abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?>(var aapsLogger: AAPSLogger,
var medtronicUtil: MedtronicUtil,
var bitUtils: ByteUtil) : MedtronicHistoryDecoderInterface<T> {
// STATISTICS (remove at later time or not)
protected var statisticsEnabled = true
protected var unknownOpCodes: MutableMap<Int, Int?>? = null
protected var mapStatistics: MutableMap<RecordDecodeStatus, MutableMap<String, String>>? = null
protected var unknownOpCodes: MutableMap<Int, Int?> = mutableMapOf()
protected var mapStatistics: MutableMap<RecordDecodeStatus, MutableMap<String, String>> = mutableMapOf()
// public abstract <E extends MedtronicHistoryEntry> Class<E> getHistoryEntryClass();
// public abstract RecordDecodeStatus decodeRecord(T record);
abstract fun postProcess()
protected abstract fun runPostDecodeTasks()
// TODO_ extend this to also use bigger pages (for now we support only 1024 pages)
@Throws(RuntimeException::class)
private fun checkPage(page: RawHistoryPage): MutableList<Byte> {
//val byteList: MutableList<Byte> = mutableListOf()
if (!medtronicUtil.isModelSet) {
aapsLogger.error(LTag.PUMPCOMM, "Device Type is not defined.")
return mutableListOf()
@ -69,36 +54,37 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
protected fun prepareStatistics() {
if (!statisticsEnabled) return
unknownOpCodes = HashMap()
mapStatistics = HashMap()
// unknownOpCodes = HashMap()
// mapStatistics = HashMap()
for (stat in RecordDecodeStatus.values()) {
(mapStatistics as HashMap<RecordDecodeStatus, MutableMap<String, String>>)[stat] = HashMap()
mapStatistics[stat] = hashMapOf()
//(mapStatistics as HashMap<RecordDecodeStatus, MutableMap<String, String>>)[stat] = hashMapOf()
}
}
protected fun addToStatistics(pumpHistoryEntry: MedtronicHistoryEntryInterface, status: RecordDecodeStatus?, opCode: Int?) {
if (!statisticsEnabled) return
if (opCode != null) {
if (!unknownOpCodes!!.containsKey(opCode)) {
unknownOpCodes!![opCode] = opCode
if (!unknownOpCodes.containsKey(opCode)) {
unknownOpCodes[opCode] = opCode
}
return
}
if (!mapStatistics!![status]!!.containsKey(pumpHistoryEntry.entryTypeName)) {
mapStatistics!![status]!!.put(pumpHistoryEntry.entryTypeName!!, "")
if (!mapStatistics[status]!!.containsKey(pumpHistoryEntry.entryTypeName)) {
mapStatistics[status]!!.put(pumpHistoryEntry.entryTypeName, "")
}
}
protected fun showStatistics() {
var sb = StringBuilder()
for ((key) in unknownOpCodes!!) {
for ((key) in unknownOpCodes) {
StringUtil.appendToStringBuilder(sb, "" + key, ", ")
}
aapsLogger.info(LTag.PUMPCOMM, "STATISTICS OF PUMP DECODE")
if (unknownOpCodes!!.size > 0) {
if (unknownOpCodes.size > 0) {
aapsLogger.warn(LTag.PUMPCOMM, "Unknown Op Codes: $sb")
}
for ((key, value) in mapStatistics!!) {
for ((key, value) in mapStatistics) {
sb = StringBuilder()
if (key !== RecordDecodeStatus.OK) {
if (value.size == 0) continue
@ -106,9 +92,9 @@ abstract class MedtronicHistoryDecoder<T : MedtronicHistoryEntry?> : MedtronicHi
StringUtil.appendToStringBuilder(sb, key1, ", ")
}
val spaces = StringUtils.repeat(" ", 14 - key.name.length)
aapsLogger.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s%s - %d. Elements: %s", key.name, spaces, value.size, sb.toString()))
aapsLogger.info(LTag.PUMPCOMM, " ${key.name}$spaces - ${value.size}. Elements: ${sb.toString()}")
} else {
aapsLogger.info(LTag.PUMPCOMM, String.format(Locale.ENGLISH, " %s - %d", key.name, value.size))
aapsLogger.info(LTag.PUMPCOMM, " ${key.name} - ${value.size}")
}
}
}

View file

@ -1,12 +1,9 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history
import android.util.Log
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType
import java.util.*
/**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
@ -17,17 +14,15 @@ import java.util.*
*/
abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
var rawData: List<Byte>? = null
get() = field
lateinit var rawData: List<Byte>
protected var sizes = IntArray(3)
get() = field
var head: ByteArray? = null
get() = field
lateinit var head: ByteArray
lateinit var datetime: ByteArray
lateinit var body: ByteArray
var datetime: ByteArray? = null
var body: ByteArray? = null
var id: Long = 0
set(value) {
field = value
@ -81,7 +76,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
abstract fun isEntryTypeSet(): Boolean
override fun setData(listRawData: List<Byte>, doNotProcess: Boolean) {
override fun setData(listRawData: MutableList<Byte>, doNotProcess: Boolean) {
rawData = listRawData
// System.out.println("Head: " + sizes[0] + ", dates: " + sizes[1] +
@ -89,28 +84,31 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
if (!doNotProcess) {
head = ByteArray(headLength - 1)
for (i in 1 until headLength) {
head!![i - 1] = listRawData[i]
head[i - 1] = listRawData[i]
}
if (dateTimeLength > 0) {
datetime = ByteArray(dateTimeLength)
var i = headLength
var j = 0
while (j < dateTimeLength) {
datetime!![j] = listRawData[i]
datetime[j] = listRawData[i]
i++
j++
}
}
} else
datetime = byteArrayOf()
if (bodyLength > 0) {
body = ByteArray(bodyLength)
var i = headLength + dateTimeLength
var j = 0
while (j < bodyLength) {
body!![j] = listRawData[i]
body[j] = listRawData[i]
i++
j++
}
}
} else
body = byteArrayOf()
}
return
}
@ -177,15 +175,15 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
sb.append("]")
return sb.toString()
}
if (head != null) {
if (head.size != 0) {
sb.append(", head=")
sb.append(ByteUtil.shortHexString(head))
}
if (datetime != null) {
if (datetime.size != 0) {
sb.append(", datetime=")
sb.append(ByteUtil.shortHexString(datetime))
}
if (body != null) {
if (body.size != 0) {
sb.append(", body=")
sb.append(ByteUtil.shortHexString(body))
}
@ -204,15 +202,15 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
abstract val toStringStart: String?
fun getRawDataByIndex(index: Int): Byte {
return rawData!![index]
return rawData[index]
}
fun getRawDataByIndexInt(index: Int): Int {
return rawData!![index].toInt()
return rawData[index].toInt()
}
fun getUnsignedRawDataByIndex(index: Int): Int {
return ByteUtil.convertUnsignedByteToInt(rawData!![index])
return ByteUtil.convertUnsignedByteToInt(rawData[index])
}
fun addDecodedData(key: String, value: Any) {
@ -220,7 +218,7 @@ abstract class MedtronicHistoryEntry : MedtronicHistoryEntryInterface {
}
fun toShortString(): String {
return if (head == null) {
return if (head.size != 0) {
"Unidentified record. "
} else {
"HistoryRecord: head=[" + ByteUtil.shortHexString(head) + "]"

View file

@ -5,7 +5,7 @@ package info.nightscout.androidaps.plugins.pump.medtronic.comm.history
*/
interface MedtronicHistoryEntryInterface {
val entryTypeName: String?
fun setData(listRawData: List<Byte>, doNotProcess: Boolean)
val entryTypeName: String
fun setData(listRawData: MutableList<Byte>, doNotProcess: Boolean)
val dateLength: Int
}

View file

@ -14,11 +14,11 @@ import org.joda.time.LocalDateTime
*/
class CGMSHistoryEntry : MedtronicHistoryEntry() {
var entryType: CGMSHistoryEntryType? = null
var entryType: CGMSHistoryEntryType = CGMSHistoryEntryType.UnknownOpCode
private set
override var opCode: Byte? = null // this is set only when we have unknown entry...
get() = if (field == null) entryType!!.code.toByte() else field
get() = if (field == null) entryType.code.toByte() else field
fun setEntryType(entryType: CGMSHistoryEntryType) {
this.entryType = entryType
@ -28,21 +28,21 @@ class CGMSHistoryEntry : MedtronicHistoryEntry() {
}
override val entryTypeName: String
get() = entryType!!.name
get() = entryType.name
override fun generatePumpId(): Long {
return if (entryType==null)
return if (entryType == null)
atechDateTime * 1000L
else
entryType!!.code + atechDateTime * 1000L
entryType.code + atechDateTime * 1000L
}
override fun isEntryTypeSet(): Boolean {
return entryType!=null
return entryType != CGMSHistoryEntryType.UnknownOpCode
}
override fun setData(listRawData: List<Byte>, doNotProcess: Boolean) {
if (entryType!!.schemaSet) {
override fun setData(listRawData: MutableList<Byte>, doNotProcess: Boolean) {
if (entryType.schemaSet) {
super.setData(listRawData, doNotProcess)
} else {
rawData = listRawData
@ -50,14 +50,14 @@ class CGMSHistoryEntry : MedtronicHistoryEntry() {
}
override val dateLength: Int
get() = entryType!!.dateLength
get() = entryType.dateLength
fun hasTimeStamp(): Boolean {
return entryType!!.hasDate()
return entryType.hasDate()
}
override val toStringStart: String
get() = ("CGMSHistoryEntry [type=" + StringUtils.rightPad(entryType!!.name, 18) + " ["
get() = ("CGMSHistoryEntry [type=" + StringUtils.rightPad(entryType.name, 18) + " ["
+ StringUtils.leftPad("" + opCode, 3) + ", 0x" + ByteUtil.getCorrectHexValue(opCode!!) + "]")
fun setDateTime(timeStamp: LocalDateTime, getIndex: Int) {

View file

@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.cgms
import java.util.*
/**
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
* management and modified/extended for AAPS.
@ -22,14 +20,19 @@ enum class CGMSHistoryEntryType(val code: Int, val description: String, val head
CalBGForGH(0x0e, "CalBGForGH',packet_size=5", 1, 4, 1, DateType.MinuteSpecific), //
SensorCalFactor(0x0f, "SensorCalFactor", 1, 4, 2, DateType.MinuteSpecific), //
Something10(0x10, "10-Something", 1, 4, 0, DateType.MinuteSpecific), //
Something19(0x13, "19-Something", 1, 0, 0, DateType.PreviousTimeStamp), GlucoseSensorData(0xFF, "GlucoseSensorData", 1, 0, 0, DateType.PreviousTimeStamp);
Something19(0x13, "19-Something", 1, 0, 0, DateType.PreviousTimeStamp), GlucoseSensorData(0xFF, "GlucoseSensorData", 1, 0, 0, DateType.PreviousTimeStamp),
UnknownOpCode(0xFF, "Unknown", 0, 0, 0, DateType.None);
companion object {
private val opCodeMap: MutableMap<Int, CGMSHistoryEntryType?> = HashMap()
@JvmStatic fun getByCode(opCode: Int): CGMSHistoryEntryType? {
return if (opCodeMap.containsKey(opCode)) {
opCodeMap[opCode]
} else None
private val opCodeMap: MutableMap<Int, CGMSHistoryEntryType> = mutableMapOf()
@JvmStatic
fun getByCode(opCode: Int): CGMSHistoryEntryType {
return if (opCodeMap.containsKey(opCode))
opCodeMap[opCode]!!
else
UnknownOpCode
}
init {

View file

@ -30,7 +30,7 @@ class MedtronicCGMSHistoryDecoder constructor(
return try {
decodeRecordInternal(record)
} catch (ex: Exception) {
aapsLogger.error(LTag.PUMPCOMM, " Error decoding: type={}, ex={}", record.entryType!!.name, ex.message, ex)
aapsLogger.error(LTag.PUMPCOMM, " Error decoding: type={}, ex={}", record.entryType.name, ex.message, ex)
RecordDecodeStatus.Error
}
}
@ -40,25 +40,30 @@ class MedtronicCGMSHistoryDecoder constructor(
parseDate(entry)
}
when (entry.entryType) {
CGMSHistoryEntryType.SensorPacket -> decodeSensorPacket(entry)
CGMSHistoryEntryType.SensorError -> decodeSensorError(entry)
CGMSHistoryEntryType.SensorDataLow -> decodeDataHighLow(entry, 40)
CGMSHistoryEntryType.SensorDataHigh -> decodeDataHighLow(entry, 400)
CGMSHistoryEntryType.SensorTimestamp -> decodeSensorTimestamp(entry)
CGMSHistoryEntryType.SensorCal -> decodeSensorCal(entry)
CGMSHistoryEntryType.SensorCalFactor -> decodeSensorCalFactor(entry)
CGMSHistoryEntryType.SensorSync -> decodeSensorSync(entry)
CGMSHistoryEntryType.SensorStatus -> decodeSensorStatus(entry)
CGMSHistoryEntryType.CalBGForGH -> decodeCalBGForGH(entry)
CGMSHistoryEntryType.GlucoseSensorData -> decodeGlucoseSensorData(entry)
CGMSHistoryEntryType.SensorPacket -> decodeSensorPacket(entry)
CGMSHistoryEntryType.SensorError -> decodeSensorError(entry)
CGMSHistoryEntryType.SensorDataLow -> decodeDataHighLow(entry, 40)
CGMSHistoryEntryType.SensorDataHigh -> decodeDataHighLow(entry, 400)
CGMSHistoryEntryType.SensorTimestamp -> decodeSensorTimestamp(entry)
CGMSHistoryEntryType.SensorCal -> decodeSensorCal(entry)
CGMSHistoryEntryType.SensorCalFactor -> decodeSensorCalFactor(entry)
CGMSHistoryEntryType.SensorSync -> decodeSensorSync(entry)
CGMSHistoryEntryType.SensorStatus -> decodeSensorStatus(entry)
CGMSHistoryEntryType.CalBGForGH -> decodeCalBGForGH(entry)
CGMSHistoryEntryType.GlucoseSensorData -> decodeGlucoseSensorData(entry)
CGMSHistoryEntryType.BatteryChange, CGMSHistoryEntryType.Something10, CGMSHistoryEntryType.DateTimeChange -> {
CGMSHistoryEntryType.BatteryChange,
CGMSHistoryEntryType.Something10,
CGMSHistoryEntryType.DateTimeChange -> {
}
CGMSHistoryEntryType.Something19, CGMSHistoryEntryType.DataEnd, CGMSHistoryEntryType.SensorWeakSignal -> {
CGMSHistoryEntryType.Something19,
CGMSHistoryEntryType.DataEnd,
CGMSHistoryEntryType.SensorWeakSignal -> {
}
CGMSHistoryEntryType.None -> {
CGMSHistoryEntryType.UnknownOpCode,
CGMSHistoryEntryType.None -> {
}
}
return RecordDecodeStatus.NotSupported
@ -83,7 +88,7 @@ class MedtronicCGMSHistoryDecoder constructor(
} else if (opCode > 0 && opCode < 20) {
entryType = getByCode(opCode)
if (entryType === CGMSHistoryEntryType.None) {
unknownOpCodes!![opCode] = opCode
unknownOpCodes[opCode] = opCode
aapsLogger.warn(LTag.PUMPCOMM, "GlucoseHistoryEntry with unknown code: $opCode")
val pe = CGMSHistoryEntry()
pe.setEntryType(CGMSHistoryEntryType.None)
@ -94,7 +99,7 @@ class MedtronicCGMSHistoryDecoder constructor(
// System.out.println("OpCode: " + opCode);
val listRawData: MutableList<Byte> = ArrayList()
listRawData.add(opCode.toByte())
for (j in 0 until entryType!!.totalLength - 1) {
for (j in 0 until entryType.totalLength - 1) {
listRawData.add(dataClear[counter])
counter++
}
@ -166,14 +171,14 @@ class MedtronicCGMSHistoryDecoder constructor(
}
private fun parseDate(entry: CGMSHistoryEntry): Long? {
if (!entry.entryType!!.hasDate()) return null
if (!entry.entryType.hasDate()) return null
val data = entry.datetime
return if (entry.entryType!!.dateType === CGMSHistoryEntryType.DateType.MinuteSpecific) {
val atechDateTime = DateTimeUtil.toATechDate(parseYear(data!![3].toInt()), parseMonths(data[0].toInt(), data[1].toInt()),
return if (entry.entryType.dateType === CGMSHistoryEntryType.DateType.MinuteSpecific) {
val atechDateTime = DateTimeUtil.toATechDate(parseYear(data[3].toInt()), parseMonths(data[0].toInt(), data[1].toInt()),
parseDay(data[2].toInt()), parseHours(data[0].toInt()), parseMinutes(data[1].toInt()), 0)
entry.atechDateTime = atechDateTime
atechDateTime
} else if (entry.entryType!!.dateType === CGMSHistoryEntryType.DateType.SecondSpecific) {
} else if (entry.entryType.dateType === CGMSHistoryEntryType.DateType.SecondSpecific) {
aapsLogger.warn(LTag.PUMPCOMM, "parseDate for SecondSpecific type is not implemented.")
throw RuntimeException()
// return null;

View file

@ -75,7 +75,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
if (counter >= 1022) {
break
}
val listRawData: MutableList<Byte?> = ArrayList()
val listRawData: MutableList<Byte> = ArrayList()
listRawData.add(opCode.toByte())
if (entryType === PumpHistoryEntryType.UnabsorbedInsulin
|| entryType === PumpHistoryEntryType.UnabsorbedInsulin512) {
@ -112,7 +112,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
pe.opCode = opCode.toByte()
}
if (entryType.getHeadLength(medtronicUtil.medtronicPumpModel) == 0) special = true
pe.setData(listRawData as List<Byte>, special)
pe.setData(listRawData, special)
val decoded = decodeRecord(pe)
if (decoded === RecordDecodeStatus.OK || decoded === RecordDecodeStatus.Ignored) {
//Log.i(TAG, "#" + record + " " + decoded.getDescription() + " " + pe);
@ -291,14 +291,14 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
}
private fun decodeBatteryActivity(entry: PumpHistoryEntry) {
entry.displayableValue = if (entry.head!![0] == 0.toByte()) "Battery Removed" else "Battery Replaced"
entry.displayableValue = if (entry.head[0] == 0.toByte()) "Battery Removed" else "Battery Replaced"
}
private fun decodeBasalProfileStart(entry: PumpHistoryEntry): RecordDecodeStatus {
val body = entry.body
val offset = body!![0] * 1000 * 30 * 60
val offset = body[0] * 1000 * 30 * 60
var rate: Float? = null
val index = entry.head!![0].toInt()
val index = entry.head[0].toInt()
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
rate = body[1] * 0.025f
}
@ -315,14 +315,14 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
}
private fun decodeBolusWizard(entry: PumpHistoryEntry): RecordDecodeStatus {
val body = entry.body!!
val body = entry.body
val dto = BolusWizardDTO()
var bolusStrokes = 10.0f
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
// https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/log_entries/bolus_wizard.rb#L102
bolusStrokes = 40.0f
dto.carbs = ((body[1] and 0x0c.toByte()).toInt() shl 6) + body[0]
dto.bloodGlucose = ((body[1] and 0x03).toInt() shl 8) + entry.head!![0]
dto.bloodGlucose = ((body[1] and 0x03).toInt() shl 8) + entry.head[0]
dto.carbRatio = body[1] / 10.0f
// carb_ratio (?) = (((self.body[2] & 0x07) << 8) + self.body[3]) /
// 10.0s
@ -334,7 +334,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
dto.unabsorbedInsulin = ((body[10].toInt() shl 8) + body[11]) / bolusStrokes
dto.bolusTotal = ((body[12].toInt() shl 8) + body[13]) / bolusStrokes
} else {
dto.bloodGlucose = (body.get(1) and 0x0F).toInt() shl 8 or entry.head!!.get(0).toInt()
dto.bloodGlucose = (body.get(1) and 0x0F).toInt() shl 8 or entry.head.get(0).toInt()
dto.carbs = body[0].toInt()
dto.carbRatio = body[2].toFloat()
dto.insulinSensitivity = body[3].toFloat()
@ -356,10 +356,10 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
}
private fun decodeBolusWizard512(entry: PumpHistoryEntry): RecordDecodeStatus {
val body = entry.body!!
val body = entry.body
val dto = BolusWizardDTO()
val bolusStrokes = 10.0f
dto.bloodGlucose = (body.get(1) and 0x03).toInt() shl 8 or entry.head!!.get(0).toInt()
dto.bloodGlucose = (body.get(1) and 0x03).toInt() shl 8 or entry.head.get(0).toInt()
dto.carbs = body.get(1).toInt() and 0xC shl 6 or body.get(0).toInt() // (int)body[0];
dto.carbRatio = body.get(2).toFloat()
dto.insulinSensitivity = body.get(3).toFloat()
@ -379,13 +379,13 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
}
private fun decodeLowReservoir(entry: PumpHistoryEntry) {
val amount = getUnsignedInt(entry.head!!.get(0)) * 1.0f / 10.0f * 2
val amount = getUnsignedInt(entry.head.get(0)) * 1.0f / 10.0f * 2
entry.displayableValue = getFormattedValue(amount, 1)
}
private fun decodePrime(entry: PumpHistoryEntry) {
val amount = ByteUtil.toInt(entry.head!!.get(2), entry.head!!.get(3)) / 10.0f
val fixed = ByteUtil.toInt(entry.head!!.get(0), entry.head!!.get(1)) / 10.0f
val amount = ByteUtil.toInt(entry.head.get(2), entry.head.get(3)) / 10.0f
val fixed = ByteUtil.toInt(entry.head.get(0), entry.head.get(1)) / 10.0f
// amount = (double)(asUINT8(data[4]) << 2) / 40.0;
// programmedAmount = (double)(asUINT8(data[2]) << 2) / 40.0;
@ -422,7 +422,7 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
private fun decodeBolus(entry: PumpHistoryEntry) {
val bolus: BolusDTO?
val data = entry.head!!
val data = entry.head
if (MedtronicDeviceType.isSameDevice(medtronicUtil.medtronicPumpModel, MedtronicDeviceType.Medtronic_523andHigher)) {
bolus = BolusDTO(atechDateTime = entry.atechDateTime,
requestedAmount = ByteUtil.toInt(data.get(0), data.get(1)) / 40.0,
@ -455,20 +455,20 @@ class MedtronicPumpHistoryDecoder @Inject constructor(
}
val tbr = TempBasalPair(
tbrRate.head!!.get(0),
tbrRate.body!!.get(0),
tbrDuration!!.head!!.get(0).toInt(),
ByteUtil.asUINT8(tbrRate.datetime!!.get(4)) shr 3 == 0)
tbrRate.head.get(0),
tbrRate.body.get(0),
tbrDuration!!.head.get(0).toInt(),
ByteUtil.asUINT8(tbrRate.datetime.get(4)) shr 3 == 0)
entry.addDecodedData("Object", tbr)
entry.displayableValue = tbr.description
}
private fun decodeDateTime(entry: PumpHistoryEntry) {
if (entry.datetime == null) {
if (entry.datetime.size == 0) {
aapsLogger.warn(LTag.PUMPBTCOMM, "DateTime not set.")
}
val dt = entry.datetime!!
val dt = entry.datetime
if (entry.dateTimeLength == 5) {
val seconds: Int = (dt.get(0) and 0x3F.toByte()).toInt()
val minutes: Int = (dt.get(1) and 0x3F.toByte()).toInt()

View file

@ -12,7 +12,12 @@ import java.util.*
* Author: Andy {andy.rozman@gmail.com}
*/
enum class PumpHistoryEntryType // implements CodeEnum
constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int = 2, date: Int = 5, body: Int = 0) {
constructor(var code: Byte,
var description: String,
var group: PumpHistoryEntryGroup,
var headLength: Int = 2,
var dateLength: Int = 5,
var bodyLength: Int = 0) {
// all commented out are probably not the real items
None(0, "None", PumpHistoryEntryGroup.Unknown, 1, 0, 0),
@ -193,16 +198,6 @@ constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int
}
}
val code: Byte
val description: String?
get() = field
val headLength: Int
val dateLength: Int
// private MinimedDeviceType deviceType;
private val bodyLength: Int
private val totalLength: Int
// special rules need to be put in list from highest to lowest (e.g.:
@ -212,12 +207,6 @@ constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int
private var hasSpecialRules = false
get() = field
val group: PumpHistoryEntryGroup
get() = field
private constructor(opCode: Byte, group: PumpHistoryEntryGroup) : this(opCode, null, group, 2, 5, 0) {}
private constructor(opCode: Byte, group: PumpHistoryEntryGroup, head: Int, date: Int, body: Int) : this(opCode, null, group, head, date, body) {}
fun getTotalLength(medtronicDeviceType: MedtronicDeviceType): Int {
return if (hasSpecialRules) {
getHeadLength(medtronicDeviceType) + getBodyLength(medtronicDeviceType) + dateLength
@ -227,7 +216,7 @@ constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int
}
fun addSpecialRuleHead(rule: SpecialRule) {
if (isEmpty(specialRulesHead)) {
if (specialRulesHead.isNullOrEmpty()) {
specialRulesHead = ArrayList()
}
specialRulesHead!!.add(rule)
@ -235,53 +224,33 @@ constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int
}
fun addSpecialRuleBody(rule: SpecialRule) {
if (isEmpty(specialRulesBody)) {
if (specialRulesBody.isNullOrEmpty()) {
specialRulesBody = ArrayList()
}
specialRulesBody!!.add(rule)
hasSpecialRules = true
}
// fun getDescription(): String {
// return description ?: name
// }
fun getHeadLength(medtronicDeviceType: MedtronicDeviceType): Int {
return if (hasSpecialRules) {
if (isNotEmpty(specialRulesHead)) {
determineSizeByRule(medtronicDeviceType, headLength, specialRulesHead)
} else {
headLength
}
return if (hasSpecialRules && !specialRulesHead.isNullOrEmpty()) {
determineSizeByRule(medtronicDeviceType, headLength, specialRulesHead!!)
} else {
headLength
}
}
fun getBodyLength(medtronicDeviceType: MedtronicDeviceType): Int {
return if (hasSpecialRules) {
if (isNotEmpty(specialRulesBody)) {
determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody)
} else {
bodyLength
}
return if (hasSpecialRules && !specialRulesBody.isNullOrEmpty()) {
determineSizeByRule(medtronicDeviceType, bodyLength, specialRulesBody!!)
} else {
bodyLength
}
}
private fun isNotEmpty(list: List<*>?): Boolean {
return list != null && !list.isEmpty()
}
private fun isEmpty(list: List<*>?): Boolean {
return list == null || list.isEmpty()
}
// byte[] dh = { 2, 3 };
private fun determineSizeByRule(medtronicDeviceType: MedtronicDeviceType, defaultValue: Int, rules: List<SpecialRule>?): Int {
private fun determineSizeByRule(medtronicDeviceType: MedtronicDeviceType, defaultValue: Int, rules: List<SpecialRule>): Int {
var size = defaultValue
for (rule in rules!!) {
for (rule in rules) {
if (MedtronicDeviceType.isSameDevice(medtronicDeviceType, rule.deviceType)) {
size = rule.size
break
@ -293,12 +262,6 @@ constructor(opCode: Byte, name: String?, group: PumpHistoryEntryGroup, head: Int
class SpecialRule internal constructor(var deviceType: MedtronicDeviceType, var size: Int)
init {
this.code = opCode //as Byte.toInt()
description = name
headLength = head
dateLength = date
bodyLength = body
totalLength = head + date + body
this.group = group
totalLength = headLength + dateLength + bodyLength
}
}

View file

@ -85,9 +85,9 @@ class PumpMessage : RLMessage {
// + commandType);
// rawContent = just response without code (contents-2, messageBody.txData-1);
val rawContent: ByteArray?
val rawContent: ByteArray
get() {
if (messageBody == null || messageBody!!.txData == null || messageBody!!.txData!!.size == 0) return null
if (messageBody == null || messageBody!!.txData == null || messageBody!!.txData!!.size == 0) return byteArrayOf()
val data = messageBody!!.txData
var length = ByteUtil.asUINT8(data!![0]) // length is not always correct so, we check whole array if we have
// data, after length
@ -121,7 +121,7 @@ class PumpMessage : RLMessage {
get() {
val raw = messageBody!!.txData
return if (raw == null || raw.size == 0) {
ByteArray(0)
byteArrayOf()
} else {
ByteUtil.substring(raw, 1, Math.min(FRAME_DATA_LENGTH, raw.size - 1))
}
@ -178,6 +178,7 @@ class PumpMessage : RLMessage {
}
companion object {
const val FRAME_DATA_LENGTH = 64
}
}

View file

@ -43,8 +43,6 @@ class MedtronicUIPostprocessor @Inject constructor(
val basalProfile = uiTask.getParameter(0) as BasalProfile
aapsLogger.debug("D: basal profile returned after set: $basalProfile")
//var desc: PumpDescription = medtronicPumpPlugin.getP.getPumpDescription()
medtronicPumpStatus.basalsByHour = basalProfile.getProfilesByHour(medtronicPumpPlugin.pumpDescription.pumpType)
}
}
@ -145,40 +143,53 @@ class MedtronicUIPostprocessor @Inject constructor(
}
private fun postProcessSettings(uiTask: MedtronicUITask) {
val settings = uiTask.result as Map<String, PumpSettingDTO>?
val settings = uiTask.result as? Map<String, PumpSettingDTO>
if (settings == null)
return
medtronicUtil.settings = settings
var checkValue: PumpSettingDTO?
medtronicPumpPlugin.rileyLinkService!!.verifyConfiguration()
var checkValue: PumpSettingDTO
medtronicPumpPlugin.rileyLinkService.verifyConfiguration()
// check profile
if ("Yes" != settings!!["PCFG_BASAL_PROFILES_ENABLED"]!!.value) {
aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump.")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus)
} else {
checkValue = settings["PCFG_ACTIVE_BASAL_PROFILE"]
if ("STD" != checkValue!!.value) {
aapsLogger.error("Basal profile set on pump is incorrect (must be STD).")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus)
if (settings.containsKey("PCFG_BASAL_PROFILES_ENABLED") && settings.containsKey("PCFG_ACTIVE_BASAL_PROFILE")) {
checkValue = settings["PCFG_BASAL_PROFILES_ENABLED"]!!
if ("Yes" != checkValue.value) {
aapsLogger.error(LTag.PUMP, "Basal profiles are not enabled on pump.")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpBasalProfilesNotEnabled, resourceHelper, rxBus)
} else {
checkValue = settings["PCFG_ACTIVE_BASAL_PROFILE"]!!
if ("STD" != checkValue.value) {
aapsLogger.error("Basal profile set on pump is incorrect (must be STD).")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpIncorrectBasalProfileSelected, resourceHelper, rxBus)
}
}
}
// TBR
checkValue = settings["PCFG_TEMP_BASAL_TYPE"]
if ("Units" != checkValue!!.value) {
aapsLogger.error("Wrong TBR type set on pump (must be Absolute).")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus)
if (settings.containsKey("PCFG_TEMP_BASAL_TYPE")) {
if ("Units" != settings["PCFG_TEMP_BASAL_TYPE"]!!.value) {
aapsLogger.error("Wrong TBR type set on pump (must be Absolute).")
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongTBRTypeSet, resourceHelper, rxBus)
}
}
// MAXes
checkValue = settings["PCFG_MAX_BOLUS"]
if (!MedtronicUtil.isSame(checkValue!!.value.toDouble(), medtronicPumpStatus.maxBolus!!)) {
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Bolus set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBolus))
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, medtronicPumpStatus.maxBolus)
if (settings.containsKey("PCFG_MAX_BOLUS")) {
checkValue = settings["PCFG_MAX_BOLUS"]!!
if (!MedtronicUtil.isSame(checkValue.value.toDouble(), medtronicPumpStatus.maxBolus!!)) {
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Bolus set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBolus))
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBolusSet, resourceHelper, rxBus, medtronicPumpStatus.maxBolus)
}
}
checkValue = settings["PCFG_MAX_BASAL"]
if (!MedtronicUtil.isSame(checkValue!!.value.toDouble(), medtronicPumpStatus.maxBasal!!)) {
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Basal set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBasal))
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, medtronicPumpStatus.maxBasal)
if (settings.containsKey("PCFG_MAX_BASAL")) {
checkValue = settings["PCFG_MAX_BASAL"]!!
if (!MedtronicUtil.isSame(checkValue.value.toDouble(), medtronicPumpStatus.maxBasal!!)) {
aapsLogger.error(LTag.PUMPCOMM, String.format(Locale.ENGLISH, "Wrong Max Basal set on Pump (current=%s, required=%.2f).", checkValue.value, medtronicPumpStatus.maxBasal))
medtronicUtil.sendNotification(MedtronicNotificationType.PumpWrongMaxBasalSet, resourceHelper, rxBus, medtronicPumpStatus.maxBasal)
}
}
}

View file

@ -429,16 +429,16 @@ class MedtronicHistoryData @Inject constructor(
private fun uploadCareportalEventIfFoundInHistory(historyRecord: PumpHistoryEntry, eventSP: String, eventType: DetailedBolusInfo.EventType) {
val lastPrimeFromAAPS = sp.getLong(eventSP, 0L)
if (historyRecord.atechDateTime != lastPrimeFromAAPS) {
var result = pumpSync.insertTherapyEventIfNewWithTimestamp(
val result = pumpSync.insertTherapyEventIfNewWithTimestamp(
DateTimeUtil.toMillisFromATD(historyRecord.atechDateTime),
eventType, null,
historyRecord.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ROOT, "insertTherapyEventIfNewWithTimestamp [date=%d, eventType=%s, pumpId=%d, pumpSerial=%s] - Result: %b",
historyRecord.atechDateTime, eventType, historyRecord.pumpId,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
sp.putLong(eventSP, historyRecord.atechDateTime)
}
@ -460,7 +460,7 @@ class MedtronicHistoryData @Inject constructor(
totalsDTO.insulinTotal,
tdd.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!
medtronicPumpStatus.serialNumber
)
}
}
@ -515,11 +515,11 @@ class MedtronicHistoryData @Inject constructor(
type,
bolus.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithTempId [date=%d, temporaryId=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime, temporaryId, bolus.pumpId, deliveredAmount,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
} else {
val result = pumpSync.syncBolusWithPumpId(
tryToGetByLocalTime(bolus.atechDateTime),
@ -527,11 +527,11 @@ class MedtronicHistoryData @Inject constructor(
type,
bolus.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncBolusWithPumpId [date=%d, pumpId=%d, insulin=%.2f, pumpSerial=%s] - Result: %b",
bolus.atechDateTime, bolus.pumpId, deliveredAmount,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
}
addCarbs(bolus)
@ -548,11 +548,11 @@ class MedtronicHistoryData @Inject constructor(
false,
bolus.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncExtendedBolusWithPumpId [date=%d, amount=%.2f, duration=%d, pumpId=%d, pumpSerial=%s, multiwave=%b] - Result: %b",
bolus.atechDateTime, bolusDTO.deliveredAmount, bolusDTO.duration, bolus.pumpId,
medtronicPumpStatus.serialNumber!!, isMultiwave, result))
medtronicPumpStatus.serialNumber, isMultiwave, result))
}
private fun addCarbs(bolus: PumpHistoryEntry) {
@ -563,7 +563,7 @@ class MedtronicHistoryData @Inject constructor(
tryToGetByLocalTime(bolus.atechDateTime),
bolusWizard.carbs.toDouble(),
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!,
medtronicPumpStatus.serialNumber,
bolus.pumpId
))
}
@ -589,8 +589,8 @@ class MedtronicHistoryData @Inject constructor(
var processDTO: TempBasalProcessDTO? = null
val processList: MutableList<TempBasalProcessDTO> = mutableListOf()
for (treatment in entryList) {
val tbr2 = treatment.getDecodedDataEntry("Object") as TempBasalPair?
if (tbr2!!.isCancelTBR) {
val tbr2 = treatment.getDecodedDataEntry("Object") as TempBasalPair
if (tbr2.isCancelTBR) {
if (processDTO != null) {
processDTO.itemTwo = treatment
processDTO.cancelPresent = true
@ -627,7 +627,7 @@ class MedtronicHistoryData @Inject constructor(
if (entryWithTempId != null) {
aapsLogger.debug(LTag.PUMP, String.format("DD: tempIdEntry=%s, tbrEntry=%s, tempBasalProcessDTO=%s, pumpType=%s, serial=%s",
gson.toJson(entryWithTempId), gson.toJson(tbrEntry), gson.toJson(tempBasalProcessDTO), medtronicPumpStatus.pumpType, medtronicPumpStatus.serialNumber!!))
gson.toJson(entryWithTempId), gson.toJson(tbrEntry), gson.toJson(tempBasalProcessDTO), medtronicPumpStatus.pumpType, medtronicPumpStatus.serialNumber))
val result = pumpSync.syncTemporaryBasalWithTempId(
tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
@ -638,12 +638,12 @@ class MedtronicHistoryData @Inject constructor(
PumpSync.TemporaryBasalType.NORMAL,
tempBasalProcessDTO.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncTemporaryBasalWithTempId [date=%d, temporaryId=%d, pumpId=%d, rate=%.2f %s, duration=%d, pumpSerial=%s] - Result: %b",
tempBasalProcessDTO.atechDateTime, entryWithTempId.temporaryId, tempBasalProcessDTO.pumpId,
tbrEntry.insulinRate, (if (tbrEntry.isPercent) "%" else "U"), tempBasalProcessDTO.duration,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
pumpSyncStorage.removeTemporaryBasalWithTemporaryId(entryWithTempId.temporaryId)
tbrRecords.remove(entryWithTempId)
@ -664,12 +664,12 @@ class MedtronicHistoryData @Inject constructor(
PumpSync.TemporaryBasalType.NORMAL,
tempBasalProcessDTO.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncTemporaryBasalWithPumpId [date=%d, pumpId=%d, rate=%.2f %s, duration=%d, pumpSerial=%s] - Result: %b",
tempBasalProcessDTO.atechDateTime, tempBasalProcessDTO.pumpId,
tbrEntry.insulinRate, (if (tbrEntry.isPercent) "%" else "U"), tempBasalProcessDTO.duration,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
if (medtronicPumpStatus.runningTBR != null) {
if (!isTBRActive(medtronicPumpStatus.runningTBR!!)) {
@ -682,7 +682,7 @@ class MedtronicHistoryData @Inject constructor(
medtronicPumpStatus.runningTBR = PumpDbEntry(0L,
tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!,
medtronicPumpStatus.serialNumber,
null,
PumpDbEntryTBR(tbrEntry.insulinRate, !tbrEntry.isPercent, tempBasalProcessDTO.duration, PumpSync.TemporaryBasalType.NORMAL),
tempBasalProcessDTO.pumpId)
@ -716,13 +716,13 @@ class MedtronicHistoryData @Inject constructor(
/**
* Looks at all boluses that have temporaryId and find one that is correct for us (if such entry exists)
*/
private fun findDbEntry(treatment: PumpHistoryEntry?, temporaryEntries: MutableList<PumpDbEntry>): PumpDbEntry? {
private fun findDbEntry(treatment: PumpHistoryEntry, temporaryEntries: MutableList<PumpDbEntry>): PumpDbEntry? {
if (temporaryEntries.isEmpty()) {
return null
}
var proposedTime = DateTimeUtil.toMillisFromATD(treatment!!.atechDateTime)
var proposedTime = DateTimeUtil.toMillisFromATD(treatment.atechDateTime)
// pumpTime should never be null, but it can theoretically happen if reading of time from pump fails
this.pumpTime?.let { proposedTime += (it.timeDifference * 1000) }
@ -784,11 +784,11 @@ class MedtronicHistoryData @Inject constructor(
PumpSync.TemporaryBasalType.PUMP_SUSPEND,
tempBasalProcess.itemOne.pumpId,
medtronicPumpStatus.pumpType,
medtronicPumpStatus.serialNumber!!)
medtronicPumpStatus.serialNumber)
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "processSuspends::syncTemporaryBasalWithPumpId [date=%d, rate=%.2f, duration=%d, pumpId=%d, pumpSerial=%s] - Result: %b",
tempBasalProcess.itemOne.atechDateTime, 0.0, tempBasalProcess.duration, tempBasalProcess.itemOne.pumpId,
medtronicPumpStatus.serialNumber!!, result))
medtronicPumpStatus.serialNumber, result))
}
}

View file

@ -34,8 +34,7 @@ class BolusDTO constructor(atechDateTime: Long,
@Expose var requestedAmount: Double,
@Expose var deliveredAmount: Double,
@Expose var duration: Int = 0
)
: PumpTimeStampedRecord(atechDateTime) {
) : PumpTimeStampedRecord(atechDateTime) {
// @Expose
// var requestedAmount: Double? = null
@ -50,7 +49,7 @@ class BolusDTO constructor(atechDateTime: Long,
// var duration: Int? = null
@Expose
var bolusType: PumpBolusType? = null
lateinit var bolusType: PumpBolusType
var insulinOnBoard: Double? = null
@ -87,9 +86,9 @@ class BolusDTO constructor(atechDateTime: Long,
}
val bolusKey: String
get() = "Bolus_" + bolusType!!.name
get() = "Bolus_" + bolusType.name
override fun toString(): String {
return "BolusDTO [type=" + bolusType!!.name + ", " + value + "]"
return "BolusDTO [type=" + bolusType.name + ", " + value + "]"
}
}

View file

@ -1,9 +1,8 @@
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto
import com.google.gson.annotations.Expose
//import info.nightscout.androidaps.db.TDD
import com.google.gson.annotations.Expose
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntryType
@ -65,8 +64,8 @@ class DailyTotalsDTO(var entry: PumpHistoryEntry) {
}
private fun decodeEndResultsTotals(entry: PumpHistoryEntry) {
val totals = ByteUtil.toInt(entry.head!![0].toInt(), entry.head!![1].toInt(), entry.head!![2].toInt(),
entry.head!![3].toInt(), ByteUtil.BitConversion.BIG_ENDIAN) * 0.025
val totals = ByteUtil.toInt(entry.head[0].toInt(), entry.head[1].toInt(), entry.head[2].toInt(),
entry.head[3].toInt(), ByteUtil.BitConversion.BIG_ENDIAN) * 0.025
insulinTotal = totals
entry.addDecodedData("Totals", totals)
}
@ -88,9 +87,9 @@ class DailyTotalsDTO(var entry: PumpHistoryEntry) {
}
}
private fun decodeDailyTotals515(data: ByteArray?) {
private fun decodeDailyTotals515(data: ByteArray) {
// LOG.debug("Can't decode DailyTotals515: Body={}", ByteUtil.getHex(data));
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
@ -102,8 +101,8 @@ class DailyTotalsDTO(var entry: PumpHistoryEntry) {
//LOG.debug("515: {}", toString());
}
private fun decodeDailyTotals522(data: ByteArray?) {
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
private fun decodeDailyTotals522(data: ByteArray) {
insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
bolusTotal = ByteUtil.toInt(data[17], data[18], data[19]) / 40.0
@ -124,8 +123,8 @@ class DailyTotalsDTO(var entry: PumpHistoryEntry) {
//LOG.debug("522: {}", toString());
}
private fun decodeDailyTotals523(data: ByteArray?) {
insulinTotal = ByteUtil.toInt(data!![8], data[9]) / 40.0
private fun decodeDailyTotals523(data: ByteArray) {
insulinTotal = ByteUtil.toInt(data[8], data[9]) / 40.0
insulinBasal = ByteUtil.toInt(data[10], data[11]) / 40.0
insulinBolus = ByteUtil.toInt(data[13], data[14]) / 40.0
insulinCarbs = ByteUtil.toInt(data[16], data[17]) * 1.0
@ -177,23 +176,13 @@ class DailyTotalsDTO(var entry: PumpHistoryEntry) {
.toString()
}
// fun setTDD(tdd: TDD) {
// tdd.date = DateTimeUtil.toMillisFromATD(entry.atechDateTime!!)
// tdd.basal = insulinBasal!!
// tdd.bolus = insulinBolus
// tdd.total = insulinTotal
// }
//
// fun doesEqual(tdd: TDD): Boolean {
// return tdd.total == insulinTotal && tdd.bolus == insulinBolus && tdd.basal == insulinBasal
// }
init {
when (entry.entryType) {
PumpHistoryEntryType.EndResultTotals -> decodeEndResultsTotals(entry)
PumpHistoryEntryType.DailyTotals515 -> decodeDailyTotals515(entry.body)
PumpHistoryEntryType.DailyTotals522 -> decodeDailyTotals522(entry.body)
PumpHistoryEntryType.DailyTotals523 -> decodeDailyTotals523(entry.body)
else -> {
}
}

View file

@ -25,8 +25,7 @@ import java.util.*
*
* Author: Andy {andy@atech-software.com}
*/
enum class MedtronicCommandType
{
enum class MedtronicCommandType {
InvalidCommand(0, "Invalid Command", null, null), //
@ -57,7 +56,7 @@ enum class MedtronicCommandType
GetRealTimeClock(112, "Get Pump Time", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
7, R.string.medtronic_cmd_desc_get_time), // 0x70
GetBatteryStatus(0x72, "Get Battery Status", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters,
0, R.string.medtronic_cmd_desc_get_battery_status), //
0, R.string.medtronic_cmd_desc_get_battery_status), //
GetRemainingInsulin(0x73, "Read Remaining Insulin", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters,
2, R.string.medtronic_cmd_desc_get_remaining_insulin), // 115
SetBolus(0x42, "Set Bolus", MedtronicDeviceType.All, MinimedCommandParameterType.NoParameters, //
@ -130,9 +129,8 @@ enum class MedtronicCommandType
// Fake Commands
CancelTBR;
companion object {
var mapByCode: MutableMap<Byte, MedtronicCommandType> = HashMap()
// private fun getDeviceTypesArray(vararg types: MedtronicDeviceType): HashMap<MedtronicDeviceType, String?> {
@ -151,16 +149,19 @@ enum class MedtronicCommandType
}
}
fun constructMessageBody(messageType: MedtronicCommandType?, bodyData: ByteArray?): MessageBody {
fun constructMessageBody(messageType: MedtronicCommandType?, bodyData: ByteArray): MessageBody {
return when (messageType) {
CommandACK -> PumpAckMessageBody(bodyData)
else -> UnknownMessageBody(bodyData!!)
else -> UnknownMessageBody(bodyData)
}
}
@JvmStatic
fun getSettings(medtronicPumpModel: MedtronicDeviceType?): MedtronicCommandType {
return if (isSameDevice(medtronicPumpModel!!, MedtronicDeviceType.Medtronic_512_712)) Settings_512 else Settings
return if (isSameDevice(medtronicPumpModel!!, MedtronicDeviceType.Medtronic_512_712))
Settings_512
else
Settings
}
init {
@ -194,19 +195,19 @@ enum class MedtronicCommandType
}
constructor(code: Int, description: String, devices: MedtronicDeviceType?,
parameterType: MinimedCommandParameterType?, cmd_params: ByteArray) : this(code, description, devices, parameterType) {
parameterType: MinimedCommandParameterType?, cmd_params: ByteArray) : this(code, description, devices, parameterType) {
commandParameters = cmd_params
commandParametersCount = cmd_params.size
}
// NEW
constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
parameterType: MinimedCommandParameterType?, expectedLength: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, null) {
parameterType: MinimedCommandParameterType?, expectedLength: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, null) {
}
// NEW
constructor(code: Int, description: String, devices: MedtronicDeviceType?, //
parameterType: MinimedCommandParameterType?, expectedLength: Int, resourceId: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId) {
parameterType: MinimedCommandParameterType?, expectedLength: Int, resourceId: Int) : this(code, description, devices, parameterType, 64, 1, expectedLength, resourceId) {
}
// NEW
@ -253,7 +254,6 @@ enum class MedtronicCommandType
// }
// }
override fun toString(): String {
return name
}

View file

@ -30,7 +30,7 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
) : PumpStatus(PumpType.MEDTRONIC_522_722) {
var errorDescription: String? = null
var serialNumber: String? = null
lateinit var serialNumber: String //? = null
var pumpFrequency: String? = null
var maxBolus: Double? = null
var maxBasal: Double? = null
@ -58,6 +58,10 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
if (medtronicDeviceTypeMap.isEmpty()) createMedtronicDeviceTypeMap()
lastConnection = sp.getLong(MedtronicConst.Statistics.LastGoodPumpCommunicationTime, 0L)
lastDataTime = lastConnection
var serial = sp.getStringOrNull(MedtronicConst.Prefs.PumpSerial, null)
if (serial != null) {
serialNumber = serial
}
}
private fun createMedtronicDeviceTypeMap() {

View file

@ -69,9 +69,10 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
* If you have customized RileyLinkServiceData you need to override this
*/
override fun initRileyLinkServiceData() {
frequencies = arrayOf()
frequencies[0] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_us_ca)
frequencies[1] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_worldwide)
frequencies = arrayOf(resourceHelper.gs(R.string.key_medtronic_pump_frequency_us_ca),
resourceHelper.gs(R.string.key_medtronic_pump_frequency_worldwide))
// frequencies[0] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_us_ca)
// frequencies[1] = resourceHelper.gs(R.string.key_medtronic_pump_frequency_worldwide)
rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.MedtronicPump
setPumpIDString(sp.getString(MedtronicConst.Prefs.PumpSerial, "000000"))
@ -160,9 +161,9 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
medtronicPumpStatus.errorDescription = resourceHelper.gs(R.string.medtronic_error_pump_type_invalid)
return false
} else {
val pumpType = medtronicPumpStatus.medtronicPumpMap[pumpTypePart]
val pumpType = medtronicPumpStatus.medtronicPumpMap[pumpTypePart]!!
medtronicPumpStatus.medtronicDeviceType = medtronicPumpStatus.medtronicDeviceTypeMap[pumpTypePart]!!
medtronicPumpStatus.pumpType = pumpType!!
medtronicPumpStatus.pumpType = pumpType
medtronicPumpPlugin.pumpType = pumpType
if (pumpTypePart.startsWith("7")) medtronicPumpStatus.reservoirFullUnits = 300 else medtronicPumpStatus.reservoirFullUnits = 176
}
@ -245,7 +246,7 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
private fun reconfigureService(forceRileyLinkAddressRenewal: Boolean): Boolean {
if (!inPreInit) {
if (serialChanged) {
setPumpIDString(medtronicPumpStatus.serialNumber!!) // short operation
setPumpIDString(medtronicPumpStatus.serialNumber) // short operation
serialChanged = false
}
if (rileyLinkAddressChanged || forceRileyLinkAddressRenewal) {

View file

@ -173,7 +173,7 @@ class MedtronicUtil @Inject constructor(
b = b or 128.toByte()
// b |= doneBit;
frameData.add(0, b)
checkAndAppenLastFrame(frameData)
checkAndAppendLastFrame(frameData)
lastFrame = true
done = true
} else {
@ -194,12 +194,12 @@ class MedtronicUtil @Inject constructor(
b = b or 128.toByte()
// b |= doneBit;
frameData.add(b)
checkAndAppenLastFrame(frameData)
checkAndAppendLastFrame(frameData)
}
return frames
}
private fun checkAndAppenLastFrame(frameData: MutableList<Byte>) {
private fun checkAndAppendLastFrame(frameData: MutableList<Byte>) {
if (frameData.size == BIG_FRAME_LENGTH) return
val missing = BIG_FRAME_LENGTH - frameData.size
for (i in 0 until missing) {