NSTreatment -> RemoteTreatment conversion

This commit is contained in:
Milos Kozak 2022-12-11 17:52:29 +01:00
parent d7a8323bc8
commit e1cc42635c
22 changed files with 400 additions and 85 deletions

View file

@ -3,12 +3,16 @@ package info.nightscout.sdk
import android.content.Context import android.content.Context
import info.nightscout.sdk.exceptions.DateHeaderOutOfToleranceException import info.nightscout.sdk.exceptions.DateHeaderOutOfToleranceException
import info.nightscout.sdk.exceptions.InvalidAccessTokenException import info.nightscout.sdk.exceptions.InvalidAccessTokenException
import info.nightscout.sdk.exceptions.InvalidFormatNightscoutException
import info.nightscout.sdk.exceptions.TodoNightscoutException import info.nightscout.sdk.exceptions.TodoNightscoutException
import info.nightscout.sdk.exceptions.UnknownResponseNightscoutException
import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.sdk.localmodel.Status import info.nightscout.sdk.localmodel.Status
import info.nightscout.sdk.localmodel.entry.NSSgvV3 import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
import info.nightscout.sdk.localmodel.treatment.NSTreatment import info.nightscout.sdk.localmodel.treatment.NSTreatment
import info.nightscout.sdk.mapper.toLocal import info.nightscout.sdk.mapper.toLocal
import info.nightscout.sdk.mapper.toRemoteTreatment
import info.nightscout.sdk.mapper.toSgv import info.nightscout.sdk.mapper.toSgv
import info.nightscout.sdk.mapper.toTreatment import info.nightscout.sdk.mapper.toTreatment
import info.nightscout.sdk.networking.NetworkStackBuilder import info.nightscout.sdk.networking.NetworkStackBuilder
@ -154,6 +158,22 @@ class NSAndroidClientImpl(
} }
} }
override suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) {
val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException()
val response = api.createTreatment(remoteTreatment)
if (response.isSuccessful) {
return@callWrapper CreateUpdateResponse(
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 TodoNightscoutException() // TODO: react to response errors (offline, ...)
}
}
private suspend fun <T> callWrapper(dispatcher: CoroutineDispatcher, block: suspend () -> T): T = private suspend fun <T> callWrapper(dispatcher: CoroutineDispatcher, block: suspend () -> T): T =
withContext(dispatcher) { withContext(dispatcher) {
retry( retry(

View file

@ -0,0 +1,3 @@
package info.nightscout.sdk.exceptions
class InvalidFormatNightscoutException : NightscoutException()

View file

@ -0,0 +1,3 @@
package info.nightscout.sdk.exceptions
class UnknownResponseNightscoutException : NightscoutException()

View file

@ -2,6 +2,7 @@ package info.nightscout.sdk.interfaces
import info.nightscout.sdk.localmodel.Status import info.nightscout.sdk.localmodel.Status
import info.nightscout.sdk.localmodel.entry.NSSgvV3 import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
import info.nightscout.sdk.localmodel.treatment.NSTreatment import info.nightscout.sdk.localmodel.treatment.NSTreatment
import info.nightscout.sdk.remotemodel.LastModified import info.nightscout.sdk.remotemodel.LastModified
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
@ -19,4 +20,5 @@ interface NSAndroidClient {
suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3> suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3>
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment> suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment>
suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus> suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus>
suspend fun createTreatment(NsTreatment: NSTreatment): CreateUpdateResponse
} }

View file

@ -0,0 +1,8 @@
package info.nightscout.sdk.localmodel.treatment
class CreateUpdateResponse(
val identifier: String?,
val isDeduplication: Boolean? = false,
val deduplicatedIdentifier: String? = null,
val lastModified: Long? = null
)

View file

@ -7,8 +7,8 @@ data class NSBolus(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ data class NSBolusWizard(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -7,8 +7,8 @@ data class NSCarbs(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ data class NSEffectiveProfileSwitch(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -7,8 +7,8 @@ data class NSExtendedBolus(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,
@ -21,5 +21,5 @@ data class NSExtendedBolus(
override val pumpSerial: String?, override val pumpSerial: String?,
val duration: Long, val duration: Long,
val enteredinsulin: Double, val enteredinsulin: Double,
val isEmulatingTempbasal: Boolean val isEmulatingTempBasal: Boolean?
) : NSTreatment ) : NSTreatment

View file

@ -7,8 +7,8 @@ data class NSOfflineEvent(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ data class NSProfileSwitch(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ data class NSTemporaryBasal(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,
@ -21,9 +21,11 @@ data class NSTemporaryBasal(
override val pumpType: String?, override val pumpType: String?,
override val pumpSerial: String?, override val pumpSerial: String?,
val duration: Long, val duration: Long,
val rate: Double, val rate: Double, // when sending to NS always convertedToAbsolute(timestamp, profile)
val isAbsolute: Boolean, val isAbsolute: Boolean,
val type: Type val type: Type,
val percent: Double? = null, // when sending to NS (rate - 100)
val absolute: Double? = null // when sending to NS (rate)
) : NSTreatment { ) : NSTreatment {
enum class Type { enum class Type {

View file

@ -7,8 +7,8 @@ data class NSTemporaryTarget(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ data class NSTherapyEvent(
override val device: String?, override val device: String?,
override val identifier: String, override val identifier: String,
override val units: NsUnits?, override val units: NsUnits?,
override val srvModified: Long, override val srvModified: Long?,
override val srvCreated: Long, override val srvCreated: Long?,
override val utcOffset: Long, override val utcOffset: Long,
override val subject: String?, override val subject: String?,
override var isReadOnly: Boolean, override var isReadOnly: Boolean,

View file

@ -8,8 +8,8 @@ interface NSTreatment {
val identifier: String val identifier: String
val units: NsUnits? val units: NsUnits?
val eventType: EventType val eventType: EventType
val srvModified: Long val srvModified: Long?
val srvCreated: Long val srvCreated: Long?
val utcOffset: Long val utcOffset: Long
val subject: String? val subject: String?
var isReadOnly: Boolean var isReadOnly: Boolean

View file

@ -117,7 +117,7 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
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
) )
} }
@ -329,10 +329,270 @@ 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
) )
} }
} }
return null return null
} }
internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
when (this) {
is NSBolus -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
insulin = insulin,
type = type.name
)
is NSCarbs -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
carbs = carbs,
duration = duration
)
is NSTemporaryTarget -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
targetBottom = targetBottom,
targetTop = targetTop,
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(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
absolute = absolute,
percent = percent,
rate = absolute,
type = type.name
)
is NSEffectiveProfileSwitch -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
profileJson = profileJson.toString(),
originalProfileName = originalProfileName,
originalCustomizedName = originalCustomizedName,
originalTimeshift = originalTimeshift,
originalPercentage = originalPercentage,
originalDuration = originalDuration,
originalEnd = originalEnd
)
is NSProfileSwitch -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
profileJson = profileJson.toString(), // must be de-customized
profile = profileName,
originalProfileName = originalProfileName,
originalDuration = originalDuration,
duration = duration,
timeshift = timeShift,
percentage = percentage,
)
is NSBolusWizard -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
bolusCalculatorResult = bolusCalculatorResult,
glucose = glucose
)
is NSTherapyEvent -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
glucose = glucose,
enteredBy = enteredBy,
glucoseType = glucoseType?.text
)
is NSOfflineEvent -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
reason = reason.name
)
is NSExtendedBolus -> RemoteTreatment(
date = date,
device = device,
identifier = identifier,
units = units?.value,
srvModified = srvModified,
srvCreated = srvCreated,
utcOffset = utcOffset,
subject = subject,
isReadOnly = isReadOnly,
isValid = isValid,
eventType = eventType,
notes = notes,
pumpId = pumpId,
endId = endId,
pumpType = pumpType,
pumpSerial = pumpSerial,
enteredinsulin = enteredinsulin,
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
durationInMilliseconds = duration,
isEmulatingTempBasal = isEmulatingTempBasal
)
else -> null
}

View file

@ -4,11 +4,17 @@ import com.google.gson.JsonElement
import info.nightscout.sdk.remotemodel.LastModified import info.nightscout.sdk.remotemodel.LastModified
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.remotemodel.NSResponse import info.nightscout.sdk.remotemodel.NSResponse
import info.nightscout.sdk.remotemodel.RemoteCreateUpdateResponse
import info.nightscout.sdk.remotemodel.RemoteEntry import info.nightscout.sdk.remotemodel.RemoteEntry
import info.nightscout.sdk.remotemodel.RemoteStatusResponse import info.nightscout.sdk.remotemodel.RemoteStatusResponse
import info.nightscout.sdk.remotemodel.RemoteTreatment import info.nightscout.sdk.remotemodel.RemoteTreatment
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Response import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.Path import retrofit2.http.Path
import retrofit2.http.Query import retrofit2.http.Query
@ -48,4 +54,8 @@ internal interface NightscoutRemoteService {
@GET("v3/devicestatus/history/{from}") @GET("v3/devicestatus/history/{from}")
suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>> suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>>
@POST("v3/treatments")
fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
} }

View file

@ -17,6 +17,13 @@ internal data class RemoteStorage(
@SerializedName("version") val version: String @SerializedName("version") val version: String
) )
internal data class RemoteCreateUpdateResponse(
@SerializedName("identifier") val identifier: String?,
@SerializedName("isDeduplication") val isDeduplication: Boolean?,
@SerializedName("deduplicatedIdentifier") val deduplicatedIdentifier: String?,
@SerializedName("lastModified") val lastModified: Long?
)
internal data class RemoteApiPermissions( internal data class RemoteApiPermissions(
@SerializedName("devicestatus") val deviceStatus: RemoteApiPermission, @SerializedName("devicestatus") val deviceStatus: RemoteApiPermission,
@SerializedName("entries") val entries: RemoteApiPermission, @SerializedName("entries") val entries: RemoteApiPermission,

View file

@ -18,72 +18,71 @@ import org.json.JSONObject
* */ * */
internal data class RemoteTreatment( 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("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?, // 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") 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("mills") val mills: Long?, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix @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?, // 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("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, // 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("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?, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming @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.
// document) or it is automatically parsed from the date field.
// @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("app") val app : String, // TODO required ? Application or system in which the record was entered by human or device for the first time.
@SerializedName("device") val device: String?, // string The device from which the data originated (including serial number of the device, if it is relevant and safe). @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, // 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. @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.
@SerializedName("subject") val subject: String?, // 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("subject") val subject: String? = null, // 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("srvModified") val srvModified: Long, // integer($int64) example: 1525383610088 The server's timestamp of the last document modification in the database (Unix epoch in ms). This field appears only for documents which were somehow modified by API v3 (inserted, updated or deleted). @SerializedName("srvModified") val srvModified: Long? = null, // integer($int64) example: 1525383610088 The server's timestamp of the last document modification in the database (Unix epoch in ms). This field appears only for documents which were somehow modified by API v3 (inserted, updated or deleted).
@SerializedName("modifiedBy") val modifiedBy: String?, // 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, // 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("isValid") val isValid: Boolean?, // 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("isValid") val isValid: Boolean? = null, // 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?, // 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("isReadOnly") val isReadOnly: Boolean? = null, // 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("eventType") val eventType: EventType, // string "BG Check", "Snack Bolus", "Meal Bolus", "Correction Bolus", "Carb Correction", "Combo Bolus", "Announcement", "Note", "Question", "Exercise", "Site Change", "Sensor Start", "Sensor Change", "Pump Battery Change", "Insulin Change", "Temp Basal", "Profile Switch", "D.A.D. Alert", "Temporary Target", "OpenAPS Offline", "Bolus Wizard" @SerializedName("eventType") val eventType: EventType, // string "BG Check", "Snack Bolus", "Meal Bolus", "Correction Bolus", "Carb Correction", "Combo Bolus", "Announcement", "Note", "Question", "Exercise", "Site Change", "Sensor Start", "Sensor Change", "Pump Battery Change", "Insulin Change", "Temp Basal", "Profile Switch", "D.A.D. Alert", "Temporary Target", "OpenAPS Offline", "Bolus Wizard"
@SerializedName("glucose") val glucose: Double?, // double Current glucose @SerializedName("glucose") val glucose: Double? = null, // double Current glucose
@SerializedName("glucoseType") val glucoseType: String?, // string example: "Sensor", "Finger", "Manual" @SerializedName("glucoseType") val glucoseType: String? = null, // string example: "Sensor", "Finger", "Manual"
@SerializedName("units") val units: String?, // 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? = null, // string The units for the glucose value, mg/dl or mmol/l. It is strongly recommended to fill in this field.
@SerializedName("carbs") val carbs: Double?, // number... Amount of carbs given. @SerializedName("carbs") val carbs: Double? = null, // number... Amount of carbs given.
@SerializedName("protein") val protein: Int?, // number... Amount of protein given. @SerializedName("protein") val protein: Int? = null, // number... Amount of protein given.
@SerializedName("fat") val fat: Int?, // number... Amount of fat given. @SerializedName("fat") val fat: Int? = null, // number... Amount of fat given.
@SerializedName("insulin") val insulin: Double?, // number... Amount of insulin, if any. @SerializedName("insulin") val insulin: Double? = null, // number... Amount of insulin, if any.
@SerializedName("duration") val duration: Long?, // number... Duration in minutes. @SerializedName("duration") val duration: Long? = null, // number... Duration in minutes.
@SerializedName("durationInMilliseconds") val durationInMilliseconds: Long?, // number... Duration in milliseconds. @SerializedName("durationInMilliseconds") val durationInMilliseconds: Long? = null, // number... Duration in milliseconds.
@SerializedName("preBolus") val preBolus: Int?, // number... How many minutes the bolus was given before the meal started. @SerializedName("preBolus") val preBolus: Int? = null, // number... How many minutes the bolus was given before the meal started.
@SerializedName("splitNow") val splitNow: Int?, // number... Immediate part of combo bolus (in percent). @SerializedName("splitNow") val splitNow: Int? = null, // number... Immediate part of combo bolus (in percent).
@SerializedName("splitExt") val splitExt: Int?, // number... Extended part of combo bolus (in percent). @SerializedName("splitExt") val splitExt: Int? = null, // number... Extended part of combo bolus (in percent).
@SerializedName("percent") val percent: Double?, // number... Eventual basal change in percent. @SerializedName("percent") val percent: Double? = null, // number... Eventual basal change in percent.
@SerializedName("absolute") val absolute: Double?, // number... Eventual basal change in absolute value (insulin units per hour). @SerializedName("absolute") val absolute: Double? = null, // number... Eventual basal change in absolute value (insulin units per hour).
@SerializedName("targetTop") val targetTop: Double?, // number... Top limit of temporary target. @SerializedName("targetTop") val targetTop: Double? = null, // number... Top limit of temporary target.
@SerializedName("targetBottom") val targetBottom: Double?, // number... Bottom limit of temporary target. @SerializedName("targetBottom") val targetBottom: Double? = null, // number... Bottom limit of temporary target.
@SerializedName("profile") val profile: String?, // string Name of the profile to which the pump has been switched. @SerializedName("profile") val profile: String? = null, // string Name of the profile to which the pump has been switched.
@SerializedName("reason") val reason: String?, // string For example the reason why the profile has been switched or why the temporary target has been set. @SerializedName("reason") val reason: String? = null, // string For example the reason why the profile has been switched or why the temporary target has been set.
@SerializedName("notes") val notes: String?, // string Description/notes of treatment. @SerializedName("notes") val notes: String? = null, // string Description/notes of treatment.
@SerializedName("enteredBy") val enteredBy: String?, // string Who entered the treatment. @SerializedName("enteredBy") val enteredBy: String? = null, // string Who entered the treatment.
@SerializedName("endId") val endId: Long?, // long id of record which ended this @SerializedName("endId") val endId: Long? = null, // long id of record which ended this
@SerializedName("pumpId") val pumpId: Long?, // long or "Meal Bolus", "Correction Bolus", "Combo Bolus" ex 4102 not sure if long or int @SerializedName("pumpId") val pumpId: Long? = null, // long or "Meal Bolus", "Correction Bolus", "Combo Bolus" ex 4102 not sure if long or int
@SerializedName("pumpType") val pumpType: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" ex "ACCU_CHEK_INSIGHT_BLUETOOTH", @SerializedName("pumpType") val pumpType: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" ex "ACCU_CHEK_INSIGHT_BLUETOOTH",
@SerializedName("pumpSerial") val pumpSerial: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" "33013206", @SerializedName("pumpSerial") val pumpSerial: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" "33013206",
// other fields found in examples but not in documentation // other fields found in examples but not in documentation
@SerializedName("profileJson") val profileJson: String?, // string "Profile Switch" ex json toString "{\"units\":\"mg\\/dl\",\"dia\":5,\"timezone\":\"Africa\\/Cairo\", @SerializedName("profileJson") val profileJson: String? = null, // string "Profile Switch" ex json toString "{\"units\":\"mg\\/dl\",\"dia\":5,\"timezone\":\"Africa\\/Cairo\",
// \"sens\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":60},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":60},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":61.33333333333333},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":65.33333333333333},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":69.33333333333333},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":73.33333333333333},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":72},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":68},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":65.33333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":65.33333333333333}],\"carbratio\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":5.7333333333333325},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":7.333333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":6.666666666666666}],\"basal\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0.5249999999999999},{\"time\":\"01:00\",\"timeAsSeconds\":3600,\"value\":0.585},{\"time\":\"02:00\",\"timeAsSeconds\":7200,\"value\":0.6375},{\"time\":\"03:00\",\"timeAsSeconds\":10800,\"value\":0.5625},{\"time\":\"04:00\",\"timeAsSeconds\":14400,\"value\":0.4575},{\"time\":\"05:00\",\"timeAsSeconds\":18000,\"value\":0.5175},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":0.48},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":0.51},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":0.48750000000000004},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":0.48},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":0.48750000000000004},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":0.5025000000000001},{\"time\":\"12:00\",\"timeAsSeconds\":43200,\"value\":0.5549999999999999},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":0.5700000000000001},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":0.5700000000000001},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":0.5775},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":0.51},{\"time\":\"17:00\",\"timeAsSeconds\":61200,\"value\":0.54},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":0.48750000000000004},{\"time\":\"19:00\",\"timeAsSeconds\":68400,\"value\":0.5249999999999999},{\"time\":\"20:00\",\"timeAsSeconds\":72000,\"value\":0.46499999999999997},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":0.46499999999999997},{\"time\":\"22:00\",\"timeAsSeconds\":79200,\"value\":0.43499999999999994},{\"time\":\"23:00\",\"timeAsSeconds\":82800,\"value\":0.41250000000000003}],\"target_low\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}],\"target_high\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}]}", // \"sens\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":60},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":60},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":61.33333333333333},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":65.33333333333333},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":69.33333333333333},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":73.33333333333333},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":72},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":68},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":65.33333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":65.33333333333333}],\"carbratio\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":5.7333333333333325},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":7.333333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":6.666666666666666}],\"basal\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0.5249999999999999},{\"time\":\"01:00\",\"timeAsSeconds\":3600,\"value\":0.585},{\"time\":\"02:00\",\"timeAsSeconds\":7200,\"value\":0.6375},{\"time\":\"03:00\",\"timeAsSeconds\":10800,\"value\":0.5625},{\"time\":\"04:00\",\"timeAsSeconds\":14400,\"value\":0.4575},{\"time\":\"05:00\",\"timeAsSeconds\":18000,\"value\":0.5175},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":0.48},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":0.51},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":0.48750000000000004},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":0.48},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":0.48750000000000004},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":0.5025000000000001},{\"time\":\"12:00\",\"timeAsSeconds\":43200,\"value\":0.5549999999999999},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":0.5700000000000001},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":0.5700000000000001},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":0.5775},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":0.51},{\"time\":\"17:00\",\"timeAsSeconds\":61200,\"value\":0.54},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":0.48750000000000004},{\"time\":\"19:00\",\"timeAsSeconds\":68400,\"value\":0.5249999999999999},{\"time\":\"20:00\",\"timeAsSeconds\":72000,\"value\":0.46499999999999997},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":0.46499999999999997},{\"time\":\"22:00\",\"timeAsSeconds\":79200,\"value\":0.43499999999999994},{\"time\":\"23:00\",\"timeAsSeconds\":82800,\"value\":0.41250000000000003}],\"target_low\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}],\"target_high\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}]}",
@SerializedName("originalProfileName") val originalProfileName: String?, // string "Effective Profile Switch" @SerializedName("originalProfileName") val originalProfileName: String? = null, // string "Effective Profile Switch"
@SerializedName("originalCustomizedName") val originalCustomizedName: String?, // string "Effective Profile Switch" @SerializedName("originalCustomizedName") val originalCustomizedName: String? = null, // string "Effective Profile Switch"
@SerializedName("originalTimeshift") val originalTimeshift: Long?, // long "Effective Profile Switch" @SerializedName("originalTimeshift") val originalTimeshift: Long? = null, // long "Effective Profile Switch"
@SerializedName("originalPercentage") val originalPercentage: Int?, // int "Effective Profile Switch" @SerializedName("originalPercentage") val originalPercentage: Int? = null, // int "Effective Profile Switch"
@SerializedName("originalDuration") val originalDuration: Long?, // long "Effective Profile Switch" @SerializedName("originalDuration") val originalDuration: Long? = null, // long "Effective Profile Switch"
@SerializedName("originalEnd") val originalEnd: Long?, // long "Effective Profile Switch" @SerializedName("originalEnd") val originalEnd: Long? = null, // long "Effective Profile Switch"
@SerializedName("bolusCalculatorResult") val bolusCalculatorResult: String?, // string "Bolus Wizard" json toString ex "bolusCalculatorResult": "{\"basalIOB\":-0.247,\"bolusIOB\":-1.837,\"carbs\":45.0,\"carbsInsulin\":9.0,\"cob\":0.0,\"cobInsulin\":0.0,\"dateCreated\":1626202788810,\"glucoseDifference\":44.0,\"glucoseInsulin\":0.8979591836734694,\"glucoseTrend\":5.5,\"glucoseValue\":134.0,\"ic\":5.0,\"id\":331,\"interfaceIDs_backing\":{\"nightscoutId\":\"60ede2a4c574da0004a3869d\"},\"isValid\":true,\"isf\":49.0,\"note\":\"\",\"otherCorrection\":0.0,\"percentageCorrection\":90,\"profileName\":\"Tuned 13/01 90%Lyum\",\"superbolusInsulin\":0.0,\"targetBGHigh\":90.0,\"targetBGLow\":90.0,\"timestamp\":1626202783325,\"totalInsulin\":7.34,\"trendInsulin\":0.336734693877551,\"utcOffset\":7200000,\"version\":1,\"wasBasalIOBUsed\":true,\"wasBolusIOBUsed\":true,\"wasCOBUsed\":true,\"wasGlucoseUsed\":true,\"wasSuperbolusUsed\":false,\"wasTempTargetUsed\":false,\"wasTrendUsed\":true,\"wereCarbsUsed\":false}", @SerializedName("bolusCalculatorResult") val bolusCalculatorResult: String? = null, // string "Bolus Wizard" json toString ex "bolusCalculatorResult": "{\"basalIOB\":-0.247,\"bolusIOB\":-1.837,\"carbs\":45.0,\"carbsInsulin\":9.0,\"cob\":0.0,\"cobInsulin\":0.0,\"dateCreated\":1626202788810,\"glucoseDifference\":44.0,\"glucoseInsulin\":0.8979591836734694,\"glucoseTrend\":5.5,\"glucoseValue\":134.0,\"ic\":5.0,\"id\":331,\"interfaceIDs_backing\":{\"nightscoutId\":\"60ede2a4c574da0004a3869d\"},\"isValid\":true,\"isf\":49.0,\"note\":\"\",\"otherCorrection\":0.0,\"percentageCorrection\":90,\"profileName\":\"Tuned 13/01 90%Lyum\",\"superbolusInsulin\":0.0,\"targetBGHigh\":90.0,\"targetBGLow\":90.0,\"timestamp\":1626202783325,\"totalInsulin\":7.34,\"trendInsulin\":0.336734693877551,\"utcOffset\":7200000,\"version\":1,\"wasBasalIOBUsed\":true,\"wasBolusIOBUsed\":true,\"wasCOBUsed\":true,\"wasGlucoseUsed\":true,\"wasSuperbolusUsed\":false,\"wasTempTargetUsed\":false,\"wasTrendUsed\":true,\"wereCarbsUsed\":false}",
@SerializedName("type") val type: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus", "Temp Basal" type of bolus "NORMAL", "SMB", "FAKE_EXTENDED" @SerializedName("type") val type: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus", "Temp Basal" type of bolus "NORMAL", "SMB", "FAKE_EXTENDED"
@SerializedName("isSMB") val isSMB: Boolean, // boolean "Meal Bolus", "Correction Bolus", "Combo Bolus" @SerializedName("isSMB") val isSMB: Boolean? = null, // boolean "Meal Bolus", "Correction Bolus", "Combo Bolus"
@SerializedName("enteredinsulin") val enteredinsulin: Double?, // number... "Combo Bolus" insulin is missing only enteredinsulin field found @SerializedName("enteredinsulin") val enteredinsulin: Double? = null, // number... "Combo Bolus" insulin is missing only enteredinsulin field found
@SerializedName("relative") val relative: Double?, // number... "Combo Bolus", "extendedEmulated" (not in doc see below) @SerializedName("relative") val relative: Double? = null, // number... "Combo Bolus", "extendedEmulated" (not in doc see below)
@SerializedName("isEmulatingTempBasal") val isEmulatingTempBasal: Boolean, // 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, // boolean "Announcement" @SerializedName("isAnnouncement") val isAnnouncement: Boolean? = null, // boolean "Announcement"
@SerializedName("rate") val rate: Double?, // 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?, // Gson of emulated EB @SerializedName("extendedEmulated") val extendedEmulated: RemoteTreatment? = null, // Gson of emulated EB
@SerializedName("timeshift") val timeshift: Long, // integer "Profile Switch" @SerializedName("timeshift") val timeshift: Long? = null, // integer "Profile Switch"
@SerializedName("percentage") val percentage: Int?, // integer "Profile Switch" @SerializedName("percentage") val percentage: Int? = null // integer "Profile Switch"
) { ) {
fun timestamp(): Long { fun timestamp(): Long {
return date ?: mills ?: timestamp ?: fromISODateString(created_at) return date ?: mills ?: timestamp ?: created_at?. let { fromISODateString(created_at) } ?: 0L
} }
private fun fromISODateString(isoDateString: String): Long = private fun fromISODateString(isoDateString: String): Long =

View file

@ -5,6 +5,7 @@ import info.nightscout.core.extensions.getCustomizedName
import info.nightscout.core.extensions.pureProfileFromJson import info.nightscout.core.extensions.pureProfileFromJson
import info.nightscout.core.profile.ProfileSealed import info.nightscout.core.profile.ProfileSealed
import info.nightscout.database.entities.ProfileSwitch import info.nightscout.database.entities.ProfileSwitch
import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
@ -23,7 +24,7 @@ fun ProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
.put("created_at", dateUtil.toISOString(timestamp)) .put("created_at", dateUtil.toISOString(timestamp))
.put("enteredBy", "openaps://" + "AndroidAPS") .put("enteredBy", "openaps://" + "AndroidAPS")
.put("isValid", isValid) .put("isValid", isValid)
.put("eventType", info.nightscout.database.entities.TherapyEvent.Type.PROFILE_SWITCH.text) .put("eventType", TherapyEvent.Type.PROFILE_SWITCH.text)
.also { // remove customization to store original profileJson in toPureNsJson call .also { // remove customization to store original profileJson in toPureNsJson call
timeshift = 0 timeshift = 0
percentage = 100 percentage = 100

View file

@ -11,6 +11,6 @@ fun NSExtendedBolus.toExtendedBolus(): ExtendedBolus =
utcOffset = utcOffset, utcOffset = utcOffset,
amount = enteredinsulin, amount = enteredinsulin,
duration = duration, duration = duration,
isEmulatingTempBasal = isEmulatingTempbasal, 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)
) )