NSCv3: NSDeviceStatus

This commit is contained in:
Milos Kozak 2023-01-08 22:18:35 +01:00
parent 4b6eab6aa4
commit 9fa5017b15
13 changed files with 250 additions and 52 deletions

View file

@ -1,6 +1,6 @@
package info.nightscout.interfaces.configBuilder
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import org.json.JSONObject
interface RunningConfiguration {
@ -9,5 +9,5 @@ interface RunningConfiguration {
fun configuration(): JSONObject
// called in NSClient mode only
fun apply(configuration: RemoteDeviceStatus.Configuration)
fun apply(configuration: NSDeviceStatus.Configuration)
}

View file

@ -9,12 +9,15 @@ import info.nightscout.sdk.exceptions.UnknownResponseNightscoutException
import info.nightscout.sdk.exceptions.UnsuccessfullNightscoutException
import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.sdk.localmodel.Status
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.food.NSFood
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.toNSDeviceStatus
import info.nightscout.sdk.mapper.toNSFood
import info.nightscout.sdk.mapper.toRemoteDeviceStatus
import info.nightscout.sdk.mapper.toRemoteEntry
import info.nightscout.sdk.mapper.toRemoteFood
import info.nightscout.sdk.mapper.toRemoteTreatment
@ -227,20 +230,20 @@ class NSAndroidClientImpl(
}
}
override suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus> = callWrapper(dispatcher) {
override suspend fun getDeviceStatusModifiedSince(from: Long): List<NSDeviceStatus> = callWrapper(dispatcher) {
val response = api.getDeviceStatusModifiedSince(from)
if (response.isSuccessful) {
return@callWrapper response.body()?.result.toNotNull()
return@callWrapper response.body()?.result?.map(RemoteDeviceStatus::toNSDeviceStatus).toNotNull()
} else {
throw UnsuccessfullNightscoutException()
}
}
override suspend fun createDeviceStatus(remoteDeviceStatus: RemoteDeviceStatus): CreateUpdateResponse = callWrapper(dispatcher) {
override suspend fun createDeviceStatus(nsDeviceStatus: NSDeviceStatus): CreateUpdateResponse = callWrapper(dispatcher) {
remoteDeviceStatus.app = "AAPS"
val response = api.createDeviceStatus(remoteDeviceStatus)
nsDeviceStatus.app = "AAPS"
val response = api.createDeviceStatus(nsDeviceStatus.toRemoteDeviceStatus())
if (response.isSuccessful) {
if (response.code() == 200) {
return@callWrapper CreateUpdateResponse(

View file

@ -1,12 +1,12 @@
package info.nightscout.sdk.interfaces
import info.nightscout.sdk.localmodel.Status
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.food.NSFood
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
import info.nightscout.sdk.localmodel.treatment.NSTreatment
import info.nightscout.sdk.remotemodel.LastModified
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import org.json.JSONObject
interface NSAndroidClient {
@ -30,8 +30,8 @@ interface NSAndroidClient {
suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): List<NSTreatment>
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>>
suspend fun createDeviceStatus(remoteDeviceStatus: RemoteDeviceStatus): CreateUpdateResponse
suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus>
suspend fun createDeviceStatus(nsDeviceStatus: NSDeviceStatus): CreateUpdateResponse
suspend fun getDeviceStatusModifiedSince(from: Long): List<NSDeviceStatus>
suspend fun createProfileStore(remoteProfileStore: JSONObject): CreateUpdateResponse
suspend fun getLastProfileStore(): ReadResponse<List<JSONObject>>

View file

@ -0,0 +1,74 @@
package info.nightscout.sdk.localmodel.devicestatus
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.json.JSONObject
/**
* NS DeviceStatus coming from uploader or AAPS
*
**/
@Serializable
data class NSDeviceStatus(
@SerializedName("app") var app: String? = null,
@SerializedName("identifier")
val identifier: String? = null, // 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("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("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("created_at")
val createdAt: String? = null, // string 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("date") val date: Long?, // date as milliseconds
@SerializedName("uploaderBattery") val uploaderBattery: Int?,// integer($int64)
@SerializedName("device") val device: String?, // "openaps://samsung SM-G970F"
@SerializedName("uploader") val uploader: Uploader?,
@SerializedName("pump") val pump: Pump?,
@SerializedName("openaps") val openaps: OpenAps?,
@SerializedName("configuration") val configuration: Configuration?
) {
@Serializable data class Pump(
@SerializedName("clock") val clock: String?, // timestamp in ISO
@SerializedName("reservoir") val reservoir: Double?,
@SerializedName("reservoir_display_override") val reservoirDisplayOverride: String?,
@SerializedName("battery") val battery: Battery?,
@SerializedName("status") val status: Status?,
@Contextual @SerializedName("extended") val extended: JSONObject? // Gson, content depending on pump driver
) {
@Serializable data class Battery(
@SerializedName("percent") val percent: Int?,
@SerializedName("voltage") val voltage: Double?
)
@Serializable data class Status(
@SerializedName("status") val status: String?,
@SerializedName("timestamp") val timestamp: String?
)
}
@Serializable data class OpenAps(
@Contextual @SerializedName("suggested") val suggested: JSONObject?, // Gson
@Contextual @SerializedName("enacted") val enacted: JSONObject?, // Gson
@Contextual @SerializedName("iob") val iob: JSONObject? // Gson
)
@Serializable data class Uploader(
@SerializedName("battery") val battery: Int?,
)
@Serializable data class Configuration(
@SerializedName("pump") val pump: String?,
@SerializedName("version") val version: String?,
@SerializedName("insulin") val insulin: Int?,
@SerializedName("sensitivity") val sensitivity: Int?,
@SerializedName("smoothing") val smoothing: String?,
@Contextual @SerializedName("insulinConfiguration") val insulinConfiguration: JSONObject?,
@Contextual @SerializedName("sensitivityConfiguration") val sensitivityConfiguration: JSONObject?,
@Contextual @SerializedName("overviewConfiguration") val overviewConfiguration: JSONObject?,
@Contextual @SerializedName("safetyConfiguration") val safetyConfiguration: JSONObject?
)
}

View file

@ -0,0 +1,102 @@
package info.nightscout.sdk.mapper
import com.google.gson.JsonParser
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import org.json.JSONObject
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
toRemoteDeviceStatus().toNSDeviceStatus()
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
NSDeviceStatus(
app = app,
identifier = identifier,
srvCreated = srvCreated,
srvModified = srvModified,
createdAt = createdAt,
date = date,
uploaderBattery = uploaderBattery,
device = device,
uploader = NSDeviceStatus.Uploader(uploader?.battery),
pump = pump?.toNSDeviceStatusPump(),
openaps = openaps?.toNSDeviceStatusOpenAps(),
configuration = configuration?.toNSDeviceStatusConfiguration()
)
internal fun NSDeviceStatus.toRemoteDeviceStatus(): RemoteDeviceStatus =
RemoteDeviceStatus(
app = app,
identifier = identifier,
srvCreated = srvCreated,
srvModified = srvModified,
createdAt = createdAt,
date = date,
uploaderBattery = uploaderBattery,
device = device,
uploader = RemoteDeviceStatus.Uploader(uploader?.battery),
pump = pump?.toRemoteDeviceStatusPump(),
openaps = openaps?.toRemoteDeviceStatusOpenAps(),
configuration = configuration?.toRemoteDeviceStatusConfiguration()
)
internal fun RemoteDeviceStatus.Pump.toNSDeviceStatusPump(): NSDeviceStatus.Pump =
NSDeviceStatus.Pump(
clock = clock,
reservoir = reservoir,
reservoirDisplayOverride = reservoirDisplayOverride,
battery = NSDeviceStatus.Pump.Battery(battery?.percent, battery?.voltage),
status = NSDeviceStatus.Pump.Status(status?.status, status?.timestamp),
extended = extended?.let { JSONObject(it.toString()) }
)
internal fun NSDeviceStatus.Pump.toRemoteDeviceStatusPump(): RemoteDeviceStatus.Pump =
RemoteDeviceStatus.Pump(
clock = clock,
reservoir = reservoir,
reservoirDisplayOverride = reservoirDisplayOverride,
battery = RemoteDeviceStatus.Pump.Battery(battery?.percent, battery?.voltage),
status = RemoteDeviceStatus.Pump.Status(status?.status, status?.timestamp),
extended = extended?.let { JsonParser.parseString(it.toString()).asJsonObject }
)
internal fun RemoteDeviceStatus.OpenAps.toNSDeviceStatusOpenAps(): NSDeviceStatus.OpenAps =
NSDeviceStatus.OpenAps(
suggested = suggested?.let { JSONObject(it.toString()) },
enacted = enacted?.let { JSONObject(it.toString()) },
iob = iob?.let { JSONObject(it.toString()) }
)
internal fun NSDeviceStatus.OpenAps.toRemoteDeviceStatusOpenAps(): RemoteDeviceStatus.OpenAps =
RemoteDeviceStatus.OpenAps(
suggested = suggested?.let { JsonParser.parseString(it.toString()).asJsonObject },
enacted = enacted?.let { JsonParser.parseString(it.toString()).asJsonObject },
iob = iob?.let { JsonParser.parseString(it.toString()).asJsonObject }
)
internal fun RemoteDeviceStatus.Configuration.toNSDeviceStatusConfiguration(): NSDeviceStatus.Configuration =
NSDeviceStatus.Configuration(
pump = pump,
version = version,
insulin = insulin,
sensitivity = sensitivity,
smoothing = smoothing,
insulinConfiguration = insulinConfiguration?.let { JSONObject(it.toString()) },
sensitivityConfiguration = sensitivityConfiguration?.let { JSONObject(it.toString()) },
overviewConfiguration = overviewConfiguration?.let { JSONObject(it.toString()) },
safetyConfiguration = safetyConfiguration?.let { JSONObject(it.toString()) }
)
internal fun NSDeviceStatus.Configuration.toRemoteDeviceStatusConfiguration(): RemoteDeviceStatus.Configuration =
RemoteDeviceStatus.Configuration(
pump = pump,
version = version,
insulin = insulin,
sensitivity = sensitivity,
smoothing = smoothing,
insulinConfiguration = insulinConfiguration?.let { JsonParser.parseString(it.toString()).asJsonObject },
sensitivityConfiguration = sensitivityConfiguration?.let { JsonParser.parseString(it.toString()).asJsonObject },
overviewConfiguration = overviewConfiguration?.let { JsonParser.parseString(it.toString()).asJsonObject },
safetyConfiguration = safetyConfiguration?.let { JsonParser.parseString(it.toString()).asJsonObject }
)

View file

@ -1,21 +1,25 @@
package info.nightscout.sdk.remotemodel
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.json.JSONObject
/**
* DeviceStatus coming from uploader or AAPS
*
**/
@Serializable
data class RemoteDeviceStatus(
internal data class RemoteDeviceStatus(
@SerializedName("app") var app: String? = null,
@SerializedName("identifier") val identifier: String? = null, // 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("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("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("created_at") val createdAt: String? = null, // string 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("identifier")
val identifier: String? = null, // 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("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("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("created_at")
val createdAt: String? = null, // string 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("date") val date: Long?, // date as milliseconds
@SerializedName("uploaderBattery") val uploaderBattery: Int?,// integer($int64)
@SerializedName("device") val device: String?, // "openaps://samsung SM-G970F"
@ -32,7 +36,7 @@ data class RemoteDeviceStatus(
@SerializedName("reservoir_display_override") val reservoirDisplayOverride: String?,
@SerializedName("battery") val battery: Battery?,
@SerializedName("status") val status: Status?,
@Contextual @SerializedName("extended") val extended: JSONObject? // Gson, content depending on pump driver
@Contextual @SerializedName("extended") val extended: JsonObject? // Gson, content depending on pump driver
) {
@Serializable data class Battery(
@ -47,9 +51,9 @@ data class RemoteDeviceStatus(
}
@Serializable data class OpenAps(
@Contextual @SerializedName("suggested") val suggested: JSONObject?, // Gson
@Contextual @SerializedName("enacted") val enacted: JSONObject?, // Gson
@Contextual @SerializedName("iob") val iob: JSONObject? // Gson
@Contextual @SerializedName("suggested") val suggested: JsonObject?, // Gson
@Contextual @SerializedName("enacted") val enacted: JsonObject?, // Gson
@Contextual @SerializedName("iob") val iob: JsonObject? // Gson
)
@Serializable data class Uploader(
@ -62,9 +66,9 @@ data class RemoteDeviceStatus(
@SerializedName("insulin") val insulin: Int?,
@SerializedName("sensitivity") val sensitivity: Int?,
@SerializedName("smoothing") val smoothing: String?,
@Contextual @SerializedName("insulinConfiguration") val insulinConfiguration: JSONObject?,
@Contextual @SerializedName("sensitivityConfiguration") val sensitivityConfiguration: JSONObject?,
@Contextual @SerializedName("overviewConfiguration") val overviewConfiguration: JSONObject?,
@Contextual @SerializedName("safetyConfiguration") val safetyConfiguration: JSONObject?
@Contextual @SerializedName("insulinConfiguration") val insulinConfiguration: JsonObject?,
@Contextual @SerializedName("sensitivityConfiguration") val sensitivityConfiguration: JsonObject?,
@Contextual @SerializedName("overviewConfiguration") val overviewConfiguration: JsonObject?,
@Contextual @SerializedName("safetyConfiguration") val safetyConfiguration: JsonObject?
)
}

View file

@ -17,7 +17,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONException
@ -71,7 +71,7 @@ class RunningConfigurationImpl @Inject constructor(
}
// called in NSClient mode only
override fun apply(configuration: RemoteDeviceStatus.Configuration) {
override fun apply(configuration: NSDeviceStatus.Configuration) {
assert(config.NSCLIENT)
configuration.version?.let {

View file

@ -5,7 +5,7 @@ import info.nightscout.interfaces.configBuilder.RunningConfiguration
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import javax.inject.Inject
@ -73,7 +73,7 @@ class NSDeviceStatusHandler @Inject constructor(
private val processedDeviceStatusData: ProcessedDeviceStatusData
) {
fun handleNewData(deviceStatuses: Array<RemoteDeviceStatus>) {
fun handleNewData(deviceStatuses: Array<NSDeviceStatus>) {
var configurationDetected = false
for (i in deviceStatuses.size - 1 downTo 0) {
val nsDeviceStatus = deviceStatuses[i]
@ -91,7 +91,7 @@ class NSDeviceStatusHandler @Inject constructor(
}
}
private fun updateDeviceData(deviceStatus: RemoteDeviceStatus) {
private fun updateDeviceData(deviceStatus: NSDeviceStatus) {
val createdAt = deviceStatus.createdAt?.let { dateUtil.fromISODateString(it) } ?: return
processedDeviceStatusData.device?.let { if (createdAt < it.createdAt) return } // take only newer record
deviceStatus.device?.let {
@ -99,8 +99,8 @@ class NSDeviceStatusHandler @Inject constructor(
}
}
private fun updatePumpData(remoteDeviceStatus: RemoteDeviceStatus) {
val pump = remoteDeviceStatus.pump ?: return
private fun updatePumpData(NSDeviceStatus: NSDeviceStatus) {
val pump = NSDeviceStatus.pump ?: return
val clock = pump.clock?.let { dateUtil.fromISODateString(it) } ?: return
processedDeviceStatusData.pumpData?.let { if (clock < it.clock) return } // take only newer record
@ -132,8 +132,8 @@ class NSDeviceStatusHandler @Inject constructor(
}
}
private fun updateOpenApsData(remoteDeviceStatus: RemoteDeviceStatus) {
remoteDeviceStatus.openaps?.suggested?.let {
private fun updateOpenApsData(NSDeviceStatus: NSDeviceStatus) {
NSDeviceStatus.openaps?.suggested?.let {
JsonHelper.safeGetString(it, "timestamp")?.let { timestamp ->
val clock = dateUtil.fromISODateString(timestamp)
// check if this is new data
@ -143,7 +143,7 @@ class NSDeviceStatusHandler @Inject constructor(
}
}
}
remoteDeviceStatus.openaps?.enacted?.let {
NSDeviceStatus.openaps?.enacted?.let {
JsonHelper.safeGetString(it, "timestamp")?.let { timestamp ->
val clock = dateUtil.fromISODateString(timestamp)
// check if this is new data
@ -155,10 +155,10 @@ class NSDeviceStatusHandler @Inject constructor(
}
}
private fun updateUploaderData(remoteDeviceStatus: RemoteDeviceStatus) {
val clock = remoteDeviceStatus.createdAt?.let { dateUtil.fromISODateString(it) } ?: return
val device = remoteDeviceStatus.device ?: return
val battery = remoteDeviceStatus.uploaderBattery ?: remoteDeviceStatus.uploader?.battery ?: return
private fun updateUploaderData(NSDeviceStatus: NSDeviceStatus) {
val clock = NSDeviceStatus.createdAt?.let { dateUtil.fromISODateString(it) } ?: return
val device = NSDeviceStatus.device ?: return
val battery = NSDeviceStatus.uploaderBattery ?: NSDeviceStatus.uploader?.battery ?: return
var uploader = processedDeviceStatusData.uploaderMap[device]
// check if this is new data

View file

@ -59,8 +59,8 @@ class ProcessedDeviceStatusDataImpl @Inject constructor(
}
string.append("<span style=\"color:${level.toColor()}\">")
// val insulinUnit = rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname)
val fields = nsSettingsStatus.pumpExtendedSettingsFields()
// Removed here. Same value is in StatusLights
// val fields = nsSettingsStatus.pumpExtendedSettingsFields()
// Removed here. Same value is in StatusLights
// if (pumpData.reservoirDisplayOverride != "") string.append(pumpData.reservoirDisplayOverride).append("$insulinUnit ")
// else if (fields.contains("reservoir")) string.append(pumpData.reservoir.toInt()).append("$insulinUnit ")
if (pumpData.isPercent) string.append(pumpData.percent).append("% ")

View file

@ -52,7 +52,7 @@ import info.nightscout.rx.events.EventNSClientRestart
import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -510,7 +510,7 @@ class NSClientService : DaggerService() {
}
}
val devicestatuses = gson.fromJson(data.getString("devicestatus"), Array<RemoteDeviceStatus>::class.java)
val devicestatuses = gson.fromJson(data.getString("devicestatus"), Array<NSDeviceStatus>::class.java)
if (devicestatuses.isNotEmpty()) {
rxBus.send(EventNSClientNewLog("DATA", "received " + devicestatuses.size + " device statuses"))
nsDeviceStatusHandler.handleNewData(devicestatuses)

View file

@ -39,6 +39,7 @@ import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSDeviceStatus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSEffectiveProfileSwitch
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSExtendedBolus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSFood
@ -48,7 +49,6 @@ 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
import info.nightscout.plugins.sync.nsclientV3.extensions.toRemoteDeviceStatus
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
@ -371,7 +371,7 @@ class NSClientV3Plugin @Inject constructor(
}
private fun dbOperationDeviceStatus(collection: String = "devicestatus", dataPair: DataSyncSelector.DataPair, progress: String) {
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toRemoteDeviceStatus()
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
scope.launch {
try {
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"))

View file

@ -3,10 +3,10 @@ package info.nightscout.plugins.sync.nsclientV3.extensions
import com.google.gson.GsonBuilder
import com.google.gson.JsonDeserializer
import info.nightscout.database.entities.DeviceStatus
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import org.json.JSONObject
fun DeviceStatus.toRemoteDeviceStatus(): RemoteDeviceStatus {
fun DeviceStatus.toNSDeviceStatus(): NSDeviceStatus {
val deserializer: JsonDeserializer<JSONObject?> =
JsonDeserializer<JSONObject?> { json, _, _ ->
JSONObject(json.asJsonObject.toString())
@ -15,19 +15,19 @@ fun DeviceStatus.toRemoteDeviceStatus(): RemoteDeviceStatus {
it.registerTypeAdapter(JSONObject::class.java, deserializer)
}.create()
val pump = gson.fromJson(pump, RemoteDeviceStatus.Pump::class.java)
val openAps = RemoteDeviceStatus.OpenAps(
val pump = gson.fromJson(pump, NSDeviceStatus.Pump::class.java)
val openAps = NSDeviceStatus.OpenAps(
suggested = suggested?.let { JSONObject(it) },
enacted = enacted?.let { JSONObject(it) },
iob = iob?.let { JSONObject(it) },
)
return RemoteDeviceStatus(
return NSDeviceStatus(
date = timestamp,
device = device,
pump = pump,
openaps = openAps,
uploaderBattery = if (uploaderBattery != 0) uploaderBattery else null,
configuration = gson.fromJson(configuration, RemoteDeviceStatus.Configuration::class.java),
configuration = gson.fromJson(configuration, NSDeviceStatus.Configuration::class.java),
uploader = null
)
}

View file

@ -15,6 +15,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.plugins.aps.APSResultObject
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
import info.nightscout.sdk.mapper.convertToRemoteAndBack
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -78,9 +79,23 @@ internal class DeviceStatusExtensionKtTest : TestBase() {
configuration = "{\"insulin\":5,\"insulinConfiguration\":{},\"sensitivity\":2,\"sensitivityConfiguration\":{\"openapsama_min_5m_carbimpact\":8,\"absorption_cutoff\":4,\"autosens_max\":1.2,\"autosens_min\":0.7},\"overviewConfiguration\":{\"units\":\"mmol\",\"QuickWizard\":\"[]\",\"eatingsoon_duration\":60,\"eatingsoon_target\":4,\"activity_duration\":180,\"activity_target\":7.5,\"hypo_duration\":90,\"hypo_target\":8,\"low_mark\":3.9,\"high_mark\":10,\"statuslights_cage_warning\":72,\"statuslights_cage_critical\":96,\"statuslights_iage_warning\":120,\"statuslights_iage_critical\":150,\"statuslights_sage_warning\":168,\"statuslights_sage_critical\":336,\"statuslights_sbat_warning\":25,\"statuslights_sbat_critical\":5,\"statuslights_bage_warning\":720,\"statuslights_bage_critical\":800,\"statuslights_res_warning\":30,\"statuslights_res_critical\":10,\"statuslights_bat_warning\":50,\"statuslights_bat_critical\":25,\"boluswizard_percentage\":70},\"safetyConfiguration\":{\"age\":\"resistantadult\",\"treatmentssafety_maxbolus\":10,\"treatmentssafety_maxcarbs\":70}}"
)
val remoteDeviceStatus = deviceStatus.toRemoteDeviceStatus()
val nsDeviceStatus = deviceStatus.toNSDeviceStatus()
nsDeviceStatusHandler.handleNewData(arrayOf(remoteDeviceStatus))
nsDeviceStatusHandler.handleNewData(arrayOf(nsDeviceStatus))
Assertions.assertEquals(75, processedDeviceStatusData.pumpData?.percent)
val nsDeviceStatus2 = nsDeviceStatus.convertToRemoteAndBack()
Assertions.assertTrue(nsDeviceStatus.device == nsDeviceStatus2.device)
Assertions.assertTrue(nsDeviceStatus.identifier == nsDeviceStatus2.identifier)
Assertions.assertTrue(nsDeviceStatus.srvCreated == nsDeviceStatus2.srvCreated)
Assertions.assertTrue(nsDeviceStatus.srvModified == nsDeviceStatus2.srvModified)
Assertions.assertTrue(nsDeviceStatus.createdAt == nsDeviceStatus2.createdAt)
Assertions.assertTrue(nsDeviceStatus.date == nsDeviceStatus2.date)
Assertions.assertTrue(nsDeviceStatus.uploaderBattery == nsDeviceStatus2.uploaderBattery)
Assertions.assertTrue(nsDeviceStatus.device == nsDeviceStatus2.device)
Assertions.assertTrue(nsDeviceStatus.uploader?.battery == nsDeviceStatus2.uploader?.battery)
Assertions.assertTrue(nsDeviceStatus.pump?.battery == nsDeviceStatus2.pump?.battery)
Assertions.assertTrue(nsDeviceStatus.openaps?.enacted?.toString() == nsDeviceStatus2.openaps?.enacted?.toString())
Assertions.assertTrue(nsDeviceStatus.configuration?.toString() == nsDeviceStatus2.configuration?.toString())
}
}