diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index 1eca9dadd1..6e3f5de1c2 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -349,6 +349,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() { message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n" message += "${rh.gs(info.nightscout.configuration.R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.getVersion()}" if (config.isEngineeringMode()) message += "\n${rh.gs(info.nightscout.configuration.R.string.engineering_mode_enabled)}" + if (config.isUnfinishedMode()) message += "\nUnfinished mode enabled" if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(R.string.fabric_upload_disabled)}" message += rh.gs(info.nightscout.pump.combo.R.string.about_link_urls) val messageSpanned = SpannableString(message) diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/nsclient/StoreDataForDb.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/nsclient/StoreDataForDb.kt index d01b23f829..7bb85952c0 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/nsclient/StoreDataForDb.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/nsclient/StoreDataForDb.kt @@ -1,7 +1,48 @@ package info.nightscout.interfaces.nsclient +import info.nightscout.database.entities.Bolus +import info.nightscout.database.entities.BolusCalculatorResult +import info.nightscout.database.entities.Carbs +import info.nightscout.database.entities.DeviceStatus +import info.nightscout.database.entities.EffectiveProfileSwitch +import info.nightscout.database.entities.ExtendedBolus +import info.nightscout.database.entities.Food +import info.nightscout.database.entities.GlucoseValue +import info.nightscout.database.entities.OfflineEvent +import info.nightscout.database.entities.ProfileSwitch +import info.nightscout.database.entities.TemporaryBasal +import info.nightscout.database.entities.TemporaryTarget +import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.transactions.TransactionGlucoseValue interface StoreDataForDb { val glucoseValues: MutableList + val boluses: MutableList + val carbs: MutableList + val temporaryTargets: MutableList + val effectiveProfileSwitches: MutableList + val bolusCalculatorResults: MutableList + val therapyEvents: MutableList + val extendedBoluses: MutableList + val temporaryBasals: MutableList + val profileSwitches: MutableList + val offlineEvents: MutableList + + val nsIdGlucoseValues: MutableList + val nsIdBoluses: MutableList + val nsIdCarbs: MutableList + val nsIdFoods: MutableList + val nsIdTemporaryTargets: MutableList + val nsIdEffectiveProfileSwitches: MutableList + val nsIdBolusCalculatorResults: MutableList + val nsIdTherapyEvents: MutableList + val nsIdExtendedBoluses: MutableList + val nsIdTemporaryBasals: MutableList + val nsIdProfileSwitches: MutableList + val nsIdOfflineEvents: MutableList + val nsIdDeviceStatuses: MutableList + + fun storeTreatmentsToDb() + fun storeGlucoseValuesToDb() + fun scheduleNsIdUpdate() } \ No newline at end of file diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/sync/DataSyncSelector.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/sync/DataSyncSelector.kt index dc097f6b8f..9ae892c854 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/sync/DataSyncSelector.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/sync/DataSyncSelector.kt @@ -17,19 +17,24 @@ import org.json.JSONObject interface DataSyncSelector { - data class PairTemporaryTarget(val value: TemporaryTarget, val updateRecordId: Long) - data class PairGlucoseValue(val value: GlucoseValue, val updateRecordId: Long) - data class PairTherapyEvent(val value: TherapyEvent, val updateRecordId: Long) - data class PairFood(val value: Food, val updateRecordId: Long) - data class PairBolus(val value: Bolus, val updateRecordId: Long) - data class PairCarbs(val value: Carbs, val updateRecordId: Long) - data class PairBolusCalculatorResult(val value: BolusCalculatorResult, val updateRecordId: Long) - data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long) - data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long) - data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long) - data class PairEffectiveProfileSwitch(val value: EffectiveProfileSwitch, val updateRecordId: Long) - data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long) - data class PairProfileStore(val value: JSONObject, val timestampSync: Long) + interface DataPair { + val value: Any + val id: Long + } + data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long): DataPair + data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long): DataPair + data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long): DataPair + data class PairFood(override val value: Food, override val id: Long): DataPair + data class PairBolus(override val value: Bolus, override val id: Long): DataPair + data class PairCarbs(override val value: Carbs, override val id: Long): DataPair + data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long): DataPair + data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long): DataPair + data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long): DataPair + data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long): DataPair + data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long): DataPair + data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long): DataPair + data class PairProfileStore(override val value: JSONObject, override val id: Long): DataPair + data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long): DataPair fun queueSize(): Long @@ -38,81 +43,42 @@ interface DataSyncSelector { fun resetToNextFullSync() fun confirmLastBolusIdIfGreater(lastSynced: Long) - fun changedBoluses(): List - - // Until NS v3 fun processChangedBolusesCompat() fun confirmLastCarbsIdIfGreater(lastSynced: Long) - fun changedCarbs(): List - - // Until NS v3 fun processChangedCarbsCompat() fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) - fun changedBolusCalculatorResults(): List - - // Until NS v3 fun processChangedBolusCalculatorResultsCompat() fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) - fun changedTempTargets(): List - - // Until NS v3 fun processChangedTempTargetsCompat() fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) - fun changedGlucoseValues(): List - - // Until NS v3 fun processChangedGlucoseValuesCompat() fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) - fun changedTherapyEvents(): List - - // Until NS v3 fun processChangedTherapyEventsCompat() fun confirmLastFoodIdIfGreater(lastSynced: Long) - fun changedFoods(): List - - // Until NS v3 fun processChangedFoodsCompat() fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) - fun changedDeviceStatuses(): List - - // Until NS v3 fun processChangedDeviceStatusesCompat() fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) - fun changedTemporaryBasals(): List - - // Until NS v3 fun processChangedTemporaryBasalsCompat() fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) - fun changedExtendedBoluses(): List - - // Until NS v3 fun processChangedExtendedBolusesCompat() fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) - fun changedProfileSwitch(): List - - // Until NS v3 fun processChangedProfileSwitchesCompat() fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) - fun changedEffectiveProfileSwitch(): List - - // Until NS v3 fun processChangedEffectiveProfileSwitchesCompat() fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) - fun changedOfflineEvents(): List - - // Until NS v3 fun processChangedOfflineEventsCompat() fun confirmLastProfileStore(lastSynced: Long) diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/sync/NsClient.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/sync/NsClient.kt index 6ef90a7c02..f45013aa16 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/sync/NsClient.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/sync/NsClient.kt @@ -2,7 +2,6 @@ package info.nightscout.interfaces.sync import android.text.Spanned import info.nightscout.interfaces.nsclient.NSAlarm -import org.json.JSONObject interface NsClient : Sync { enum class Version { @@ -23,6 +22,6 @@ interface NsClient : Sync { fun resetToFullSync() - fun dbAdd(collection: String, data: JSONObject, originalObject: Any, progress: String) - fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any, progress: String) + fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) + fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) } \ No newline at end of file diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidClientImpl.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidClientImpl.kt index 183c8e09ca..cb76bf8351 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidClientImpl.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidClientImpl.kt @@ -138,11 +138,13 @@ class NSAndroidClientImpl( } } - override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List = callWrapper(dispatcher) { + override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse> = callWrapper(dispatcher) { val response = api.getTreatmentsModifiedSince(from, limit) + val eTagString = response.headers()["ETag"] + val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw TodoNightscoutException() if (response.isSuccessful) { - return@callWrapper response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull() + return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()) } else { throw TodoNightscoutException() // TODO: react to response errors (offline, ...) } @@ -161,9 +163,28 @@ class NSAndroidClientImpl( override suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) { val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException() + 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 + ) + } else { + throw TodoNightscoutException() // TODO: react to response errors (offline, ...) + } + } + + override suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) { + + val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException() + val response = api.updateTreatment(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, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidRxClientImpl.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidRxClientImpl.kt index 93b11ca0ce..1d4cb3c02c 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidRxClientImpl.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/NSAndroidRxClientImpl.kt @@ -16,7 +16,7 @@ class NSAndroidRxClientImpl(private val client: NSAndroidClient) : NSAndroidRxCl override fun getStatus(): Single = rxSingle { client.getStatus() } override fun getLastModified(): Single = rxSingle { client.getLastModified() } override fun getSgvsModifiedSince(from: Long): Single> = rxSingle { client.getSgvsModifiedSince(from) } - override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single> = + override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single>> = rxSingle { client.getTreatmentsModifiedSince(from, limit) } override fun getDeviceStatusModifiedSince(from: Long): Single> = rxSingle { client.getDeviceStatusModifiedSince(from) } diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidClient.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidClient.kt index bfb07f1490..d29b959080 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidClient.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidClient.kt @@ -9,6 +9,11 @@ import info.nightscout.sdk.remotemodel.RemoteDeviceStatus interface NSAndroidClient { + class ReadResponse( + val lastServerModified: Long, + val values: T + ) + val lastStatus: Status? suspend fun getVersion(): String suspend fun getStatus(): Status @@ -18,7 +23,8 @@ interface NSAndroidClient { suspend fun getSgvs(): List suspend fun getSgvsModifiedSince(from: Long): List suspend fun getSgvsNewerThan(from: Long, limit: Long): List - suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List + suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse> suspend fun getDeviceStatusModifiedSince(from: Long): List - suspend fun createTreatment(NsTreatment: NSTreatment): CreateUpdateResponse + suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse + suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse } \ No newline at end of file diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidRxClient.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidRxClient.kt index 77a88358a1..01b365b6f5 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidRxClient.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/interfaces/NSAndroidRxClient.kt @@ -13,7 +13,7 @@ interface NSAndroidRxClient { fun getStatus(): Single fun getLastModified(): Single fun getSgvsModifiedSince(from: Long): Single> - fun getTreatmentsModifiedSince(from: Long, limit: Long): Single> + fun getTreatmentsModifiedSince(from: Long, limit: Long): Single>> fun getDeviceStatusModifiedSince(from: Long): Single> } diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/CreateUpdateResponse.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/CreateUpdateResponse.kt index ad7a3835a2..4799277f2b 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/CreateUpdateResponse.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/CreateUpdateResponse.kt @@ -1,6 +1,7 @@ package info.nightscout.sdk.localmodel.treatment class CreateUpdateResponse( + val response: Int, val identifier: String?, val isDeduplication: Boolean? = false, val deduplicatedIdentifier: String? = null, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolus.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolus.kt index dbc9f63408..c9f143f1ea 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolus.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolus.kt @@ -4,14 +4,14 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSBolus( override val date: Long, - override val device: String?, - override val identifier: String, - override val units: NsUnits?, - override val srvModified: Long?, - override val srvCreated: 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 val subject: String?, - override var isReadOnly: Boolean, + override val subject: String? = null, + override var isReadOnly: Boolean = false, override val isValid: Boolean, override val eventType: EventType, override val notes: String?, @@ -19,6 +19,7 @@ data class NSBolus( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val insulin: Double, val type: BolusType diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolusWizard.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolusWizard.kt index d192577c70..5418175fe1 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolusWizard.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSBolusWizard.kt @@ -1,12 +1,11 @@ package info.nightscout.sdk.localmodel.treatment import info.nightscout.sdk.localmodel.entry.NsUnits -import org.json.JSONObject data class NSBolusWizard( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -20,6 +19,7 @@ data class NSBolusWizard( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val bolusCalculatorResult: String?, val glucose: Double?, ) : NSTreatment \ No newline at end of file diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSCarbs.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSCarbs.kt index b3069a4a1d..27c976ab4e 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSCarbs.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSCarbs.kt @@ -5,7 +5,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSCarbs( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -19,6 +19,7 @@ data class NSCarbs( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val carbs: Double, val duration: Long ) : NSTreatment \ No newline at end of file diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSEffectiveProfileSwitch.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSEffectiveProfileSwitch.kt index 731048b678..65662e5058 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSEffectiveProfileSwitch.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSEffectiveProfileSwitch.kt @@ -6,7 +6,7 @@ import org.json.JSONObject data class NSEffectiveProfileSwitch( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -20,6 +20,7 @@ data class NSEffectiveProfileSwitch( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val profileJson: JSONObject, val originalProfileName: String, val originalCustomizedName: String, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSExtendedBolus.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSExtendedBolus.kt index cb179b70d2..eb140215fb 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSExtendedBolus.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSExtendedBolus.kt @@ -5,7 +5,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSExtendedBolus( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -19,6 +19,7 @@ data class NSExtendedBolus( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val duration: Long, val enteredinsulin: Double, val isEmulatingTempBasal: Boolean? diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSOfflineEvent.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSOfflineEvent.kt index 1d64e0c6cd..64b7607b17 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSOfflineEvent.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSOfflineEvent.kt @@ -5,7 +5,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSOfflineEvent( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -19,6 +19,7 @@ data class NSOfflineEvent( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val duration: Long, val reason: Reason ) : NSTreatment { diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSProfileSwitch.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSProfileSwitch.kt index d36056eebd..afd55d90b3 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSProfileSwitch.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSProfileSwitch.kt @@ -6,7 +6,7 @@ import org.json.JSONObject data class NSProfileSwitch( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -20,6 +20,7 @@ data class NSProfileSwitch( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val profileJson: JSONObject?, val profileName: String, val originalProfileName: String?, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryBasal.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryBasal.kt index b3dabf908a..88d588aca2 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryBasal.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryBasal.kt @@ -1,12 +1,11 @@ package info.nightscout.sdk.localmodel.treatment import info.nightscout.sdk.localmodel.entry.NsUnits -import org.json.JSONObject data class NSTemporaryBasal( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -20,6 +19,7 @@ data class NSTemporaryBasal( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val duration: Long, val rate: Double, // when sending to NS always convertedToAbsolute(timestamp, profile) val isAbsolute: Boolean, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryTarget.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryTarget.kt index 77276096db..4e151dab37 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryTarget.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTemporaryTarget.kt @@ -5,7 +5,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSTemporaryTarget( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -19,6 +19,7 @@ data class NSTemporaryTarget( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val duration: Long, val targetBottom: Double, val targetTop: Double, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTherapyEvent.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTherapyEvent.kt index 1fe671107c..03d47013ad 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTherapyEvent.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTherapyEvent.kt @@ -6,7 +6,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits data class NSTherapyEvent( override val date: Long, override val device: String?, - override val identifier: String, + override val identifier: String?, override val units: NsUnits?, override val srvModified: Long?, override val srvCreated: Long?, @@ -20,6 +20,7 @@ data class NSTherapyEvent( override val endId: Long?, override val pumpType: String?, override val pumpSerial: String?, + override var app: String? = null, val duration: Long, var enteredBy: String? = null, var glucose: Double? = null, diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTreatment.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTreatment.kt index 04a10c17eb..17b4037b5e 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTreatment.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/localmodel/treatment/NSTreatment.kt @@ -5,7 +5,7 @@ import info.nightscout.sdk.localmodel.entry.NsUnits interface NSTreatment { val date: Long val device: String? - val identifier: String + val identifier: String? val units: NsUnits? val eventType: EventType val srvModified: Long? @@ -19,6 +19,7 @@ interface NSTreatment { val endId: Long? val pumpType: String? val pumpSerial: String? + var app: String? fun Double.asMgdl() = when (units) { diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/networking/NightscoutRemoteService.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/networking/NightscoutRemoteService.kt index 3ae740d2db..fc52b14891 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/networking/NightscoutRemoteService.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/networking/NightscoutRemoteService.kt @@ -2,19 +2,17 @@ package info.nightscout.sdk.networking import com.google.gson.JsonElement import info.nightscout.sdk.remotemodel.LastModified -import info.nightscout.sdk.remotemodel.RemoteDeviceStatus import info.nightscout.sdk.remotemodel.NSResponse import info.nightscout.sdk.remotemodel.RemoteCreateUpdateResponse +import info.nightscout.sdk.remotemodel.RemoteDeviceStatus import info.nightscout.sdk.remotemodel.RemoteEntry import info.nightscout.sdk.remotemodel.RemoteStatusResponse import info.nightscout.sdk.remotemodel.RemoteTreatment -import okhttp3.RequestBody -import retrofit2.Call import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET -import retrofit2.http.Header import retrofit2.http.POST +import retrofit2.http.PUT import retrofit2.http.Path import retrofit2.http.Query @@ -56,6 +54,9 @@ internal interface NightscoutRemoteService { suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response>> @POST("v3/treatments") - fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response> + suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response> + + @PUT("v3/treatments") + suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment): Response> } diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/RemoteTreatment.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/RemoteTreatment.kt index d73f0098fc..df11416054 100644 --- a/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/RemoteTreatment.kt +++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/RemoteTreatment.kt @@ -1,11 +1,9 @@ package info.nightscout.sdk.remotemodel -import com.google.gson.Gson import com.google.gson.annotations.SerializedName import info.nightscout.sdk.localmodel.treatment.EventType import org.joda.time.DateTime import org.joda.time.format.ISODateTimeFormat -import org.json.JSONObject /* * Depending on the type, different other fields are present. @@ -17,13 +15,13 @@ import org.json.JSONObject * * */ 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? = 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("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") 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. @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. diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusCalculatorResultTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusCalculatorResultTransaction.kt index 99c9329a9c..d0796b6c70 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusCalculatorResultTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusCalculatorResultTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.BolusCalculatorResult -class UpdateNsIdBolusCalculatorResultTransaction(val bolusCalculatorResult: BolusCalculatorResult) : Transaction() { +class UpdateNsIdBolusCalculatorResultTransaction(private val bolusCalculatorResults: List) : Transaction() { - override fun run() { - val current = database.bolusCalculatorResultDao.findById(bolusCalculatorResult.id) - if (current != null && current.interfaceIDs.nightscoutId != bolusCalculatorResult.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = bolusCalculatorResult.interfaceIDs.nightscoutId - database.bolusCalculatorResultDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (bolusCalculatorResult in bolusCalculatorResults) { + val current = database.bolusCalculatorResultDao.findById(bolusCalculatorResult.id) + if (current != null && current.interfaceIDs.nightscoutId != bolusCalculatorResult.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = bolusCalculatorResult.interfaceIDs.nightscoutId + database.bolusCalculatorResultDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusTransaction.kt index 1075094e0b..b75b15f303 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdBolusTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.Bolus -class UpdateNsIdBolusTransaction(val bolus: Bolus) : Transaction() { +class UpdateNsIdBolusTransaction(private val boluses: List) : Transaction() { - override fun run() { - val current = database.bolusDao.findById(bolus.id) - if (current != null && current.interfaceIDs.nightscoutId != bolus.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = bolus.interfaceIDs.nightscoutId - database.bolusDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (bolus in boluses) { + val current = database.bolusDao.findById(bolus.id) + if (current != null && current.interfaceIDs.nightscoutId != bolus.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = bolus.interfaceIDs.nightscoutId + database.bolusDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdCarbsTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdCarbsTransaction.kt index 2c6ae614e3..15b376ef47 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdCarbsTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdCarbsTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.Carbs -class UpdateNsIdCarbsTransaction(val carbs: Carbs) : Transaction() { +class UpdateNsIdCarbsTransaction(private val carbs: List) : Transaction() { - override fun run() { - val current = database.carbsDao.findById(carbs.id) - if (current != null && current.interfaceIDs.nightscoutId != carbs.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = carbs.interfaceIDs.nightscoutId - database.carbsDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (carb in carbs) { + val current = database.carbsDao.findById(carb.id) + if (current != null && current.interfaceIDs.nightscoutId != carb.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = carb.interfaceIDs.nightscoutId + database.carbsDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdDeviceStatusTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdDeviceStatusTransaction.kt index fc582722a3..5b63815049 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdDeviceStatusTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdDeviceStatusTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.DeviceStatus -class UpdateNsIdDeviceStatusTransaction(val deviceStatus: DeviceStatus) : Transaction() { +class UpdateNsIdDeviceStatusTransaction(private val deviceStatuses: List) : Transaction() { - override fun run() { - val current = database.deviceStatusDao.findById(deviceStatus.id) - if (current != null && current.interfaceIDs.nightscoutId != deviceStatus.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = deviceStatus.interfaceIDs.nightscoutId - database.deviceStatusDao.update(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (deviceStatus in deviceStatuses) { + val current = database.deviceStatusDao.findById(deviceStatus.id) + if (current != null && current.interfaceIDs.nightscoutId != deviceStatus.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = deviceStatus.interfaceIDs.nightscoutId + database.deviceStatusDao.update(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdEffectiveProfileSwitchTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdEffectiveProfileSwitchTransaction.kt index d76205f75b..89cb509d40 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdEffectiveProfileSwitchTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdEffectiveProfileSwitchTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.EffectiveProfileSwitch -class UpdateNsIdEffectiveProfileSwitchTransaction(val effectiveProfileSwitch: EffectiveProfileSwitch) : Transaction() { +class UpdateNsIdEffectiveProfileSwitchTransaction(private val effectiveProfileSwitches: List) : Transaction() { - override fun run() { - val current = database.effectiveProfileSwitchDao.findById(effectiveProfileSwitch.id) - if (current != null && current.interfaceIDs.nightscoutId != effectiveProfileSwitch.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = effectiveProfileSwitch.interfaceIDs.nightscoutId - database.effectiveProfileSwitchDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (effectiveProfileSwitch in effectiveProfileSwitches) { + val current = database.effectiveProfileSwitchDao.findById(effectiveProfileSwitch.id) + if (current != null && current.interfaceIDs.nightscoutId != effectiveProfileSwitch.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = effectiveProfileSwitch.interfaceIDs.nightscoutId + database.effectiveProfileSwitchDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdExtendedBolusTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdExtendedBolusTransaction.kt index 6d070a6516..43beaebd3d 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdExtendedBolusTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdExtendedBolusTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.ExtendedBolus -class UpdateNsIdExtendedBolusTransaction(val bolus: ExtendedBolus) : Transaction() { +class UpdateNsIdExtendedBolusTransaction(val boluses: List) : Transaction() { - override fun run() { - val current = database.extendedBolusDao.findById(bolus.id) - if (current != null && current.interfaceIDs.nightscoutId != bolus.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = bolus.interfaceIDs.nightscoutId - database.extendedBolusDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (bolus in boluses) { + val current = database.extendedBolusDao.findById(bolus.id) + if (current != null && current.interfaceIDs.nightscoutId != bolus.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = bolus.interfaceIDs.nightscoutId + database.extendedBolusDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdFoodTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdFoodTransaction.kt index f35b5a3efe..228d8665ff 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdFoodTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdFoodTransaction.kt @@ -2,13 +2,24 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.Food -class UpdateNsIdFoodTransaction(val food: Food) : Transaction() { +class UpdateNsIdFoodTransaction(private val foods: List) : Transaction() { - override fun run() { - val current = database.foodDao.findById(food.id) - if (current != null && current.interfaceIDs.nightscoutId != food.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = food.interfaceIDs.nightscoutId - database.foodDao.updateExistingEntry(current) + val result = TransactionResult() + + override fun run(): TransactionResult { + for (food in foods) { + val current = database.foodDao.findById(food.id) + if (current != null && current.interfaceIDs.nightscoutId != food.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = food.interfaceIDs.nightscoutId + database.foodDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdGlucoseValueTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdGlucoseValueTransaction.kt index eb047a377b..073b7f2fcf 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdGlucoseValueTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdGlucoseValueTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.GlucoseValue -class UpdateNsIdGlucoseValueTransaction(val glucoseValue: GlucoseValue) : Transaction() { +class UpdateNsIdGlucoseValueTransaction(private val glucoseValues: List) : Transaction() { - override fun run() { - val current = database.glucoseValueDao.findById(glucoseValue.id) - if (current != null && current.interfaceIDs.nightscoutId != glucoseValue.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = glucoseValue.interfaceIDs.nightscoutId - database.glucoseValueDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (glucoseValue in glucoseValues) { + val current = database.glucoseValueDao.findById(glucoseValue.id) + if (current != null && current.interfaceIDs.nightscoutId != glucoseValue.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = glucoseValue.interfaceIDs.nightscoutId + database.glucoseValueDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdOfflineEventTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdOfflineEventTransaction.kt index 48f8676d44..b568b5b3f9 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdOfflineEventTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdOfflineEventTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.OfflineEvent -class UpdateNsIdOfflineEventTransaction(val offlineEvent: OfflineEvent) : Transaction() { +class UpdateNsIdOfflineEventTransaction(private val offlineEvents: List) : Transaction() { - override fun run() { - val current = database.offlineEventDao.findById(offlineEvent.id) - if (current != null && current.interfaceIDs.nightscoutId != offlineEvent.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = offlineEvent.interfaceIDs.nightscoutId - database.offlineEventDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (offlineEvent in offlineEvents) { + val current = database.offlineEventDao.findById(offlineEvent.id) + if (current != null && current.interfaceIDs.nightscoutId != offlineEvent.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = offlineEvent.interfaceIDs.nightscoutId + database.offlineEventDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdProfileSwitchTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdProfileSwitchTransaction.kt index b8886ed610..d15421d316 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdProfileSwitchTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdProfileSwitchTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.ProfileSwitch -class UpdateNsIdProfileSwitchTransaction(val profileSwitch: ProfileSwitch) : Transaction() { +class UpdateNsIdProfileSwitchTransaction(val profileSwitches: List) : Transaction() { - override fun run() { - val current = database.profileSwitchDao.findById(profileSwitch.id) - if (current != null && current.interfaceIDs.nightscoutId != profileSwitch.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = profileSwitch.interfaceIDs.nightscoutId - database.profileSwitchDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (profileSwitch in profileSwitches) { + val current = database.profileSwitchDao.findById(profileSwitch.id) + if (current != null && current.interfaceIDs.nightscoutId != profileSwitch.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = profileSwitch.interfaceIDs.nightscoutId + database.profileSwitchDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryBasalTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryBasalTransaction.kt index 1daa83442f..667daae619 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryBasalTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryBasalTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.TemporaryBasal -class UpdateNsIdTemporaryBasalTransaction(val temporaryBasal: TemporaryBasal) : Transaction() { +class UpdateNsIdTemporaryBasalTransaction(private val temporaryBasals: List) : Transaction() { - override fun run() { - val current = database.temporaryBasalDao.findById(temporaryBasal.id) - if (current != null && current.interfaceIDs.nightscoutId != temporaryBasal.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = temporaryBasal.interfaceIDs.nightscoutId - database.temporaryBasalDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (temporaryBasal in temporaryBasals) { + val current = database.temporaryBasalDao.findById(temporaryBasal.id) + if (current != null && current.interfaceIDs.nightscoutId != temporaryBasal.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = temporaryBasal.interfaceIDs.nightscoutId + database.temporaryBasalDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryTargetTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryTargetTransaction.kt index 0b4a369708..f629302486 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryTargetTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTemporaryTargetTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.TemporaryTarget -class UpdateNsIdTemporaryTargetTransaction(val temporaryTarget: TemporaryTarget) : Transaction() { +class UpdateNsIdTemporaryTargetTransaction(private val temporaryTargets: List) : Transaction() { - override fun run() { - val current = database.temporaryTargetDao.findById(temporaryTarget.id) - if (current != null && current.interfaceIDs.nightscoutId != temporaryTarget.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = temporaryTarget.interfaceIDs.nightscoutId - database.temporaryTargetDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (temporaryTarget in temporaryTargets) { + val current = database.temporaryTargetDao.findById(temporaryTarget.id) + if (current != null && current.interfaceIDs.nightscoutId != temporaryTarget.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = temporaryTarget.interfaceIDs.nightscoutId + database.temporaryTargetDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTherapyEventTransaction.kt b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTherapyEventTransaction.kt index e310f1c1d3..d82086e9b1 100644 --- a/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTherapyEventTransaction.kt +++ b/database/impl/src/main/java/info/nightscout/database/impl/transactions/UpdateNsIdTherapyEventTransaction.kt @@ -2,13 +2,23 @@ package info.nightscout.database.impl.transactions import info.nightscout.database.entities.TherapyEvent -class UpdateNsIdTherapyEventTransaction(val therapyEvent: TherapyEvent) : Transaction() { +class UpdateNsIdTherapyEventTransaction(val therapyEvents: List) : Transaction() { - override fun run() { - val current = database.therapyEventDao.findById(therapyEvent.id) - if (current != null && current.interfaceIDs.nightscoutId != therapyEvent.interfaceIDs.nightscoutId) { - current.interfaceIDs.nightscoutId = therapyEvent.interfaceIDs.nightscoutId - database.therapyEventDao.updateExistingEntry(current) + val result = TransactionResult() + override fun run(): TransactionResult { + for (therapyEvent in therapyEvents) { + val current = database.therapyEventDao.findById(therapyEvent.id) + if (current != null && current.interfaceIDs.nightscoutId != therapyEvent.interfaceIDs.nightscoutId) { + current.interfaceIDs.nightscoutId = therapyEvent.interfaceIDs.nightscoutId + database.therapyEventDao.updateExistingEntry(current) + result.updatedNsId.add(current) + } } + return result + } + + class TransactionResult { + + val updatedNsId = mutableListOf() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt index f1d0bac4e8..6ecb8a379a 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt @@ -7,9 +7,9 @@ import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.sync.DataSyncSelector +import info.nightscout.plugins.sync.nsShared.DataSyncSelectorImplementation import info.nightscout.plugins.sync.nsShared.NSClientFragment import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl -import info.nightscout.plugins.sync.nsclient.DataSyncSelectorImplementation import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl import info.nightscout.plugins.sync.nsclient.services.NSClientService @@ -17,6 +17,7 @@ import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker +import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker import info.nightscout.plugins.sync.nsclientV3.workers.LoadDeviceStatusWorker import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker @@ -49,6 +50,7 @@ abstract class SyncModule { @ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker @ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker @ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker + @ContributesAndroidInjector abstract fun contributesDataSyncWorker(): DataSyncWorker @ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/DataSyncSelectorImplementation.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt similarity index 72% rename from plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/DataSyncSelectorImplementation.kt rename to plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt index 7536a783d9..b38d6eea6b 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/DataSyncSelectorImplementation.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt @@ -1,26 +1,11 @@ -package info.nightscout.plugins.sync.nsclient +package info.nightscout.plugins.sync.nsShared -import info.nightscout.core.extensions.toJson import info.nightscout.database.ValueWrapper -import info.nightscout.database.entities.Bolus -import info.nightscout.database.entities.BolusCalculatorResult -import info.nightscout.database.entities.Carbs -import info.nightscout.database.entities.DeviceStatus -import info.nightscout.database.entities.EffectiveProfileSwitch -import info.nightscout.database.entities.ExtendedBolus -import info.nightscout.database.entities.Food -import info.nightscout.database.entities.GlucoseValue -import info.nightscout.database.entities.OfflineEvent -import info.nightscout.database.entities.ProfileSwitch -import info.nightscout.database.entities.TemporaryBasal -import info.nightscout.database.entities.TemporaryTarget -import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.plugins.sync.R -import info.nightscout.plugins.sync.nsclient.extensions.toJson import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag import info.nightscout.shared.sharedPreferences.SP @@ -71,11 +56,12 @@ class DataSyncSelectorImplementation @Inject constructor( } private val queueCounter = QueueCounter() + private val isPaused get() = sp.getBoolean(R.string.key_ns_client_paused, false) override fun queueSize(): Long = queueCounter.size() override fun doUpload() { - if (sp.getBoolean(R.string.key_ns_upload, true)) { + if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) { processChangedBolusesCompat() processChangedCarbsCompat() processChangedBolusCalculatorResultsCompat() @@ -120,18 +106,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedBoluses(): List { - val startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0) - return appRepository.getModifiedBolusesDataFromId(startId) - .blockingGet() - .filter { it.type != Bolus.Type.PRIMING } - .also { - aapsLogger.debug(LTag.NSCLIENT, "Loading Bolus data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedBolusesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0) @@ -141,18 +117,18 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.bolusesRemaining = lastDbId - startId appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus -> - aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ID: ${bolus.first.id} HistoryID: ${bolus.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore bolus.first.id == bolus.second.id && bolus.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Loaded from NS: ${bolus.first.id} HistoryID: ${bolus.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Loaded from NS: ${bolus.second.id} ") confirmLastBolusIdIfGreater(bolus.second.id) processChangedBolusesCompat() return } // only NsId changed, no need to upload bolus.first.onlyNsIdAdded(bolus.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed ID: ${bolus.first.id} HistoryID: ${bolus.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed: ${bolus.second.id} ") confirmLastBolusIdIfGreater(bolus.second.id) processChangedBolusesCompat() return @@ -161,7 +137,6 @@ class DataSyncSelectorImplementation @Inject constructor( bolus.first.interfaceIDs.nightscoutId == null -> activePlugin.activeNsClient?.dbAdd( "treatments", - bolus.first.toJson(true, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId" ) @@ -169,8 +144,6 @@ class DataSyncSelectorImplementation @Inject constructor( bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id -> activePlugin.activeNsClient?.dbUpdate( "treatments", - bolus.first.interfaceIDs.nightscoutId, - bolus.first.toJson(false, dateUtil), DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId" ) @@ -186,15 +159,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedCarbs(): List { - val startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0) - return appRepository.getModifiedCarbsDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading Carbs data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedCarbsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0) @@ -204,31 +170,29 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.carbsRemaining = lastDbId - startId appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb -> - aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ID: ${carb.first.id} HistoryID: ${carb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore carb.first.id == carb.second.id && carb.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Loaded from NS: ${carb.first.id} HistoryID: ${carb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Loaded from NS: ${carb.second.id} ") confirmLastCarbsIdIfGreater(carb.second.id) processChangedCarbsCompat() return } // only NsId changed, no need to upload carb.first.onlyNsIdAdded(carb.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.first.id} HistoryID: ${carb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.second.id} ") confirmLastCarbsIdIfGreater(carb.second.id) processChangedCarbsCompat() return } // without nsId = create new carb.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("treatments", carb.first.toJson(true, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") // with nsId = update if it's modified record carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id -> activePlugin.activeNsClient?.dbUpdate( "treatments", - carb.first.interfaceIDs.nightscoutId, - carb.first.toJson(false, dateUtil), DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId" ) @@ -244,15 +208,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedBolusCalculatorResults(): List { - val startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0) - return appRepository.getModifiedBolusCalculatorResultsDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading BolusCalculatorResult data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedBolusCalculatorResultsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0) @@ -262,18 +219,18 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.bcrRemaining = lastDbId - startId appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult -> - aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ID: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore bolusCalculatorResult.first.id == bolusCalculatorResult.second.id && bolusCalculatorResult.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Loaded from NS: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Loaded from NS: ${bolusCalculatorResult.second.id} ") confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id) processChangedBolusCalculatorResultsCompat() return } // only NsId changed, no need to upload bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.first.id} HistoryID: ${bolusCalculatorResult.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.second.id} ") confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id) processChangedBolusCalculatorResultsCompat() return @@ -282,14 +239,13 @@ class DataSyncSelectorImplementation @Inject constructor( bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> activePlugin.activeNsClient?.dbAdd( "treatments", - bolusCalculatorResult.first.toJson(true, dateUtil, profileFunction), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" ) // with nsId = update if it's modified record bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id -> activePlugin.activeNsClient?.dbUpdate( - "treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil, profileFunction), + "treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" ) } @@ -304,15 +260,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedTempTargets(): List { - val startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0) - return appRepository.getModifiedTemporaryTargetsDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading TemporaryTarget data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedTempTargetsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0) @@ -322,18 +271,18 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.ttsRemaining = lastDbId - startId appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt -> - aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ID: ${tt.first.id} HistoryID: ${tt.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore tt.first.id == tt.second.id && tt.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Loaded from NS: ${tt.first.id} HistoryID: ${tt.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Loaded from NS: ${tt.second.id} ") confirmLastTempTargetsIdIfGreater(tt.second.id) processChangedTempTargetsCompat() return } // only NsId changed, no need to upload tt.first.onlyNsIdAdded(tt.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.first.id} HistoryID: ${tt.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.second.id} ") confirmLastTempTargetsIdIfGreater(tt.second.id) processChangedTempTargetsCompat() return @@ -342,7 +291,6 @@ class DataSyncSelectorImplementation @Inject constructor( tt.first.interfaceIDs.nightscoutId == null -> activePlugin.activeNsClient?.dbAdd( "treatments", - tt.first.toJson(true, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId" ) @@ -350,8 +298,6 @@ class DataSyncSelectorImplementation @Inject constructor( tt.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - tt.first.interfaceIDs.nightscoutId, - tt.first.toJson(false, profileFunction.getUnits(), dateUtil), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId" ) @@ -367,15 +313,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedFoods(): List { - val startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0) - return appRepository.getModifiedFoodDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading Food data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedFoodsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0) @@ -385,31 +324,29 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.foodsRemaining = lastDbId - startId appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food -> - aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ID: ${food.first.id} HistoryID: ${food.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore food.first.id == food.second.id && food.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Loaded from NS: ${food.first.id} HistoryID: ${food.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Loaded from NS: ${food.second.id} ") confirmLastFoodIdIfGreater(food.second.id) processChangedFoodsCompat() return } // only NsId changed, no need to upload food.first.onlyNsIdAdded(food.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.first.id} HistoryID: ${food.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.second.id} ") confirmLastFoodIdIfGreater(food.second.id) processChangedFoodsCompat() return } // without nsId = create new food.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("food", food.first.toJson(true), DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") // with nsId = update food.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "food", - food.first.interfaceIDs.nightscoutId, - food.first.toJson(false), DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId" ) @@ -425,15 +362,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedGlucoseValues(): List { - val startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0) - return appRepository.getModifiedBgReadingsDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading GlucoseValue data for sync from $startId . Records ${it.size}") - } - } - override tailrec fun processChangedGlucoseValuesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0) @@ -443,32 +373,30 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.gvsRemaining = lastDbId - startId appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv -> - aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data ID: ${gv.first.id} HistoryID: ${gv.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ") if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) { when { - // new record with existing NS id => must be coming from NS => ignore + // new record with existing NS id => must be coming from NS => ignore gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.first.id} HistoryID: ${gv.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ") confirmLastGlucoseValueIdIfGreater(gv.second.id) processChangedGlucoseValuesCompat() return } // only NsId changed, no need to upload gv.first.onlyNsIdAdded(gv.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.first.id} HistoryID: ${gv.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.second.id} ") confirmLastGlucoseValueIdIfGreater(gv.second.id) processChangedGlucoseValuesCompat() return } // without nsId = create new gv.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("entries", gv.first.toJson(true, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") // with nsId = update else -> // gv.first.interfaceIDs.nightscoutId != null activePlugin.activeNsClient?.dbUpdate( "entries", - gv.first.interfaceIDs.nightscoutId, - gv.first.toJson(false, dateUtil), DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId" ) @@ -488,15 +416,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedTherapyEvents(): List { - val startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0) - return appRepository.getModifiedTherapyEventDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading TherapyEvents data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedTherapyEventsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0) @@ -506,31 +427,29 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.tesRemaining = lastDbId - startId appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te -> - aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ID: ${te.first.id} HistoryID: ${te.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore te.first.id == te.second.id && te.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Loaded from NS: ${te.first.id} HistoryID: ${te.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Loaded from NS: ${te.second.id} ") confirmLastTherapyEventIdIfGreater(te.second.id) processChangedTherapyEventsCompat() return } // only NsId changed, no need to upload te.first.onlyNsIdAdded(te.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.first.id} HistoryID: ${te.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.second.id} ") confirmLastTherapyEventIdIfGreater(te.second.id) processChangedTherapyEventsCompat() return } // without nsId = create new te.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("treatments", te.first.toJson(true, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") // nsId = update te.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - te.first.interfaceIDs.nightscoutId, - te.first.toJson(false, dateUtil), DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId" ) @@ -546,14 +465,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - override fun changedDeviceStatuses(): List { - val startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0) - return appRepository.getModifiedDeviceStatusDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading DeviceStatus data for sync from $startId. Records ${it.size}") - } - } - override fun processChangedDeviceStatusesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0) @@ -563,11 +476,11 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.dssRemaining = lastDbId - startId appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus -> - aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId ID: ${deviceStatus.id}") + aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus") when { // without nsId = create new deviceStatus.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("devicestatus", deviceStatus.toJson(dateUtil), deviceStatus, "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, 0), "$startId/$lastDbId") // with nsId = ignore deviceStatus.interfaceIDs.nightscoutId != null -> Any() } @@ -582,15 +495,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedTemporaryBasals(): List { - val startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0) - return appRepository.getModifiedTemporaryBasalDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading TemporaryBasal data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedTemporaryBasalsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0) @@ -600,49 +506,38 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.tbrsRemaining = lastDbId - startId appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb -> - aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ID: ${tb.first.id} HistoryID: ${tb.second} ") - val profile = profileFunction.getProfile(tb.first.timestamp) - if (profile != null) { - when { - // new record with existing NS id => must be coming from NS => ignore - tb.first.id == tb.second.id && tb.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Loaded from NS: ${tb.first.id} HistoryID: ${tb.second.id} ") - confirmLastTemporaryBasalIdIfGreater(tb.second.id) - processChangedTemporaryBasalsCompat() - return - } - // only NsId changed, no need to upload - tb.first.onlyNsIdAdded(tb.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.first.id} HistoryID: ${tb.second.id} ") - confirmLastTemporaryBasalIdIfGreater(tb.second.id) - processChangedTemporaryBasalsCompat() - return - } - // without nsId = create new - tb.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd( - "treatments", - tb.first.toJson(true, profile, dateUtil), - DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), - "$startId/$lastDbId" - ) - // with nsId = update - tb.first.interfaceIDs.nightscoutId != null -> - activePlugin.activeNsClient?.dbUpdate( - "treatments", - tb.first.interfaceIDs.nightscoutId, - tb.first.toJson(false, profile, dateUtil), - DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), - "$startId/$lastDbId" - ) + aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ") + when { + // new record with existing NS id => must be coming from NS => ignore + tb.first.id == tb.second.id && tb.first.interfaceIDs.nightscoutId != null -> { + aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Loaded from NS: ${tb.second.id} ") + confirmLastTemporaryBasalIdIfGreater(tb.second.id) + processChangedTemporaryBasalsCompat() + return } - return - } else { - aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. No profile: ${tb.first.id} HistoryID: ${tb.second.id} ") - confirmLastTemporaryBasalIdIfGreater(tb.second.id) - processChangedTemporaryBasalsCompat() - return + // only NsId changed, no need to upload + tb.first.onlyNsIdAdded(tb.second) -> { + aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.second.id} ") + confirmLastTemporaryBasalIdIfGreater(tb.second.id) + processChangedTemporaryBasalsCompat() + return + } + // without nsId = create new + tb.first.interfaceIDs.nightscoutId == null -> + activePlugin.activeNsClient?.dbAdd( + "treatments", + DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), + "$startId/$lastDbId" + ) + // with nsId = update + tb.first.interfaceIDs.nightscoutId != null -> + activePlugin.activeNsClient?.dbUpdate( + "treatments", + DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), + "$startId/$lastDbId" + ) } + return } } @@ -653,15 +548,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedExtendedBoluses(): List { - val startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0) - return appRepository.getModifiedExtendedBolusDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading ExtendedBolus data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedExtendedBolusesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0) @@ -671,20 +559,20 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.ebsRemaining = lastDbId - startId appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb -> - aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ID: ${eb.first.id} HistoryID: ${eb.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ") val profile = profileFunction.getProfile(eb.first.timestamp) if (profile != null) { when { // new record with existing NS id => must be coming from NS => ignore eb.first.id == eb.second.id && eb.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Loaded from NS: ${eb.first.id} HistoryID: ${eb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Loaded from NS: ${eb.second.id} ") confirmLastExtendedBolusIdIfGreater(eb.second.id) processChangedExtendedBolusesCompat() return } // only NsId changed, no need to upload eb.first.onlyNsIdAdded(eb.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.first.id} HistoryID: ${eb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.second.id} ") confirmLastExtendedBolusIdIfGreater(eb.second.id) processChangedExtendedBolusesCompat() return @@ -693,7 +581,6 @@ class DataSyncSelectorImplementation @Inject constructor( eb.first.interfaceIDs.nightscoutId == null -> activePlugin.activeNsClient?.dbAdd( "treatments", - eb.first.toJson(true, profile, dateUtil), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId" ) @@ -701,15 +588,13 @@ class DataSyncSelectorImplementation @Inject constructor( eb.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - eb.first.interfaceIDs.nightscoutId, - eb.first.toJson(false, profile, dateUtil), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId" ) } return } else { - aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.first.id} HistoryID: ${eb.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.second.id} ") confirmLastExtendedBolusIdIfGreater(eb.second.id) processChangedExtendedBolusesCompat() return @@ -724,14 +609,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - override fun changedProfileSwitch(): List { - val startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0) - return appRepository.getModifiedProfileSwitchDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading ProfileSwitch data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedProfileSwitchesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0) @@ -741,31 +620,29 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.pssRemaining = lastDbId - startId appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps -> - aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ID: ${ps.first.id} HistoryID: ${ps.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Loaded from NS: ${ps.first.id} HistoryID: ${ps.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Loaded from NS: ${ps.second.id} ") confirmLastProfileSwitchIdIfGreater(ps.second.id) processChangedProfileSwitchesCompat() return } // only NsId changed, no need to upload ps.first.onlyNsIdAdded(ps.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.first.id} HistoryID: ${ps.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.second.id} ") confirmLastProfileSwitchIdIfGreater(ps.second.id) processChangedProfileSwitchesCompat() return } // without nsId = create new ps.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") // with nsId = update ps.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - ps.first.interfaceIDs.nightscoutId, - ps.first.toJson(false, dateUtil), DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId" ) @@ -781,14 +658,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - override fun changedEffectiveProfileSwitch(): List { - val startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0) - return appRepository.getModifiedEffectiveProfileSwitchDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedEffectiveProfileSwitchesCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0) @@ -798,18 +669,18 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.epssRemaining = lastDbId - startId appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps -> - aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ID: ${ps.first.id} HistoryID: ${ps.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Loaded from NS: ${ps.first.id} HistoryID: ${ps.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Loaded from NS: ${ps.second.id} ") confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id) processChangedEffectiveProfileSwitchesCompat() return } // only NsId changed, no need to upload ps.first.onlyNsIdAdded(ps.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.first.id} HistoryID: ${ps.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.second.id} ") confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id) processChangedEffectiveProfileSwitchesCompat() return @@ -818,7 +689,6 @@ class DataSyncSelectorImplementation @Inject constructor( ps.first.interfaceIDs.nightscoutId == null -> activePlugin.activeNsClient?.dbAdd( "treatments", - ps.first.toJson(true, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId" ) @@ -826,8 +696,6 @@ class DataSyncSelectorImplementation @Inject constructor( ps.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - ps.first.interfaceIDs.nightscoutId, - ps.first.toJson(false, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId" ) @@ -843,15 +711,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - // Prepared for v3 (returns all modified after) - override fun changedOfflineEvents(): List { - val startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0) - return appRepository.getModifiedOfflineEventsDataFromId(startId).blockingGet().also { - aapsLogger.debug(LTag.NSCLIENT, "Loading OfflineEvent data for sync from $startId. Records ${it.size}") - } - } - override tailrec fun processChangedOfflineEventsCompat() { + if (isPaused) return val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0) @@ -861,31 +722,29 @@ class DataSyncSelectorImplementation @Inject constructor( } queueCounter.oesRemaining = lastDbId - startId appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe -> - aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ID: ${oe.first.id} HistoryID: ${oe.second} ") + aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ") when { // new record with existing NS id => must be coming from NS => ignore oe.first.id == oe.second.id && oe.first.interfaceIDs.nightscoutId != null -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Loaded from NS: ${oe.first.id} HistoryID: ${oe.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Loaded from NS: ${oe.second.id} ") confirmLastOfflineEventIdIfGreater(oe.second.id) processChangedOfflineEventsCompat() return } // only NsId changed, no need to upload oe.first.onlyNsIdAdded(oe.second) -> { - aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.first.id} HistoryID: ${oe.second.id} ") + aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.second.id} ") confirmLastOfflineEventIdIfGreater(oe.second.id) processChangedOfflineEventsCompat() return } // without nsId = create new oe.first.interfaceIDs.nightscoutId == null -> - activePlugin.activeNsClient?.dbAdd("treatments", oe.first.toJson(true, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") + activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") // existing with nsId = update oe.first.interfaceIDs.nightscoutId != null -> activePlugin.activeNsClient?.dbUpdate( "treatments", - oe.first.interfaceIDs.nightscoutId, - oe.first.toJson(false, dateUtil), DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId" ) @@ -899,13 +758,14 @@ class DataSyncSelectorImplementation @Inject constructor( } override fun processChangedProfileStore() { + if (isPaused) return val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0) val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0) if (lastChange == 0L) return if (lastChange > lastSync) { if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return val profileJson = activePlugin.activeProfileSource.profile?.data ?: return - activePlugin.activeNsClient?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "") + activePlugin.activeNsClient?.dbAdd("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "") } } -} +} \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt index 02fe44799b..aadc32a8b0 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt @@ -26,7 +26,6 @@ import info.nightscout.interfaces.sync.NsClient import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.databinding.NsClientFragmentBinding import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI -import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientRestart @@ -56,7 +55,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment { const val ID_MENU_RESTART = 508 const val ID_MENU_SEND_NOW = 509 const val ID_MENU_FULL_SYNC = 510 - const val ID_MENU_TEST = 601 } override var plugin: PluginBase? = null @@ -97,8 +95,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment { } override fun onCreateMenu(menu: Menu, inflater: MenuInflater) { - if (config.isUnfinishedMode()) - menu.add(Menu.FIRST, ID_MENU_TEST, 0, "Test").setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) menu.add(Menu.FIRST, ID_MENU_CLEAR_LOG, 0, rh.gs(R.string.clear_log)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) menu.add(Menu.FIRST, ID_MENU_RESTART, 0, rh.gs(R.string.restart)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) menu.add(Menu.FIRST, ID_MENU_SEND_NOW, 0, rh.gs(R.string.deliver_now)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER) @@ -133,11 +129,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment { true } - ID_MENU_TEST -> { - nsClientPlugin?.let { plugin -> if (plugin is NSClientV3Plugin) handler.post { plugin.test() } } - true - } - else -> false } diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt index 15cfa0b514..dd1241c8d7 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt @@ -7,8 +7,10 @@ import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.database.entities.Bolus import info.nightscout.database.entities.BolusCalculatorResult import info.nightscout.database.entities.Carbs +import info.nightscout.database.entities.DeviceStatus import info.nightscout.database.entities.EffectiveProfileSwitch import info.nightscout.database.entities.ExtendedBolus +import info.nightscout.database.entities.Food import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.OfflineEvent import info.nightscout.database.entities.ProfileSwitch @@ -29,6 +31,19 @@ import info.nightscout.database.impl.transactions.SyncNsProfileSwitchTransaction import info.nightscout.database.impl.transactions.SyncNsTemporaryBasalTransaction import info.nightscout.database.impl.transactions.SyncNsTemporaryTargetTransaction import info.nightscout.database.impl.transactions.SyncNsTherapyEventTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdBolusCalculatorResultTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdBolusTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdCarbsTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdDeviceStatusTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdEffectiveProfileSwitchTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdExtendedBolusTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdFoodTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdGlucoseValueTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdOfflineEventTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdProfileSwitchTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdTemporaryBasalTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdTemporaryTargetTransaction +import info.nightscout.database.impl.transactions.UpdateNsIdTherapyEventTransaction import info.nightscout.database.transactions.TransactionGlucoseValue import info.nightscout.interfaces.Config import info.nightscout.interfaces.Constants @@ -43,18 +58,10 @@ 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.localmodel.treatment.NSBolus -import info.nightscout.sdk.localmodel.treatment.NSBolusWizard -import info.nightscout.sdk.localmodel.treatment.NSCarbs -import info.nightscout.sdk.localmodel.treatment.NSEffectiveProfileSwitch -import info.nightscout.sdk.localmodel.treatment.NSExtendedBolus -import info.nightscout.sdk.localmodel.treatment.NSOfflineEvent -import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch -import info.nightscout.sdk.localmodel.treatment.NSTemporaryBasal -import info.nightscout.sdk.localmodel.treatment.NSTemporaryTarget -import info.nightscout.sdk.localmodel.treatment.NSTherapyEvent import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @@ -75,17 +82,30 @@ class StoreDataForDbImpl @Inject constructor( ) : StoreDataForDb { override val glucoseValues: MutableList = mutableListOf() + override val boluses: MutableList = mutableListOf() + override val carbs: MutableList = mutableListOf() + override val temporaryTargets: MutableList = mutableListOf() + override val effectiveProfileSwitches: MutableList = mutableListOf() + override val bolusCalculatorResults: MutableList = mutableListOf() + override val therapyEvents: MutableList = mutableListOf() + override val extendedBoluses: MutableList = mutableListOf() + override val temporaryBasals: MutableList = mutableListOf() + override val profileSwitches: MutableList = mutableListOf() + override val offlineEvents: MutableList = mutableListOf() - val boluses: MutableList = mutableListOf() - val carbs: MutableList = mutableListOf() - val temporaryTargets: MutableList = mutableListOf() - val effectiveProfileSwitches: MutableList = mutableListOf() - val bolusCalculatorResults: MutableList = mutableListOf() - val therapyEvents: MutableList = mutableListOf() - val extendedBoluses: MutableList = mutableListOf() - val temporaryBasals: MutableList = mutableListOf() - val profileSwitches: MutableList = mutableListOf() - val offlineEvents: MutableList = mutableListOf() + override val nsIdGlucoseValues: MutableList = mutableListOf() + override val nsIdBoluses: MutableList = mutableListOf() + override val nsIdCarbs: MutableList = mutableListOf() + override val nsIdFoods: MutableList = mutableListOf() + override val nsIdTemporaryTargets: MutableList = mutableListOf() + override val nsIdEffectiveProfileSwitches: MutableList = mutableListOf() + override val nsIdBolusCalculatorResults: MutableList = mutableListOf() + override val nsIdTherapyEvents: MutableList = mutableListOf() + override val nsIdExtendedBoluses: MutableList = mutableListOf() + override val nsIdTemporaryBasals: MutableList = mutableListOf() + override val nsIdProfileSwitches: MutableList = mutableListOf() + override val nsIdOfflineEvents: MutableList = mutableListOf() + override val nsIdDeviceStatuses: MutableList = mutableListOf() private val userEntries: MutableList = mutableListOf() @@ -103,7 +123,7 @@ class StoreDataForDbImpl @Inject constructor( params: WorkerParameters ) : LoggingWorker(context, params) { - @Inject lateinit var storeDataForDb: StoreDataForDbImpl + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { storeDataForDb.storeGlucoseValuesToDb() @@ -115,7 +135,7 @@ class StoreDataForDbImpl @Inject constructor( if (containsKey(key)) merge(key, 1, Long::plus) else put(key, 1) - private fun storeGlucoseValuesToDb() { + override fun storeGlucoseValuesToDb() { rxBus.send(EventNSClientNewLog("PROCESSING BG", "")) if (glucoseValues.isNotEmpty()) @@ -151,7 +171,7 @@ class StoreDataForDbImpl @Inject constructor( rxBus.send(EventNSClientNewLog("DONE BG", "")) } - fun storeTreatmentsToDb() { + override fun storeTreatmentsToDb() { rxBus.send(EventNSClientNewLog("PROCESSING TR", "")) if (boluses.isNotEmpty()) @@ -173,7 +193,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it") - inserted.inc(NSBolus::class.java.simpleName) + inserted.inc(Bolus::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -186,19 +206,19 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") - invalidated.inc(NSBolus::class.java.simpleName) + invalidated.inc(Bolus::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId of bolus $it") - nsIdUpdated.inc(NSBolus::class.java.simpleName) + nsIdUpdated.inc(Bolus::class.java.simpleName) } result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated amount of bolus $it") - updated.inc(NSBolus::class.java.simpleName) + updated.inc(Bolus::class.java.simpleName) } } - sendLog("Bolus", NSBolus::class.java.simpleName) + sendLog("Bolus", Bolus::class.java.simpleName) SystemClock.sleep(pause) if (carbs.isNotEmpty()) @@ -220,7 +240,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") - inserted.inc(NSCarbs::class.java.simpleName) + inserted.inc(Carbs::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -233,7 +253,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") - invalidated.inc(NSCarbs::class.java.simpleName) + invalidated.inc(Carbs::class.java.simpleName) } result.updated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -246,16 +266,16 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") - updated.inc(NSCarbs::class.java.simpleName) + updated.inc(Carbs::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it") - nsIdUpdated.inc(NSCarbs::class.java.simpleName) + nsIdUpdated.inc(Carbs::class.java.simpleName) } } - sendLog("Carbs", NSCarbs::class.java.simpleName) + sendLog("Carbs", Carbs::class.java.simpleName) SystemClock.sleep(pause) if (temporaryTargets.isNotEmpty()) @@ -282,7 +302,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt") - inserted.inc(NSTemporaryTarget::class.java.simpleName) + inserted.inc(TemporaryTarget::class.java.simpleName) } result.invalidated.forEach { tt -> if (config.NSCLIENT.not()) userEntries.add( @@ -300,7 +320,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt") - invalidated.inc(NSTemporaryTarget::class.java.simpleName) + invalidated.inc(TemporaryTarget::class.java.simpleName) } result.ended.forEach { tt -> if (config.NSCLIENT.not()) userEntries.add( @@ -318,19 +338,19 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt") - ended.inc(NSTemporaryTarget::class.java.simpleName) + ended.inc(TemporaryTarget::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it") - nsIdUpdated.inc(NSTemporaryTarget::class.java.simpleName) + nsIdUpdated.inc(TemporaryTarget::class.java.simpleName) } result.updatedDuration.forEach { aapsLogger.debug(LTag.DATABASE, "Updated duration TemporaryTarget $it") - durationUpdated.inc(NSTemporaryTarget::class.java.simpleName) + durationUpdated.inc(TemporaryTarget::class.java.simpleName) } } - sendLog("TemporaryTarget", NSTemporaryTarget::class.java.simpleName) + sendLog("TemporaryTarget", TemporaryTarget::class.java.simpleName) SystemClock.sleep(pause) if (temporaryBasals.isNotEmpty()) @@ -356,7 +376,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it") - inserted.inc(NSTemporaryBasal::class.java.simpleName) + inserted.inc(TemporaryBasal::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -373,7 +393,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it") - invalidated.inc(NSTemporaryBasal::class.java.simpleName) + invalidated.inc(TemporaryBasal::class.java.simpleName) } result.ended.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -390,19 +410,19 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it") - ended.inc(NSTemporaryBasal::class.java.simpleName) + ended.inc(TemporaryBasal::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it") - nsIdUpdated.inc(NSTemporaryBasal::class.java.simpleName) + nsIdUpdated.inc(TemporaryBasal::class.java.simpleName) } result.updatedDuration.forEach { aapsLogger.debug(LTag.DATABASE, "Updated duration TemporaryBasal $it") - durationUpdated.inc(NSTemporaryBasal::class.java.simpleName) + durationUpdated.inc(TemporaryBasal::class.java.simpleName) } } - sendLog("TemporaryBasal", NSTemporaryBasal::class.java.simpleName) + sendLog("TemporaryBasal", TemporaryBasal::class.java.simpleName) SystemClock.sleep(pause) if (effectiveProfileSwitches.isNotEmpty()) @@ -424,7 +444,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted EffectiveProfileSwitch $it") - inserted.inc(NSEffectiveProfileSwitch::class.java.simpleName) + inserted.inc(EffectiveProfileSwitch::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -437,15 +457,15 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated EffectiveProfileSwitch $it") - invalidated.inc(NSEffectiveProfileSwitch::class.java.simpleName) + invalidated.inc(EffectiveProfileSwitch::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId EffectiveProfileSwitch $it") - nsIdUpdated.inc(NSEffectiveProfileSwitch::class.java.simpleName) + nsIdUpdated.inc(EffectiveProfileSwitch::class.java.simpleName) } } - sendLog("EffectiveProfileSwitch", NSEffectiveProfileSwitch::class.java.simpleName) + sendLog("EffectiveProfileSwitch", EffectiveProfileSwitch::class.java.simpleName) SystemClock.sleep(pause) if (profileSwitches.isNotEmpty()) @@ -467,7 +487,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it") - inserted.inc(NSProfileSwitch::class.java.simpleName) + inserted.inc(ProfileSwitch::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -480,15 +500,15 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") - invalidated.inc(NSProfileSwitch::class.java.simpleName) + invalidated.inc(ProfileSwitch::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it") - nsIdUpdated.inc(NSProfileSwitch::class.java.simpleName) + nsIdUpdated.inc(ProfileSwitch::class.java.simpleName) } } - sendLog("ProfileSwitch", NSProfileSwitch::class.java.simpleName) + sendLog("ProfileSwitch", ProfileSwitch::class.java.simpleName) SystemClock.sleep(pause) if (bolusCalculatorResults.isNotEmpty()) @@ -501,19 +521,19 @@ class StoreDataForDbImpl @Inject constructor( bolusCalculatorResults.clear() result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted BolusCalculatorResult $it") - inserted.inc(NSBolusWizard::class.java.simpleName) + inserted.inc(BolusCalculatorResult::class.java.simpleName) } result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated BolusCalculatorResult $it") - invalidated.inc(NSBolusWizard::class.java.simpleName) + invalidated.inc(BolusCalculatorResult::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId BolusCalculatorResult $it") - nsIdUpdated.inc(NSBolusWizard::class.java.simpleName) + nsIdUpdated.inc(BolusCalculatorResult::class.java.simpleName) } } - sendLog("BolusCalculatorResult", NSBolusWizard::class.java.simpleName) + sendLog("BolusCalculatorResult", BolusCalculatorResult::class.java.simpleName) SystemClock.sleep(pause) if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT) @@ -553,7 +573,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $therapyEvent") - inserted.inc(NSTherapyEvent::class.java.simpleName) + inserted.inc(TherapyEvent::class.java.simpleName) } result.invalidated.forEach { therapyEvent -> if (config.NSCLIENT.not()) userEntries.add( @@ -569,19 +589,19 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $therapyEvent") - invalidated.inc(NSTherapyEvent::class.java.simpleName) + invalidated.inc(TherapyEvent::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it") - nsIdUpdated.inc(NSTherapyEvent::class.java.simpleName) + nsIdUpdated.inc(TherapyEvent::class.java.simpleName) } result.updatedDuration.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it") - durationUpdated.inc(NSTherapyEvent::class.java.simpleName) + durationUpdated.inc(TherapyEvent::class.java.simpleName) } } - sendLog("TherapyEvent", NSTherapyEvent::class.java.simpleName) + sendLog("TherapyEvent", TherapyEvent::class.java.simpleName) SystemClock.sleep(pause) if (offlineEvents.isNotEmpty()) @@ -605,7 +625,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $oe") - inserted.inc(NSOfflineEvent::class.java.simpleName) + inserted.inc(OfflineEvent::class.java.simpleName) } result.invalidated.forEach { oe -> if (config.NSCLIENT.not()) userEntries.add( @@ -621,7 +641,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated OfflineEvent $oe") - invalidated.inc(NSOfflineEvent::class.java.simpleName) + invalidated.inc(OfflineEvent::class.java.simpleName) } result.ended.forEach { oe -> if (config.NSCLIENT.not()) userEntries.add( @@ -637,19 +657,19 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $oe") - ended.inc(NSOfflineEvent::class.java.simpleName) + ended.inc(OfflineEvent::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId OfflineEvent $it") - nsIdUpdated.inc(NSOfflineEvent::class.java.simpleName) + nsIdUpdated.inc(OfflineEvent::class.java.simpleName) } result.updatedDuration.forEach { aapsLogger.debug(LTag.DATABASE, "Updated duration OfflineEvent $it") - durationUpdated.inc(NSOfflineEvent::class.java.simpleName) + durationUpdated.inc(OfflineEvent::class.java.simpleName) } } - sendLog("OfflineEvent", NSOfflineEvent::class.java.simpleName) + sendLog("OfflineEvent", OfflineEvent::class.java.simpleName) SystemClock.sleep(pause) if (extendedBoluses.isNotEmpty()) @@ -676,7 +696,7 @@ class StoreDataForDbImpl @Inject constructor( ) if (it.isEmulatingTempBasal) virtualPump.fakeDataDetected = true aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it") - inserted.inc(NSExtendedBolus::class.java.simpleName) + inserted.inc(ExtendedBolus::class.java.simpleName) } result.invalidated.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -694,7 +714,7 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it") - invalidated.inc(NSExtendedBolus::class.java.simpleName) + invalidated.inc(ExtendedBolus::class.java.simpleName) } result.ended.forEach { if (config.NSCLIENT.not()) userEntries.add( @@ -712,25 +732,212 @@ class StoreDataForDbImpl @Inject constructor( ) ) aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it") - ended.inc(NSExtendedBolus::class.java.simpleName) + ended.inc(ExtendedBolus::class.java.simpleName) } result.updatedNsId.forEach { aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it") - nsIdUpdated.inc(NSExtendedBolus::class.java.simpleName) + nsIdUpdated.inc(ExtendedBolus::class.java.simpleName) } result.updatedDuration.forEach { aapsLogger.debug(LTag.DATABASE, "Updated duration ExtendedBolus $it") - durationUpdated.inc(NSExtendedBolus::class.java.simpleName) + durationUpdated.inc(ExtendedBolus::class.java.simpleName) } } - sendLog("ExtendedBolus", NSExtendedBolus::class.java.simpleName) + sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName) SystemClock.sleep(pause) uel.log(userEntries) rxBus.send(EventNSClientNewLog("DONE TR", "")) } + private val eventWorker = Executors.newSingleThreadScheduledExecutor() + private var scheduledEventPost: ScheduledFuture<*>? = null + override fun scheduleNsIdUpdate() { + class PostRunnable : Runnable { + + override fun run() { + aapsLogger.debug(LTag.CORE, "Firing updateNsIds") + scheduledEventPost = null + updateNsIds() + } + } + // cancel waiting task to prevent sending multiple posts + scheduledEventPost?.cancel(false) + val task: Runnable = PostRunnable() + scheduledEventPost = eventWorker.schedule(task, 30, TimeUnit.SECONDS) + } + + private fun updateNsIds() { + repository.runTransactionForResult(UpdateNsIdTemporaryTargetTransaction(nsIdTemporaryTargets)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of TemporaryTarget failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of TemporaryTarget $it") + nsIdUpdated.inc(TemporaryTarget::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdGlucoseValueTransaction(nsIdGlucoseValues)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of GlucoseValue failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of GlucoseValue $it") + nsIdUpdated.inc(GlucoseValue::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdFoodTransaction(nsIdFoods)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of Food failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of Food $it") + nsIdUpdated.inc(Food::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdTherapyEventTransaction(nsIdTherapyEvents)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of TherapyEvent failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of TherapyEvent $it") + nsIdUpdated.inc(TherapyEvent::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdBolusTransaction(nsIdBoluses)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of Bolus failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of Bolus $it") + nsIdUpdated.inc(Bolus::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdCarbsTransaction(nsIdCarbs)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of Carbs failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of Carbs $it") + nsIdUpdated.inc(Carbs::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdBolusCalculatorResultTransaction(nsIdBolusCalculatorResults)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of BolusCalculatorResult failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of BolusCalculatorResult $it") + nsIdUpdated.inc(BolusCalculatorResult::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdTemporaryBasalTransaction(nsIdTemporaryBasals)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of TemporaryBasal failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of TemporaryBasal $it") + nsIdUpdated.inc(TemporaryBasal::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdExtendedBolusTransaction(nsIdExtendedBoluses)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of ExtendedBolus failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of ExtendedBolus $it") + nsIdUpdated.inc(ExtendedBolus::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdProfileSwitchTransaction(nsIdProfileSwitches)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of ProfileSwitch failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of ProfileSwitch $it") + nsIdUpdated.inc(ProfileSwitch::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdEffectiveProfileSwitchTransaction(nsIdEffectiveProfileSwitches)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of EffectiveProfileSwitch failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of EffectiveProfileSwitch $it") + nsIdUpdated.inc(EffectiveProfileSwitch::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdDeviceStatusTransaction(nsIdDeviceStatuses)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of DeviceStatus failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of DeviceStatus $it") + nsIdUpdated.inc(DeviceStatus::class.java.simpleName) + } + } + + repository.runTransactionForResult(UpdateNsIdOfflineEventTransaction(nsIdOfflineEvents)) + .doOnError { error -> + aapsLogger.error(LTag.DATABASE, "Updated nsId of OfflineEvent failed", error) + } + .blockingGet() + .also { result -> + result.updatedNsId.forEach { + aapsLogger.debug(LTag.DATABASE, "Updated nsId of OfflineEvent $it") + nsIdUpdated.inc(OfflineEvent::class.java.simpleName) + } + } + sendLog("GlucoseValue", GlucoseValue::class.java.simpleName) + sendLog("Bolus", Bolus::class.java.simpleName) + sendLog("Carbs", Carbs::class.java.simpleName) + sendLog("TemporaryTarget", TemporaryTarget::class.java.simpleName) + sendLog("TemporaryBasal", TemporaryBasal::class.java.simpleName) + sendLog("EffectiveProfileSwitch", EffectiveProfileSwitch::class.java.simpleName) + sendLog("ProfileSwitch", ProfileSwitch::class.java.simpleName) + sendLog("BolusCalculatorResult", BolusCalculatorResult::class.java.simpleName) + sendLog("TherapyEvent", TherapyEvent::class.java.simpleName) + sendLog("OfflineEvent", OfflineEvent::class.java.simpleName) + sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName) + rxBus.send(EventNSClientNewLog("DONE NSIDs", "")) + } + private fun sendLog(item: String, clazz: String) { inserted[clazz]?.let { rxBus.send(EventNSClientNewLog("INSERT", "$item $it")) diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt index a6dad603c0..67e6885aba 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt @@ -12,6 +12,7 @@ import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceScreen import androidx.preference.SwitchPreference import dagger.android.HasAndroidInjector +import info.nightscout.core.extensions.toJson import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.Config import info.nightscout.interfaces.Constants @@ -20,6 +21,7 @@ import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginType +import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.source.DoingOwnUploadSource import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.NsClient @@ -32,6 +34,7 @@ import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI import info.nightscout.plugins.sync.nsclient.data.AlarmAck +import info.nightscout.plugins.sync.nsclient.extensions.toJson import info.nightscout.plugins.sync.nsclient.services.NSClientService import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus @@ -45,9 +48,9 @@ import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.shared.utils.DateUtil import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign -import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton @@ -65,7 +68,9 @@ class NSClientPlugin @Inject constructor( private val config: Config, private val dataSyncSelector: DataSyncSelector, private val uiInteraction: UiInteraction, - private val activePlugin: ActivePlugin + private val activePlugin: ActivePlugin, + private val dateUtil: DateUtil, + private val profileFunction: ProfileFunction ) : NsClient, Sync, PluginBase( PluginDescription() .mainType(PluginType.SYNC) @@ -237,11 +242,60 @@ class NSClientPlugin @Inject constructor( dataSyncSelector.resetToNextFullSync() } - override fun dbAdd(collection: String, data: JSONObject, originalObject: Any, progress: String) { - nsClientService?.dbAdd(collection, data, originalObject, progress) + override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { + when (dataPair) { + is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileFunction) + is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, profileFunction.getUnits(), dateUtil) + is DataSyncSelector.PairFood -> dataPair.value.toJson(true) + is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairDeviceStatus -> dataPair.value.toJson(dateUtil) + is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(true, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(true, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil) + is DataSyncSelector.PairProfileStore -> dataPair.value + else -> null + }?.let { data -> + nsClientService?.dbAdd(collection, data, dataPair, progress) + } } - override fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any, progress: String) { - nsClientService?.dbUpdate(collection, _id, data, originalObject, progress) + override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { + val id = when (dataPair) { + is DataSyncSelector.PairBolus -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairCarbs -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairTemporaryTarget -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairFood -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairGlucoseValue -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairTherapyEvent -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairTemporaryBasal -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairExtendedBolus -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairProfileSwitch -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.interfaceIDs.nightscoutId + is DataSyncSelector.PairOfflineEvent -> dataPair.value.interfaceIDs.nightscoutId + else -> throw IllegalStateException() + } + when (dataPair) { + is DataSyncSelector.PairBolus -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction) + is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil) + is DataSyncSelector.PairFood -> dataPair.value.toJson(false) + is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil) + is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil) + else -> null + }?.let { data -> + nsClientService?.dbUpdate(collection, id, data, dataPair, progress) + } } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSAddAck.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSAddAck.kt index 0b68f3c8e9..7163a77321 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSAddAck.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSAddAck.kt @@ -1,10 +1,15 @@ package info.nightscout.plugins.sync.nsclient.acks +import androidx.work.OneTimeWorkRequest +import info.nightscout.core.utils.receivers.DataWorkerStorage +import info.nightscout.plugins.sync.nsclient.services.NSClientService +import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.Event import info.nightscout.rx.events.EventNSClientRestart import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag +import info.nightscout.shared.utils.DateUtil import io.socket.client.Ack import org.json.JSONArray import org.json.JSONObject @@ -12,11 +17,13 @@ import org.json.JSONObject class NSAddAck( private val aapsLogger: AAPSLogger, private val rxBus: RxBus, + private val nsClientService: NSClientService, + private val dateUtil: DateUtil, + private val dataWorkerStorage: DataWorkerStorage, val originalObject: Any? = null ) : Event(), Ack { var id: String? = null - private var nsClientID: String? = null var json: JSONObject? = null override fun call(vararg args: Any) { // Regular response @@ -27,11 +34,8 @@ class NSAddAck( response = responseArray.getJSONObject(0) id = response.getString("_id") json = response - if (response.has("NSCLIENT_ID")) { - nsClientID = response.getString("NSCLIENT_ID") - } } - rxBus.send(this) + processAddAck() return } catch (e: Exception) { aapsLogger.error("Unhandled exception", e) @@ -51,4 +55,13 @@ class NSAddAck( aapsLogger.error("Unhandled exception", e) } } + + private fun processAddAck() { + nsClientService.lastAckTime = dateUtil.now() + dataWorkerStorage.enqueue( + OneTimeWorkRequest.Builder(NSClientAddAckWorker::class.java) + .setInputData(dataWorkerStorage.storeInputData(this)) + .build() + ) + } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSUpdateAck.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSUpdateAck.kt index fd07b22ce5..5abd391fa9 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSUpdateAck.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/acks/NSUpdateAck.kt @@ -1,9 +1,14 @@ package info.nightscout.plugins.sync.nsclient.acks +import androidx.work.OneTimeWorkRequest +import info.nightscout.core.utils.receivers.DataWorkerStorage +import info.nightscout.plugins.sync.nsclient.services.NSClientService +import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.Event import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.LTag +import info.nightscout.shared.utils.DateUtil import io.socket.client.Ack import org.json.JSONException import org.json.JSONObject @@ -16,6 +21,9 @@ class NSUpdateAck( var _id: String, private val aapsLogger: AAPSLogger, private val rxBus: RxBus, + private val nsClientService: NSClientService, + private val dateUtil: DateUtil, + private val dataWorkerStorage: DataWorkerStorage, val originalObject: Any? = null ) : Event(), Ack { @@ -29,9 +37,18 @@ class NSUpdateAck( result = true aapsLogger.debug(LTag.NSCLIENT, "Internal error: Missing _id returned on dbUpdate ack") } - rxBus.send(this) + processUpdateAck() } catch (e: JSONException) { aapsLogger.error("Unhandled exception", e) } } + + private fun processUpdateAck() { + nsClientService.lastAckTime = dateUtil.now() + dataWorkerStorage.enqueue( + OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker::class.java) + .setInputData(dataWorkerStorage.storeInputData(this)) + .build() + ) + } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/ExtendedBolusExtension.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/ExtendedBolusExtension.kt index 22ad91b616..5e2f62df7d 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/ExtendedBolusExtension.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/ExtendedBolusExtension.kt @@ -9,12 +9,15 @@ import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.T import org.json.JSONObject -fun ExtendedBolus.toJson(isAdd: Boolean, profile: Profile, dateUtil: DateUtil): JSONObject = - if (isEmulatingTempBasal) - toTemporaryBasal(profile) - .toJson(isAdd, profile, dateUtil) - .put("extendedEmulated", toRealJson(isAdd, dateUtil)) - else toRealJson(isAdd, dateUtil) +fun ExtendedBolus.toJson(isAdd: Boolean, profile: Profile?, dateUtil: DateUtil): JSONObject? = + profile?.let { + if (isEmulatingTempBasal) + toTemporaryBasal(profile) + .toJson(isAdd, profile, dateUtil) + ?.put("extendedEmulated", toRealJson(isAdd, dateUtil)) + else toRealJson(isAdd, dateUtil) + } + fun ExtendedBolus.toRealJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject = JSONObject() diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/TemporaryBasalExtension.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/TemporaryBasalExtension.kt index e79e2ce859..79d8e32b23 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/TemporaryBasalExtension.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/extensions/TemporaryBasalExtension.kt @@ -10,25 +10,27 @@ import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.T import org.json.JSONObject -fun TemporaryBasal.toJson(isAdd: Boolean, profile: Profile, dateUtil: DateUtil): JSONObject = - JSONObject() - .put("created_at", dateUtil.toISOString(timestamp)) - .put("enteredBy", "openaps://" + "AndroidAPS") - .put("eventType", info.nightscout.database.entities.TherapyEvent.Type.TEMPORARY_BASAL.text) - .put("isValid", isValid) - .put("duration", T.msecs(duration).mins()) - .put("durationInMilliseconds", duration) // rounded duration leads to different basal IOB - .put("type", type.name) - .put("rate", convertedToAbsolute(timestamp, profile)) // generated by OpenAPS, for compatibility - .also { - if (isAbsolute) it.put("absolute", rate) - else it.put("percent", rate - 100) - if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId) - if (interfaceIDs.endId != null) it.put("endId", interfaceIDs.endId) - if (interfaceIDs.pumpType != null) it.put("pumpType", interfaceIDs.pumpType!!.name) - if (interfaceIDs.pumpSerial != null) it.put("pumpSerial", interfaceIDs.pumpSerial) - if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) - } +fun TemporaryBasal.toJson(isAdd: Boolean, profile: Profile?, dateUtil: DateUtil): JSONObject? = + profile?.let { + JSONObject() + .put("created_at", dateUtil.toISOString(timestamp)) + .put("enteredBy", "openaps://" + "AndroidAPS") + .put("eventType", info.nightscout.database.entities.TherapyEvent.Type.TEMPORARY_BASAL.text) + .put("isValid", isValid) + .put("duration", T.msecs(duration).mins()) + .put("durationInMilliseconds", duration) // rounded duration leads to different basal IOB + .put("type", type.name) + .put("rate", convertedToAbsolute(timestamp, profile)) // generated by OpenAPS, for compatibility + .also { + if (isAbsolute) it.put("absolute", rate) + else it.put("percent", rate - 100) + if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId) + if (interfaceIDs.endId != null) it.put("endId", interfaceIDs.endId) + if (interfaceIDs.pumpType != null) it.put("pumpType", interfaceIDs.pumpType!!.name) + if (interfaceIDs.pumpSerial != null) it.put("pumpSerial", interfaceIDs.pumpSerial) + if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) + } + } fun temporaryBasalFromJson(jsonObject: JSONObject): TemporaryBasal? { val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt index 6933b8bfee..5c4d1506d3 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt @@ -39,10 +39,8 @@ import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck import info.nightscout.plugins.sync.nsclient.data.AlarmAck import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler -import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker -import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus @@ -110,7 +108,7 @@ class NSClientService : DaggerService() { private var nsAPISecret = "" private var nsDevice = "" private val nsHours = 48 - private var lastAckTime: Long = 0 + internal var lastAckTime: Long = 0 private var nsApiHashCode = "" private val reconnections = ArrayList() @@ -167,14 +165,6 @@ class NSClientService : DaggerService() { .toObservable(NSAuthAck::class.java) .observeOn(aapsSchedulers.io) .subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException) - disposable += rxBus - .toObservable(NSUpdateAck::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ack -> processUpdateAck(ack) }, fabricPrivacy::logException) - disposable += rxBus - .toObservable(NSAddAck::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ ack -> processAddAck(ack) }, fabricPrivacy::logException) } override fun onDestroy() { @@ -183,24 +173,6 @@ class NSClientService : DaggerService() { if (wakeLock?.isHeld == true) wakeLock?.release() } - private fun processAddAck(ack: NSAddAck) { - lastAckTime = dateUtil.now() - dataWorkerStorage.enqueue( - OneTimeWorkRequest.Builder(NSClientAddAckWorker::class.java) - .setInputData(dataWorkerStorage.storeInputData(ack)) - .build() - ) - } - - private fun processUpdateAck(ack: NSUpdateAck) { - lastAckTime = dateUtil.now() - dataWorkerStorage.enqueue( - OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker::class.java) - .setInputData(dataWorkerStorage.storeInputData(ack)) - .build() - ) - } - private fun processAuthAck(ack: NSAuthAck) { var connectionStatus = "Authenticated (" if (ack.read) connectionStatus += "R" @@ -605,10 +577,10 @@ class NSClientService : DaggerService() { message.put("collection", collection) message.put("_id", _id) message.put("data", data) - socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, originalObject)) + socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject)) rxBus.send( EventNSClientNewLog( - "DBUPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " + + "UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " + "" + _id + " " + data + progress ) ) @@ -623,8 +595,8 @@ class NSClientService : DaggerService() { val message = JSONObject() message.put("collection", collection) message.put("data", data) - socket?.emit("dbAdd", message, NSAddAck(aapsLogger, rxBus, originalObject)) - rxBus.send(EventNSClientNewLog("DBADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress)) + socket?.emit("dbAdd", message, NSAddAck(aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject)) + rxBus.send(EventNSClientNewLog("ADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress)) } catch (e: JSONException) { aapsLogger.error("Unhandled exception", e) } diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddAckWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddAckWorker.kt index ad0e5946cd..ed3065b845 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddAckWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddAckWorker.kt @@ -6,21 +6,8 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.worker.LoggingWorker -import info.nightscout.database.entities.DeviceStatus import info.nightscout.database.impl.AppRepository -import info.nightscout.database.impl.transactions.UpdateNsIdBolusCalculatorResultTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdBolusTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdCarbsTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdDeviceStatusTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdEffectiveProfileSwitchTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdExtendedBolusTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdFoodTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdGlucoseValueTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdOfflineEventTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdProfileSwitchTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdTemporaryBasalTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdTemporaryTargetTransaction -import info.nightscout.database.impl.transactions.UpdateNsIdTherapyEventTransaction +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.DataSyncSelector.PairBolus import info.nightscout.interfaces.sync.DataSyncSelector.PairBolusCalculatorResult @@ -40,7 +27,6 @@ import info.nightscout.plugins.sync.nsclient.acks.NSAddAck import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientNewLog -import info.nightscout.rx.logging.LTag import info.nightscout.shared.sharedPreferences.SP import javax.inject.Inject @@ -55,30 +41,22 @@ class NSClientAddAckWorker( @Inject lateinit var dataSyncSelector: DataSyncSelector @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var sp: SP + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { - var ret = Result.success() - val ack = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAddAck? ?: return Result.failure(workDataOf("Error" to "missing input data")) if (sp.getBoolean(R.string.key_ns_sync_slow, false)) SystemClock.sleep(1000) + val ret = Result.success(workDataOf("ProcessedData" to ack.originalObject.toString())) when (ack.originalObject) { is PairTemporaryTarget -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdTemporaryTargetTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of TemporaryTarget failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of TemporaryTarget " + pair.value) - dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdTemporaryTargets.add(pair.value) + dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedTempTargetsCompat() @@ -87,17 +65,9 @@ class NSClientAddAckWorker( is PairGlucoseValue -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdGlucoseValueTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of GlucoseValue failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of GlucoseValue " + pair.value) - dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdGlucoseValues.add(pair.value) + dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedGlucoseValuesCompat() @@ -106,17 +76,9 @@ class NSClientAddAckWorker( is PairFood -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdFoodTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of Food failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of Food " + pair.value) - dataSyncSelector.confirmLastFoodIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdFoods.add(pair.value) + dataSyncSelector.confirmLastFoodIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedFoodsCompat() @@ -125,17 +87,9 @@ class NSClientAddAckWorker( is PairTherapyEvent -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdTherapyEventTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of TherapyEvent failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of TherapyEvent " + pair.value) - dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdTherapyEvents.add(pair.value) + dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedTherapyEventsCompat() @@ -144,17 +98,9 @@ class NSClientAddAckWorker( is PairBolus -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdBolusTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of Bolus failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of Bolus " + pair.value) - dataSyncSelector.confirmLastBolusIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdBoluses.add(pair.value) + dataSyncSelector.confirmLastBolusIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedBolusesCompat() @@ -163,17 +109,9 @@ class NSClientAddAckWorker( is PairCarbs -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdCarbsTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of Carbs failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of Carbs " + pair.value) - dataSyncSelector.confirmLastCarbsIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdCarbs.add(pair.value) + dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedCarbsCompat() @@ -182,17 +120,9 @@ class NSClientAddAckWorker( is PairBolusCalculatorResult -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdBolusCalculatorResultTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of BolusCalculatorResult failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of BolusCalculatorResult " + pair.value) - dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdBolusCalculatorResults.add(pair.value) + dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedBolusCalculatorResultsCompat() @@ -201,17 +131,9 @@ class NSClientAddAckWorker( is PairTemporaryBasal -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdTemporaryBasalTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of TemporaryBasal failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of TemporaryBasal " + pair.value) - dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdTemporaryBasals.add(pair.value) + dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedTemporaryBasalsCompat() @@ -220,17 +142,9 @@ class NSClientAddAckWorker( is PairExtendedBolus -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdExtendedBolusTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of ExtendedBolus failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of ExtendedBolus " + pair.value) - dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdExtendedBoluses.add(pair.value) + dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedExtendedBolusesCompat() @@ -239,17 +153,9 @@ class NSClientAddAckWorker( is PairProfileSwitch -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdProfileSwitchTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of ProfileSwitch failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of ProfileSwitch " + pair.value) - dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdProfileSwitches.add(pair.value) + dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedProfileSwitchesCompat() @@ -258,60 +164,36 @@ class NSClientAddAckWorker( is PairEffectiveProfileSwitch -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdEffectiveProfileSwitchTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of EffectiveProfileSwitch failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of EffectiveProfileSwitch " + pair.value) - dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value) + dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedEffectiveProfileSwitchesCompat() } - is DeviceStatus -> { - val deviceStatus = ack.originalObject - deviceStatus.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdDeviceStatusTransaction(deviceStatus)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of DeviceStatus failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to deviceStatus.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of DeviceStatus $deviceStatus") - dataSyncSelector.confirmLastDeviceStatusIdIfGreater(deviceStatus.id) - } - .blockingGet() - rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus " + deviceStatus.interfaceIDs.nightscoutId)) + is DataSyncSelector.PairDeviceStatus -> { + val pair = ack.originalObject + pair.value.interfaceIDs.nightscoutId = ack.id + storeDataForDb.nsIdDeviceStatuses.add(pair.value) + dataSyncSelector.confirmLastDeviceStatusIdIfGreater(pair.value.id) + storeDataForDb.scheduleNsIdUpdate() + rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedDeviceStatusesCompat() } is PairProfileStore -> { - dataSyncSelector.confirmLastProfileStore(ack.originalObject.timestampSync) + dataSyncSelector.confirmLastProfileStore(ack.originalObject.id) rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileStore " + ack.id)) } is PairOfflineEvent -> { val pair = ack.originalObject pair.value.interfaceIDs.nightscoutId = ack.id - repository.runTransactionForResult(UpdateNsIdOfflineEventTransaction(pair.value)) - .doOnError { error -> - aapsLogger.error(LTag.DATABASE, "Updated ns id of OfflineEvent failed", error) - ret = Result.failure((workDataOf("Error" to error.toString()))) - } - .doOnSuccess { - ret = Result.success(workDataOf("ProcessedData" to pair.toString())) - aapsLogger.debug(LTag.DATABASE, "Updated ns id of OfflineEvent " + pair.value) - dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId) - } - .blockingGet() + storeDataForDb.nsIdOfflineEvents.add(pair.value) + dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id) + storeDataForDb.scheduleNsIdUpdate() rxBus.send(EventNSClientNewLog("DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId)) // Send new if waiting dataSyncSelector.processChangedOfflineEventsCompat() diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddUpdateWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddUpdateWorker.kt index 7c79f38715..ee941fab59 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddUpdateWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientAddUpdateWorker.kt @@ -11,11 +11,11 @@ import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.Config import info.nightscout.interfaces.XDripBroadcast import info.nightscout.interfaces.logging.UserEntryLogger +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.pump.VirtualPump import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.plugins.sync.R -import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsclient.extensions.bolusFromJson import info.nightscout.plugins.sync.nsclient.extensions.carbsFromJson import info.nightscout.plugins.sync.nsclient.extensions.effectiveProfileSwitchFromJson @@ -46,7 +46,7 @@ class NSClientAddUpdateWorker( @Inject lateinit var rxBus: RxBus @Inject lateinit var uel: UserEntryLogger @Inject lateinit var xDripBroadcast: XDripBroadcast - @Inject lateinit var storeDataForDb: StoreDataForDbImpl + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { val treatments = dataWorkerStorage.pickupJSONArray(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientMbgWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientMbgWorker.kt index 26cb5321b0..4ba8f44dc9 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientMbgWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientMbgWorker.kt @@ -6,7 +6,7 @@ import androidx.work.workDataOf import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.interfaces.Config -import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.plugins.sync.nsclient.data.NSMbg import info.nightscout.plugins.sync.nsclient.extensions.therapyEventFromNsMbg import info.nightscout.shared.sharedPreferences.SP @@ -20,7 +20,7 @@ class NSClientMbgWorker( @Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var sp: SP @Inject lateinit var config: Config - @Inject lateinit var storeDataForDb: StoreDataForDbImpl + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { val ret = Result.success() diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientUpdateRemoveAckWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientUpdateRemoveAckWorker.kt index bf000d9c03..3536329da1 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientUpdateRemoveAckWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/workers/NSClientUpdateRemoveAckWorker.kt @@ -46,7 +46,7 @@ class NSClientUpdateRemoveAckWorker( when (ack.originalObject) { is PairTemporaryTarget -> { val pair = ack.originalObject - dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryTarget" + ack._id)) // Send new if waiting dataSyncSelector.processChangedTempTargetsCompat() @@ -55,7 +55,7 @@ class NSClientUpdateRemoveAckWorker( is PairGlucoseValue -> { val pair = ack.originalObject - dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked GlucoseValue " + ack._id)) // Send new if waiting dataSyncSelector.processChangedGlucoseValuesCompat() @@ -64,7 +64,7 @@ class NSClientUpdateRemoveAckWorker( is PairFood -> { val pair = ack.originalObject - dataSyncSelector.confirmLastFoodIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastFoodIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Food " + ack._id)) // Send new if waiting dataSyncSelector.processChangedFoodsCompat() @@ -73,7 +73,7 @@ class NSClientUpdateRemoveAckWorker( is PairTherapyEvent -> { val pair = ack.originalObject - dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TherapyEvent " + ack._id)) // Send new if waiting dataSyncSelector.processChangedTherapyEventsCompat() @@ -82,7 +82,7 @@ class NSClientUpdateRemoveAckWorker( is PairBolus -> { val pair = ack.originalObject - dataSyncSelector.confirmLastBolusIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastBolusIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Bolus " + ack._id)) // Send new if waiting dataSyncSelector.processChangedBolusesCompat() @@ -91,7 +91,7 @@ class NSClientUpdateRemoveAckWorker( is PairCarbs -> { val pair = ack.originalObject - dataSyncSelector.confirmLastCarbsIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Carbs " + ack._id)) // Send new if waiting dataSyncSelector.processChangedCarbsCompat() @@ -100,7 +100,7 @@ class NSClientUpdateRemoveAckWorker( is PairBolusCalculatorResult -> { val pair = ack.originalObject - dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked BolusCalculatorResult " + ack._id)) // Send new if waiting dataSyncSelector.processChangedBolusCalculatorResultsCompat() @@ -109,7 +109,7 @@ class NSClientUpdateRemoveAckWorker( is PairTemporaryBasal -> { val pair = ack.originalObject - dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryBasal " + ack._id)) // Send new if waiting dataSyncSelector.processChangedTemporaryBasalsCompat() @@ -118,7 +118,7 @@ class NSClientUpdateRemoveAckWorker( is PairExtendedBolus -> { val pair = ack.originalObject - dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ExtendedBolus " + ack._id)) // Send new if waiting dataSyncSelector.processChangedExtendedBolusesCompat() @@ -127,7 +127,7 @@ class NSClientUpdateRemoveAckWorker( is PairProfileSwitch -> { val pair = ack.originalObject - dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ProfileSwitch " + ack._id)) // Send new if waiting dataSyncSelector.processChangedProfileSwitchesCompat() @@ -136,7 +136,7 @@ class NSClientUpdateRemoveAckWorker( is PairEffectiveProfileSwitch -> { val pair = ack.originalObject - dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id)) // Send new if waiting dataSyncSelector.processChangedEffectiveProfileSwitchesCompat() @@ -145,7 +145,7 @@ class NSClientUpdateRemoveAckWorker( is PairOfflineEvent -> { val pair = ack.originalObject - dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId) + dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id) rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked OfflineEvent" + ack._id)) // Send new if waiting dataSyncSelector.processChangedOfflineEventsCompat() diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt index 9cc8242897..7c98627f2e 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt @@ -11,14 +11,19 @@ import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequest import androidx.work.WorkInfo import androidx.work.WorkManager +import com.google.gson.Gson +import com.google.gson.GsonBuilder import dagger.android.HasAndroidInjector import info.nightscout.core.utils.fabric.FabricPrivacy +import info.nightscout.database.entities.interfaces.TraceableDBEntry import info.nightscout.interfaces.Config import info.nightscout.interfaces.Constants import info.nightscout.interfaces.nsclient.NSAlarm +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginType +import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.ui.UiInteraction @@ -28,8 +33,7 @@ import info.nightscout.plugins.sync.nsShared.NSClientFragment import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate -import info.nightscout.plugins.sync.nsclient.data.AlarmAck -import info.nightscout.plugins.sync.nsclient.services.NSClientService +import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker @@ -51,9 +55,9 @@ import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.T import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign +import kotlinx.coroutines.runBlocking import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton import kotlin.math.max @@ -71,7 +75,9 @@ class NSClientV3Plugin @Inject constructor( private val nsClientReceiverDelegate: NsClientReceiverDelegate, private val config: Config, private val dateUtil: DateUtil, - private val uiInteraction: UiInteraction + private val uiInteraction: UiInteraction, + private val storeDataForDb: StoreDataForDb, + private val dataSyncSelector: DataSyncSelector ) : NsClient, Sync, PluginBase( PluginDescription() .mainType(PluginType.SYNC) @@ -113,8 +119,8 @@ class NSClientV3Plugin @Inject constructor( val blockingReason get() = nsClientReceiverDelegate.blockingReason private val maxAge = T.days(77).msecs() - internal var lastModified: LastModified? = null // timestamp of last modification for every collection - internal var lastFetched = + internal var newestDataOnServer: LastModified? = null // timestamp of last modification for every collection + internal var lastLoadedSrvModified = LastModified( LastModified.Collections( dateUtil.now() - maxAge, @@ -128,7 +134,7 @@ class NSClientV3Plugin @Inject constructor( // context.bindService(Intent(context, NSClientService::class.java), mConnection, Context.BIND_AUTO_CREATE) super.onStart() - lastFetched = Json.decodeFromString( + lastLoadedSrvModified = Json.decodeFromString( sp.getString( R.string.key_ns_client_v3_last_modified, Json.encodeToString( @@ -137,10 +143,10 @@ class NSClientV3Plugin @Inject constructor( ) ) ) - lastFetched.collections.entries = max(dateUtil.now() - maxAge, lastFetched.collections.entries) - lastFetched.collections.treatments = max(dateUtil.now() - maxAge, lastFetched.collections.treatments) - lastFetched.collections.profile = max(dateUtil.now() - maxAge, lastFetched.collections.profile) - lastFetched.collections.devicestatus = max(dateUtil.now() - maxAge, lastFetched.collections.devicestatus) + lastLoadedSrvModified.collections.entries = max(dateUtil.now() - maxAge, lastLoadedSrvModified.collections.entries) + lastLoadedSrvModified.collections.treatments = max(dateUtil.now() - maxAge, lastLoadedSrvModified.collections.treatments) + lastLoadedSrvModified.collections.profile = max(dateUtil.now() - maxAge, lastLoadedSrvModified.collections.profile) + lastLoadedSrvModified.collections.devicestatus = max(dateUtil.now() - maxAge, lastLoadedSrvModified.collections.devicestatus) setClient() @@ -251,7 +257,7 @@ class NSClientV3Plugin @Inject constructor( } override fun resend(reason: String) { -// nsClientService?.resend(reason) + executeLoop() } override fun pause(newState: Boolean) { @@ -278,19 +284,19 @@ class NSClientV3Plugin @Inject constructor( } override fun updateLatestBgReceivedIfNewer(latestReceived: Long) { - if (latestReceived > lastFetched.collections.entries) { - lastFetched.collections.entries = latestReceived + if (latestReceived > lastLoadedSrvModified.collections.entries) { + lastLoadedSrvModified.collections.entries = latestReceived storeLastFetched() } } override fun updateLatestTreatmentReceivedIfNewer(latestReceived: Long) { - lastFetched.collections.treatments = latestReceived + lastLoadedSrvModified.collections.treatments = latestReceived storeLastFetched() } override fun resetToFullSync() { - lastFetched = LastModified( + lastLoadedSrvModified = LastModified( LastModified.Collections( dateUtil.now() - maxAge, dateUtil.now() - maxAge, @@ -301,16 +307,83 @@ class NSClientV3Plugin @Inject constructor( storeLastFetched() } - override fun dbAdd(collection: String, data: JSONObject, originalObject: Any, progress: String) { - TODO("Not yet implemented") + override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { + dbOperation(collection, dataPair, progress, Operation.CREATE) } - override fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any, progress: String) { - TODO("Not yet implemented") + override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { + dbOperation(collection, dataPair, progress, Operation.UPDATE) } + enum class Operation { CREATE, UPDATE } + private val gson: Gson = GsonBuilder().create() + private fun dbOperation(collection: String, dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) { + val call = when(operation) { + Operation.CREATE -> nsAndroidClient::createTreatment + Operation.UPDATE -> nsAndroidClient::updateTreatment + } + when (dataPair) { + is DataSyncSelector.PairBolus -> dataPair.value.toNSBolus() + // is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction) + // is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil) + // is DataSyncSelector.PairFood -> dataPair.value.toJson(false) + // is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + // is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + // is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil) + else -> null + }?.let { data -> + runBlocking { + if (collection == "treatments") { + 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" + } + ) + ) + val result = call(data) + when (dataPair) { + 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) + } + // is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction) + // is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil) + // is DataSyncSelector.PairFood -> dataPair.value.toJson(false) + // is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + // is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil) + // is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil) + // is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil) + } + } catch (e: Exception) { + aapsLogger.error(LTag.NSCLIENT, "Upload exception", e) + } + } + } + } + } private fun storeLastFetched() { - sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastFetched)) + sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastLoadedSrvModified)) } fun test() { @@ -318,7 +391,7 @@ class NSClientV3Plugin @Inject constructor( } fun scheduleNewExecution() { - val toTime = lastFetched.collections.entries + T.mins(6).plus(T.secs(0)).msecs() + val toTime = lastLoadedSrvModified.collections.entries + T.mins(6).plus(T.secs(0)).msecs() if (toTime > dateUtil.now()) { handler.postDelayed({ executeLoop() }, toTime - dateUtil.now()) rxBus.send(EventNSClientNewLog("NEXT", dateUtil.dateAndTimeAndSecondsString(toTime))) @@ -346,8 +419,10 @@ class NSClientV3Plugin @Inject constructor( ) .then(OneTimeWorkRequest.Builder(LoadLastModificationWorker::class.java).build()) .then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()) - // LoadTreatmentsWorker is enqueued after BG finish - //.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) + // Other Workers are enqueued after BG finish + // LoadTreatmentsWorker + // LoadDeviceStatusWorker + // DataSyncWorker .enqueue() } } diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/extensions/BolusExtension.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/extensions/BolusExtension.kt index 23746cd94c..9b901ac7dd 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/extensions/BolusExtension.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/extensions/BolusExtension.kt @@ -1,7 +1,9 @@ package info.nightscout.plugins.sync.nsclientV3.extensions import info.nightscout.database.entities.Bolus +import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.embedments.InterfaceIDs +import info.nightscout.sdk.localmodel.treatment.EventType import info.nightscout.sdk.localmodel.treatment.NSBolus fun NSBolus.toBolus(): Bolus = @@ -21,4 +23,28 @@ fun NSBolus.BolusType?.toBolusType(): Bolus.Type = NSBolus.BolusType.SMB -> Bolus.Type.SMB NSBolus.BolusType.PRIMING -> Bolus.Type.PRIMING null -> Bolus.Type.NORMAL + } + +fun Bolus.toNSBolus(): NSBolus = + NSBolus( + eventType = EventType.fromString(if (type == Bolus.Type.SMB) TherapyEvent.Type.CORRECTION_BOLUS.text else TherapyEvent.Type.MEAL_BOLUS.text), + isValid = isValid, + date = timestamp, + utcOffset = utcOffset, + insulin = amount, + type = type.toBolusType(), + notes = notes, + identifier = interfaceIDs.nightscoutId, + pumpId = interfaceIDs.pumpId, + pumpType = interfaceIDs.pumpType?.name, + pumpSerial = interfaceIDs.pumpSerial, + endId = interfaceIDs.endId + ) + +fun Bolus.Type?.toBolusType(): NSBolus.BolusType = + when (this) { + Bolus.Type.NORMAL -> NSBolus.BolusType.NORMAL + Bolus.Type.SMB -> NSBolus.BolusType.SMB + Bolus.Type.PRIMING -> NSBolus.BolusType.PRIMING + null -> NSBolus.BolusType.NORMAL } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt new file mode 100644 index 0000000000..dcd0f6dcef --- /dev/null +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt @@ -0,0 +1,21 @@ +package info.nightscout.plugins.sync.nsclientV3.workers + +import android.content.Context +import androidx.work.WorkerParameters +import info.nightscout.core.utils.worker.LoggingWorker +import info.nightscout.interfaces.plugin.ActivePlugin +import info.nightscout.interfaces.sync.DataSyncSelector +import javax.inject.Inject + +class DataSyncWorker( + context: Context, params: WorkerParameters +) : LoggingWorker(context, params) { + + @Inject lateinit var dataSyncSelector: DataSyncSelector + @Inject lateinit var activePlugin: ActivePlugin + + override fun doWorkAndLog(): Result { + if (activePlugin.activeNsClient?.hasWritePermission == true) dataSyncSelector.doUpload() + return Result.success() + } +} \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt index 99b9cbed8c..f381913e58 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt @@ -39,16 +39,16 @@ class LoadBgWorker( var ret = Result.success() runBlocking { - if ((nsClientV3Plugin.lastModified?.collections?.entries ?: Long.MAX_VALUE) > nsClientV3Plugin.lastFetched.collections.entries) + if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > nsClientV3Plugin.lastLoadedSrvModified.collections.entries) try { //val sgvs = nsClientV3Plugin.nsAndroidClient.getSgvsModifiedSince(nsClientV3Plugin.lastFetched.collections.entries) - val sgvs = nsClientV3Plugin.nsAndroidClient.getSgvsNewerThan(nsClientV3Plugin.lastFetched.collections.entries, 500) + val sgvs = nsClientV3Plugin.nsAndroidClient.getSgvsNewerThan(nsClientV3Plugin.lastLoadedSrvModified.collections.entries, 500) aapsLogger.debug("SGVS: $sgvs") if (sgvs.isNotEmpty()) { rxBus.send( EventNSClientNewLog( "RCV", - "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}" + "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.entries)}" ) ) // Objective0 @@ -60,7 +60,7 @@ class LoadBgWorker( OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build() ).then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()).enqueue() } else { - rxBus.send(EventNSClientNewLog("END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}")) + rxBus.send(EventNSClientNewLog("END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.entries)}")) WorkManager.getInstance(context) .beginUniqueWork( NSClientV3Plugin.JOB_NAME, @@ -75,7 +75,7 @@ class LoadBgWorker( ret = Result.failure(workDataOf("Error" to error.toString())) } else { - rxBus.send(EventNSClientNewLog("END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}")) + rxBus.send(EventNSClientNewLog("END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.entries)}")) nsClientV3Plugin.scheduleNewExecution() // Idea is to run after 5 min after last BG WorkManager.getInstance(context) .beginUniqueWork( diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt index 693ea1374a..80d2cc4661 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt @@ -1,6 +1,9 @@ package info.nightscout.plugins.sync.nsclientV3.workers import android.content.Context +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkManager import androidx.work.WorkerParameters import androidx.work.workDataOf import info.nightscout.core.utils.receivers.DataWorkerStorage @@ -40,6 +43,12 @@ class LoadDeviceStatusWorker( } else { rxBus.send(EventNSClientNewLog("END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}")) } + WorkManager.getInstance(context) + .enqueueUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build() + ) } catch (error: Exception) { aapsLogger.error("Error: ", error) ret = Result.failure(workDataOf("Error" to error.toString())) diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt index 1dbf94d6a7..8c897985e0 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt @@ -20,8 +20,8 @@ class LoadLastModificationWorker( runBlocking { try { val lm = nsClientV3Plugin.nsAndroidClient.getLastModified() - nsClientV3Plugin.lastModified = lm - aapsLogger.debug("LAST MODIFIED: ${nsClientV3Plugin.lastModified}") + nsClientV3Plugin.newestDataOnServer = lm + aapsLogger.debug("LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}") } catch (error: Exception) { aapsLogger.error("Error: ", error) ret = Result.failure(workDataOf("Error" to error.toString())) diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt index 21ac3717fb..39dd4663de 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt @@ -8,7 +8,7 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.worker.LoggingWorker -import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientNewLog @@ -26,21 +26,21 @@ class LoadTreatmentsWorker( @Inject lateinit var context: Context @Inject lateinit var nsClientV3Plugin: NSClientV3Plugin @Inject lateinit var dateUtil: DateUtil - @Inject lateinit var storeDataForDb: StoreDataForDbImpl + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { var ret = Result.success() runBlocking { - if ((nsClientV3Plugin.lastModified?.collections?.treatments ?: Long.MAX_VALUE) > nsClientV3Plugin.lastFetched.collections.treatments) + if ((nsClientV3Plugin.newestDataOnServer?.collections?.treatments ?: Long.MAX_VALUE) > nsClientV3Plugin.lastLoadedSrvModified.collections.treatments) try { - val treatments = nsClientV3Plugin.nsAndroidClient.getTreatmentsModifiedSince(nsClientV3Plugin.lastFetched.collections.treatments, 500) + val treatments = nsClientV3Plugin.nsAndroidClient.getTreatmentsModifiedSince(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments, 500) aapsLogger.debug("TREATMENTS: $treatments") - if (treatments.isNotEmpty()) { + if (treatments.values.isNotEmpty()) { rxBus.send( EventNSClientNewLog( "RCV", - "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}" + "${treatments.values.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments)}" ) ) // Schedule processing of fetched data and continue of loading @@ -56,7 +56,7 @@ class LoadTreatmentsWorker( } else { rxBus.send( EventNSClientNewLog( - "END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}" + "END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments)}" ) ) storeDataForDb.storeTreatmentsToDb() @@ -72,7 +72,7 @@ class LoadTreatmentsWorker( ret = Result.failure(workDataOf("Error" to error.toString())) } else { - rxBus.send(EventNSClientNewLog("END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}")) + rxBus.send(EventNSClientNewLog("END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments)}")) storeDataForDb.storeTreatmentsToDb() WorkManager.getInstance(context) .enqueueUniqueWork( diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt index 096f746e20..6859805e5d 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt @@ -10,9 +10,9 @@ import info.nightscout.interfaces.Config import info.nightscout.interfaces.Constants import info.nightscout.interfaces.XDripBroadcast import info.nightscout.interfaces.logging.UserEntryLogger +import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.plugins.sync.R -import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsclientV3.extensions.toBolus import info.nightscout.plugins.sync.nsclientV3.extensions.toBolusCalculatorResult import info.nightscout.plugins.sync.nsclientV3.extensions.toCarbs @@ -25,6 +25,7 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toTemporaryTarget import info.nightscout.plugins.sync.nsclientV3.extensions.toTherapyEvent import info.nightscout.rx.bus.RxBus import info.nightscout.rx.logging.LTag +import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.sdk.localmodel.treatment.NSBolus import info.nightscout.sdk.localmodel.treatment.NSBolusWizard import info.nightscout.sdk.localmodel.treatment.NSCarbs @@ -54,24 +55,19 @@ class ProcessTreatmentsWorker( @Inject lateinit var rxBus: RxBus @Inject lateinit var uel: UserEntryLogger @Inject lateinit var xDripBroadcast: XDripBroadcast - @Inject lateinit var storeDataForDb: StoreDataForDbImpl + @Inject lateinit var storeDataForDb: StoreDataForDb override fun doWorkAndLog(): Result { @Suppress("UNCHECKED_CAST") - val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List? + val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse>? ?: return Result.failure(workDataOf("Error" to "missing input data")) val ret = Result.success() - var latestDateInReceivedData = 0L - - for (treatment in treatments) { + for (treatment in treatments.values) { aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment") //Find latest date in treatment val mills = treatment.date - if (mills != 0L && mills < dateUtil.now()) - if (mills > latestDateInReceivedData) latestDateInReceivedData = mills - when (treatment) { is NSBolus -> if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_insulin, false) || config.NSCLIENT) @@ -140,7 +136,7 @@ class ProcessTreatmentsWorker( } } } - activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData) + activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(treatments.lastServerModified) // xDripBroadcast.sendTreatments(treatments) return ret }