Merge pull request #742 from andyrozman/mdt_syncstorage
Medtronic - reafctoring sync storage and OL
This commit is contained in:
commit
3c7a8225c0
14 changed files with 520 additions and 320 deletions
|
@ -1006,24 +1006,23 @@ class MedtronicPumpPlugin @Inject constructor(
|
||||||
if (medtronicHistoryData.isTBRActive(runningTBR)) {
|
if (medtronicHistoryData.isTBRActive(runningTBR)) {
|
||||||
|
|
||||||
val differenceTime = System.currentTimeMillis() - runningTBR.date
|
val differenceTime = System.currentTimeMillis() - runningTBR.date
|
||||||
val tbrData = runningTBR.tbrData!!
|
//val tbrData = runningTBR
|
||||||
|
|
||||||
val result = pumpSync.syncTemporaryBasalWithPumpId(
|
val result = pumpSync.syncTemporaryBasalWithPumpId(
|
||||||
runningTBR.date,
|
runningTBR.date,
|
||||||
tbrData.rate,
|
runningTBR.rate,
|
||||||
differenceTime,
|
differenceTime,
|
||||||
tbrData.isAbsolute,
|
runningTBR.isAbsolute,
|
||||||
tbrData.tbrType,
|
runningTBR.tbrType,
|
||||||
runningTBR.pumpId!!,
|
runningTBR.pumpId!!,
|
||||||
runningTBR.pumpType,
|
runningTBR.pumpType,
|
||||||
runningTBR.serialNumber)
|
runningTBR.serialNumber)
|
||||||
|
|
||||||
val differenceTimeMin = Math.floor(differenceTime / (60.0 * 1000.0))
|
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",
|
aapsLogger.debug(LTag.PUMP, "canceling running TBR - syncTemporaryBasalWithPumpId [date=${runningTBR.date}, " +
|
||||||
runningTBR.date, runningTBR.pumpId,
|
"pumpId=${runningTBR.pumpId}, rate=${runningTBR.rate} U, duration=${differenceTimeMin.toInt()}, " +
|
||||||
tbrData.rate, differenceTimeMin.toInt(),
|
"pumpSerial=${medtronicPumpStatus.serialNumber}] - Result: $result")
|
||||||
medtronicPumpStatus.serialNumber, result))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||||
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntry
|
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntry
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryBolus
|
||||||
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
|
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil
|
||||||
|
@ -490,17 +491,17 @@ class MedtronicHistoryData @Inject constructor(
|
||||||
var temporaryId: Long? = null
|
var temporaryId: Long? = null
|
||||||
|
|
||||||
if (!multiwave) {
|
if (!multiwave) {
|
||||||
val entryWithTempId = findDbEntry(bolus, boluses)
|
val entryWithTempId = findDbEntry(bolus, boluses as MutableList<PumpDbEntry>) as PumpDbEntryBolus?
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "DD: entryWithTempId=$entryWithTempId")
|
aapsLogger.debug(LTag.PUMP, "DD: entryWithTempId=$entryWithTempId")
|
||||||
|
|
||||||
if (entryWithTempId != null) {
|
if (entryWithTempId != null) {
|
||||||
aapsLogger.debug(LTag.PUMP, String.format("DD: entryWithTempId.bolusData=%s", if (entryWithTempId.bolusData == null) "null" else entryWithTempId.bolusData))
|
//aapsLogger.debug(LTag.PUMP, String.format("DD: entryWithTempId.bolusData=%s", if (entryWithTempId.bolusData == null) "null" else entryWithTempId.bolusData))
|
||||||
|
|
||||||
temporaryId = entryWithTempId.temporaryId
|
temporaryId = entryWithTempId.temporaryId
|
||||||
pumpSyncStorage.removeBolusWithTemporaryId(temporaryId)
|
pumpSyncStorage.removeBolusWithTemporaryId(temporaryId)
|
||||||
boluses.remove(entryWithTempId)
|
boluses.remove(entryWithTempId)
|
||||||
type = entryWithTempId.bolusData!!.bolusType
|
type = entryWithTempId.bolusType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,7 +620,7 @@ class MedtronicHistoryData @Inject constructor(
|
||||||
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemOne: " + gson.toJson(tempBasalProcessDTO.itemOne))
|
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemOne: " + gson.toJson(tempBasalProcessDTO.itemOne))
|
||||||
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemTwo: " + (if (tempBasalProcessDTO.itemTwo == null) "null" else gson.toJson(tempBasalProcessDTO.itemTwo!!)))
|
aapsLogger.debug(LTag.PUMP, "DD: tempBasalProcessDTO.itemTwo: " + (if (tempBasalProcessDTO.itemTwo == null) "null" else gson.toJson(tempBasalProcessDTO.itemTwo!!)))
|
||||||
|
|
||||||
val entryWithTempId = findDbEntry(tempBasalProcessDTO.itemOne, tbrRecords)
|
val entryWithTempId = findDbEntry(tempBasalProcessDTO.itemOne, tbrRecords as MutableList<PumpDbEntry>) as PumpDbEntryTBR?
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "DD: entryWithTempId: " + (if (entryWithTempId == null) "null" else entryWithTempId.toString()))
|
aapsLogger.debug(LTag.PUMP, "DD: entryWithTempId: " + (if (entryWithTempId == null) "null" else entryWithTempId.toString()))
|
||||||
|
|
||||||
|
@ -697,16 +698,16 @@ class MedtronicHistoryData @Inject constructor(
|
||||||
if (isTBRActive(startTimestamp = tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
|
if (isTBRActive(startTimestamp = tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
|
||||||
durationSeconds = tempBasalProcessDTO.durationAsSeconds)) {
|
durationSeconds = tempBasalProcessDTO.durationAsSeconds)) {
|
||||||
if (medtronicPumpStatus.runningTBR == null) {
|
if (medtronicPumpStatus.runningTBR == null) {
|
||||||
medtronicPumpStatus.runningTBR = info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntry(0L,
|
medtronicPumpStatus.runningTBR = PumpDbEntryTBR(
|
||||||
tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
|
temporaryId = 0L,
|
||||||
medtronicPumpStatus.pumpType,
|
date = tryToGetByLocalTime(tempBasalProcessDTO.atechDateTime),
|
||||||
medtronicPumpStatus.serialNumber,
|
pumpType = medtronicPumpStatus.pumpType,
|
||||||
null,
|
serialNumber = medtronicPumpStatus.serialNumber,
|
||||||
PumpDbEntryTBR(rate = tbrEntry.insulinRate,
|
entry = PumpDbEntryTBR(rate = tbrEntry.insulinRate,
|
||||||
isAbsolute = !tbrEntry.isPercent,
|
isAbsolute = !tbrEntry.isPercent,
|
||||||
durationInSeconds = tempBasalProcessDTO.durationAsSeconds,
|
durationInSeconds = tempBasalProcessDTO.durationAsSeconds,
|
||||||
tbrType = PumpSync.TemporaryBasalType.NORMAL),
|
tbrType = PumpSync.TemporaryBasalType.NORMAL),
|
||||||
tempBasalProcessDTO.pumpId)
|
pumpId = tempBasalProcessDTO.pumpId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -717,10 +718,12 @@ class MedtronicHistoryData @Inject constructor(
|
||||||
} // collection
|
} // collection
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isTBRActive(dbEntry: PumpDbEntry): Boolean {
|
|
||||||
|
|
||||||
|
fun isTBRActive(dbEntry: PumpDbEntryTBR): Boolean {
|
||||||
return isTBRActive(
|
return isTBRActive(
|
||||||
startTimestamp = dbEntry.date,
|
startTimestamp = dbEntry.date,
|
||||||
durationSeconds = dbEntry.tbrData!!.durationInSeconds)
|
durationSeconds = dbEntry.durationInSeconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isTBRActive(startTimestamp: Long, durationSeconds: Int): Boolean {
|
fun isTBRActive(startTimestamp: Long, durationSeconds: Int): Boolean {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDevic
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus
|
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BasalProfileStatus
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType
|
import info.nightscout.androidaps.plugins.pump.medtronic.defs.BatteryType
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
|
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType
|
||||||
|
@ -32,7 +33,7 @@ class MedtronicPumpStatus @Inject constructor(private val resourceHelper: Resour
|
||||||
var pumpFrequency: String? = null
|
var pumpFrequency: String? = null
|
||||||
var maxBolus: Double? = null
|
var maxBolus: Double? = null
|
||||||
var maxBasal: Double? = null
|
var maxBasal: Double? = null
|
||||||
var runningTBR: info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntry? = null
|
var runningTBR: PumpDbEntryTBR? = null
|
||||||
|
|
||||||
// statuses
|
// statuses
|
||||||
var pumpDeviceState = PumpDeviceState.NeverContacted
|
var pumpDeviceState = PumpDeviceState.NeverContacted
|
||||||
|
|
|
@ -4,45 +4,75 @@ import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
import info.nightscout.androidaps.interfaces.PumpSync
|
import info.nightscout.androidaps.interfaces.PumpSync
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||||
|
|
||||||
data class PumpDbEntry constructor(var temporaryId: Long,
|
// data class PumpDbEntry constructor(var temporaryId: Long,
|
||||||
var date: Long,
|
// var date: Long,
|
||||||
var pumpType: PumpType,
|
// var pumpType: PumpType,
|
||||||
var serialNumber: String,
|
// var serialNumber: String,
|
||||||
var bolusData: PumpDbEntryBolus? = null,
|
// var bolusData: PumpDbEntryBolus? = null,
|
||||||
var tbrData: PumpDbEntryTBR? = null,
|
// var tbrData: PumpDbEntryTBR? = null,
|
||||||
var pumpId: Long? = null) {
|
// var pumpId: Long? = null) {
|
||||||
|
//
|
||||||
|
// constructor(temporaryId: Long,
|
||||||
|
// date: Long,
|
||||||
|
// pumpType: PumpType,
|
||||||
|
// serialNumber: String,
|
||||||
|
// detailedBolusInfo: DetailedBolusInfo) : this(temporaryId, date, pumpType, serialNumber) {
|
||||||
|
// this.bolusData = PumpDbEntryBolus(
|
||||||
|
// detailedBolusInfo.insulin,
|
||||||
|
// detailedBolusInfo.carbs,
|
||||||
|
// detailedBolusInfo.bolusType)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constructor(temporaryId: Long,
|
||||||
|
// date: Long,
|
||||||
|
// pumpType: PumpType,
|
||||||
|
// serialNumber: String,
|
||||||
|
// rate: Double,
|
||||||
|
// isAbsolute: Boolean,
|
||||||
|
// durationInMinutes: Int,
|
||||||
|
// tbrType: PumpSync.TemporaryBasalType) : this(temporaryId, date, pumpType, serialNumber) {
|
||||||
|
// this.tbrData = PumpDbEntryTBR(
|
||||||
|
// rate,
|
||||||
|
// isAbsolute,
|
||||||
|
// durationInMinutes,
|
||||||
|
// tbrType)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
constructor(temporaryId: Long,
|
|
||||||
date: Long,
|
|
||||||
pumpType: PumpType,
|
|
||||||
serialNumber: String,
|
|
||||||
detailedBolusInfo: DetailedBolusInfo) : this(temporaryId, date, pumpType, serialNumber) {
|
|
||||||
this.bolusData = PumpDbEntryBolus(
|
|
||||||
detailedBolusInfo.insulin,
|
|
||||||
detailedBolusInfo.carbs,
|
|
||||||
detailedBolusInfo.bolusType)
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(temporaryId: Long,
|
|
||||||
date: Long,
|
|
||||||
pumpType: PumpType,
|
|
||||||
serialNumber: String,
|
|
||||||
rate: Double,
|
|
||||||
isAbsolute: Boolean,
|
|
||||||
durationInMinutes: Int,
|
|
||||||
tbrType: PumpSync.TemporaryBasalType) : this(temporaryId, date, pumpType, serialNumber) {
|
|
||||||
this.tbrData = PumpDbEntryTBR(
|
|
||||||
rate,
|
|
||||||
isAbsolute,
|
|
||||||
durationInMinutes,
|
|
||||||
tbrType)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
interface PumpDbEntry {
|
||||||
|
var temporaryId: Long
|
||||||
|
var date: Long
|
||||||
|
var pumpType: PumpType
|
||||||
|
var serialNumber: String
|
||||||
|
var pumpId: Long?
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PumpDbEntryBolus(var insulin: Double,
|
|
||||||
|
|
||||||
|
data class PumpDbEntryBolus(override var temporaryId: Long,
|
||||||
|
override var date: Long,
|
||||||
|
override var pumpType: PumpType,
|
||||||
|
override var serialNumber: String,
|
||||||
|
override var pumpId: Long? = null,
|
||||||
|
var insulin: Double,
|
||||||
var carbs: Double,
|
var carbs: Double,
|
||||||
var bolusType: DetailedBolusInfo.BolusType)
|
var bolusType: DetailedBolusInfo.BolusType) : PumpDbEntry {
|
||||||
|
|
||||||
|
constructor(temporaryId: Long,
|
||||||
|
date: Long,
|
||||||
|
pumpType: PumpType,
|
||||||
|
serialNumber: String,
|
||||||
|
detailedBolusInfo: DetailedBolusInfo) : this(temporaryId, date, pumpType, serialNumber, null,
|
||||||
|
detailedBolusInfo.insulin,
|
||||||
|
detailedBolusInfo.carbs,
|
||||||
|
detailedBolusInfo.bolusType) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
data class PumpDbEntryCarbs(var date: Long,
|
data class PumpDbEntryCarbs(var date: Long,
|
||||||
var carbs: Double,
|
var carbs: Double,
|
||||||
|
@ -57,7 +87,29 @@ data class PumpDbEntryCarbs(var date: Long,
|
||||||
creator.serialNumber())
|
creator.serialNumber())
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PumpDbEntryTBR(var rate: Double,
|
data class PumpDbEntryTBR(override var temporaryId: Long,
|
||||||
|
override var date: Long,
|
||||||
|
override var pumpType: PumpType,
|
||||||
|
override var serialNumber: String,
|
||||||
|
override var pumpId: Long? = null,
|
||||||
|
var rate: Double,
|
||||||
var isAbsolute: Boolean,
|
var isAbsolute: Boolean,
|
||||||
var durationInSeconds: Int,
|
var durationInSeconds: Int,
|
||||||
var tbrType: PumpSync.TemporaryBasalType)
|
var tbrType: PumpSync.TemporaryBasalType) : PumpDbEntry {
|
||||||
|
|
||||||
|
constructor(rate: Double,
|
||||||
|
isAbsolute: Boolean,
|
||||||
|
durationInSeconds: Int,
|
||||||
|
tbrType: PumpSync.TemporaryBasalType) : this(0, 0, PumpType.GENERIC_AAPS, "", null,
|
||||||
|
rate, isAbsolute, durationInSeconds, tbrType)
|
||||||
|
|
||||||
|
constructor(temporaryId: Long,
|
||||||
|
date: Long,
|
||||||
|
pumpType: PumpType,
|
||||||
|
serialNumber: String,
|
||||||
|
entry: PumpDbEntryTBR,
|
||||||
|
pumpId: Long?
|
||||||
|
) : this(temporaryId, date, pumpType, serialNumber, pumpId,
|
||||||
|
entry.rate, entry.isAbsolute, entry.durationInSeconds, entry.tbrType)
|
||||||
|
|
||||||
|
}
|
|
@ -22,13 +22,13 @@ class PumpSyncStorage @Inject constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val pumpSyncStorageBolusKey: String = "pump_sync_storage_bolus"
|
||||||
const val pumpSyncStorageKey: String = "pump_sync_storage_xstream_v2"
|
const val pumpSyncStorageTBRKey: String = "pump_sync_storage_tbr"
|
||||||
const val TBR: String = "TBR"
|
|
||||||
const val BOLUS: String = "BOLUS"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var pumpSyncStorage: MutableMap<String, MutableList<PumpDbEntry>> = mutableMapOf()
|
var pumpSyncStorageBolus: MutableList<PumpDbEntryBolus> = mutableListOf()
|
||||||
|
var pumpSyncStorageTBR: MutableList<PumpDbEntryTBR> = mutableListOf()
|
||||||
|
|
||||||
private var storageInitialized: Boolean = false
|
private var storageInitialized: Boolean = false
|
||||||
private var xstream: XStream = XStream()
|
private var xstream: XStream = XStream()
|
||||||
|
|
||||||
|
@ -41,38 +41,58 @@ class PumpSyncStorage @Inject constructor(
|
||||||
if (storageInitialized)
|
if (storageInitialized)
|
||||||
return
|
return
|
||||||
|
|
||||||
var loaded = false
|
xstream.addPermission(AnyTypePermission.ANY)
|
||||||
|
|
||||||
if (sp.contains(pumpSyncStorageKey)) {
|
if (sp.contains(pumpSyncStorageBolusKey)) {
|
||||||
val jsonData: String = sp.getString(pumpSyncStorageKey, "")
|
val jsonData: String = sp.getString(pumpSyncStorageBolusKey, "")
|
||||||
|
|
||||||
if (jsonData.isNotBlank()) {
|
if (jsonData.isNotBlank()) {
|
||||||
xstream.addPermission(AnyTypePermission.ANY)
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
pumpSyncStorage = xstream.fromXML(jsonData, MutableMap::class.java) as MutableMap<String, MutableList<PumpDbEntry>>
|
pumpSyncStorageBolus = xstream.fromXML(jsonData, MutableList::class.java) as
|
||||||
|
MutableList<PumpDbEntryBolus>
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, String.format("Loading Pump Sync Storage: boluses=%d, tbrs=%d.", pumpSyncStorage[BOLUS]!!.size, pumpSyncStorage[TBR]!!.size))
|
aapsLogger.debug(LTag.PUMP, "Loading Pump Sync Storage Bolus: boluses=${pumpSyncStorageBolus.size}")
|
||||||
aapsLogger.debug(LTag.PUMP, "DD: PumpSyncStorage=$pumpSyncStorage")
|
aapsLogger.debug(LTag.PUMP, "DD: PumpSyncStorageBolus=$pumpSyncStorageBolus")
|
||||||
|
|
||||||
loaded = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded) {
|
if (sp.contains(pumpSyncStorageTBRKey)) {
|
||||||
pumpSyncStorage[BOLUS] = mutableListOf()
|
val jsonData: String = sp.getString(pumpSyncStorageTBRKey, "")
|
||||||
pumpSyncStorage[TBR] = mutableListOf()
|
|
||||||
|
if (jsonData.isNotBlank()) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
pumpSyncStorageTBR = xstream.fromXML(jsonData, MutableList::class.java) as
|
||||||
|
MutableList<PumpDbEntryTBR>
|
||||||
|
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Loading Pump Sync Storage: tbrs=${pumpSyncStorageTBR.size}.")
|
||||||
|
aapsLogger.debug(LTag.PUMP, "DD: PumpSyncStorageTBR=$pumpSyncStorageTBR")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storageInitialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveStorageBolus() {
|
||||||
|
if (!pumpSyncStorageBolus.isEmpty()) {
|
||||||
|
sp.putString(pumpSyncStorageBolusKey, xstream.toXML(pumpSyncStorageBolus))
|
||||||
|
aapsLogger.debug(LTag.PUMP,"Saving Pump Sync Storage: boluses=${pumpSyncStorageBolus.size}")
|
||||||
|
} else {
|
||||||
|
if (sp.contains(pumpSyncStorageBolusKey))
|
||||||
|
sp.remove(pumpSyncStorageBolusKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveStorage() {
|
fun saveStorageTBR() {
|
||||||
if (!isStorageEmpty()) {
|
if (!pumpSyncStorageTBR.isEmpty()) {
|
||||||
sp.putString(pumpSyncStorageKey, xstream.toXML(pumpSyncStorage))
|
sp.putString(pumpSyncStorageTBRKey, xstream.toXML(pumpSyncStorageTBR))
|
||||||
aapsLogger.debug(String.format("Saving Pump Sync Storage: boluses=%d, tbrs=%d.", pumpSyncStorage[BOLUS]!!.size, pumpSyncStorage[TBR]!!.size))
|
aapsLogger.debug(LTag.PUMP, "Saving Pump Sync Storage: tbr=${pumpSyncStorageTBR.size}")
|
||||||
|
} else {
|
||||||
|
if (sp.contains(pumpSyncStorageTBRKey))
|
||||||
|
sp.remove(pumpSyncStorageTBRKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanOldStorage() {
|
private fun cleanOldStorage() {
|
||||||
val oldSpKeys = setOf("pump_sync_storage", "pump_sync_storage_xstream")
|
val oldSpKeys = setOf("pump_sync_storage", "pump_sync_storage_xstream", "pump_sync_storage_xstream_v2")
|
||||||
|
|
||||||
for (oldSpKey in oldSpKeys) {
|
for (oldSpKey in oldSpKeys) {
|
||||||
if (sp.contains(oldSpKey))
|
if (sp.contains(oldSpKey))
|
||||||
|
@ -80,16 +100,12 @@ class PumpSyncStorage @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isStorageEmpty(): Boolean {
|
fun getBoluses(): MutableList<PumpDbEntryBolus> {
|
||||||
return pumpSyncStorage[BOLUS]!!.isEmpty() && pumpSyncStorage[TBR]!!.isEmpty()
|
return pumpSyncStorageBolus
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBoluses(): MutableList<PumpDbEntry> {
|
fun getTBRs(): MutableList<PumpDbEntryTBR> {
|
||||||
return pumpSyncStorage[BOLUS]!!
|
return pumpSyncStorageTBR
|
||||||
}
|
|
||||||
|
|
||||||
fun getTBRs(): MutableList<PumpDbEntry> {
|
|
||||||
return pumpSyncStorage[TBR]!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addBolusWithTempId(detailedBolusInfo: DetailedBolusInfo, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator): Boolean {
|
fun addBolusWithTempId(detailedBolusInfo: DetailedBolusInfo, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator): Boolean {
|
||||||
|
@ -102,24 +118,25 @@ class PumpSyncStorage @Inject constructor(
|
||||||
creator.model(),
|
creator.model(),
|
||||||
creator.serialNumber())
|
creator.serialNumber())
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "addBolusWithTempId [date=%d, temporaryId=%d, insulin=%.2f, type=%s, pumpSerial=%s] - Result: %b",
|
aapsLogger.debug(LTag.PUMP, "addBolusWithTempId [date=${detailedBolusInfo.timestamp}, temporaryId=$temporaryId, " +
|
||||||
detailedBolusInfo.timestamp, temporaryId, detailedBolusInfo.insulin, detailedBolusInfo.bolusType,
|
"insulin=${detailedBolusInfo.insulin}, type=${detailedBolusInfo.bolusType}, pumpSerial=${creator.serialNumber()}] - " +
|
||||||
creator.serialNumber(), result))
|
"Result: $result")
|
||||||
|
|
||||||
if (detailedBolusInfo.carbs > 0.0) {
|
if (detailedBolusInfo.carbs > 0.0) {
|
||||||
addCarbs(PumpDbEntryCarbs(detailedBolusInfo, creator))
|
addCarbs(PumpDbEntryCarbs(detailedBolusInfo, creator))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result && writeToInternalHistory) {
|
if (result && writeToInternalHistory) {
|
||||||
val innerList: MutableList<PumpDbEntry> = pumpSyncStorage[BOLUS]!!
|
val dbEntry = PumpDbEntryBolus(temporaryId = temporaryId,
|
||||||
|
date = detailedBolusInfo.timestamp,
|
||||||
|
pumpType = creator.model(),
|
||||||
|
serialNumber = creator.serialNumber(),
|
||||||
|
detailedBolusInfo = detailedBolusInfo)
|
||||||
|
|
||||||
val dbEntry = PumpDbEntry(temporaryId, detailedBolusInfo.timestamp, creator.model(), creator.serialNumber(), detailedBolusInfo)
|
aapsLogger.debug("PumpDbEntryBolus: $dbEntry")
|
||||||
|
|
||||||
aapsLogger.debug("PumpDbEntry: $dbEntry")
|
pumpSyncStorageBolus.add(dbEntry)
|
||||||
|
saveStorageBolus()
|
||||||
innerList.add(dbEntry)
|
|
||||||
pumpSyncStorage[BOLUS] = innerList
|
|
||||||
saveStorage()
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -132,8 +149,8 @@ class PumpSyncStorage @Inject constructor(
|
||||||
carbsDto.pumpType,
|
carbsDto.pumpType,
|
||||||
carbsDto.serialNumber)
|
carbsDto.serialNumber)
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, String.format(Locale.ENGLISH, "syncCarbsWithTimestamp [date=%d, carbs=%.2f, pumpSerial=%s] - Result: %b",
|
aapsLogger.debug(LTag.PUMP, "syncCarbsWithTimestamp [date=${carbsDto.date}, " +
|
||||||
carbsDto.date, carbsDto.carbs, carbsDto.serialNumber, result))
|
"carbs=${carbsDto.carbs}, pumpSerial=${carbsDto.serialNumber}] - Result: $result")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addTemporaryBasalRateWithTempId(temporaryBasal: PumpDbEntryTBR, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator): Boolean {
|
fun addTemporaryBasalRateWithTempId(temporaryBasal: PumpDbEntryTBR, writeToInternalHistory: Boolean, creator: PumpSyncEntriesCreator): Boolean {
|
||||||
|
@ -151,42 +168,52 @@ class PumpSyncStorage @Inject constructor(
|
||||||
creator.serialNumber())
|
creator.serialNumber())
|
||||||
|
|
||||||
if (response && writeToInternalHistory) {
|
if (response && writeToInternalHistory) {
|
||||||
val innerList: MutableList<PumpDbEntry> = pumpSyncStorage[TBR]!!
|
val dbEntry = PumpDbEntryTBR(temporaryId = temporaryId,
|
||||||
|
date = timeNow,
|
||||||
|
pumpType = creator.model(),
|
||||||
|
serialNumber = creator.serialNumber(),
|
||||||
|
entry = temporaryBasal,
|
||||||
|
pumpId=null)
|
||||||
|
|
||||||
innerList.add(PumpDbEntry(temporaryId, timeNow, creator.model(), creator.serialNumber(), null, temporaryBasal))
|
aapsLogger.debug("PumpDbEntryTBR: $dbEntry")
|
||||||
pumpSyncStorage[BOLUS] = innerList
|
|
||||||
saveStorage()
|
pumpSyncStorageTBR.add(dbEntry)
|
||||||
|
saveStorageTBR()
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeBolusWithTemporaryId(temporaryId: Long) {
|
fun removeBolusWithTemporaryId(temporaryId: Long) {
|
||||||
val bolusList = removeTemporaryId(temporaryId, pumpSyncStorage[BOLUS]!!)
|
var dbEntry: PumpDbEntryBolus? = null
|
||||||
pumpSyncStorage[BOLUS] = bolusList
|
|
||||||
saveStorage()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeTemporaryBasalWithTemporaryId(temporaryId: Long) {
|
for (pumpDbEntry in pumpSyncStorageBolus) {
|
||||||
val tbrList = removeTemporaryId(temporaryId, pumpSyncStorage[TBR]!!)
|
|
||||||
pumpSyncStorage[TBR] = tbrList
|
|
||||||
saveStorage()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeTemporaryId(temporaryId: Long, list: MutableList<PumpDbEntry>): MutableList<PumpDbEntry> {
|
|
||||||
var dbEntry: PumpDbEntry? = null
|
|
||||||
|
|
||||||
for (pumpDbEntry in list) {
|
|
||||||
if (pumpDbEntry.temporaryId == temporaryId) {
|
if (pumpDbEntry.temporaryId == temporaryId) {
|
||||||
dbEntry = pumpDbEntry
|
dbEntry = pumpDbEntry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbEntry != null) {
|
if (dbEntry != null) {
|
||||||
list.remove(dbEntry)
|
pumpSyncStorageBolus.remove(dbEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
return list
|
saveStorageBolus()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeTemporaryBasalWithTemporaryId(temporaryId: Long) {
|
||||||
|
var dbEntry: PumpDbEntryTBR? = null
|
||||||
|
|
||||||
|
for (pumpDbEntry in pumpSyncStorageTBR) {
|
||||||
|
if (pumpDbEntry.temporaryId == temporaryId) {
|
||||||
|
dbEntry = pumpDbEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbEntry != null) {
|
||||||
|
pumpSyncStorageTBR.remove(dbEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
saveStorageTBR()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.S
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SetPreamble
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.command.SetPreamble
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioPacket
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RadioResponse
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.device.OrangeLinkImpl
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusGeneralFragment
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusGeneralFragment
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusHistoryFragment
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusHistoryFragment
|
||||||
|
@ -30,6 +31,7 @@ abstract class RileyLinkModule {
|
||||||
@ContributesAndroidInjector abstract fun sendAndListenProvider(): SendAndListen
|
@ContributesAndroidInjector abstract fun sendAndListenProvider(): SendAndListen
|
||||||
@ContributesAndroidInjector abstract fun setPreambleProvider(): SetPreamble
|
@ContributesAndroidInjector abstract fun setPreambleProvider(): SetPreamble
|
||||||
@ContributesAndroidInjector abstract fun radioPacketProvider(): RadioPacket
|
@ContributesAndroidInjector abstract fun radioPacketProvider(): RadioPacket
|
||||||
|
@ContributesAndroidInjector abstract fun orangeLinkDeviceProvider(): OrangeLinkImpl
|
||||||
|
|
||||||
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
|
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
|
||||||
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
|
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class RFSpy {
|
||||||
private final UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA);
|
private final UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA);
|
||||||
private final UUID radioVersionUUID = UUID.fromString(GattAttributes.CHARA_RADIO_VERSION);
|
private final UUID radioVersionUUID = UUID.fromString(GattAttributes.CHARA_RADIO_VERSION);
|
||||||
private final UUID batteryServiceUUID = UUID.fromString(GattAttributes.SERVICE_BATTERY);
|
private final UUID batteryServiceUUID = UUID.fromString(GattAttributes.SERVICE_BATTERY);
|
||||||
private final UUID batteryLevelUUID = UUID.fromString(GattAttributes.CHARA_BATTERY_UNK);
|
private final UUID batteryLevelUUID = UUID.fromString(GattAttributes.CHARA_BATTERY_LEVEL);
|
||||||
private String bleVersion; // We don't use it so no need of sofisticated logic
|
private String bleVersion; // We don't use it so no need of sofisticated logic
|
||||||
private Double currentFrequencyMHz;
|
private Double currentFrequencyMHz;
|
||||||
private long nextBatteryCheck = 0;
|
private long nextBatteryCheck = 0;
|
||||||
|
@ -103,6 +103,10 @@ public class RFSpy {
|
||||||
String cc1110Version = getCC1110Version();
|
String cc1110Version = getCC1110Version();
|
||||||
rileyLinkServiceData.versionCC110 = cc1110Version;
|
rileyLinkServiceData.versionCC110 = cc1110Version;
|
||||||
rileyLinkServiceData.firmwareVersion = getFirmwareVersion(aapsLogger, bleVersion, cc1110Version);
|
rileyLinkServiceData.firmwareVersion = getFirmwareVersion(aapsLogger, bleVersion, cc1110Version);
|
||||||
|
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM,
|
||||||
|
String.format("RileyLink - BLE Version: %s, CC1110 Version: %s, Firmware Version: %s",
|
||||||
|
bleVersion, cc1110Version, rileyLinkServiceData.firmwareVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this from the "response count" notification handler.
|
// Call this from the "response count" notification handler.
|
||||||
|
|
|
@ -8,19 +8,11 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.bluetooth.BluetoothGattDescriptor;
|
import android.bluetooth.BluetoothGattDescriptor;
|
||||||
import android.bluetooth.BluetoothGattService;
|
import android.bluetooth.BluetoothGattService;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.le.BluetoothLeScanner;
|
|
||||||
import android.bluetooth.le.ScanCallback;
|
|
||||||
import android.bluetooth.le.ScanFilter;
|
|
||||||
import android.bluetooth.le.ScanResult;
|
|
||||||
import android.bluetooth.le.ScanSettings;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -34,6 +26,7 @@ import info.nightscout.androidaps.logging.LTag;
|
||||||
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.RileyLinkUtil;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.device.OrangeLinkImpl;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperation;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperation;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.CharacteristicReadOperation;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.CharacteristicReadOperation;
|
||||||
|
@ -57,6 +50,7 @@ public class RileyLinkBLE {
|
||||||
@Inject RileyLinkServiceData rileyLinkServiceData;
|
@Inject RileyLinkServiceData rileyLinkServiceData;
|
||||||
@Inject RileyLinkUtil rileyLinkUtil;
|
@Inject RileyLinkUtil rileyLinkUtil;
|
||||||
@Inject SP sp;
|
@Inject SP sp;
|
||||||
|
@Inject OrangeLinkImpl orangeLink;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final boolean gattDebugEnabled = true;
|
private final boolean gattDebugEnabled = true;
|
||||||
|
@ -75,6 +69,8 @@ public class RileyLinkBLE {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
|
||||||
|
//orangeLink.rileyLinkBLE = this;
|
||||||
|
|
||||||
bluetoothGattCallback = new BluetoothGattCallback() {
|
bluetoothGattCallback = new BluetoothGattCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,16 +89,7 @@ public class RileyLinkBLE {
|
||||||
radioResponseCountNotified.run();
|
radioResponseCountNotified.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characteristic.getUuid().toString().equals(GattAttributes.UUID_NOTIF_CHARACTER.toString())) {
|
orangeLink.onCharacteristicChanged(characteristic);
|
||||||
final byte[] data = characteristic.getValue();
|
|
||||||
int first = 0xff & data[0];
|
|
||||||
aapsLogger.info(LTag.PUMPBTCOMM,
|
|
||||||
"onCharacteristicChanged " + ByteUtil.shortHexString(characteristic.getValue()) + "=====" + first);
|
|
||||||
String fv = data[3] + "." + data[4];
|
|
||||||
String hv = data[5] + "." + data[6];
|
|
||||||
rileyLinkServiceData.versionOrangeFV = fv;
|
|
||||||
rileyLinkServiceData.versionOrangeHV = hv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,6 +229,9 @@ public class RileyLinkBLE {
|
||||||
final List<BluetoothGattService> services = gatt.getServices();
|
final List<BluetoothGattService> services = gatt.getServices();
|
||||||
|
|
||||||
boolean rileyLinkFound = false;
|
boolean rileyLinkFound = false;
|
||||||
|
orangeLink.resetOrangeLinkData();
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder("RileyLink Device Debug\n");
|
||||||
|
|
||||||
for (BluetoothGattService service : services) {
|
for (BluetoothGattService service : services) {
|
||||||
final UUID uuidService = service.getUuid();
|
final UUID uuidService = service.getUuid();
|
||||||
|
@ -251,14 +241,14 @@ public class RileyLinkBLE {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gattDebugEnabled) {
|
if (gattDebugEnabled) {
|
||||||
debugService(service, 0);
|
debugService(service, 0, stringBuilder);
|
||||||
}
|
|
||||||
if (GattAttributes.isOrange(uuidService)) {
|
|
||||||
rileyLinkServiceData.isOrange = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
orangeLink.checkIsOrange(uuidService);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gattDebugEnabled) {
|
if (gattDebugEnabled) {
|
||||||
|
aapsLogger.warn(LTag.PUMPBTCOMM, stringBuilder.toString());
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "onServicesDiscovered " + getGattStatusMessage(status));
|
aapsLogger.warn(LTag.PUMPBTCOMM, "onServicesDiscovered " + getGattStatusMessage(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +274,7 @@ public class RileyLinkBLE {
|
||||||
@Inject
|
@Inject
|
||||||
public void onInit() {
|
public void onInit() {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "BT Adapter: " + this.bluetoothAdapter);
|
aapsLogger.debug(LTag.PUMPBTCOMM, "BT Adapter: " + this.bluetoothAdapter);
|
||||||
|
this.orangeLink.rileyLinkBLE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,6 +291,7 @@ public class RileyLinkBLE {
|
||||||
if (isAnyRileyLinkServiceFound(serviceI)) {
|
if (isAnyRileyLinkServiceFound(serviceI)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
orangeLink.checkIsOrange(serviceI.getUuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +304,7 @@ public class RileyLinkBLE {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void debugService(BluetoothGattService service, int indentCount) {
|
public void debugService(BluetoothGattService service, int indentCount, StringBuilder stringBuilder) {
|
||||||
|
|
||||||
String indentString = StringUtils.repeat(' ', indentCount);
|
String indentString = StringUtils.repeat(' ', indentCount);
|
||||||
|
|
||||||
|
@ -321,7 +313,7 @@ public class RileyLinkBLE {
|
||||||
if (gattDebugEnabled) {
|
if (gattDebugEnabled) {
|
||||||
final String uuidServiceString = uuidService.toString();
|
final String uuidServiceString = uuidService.toString();
|
||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
//StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
||||||
stringBuilder.append(indentString);
|
stringBuilder.append(indentString);
|
||||||
stringBuilder.append(GattAttributes.lookup(uuidServiceString, "Unknown service"));
|
stringBuilder.append(GattAttributes.lookup(uuidServiceString, "Unknown service"));
|
||||||
|
@ -338,12 +330,12 @@ public class RileyLinkBLE {
|
||||||
|
|
||||||
stringBuilder.append("\n\n");
|
stringBuilder.append("\n\n");
|
||||||
|
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, stringBuilder.toString());
|
//aapsLogger.warn(LTag.PUMPBTCOMM, stringBuilder.toString());
|
||||||
|
|
||||||
List<BluetoothGattService> includedServices = service.getIncludedServices();
|
List<BluetoothGattService> includedServices = service.getIncludedServices();
|
||||||
|
|
||||||
for (BluetoothGattService serviceI : includedServices) {
|
for (BluetoothGattService serviceI : includedServices) {
|
||||||
debugService(serviceI, indentCount + 4);
|
debugService(serviceI, indentCount + 4, stringBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,53 +375,46 @@ public class RileyLinkBLE {
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, "Error setting response count notification");
|
aapsLogger.error(LTag.PUMPBTCOMM, "Error setting response count notification");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(rileyLinkServiceData.isOrange){
|
|
||||||
enableNotificationsOrange();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public boolean enableNotificationsOrange() {
|
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, "enableNotificationsORG");
|
|
||||||
BLECommOperationResult result = setNotification_blocking(GattAttributes.UUID_NOTIF_SERVICE, //
|
|
||||||
GattAttributes.UUID_NOTIF_CHARACTER);
|
|
||||||
if (result.resultCode != BLECommOperationResult.RESULT_SUCCESS) {
|
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, "Error setting response count notification");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String macAddress;
|
|
||||||
|
|
||||||
public void findRileyLink(String RileyLinkAddress) {
|
if (rileyLinkServiceData.isOrange) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLink address: " + RileyLinkAddress);
|
return orangeLink.enableNotifications();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void findRileyLink(String rileyLinkAddress) {
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLink address: " + rileyLinkAddress);
|
||||||
// Must verify that this is a valid MAC, or crash.
|
// Must verify that this is a valid MAC, or crash.
|
||||||
macAddress = RileyLinkAddress;
|
//macAddress = RileyLinkAddress;
|
||||||
boolean useScanning = sp.getBoolean(RileyLinkConst.Prefs.OrangeUseScanning, false);
|
boolean useScanning = sp.getBoolean(RileyLinkConst.Prefs.OrangeUseScanning, false);
|
||||||
if (useScanning) {
|
if (useScanning) {
|
||||||
startScan();
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Start scan for OrangeLink device.");
|
||||||
|
orangeLink.startScan();
|
||||||
} else {
|
} else {
|
||||||
rileyLinkDevice = bluetoothAdapter.getRemoteDevice(RileyLinkAddress);
|
rileyLinkDevice = bluetoothAdapter.getRemoteDevice(rileyLinkAddress);
|
||||||
// if this succeeds, we get a connection state change callback?
|
// if this succeeds, we get a connection state change callback?
|
||||||
if (rileyLinkDevice != null) {
|
if (rileyLinkDevice != null) {
|
||||||
connectGatt();
|
connectGattInternal();
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device not found with address: " + RileyLinkAddress);
|
aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device not found with address: " + rileyLinkAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connectGattCheckOrange() {
|
public void connectGatt() {
|
||||||
boolean useScanning = sp.getBoolean(RileyLinkConst.Prefs.OrangeUseScanning, false);
|
boolean useScanning = sp.getBoolean(RileyLinkConst.Prefs.OrangeUseScanning, false);
|
||||||
if (useScanning) {
|
if (useScanning) {
|
||||||
startScan();
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Start scan for OrangeLink device.");
|
||||||
|
orangeLink.startScan();
|
||||||
} else {
|
} else {
|
||||||
connectGatt();
|
connectGattInternal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This function must be run on UI thread.
|
// This function must be run on UI thread.
|
||||||
public void connectGatt() {
|
public void connectGattInternal() {
|
||||||
if (this.rileyLinkDevice == null) {
|
if (this.rileyLinkDevice == null) {
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device is null, can't do connectGatt.");
|
aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device is null, can't do connectGatt.");
|
||||||
return;
|
return;
|
||||||
|
@ -478,7 +463,7 @@ public class RileyLinkBLE {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private BLECommOperationResult setNotification_blocking(UUID serviceUUID, UUID charaUUID) {
|
public BLECommOperationResult setNotification_blocking(UUID serviceUUID, UUID charaUUID) {
|
||||||
BLECommOperationResult rval = new BLECommOperationResult();
|
BLECommOperationResult rval = new BLECommOperationResult();
|
||||||
if (bluetoothConnectionGatt != null) {
|
if (bluetoothConnectionGatt != null) {
|
||||||
|
|
||||||
|
@ -643,116 +628,11 @@ public class RileyLinkBLE {
|
||||||
return statusMessage;
|
return statusMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ScanFilter> buildScanFilters() {
|
public void setRileyLinkDevice(BluetoothDevice device) {
|
||||||
ArrayList scanFilterList = new ArrayList<>();
|
this.rileyLinkDevice = device;
|
||||||
ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder();
|
|
||||||
scanFilterBuilder.setDeviceAddress(macAddress);
|
|
||||||
scanFilterList.add(scanFilterBuilder.build());
|
|
||||||
return scanFilterList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScanSettings buildScanSettings() {
|
public BluetoothAdapter getBluetoothAdapter() {
|
||||||
ScanSettings.Builder scanSettingBuilder = new ScanSettings.Builder();
|
return bluetoothAdapter;
|
||||||
scanSettingBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
|
|
||||||
scanSettingBuilder.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE);
|
|
||||||
scanSettingBuilder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
|
|
||||||
return scanSettingBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startScan() {
|
|
||||||
try {
|
|
||||||
stopScan();
|
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "startScan");
|
|
||||||
handler.sendEmptyMessageDelayed(TIME_OUT_WHAT, TIME_OUT);
|
|
||||||
BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
|
||||||
if (bluetoothLeScanner == null) {
|
|
||||||
bluetoothAdapter.startLeScan(mLeScanCallback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), scanCallback);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ScanCallback scanCallback = new ScanCallback() {
|
|
||||||
@Override
|
|
||||||
public void onScanResult(int callbackType, ScanResult result) {
|
|
||||||
super.onScanResult(callbackType, result);
|
|
||||||
String name = result.getDevice().getName();
|
|
||||||
String address = result.getDevice().getAddress();
|
|
||||||
if (macAddress.equals(address)) {
|
|
||||||
stopScan();
|
|
||||||
rileyLinkDevice = result.getDevice();
|
|
||||||
connectGatt();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBatchScanResults(List<ScanResult> results) {
|
|
||||||
super.onBatchScanResults(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScanFailed(int errorCode) {
|
|
||||||
super.onScanFailed(errorCode);
|
|
||||||
stopScan();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
|
|
||||||
public void onLeScan(final BluetoothDevice device, final int rssi,
|
|
||||||
final byte[] scanRecord) {
|
|
||||||
if (macAddress.equals(device.getAddress())) {
|
|
||||||
stopScan();
|
|
||||||
rileyLinkDevice = device;
|
|
||||||
connectGatt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final int TIME_OUT = 90 * 1000;
|
|
||||||
public static final int TIME_OUT_WHAT = 0x12;
|
|
||||||
Handler handler = new Handler() {
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
super.handleMessage(msg);
|
|
||||||
switch (msg.what) {
|
|
||||||
case TIME_OUT_WHAT:
|
|
||||||
stopScan();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void stopScan() {
|
|
||||||
handler.removeMessages(TIME_OUT_WHAT);
|
|
||||||
if (bluetoothAdapter == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
|
||||||
if (bluetoothLeScanner == null) {
|
|
||||||
if (isBluetoothAvailable()) {
|
|
||||||
bluetoothAdapter.stopLeScan(mLeScanCallback);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isBluetoothAvailable()) {
|
|
||||||
bluetoothLeScanner.stopScan(scanCallback);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
aapsLogger.error(LTag.PUMPBTCOMM, e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBluetoothAvailable() {
|
|
||||||
return (bluetoothAdapter != null &&
|
|
||||||
bluetoothAdapter.isEnabled() &&
|
|
||||||
bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,20 @@ public class GattAttributes {
|
||||||
|
|
||||||
public static String PREFIX = "0000";
|
public static String PREFIX = "0000";
|
||||||
public static String SUFFIX = "-0000-1000-8000-00805f9b34fb";
|
public static String SUFFIX = "-0000-1000-8000-00805f9b34fb";
|
||||||
public static String SERVICE_GAP = PREFIX + "1800" + SUFFIX;
|
|
||||||
public static String CHARA_GAP_NAME = PREFIX + "2a00" + SUFFIX; // RileyLink RFSpy
|
|
||||||
public static String CHARA_GAP_NUM = PREFIX + "2a01" + SUFFIX; // 0000
|
|
||||||
public static String CHARA_GAP_UNK = PREFIX + "2a01" + SUFFIX; // a
|
|
||||||
|
|
||||||
|
// Generic Access
|
||||||
|
public static String SERVICE_GA = PREFIX + "1800" + SUFFIX;
|
||||||
|
public static String CHARA_GA_NAME = PREFIX + "2a00" + SUFFIX; // RileyLink RFSpy
|
||||||
|
public static String CHARA_GA_APPEARANCE = PREFIX + "2a01" + SUFFIX; // 0000
|
||||||
|
public static String CHARA_GA_PPCP = PREFIX + "2a04" + SUFFIX; // 0000
|
||||||
|
public static String CHARA_GA_CAR = PREFIX + "2aa6" + SUFFIX; // 0000
|
||||||
|
|
||||||
|
// Generic Attribute
|
||||||
|
public static String SERVICE_G_ATTR = PREFIX + "1801" + SUFFIX;
|
||||||
|
|
||||||
|
// Battery Service
|
||||||
public static String SERVICE_BATTERY = PREFIX + "180f" + SUFFIX; // Battery
|
public static String SERVICE_BATTERY = PREFIX + "180f" + SUFFIX; // Battery
|
||||||
public static String CHARA_BATTERY_UNK = PREFIX + "2a19" + SUFFIX;
|
public static String CHARA_BATTERY_LEVEL = PREFIX + "2a19" + SUFFIX;
|
||||||
|
|
||||||
// RileyLink Radio Service
|
// RileyLink Radio Service
|
||||||
public static String SERVICE_RADIO = "0235733b-99c5-4197-b856-69219c2a3845";
|
public static String SERVICE_RADIO = "0235733b-99c5-4197-b856-69219c2a3845";
|
||||||
|
@ -29,9 +36,20 @@ public class GattAttributes {
|
||||||
public static String CHARA_RADIO_CUSTOM_NAME = "d93b2af0-1e28-11e4-8c21-0800200c9a66";
|
public static String CHARA_RADIO_CUSTOM_NAME = "d93b2af0-1e28-11e4-8c21-0800200c9a66";
|
||||||
public static String CHARA_RADIO_VERSION = "30d99dc9-7c91-4295-a051-0a104d238cf2";
|
public static String CHARA_RADIO_VERSION = "30d99dc9-7c91-4295-a051-0a104d238cf2";
|
||||||
public static String CHARA_RADIO_LED_MODE = "c6d84241-f1a7-4f9c-a25f-fce16732f14e";
|
public static String CHARA_RADIO_LED_MODE = "c6d84241-f1a7-4f9c-a25f-fce16732f14e";
|
||||||
//Orange Radio Service
|
|
||||||
public static UUID UUID_NOTIF_SERVICE = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
|
// Secure DFU Service (Orange 1.5 - 3.2)
|
||||||
public static UUID UUID_NOTIF_CHARACTER = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
|
public static String SERVICE_DFU = "0000fe59-0000-1000-8000-00805f9b34fb";
|
||||||
|
public static String CHARA_BUTTONLESS_DFU = "8ec90003-f315-4f60-9fb8-838830daea50";
|
||||||
|
|
||||||
|
// Nordic UART Service (Orange 2.1 - 3.2)
|
||||||
|
public static String SERVICE_NORDIC_UART = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
|
public static String CHARA_NORDIC_RX = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
|
public static String CHARA_NORDIC_TX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
|
|
||||||
|
|
||||||
|
// Orange Radio Service
|
||||||
|
public static String SERVICE_RADIO_ORANGE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
|
public static String CHARA_NOTIFICATION_ORANGE = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
|
|
||||||
private static final Map<String, String> attributes;
|
private static final Map<String, String> attributes;
|
||||||
private static final Map<String, String> attributesRileyLinkSpecific;
|
private static final Map<String, String> attributesRileyLinkSpecific;
|
||||||
|
@ -40,13 +58,18 @@ public class GattAttributes {
|
||||||
static {
|
static {
|
||||||
attributes = new HashMap<>();
|
attributes = new HashMap<>();
|
||||||
|
|
||||||
attributes.put(SERVICE_GAP, "Device Information Service");
|
attributes.put(SERVICE_GA, "Generic Access");
|
||||||
attributes.put(CHARA_GAP_NAME, "Name"); //
|
attributes.put(CHARA_GA_NAME, "Device Name"); //
|
||||||
attributes.put(CHARA_GAP_NUM, "Number"); //
|
attributes.put(CHARA_GA_APPEARANCE, "Appearance"); //
|
||||||
|
attributes.put(CHARA_GA_PPCP, "Peripheral Preffered Connection Parameters");
|
||||||
|
attributes.put(CHARA_GA_CAR, "Central Address Resolution");
|
||||||
|
|
||||||
|
attributes.put(SERVICE_G_ATTR, "Generic Attribute");
|
||||||
|
|
||||||
attributes.put(SERVICE_BATTERY, "Battery Service");
|
attributes.put(SERVICE_BATTERY, "Battery Service");
|
||||||
|
attributes.put(CHARA_BATTERY_LEVEL, "Battery Level");
|
||||||
|
|
||||||
attributes.put(SERVICE_RADIO, "Radio Interface"); // a
|
attributes.put(SERVICE_RADIO, "Radio Interface Service");
|
||||||
attributes.put(CHARA_RADIO_CUSTOM_NAME, "Custom Name");
|
attributes.put(CHARA_RADIO_CUSTOM_NAME, "Custom Name");
|
||||||
attributes.put(CHARA_RADIO_DATA, "Data");
|
attributes.put(CHARA_RADIO_DATA, "Data");
|
||||||
attributes.put(CHARA_RADIO_RESPONSE_COUNT, "Response Count");
|
attributes.put(CHARA_RADIO_RESPONSE_COUNT, "Response Count");
|
||||||
|
@ -54,6 +77,13 @@ public class GattAttributes {
|
||||||
attributes.put(CHARA_RADIO_VERSION, "Version"); // firmwareVersion
|
attributes.put(CHARA_RADIO_VERSION, "Version"); // firmwareVersion
|
||||||
attributes.put(CHARA_RADIO_LED_MODE, "Led Mode");
|
attributes.put(CHARA_RADIO_LED_MODE, "Led Mode");
|
||||||
|
|
||||||
|
attributes.put(SERVICE_DFU, "Secure DFU Service");
|
||||||
|
attributes.put(CHARA_BUTTONLESS_DFU, "Buttonless DFU");
|
||||||
|
|
||||||
|
attributes.put(SERVICE_NORDIC_UART, "Nordic UART Service");
|
||||||
|
attributes.put(CHARA_NORDIC_RX, "RX Characteristic");
|
||||||
|
attributes.put(CHARA_NORDIC_TX, "TX Characteristic");
|
||||||
|
|
||||||
attributesRileyLinkSpecific = new HashMap<>();
|
attributesRileyLinkSpecific = new HashMap<>();
|
||||||
|
|
||||||
attributesRileyLinkSpecific.put(SERVICE_RADIO, "Radio Interface"); // a
|
attributesRileyLinkSpecific.put(SERVICE_RADIO, "Radio Interface"); // a
|
||||||
|
@ -63,6 +93,9 @@ public class GattAttributes {
|
||||||
attributesRileyLinkSpecific.put(CHARA_RADIO_TIMER_TICK, "Timer Tick");
|
attributesRileyLinkSpecific.put(CHARA_RADIO_TIMER_TICK, "Timer Tick");
|
||||||
attributesRileyLinkSpecific.put(CHARA_RADIO_VERSION, "Version"); // firmwareVersion
|
attributesRileyLinkSpecific.put(CHARA_RADIO_VERSION, "Version"); // firmwareVersion
|
||||||
attributesRileyLinkSpecific.put(CHARA_RADIO_LED_MODE, "Led Mode");
|
attributesRileyLinkSpecific.put(CHARA_RADIO_LED_MODE, "Led Mode");
|
||||||
|
|
||||||
|
attributesRileyLinkSpecific.put(SERVICE_RADIO_ORANGE, "Orange Radio Interface");
|
||||||
|
attributesRileyLinkSpecific.put(CHARA_NOTIFICATION_ORANGE, "Orange Notification");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,8 +119,10 @@ public class GattAttributes {
|
||||||
public static boolean isRileyLink(UUID uuid) {
|
public static boolean isRileyLink(UUID uuid) {
|
||||||
return attributesRileyLinkSpecific.containsKey(uuid.toString());
|
return attributesRileyLinkSpecific.containsKey(uuid.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isOrange(UUID uuid) {
|
public static boolean isOrange(UUID uuid) {
|
||||||
return UUID_NOTIF_SERVICE.equals(uuid.toString());
|
return SERVICE_RADIO_ORANGE.equals(uuid.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.device
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.bluetooth.BluetoothAdapter.LeScanCallback
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
|
import android.bluetooth.le.BluetoothLeScanner
|
||||||
|
import android.bluetooth.le.ScanCallback
|
||||||
|
import android.bluetooth.le.ScanFilter
|
||||||
|
import android.bluetooth.le.ScanResult
|
||||||
|
import android.bluetooth.le.ScanSettings
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Message
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import java.lang.Exception
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class OrangeLinkImpl @Inject constructor(
|
||||||
|
var aapsLogger: AAPSLogger,
|
||||||
|
var rileyLinkServiceData: RileyLinkServiceData,
|
||||||
|
var rileyLinkUtil: RileyLinkUtil,
|
||||||
|
var sp: SP) {
|
||||||
|
|
||||||
|
lateinit var rileyLinkBLE: RileyLinkBLE
|
||||||
|
|
||||||
|
fun onCharacteristicChanged(characteristic: BluetoothGattCharacteristic) {
|
||||||
|
if (characteristic.uuid.toString().equals(GattAttributes.CHARA_NOTIFICATION_ORANGE)) {
|
||||||
|
val data = characteristic.value
|
||||||
|
val first = 0xff and data[0].toInt()
|
||||||
|
aapsLogger.info(LTag.PUMPBTCOMM,
|
||||||
|
"OrangeLinkImpl: onCharacteristicChanged " + ByteUtil.shortHexString(characteristic.value) + "=====" + first)
|
||||||
|
val fv = data[3].toString() + "." + data[4]
|
||||||
|
val hv = data[5].toString() + "." + data[6]
|
||||||
|
rileyLinkServiceData.versionOrangeFirmware = fv
|
||||||
|
rileyLinkServiceData.versionOrangeHardware = hv
|
||||||
|
|
||||||
|
aapsLogger.info(LTag.PUMPBTCOMM, "OrangeLink: Firmware: ${fv}, Hardware: ${hv}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun resetOrangeLinkData() {
|
||||||
|
rileyLinkServiceData.isOrange = false
|
||||||
|
rileyLinkServiceData.versionOrangeFirmware = null
|
||||||
|
rileyLinkServiceData.versionOrangeHardware = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are checking if this is special Orange (with ORANGE_NOTIFICTION_SERVICE)
|
||||||
|
*/
|
||||||
|
fun checkIsOrange(uuidService: UUID) {
|
||||||
|
if (GattAttributes.isOrange(uuidService)) {
|
||||||
|
rileyLinkServiceData.isOrange = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun enableNotifications(): Boolean {
|
||||||
|
aapsLogger.info(LTag.PUMPBTCOMM, "OrangeLinkImpl::enableNotifications")
|
||||||
|
val result: BLECommOperationResult = rileyLinkBLE.setNotification_blocking(
|
||||||
|
UUID.fromString(GattAttributes.SERVICE_RADIO_ORANGE), //
|
||||||
|
UUID.fromString(GattAttributes.CHARA_NOTIFICATION_ORANGE)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result.resultCode != BLECommOperationResult.RESULT_SUCCESS) {
|
||||||
|
aapsLogger.error(LTag.PUMPBTCOMM, "Error setting response count notification")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun buildScanFilters(): List<ScanFilter> {
|
||||||
|
val scanFilterList: MutableList<ScanFilter> = mutableListOf() //ArrayList<*> = ArrayList<Any>()
|
||||||
|
val scanFilterBuilder = ScanFilter.Builder()
|
||||||
|
scanFilterBuilder.setDeviceAddress(rileyLinkServiceData.rileyLinkAddress)
|
||||||
|
scanFilterList.add(scanFilterBuilder.build())
|
||||||
|
return scanFilterList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildScanSettings(): ScanSettings? {
|
||||||
|
val scanSettingBuilder = ScanSettings.Builder()
|
||||||
|
scanSettingBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
||||||
|
scanSettingBuilder.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
|
||||||
|
scanSettingBuilder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
|
||||||
|
return scanSettingBuilder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startScan() {
|
||||||
|
try {
|
||||||
|
stopScan()
|
||||||
|
val bluetoothAdapter = rileyLinkBLE.getBluetoothAdapter()
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "startScan")
|
||||||
|
handler.sendEmptyMessageDelayed(TIME_OUT_WHAT, TIME_OUT.toLong())
|
||||||
|
val bluetoothLeScanner: BluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
|
||||||
|
// if (bluetoothLeScanner == null) {
|
||||||
|
// bluetoothAdapter.startLeScan(mLeScanCallback)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
bluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), scanCallback)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
aapsLogger.error(LTag.PUMPBTCOMM, "Start scan: ${e.message}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var scanCallback: ScanCallback = object : ScanCallback() {
|
||||||
|
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||||
|
super.onScanResult(callbackType, result)
|
||||||
|
//val name = result.device.name
|
||||||
|
val address = result.device.address
|
||||||
|
if (rileyLinkServiceData.rileyLinkAddress.equals(address)) {
|
||||||
|
stopScan()
|
||||||
|
rileyLinkBLE.rileyLinkDevice = result.device
|
||||||
|
rileyLinkBLE.connectGattInternal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBatchScanResults(results: List<ScanResult>) {
|
||||||
|
super.onBatchScanResults(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScanFailed(errorCode: Int) {
|
||||||
|
super.onScanFailed(errorCode)
|
||||||
|
stopScan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val mLeScanCallback = LeScanCallback { device, _, _ ->
|
||||||
|
if (rileyLinkServiceData.rileyLinkAddress.equals(device.address)) {
|
||||||
|
stopScan()
|
||||||
|
rileyLinkBLE.rileyLinkDevice = device
|
||||||
|
rileyLinkBLE.connectGattInternal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val TIME_OUT = 90 * 1000
|
||||||
|
val TIME_OUT_WHAT = 0x12
|
||||||
|
|
||||||
|
var handler: Handler = object : Handler() {
|
||||||
|
override fun handleMessage(msg: Message) {
|
||||||
|
super.handleMessage(msg)
|
||||||
|
when (msg.what) {
|
||||||
|
TIME_OUT_WHAT -> stopScan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopScan() {
|
||||||
|
handler.removeMessages(TIME_OUT_WHAT)
|
||||||
|
|
||||||
|
val bluetoothAdapter = rileyLinkBLE.getBluetoothAdapter() ?: return
|
||||||
|
|
||||||
|
try {
|
||||||
|
val bluetoothLeScanner: BluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner()
|
||||||
|
|
||||||
|
if (isBluetoothAvailable()) {
|
||||||
|
bluetoothLeScanner.stopScan(scanCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
// if (bluetoothLeScanner == null) {
|
||||||
|
// if (isBluetoothAvailable()) {
|
||||||
|
// bluetoothAdapter.stopLeScan(mLeScanCallback)
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if (isBluetoothAvailable()) {
|
||||||
|
// bluetoothLeScanner.stopScan(scanCallback)
|
||||||
|
// }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
aapsLogger.error(LTag.PUMPBTCOMM, "Stop scan: ${e.message}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isBluetoothAvailable(): Boolean {
|
||||||
|
val bluetoothAdapter = rileyLinkBLE.getBluetoothAdapter()
|
||||||
|
return bluetoothAdapter != null &&
|
||||||
|
bluetoothAdapter.isEnabled() &&
|
||||||
|
bluetoothAdapter.getState() == BluetoothAdapter.STATE_ON
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -91,8 +91,6 @@ public class RileyLinkStatusGeneralFragment extends DaggerFragment implements Re
|
||||||
|
|
||||||
this.connectionStatus.setText(resourceHelper.gs(rileyLinkServiceData.rileyLinkServiceState.getResourceId()));
|
this.connectionStatus.setText(resourceHelper.gs(rileyLinkServiceData.rileyLinkServiceState.getResourceId()));
|
||||||
|
|
||||||
// BS FIXME rileyLinkServiceData is injected so I suppose it cannot be null?
|
|
||||||
if (rileyLinkServiceData != null) {
|
|
||||||
this.configuredRileyLinkAddress.setText(Optional.ofNullable(rileyLinkServiceData.rileyLinkAddress).orElse(PLACEHOLDER));
|
this.configuredRileyLinkAddress.setText(Optional.ofNullable(rileyLinkServiceData.rileyLinkAddress).orElse(PLACEHOLDER));
|
||||||
this.configuredRileyLinkName.setText(Optional.ofNullable(rileyLinkServiceData.rileyLinkName).orElse(PLACEHOLDER));
|
this.configuredRileyLinkName.setText(Optional.ofNullable(rileyLinkServiceData.rileyLinkName).orElse(PLACEHOLDER));
|
||||||
|
|
||||||
|
@ -108,13 +106,14 @@ public class RileyLinkStatusGeneralFragment extends DaggerFragment implements Re
|
||||||
this.connectionError.setText(rileyLinkError == null ? PLACEHOLDER : resourceHelper.gs(rileyLinkError.getResourceId(targetDevice)));
|
this.connectionError.setText(rileyLinkError == null ? PLACEHOLDER : resourceHelper.gs(rileyLinkError.getResourceId(targetDevice)));
|
||||||
|
|
||||||
|
|
||||||
if(rileyLinkServiceData.isOrange){
|
if (rileyLinkServiceData.isOrange && rileyLinkServiceData.versionOrangeFirmware!=null) {
|
||||||
this.firmwareVersion.setText("FV:"+Optional.ofNullable(rileyLinkServiceData.versionOrangeFV).orElse(PLACEHOLDER)+"\nHV:"+Optional.ofNullable(rileyLinkServiceData.versionOrangeHV).orElse(PLACEHOLDER));
|
this.firmwareVersion.setText(resourceHelper.gs(R.string.rileylink_firmware_version_value_orange,
|
||||||
}else{
|
rileyLinkServiceData.versionOrangeFirmware,
|
||||||
|
Optional.ofNullable(rileyLinkServiceData.versionOrangeHardware).orElse(PLACEHOLDER)));
|
||||||
|
} else {
|
||||||
this.firmwareVersion.setText(resourceHelper.gs(R.string.rileylink_firmware_version_value,
|
this.firmwareVersion.setText(resourceHelper.gs(R.string.rileylink_firmware_version_value,
|
||||||
Optional.ofNullable(rileyLinkServiceData.versionBLE113).orElse(PLACEHOLDER), Optional.ofNullable(rileyLinkServiceData.versionCC110).orElse(PLACEHOLDER)));
|
Optional.ofNullable(rileyLinkServiceData.versionBLE113).orElse(PLACEHOLDER),
|
||||||
|
Optional.ofNullable(rileyLinkServiceData.versionCC110).orElse(PLACEHOLDER)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RileyLinkPumpDevice rileyLinkPumpDevice = (RileyLinkPumpDevice) activePlugin.getActivePump();
|
RileyLinkPumpDevice rileyLinkPumpDevice = (RileyLinkPumpDevice) activePlugin.getActivePump();
|
||||||
|
|
|
@ -48,9 +48,11 @@ public class RileyLinkServiceData {
|
||||||
public String versionBLE113;
|
public String versionBLE113;
|
||||||
// radio version
|
// radio version
|
||||||
public String versionCC110;
|
public String versionCC110;
|
||||||
|
|
||||||
|
// orangeLink
|
||||||
public boolean isOrange;
|
public boolean isOrange;
|
||||||
public String versionOrangeFV;
|
public String versionOrangeFirmware;
|
||||||
public String versionOrangeHV;
|
public String versionOrangeHardware;
|
||||||
|
|
||||||
public RileyLinkTargetDevice targetDevice;
|
public RileyLinkTargetDevice targetDevice;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class DiscoverGattServicesTask extends ServiceTask {
|
||||||
RileyLinkPumpDevice pumpDevice = (RileyLinkPumpDevice) activePlugin.getActivePump();
|
RileyLinkPumpDevice pumpDevice = (RileyLinkPumpDevice) activePlugin.getActivePump();
|
||||||
|
|
||||||
if (needToConnect) {
|
if (needToConnect) {
|
||||||
pumpDevice.getRileyLinkService().getRileyLinkBLE().connectGattCheckOrange();
|
pumpDevice.getRileyLinkService().getRileyLinkBLE().connectGatt();
|
||||||
}
|
}
|
||||||
|
|
||||||
pumpDevice.getRileyLinkService().getRileyLinkBLE().discoverServices();
|
pumpDevice.getRileyLinkService().getRileyLinkBLE().discoverServices();
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
<string name="rileylink_last_device_contact">Last Device Contact:</string>
|
<string name="rileylink_last_device_contact">Last Device Contact:</string>
|
||||||
<string name="rileylink_firmware_version">Firmware Version:</string>
|
<string name="rileylink_firmware_version">Firmware Version:</string>
|
||||||
<string name="rileylink_firmware_version_value">BLE113: %1$s\nCC110: %2$s</string>
|
<string name="rileylink_firmware_version_value">BLE113: %1$s\nCC110: %2$s</string>
|
||||||
|
<string name="rileylink_firmware_version_value_orange">Fw: %1$s\nHw: %2$s</string>
|
||||||
<string name="rileylink_pump_serial_number">Pump Serial Number:</string>
|
<string name="rileylink_pump_serial_number">Pump Serial Number:</string>
|
||||||
<string name="rileylink_pump_frequency">Pump Frequency:</string>
|
<string name="rileylink_pump_frequency">Pump Frequency:</string>
|
||||||
<string name="rileylink_pump_frequency_value">%1$.2f MHz</string>
|
<string name="rileylink_pump_frequency_value">%1$.2f MHz</string>
|
||||||
|
|
Loading…
Reference in a new issue