NSCv3: process ExtendedBolus

This commit is contained in:
Milos Kozak 2022-12-29 21:33:37 +01:00
parent a2522eed9d
commit 228b2ddaca
8 changed files with 159 additions and 75 deletions

View file

@ -4,17 +4,17 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
data class NSExtendedBolus( data class NSExtendedBolus(
override val date: Long, override val date: Long,
override val device: String?, override val device: String? = null,
override val identifier: String?, override val identifier: String?,
override val units: NsUnits?, override val units: NsUnits? = null,
override val srvModified: Long?, override val srvModified: Long? = null,
override val srvCreated: Long?, override val srvCreated: Long? = null,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String? = null,
override var isReadOnly: Boolean, override var isReadOnly: Boolean = false,
override val isValid: Boolean, override val isValid: Boolean,
override val eventType: EventType, override val eventType: EventType,
override val notes: String?, override val notes: String? = null,
override val pumpId: Long?, override val pumpId: Long?,
override val endId: Long?, override val endId: Long?,
override val pumpType: String?, override val pumpType: String?,
@ -22,5 +22,6 @@ data class NSExtendedBolus(
override var app: String? = null, override var app: String? = null,
val duration: Long, val duration: Long,
val enteredinsulin: Double, val enteredinsulin: Double,
val isEmulatingTempBasal: Boolean? val isEmulatingTempBasal: Boolean?,
val rate: Double?
) : NSTreatment ) : NSTreatment

View file

@ -25,7 +25,8 @@ data class NSTemporaryBasal(
val isAbsolute: Boolean, val isAbsolute: Boolean,
val type: Type, val type: Type,
val percent: Double? = null, // when sending to NS (rate - 100) val percent: Double? = null, // when sending to NS (rate - 100)
val absolute: Double? = null // when sending to NS (rate) val absolute: Double? = null, // when sending to NS (rate)
var extendedEmulated: NSExtendedBolus? = null
) : NSTreatment { ) : NSTreatment {
enum class Type { enum class Type {

View file

@ -112,22 +112,23 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
date = treatmentTimestamp, date = treatmentTimestamp,
device = device, device = device,
identifier = identifier, identifier = identifier,
units = NsUnits.fromString(extendedEmulated.units), units = NsUnits.fromString(extendedEmulated?.units),
srvModified = srvModified, srvModified = srvModified,
srvCreated = srvCreated, srvCreated = srvCreated,
utcOffset = utcOffset ?: 0, utcOffset = utcOffset ?: 0,
subject = subject, subject = subject,
isReadOnly = extendedEmulated.isReadOnly ?: false, isReadOnly = extendedEmulated?.isReadOnly ?: false,
isValid = extendedEmulated.isValid ?: true, isValid = extendedEmulated?.isValid ?: true,
eventType = extendedEmulated.eventType, eventType = EventType.COMBO_BOLUS,
notes = extendedEmulated.notes, notes = extendedEmulated?.notes,
pumpId = extendedEmulated.pumpId, pumpId = extendedEmulated?.pumpId,
endId = extendedEmulated.endId, endId = extendedEmulated?.endId,
pumpType = extendedEmulated.pumpType, pumpType = extendedEmulated?.pumpType,
pumpSerial = extendedEmulated.pumpSerial, pumpSerial = extendedEmulated?.pumpSerial,
enteredinsulin = extendedEmulated.enteredinsulin ?: 0.0, enteredinsulin = extendedEmulated?.enteredinsulin ?: 0.0,
duration = extendedEmulated.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(extendedEmulated.duration ?: 0L), duration = extendedEmulated?.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(extendedEmulated?.duration ?: 0L),
isEmulatingTempBasal = extendedEmulated.isEmulatingTempBasal isEmulatingTempBasal = extendedEmulated?.isEmulatingTempBasal,
rate = rate
) )
} }
@ -339,7 +340,8 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
pumpSerial = this.pumpSerial, pumpSerial = this.pumpSerial,
enteredinsulin = this.enteredinsulin, enteredinsulin = this.enteredinsulin,
duration = this.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(this.duration ?: 0L), duration = this.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(this.duration ?: 0L),
isEmulatingTempBasal = this.isEmulatingTempBasal isEmulatingTempBasal = this.isEmulatingTempBasal,
rate = rate
) )
} }
} }
@ -411,33 +413,7 @@ internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
targetTop = targetTop, targetTop = targetTop,
reason = reason.text reason = reason.text
) )
/*
// Convert back emulated TBR -> EB
eventType == EventType.TEMPORARY_BASAL && extendedEmulated != null ->
return RemoteTreatment(
date = treatmentTimestamp,
device = device,
identifier = identifier,
units = NsUnits.fromString(extendedEmulated.units),
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset ?: 0,
subject = subject,
isReadOnly = extendedEmulated.isReadOnly ?: false,
isValid = extendedEmulated.isValid ?: true,
eventType = extendedEmulated.eventType,
notes = extendedEmulated.notes,
pumpId = extendedEmulated.pumpId,
endId = extendedEmulated.endId,
pumpType = extendedEmulated.pumpType,
pumpSerial = extendedEmulated.pumpSerial,
enteredinsulin = extendedEmulated.enteredinsulin ?: 0.0,
duration = extendedEmulated.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(extendedEmulated.duration ?: 0L),
isEmulatingTempbasal = extendedEmulated.isEmulatingTempBasal
)
}
*/
is NSTemporaryBasal -> RemoteTreatment( is NSTemporaryBasal -> RemoteTreatment(
date = date, date = date,
device = device, device = device,
@ -460,7 +436,8 @@ internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
absolute = absolute, absolute = absolute,
percent = percent, percent = percent,
rate = rate, rate = rate,
type = type.name type = type.name,
extendedEmulated = extendedEmulated?.toRemoteTreatment()
) )
is NSEffectiveProfileSwitch -> RemoteTreatment( is NSEffectiveProfileSwitch -> RemoteTreatment(
@ -582,7 +559,8 @@ internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
reason = reason.name reason = reason.name
) )
is NSExtendedBolus -> RemoteTreatment( is NSExtendedBolus ->
RemoteTreatment(
date = date, date = date,
device = device, device = device,
identifier = identifier, identifier = identifier,
@ -594,15 +572,18 @@ internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
isReadOnly = isReadOnly, isReadOnly = isReadOnly,
isValid = isValid, isValid = isValid,
eventType = eventType, eventType = eventType,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
notes = notes, notes = notes,
splitNow = 0,
splitExt = 100,
enteredinsulin = enteredinsulin,
relative = rate,
isEmulatingTempBasal = isEmulatingTempBasal,
pumpId = pumpId, pumpId = pumpId,
endId = endId, endId = endId,
pumpType = pumpType, pumpType = pumpType,
pumpSerial = pumpSerial, pumpSerial = pumpSerial
enteredinsulin = enteredinsulin,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
isEmulatingTempBasal = isEmulatingTempBasal
) )
else -> null else -> null

View file

@ -74,7 +74,7 @@ internal data class RemoteTreatment(
@SerializedName("isEmulatingTempBasal") val isEmulatingTempBasal: Boolean? = null, // boolean "Combo Bolus", "extendedEmulated" (not in doc see below) @SerializedName("isEmulatingTempBasal") val isEmulatingTempBasal: Boolean? = null, // boolean "Combo Bolus", "extendedEmulated" (not in doc see below)
@SerializedName("isAnnouncement") val isAnnouncement: Boolean? = null, // boolean "Announcement" @SerializedName("isAnnouncement") val isAnnouncement: Boolean? = null, // boolean "Announcement"
@SerializedName("rate") val rate: Double? = null, // Double "Temp Basal" absolute rate (could be calculated with percent and profile information...) @SerializedName("rate") val rate: Double? = null, // Double "Temp Basal" absolute rate (could be calculated with percent and profile information...)
@SerializedName("extendedEmulated") val extendedEmulated: RemoteTreatment? = null, // Gson of emulated EB @SerializedName("extendedEmulated") var extendedEmulated: RemoteTreatment? = null, // Gson of emulated EB
@SerializedName("timeshift") val timeshift: Long? = null, // integer "Profile Switch" @SerializedName("timeshift") val timeshift: Long? = null, // integer "Profile Switch"
@SerializedName("percentage") val percentage: Int? = null, // integer "Profile Switch" @SerializedName("percentage") val percentage: Int? = null, // integer "Profile Switch"
@SerializedName("isBasalInsulin") val isBasalInsulin: Boolean? = null // boolean "Bolus" @SerializedName("isBasalInsulin") val isBasalInsulin: Boolean? = null // boolean "Bolus"

View file

@ -48,7 +48,7 @@ data class ExtendedBolus(
require(duration > 0) require(duration > 0)
} }
private fun contentEqualsTo(other: ExtendedBolus): Boolean = fun contentEqualsTo(other: ExtendedBolus): Boolean =
isValid == other.isValid && isValid == other.isValid &&
timestamp == other.timestamp && timestamp == other.timestamp &&
utcOffset == other.utcOffset && utcOffset == other.utcOffset &&

View file

@ -38,6 +38,7 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSEffectiveProfileSwitch import info.nightscout.plugins.sync.nsclientV3.extensions.toNSEffectiveProfileSwitch
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSExtendedBolus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSFood import info.nightscout.plugins.sync.nsclientV3.extensions.toNSFood
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSOfflineEvent import info.nightscout.plugins.sync.nsclientV3.extensions.toNSOfflineEvent
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSProfileSwitch import info.nightscout.plugins.sync.nsclientV3.extensions.toNSProfileSwitch
@ -387,7 +388,14 @@ class NSClientV3Plugin @Inject constructor(
} }
dataPair.value.toNSTemporaryBasal(profile) dataPair.value.toNSTemporaryBasal(profile)
} }
// is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) is DataSyncSelector.PairExtendedBolus -> {
val profile = profileFunction.getProfile(dataPair.value.timestamp)
if (profile == null) {
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
return
}
dataPair.value.toNSExtendedBolus(profile)
}
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toNSProfileSwitch(dateUtil) is DataSyncSelector.PairProfileSwitch -> dataPair.value.toNSProfileSwitch(dateUtil)
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toNSEffectiveProfileSwitch(dateUtil) is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toNSEffectiveProfileSwitch(dateUtil)
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toNSOfflineEvent() is DataSyncSelector.PairOfflineEvent -> dataPair.value.toNSOfflineEvent()
@ -463,7 +471,15 @@ class NSClientV3Plugin @Inject constructor(
} }
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id) dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id)
} }
// is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) is DataSyncSelector.PairExtendedBolus -> {
if (result.response == 201) { // created
dataPair.value.interfaceIDs.nightscoutId = result.identifier
storeDataForDb.nsIdExtendedBoluses.add(dataPair.value)
storeDataForDb.scheduleNsIdUpdate()
}
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
}
is DataSyncSelector.PairProfileSwitch -> { is DataSyncSelector.PairProfileSwitch -> {
if (result.response == 201) { // created if (result.response == 201) { // created
dataPair.value.interfaceIDs.nightscoutId = result.identifier dataPair.value.interfaceIDs.nightscoutId = result.identifier

View file

@ -1,8 +1,12 @@
package info.nightscout.plugins.sync.nsclientV3.extensions package info.nightscout.plugins.sync.nsclientV3.extensions
import info.nightscout.core.extensions.toTemporaryBasal
import info.nightscout.database.entities.ExtendedBolus import info.nightscout.database.entities.ExtendedBolus
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.interfaces.profile.Profile
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSExtendedBolus import info.nightscout.sdk.localmodel.treatment.NSExtendedBolus
import info.nightscout.sdk.localmodel.treatment.NSTreatment
fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus = fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus =
ExtendedBolus( ExtendedBolus(
@ -14,3 +18,25 @@ fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus =
isEmulatingTempBasal = isEmulatingTempBasal ?: false, isEmulatingTempBasal = isEmulatingTempBasal ?: false,
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId) interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
) )
fun ExtendedBolus.toNSExtendedBolus(profile: Profile, convertToTemporaryBasal: Boolean = true): NSTreatment =
if (isEmulatingTempBasal && convertToTemporaryBasal)
this.toTemporaryBasal(profile).toNSTemporaryBasal(profile).also {
it.extendedEmulated = toNSExtendedBolus(profile, convertToTemporaryBasal = false) as NSExtendedBolus
}
else
NSExtendedBolus(
eventType = EventType.COMBO_BOLUS,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
enteredinsulin = amount,
duration = duration,
isEmulatingTempBasal = isEmulatingTempBasal,
rate = rate,
identifier = interfaceIDs.nightscoutId,
pumpId = interfaceIDs.pumpId,
pumpType = interfaceIDs.pumpType?.name,
pumpSerial = interfaceIDs.pumpSerial,
endId = interfaceIDs.endId
)

View file

@ -0,0 +1,59 @@
package info.nightscout.plugins.sync.nsclientV3.extensions
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.database.entities.ExtendedBolus
import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.treatment.NSExtendedBolus
import info.nightscout.sdk.localmodel.treatment.NSTemporaryBasal
import info.nightscout.sdk.mapper.convertToRemoteAndBack
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
@Suppress("SpellCheckingInspection")
internal class ExtendedBolusExtensionKtTest : TestBaseWithProfile() {
@Test
fun toExtendedBolus() {
var extendedBolus = ExtendedBolus(
timestamp = 10000,
isValid = true,
amount = 2.0,
isEmulatingTempBasal = false,
duration = 3600000,
interfaceIDs_backing = InterfaceIDs(
nightscoutId = "nightscoutId",
pumpId = 11000,
pumpType = InterfaceIDs.PumpType.DANA_I,
pumpSerial = "bbbb"
)
)
var extendedBolus2 = (extendedBolus.toNSExtendedBolus(validProfile).convertToRemoteAndBack() as NSExtendedBolus).toExtendedBolus()
Assertions.assertTrue(extendedBolus.contentEqualsTo(extendedBolus2))
Assertions.assertTrue(extendedBolus.interfaceIdsEqualsTo(extendedBolus2))
extendedBolus = ExtendedBolus(
timestamp = 10000,
isValid = true,
amount = 4.0,
isEmulatingTempBasal = true,
duration = 36000,
interfaceIDs_backing = InterfaceIDs(
nightscoutId = "nightscoutId",
pumpId = 11000,
pumpType = InterfaceIDs.PumpType.DANA_I,
pumpSerial = "bbbb"
)
)
val converted = extendedBolus.toNSExtendedBolus(validProfile)
Assertions.assertTrue(converted is NSTemporaryBasal)
Assertions.assertNotNull((converted as NSTemporaryBasal).extendedEmulated)
val convertedBack = converted.convertToRemoteAndBack()
Assertions.assertTrue(convertedBack is NSExtendedBolus)
extendedBolus2 = (extendedBolus.toNSExtendedBolus(validProfile).convertToRemoteAndBack() as NSExtendedBolus).toExtendedBolus()
Assertions.assertTrue(extendedBolus.contentEqualsTo(extendedBolus2))
Assertions.assertTrue(extendedBolus.interfaceIdsEqualsTo(extendedBolus2))
}
}