NSCv3: utcOffset, improve handling

This commit is contained in:
Milos Kozak 2023-01-03 23:10:04 +01:00
parent 688a95746c
commit 854acc2992
19 changed files with 58 additions and 43 deletions

View file

@ -120,7 +120,7 @@ class NSAndroidClientImpl(
val response = api.getSgvsModifiedSince(from, limit)
if (response.isSuccessful) {
val eTagString = response.headers()["ETag"]
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw UnsuccessfullNightscoutException()
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
} else {
throw UnsuccessfullNightscoutException()
@ -142,6 +142,7 @@ class NSAndroidClientImpl(
val remoteEntry = nsSgvV3.toRemoteEntry()
remoteEntry.app = "AAPS"
val response = api.createEntry(remoteEntry)
val responseBody = response.body()
val errorResponse = response.errorBody()?.string()
if (response.code() == 200) {
return@callWrapper CreateUpdateResponse(
@ -152,11 +153,10 @@ class NSAndroidClientImpl(
} else if (response.code() == 201) {
return@callWrapper CreateUpdateResponse(
response = response.code(),
identifier = response.body()?.result?.identifier
?: throw UnknownResponseNightscoutException(),
isDeduplication = response.body()?.result?.isDeduplication ?: false,
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
lastModified = response.body()?.result?.lastModified
identifier = responseBody?.result?.identifier,
isDeduplication = responseBody?.result?.isDeduplication ?: false,
deduplicatedIdentifier = responseBody?.result?.deduplicatedIdentifier,
lastModified = responseBody?.result?.lastModified
)
} else if (response.code() == 400 && errorResponse?.contains("Bad or missing utcOffset field") == true && nsSgvV3.utcOffset != 0L) {
// Record can be originally uploaded without utcOffset
@ -211,7 +211,6 @@ class NSAndroidClientImpl(
if (response.isSuccessful) {
val eTagString = response.headers()["ETag"]
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
?: throw UnsuccessfullNightscoutException()
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
} else {
throw UnsuccessfullNightscoutException()
@ -243,8 +242,7 @@ class NSAndroidClientImpl(
} else if (response.code() == 201) {
return@callWrapper CreateUpdateResponse(
response = response.code(),
identifier = response.body()?.result?.identifier
?: throw UnknownResponseNightscoutException(),
identifier = response.body()?.result?.identifier,
isDeduplication = response.body()?.result?.isDeduplication ?: false,
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
lastModified = response.body()?.result?.lastModified
@ -326,7 +324,7 @@ class NSAndroidClientImpl(
} else if (response.code() == 201) {
return@callWrapper CreateUpdateResponse(
response = response.code(),
identifier = response.body()?.result?.identifier ?: throw UnknownResponseNightscoutException(),
identifier = response.body()?.result?.identifier,
isDeduplication = response.body()?.result?.isDeduplication ?: false,
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
lastModified = response.body()?.result?.lastModified
@ -361,7 +359,8 @@ class NSAndroidClientImpl(
delayBetweenRetries = RETRY_DELAY,
excludedExceptions = listOf(
InvalidAccessTokenException::class,
DateHeaderOutOfToleranceException::class
DateHeaderOutOfToleranceException::class,
InvalidFormatNightscoutException::class
)
) {
block.invoke()

View file

@ -11,7 +11,7 @@ import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
interface NSAndroidClient {
class ReadResponse<T>(
val lastServerModified: Long,
val lastServerModified: Long?,
val values: T
)

View file

@ -1,6 +1,7 @@
package info.nightscout.database.transactions
import info.nightscout.database.entities.GlucoseValue
import java.util.TimeZone
data class TransactionGlucoseValue(
val timestamp: Long,
@ -10,5 +11,6 @@ data class TransactionGlucoseValue(
val trendArrow: GlucoseValue.TrendArrow,
val nightscoutId: String? = null,
val sourceSensor: GlucoseValue.SourceSensor,
val isValid: Boolean = true
val isValid: Boolean = true,
val utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong()
)

View file

@ -24,7 +24,8 @@ class CgmSourceTransaction constructor(
noise = it.noise,
trendArrow = it.trendArrow,
sourceSensor = it.sourceSensor,
isValid = it.isValid
isValid = it.isValid,
utcOffset = it.utcOffset
).also { gv ->
gv.interfaceIDs.nightscoutId = it.nightscoutId
}

View file

@ -121,7 +121,8 @@ class NSClientSourcePlugin @Inject constructor(
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
nightscoutId = sgv.identifier,
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device),
isValid = sgv.isValid
isValid = sgv.isValid,
utcOffset = T.mins(sgv.utcOffset ?: 0L).msecs()
)
}

View file

@ -358,7 +358,7 @@ class NSClientV3Plugin @Inject constructor(
call?.let { it(data) }?.let { result ->
when (result.response) {
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
@ -411,7 +411,7 @@ class NSClientV3Plugin @Inject constructor(
call?.let { it(data) }?.let { result ->
when (result.response) {
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
@ -490,7 +490,7 @@ class NSClientV3Plugin @Inject constructor(
call?.let { it(data) }?.let { result ->
when (result.response) {
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {

View file

@ -6,6 +6,7 @@ import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.sdk.localmodel.entry.NsUnits
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
import info.nightscout.shared.utils.T
fun NSBolusWizard.toBolusCalculatorResult(): BolusCalculatorResult? =
try {
@ -25,7 +26,7 @@ fun BolusCalculatorResult.toNSBolusWizard(): NSBolusWizard =
eventType = EventType.BOLUS_WIZARD,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
notes = note,
bolusCalculatorResult = Gson().toJson(this).toString(),
units = NsUnits.MG_DL,

View file

@ -4,13 +4,14 @@ import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSBolus
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSBolus.toBolus(): Bolus =
Bolus(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
amount = insulin,
type = type.toBolusType(),
notes = notes,
@ -26,7 +27,7 @@ fun Bolus.toNSBolus(): NSBolus =
eventType = if (type == Bolus.Type.SMB) EventType.CORRECTION_BOLUS else EventType.MEAL_BOLUS,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
insulin = amount,
type = type.toBolusType(),
notes = notes,

View file

@ -4,13 +4,14 @@ import info.nightscout.database.entities.Carbs
import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSCarbs
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSCarbs.toCarbs(): Carbs =
Carbs(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
amount = carbs,
notes = notes,
duration = duration ?: 0L,
@ -22,7 +23,7 @@ fun Carbs.toNSCarbs(): NSCarbs =
eventType = if (amount < 12) EventType.CARBS_CORRECTION else EventType.MEAL_BOLUS,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
carbs = amount,
notes = notes,
duration = if (duration != 0L) duration else null,

View file

@ -8,6 +8,7 @@ import info.nightscout.plugins.sync.nsclient.extensions.fromConstant
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSEffectiveProfileSwitch
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSEffectiveProfileSwitch.toEffectiveProfileSwitch(dateUtil: DateUtil): EffectiveProfileSwitch? {
@ -17,7 +18,7 @@ fun NSEffectiveProfileSwitch.toEffectiveProfileSwitch(dateUtil: DateUtil): Effec
return EffectiveProfileSwitch(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
basalBlocks = profileSealed.basalBlocks,
isfBlocks = profileSealed.isfBlocks,
icBlocks = profileSealed.icBlocks,
@ -39,7 +40,7 @@ fun EffectiveProfileSwitch.toNSEffectiveProfileSwitch(dateUtil: DateUtil) : NSEf
eventType = EventType.NOTE,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
profileJson = ProfileSealed.EPS(this).toPureNsJson(dateUtil),
originalProfileName = originalProfileName,
originalCustomizedName = originalCustomizedName,

View file

@ -7,13 +7,14 @@ 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.NSTreatment
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus =
ExtendedBolus(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
amount = enteredinsulin,
duration = duration,
isEmulatingTempBasal = isEmulatingTempBasal ?: false,
@ -30,7 +31,7 @@ fun ExtendedBolus.toNSExtendedBolus(profile: Profile, convertToTemporaryBasal: B
eventType = EventType.COMBO_BOLUS,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
enteredinsulin = amount,
duration = duration,
isEmulatingTempBasal = isEmulatingTempBasal,

View file

@ -5,6 +5,7 @@ import info.nightscout.database.transactions.TransactionGlucoseValue
import info.nightscout.sdk.localmodel.entry.Direction
import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.entry.NsUnits
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
// copy of NSClientSourcePlugin for testing
@ -12,12 +13,13 @@ fun NSSgvV3.toTransactionGlucoseValue(): TransactionGlucoseValue {
return TransactionGlucoseValue(
timestamp = date ?: throw InvalidParameterException(),
value = sgv,
noise = noise?.toDouble(),
noise = noise,
raw = filtered,
trendArrow = GlucoseValue.TrendArrow.fromString(direction?.nsName),
nightscoutId = identifier,
sourceSensor = GlucoseValue.SourceSensor.fromString(device),
isValid = isValid
isValid = isValid,
utcOffset = T.mins(utcOffset ?: 0L).msecs()
)
}
@ -30,7 +32,8 @@ fun TransactionGlucoseValue.toGlucoseValue() =
noise = noise,
trendArrow = trendArrow,
sourceSensor = sourceSensor,
isValid = isValid
isValid = isValid,
utcOffset = utcOffset
).also { gv ->
gv.interfaceIDs.nightscoutId = nightscoutId
}
@ -39,7 +42,7 @@ fun GlucoseValue.toNSSvgV3(): NSSgvV3 =
NSSgvV3(
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
filtered = raw,
unfiltered = 0.0,
sgv = value,

View file

@ -4,13 +4,14 @@ import info.nightscout.database.entities.OfflineEvent
import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSOfflineEvent
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSOfflineEvent.toOfflineEvent(): OfflineEvent =
OfflineEvent(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
duration = duration,
reason = reason.toReason(),
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
@ -24,7 +25,7 @@ fun OfflineEvent.toNSOfflineEvent(): NSOfflineEvent =
eventType = EventType.APS_OFFLINE,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
duration = duration,
reason = reason.toReason(),
identifier = interfaceIDs.nightscoutId,

View file

@ -23,7 +23,7 @@ fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUt
return ProfileSwitch(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
basalBlocks = profileSealed.basalBlocks,
isfBlocks = profileSealed.isfBlocks,
icBlocks = profileSealed.icBlocks,
@ -49,7 +49,7 @@ fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil): NSProfileSwitch {
eventType = EventType.PROFILE_SWITCH,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
timeShift = timeshift,
percentage = percentage,
duration = T.mins(duration).msecs(),

View file

@ -6,13 +6,14 @@ 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.NSTemporaryBasal
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSTemporaryBasal.toTemporaryBasal(): TemporaryBasal =
TemporaryBasal(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
type = type.toType(),
rate = rate,
isAbsolute = isAbsolute,
@ -28,7 +29,7 @@ fun TemporaryBasal.toNSTemporaryBasal(profile: Profile): NSTemporaryBasal =
eventType = EventType.TEMPORARY_BASAL,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
type = type.toType(),
rate = convertedToAbsolute(timestamp, profile),
isAbsolute = isAbsolute,

View file

@ -5,13 +5,14 @@ import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.entry.NsUnits
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSTemporaryTarget
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSTemporaryTarget.toTemporaryTarget(): TemporaryTarget =
TemporaryTarget(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
reason = reason.toReason(),
highTarget = targetTop.asMgdl(),
lowTarget = targetBottom.asMgdl(),
@ -27,7 +28,7 @@ fun TemporaryTarget.toNSTemporaryTarget(): NSTemporaryTarget =
eventType = EventType.TEMPORARY_TARGET,
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
reason = reason.toReason(),
targetTop = highTarget,
targetBottom = lowTarget,

View file

@ -5,13 +5,14 @@ import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.sdk.localmodel.entry.NsUnits
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSTherapyEvent
import info.nightscout.shared.utils.T
import java.security.InvalidParameterException
fun NSTherapyEvent.toTherapyEvent(): TherapyEvent =
TherapyEvent(
isValid = isValid,
timestamp = date ?: throw InvalidParameterException(),
utcOffset = utcOffset ?: 0L,
utcOffset = T.mins(utcOffset ?: 0L).msecs(),
glucoseUnit = units.toUnits(),
type = eventType.toType(),
note = notes,
@ -39,7 +40,7 @@ fun TherapyEvent.toNSTherapyEvent(): NSTherapyEvent =
NSTherapyEvent(
isValid = isValid,
date = timestamp,
utcOffset = utcOffset,
utcOffset = T.msecs(utcOffset).mins(),
units = glucoseUnit.toUnits(),
eventType = type.toType(),
notes = note,

View file

@ -55,7 +55,7 @@ class LoadBgWorker(
else {
response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500)
sgvs = response.values
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = response.lastServerModified
response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = it }
nsClientV3Plugin.storeLastLoadedSrvModified()
}
aapsLogger.debug("SGVS: $sgvs")

View file

@ -53,7 +53,7 @@ class LoadTreatmentsWorker(
else {
response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500)
treatments = response.values
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = response.lastServerModified
response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = it }
nsClientV3Plugin.storeLastLoadedSrvModified()
}
aapsLogger.debug("TREATMENTS: $treatments")