NSCv3: process GlucoseValue
This commit is contained in:
parent
cc605efc93
commit
823c26aa64
36 changed files with 417 additions and 160 deletions
|
@ -14,6 +14,7 @@ import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
|
|||
import info.nightscout.sdk.localmodel.treatment.NSTreatment
|
||||
import info.nightscout.sdk.mapper.toLocal
|
||||
import info.nightscout.sdk.mapper.toNSFood
|
||||
import info.nightscout.sdk.mapper.toRemoteEntry
|
||||
import info.nightscout.sdk.mapper.toRemoteFood
|
||||
import info.nightscout.sdk.mapper.toRemoteTreatment
|
||||
import info.nightscout.sdk.mapper.toSgv
|
||||
|
@ -94,13 +95,6 @@ class NSAndroidClientImpl(
|
|||
api.statusSimple().result!!.toLocal().also { lastStatus = it }
|
||||
}
|
||||
|
||||
// TODO: return something better than a String
|
||||
// TODO: parameters like count?
|
||||
// TODO: updated after timestamp
|
||||
override suspend fun getEntries(): String = callWrapper(dispatcher) {
|
||||
api.getEntries().toString()
|
||||
}
|
||||
|
||||
override suspend fun getLastModified(): LastModified = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.lastModified()
|
||||
|
@ -125,9 +119,9 @@ class NSAndroidClientImpl(
|
|||
override suspend fun getSgvsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSSgvV3>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getSgvsModifiedSince(from, limit)
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw UnsuccessfullNightscoutException()
|
||||
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(RemoteEntry::toSgv).toNotNull())
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
|
@ -144,6 +138,55 @@ class NSAndroidClientImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteEntry = nsSgvV3.toRemoteEntry()
|
||||
remoteEntry.app = "AAPS"
|
||||
val response = api.createEntry(remoteEntry)
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} 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
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
// following cannot be updated
|
||||
nsSgvV3.utcOffset = null
|
||||
nsSgvV3.date = null
|
||||
val remoteEntry = nsSgvV3.toRemoteEntry()
|
||||
val identifier = remoteEntry.identifier ?: throw InvalidFormatNightscoutException()
|
||||
val response = api.updateEntry(remoteEntry, identifier)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = false,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): List<NSTreatment> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getTreatmentsNewerThan(createdAt, limit)
|
||||
|
@ -157,10 +200,10 @@ class NSAndroidClientImpl(
|
|||
override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSTreatment>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getTreatmentsModifiedSince(from, limit)
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
|
||||
?: throw UnsuccessfullNightscoutException()
|
||||
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()
|
||||
|
@ -183,13 +226,24 @@ class NSAndroidClientImpl(
|
|||
remoteTreatment.app = "AAPS"
|
||||
val response = api.createTreatment(remoteTreatment)
|
||||
if (response.isSuccessful) {
|
||||
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
|
||||
)
|
||||
if (response.code() == 200) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} 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
|
||||
)
|
||||
} else throw UnknownResponseNightscoutException()
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
@ -197,15 +251,19 @@ class NSAndroidClientImpl(
|
|||
|
||||
override suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
// following cannot be updated
|
||||
nsTreatment.utcOffset = null
|
||||
nsTreatment.date = null
|
||||
val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException()
|
||||
val response = api.updateTreatment(remoteTreatment)
|
||||
val identifier = remoteTreatment.identifier ?: throw InvalidFormatNightscoutException()
|
||||
val response = api.updateTreatment(remoteTreatment, identifier)
|
||||
if (response.isSuccessful) {
|
||||
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 = null,
|
||||
isDeduplication = false,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
|
@ -227,11 +285,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getFoodsModifiedSince(from, limit)
|
||||
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() ?: throw UnsuccessfulNightscoutException()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteFood::toNSFood).toNotNull())
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
throw UnsuccessfulNightscoutException()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -241,13 +299,23 @@ class NSAndroidClientImpl(
|
|||
remoteFood.app = "AAPS"
|
||||
val response = api.createFood(remoteFood)
|
||||
if (response.isSuccessful) {
|
||||
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
|
||||
)
|
||||
if (response.code() == 200) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} 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
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
@ -260,10 +328,10 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
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 = null,
|
||||
isDeduplication = false,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
|
|
|
@ -18,12 +18,12 @@ interface NSAndroidClient {
|
|||
val lastStatus: Status?
|
||||
suspend fun getVersion(): String
|
||||
suspend fun getStatus(): Status
|
||||
suspend fun getEntries(): String
|
||||
|
||||
suspend fun getLastModified(): LastModified
|
||||
suspend fun getSgvs(): List<NSSgvV3>
|
||||
suspend fun getSgvsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3>
|
||||
suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): List<NSTreatment>
|
||||
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>>
|
||||
suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus>
|
||||
|
|
|
@ -10,8 +10,13 @@ enum class Direction(val nsName: String, val txtIcon: String) {
|
|||
SINGLE_UP("SingleUp", "\u2191"), // ↑
|
||||
DOUBLE_UP("DoubleUp", "\u21c8"), // ⇈
|
||||
TRIPLE_UP("TripleUp", "\u290A"), // ⤊
|
||||
NONE("NONE", "⇼"), //
|
||||
INVALID("", "-"), //
|
||||
NONE("NONE", "⇼"),
|
||||
INVALID("", "-");
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromString(text: String?) = Direction.values().firstOrNull { it.nsName == text } ?: NONE
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package info.nightscout.sdk.localmodel.entry
|
||||
|
||||
interface Entry {
|
||||
val date: Long
|
||||
val device: String?
|
||||
val identifier: String
|
||||
val srvModified: Long
|
||||
val srvCreated: Long
|
||||
val utcOffset: Long?
|
||||
val subject: String?
|
||||
var isReadOnly: Boolean // TODO: nullability?
|
||||
val isValid: Boolean
|
||||
}
|
|
@ -1,20 +1,19 @@
|
|||
package info.nightscout.sdk.localmodel.entry
|
||||
|
||||
data class NSSgvV3(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val utcOffset: Long?,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
override val isValid: Boolean,
|
||||
val sgv: Double, // TODO: might be Double?
|
||||
var date: Long?,
|
||||
val device: String? = null, // sourceSensor
|
||||
val identifier: String?,
|
||||
val srvModified: Long? = null,
|
||||
val srvCreated: Long? = null,
|
||||
var utcOffset: Long?,
|
||||
val subject: String? = null,
|
||||
var isReadOnly: Boolean = false,
|
||||
val isValid: Boolean,
|
||||
val sgv: Double,
|
||||
val units: NsUnits,
|
||||
val direction: Direction,
|
||||
val noise: Int?, // TODO: enum?
|
||||
val direction: Direction?,
|
||||
val noise: Double?,
|
||||
val filtered: Double?, // number in doc (I found decimal values in API v1
|
||||
val unfiltered: Double?, // number in doc (I found decimal values in API v1
|
||||
// TODO: add SVG fields
|
||||
) : Entry
|
||||
val unfiltered: Double? // number in doc (I found decimal values in API v1
|
||||
)
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSBolus(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String?= null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?= null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSBolusWizard(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String? = null,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSCarbs(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -4,14 +4,14 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
import org.json.JSONObject
|
||||
|
||||
data class NSEffectiveProfileSwitch(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String? = null,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String? = null ,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
override val eventType: EventType,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSExtendedBolus(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSOfflineEvent(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -4,13 +4,13 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
import org.json.JSONObject
|
||||
|
||||
data class NSProfileSwitch(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSTemporaryBasal(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSTemporaryTarget(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean = true,
|
||||
|
|
|
@ -4,13 +4,13 @@ import com.google.gson.annotations.SerializedName
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
data class NSTherapyEvent(
|
||||
override val date: Long,
|
||||
override var date: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override var utcOffset: Long?,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
|
|
|
@ -3,14 +3,14 @@ package info.nightscout.sdk.localmodel.treatment
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
||||
interface NSTreatment {
|
||||
val date: Long
|
||||
var date: Long?
|
||||
val device: String?
|
||||
val identifier: String?
|
||||
val units: NsUnits?
|
||||
val eventType: EventType
|
||||
val srvModified: Long?
|
||||
val srvCreated: Long?
|
||||
val utcOffset: Long
|
||||
var utcOffset: Long?
|
||||
val subject: String?
|
||||
var isReadOnly: Boolean
|
||||
val isValid: Boolean
|
||||
|
|
|
@ -5,19 +5,21 @@ import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
|||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import info.nightscout.sdk.remotemodel.RemoteEntry
|
||||
|
||||
@JvmSynthetic
|
||||
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
|
||||
toRemoteEntry().toSgv()
|
||||
|
||||
internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
||||
|
||||
this.sgv ?: return null
|
||||
if (this.type != "sgv") return null
|
||||
|
||||
return NSSgvV3(
|
||||
date = this.date,
|
||||
date = this.date ?: 0L,
|
||||
device = this.device,
|
||||
identifier = this.identifier,
|
||||
srvModified = this.srvModified,
|
||||
srvCreated = this.srvCreated,
|
||||
utcOffset = this.utcOffset ?: 0,
|
||||
utcOffset = this.utcOffset,
|
||||
subject = this.subject,
|
||||
direction = this.direction.toDirection(),
|
||||
sgv = this.sgv,
|
||||
|
@ -26,9 +28,30 @@ internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
|||
noise = this.noise, // TODO: to Enum?
|
||||
filtered = this.filtered,
|
||||
unfiltered = this.unfiltered,
|
||||
units = NsUnits.fromString(this.units)
|
||||
units = NsUnits.fromString(this.units),
|
||||
)
|
||||
}
|
||||
|
||||
private fun String?.toDirection(): Direction =
|
||||
Direction.values().firstOrNull { it.nsName == this } ?: Direction.INVALID
|
||||
Direction.values().firstOrNull { it.nsName == this } ?: Direction.INVALID
|
||||
|
||||
internal fun NSSgvV3.toRemoteEntry(): RemoteEntry =
|
||||
RemoteEntry(
|
||||
type = "sgv",
|
||||
date = this.date,
|
||||
device = this.device,
|
||||
identifier = this.identifier,
|
||||
srvModified = this.srvModified,
|
||||
srvCreated = this.srvCreated,
|
||||
utcOffset = this.utcOffset,
|
||||
subject = this.subject,
|
||||
direction = this.direction?.nsName,
|
||||
sgv = this.sgv,
|
||||
isReadOnly = this.isReadOnly,
|
||||
isValid = this.isValid,
|
||||
noise = this.noise,
|
||||
filtered = this.filtered,
|
||||
unfiltered = this.unfiltered,
|
||||
units = this.units.value
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.sdk.networking
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import info.nightscout.sdk.remotemodel.LastModified
|
||||
import info.nightscout.sdk.remotemodel.NSResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteCreateUpdateResponse
|
||||
|
@ -12,8 +11,8 @@ import info.nightscout.sdk.remotemodel.RemoteTreatment
|
|||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.PATCH
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
|
@ -33,9 +32,6 @@ internal interface NightscoutRemoteService {
|
|||
@GET("v3/status")
|
||||
suspend fun statusSimple(): NSResponse<RemoteStatusResponse>
|
||||
|
||||
@GET("v3/entries")
|
||||
suspend fun getEntries(): List<JsonElement>
|
||||
|
||||
@GET("v3/lastModified")
|
||||
suspend fun lastModified(): Response<NSResponse<LastModified>>
|
||||
|
||||
|
@ -48,6 +44,12 @@ internal interface NightscoutRemoteService {
|
|||
@GET("v3/entries/history/{from}")
|
||||
suspend fun getSgvsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Long): Response<NSResponse<List<RemoteEntry>>>
|
||||
|
||||
@POST("v3/entries")
|
||||
suspend fun createEntry(@Body remoteEntry: RemoteEntry): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@PATCH("v3/entries/{identifier}")
|
||||
suspend fun updateEntry(@Body remoteEntry: RemoteEntry, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@GET("v3/treatments")
|
||||
suspend fun getTreatmentsNewerThan(@Query(value = "created_at\$gt", encoded = true) createdAt: String, @Query("limit") limit: Long): Response<NSResponse<List<RemoteTreatment>>>
|
||||
|
||||
|
@ -60,8 +62,8 @@ internal interface NightscoutRemoteService {
|
|||
@POST("v3/treatments")
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@PUT("v3/treatments")
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
@PATCH("v3/treatments/{identifier}")
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@GET("v3/food")
|
||||
suspend fun getFoods(@Query("limit") limit: Long): Response<NSResponse<List<RemoteFood>>>
|
||||
|
@ -72,7 +74,7 @@ internal interface NightscoutRemoteService {
|
|||
@POST("v3/food")
|
||||
suspend fun createFood(@Body remoteFood: RemoteFood): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@PUT("v3/food")
|
||||
@PATCH("v3/food")
|
||||
suspend fun updateFood(@Body remoteFood: RemoteFood): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.sdk.remotemodel
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
|
||||
/*
|
||||
* Depending on the type, different other fields are present.
|
||||
|
@ -15,23 +14,23 @@ import info.nightscout.sdk.localmodel.treatment.EventType
|
|||
internal data class RemoteEntry(
|
||||
@SerializedName("type") val type: String, // sgv, mbg, cal, etc; Bolus type NORMAL, SMB, PRIMING
|
||||
@SerializedName("sgv") val sgv: Double?, // number The glucose reading. (only available for sgv types)
|
||||
@SerializedName("dateString") val dateString: String,
|
||||
@SerializedName("date") val date: Long, // required ? TODO: date and dateString are redundant - are both needed? how to handle inconsistency then? Only expose one to clients?
|
||||
@SerializedName("dateString") val dateString: String? = null,
|
||||
@SerializedName("date") var date: Long?, // required ? TODO: date and dateString are redundant - are both needed? how to handle inconsistency then? Only expose one to clients?
|
||||
@SerializedName("device") val device: String?, // The device from which the data originated (including serial number of the device, if it is relevant and safe).
|
||||
@SerializedName("direction") val direction: String?, // TODO: what implicit convention for the directions exists?
|
||||
@SerializedName("identifier") val identifier: String,
|
||||
@SerializedName("srvModified") val srvModified: Long,
|
||||
@SerializedName("srvCreated") val srvCreated: Long,
|
||||
@SerializedName("identifier") val identifier: String?,
|
||||
@SerializedName("srvModified") val srvModified: Long?,
|
||||
@SerializedName("srvCreated") val srvCreated: Long?,
|
||||
// Philoul Others fields below found in API v3 doc
|
||||
// @SerializedName("app") val app : String, // TODO required ? Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("utcOffset") val utcOffset: Long?, // Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is
|
||||
@SerializedName("app") var app : String? = null,
|
||||
@SerializedName("utcOffset") var utcOffset: Long?, // Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is
|
||||
// automatically parsed from the date field.
|
||||
@SerializedName("subject") val subject: String?, // Name of the security subject (within Nightscout scope) which has created the document. This field is automatically set by the server from the passed token or JWT.
|
||||
@SerializedName("modifiedBy") val modifiedBy: String?, // Name of the security subject (within Nightscout scope) which has patched or deleted the document for the last time. This field is automatically set by the server.
|
||||
@SerializedName("modifiedBy") val modifiedBy: String? = null, // Name of the security subject (within Nightscout scope) which has patched or deleted the document for the last time. This field is automatically set by the server.
|
||||
@SerializedName("isValid") val isValid: Boolean?, // A flag set by the server only for deleted documents. This field appears only within history operation and for documents which were deleted by API v3 (and they always have a false value)
|
||||
@SerializedName("isReadOnly") val isReadOnly: Boolean?, // A flag set by client that locks the document from any changes. Every document marked with isReadOnly=true is forever immutable and cannot even be deleted.
|
||||
@SerializedName("noise") val noise: Int?, // 0 or 1 found in the export, I don't know if other values possible ?
|
||||
@SerializedName("noise") val noise: Double?, // 0 or 1 found in the export, I don't know if other values possible ?
|
||||
@SerializedName("filtered") val filtered: Double?, // The raw filtered value directly from CGM transmitter. (only available for sgv types)
|
||||
@SerializedName("unfiltered") val unfiltered: Double?, // The raw unfiltered value directly from CGM transmitter. (only available for sgv types)
|
||||
@SerializedName("units") val units: String?, // The units for the glucose value, mg/dl or mmol/l. It is strongly recommended to fill in this field.
|
||||
@SerializedName("units") val units: String? // The units for the glucose value, mg/dl or mmol/l. It is strongly recommended to fill in this field.
|
||||
)
|
||||
|
|
|
@ -16,11 +16,11 @@ import org.joda.time.format.ISODateTimeFormat
|
|||
* */
|
||||
internal data class RemoteTreatment(
|
||||
@SerializedName("identifier") val identifier: String?, // string Main addressing, required field that identifies document in the collection. The client should not create the identifier, the server automatically assigns it when the document is inserted.
|
||||
@SerializedName("date") val date: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("date") var date: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("mills") val mills: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix
|
||||
@SerializedName("timestamp") val timestamp: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("created_at") val created_at: String? = null, // integer($int64) or string timestamp on previous version of api, in my examples, a lot of treatments don't have date, only created_at, some of them with string others with long...
|
||||
@SerializedName("utcOffset") val utcOffset: Long? = null, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is automatically parsed from the date field.
|
||||
@SerializedName("utcOffset") var utcOffset: Long? = null, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is automatically parsed from the date field.
|
||||
@SerializedName("app") var app : String? = null, // Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("device") val device: String? = null, // string The device from which the data originated (including serial number of the device, if it is relevant and safe).
|
||||
@SerializedName("srvCreated") val srvCreated: Long? = null, // integer($int64) example: 1525383610088 The server's timestamp of document insertion into the database (Unix epoch in ms). This field appears only for documents which were inserted by API v3.
|
||||
|
|
|
@ -32,6 +32,7 @@ import info.nightscout.shared.utils.DateUtil
|
|||
import info.nightscout.shared.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -113,11 +114,11 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
|
||||
private fun toGv(sgv: NSSgvV3): TransactionGlucoseValue {
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.date,
|
||||
timestamp = sgv.date ?: throw InvalidParameterException(),
|
||||
value = sgv.sgv,
|
||||
noise = sgv.noise?.toDouble(),
|
||||
raw = sgv.filtered,
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction.nsName),
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
|
||||
nightscoutId = sgv.identifier,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device),
|
||||
isValid = sgv.isValid
|
||||
|
|
|
@ -42,6 +42,7 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toNSExtendedBolus
|
|||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSFood
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSOfflineEvent
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSProfileSwitch
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryBasal
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
|
||||
|
@ -310,7 +311,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
override fun resetToFullSync() {
|
||||
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
|
||||
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
||||
storeLastFetched()
|
||||
storeLastLoadedSrvModified()
|
||||
}
|
||||
|
||||
override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
|
@ -325,6 +326,58 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
private val gson: Gson = GsonBuilder().create()
|
||||
private fun dbOperation(collection: String, dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
if (collection == "entries") {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createSvg }
|
||||
Operation.UPDATE -> nsAndroidClient?.let { return@let it::updateSvg }
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toNSSvgV3()
|
||||
else -> null
|
||||
}?.let { data ->
|
||||
runBlocking {
|
||||
try {
|
||||
val id = if (dataPair.value is TraceableDBEntry) (dataPair.value as TraceableDBEntry).interfaceIDs.nightscoutId else ""
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
Operation.CREATE -> "ADD $collection"
|
||||
Operation.UPDATE -> "UPDATE $collection"
|
||||
},
|
||||
when (operation) {
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
||||
}
|
||||
)
|
||||
)
|
||||
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}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@runBlocking
|
||||
}
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairGlucoseValue -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdGlucoseValues.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedGlucoseValuesCompat()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (collection == "food") {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createFood }
|
||||
|
@ -350,6 +403,15 @@ 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}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@runBlocking
|
||||
}
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairFood -> {
|
||||
if (result.response == 201) { // created
|
||||
|
@ -358,6 +420,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedFoodsCompat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -377,13 +440,13 @@ class NSClientV3Plugin @Inject constructor(
|
|||
is DataSyncSelector.PairCarbs -> dataPair.value.toNSCarbs()
|
||||
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toNSBolusWizard()
|
||||
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toNSTemporaryTarget()
|
||||
// is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil)
|
||||
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toNSTherapyEvent()
|
||||
|
||||
is DataSyncSelector.PairTemporaryBasal -> {
|
||||
val profile = profileFunction.getProfile(dataPair.value.timestamp)
|
||||
if (profile == null) {
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
return
|
||||
}
|
||||
dataPair.value.toNSTemporaryBasal(profile)
|
||||
|
@ -392,6 +455,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
val profile = profileFunction.getProfile(dataPair.value.timestamp)
|
||||
if (profile == null) {
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedExtendedBolusesCompat()
|
||||
return
|
||||
}
|
||||
dataPair.value.toNSExtendedBolus(profile)
|
||||
|
@ -417,60 +481,76 @@ 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}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@runBlocking
|
||||
}
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> {
|
||||
is DataSyncSelector.PairBolus -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdBoluses.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedBolusesCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairCarbs -> {
|
||||
is DataSyncSelector.PairCarbs -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdCarbs.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedCarbsCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairBolusCalculatorResult -> {
|
||||
is DataSyncSelector.PairBolusCalculatorResult -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdBolusCalculatorResults.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairTemporaryTarget -> {
|
||||
is DataSyncSelector.PairTemporaryTarget -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdTemporaryTargets.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTempTargetsCompat()
|
||||
}
|
||||
// is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil)
|
||||
is DataSyncSelector.PairTherapyEvent -> {
|
||||
|
||||
is DataSyncSelector.PairTherapyEvent -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdTherapyEvents.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTherapyEventsCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairTemporaryBasal -> {
|
||||
is DataSyncSelector.PairTemporaryBasal -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdTemporaryBasals.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairExtendedBolus -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
|
@ -478,6 +558,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedExtendedBolusesCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairProfileSwitch -> {
|
||||
|
@ -487,6 +568,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedProfileSwitchesCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairEffectiveProfileSwitch -> {
|
||||
|
@ -496,15 +578,17 @@ class NSClientV3Plugin @Inject constructor(
|
|||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitchesCompat()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairOfflineEvent -> {
|
||||
is DataSyncSelector.PairOfflineEvent -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdOfflineEvents.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedOfflineEventsCompat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -516,14 +600,10 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun storeLastFetched() {
|
||||
fun storeLastLoadedSrvModified() {
|
||||
sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastLoadedSrvModified))
|
||||
}
|
||||
|
||||
fun test() {
|
||||
executeLoop()
|
||||
}
|
||||
|
||||
fun scheduleNewExecution() {
|
||||
var toTime = lastLoadedSrvModified.collections.entries + T.mins(6).plus(T.secs(0)).msecs()
|
||||
if (toTime < dateUtil.now()) toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
|
||||
|
|
|
@ -4,12 +4,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSBolus.toBolus(): Bolus =
|
||||
Bolus(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
amount = insulin,
|
||||
type = type.toBolusType(),
|
||||
notes = notes,
|
||||
|
|
|
@ -4,12 +4,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSCarbs.toCarbs(): Carbs =
|
||||
Carbs(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
amount = carbs,
|
||||
notes = notes,
|
||||
duration = duration ?: 0L,
|
||||
|
|
|
@ -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 java.security.InvalidParameterException
|
||||
|
||||
fun NSEffectiveProfileSwitch.toEffectiveProfileSwitch(dateUtil: DateUtil): EffectiveProfileSwitch? {
|
||||
val pureProfile = pureProfileFromJson(profileJson, dateUtil) ?: return null
|
||||
|
@ -15,8 +16,8 @@ fun NSEffectiveProfileSwitch.toEffectiveProfileSwitch(dateUtil: DateUtil): Effec
|
|||
|
||||
return EffectiveProfileSwitch(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
basalBlocks = profileSealed.basalBlocks,
|
||||
isfBlocks = profileSealed.isfBlocks,
|
||||
icBlocks = profileSealed.icBlocks,
|
||||
|
|
|
@ -7,12 +7,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus =
|
||||
ExtendedBolus(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
amount = enteredinsulin,
|
||||
duration = duration,
|
||||
isEmulatingTempBasal = isEmulatingTempBasal ?: false,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.extensions
|
||||
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
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 java.security.InvalidParameterException
|
||||
|
||||
// copy of NSClientSourcePlugin for testing
|
||||
fun NSSgvV3.toTransactionGlucoseValue(): TransactionGlucoseValue {
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
value = sgv,
|
||||
noise = noise?.toDouble(),
|
||||
raw = filtered,
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(direction?.nsName),
|
||||
nightscoutId = identifier,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(device),
|
||||
isValid = isValid
|
||||
)
|
||||
}
|
||||
|
||||
// for testing
|
||||
fun TransactionGlucoseValue.toGlucoseValue() =
|
||||
GlucoseValue(
|
||||
timestamp = timestamp,
|
||||
raw = raw,
|
||||
value = value,
|
||||
noise = noise,
|
||||
trendArrow = trendArrow,
|
||||
sourceSensor = sourceSensor,
|
||||
isValid = isValid
|
||||
).also { gv ->
|
||||
gv.interfaceIDs.nightscoutId = nightscoutId
|
||||
}
|
||||
|
||||
fun GlucoseValue.toNSSvgV3(): NSSgvV3 =
|
||||
NSSgvV3(
|
||||
isValid = isValid,
|
||||
date = timestamp,
|
||||
utcOffset = utcOffset,
|
||||
filtered = raw,
|
||||
unfiltered = 0.0,
|
||||
sgv = value,
|
||||
units = NsUnits.MG_DL,
|
||||
direction = Direction.fromString(trendArrow.text),
|
||||
noise = noise,
|
||||
device = sourceSensor.text,
|
||||
identifier = interfaceIDs.nightscoutId
|
||||
)
|
|
@ -4,12 +4,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSOfflineEvent.toOfflineEvent(): OfflineEvent =
|
||||
OfflineEvent(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
duration = duration,
|
||||
reason = reason.toReason(),
|
||||
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.sdk.localmodel.treatment.EventType
|
|||
import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import java.security.InvalidParameterException
|
||||
|
||||
fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUtil): ProfileSwitch? {
|
||||
val pureProfile =
|
||||
|
@ -21,8 +22,8 @@ fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUt
|
|||
|
||||
return ProfileSwitch(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
basalBlocks = profileSealed.basalBlocks,
|
||||
isfBlocks = profileSealed.isfBlocks,
|
||||
icBlocks = profileSealed.icBlocks,
|
||||
|
|
|
@ -6,12 +6,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSTemporaryBasal.toTemporaryBasal(): TemporaryBasal =
|
||||
TemporaryBasal(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
type = type.toType(),
|
||||
rate = rate,
|
||||
isAbsolute = isAbsolute,
|
||||
|
|
|
@ -5,12 +5,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSTemporaryTarget.toTemporaryTarget(): TemporaryTarget =
|
||||
TemporaryTarget(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
reason = reason.toReason(),
|
||||
highTarget = targetTop.asMgdl(),
|
||||
lowTarget = targetBottom.asMgdl(),
|
||||
|
|
|
@ -5,12 +5,13 @@ 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 java.security.InvalidParameterException
|
||||
|
||||
fun NSTherapyEvent.toTherapyEvent(): TherapyEvent =
|
||||
TherapyEvent(
|
||||
isValid = isValid,
|
||||
timestamp = date,
|
||||
utcOffset = utcOffset,
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
utcOffset = utcOffset ?: 0L,
|
||||
glucoseUnit = units.toUnits(),
|
||||
type = eventType.toType(),
|
||||
note = notes,
|
||||
|
|
|
@ -56,7 +56,7 @@ class LoadBgWorker(
|
|||
response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500)
|
||||
sgvs = response.values
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = response.lastServerModified
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
aapsLogger.debug("SGVS: $sgvs")
|
||||
if (sgvs.isNotEmpty()) {
|
||||
|
@ -74,7 +74,7 @@ class LoadBgWorker(
|
|||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
|
@ -95,7 +95,7 @@ class LoadBgWorker(
|
|||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
|
|
|
@ -54,7 +54,7 @@ class LoadTreatmentsWorker(
|
|||
response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500)
|
||||
treatments = response.values
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = response.lastServerModified
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
aapsLogger.debug("TREATMENTS: $treatments")
|
||||
if (treatments.isNotEmpty()) {
|
||||
|
@ -74,7 +74,7 @@ class LoadTreatmentsWorker(
|
|||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
|
@ -93,7 +93,7 @@ class LoadTreatmentsWorker(
|
|||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
|
|
|
@ -66,7 +66,8 @@ class ProcessTreatmentsWorker(
|
|||
val ret = Result.success()
|
||||
for (treatment in treatments.values) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
if (treatment.date > latestDateInReceivedData) latestDateInReceivedData = treatment.date
|
||||
val date = treatment.date ?: continue
|
||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||
|
||||
when (treatment) {
|
||||
is NSBolus ->
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.extensions
|
||||
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.sdk.mapper.convertToRemoteAndBack
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
internal class GlucoseValueExtensionKtTest : TestBaseWithProfile() {
|
||||
|
||||
@Test
|
||||
fun toGlucoseValue() {
|
||||
val glucoseValue = GlucoseValue(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
raw = 101.0,
|
||||
value = 99.0,
|
||||
trendArrow = GlucoseValue.TrendArrow.DOUBLE_UP,
|
||||
noise = 1.0,
|
||||
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G4_WIXEL,
|
||||
interfaceIDs_backing = InterfaceIDs(
|
||||
nightscoutId = "nightscoutId"
|
||||
)
|
||||
)
|
||||
|
||||
var glucoseValue2 = glucoseValue.toNSSvgV3().convertToRemoteAndBack()?.toTransactionGlucoseValue()?.toGlucoseValue()
|
||||
Assertions.assertTrue(glucoseValue.contentEqualsTo(glucoseValue2!!))
|
||||
Assertions.assertTrue(glucoseValue.interfaceIdsEqualsTo(glucoseValue2))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue