NSCv3: optimize, use coroutines istead of recursion
This commit is contained in:
parent
40e14ba0e3
commit
af4b7829f9
72 changed files with 2094 additions and 1848 deletions
|
@ -4,6 +4,8 @@
|
|||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<JetCodeStyleSettings>
|
||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
|
|
|
@ -15,7 +15,6 @@ class EventNSClientNewLog(val action: String, val logText: String?) : Event() {
|
|||
stringBuilder.append(action)
|
||||
stringBuilder.append("</b> ")
|
||||
stringBuilder.append(logText)
|
||||
stringBuilder.append("<br>")
|
||||
return stringBuilder
|
||||
}
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
package info.nightscout.androidaps.workflow
|
||||
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
import info.nightscout.source.NSClientSourcePlugin
|
||||
import javax.inject.Inject
|
||||
|
||||
class WorkerClassesImpl @Inject constructor() : WorkerClasses {
|
||||
|
||||
override val nsClientSourceWorker = NSClientSourcePlugin.NSClientSourceWorker::class.java
|
||||
override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
|
||||
//override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
|
||||
}
|
|
@ -47,4 +47,5 @@ interface StoreDataForDb {
|
|||
fun storeGlucoseValuesToDb()
|
||||
fun storeFoodsToDb()
|
||||
fun scheduleNsIdUpdate()
|
||||
fun updateNsIds()
|
||||
}
|
|
@ -36,5 +36,6 @@ interface ProfileSource {
|
|||
var currentProfileIndex: Int
|
||||
fun currentProfile(): SingleProfile?
|
||||
fun storeSettings(activity: FragmentActivity? = null, emptyCreated: Boolean = false)
|
||||
fun loadFromStore(store: ProfileStore)
|
||||
|
||||
}
|
|
@ -18,9 +18,11 @@ import org.json.JSONObject
|
|||
interface DataSyncSelector {
|
||||
|
||||
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
|
||||
|
@ -38,49 +40,7 @@ interface DataSyncSelector {
|
|||
|
||||
fun queueSize(): Long
|
||||
|
||||
fun doUpload()
|
||||
|
||||
fun resetToNextFullSync()
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedBoluses()
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedCarbs()
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedBolusCalculatorResults()
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTempTargets()
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
|
||||
fun processChangedGlucoseValues()
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTherapyEvents()
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long)
|
||||
fun processChangedFoods()
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedDeviceStatuses()
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTemporaryBasals()
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedExtendedBoluses()
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun processChangedProfileSwitches()
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun processChangedEffectiveProfileSwitches()
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||
fun processChangedOfflineEvents()
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
fun processChangedProfileStore()
|
||||
suspend fun doUpload()
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorV1 : DataSyncSelector {
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedBoluses()
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedCarbs()
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedBolusCalculatorResults()
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTempTargets()
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedGlucoseValues()
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTherapyEvents()
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedFoods()
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedDeviceStatuses()
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTemporaryBasals()
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedExtendedBoluses()
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedProfileSwitches()
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedEffectiveProfileSwitches()
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedOfflineEvents()
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
suspend fun processChangedProfileStore()
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorV3 : DataSyncSelector
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorXdrip : DataSyncSelector
|
|
@ -1,7 +1,7 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
import android.text.Spanned
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
||||
/**
|
||||
* Plugin providing communication with Nightscout server
|
||||
|
@ -24,14 +24,14 @@ interface NsClient : Sync {
|
|||
fun resend(reason: String)
|
||||
|
||||
/**
|
||||
* @return List last of messages for fragment in HTML format
|
||||
* List of log messages for fragment
|
||||
*/
|
||||
fun textLog(): Spanned
|
||||
val listLog: MutableList<EventNSClientNewLog>
|
||||
|
||||
/**
|
||||
* Clear list of stored messages displayed in fragment
|
||||
* Used data sync selector
|
||||
*/
|
||||
fun clearLog()
|
||||
val dataSyncSelector: DataSyncSelector
|
||||
|
||||
/**
|
||||
* Version of NS server
|
||||
|
@ -89,8 +89,9 @@ interface NsClient : Sync {
|
|||
* @param collection target ns collection
|
||||
* @param dataPair data to upload (data.first) and id of changed record (data.second)
|
||||
* @param progress progress of sync in format "number/number". Only for display in fragment
|
||||
* @return true for successful upload
|
||||
*/
|
||||
fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
|
||||
|
||||
/**
|
||||
* Upload updated record to NS
|
||||
|
@ -98,6 +99,7 @@ interface NsClient : Sync {
|
|||
* @param collection target ns collection
|
||||
* @param dataPair data to upload (data.first) and id of changed record (data.second)
|
||||
* @param progress progress of sync in format "number/number". Only for display in fragment
|
||||
* @return true for successful upload
|
||||
*/
|
||||
fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package info.nightscout.interfaces.workflow
|
||||
|
||||
import androidx.work.ListenableWorker
|
||||
|
||||
interface WorkerClasses {
|
||||
val nsClientSourceWorker: Class<out ListenableWorker>
|
||||
val nsProfileWorker: Class<out ListenableWorker>
|
||||
// val nsProfileWorker: Class<out ListenableWorker>
|
||||
}
|
|
@ -119,7 +119,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getSgvs()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -132,7 +136,11 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = eTag, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = eTag,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -143,39 +151,37 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getSgvsNewerThan(from, limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
override suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
override suspend fun createSgv(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteEntry = nsSgvV3.toRemoteEntry()
|
||||
remoteEntry.app = "AAPS"
|
||||
val response = api.createEntry(remoteEntry)
|
||||
val responseBody = response.body()
|
||||
val errorResponse = response.errorBody()?.string()
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = responseBody?.result?.identifier,
|
||||
isDeduplication = responseBody?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = responseBody?.result?.deduplicatedIdentifier,
|
||||
lastModified = responseBody?.result?.lastModified
|
||||
identifier = responseBody?.identifier,
|
||||
isDeduplication = responseBody?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = responseBody?.deduplicatedIdentifier,
|
||||
lastModified = responseBody?.lastModified
|
||||
)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("Bad or missing utcOffset field") == true && nsSgvV3.utcOffset != 0L) {
|
||||
// Record can be originally uploaded without utcOffset
|
||||
// because utcOffset is mandatory and cannot be change, try 0
|
||||
nsSgvV3.utcOffset = 0
|
||||
return@callWrapper createSvg(nsSgvV3)
|
||||
return@callWrapper createSgv(nsSgvV3)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("cannot be modified by the client") == true) {
|
||||
// there is different field to field in AAPS
|
||||
// not possible to upload
|
||||
|
@ -234,7 +240,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getTreatmentsNewerThan(createdAt, limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -273,22 +283,13 @@ class NSAndroidClientImpl(
|
|||
nsDeviceStatus.app = "AAPS"
|
||||
val response = api.createDeviceStatus(nsDeviceStatus.toRemoteDeviceStatus())
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier
|
||||
?: throw UnknownResponseNightscoutException(),
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnknownResponseNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -307,19 +308,13 @@ class NSAndroidClientImpl(
|
|||
remoteTreatment.app = "AAPS"
|
||||
val response = api.createTreatment(remoteTreatment)
|
||||
val errorResponse = response.errorBody()?.string()
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("Bad or missing utcOffset field") == true && nsTreatment.utcOffset != 0L) {
|
||||
// Record can be originally uploaded without utcOffset
|
||||
|
@ -384,7 +379,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getFoods(limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteFood::toNSFood).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteFood::toNSFood).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -410,21 +409,13 @@ class NSAndroidClientImpl(
|
|||
remoteFood.app = "AAPS"
|
||||
val response = api.createFood(remoteFood)
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -474,21 +465,13 @@ class NSAndroidClientImpl(
|
|||
remoteProfileStore.put("app", "AAPS")
|
||||
val response = api.createProfile(JsonParser.parseString(remoteProfileStore.toString()).asJsonObject)
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -514,7 +497,6 @@ class NSAndroidClientImpl(
|
|||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getProfileModifiedSince(from: Long): NSAndroidClient.ReadResponse<List<JSONObject>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getProfileModifiedSince(from)
|
||||
|
@ -528,7 +510,6 @@ class NSAndroidClientImpl(
|
|||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
|
||||
private suspend fun <T> callWrapper(dispatcher: CoroutineDispatcher, block: suspend () -> T): T =
|
||||
withContext(dispatcher) {
|
||||
retry(
|
||||
|
|
|
@ -25,7 +25,7 @@ interface NSAndroidClient {
|
|||
suspend fun getSgvs(): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsModifiedSince(from: Long, limit: Int): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsNewerThan(from: Long, limit: Int): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun createSgv(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
|
||||
suspend fun getTreatmentsNewerThan(createdAt: String, limit: Int): ReadResponse<List<NSTreatment>>
|
||||
|
|
|
@ -48,7 +48,7 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getSgvsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteEntry>>>
|
||||
|
||||
@POST("v3/entries")
|
||||
suspend fun createEntry(@Body remoteEntry: RemoteEntry): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createEntry(@Body remoteEntry: RemoteEntry): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/entries/{identifier}")
|
||||
suspend fun updateEntry(@Body remoteEntry: RemoteEntry, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
@ -63,16 +63,16 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getTreatmentsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteTreatment>>>
|
||||
|
||||
@POST("v3/treatments")
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/treatments/{identifier}")
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment, @Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@DELETE("v3/treatments/{identifier}")
|
||||
suspend fun deleteTreatment(@Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun deleteTreatment(@Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@POST("v3/devicestatus")
|
||||
suspend fun createDeviceStatus(@Body remoteDeviceStatus: RemoteDeviceStatus): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createDeviceStatus(@Body remoteDeviceStatus: RemoteDeviceStatus): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@GET("v3/devicestatus/history/{from}")
|
||||
suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>>
|
||||
|
@ -85,13 +85,13 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getFoodsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteFood>>>
|
||||
*/
|
||||
@POST("v3/food")
|
||||
suspend fun createFood(@Body remoteFood: RemoteFood): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createFood(@Body remoteFood: RemoteFood): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/food")
|
||||
suspend fun updateFood(@Body remoteFood: RemoteFood, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun updateFood(@Body remoteFood: RemoteFood, @Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@DELETE("v3/food")
|
||||
suspend fun deleteFood(@Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun deleteFood(@Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@GET("v3/profile/history/{from}")
|
||||
suspend fun getProfileModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int = 10): Response<NSResponse<List<JSONObject>>>
|
||||
|
@ -100,8 +100,7 @@ internal interface NightscoutRemoteService {
|
|||
@GET("v3/profile?sort\$desc=date&limit=1")
|
||||
suspend fun getLastProfile(): Response<NSResponse<List<JSONObject>>>
|
||||
|
||||
|
||||
@POST("v3/profile")
|
||||
suspend fun createProfile(@Body profile: JsonObject): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createProfile(@Body profile: JsonObject): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,28 @@ object OKDialog {
|
|||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun show(context: Context, title: String, message: Spanned, runnable: Runnable? = null) {
|
||||
var okClicked = false
|
||||
var notEmptyTitle = title
|
||||
if (notEmptyTitle.isEmpty()) notEmptyTitle = context.getString(R.string.message)
|
||||
|
||||
MaterialAlertDialogBuilder(context, R.style.DialogTheme)
|
||||
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, notEmptyTitle))
|
||||
.setMessage(message)
|
||||
.setPositiveButton(context.getString(R.string.ok)) { dialog: DialogInterface, _: Int ->
|
||||
if (okClicked) return@setPositiveButton
|
||||
else {
|
||||
okClicked = true
|
||||
dialog.dismiss()
|
||||
SystemClock.sleep(100)
|
||||
runOnUiThread(runnable)
|
||||
}
|
||||
}
|
||||
.show()
|
||||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun show(activity: FragmentActivity, title: String, message: Spanned, runnable: Runnable? = null) {
|
||||
var okClicked = false
|
||||
|
|
|
@ -620,4 +620,9 @@
|
|||
<item quantity="other">%1$d minutes</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Maintenance-->
|
||||
<string name="cleanup_db_confirm">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.</string>
|
||||
<string name="cleanup_db_confirm_sync">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.\nDoing it will speedup full synchronization dramatically.</string>
|
||||
<string name="cleared_entries">Cleared entries</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -150,10 +150,8 @@ import kotlin.math.roundToInt
|
|||
database.glucoseValueDao.getModifiedFrom(lastId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastGlucoseValueIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastGlucoseValueId(): Long? =
|
||||
database.glucoseValueDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
fun getLastGlucoseValueWrapped(): Single<ValueWrapper<GlucoseValue>> =
|
||||
database.glucoseValueDao.getLast()
|
||||
|
@ -233,10 +231,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllTempTargetEntries() =
|
||||
database.temporaryTargetDao.deleteAllEntries()
|
||||
|
||||
fun getLastTempTargetIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTempTargetId(): Long? =
|
||||
database.temporaryTargetDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// USER ENTRY
|
||||
fun getAllUserEntries(): Single<List<UserEntry>> =
|
||||
|
@ -309,10 +305,8 @@ import kotlin.math.roundToInt
|
|||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastProfileSwitchIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastProfileSwitchId(): Long? =
|
||||
database.profileSwitchDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// EFFECTIVE PROFILE SWITCH
|
||||
/*
|
||||
|
@ -368,10 +362,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllEffectiveProfileSwitches() =
|
||||
database.effectiveProfileSwitchDao.deleteAllEntries()
|
||||
|
||||
fun getLastEffectiveProfileSwitchIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastEffectiveProfileSwitchId(): Long? =
|
||||
database.effectiveProfileSwitchDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// THERAPY EVENT
|
||||
/*
|
||||
|
@ -435,10 +427,8 @@ import kotlin.math.roundToInt
|
|||
database.therapyEventDao.compatGetTherapyEventDataFromToTime(from, to)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastTherapyEventIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTherapyEventId(): Long? =
|
||||
database.therapyEventDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// FOOD
|
||||
/*
|
||||
|
@ -471,10 +461,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllFoods() =
|
||||
database.foodDao.deleteAllEntries()
|
||||
|
||||
fun getLastFoodIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastFoodId(): Long? =
|
||||
database.foodDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// BOLUS
|
||||
/*
|
||||
|
@ -539,10 +527,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllBoluses() =
|
||||
database.bolusDao.deleteAllEntries()
|
||||
|
||||
fun getLastBolusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastBolusId(): Long? =
|
||||
database.bolusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
// CARBS
|
||||
|
||||
private fun expandCarbs(carbs: Carbs): List<Carbs> =
|
||||
|
@ -656,10 +642,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllCarbs() =
|
||||
database.carbsDao.deleteAllEntries()
|
||||
|
||||
fun getLastCarbsIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastCarbsId(): Long? =
|
||||
database.carbsDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// BOLUS CALCULATOR RESULT
|
||||
/*
|
||||
|
@ -698,10 +682,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllBolusCalculatorResults() =
|
||||
database.bolusCalculatorResultDao.deleteAllEntries()
|
||||
|
||||
fun getLastBolusCalculatorResultIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastBolusCalculatorResultId(): Long? =
|
||||
database.bolusCalculatorResultDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// DEVICE STATUS
|
||||
fun insert(deviceStatus: DeviceStatus): Long =
|
||||
|
@ -723,10 +705,8 @@ import kotlin.math.roundToInt
|
|||
database.deviceStatusDao.getModifiedFrom(lastId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastDeviceStatusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastDeviceStatusId(): Long? =
|
||||
database.deviceStatusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// TEMPORARY BASAL
|
||||
/*
|
||||
|
@ -789,10 +769,8 @@ import kotlin.math.roundToInt
|
|||
fun getOldestTemporaryBasalRecord(): TemporaryBasal? =
|
||||
database.temporaryBasalDao.getOldestRecord()
|
||||
|
||||
fun getLastTemporaryBasalIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTemporaryBasalId(): Long? =
|
||||
database.temporaryBasalDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// EXTENDED BOLUS
|
||||
/*
|
||||
|
@ -847,10 +825,8 @@ import kotlin.math.roundToInt
|
|||
fun getOldestExtendedBolusRecord(): ExtendedBolus? =
|
||||
database.extendedBolusDao.getOldestRecord()
|
||||
|
||||
fun getLastExtendedBolusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastExtendedBolusId(): Long? =
|
||||
database.extendedBolusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// TotalDailyDose
|
||||
fun getLastTotalDailyDoses(count: Int, ascending: Boolean): Single<List<TotalDailyDose>> =
|
||||
|
@ -918,10 +894,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllOfflineEventEntries() =
|
||||
database.offlineEventDao.deleteAllEntries()
|
||||
|
||||
fun getLastOfflineEventIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastOfflineEventId(): Long? =
|
||||
database.offlineEventDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
suspend fun collectNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int) = NewEntries(
|
||||
apsResults = database.apsResultDao.getNewEntriesSince(since, until, limit, offset),
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface BolusCalculatorResultDao : TraceableDao<BolusCalculatorResult
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_BOLUS_CALCULATOR_RESULTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): BolusCalculatorResult?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface BolusDao : TraceableDao<Bolus> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_BOLUSES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_BOLUSES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): Bolus?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface CarbsDao : TraceableDao<Carbs> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_CARBS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CARBS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): Carbs?
|
||||
|
|
|
@ -29,7 +29,7 @@ internal interface DeviceStatusDao {
|
|||
fun deleteOlderThan(than: Long): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_DEVICE_STATUS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("DELETE FROM $TABLE_DEVICE_STATUS WHERE id NOT IN (SELECT MAX(id) FROM $TABLE_DEVICE_STATUS)")
|
||||
fun deleteAllEntriesExceptLast()
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface EffectiveProfileSwitchDao : TraceableDao<EffectiveProfileSwit
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): EffectiveProfileSwitch?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface ExtendedBolusDao : TraceableDao<ExtendedBolus> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_EXTENDED_BOLUSES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_EXTENDED_BOLUSES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): ExtendedBolus?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface FoodDao : TraceableDao<Food> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_FOODS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_FOODS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): Food?
|
||||
|
|
|
@ -26,7 +26,7 @@ internal interface GlucoseValueDao : TraceableDao<GlucoseValue> {
|
|||
fun getLast(): Maybe<GlucoseValue>
|
||||
|
||||
@Query("SELECT id FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_GLUCOSE_VALUES WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSIdMaybe(nsId: String): Maybe<GlucoseValue>
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface OfflineEventDao : TraceableDao<OfflineEvent> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_OFFLINE_EVENTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_OFFLINE_EVENTS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): OfflineEvent?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface ProfileSwitchDao : info.nightscout.database.impl.daos.workaro
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): ProfileSwitch?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface TemporaryBasalDao : TraceableDao<TemporaryBasal> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_TEMPORARY_BASALS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_TEMPORARY_BASALS WHERE temporaryId = :temporaryId")
|
||||
fun findByTempId(temporaryId: Long): TemporaryBasal?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface TemporaryTargetDao : TraceableDao<TemporaryTarget> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_TEMPORARY_TARGETS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_TEMPORARY_TARGETS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): TemporaryTarget?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface TherapyEventDao : TraceableDao<TherapyEvent> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_THERAPY_EVENTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_THERAPY_EVENTS WHERE type = :type AND timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(type: TherapyEvent.Type, timestamp: Long): TherapyEvent?
|
||||
|
|
|
@ -24,7 +24,7 @@ import info.nightscout.interfaces.plugin.OwnDatabasePlugin
|
|||
import info.nightscout.interfaces.protection.ProtectionCheck
|
||||
import info.nightscout.interfaces.protection.ProtectionCheck.Protection.PREFERENCES
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
|
@ -51,7 +51,7 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
@Inject lateinit var persistenceLayer: PersistenceLayer
|
||||
@Inject lateinit var protectionCheck: ProtectionCheck
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorXdrip: DataSyncSelectorXdrip
|
||||
@Inject lateinit var pumpSync: PumpSync
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var overviewData: OverviewData
|
||||
|
@ -93,7 +93,8 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
for (plugin in activePlugin.getSpecificPluginsListByInterface(OwnDatabasePlugin::class.java)) {
|
||||
(plugin as OwnDatabasePlugin).clearAllTables()
|
||||
}
|
||||
dataSyncSelector.resetToNextFullSync()
|
||||
activePlugin.activeNsClient?.dataSyncSelector?.resetToNextFullSync()
|
||||
dataSyncSelectorXdrip.resetToNextFullSync()
|
||||
pumpSync.connectNewPump()
|
||||
overviewData.reset()
|
||||
iobCobCalculator.ads.reset()
|
||||
|
@ -111,7 +112,7 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
binding.cleanupDb.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
var result = ""
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.maintenance), rh.gs(R.string.cleanup_db_confirm), Runnable {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.maintenance), rh.gs(info.nightscout.core.ui.R.string.cleanup_db_confirm), Runnable {
|
||||
disposable += Completable.fromAction { result = persistenceLayer.cleanupDatabase(93, deleteTrackedChanges = true) }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -119,8 +120,12 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
onError = { aapsLogger.error("Error cleaning up databases", it) },
|
||||
onComplete = {
|
||||
if (result.isNotEmpty())
|
||||
OKDialog.show(activity, rh.gs(info.nightscout.core.ui.R.string.result), HtmlHelper.fromHtml("<b>" + rh.gs(R.string.cleared_entries) + "</b><br>" + result)
|
||||
.toSpanned())
|
||||
OKDialog.show(
|
||||
activity,
|
||||
rh.gs(info.nightscout.core.ui.R.string.result),
|
||||
HtmlHelper.fromHtml("<b>" + rh.gs(info.nightscout.core.ui.R.string.cleared_entries) + "</b><br>" + result)
|
||||
.toSpanned()
|
||||
)
|
||||
aapsLogger.info(LTag.CORE, "Cleaned up databases with result: $result")
|
||||
}
|
||||
)
|
||||
|
|
|
@ -122,8 +122,6 @@
|
|||
<string name="maintenance_shortname">MAINT</string>
|
||||
<string name="description_maintenance">Provides several functions for maintenance (eg. log sending, log deletion).</string>
|
||||
<string name="database_cleanup">Database cleanup</string>
|
||||
<string name="cleanup_db_confirm">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.</string>
|
||||
<string name="cleared_entries">Cleared entries</string>
|
||||
<string name="reset_db_confirm">Do you really want to reset the databases?</string>
|
||||
<string name="maintenance_settings">Maintenance Settings</string>
|
||||
<string name="maintenance_email">Email recipient</string>
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
|
|||
FoodModule::class,
|
||||
SMSCommunicatorModule::class,
|
||||
ProfileModule::class,
|
||||
ProfileModule.Bindings::class,
|
||||
SkinsModule::class,
|
||||
SkinsUiModule::class,
|
||||
ActionsModule::class,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package info.nightscout.plugins.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.interfaces.profile.ProfileSource
|
||||
import info.nightscout.plugins.profile.ProfileFragment
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
|
||||
|
@ -9,6 +11,12 @@ import info.nightscout.plugins.profile.ProfilePlugin
|
|||
@Suppress("unused")
|
||||
abstract class ProfileModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): ProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds fun bindProfileSource(profilePlugin: ProfilePlugin): ProfileSource
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package info.nightscout.plugins.profile
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.extensions.blockFromJsonArray
|
||||
|
@ -11,8 +8,6 @@ import info.nightscout.core.extensions.pureProfileFromJson
|
|||
import info.nightscout.core.profile.ProfileSealed
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
|
@ -39,7 +34,6 @@ 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 kotlinx.coroutines.Dispatchers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
@ -234,7 +228,7 @@ class ProfilePlugin @Inject constructor(
|
|||
}
|
||||
|
||||
@Synchronized
|
||||
fun loadFromStore(store: ProfileStore) {
|
||||
override fun loadFromStore(store: ProfileStore) {
|
||||
try {
|
||||
val newProfiles: ArrayList<ProfileSource.SingleProfile> = ArrayList()
|
||||
for (p in store.getProfileList()) {
|
||||
|
@ -428,39 +422,4 @@ class ProfilePlugin @Inject constructor(
|
|||
get() = rawProfile?.getDefaultProfile()?.let {
|
||||
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
|
||||
} ?: "INVALID"
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var profilePlugin: ProfilePlugin
|
||||
@Inject lateinit var instantiator: Instantiator
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val profileJson = dataWorkerStorage.pickupJSONObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_store, true) || config.NSCLIENT) {
|
||||
val store = instantiator.provideProfileStore(profileJson)
|
||||
val createdAt = store.getStartDate()
|
||||
val lastLocalChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange")
|
||||
@Suppress("LiftReturnOrAssignment")
|
||||
if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS
|
||||
profilePlugin.loadFromStore(store)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
return Result.success(workDataOf("Data" to profileJson.toString().substring(0..Integer.min(5000, profileJson.length()))))
|
||||
} else
|
||||
return Result.success(workDataOf("Result" to "Unchanged. Ignoring"))
|
||||
}
|
||||
return Result.success(workDataOf("Result" to "Sync not enabled"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ import info.nightscout.rx.events.EventNewBG
|
|||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.extensions.toVisibility
|
||||
import info.nightscout.shared.extensions.toVisibilityKeepSpace
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
|
@ -135,7 +136,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
|
|||
|
||||
override fun onBindViewHolder(holder: GlucoseValuesViewHolder, position: Int) {
|
||||
val glucoseValue = glucoseValues[position]
|
||||
holder.binding.ns.visibility = (glucoseValue.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.ns.visibility = (glucoseValue.interfaceIDs.nightscoutId != null).toVisibilityKeepSpace()
|
||||
holder.binding.invalid.visibility = (!glucoseValue.isValid).toVisibility()
|
||||
val newDay = position == 0 || !dateUtil.isSameDay(glucoseValue.timestamp, glucoseValues[position - 1].timestamp)
|
||||
holder.binding.date.visibility = newDay.toVisibility()
|
||||
|
|
|
@ -1,38 +1,16 @@
|
|||
package info.nightscout.source
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSSgv
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
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.source.BgSource
|
||||
import info.nightscout.interfaces.source.DoingOwnUploadSource
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -49,21 +27,15 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
.pluginIcon(info.nightscout.core.main.R.drawable.ic_nsclient_bg)
|
||||
.pluginName(R.string.ns_client_bg)
|
||||
.shortName(R.string.ns_client_bg_short)
|
||||
.description(R.string.description_source_ns_client),
|
||||
.description(R.string.description_source_ns_client)
|
||||
.alwaysEnabled(config.NSCLIENT)
|
||||
.setDefault(config.NSCLIENT),
|
||||
aapsLogger, rh, injector
|
||||
), BgSource, NSClientSource, DoingOwnUploadSource {
|
||||
|
||||
private var lastBGTimeStamp: Long = 0
|
||||
private var isAdvancedFilteringEnabled = false
|
||||
|
||||
init {
|
||||
if (config.NSCLIENT) {
|
||||
pluginDescription
|
||||
.alwaysEnabled(true)
|
||||
.setDefault()
|
||||
}
|
||||
}
|
||||
|
||||
override fun advancedFilteringSupported(): Boolean = isAdvancedFilteringEnabled
|
||||
|
||||
override fun shouldUploadToNs(glucoseValue: GlucoseValue): Boolean = false
|
||||
|
@ -80,93 +52,4 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
lastBGTimeStamp = glucoseValue.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSClientSourceWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
private fun toGv(jsonObject: JSONObject): TransactionGlucoseValue? {
|
||||
val sgv = NSSgv(jsonObject)
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.mills ?: return null,
|
||||
value = sgv.mgdl?.toDouble() ?: return null,
|
||||
noise = null,
|
||||
raw = sgv.filtered?.toDouble(),
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction),
|
||||
nightscoutId = sgv.id,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device)
|
||||
)
|
||||
}
|
||||
|
||||
private fun toGv(sgv: NSSgvV3): TransactionGlucoseValue {
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.date ?: throw InvalidParameterException(),
|
||||
value = sgv.sgv,
|
||||
noise = sgv.noise,
|
||||
raw = sgv.filtered,
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
|
||||
nightscoutId = sgv.identifier,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device),
|
||||
isValid = sgv.isValid,
|
||||
utcOffset = T.mins(sgv.utcOffset ?: 0L).msecs()
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
val sgvs = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false))
|
||||
return Result.success(workDataOf("Result" to "Sync not enabled"))
|
||||
|
||||
var latestDateInReceivedData: Long = 0
|
||||
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvs")
|
||||
val glucoseValues = mutableListOf<TransactionGlucoseValue>()
|
||||
|
||||
try {
|
||||
if (sgvs is JSONArray) { // V1 client
|
||||
for (i in 0 until sgvs.length()) {
|
||||
val sgv = toGv(sgvs.getJSONObject(i)) ?: continue
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
|
||||
} else if (sgvs is List<*>) { // V3 client
|
||||
|
||||
for (i in 0 until sgvs.size) {
|
||||
val sgv = toGv(sgvs[i] as NSSgvV3)
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestBgReceivedIfNewer(latestDateInReceivedData)
|
||||
// Was that sgv more less 5 mins ago ?
|
||||
if (T.msecs(dateUtil.now() - latestDateInReceivedData).mins() < 5L) {
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
}
|
||||
|
||||
storeDataForDb.glucoseValues.addAll(glucoseValues)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
ret = Result.failure(workDataOf("Error" to e.toString()))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,6 @@ abstract class SourceModule {
|
|||
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesXdripWorker(): XdripSourcePlugin.XdripSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDexcomWorker(): DexcomPlugin.DexcomWorker
|
||||
@ContributesAndroidInjector abstract fun contributesMM640gWorker(): MM640gPlugin.MM640gWorker
|
||||
|
|
|
@ -11,10 +11,12 @@ import info.nightscout.interfaces.XDripBroadcast
|
|||
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.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorV1Impl
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl
|
||||
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
|
||||
import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
||||
|
@ -22,17 +24,10 @@ 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.LoadFoodsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadProfileStoreWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3Impl
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.*
|
||||
import info.nightscout.plugins.sync.tidepool.TidepoolFragment
|
||||
import info.nightscout.plugins.sync.xdrip.DataSyncSelectorXdripImpl
|
||||
import info.nightscout.plugins.sync.xdrip.XdripFragment
|
||||
import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
||||
import info.nightscout.plugins.sync.xdrip.workers.XdripDataSyncWorker
|
||||
|
@ -60,14 +55,9 @@ abstract class SyncModule {
|
|||
@ContributesAndroidInjector abstract fun contributesLoadBgWorker(): LoadBgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadFoodsWorker(): LoadFoodsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreTreatmentsWorker(): StoreDataForDbImpl.StoreTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDataSyncWorker(): DataSyncWorker
|
||||
@ContributesAndroidInjector abstract fun contributesFoodWorker(): ProcessFoodWorker
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
@ContributesAndroidInjector abstract fun contributesXdripFragment(): XdripFragment
|
||||
|
@ -85,7 +75,9 @@ abstract class SyncModule {
|
|||
|
||||
@Binds fun bindProcessedDeviceStatusData(processedDeviceStatusDataImpl: ProcessedDeviceStatusDataImpl): ProcessedDeviceStatusData
|
||||
@Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus
|
||||
@Binds fun bindDataSyncSelectorInterface(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
|
||||
@Binds fun bindDataSyncSelectorV1Interface(dataSyncSelectorV1Impl: DataSyncSelectorV1Impl): DataSyncSelectorV1
|
||||
@Binds fun bindDataSyncSelectorV3Interface(dataSyncSelectorV3Impl: DataSyncSelectorV3Impl): DataSyncSelectorV3
|
||||
@Binds fun bindDataSyncSelectorXdripInterface(dataSyncSelectorXdripImpl: DataSyncSelectorXdripImpl): DataSyncSelectorXdrip
|
||||
@Binds fun bindStoreDataForDb(storeDataForDbImpl: StoreDataForDbImpl): StoreDataForDb
|
||||
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XdripPlugin): XDripBroadcast
|
||||
}
|
||||
|
|
|
@ -1,36 +1,51 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ScrollView
|
||||
import androidx.core.text.toSpanned
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.database.entities.UserEntry
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.db.PersistenceLayer
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginFragment
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
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.databinding.NsClientLogItemBinding
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiInsert
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
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 io.reactivex.rxjava3.core.Completable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
||||
|
@ -40,11 +55,11 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var persistenceLayer: PersistenceLayer
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -61,11 +76,19 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var _binding: NsClientFragmentBinding? = null
|
||||
private lateinit var logAdapter: RecyclerViewAdapter
|
||||
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
// https://stackoverflow.com/questions/31759171/recyclerview-and-java-lang-indexoutofboundsexception-inconsistency-detected-in
|
||||
class FixedLinearLayoutManager(context: Context?, @RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL, reverseLayout: Boolean = false) :
|
||||
LinearLayoutManager(context, orientation, reverseLayout) {
|
||||
|
||||
override fun supportsPredictiveItemAnimations(): Boolean = false
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
NsClientFragmentBinding.inflate(inflater, container, false).also {
|
||||
_binding = it
|
||||
|
@ -78,15 +101,17 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
binding.autoscroll.isChecked = sp.getBoolean(R.string.key_ns_client_autoscroll, true)
|
||||
binding.autoscroll.setOnCheckedChangeListener { _, isChecked ->
|
||||
sp.putBoolean(R.string.key_ns_client_autoscroll, isChecked)
|
||||
updateGui()
|
||||
}
|
||||
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.paused.setOnCheckedChangeListener { _, isChecked ->
|
||||
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
|
||||
nsClientPlugin?.pause(isChecked)
|
||||
updateGui()
|
||||
}
|
||||
|
||||
logAdapter = RecyclerViewAdapter(nsClientPlugin?.listLog ?: emptyList())
|
||||
binding.recyclerview.layoutManager = FixedLinearLayoutManager(context)
|
||||
binding.recyclerview.adapter = logAdapter
|
||||
}
|
||||
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -100,7 +125,12 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
override fun onMenuItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
ID_MENU_CLEAR_LOG -> {
|
||||
nsClientPlugin?.clearLog()
|
||||
nsClientPlugin?.listLog?.let {
|
||||
synchronized(it) {
|
||||
logAdapter.notifyItemRangeRemoved(0, it.size)
|
||||
it.clear()
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -115,10 +145,40 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
}
|
||||
|
||||
ID_MENU_FULL_SYNC -> {
|
||||
var result = ""
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(
|
||||
context, rh.gs(R.string.ns_client), rh.gs(R.string.full_sync_comment),
|
||||
Runnable { nsClientPlugin?.resetToFullSync() }
|
||||
Runnable {
|
||||
OKDialog.showConfirmation(requireContext(), rh.gs(R.string.ns_client), rh.gs(info.nightscout.core.ui.R.string.cleanup_db_confirm_sync), Runnable {
|
||||
disposable += Completable.fromAction { result = persistenceLayer.cleanupDatabase(93, deleteTrackedChanges = true) }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error cleaning up databases", it) },
|
||||
onComplete = {
|
||||
if (result.isNotEmpty())
|
||||
OKDialog.show(
|
||||
requireContext(),
|
||||
rh.gs(info.nightscout.core.ui.R.string.result),
|
||||
HtmlHelper.fromHtml("<b>" + rh.gs(info.nightscout.core.ui.R.string.cleared_entries) + "</b><br>" + result)
|
||||
.toSpanned()
|
||||
)
|
||||
aapsLogger.info(LTag.CORE, "Cleaned up databases with result: $result")
|
||||
handler.post {
|
||||
nsClientPlugin?.resetToFullSync()
|
||||
nsClientPlugin?.resend("FULL_SYNC")
|
||||
}
|
||||
}
|
||||
)
|
||||
uel.log(UserEntry.Action.CLEANUP_DATABASES, UserEntry.Sources.NSClient)
|
||||
}, Runnable {
|
||||
handler.post {
|
||||
nsClientPlugin?.resetToFullSync()
|
||||
nsClientPlugin?.resend("FULL_SYNC")
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
true
|
||||
|
@ -127,28 +187,78 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
else -> false
|
||||
}
|
||||
|
||||
@Synchronized override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGUI::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||
updateGui()
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
@Synchronized override fun onPause() {
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiInsert::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe(
|
||||
{
|
||||
logAdapter.notifyItemInserted(it.position)
|
||||
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true))
|
||||
_binding?.recyclerview?.scrollToPosition(it.position)
|
||||
nsClientPlugin?.listLog?.let { listLog ->
|
||||
synchronized(listLog) {
|
||||
if (listLog.size > Constants.MAX_LOG_LINES)
|
||||
logAdapter.notifyItemRemoved(listLog.size - 1)
|
||||
}
|
||||
}
|
||||
}, fabricPrivacy::logException
|
||||
)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiQueue::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateQueue() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiStatus::class.java)
|
||||
.debounce(3L, TimeUnit.SECONDS)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateStatus() }, fabricPrivacy::logException)
|
||||
updateStatus()
|
||||
updateQueue()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun updateGui() {
|
||||
private fun updateQueue() {
|
||||
val size = nsClientPlugin?.dataSyncSelector?.queueSize() ?: 0L
|
||||
_binding?.queue?.text = if (size >= 0) size.toString() else rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
|
||||
}
|
||||
|
||||
private fun updateStatus() {
|
||||
if (_binding == null) return
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.log.text = nsClientPlugin?.textLog()
|
||||
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
//if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
binding.url.text = nsClientPlugin?.address
|
||||
binding.status.text = nsClientPlugin?.status
|
||||
val size = dataSyncSelector.queueSize()
|
||||
binding.queue.text = if (size >= 0) size.toString() else rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
|
||||
}
|
||||
|
||||
private inner class RecyclerViewAdapter(private var logList: List<EventNSClientNewLog>) : RecyclerView.Adapter<RecyclerViewAdapter.NsClientLogViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NsClientLogViewHolder =
|
||||
NsClientLogViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.ns_client_log_item, viewGroup, false))
|
||||
|
||||
override fun onBindViewHolder(holder: NsClientLogViewHolder, position: Int) {
|
||||
holder.binding.logText.text = HtmlHelper.fromHtml(logList[position].toPreparedHtml().toString())
|
||||
}
|
||||
|
||||
override fun getItemCount() = logList.size
|
||||
|
||||
inner class NsClientLogViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = NsClientLogItemBinding.bind(view)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.extensions.foodFromJson
|
||||
import info.nightscout.database.entities.Food
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSSgv
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.profile.ProfileSource
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.*
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.food.NSFood
|
||||
import info.nightscout.sdk.localmodel.treatment.*
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class NsIncomingDataProcessor @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val nsClientSource: NSClientSource,
|
||||
private val sp: SP,
|
||||
private val rxBus: RxBus,
|
||||
private val dateUtil: DateUtil,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val storeDataForDb: StoreDataForDb,
|
||||
private val config: Config,
|
||||
private val instantiator: Instantiator,
|
||||
private val profileSource: ProfileSource
|
||||
) {
|
||||
|
||||
private fun toGv(jsonObject: JSONObject): TransactionGlucoseValue? {
|
||||
val sgv = NSSgv(jsonObject)
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.mills ?: return null,
|
||||
value = sgv.mgdl?.toDouble() ?: return null,
|
||||
noise = null,
|
||||
raw = sgv.filtered?.toDouble(),
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction),
|
||||
nightscoutId = sgv.id,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device)
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
fun processSgvs(sgvs: Any) {
|
||||
|
||||
if (!nsClientSource.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false)) return
|
||||
|
||||
var latestDateInReceivedData: Long = 0
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Received NS Data: $sgvs")
|
||||
val glucoseValues = mutableListOf<TransactionGlucoseValue>()
|
||||
|
||||
if (sgvs is JSONArray) { // V1 client
|
||||
for (i in 0 until sgvs.length()) {
|
||||
val sgv = toGv(sgvs.getJSONObject(i)) ?: continue
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
} else if (sgvs is List<*>) { // V3 client
|
||||
|
||||
for (i in 0 until sgvs.size) {
|
||||
val sgv = (sgvs[i] as NSSgvV3).toTransactionGlucoseValue()
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestBgReceivedIfNewer(latestDateInReceivedData)
|
||||
// Was that sgv more less 5 mins ago ?
|
||||
if (T.msecs(dateUtil.now() - latestDateInReceivedData).mins() < 5L) {
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
}
|
||||
storeDataForDb.glucoseValues.addAll(glucoseValues)
|
||||
}
|
||||
|
||||
fun processTreatments(treatments: List<NSTreatment>) {
|
||||
try {
|
||||
var latestDateInReceivedData: Long = 0
|
||||
for (treatment in treatments) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
val date = treatment.date ?: continue
|
||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||
|
||||
when (treatment) {
|
||||
is NSBolus ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_insulin, false) || config.NSCLIENT)
|
||||
storeDataForDb.boluses.add(treatment.toBolus())
|
||||
|
||||
is NSCarbs ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_carbs, false) || config.NSCLIENT)
|
||||
storeDataForDb.carbs.add(treatment.toCarbs())
|
||||
|
||||
is NSTemporaryTarget ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_temp_target, false) || config.NSCLIENT) {
|
||||
if (treatment.duration > 0L) {
|
||||
// not ending event
|
||||
if (treatment.targetBottomAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > treatment.targetTopAsMgdl()
|
||||
) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Ignored TemporaryTarget $treatment")
|
||||
continue
|
||||
}
|
||||
}
|
||||
storeDataForDb.temporaryTargets.add(treatment.toTemporaryTarget())
|
||||
}
|
||||
|
||||
is NSTemporaryBasal ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
storeDataForDb.temporaryBasals.add(treatment.toTemporaryBasal())
|
||||
|
||||
is NSEffectiveProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toEffectiveProfileSwitch(dateUtil)?.let { effectiveProfileSwitch ->
|
||||
storeDataForDb.effectiveProfileSwitches.add(effectiveProfileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toProfileSwitch(activePlugin, dateUtil)?.let { profileSwitch ->
|
||||
storeDataForDb.profileSwitches.add(profileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSBolusWizard ->
|
||||
treatment.toBolusCalculatorResult()?.let { bolusCalculatorResult ->
|
||||
storeDataForDb.bolusCalculatorResults.add(bolusCalculatorResult)
|
||||
}
|
||||
|
||||
is NSTherapyEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
treatment.toTherapyEvent().let { therapyEvent ->
|
||||
storeDataForDb.therapyEvents.add(therapyEvent)
|
||||
}
|
||||
|
||||
is NSOfflineEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_offline_event, false) && config.isEngineeringMode() || config.NSCLIENT)
|
||||
treatment.toOfflineEvent().let { offlineEvent ->
|
||||
storeDataForDb.offlineEvents.add(offlineEvent)
|
||||
}
|
||||
|
||||
is NSExtendedBolus ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
treatment.toExtendedBolus().let { extendedBolus ->
|
||||
storeDataForDb.extendedBoluses.add(extendedBolus)
|
||||
}
|
||||
}
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
}
|
||||
}
|
||||
|
||||
fun processFood(data: Any) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received Food Data: $data")
|
||||
|
||||
try {
|
||||
val foods = mutableListOf<Food>()
|
||||
if (data is JSONArray) {
|
||||
for (index in 0 until data.length()) {
|
||||
val jsonFood: JSONObject = data.getJSONObject(index)
|
||||
|
||||
if (JsonHelper.safeGetString(jsonFood, "type") != "food") continue
|
||||
|
||||
when (JsonHelper.safeGetString(jsonFood, "action")) {
|
||||
"remove" -> {
|
||||
val delFood = Food(
|
||||
name = "",
|
||||
portion = 0.0,
|
||||
carbs = 0,
|
||||
isValid = false
|
||||
).also { it.interfaceIDs.nightscoutId = JsonHelper.safeGetString(jsonFood, "_id") }
|
||||
foods += delFood
|
||||
}
|
||||
|
||||
else -> {
|
||||
val food = foodFromJson(jsonFood)
|
||||
if (food != null) foods += food
|
||||
else aapsLogger.error(LTag.DATABASE, "Error parsing food", jsonFood.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (data is List<*>) {
|
||||
for (i in 0 until data.size)
|
||||
foods += (data[i] as NSFood).toFood()
|
||||
}
|
||||
storeDataForDb.foods.addAll(foods)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
}
|
||||
}
|
||||
|
||||
fun processProfile(profileJson: JSONObject) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_store, true) || config.NSCLIENT) {
|
||||
val store = instantiator.provideProfileStore(profileJson)
|
||||
val createdAt = store.getStartDate()
|
||||
val lastLocalChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange")
|
||||
@Suppress("LiftReturnOrAssignment")
|
||||
if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS
|
||||
profileSource.loadFromStore(store)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import android.content.Context
|
||||
import android.os.SystemClock
|
||||
import androidx.work.WorkerParameters
|
||||
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
|
||||
|
@ -60,7 +57,6 @@ import info.nightscout.rx.logging.AAPSLogger
|
|||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -119,45 +115,6 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
private val pause = 1000L // to slow down db operations
|
||||
|
||||
class StoreBgWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreFoodWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreTreatmentsWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> HashMap<T, Long>.inc(key: T) =
|
||||
if (containsKey(key)) merge(key, 1, Long::plus)
|
||||
else put(key, 1)
|
||||
|
@ -803,6 +760,8 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||
private var scheduledEventPost: ScheduledFuture<*>? = null
|
||||
|
||||
@Synchronized
|
||||
override fun scheduleNsIdUpdate() {
|
||||
class PostRunnable : Runnable {
|
||||
|
||||
|
@ -818,7 +777,8 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
|
||||
}
|
||||
|
||||
private fun updateNsIds() {
|
||||
@Synchronized
|
||||
override fun updateNsIds() {
|
||||
repository.runTransactionForResult(UpdateNsIdTemporaryTargetTransaction(nsIdTemporaryTargets))
|
||||
.doOnError { error ->
|
||||
aapsLogger.error(LTag.DATABASE, "Updated nsId of TemporaryTarget failed", error)
|
||||
|
@ -1003,27 +963,27 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
private fun sendLog(item: String, clazz: String) {
|
||||
inserted[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("INSERT", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ INSERT", "$item $it"))
|
||||
}
|
||||
inserted.remove(clazz)
|
||||
updated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("UPDATE", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ UPDATE", "$item $it"))
|
||||
}
|
||||
updated.remove(clazz)
|
||||
invalidated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("INVALIDATE", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ INVALIDATE", "$item $it"))
|
||||
}
|
||||
invalidated.remove(clazz)
|
||||
nsIdUpdated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("NS_ID", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ NS_ID", "$item $it"))
|
||||
}
|
||||
nsIdUpdated.remove(clazz)
|
||||
durationUpdated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("DURATION", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DURATION", "$item $it"))
|
||||
}
|
||||
durationUpdated.remove(clazz)
|
||||
ended[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("CUT", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ CUT", "$item $it"))
|
||||
}
|
||||
ended.remove(clazz)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGuiInsert(val position: Int) : EventUpdateGui()
|
|
@ -2,4 +2,4 @@ package info.nightscout.plugins.sync.nsShared.events
|
|||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGUI : EventUpdateGui()
|
||||
class EventNSClientUpdateGuiQueue : EventUpdateGui()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGuiStatus : EventUpdateGui()
|
|
@ -1,12 +1,15 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.database.ValueWrapper
|
||||
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.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -15,14 +18,15 @@ import javax.inject.Inject
|
|||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class DataSyncSelectorImplementation @Inject constructor(
|
||||
class DataSyncSelectorV1Impl @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val appRepository: AppRepository
|
||||
) : DataSyncSelector {
|
||||
private val appRepository: AppRepository,
|
||||
private val rxBus: RxBus
|
||||
) : DataSyncSelectorV1 {
|
||||
|
||||
class QueueCounter(
|
||||
var bolusesRemaining: Long = -1L,
|
||||
|
@ -61,8 +65,23 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override fun doUpload() {
|
||||
override suspend fun doUpload() {
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
|
||||
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
processChangedBoluses()
|
||||
processChangedCarbs()
|
||||
processChangedBolusCalculatorResults()
|
||||
|
@ -78,6 +97,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
processChangedOfflineEvents()
|
||||
processChangedProfileStore()
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
|
@ -95,8 +115,8 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
sp.remove(R.string.key_ns_offline_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||
|
||||
val lastDeviceStatusDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
if (lastDeviceStatusDbIdWrapped is ValueWrapper.Existing) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbIdWrapped.value)
|
||||
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
|
||||
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
|
||||
else sp.remove(R.string.key_ns_device_status_last_synced_id)
|
||||
}
|
||||
|
||||
|
@ -107,16 +127,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedBoluses() {
|
||||
override tailrec suspend fun processChangedBoluses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bolusesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ")
|
||||
when {
|
||||
|
@ -136,18 +156,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
bolus.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
|
||||
" $startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId")
|
||||
// with nsId = update if it's modified record
|
||||
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -160,16 +172,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedCarbs() {
|
||||
override tailrec suspend fun processChangedCarbs() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastCarbsId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.carbsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ")
|
||||
when {
|
||||
|
@ -209,16 +221,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedBolusCalculatorResults() {
|
||||
override tailrec suspend fun processChangedBolusCalculatorResults() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bcrRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ")
|
||||
when {
|
||||
|
@ -238,17 +250,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", 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?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -261,16 +266,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTempTargets() {
|
||||
override tailrec suspend fun processChangedTempTargets() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ttsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ")
|
||||
when {
|
||||
|
@ -290,18 +295,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
tt.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
|
||||
// existing with nsId = update
|
||||
tt.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -314,16 +311,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedFoods() {
|
||||
override tailrec suspend fun processChangedFoods() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastFoodId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.foodsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ")
|
||||
when {
|
||||
|
@ -346,11 +343,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
food.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"food",
|
||||
DataSyncSelector.PairFood(food.first, food.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -363,16 +356,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedGlucoseValues() {
|
||||
override tailrec suspend fun processChangedGlucoseValues() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.gvsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ")
|
||||
if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) {
|
||||
|
@ -396,11 +389,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
else -> // gv.first.interfaceIDs.nightscoutId != null
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"entries",
|
||||
DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
} else {
|
||||
confirmLastGlucoseValueIdIfGreater(gv.second.id)
|
||||
|
@ -417,16 +406,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTherapyEvents() {
|
||||
override tailrec suspend fun processChangedTherapyEvents() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ")
|
||||
when {
|
||||
|
@ -449,11 +438,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
|
||||
// nsId = update
|
||||
te.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTherapyEvent(te.first, te.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -466,16 +451,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun processChangedDeviceStatuses() {
|
||||
override suspend fun processChangedDeviceStatuses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.dssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
|
||||
when {
|
||||
|
@ -496,16 +481,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTemporaryBasals() {
|
||||
override tailrec suspend fun processChangedTemporaryBasals() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tbrsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ")
|
||||
when {
|
||||
|
@ -525,18 +510,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
tb.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
tb.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -549,16 +526,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedExtendedBoluses() {
|
||||
override tailrec suspend fun processChangedExtendedBoluses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ebsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ")
|
||||
val profile = profileFunction.getProfile(eb.first.timestamp)
|
||||
|
@ -580,18 +557,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
eb.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
eb.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
} else {
|
||||
|
@ -610,16 +579,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedProfileSwitches() {
|
||||
override tailrec suspend fun processChangedProfileSwitches() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.pssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
|
@ -642,11 +611,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -659,16 +624,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedEffectiveProfileSwitches() {
|
||||
override tailrec suspend fun processChangedEffectiveProfileSwitches() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.epssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
|
@ -688,18 +653,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -712,16 +669,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedOfflineEvents() {
|
||||
override tailrec suspend fun processChangedOfflineEvents() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.oesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ")
|
||||
when {
|
||||
|
@ -744,11 +701,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
|
||||
// existing with nsId = update
|
||||
oe.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -758,7 +711,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
override fun processChangedProfileStore() {
|
||||
override suspend 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)
|
|
@ -4,10 +4,7 @@ import android.content.ComponentName
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.IBinder
|
||||
import android.text.Spanned
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreference
|
||||
|
@ -25,15 +22,15 @@ 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.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper.fromHtml
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
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.nsShared.events.EventNSClientUpdateGuiInsert
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclient.data.AlarmAck
|
||||
import info.nightscout.plugins.sync.nsclient.extensions.toJson
|
||||
import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
||||
|
@ -65,8 +62,7 @@ class NSClientPlugin @Inject constructor(
|
|||
private val sp: SP,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val dataSyncSelector: DataSyncSelector,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val dataSyncSelectorV1: DataSyncSelectorV1,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
|
@ -84,8 +80,8 @@ class NSClientPlugin @Inject constructor(
|
|||
) {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
private val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val dataSyncSelector: DataSyncSelector get() = dataSyncSelectorV1
|
||||
override var status = ""
|
||||
var nsClientService: NSClientService? = null
|
||||
val isAllowed: Boolean
|
||||
|
@ -102,7 +98,7 @@ class NSClientPlugin @Inject constructor(
|
|||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event ->
|
||||
status = event.getStatus(context)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
// Pass to setup wizard
|
||||
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
||||
}, fabricPrivacy::logException)
|
||||
|
@ -159,37 +155,17 @@ class NSClientPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun clearLog() {
|
||||
handler.post {
|
||||
synchronized(listLog) { listLog.clear() }
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
}
|
||||
|
||||
override fun detectedNsVersion(): String = nsSettingsStatus.getVersion()
|
||||
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
listLog.add(0, ev)
|
||||
rxBus.send(EventNSClientUpdateGuiInsert(0))
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(0)
|
||||
listLog.removeAt(listLog.size - 1)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
|
||||
override fun textLog(): Spanned {
|
||||
try {
|
||||
val newTextLog = StringBuilder()
|
||||
synchronized(listLog) {
|
||||
for (log in listLog) newTextLog.append(log.toPreparedHtml())
|
||||
}
|
||||
return fromHtml(newTextLog.toString())
|
||||
} catch (e: OutOfMemoryError) {
|
||||
uiInteraction.showToastAndNotification(context, "Out of memory!\nStop using this phone !!!", info.nightscout.core.ui.R.raw.error)
|
||||
}
|
||||
return fromHtml("")
|
||||
}
|
||||
|
||||
override fun resend(reason: String) {
|
||||
|
@ -229,7 +205,7 @@ class NSClientPlugin @Inject constructor(
|
|||
dataSyncSelector.resetToNextFullSync()
|
||||
}
|
||||
|
||||
override fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean {
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
|
||||
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
|
||||
|
@ -249,9 +225,10 @@ class NSClientPlugin @Inject constructor(
|
|||
}?.let { data ->
|
||||
nsClientService?.dbAdd(collection, data, dataPair, progress)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean {
|
||||
val id = when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.interfaceIDs.nightscoutId
|
||||
is DataSyncSelector.PairCarbs -> dataPair.value.interfaceIDs.nightscoutId
|
||||
|
@ -284,5 +261,6 @@ class NSClientPlugin @Inject constructor(
|
|||
}?.let { data ->
|
||||
nsClientService?.dbUpdate(collection, id, data, dataPair, progress)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -24,16 +24,16 @@ import info.nightscout.interfaces.Config
|
|||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.nsclient.NSSettingsStatus
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.JsonHelper.safeGetString
|
||||
import info.nightscout.interfaces.utils.JsonHelper.safeGetStringAllowNull
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
|
||||
|
@ -42,16 +42,9 @@ import info.nightscout.plugins.sync.nsclient.data.AlarmAck
|
|||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
import info.nightscout.rx.events.EventConfigBuilderChange
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
import info.nightscout.rx.events.EventNewHistoryData
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.*
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
||||
|
@ -64,14 +57,19 @@ import io.reactivex.rxjava3.kotlin.plusAssign
|
|||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import io.socket.emitter.Emitter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.net.URISyntaxException
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSClientService : DaggerService() {
|
||||
@Suppress("SpellCheckingInspection") class NSClientService : DaggerService() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
@ -86,10 +84,11 @@ class NSClientService : DaggerService() {
|
|||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uiInteraction: UiInteraction
|
||||
@Inject lateinit var workerClasses: WorkerClasses
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -99,6 +98,7 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
private var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private val binder: IBinder = LocalBinder()
|
||||
|
@ -196,12 +196,12 @@ class NSClientService : DaggerService() {
|
|||
isConnected = true
|
||||
hasWriteAuth = ack.write && ack.writeTreatment
|
||||
rxBus.send(EventNSClientStatus(connectionStatus))
|
||||
rxBus.send(EventNSClientNewLog("AUTH", connectionStatus))
|
||||
rxBus.send(EventNSClientNewLog("◄ AUTH", connectionStatus))
|
||||
if (!ack.write) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write permission not granted "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Write permission not granted "))
|
||||
}
|
||||
if (!ack.writeTreatment) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write treatment permission not granted "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Write treatment permission not granted "))
|
||||
}
|
||||
if (!hasWriteAuth) {
|
||||
val noWritePerm = Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, rh.gs(R.string.no_write_permission), Notification.URGENT)
|
||||
|
@ -227,14 +227,14 @@ class NSClientService : DaggerService() {
|
|||
@Suppress("DEPRECATION")
|
||||
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
||||
rxBus.send(EventNSClientStatus("Initializing"))
|
||||
if (nsClientPlugin.isAllowed != true) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
|
||||
if (!nsClientPlugin.isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", nsClientPlugin.blockingReason))
|
||||
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
|
||||
} else if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientStatus("Paused"))
|
||||
} else if (!nsEnabled) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disabled"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "disabled"))
|
||||
rxBus.send(EventNSClientStatus("Disabled"))
|
||||
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
|
||||
try {
|
||||
|
@ -243,7 +243,7 @@ class NSClientService : DaggerService() {
|
|||
socket = IO.socket(nsURL, opt).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnect)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "do connect"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "do connect"))
|
||||
socket.connect()
|
||||
socket.on("dataUpdate", onDataUpdate)
|
||||
socket.on("announcement", onAnnouncement)
|
||||
|
@ -252,17 +252,17 @@ class NSClientService : DaggerService() {
|
|||
socket.on("clear_alarm", onClearAlarm)
|
||||
}
|
||||
} catch (e: URISyntaxException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
} catch (e: RuntimeException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
}
|
||||
} else if (nsURL.lowercase(Locale.getDefault()).startsWith("http://")) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "NS URL not encrypted"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "NS URL not encrypted"))
|
||||
rxBus.send(EventNSClientStatus("Not encrypted"))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "No NS URL specified"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "No NS URL specified"))
|
||||
rxBus.send(EventNSClientStatus("Not configured"))
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ class NSClientService : DaggerService() {
|
|||
private val onConnect = Emitter.Listener {
|
||||
connectCounter++
|
||||
val socketId = socket?.id() ?: "NULL"
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "connect #$connectCounter event. ID: $socketId"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "connect #$connectCounter event. ID: $socketId"))
|
||||
if (socket != null) sendAuthMessage(NSAuthAck(rxBus))
|
||||
watchdog()
|
||||
}
|
||||
|
@ -284,16 +284,16 @@ class NSClientService : DaggerService() {
|
|||
reconnections.remove(r)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " minutes: " + reconnections.size + "/" + WATCHDOG_MAX_CONNECTIONS))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " minutes: " + reconnections.size + "/" + WATCHDOG_MAX_CONNECTIONS))
|
||||
if (reconnections.size >= WATCHDOG_MAX_CONNECTIONS) {
|
||||
val n = Notification(Notification.NS_MALFUNCTION, rh.gs(R.string.ns_malfunction), Notification.URGENT)
|
||||
rxBus.send(EventNewNotification(n))
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "pausing for $WATCHDOG_RECONNECT_IN minutes"))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "pausing for $WATCHDOG_RECONNECT_IN minutes"))
|
||||
nsClientPlugin.pause(true)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
Thread {
|
||||
SystemClock.sleep(mins(WATCHDOG_RECONNECT_IN.toLong()).msecs())
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "re-enabling NSClient"))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "re-enabling NSClient"))
|
||||
nsClientPlugin.pause(false)
|
||||
}.start()
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ class NSClientService : DaggerService() {
|
|||
|
||||
private val onDisconnect = Emitter.Listener { args ->
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect reason: {}", *args)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disconnect event"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "disconnect event"))
|
||||
}
|
||||
|
||||
@Synchronized fun destroy() {
|
||||
|
@ -313,7 +313,7 @@ class NSClientService : DaggerService() {
|
|||
socket?.off("alarm")
|
||||
socket?.off("urgent_alarm")
|
||||
socket?.off("clear_alarm")
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "destroy"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "destroy"))
|
||||
isConnected = false
|
||||
hasWriteAuth = false
|
||||
socket?.disconnect()
|
||||
|
@ -332,7 +332,7 @@ class NSClientService : DaggerService() {
|
|||
aapsLogger.error("Unhandled exception", e)
|
||||
return
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("AUTH", "requesting auth"))
|
||||
rxBus.send(EventNSClientNewLog("► AUTH", "requesting auth"))
|
||||
socket?.emit("authorize", authMessage, ack)
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,7 @@ class NSClientService : DaggerService() {
|
|||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("CLEARALARM", "received"))
|
||||
rxBus.send(EventNSClientNewLog("◄ CLEARALARM", "received"))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
|
@ -428,30 +428,26 @@ class NSClientService : DaggerService() {
|
|||
try {
|
||||
// delta means only increment/changes are coming
|
||||
val isDelta = data.has("delta")
|
||||
rxBus.send(EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + if (isDelta) " delta" else " full"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "Data packet #" + dataCounter++ + if (isDelta) " delta" else " full"))
|
||||
if (data.has("status")) {
|
||||
val status = data.getJSONObject("status")
|
||||
nsSettingsStatus.handleNewData(status)
|
||||
} else if (!isDelta) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Unsupported Nightscout version "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Unsupported Nightscout version "))
|
||||
}
|
||||
if (data.has("profiles")) {
|
||||
val profiles = data.getJSONArray("profiles")
|
||||
if (profiles.length() > 0) {
|
||||
// take the newest
|
||||
val profileStoreJson = profiles[profiles.length() - 1] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("PROFILE", "profile received"))
|
||||
dataWorkerStorage.enqueue(
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsProfileWorker)
|
||||
.setInputData(dataWorkerStorage.storeInputData(profileStoreJson))
|
||||
.build()
|
||||
)
|
||||
rxBus.send(EventNSClientNewLog("◄ PROFILE", "profile received"))
|
||||
nsIncomingDataProcessor.processProfile(profileStoreJson)
|
||||
}
|
||||
}
|
||||
if (data.has("treatments")) {
|
||||
val treatments = data.getJSONArray("treatments")
|
||||
val addedOrUpdatedTreatments = JSONArray()
|
||||
if (treatments.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"))
|
||||
if (treatments.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + treatments.length() + " treatments"))
|
||||
for (index in 0 until treatments.length()) {
|
||||
val jsonTreatment = treatments.getJSONObject(index)
|
||||
val action = safeGetStringAllowNull(jsonTreatment, "action", null)
|
||||
|
@ -507,7 +503,7 @@ class NSClientService : DaggerService() {
|
|||
|
||||
val devicestatuses = gson.fromJson(data.getString("devicestatus"), Array<NSDeviceStatus>::class.java)
|
||||
if (devicestatuses.isNotEmpty()) {
|
||||
rxBus.send(EventNSClientNewLog("DATA", "received " + devicestatuses.size + " device statuses"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "received " + devicestatuses.size + " device statuses"))
|
||||
nsDeviceStatusHandler.handleNewData(devicestatuses)
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
|
@ -516,19 +512,13 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
if (data.has("food")) {
|
||||
val foods = data.getJSONArray("food")
|
||||
if (foods.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + foods.length() + " foods"))
|
||||
dataWorkerStorage
|
||||
.beginUniqueWork(
|
||||
"ProcessFoods",
|
||||
OneTimeWorkRequest.Builder(ProcessFoodWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(foods))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreFoodWorker::class.java).build())
|
||||
.enqueue()
|
||||
if (foods.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + foods.length() + " foods"))
|
||||
nsIncomingDataProcessor.processFood(foods)
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
}
|
||||
if (data.has("mbgs")) {
|
||||
val mbgArray = data.getJSONArray("mbgs")
|
||||
if (mbgArray.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + mbgArray.length() + " mbgs"))
|
||||
if (mbgArray.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + mbgArray.length() + " mbgs"))
|
||||
dataWorkerStorage.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientMbgWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(mbgArray))
|
||||
|
@ -537,26 +527,20 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
if (data.has("cals")) {
|
||||
val cals = data.getJSONArray("cals")
|
||||
if (cals.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + cals.length() + " cals"))
|
||||
if (cals.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + cals.length() + " cals"))
|
||||
// Calibrations ignored
|
||||
}
|
||||
if (data.has("sgvs")) {
|
||||
val sgvs = data.getJSONArray("sgvs")
|
||||
if (sgvs.length() > 0) {
|
||||
rxBus.send(EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "received " + sgvs.length() + " sgvs"))
|
||||
// Objective0
|
||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||
dataWorkerStorage
|
||||
.beginUniqueWork(
|
||||
"ProcessBg",
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker)
|
||||
.setInputData(dataWorkerStorage.storeInputData(sgvs))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processSgvs(sgvs)
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
|
||||
rxBus.send(EventNSClientNewLog("◄ LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
|
@ -578,7 +562,7 @@ class NSClientService : DaggerService() {
|
|||
socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject))
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"► UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"" + _id + " " + data + progress
|
||||
)
|
||||
)
|
||||
|
@ -594,7 +578,7 @@ class NSClientService : DaggerService() {
|
|||
message.put("collection", collection)
|
||||
message.put("data", data)
|
||||
socket?.emit("dbAdd", message, NSAddAck(aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject))
|
||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress))
|
||||
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
|
@ -603,29 +587,22 @@ class NSClientService : DaggerService() {
|
|||
fun sendAlarmAck(alarmAck: AlarmAck) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
socket?.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime)
|
||||
rxBus.send(EventNSClientNewLog("ALARMACK ", alarmAck.level.toString() + " " + alarmAck.group + " " + alarmAck.silenceTime))
|
||||
rxBus.send(EventNSClientNewLog("► ALARMACK ", alarmAck.level.toString() + " " + alarmAck.group + " " + alarmAck.silenceTime))
|
||||
}
|
||||
|
||||
fun resend(reason: String) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
handler.post {
|
||||
if (socket?.connected() != true) return@post
|
||||
@Synchronized
|
||||
fun resend(reason: String) = runBlocking {
|
||||
if (!isConnected || !hasWriteAuth) return@runBlocking
|
||||
scope.async {
|
||||
if (socket?.connected() != true) return@async
|
||||
if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + (System.currentTimeMillis() - lastAckTime) / 1000L + " sec")
|
||||
return@post
|
||||
}
|
||||
// val powerManager = getSystemService(POWER_SERVICE) as PowerManager
|
||||
// val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
// "AndroidAPS:NSClientService_onDataUpdate")
|
||||
// wakeLock.acquire(mins(10).msecs())
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelector.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend ended: $reason"))
|
||||
} finally {
|
||||
// if (wakeLock.isHeld) wakeLock.release()
|
||||
}
|
||||
return@async
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelectorV1.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend ended: $reason"))
|
||||
}.join()
|
||||
}
|
||||
|
||||
fun restart() {
|
||||
|
@ -638,7 +615,7 @@ class NSClientService : DaggerService() {
|
|||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_announcements, defaultVal)) {
|
||||
val nsAlarm = NSAlarm(announcement)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
rxBus.send(EventNSClientNewLog("ANNOUNCEMENT", safeGetString(announcement, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ ANNOUNCEMENT", safeGetString(announcement, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, announcement.toString())
|
||||
}
|
||||
}
|
||||
|
@ -651,7 +628,7 @@ class NSClientService : DaggerService() {
|
|||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ALARM", safeGetString(alarm, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ ALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
@ -664,7 +641,7 @@ class NSClientService : DaggerService() {
|
|||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("URGENTALARM", safeGetString(alarm, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ URGENTALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
|
|||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
|
@ -39,7 +40,7 @@ class NSClientAddAckWorker(
|
|||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
@ -60,148 +61,148 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryTargets.add(pair.value)
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTempTargets()
|
||||
dataSyncSelectorV1.processChangedTempTargets()
|
||||
}
|
||||
|
||||
is PairGlucoseValue -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdGlucoseValues.add(pair.value)
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedGlucoseValues()
|
||||
dataSyncSelectorV1.processChangedGlucoseValues()
|
||||
}
|
||||
|
||||
is PairFood -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdFoods.add(pair.value)
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedFoods()
|
||||
dataSyncSelectorV1.processChangedFoods()
|
||||
}
|
||||
|
||||
is PairTherapyEvent -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTherapyEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTherapyEvents()
|
||||
dataSyncSelectorV1.processChangedTherapyEvents()
|
||||
}
|
||||
|
||||
is PairBolus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBoluses()
|
||||
dataSyncSelectorV1.processChangedBoluses()
|
||||
}
|
||||
|
||||
is PairCarbs -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdCarbs.add(pair.value)
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbs()
|
||||
dataSyncSelectorV1.processChangedCarbs()
|
||||
}
|
||||
|
||||
is PairBolusCalculatorResult -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBolusCalculatorResults.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResults()
|
||||
dataSyncSelectorV1.processChangedBolusCalculatorResults()
|
||||
}
|
||||
|
||||
is PairTemporaryBasal -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryBasals.add(pair.value)
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
dataSyncSelectorV1.processChangedTemporaryBasals()
|
||||
}
|
||||
|
||||
is PairExtendedBolus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdExtendedBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
dataSyncSelectorV1.processChangedExtendedBoluses()
|
||||
}
|
||||
|
||||
is PairProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedProfileSwitches()
|
||||
}
|
||||
|
||||
is PairEffectiveProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairDeviceStatus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdDeviceStatuses.add(pair.value)
|
||||
dataSyncSelector.confirmLastDeviceStatusIdIfGreater(pair.value.id)
|
||||
dataSyncSelectorV1.confirmLastDeviceStatusIdIfGreater(pair.value.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedDeviceStatuses()
|
||||
dataSyncSelectorV1.processChangedDeviceStatuses()
|
||||
}
|
||||
|
||||
is PairProfileStore -> {
|
||||
dataSyncSelector.confirmLastProfileStore(ack.originalObject.id)
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileStore " + ack.id))
|
||||
dataSyncSelectorV1.confirmLastProfileStore(ack.originalObject.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileStore " + ack.id))
|
||||
}
|
||||
|
||||
is PairOfflineEvent -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdOfflineEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedOfflineEvents()
|
||||
dataSyncSelectorV1.processChangedOfflineEvents()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.work.workDataOf
|
|||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairBolus
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairBolusCalculatorResult
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairCarbs
|
||||
|
@ -19,6 +18,7 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
|
|||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
|
@ -34,7 +34,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
|
@ -47,109 +47,109 @@ class NSClientUpdateRemoveAckWorker(
|
|||
when (ack.originalObject) {
|
||||
is PairTemporaryTarget -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryTarget" + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryTarget" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTempTargets()
|
||||
dataSyncSelectorV1.processChangedTempTargets()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairGlucoseValue -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked GlucoseValue " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked GlucoseValue " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedGlucoseValues()
|
||||
dataSyncSelectorV1.processChangedGlucoseValues()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairFood -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Food " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Food " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedFoods()
|
||||
dataSyncSelectorV1.processChangedFoods()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairTherapyEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TherapyEvent " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TherapyEvent " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTherapyEvents()
|
||||
dataSyncSelectorV1.processChangedTherapyEvents()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Bolus " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Bolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBoluses()
|
||||
dataSyncSelectorV1.processChangedBoluses()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairCarbs -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Carbs " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Carbs " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbs()
|
||||
dataSyncSelectorV1.processChangedCarbs()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairBolusCalculatorResult -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResults()
|
||||
dataSyncSelectorV1.processChangedBolusCalculatorResults()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairTemporaryBasal -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryBasal " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryBasal " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
dataSyncSelectorV1.processChangedTemporaryBasals()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairExtendedBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ExtendedBolus " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ExtendedBolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
dataSyncSelectorV1.processChangedExtendedBoluses()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ProfileSwitch " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedProfileSwitches()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairEffectiveProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairOfflineEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked OfflineEvent" + ack._id))
|
||||
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked OfflineEvent" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedOfflineEvents()
|
||||
dataSyncSelectorV1.processChangedOfflineEvents()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,695 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class DataSyncSelectorV3Impl @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val appRepository: AppRepository,
|
||||
private val rxBus: RxBus,
|
||||
private val storeDataForDb: StoreDataForDb
|
||||
) : DataSyncSelectorV3 {
|
||||
|
||||
class QueueCounter(
|
||||
var bolusesRemaining: Long = -1L,
|
||||
var carbsRemaining: Long = -1L,
|
||||
var bcrRemaining: Long = -1L,
|
||||
var ttsRemaining: Long = -1L,
|
||||
var foodsRemaining: Long = -1L,
|
||||
var gvsRemaining: Long = -1L,
|
||||
var tesRemaining: Long = -1L,
|
||||
var dssRemaining: Long = -1L,
|
||||
var tbrsRemaining: Long = -1L,
|
||||
var ebsRemaining: Long = -1L,
|
||||
var pssRemaining: Long = -1L,
|
||||
var epssRemaining: Long = -1L,
|
||||
var oesRemaining: Long = -1L
|
||||
) {
|
||||
|
||||
fun size(): Long =
|
||||
bolusesRemaining +
|
||||
carbsRemaining +
|
||||
bcrRemaining +
|
||||
ttsRemaining +
|
||||
foodsRemaining +
|
||||
gvsRemaining +
|
||||
tesRemaining +
|
||||
dssRemaining +
|
||||
tbrsRemaining +
|
||||
ebsRemaining +
|
||||
pssRemaining +
|
||||
epssRemaining +
|
||||
oesRemaining
|
||||
}
|
||||
|
||||
private val queueCounter = QueueCounter()
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override suspend fun doUpload() {
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
|
||||
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
processChangedGlucoseValues()
|
||||
processChangedBoluses()
|
||||
processChangedCarbs()
|
||||
processChangedBolusCalculatorResults()
|
||||
processChangedTemporaryBasals()
|
||||
processChangedExtendedBoluses()
|
||||
processChangedProfileSwitches()
|
||||
processChangedEffectiveProfileSwitches()
|
||||
processChangedTempTargets()
|
||||
processChangedFoods()
|
||||
processChangedTherapyEvents()
|
||||
processChangedDeviceStatuses()
|
||||
processChangedOfflineEvents()
|
||||
processChangedProfileStore()
|
||||
storeDataForDb.updateNsIds()
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
|
||||
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
|
||||
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
|
||||
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
|
||||
sp.remove(R.string.key_ns_food_last_synced_id)
|
||||
sp.remove(R.string.key_ns_bolus_last_synced_id)
|
||||
sp.remove(R.string.key_ns_carbs_last_synced_id)
|
||||
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
|
||||
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
|
||||
sp.remove(R.string.key_ns_effective_profile_switch_last_synced_id)
|
||||
sp.remove(R.string.key_ns_offline_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||
|
||||
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
|
||||
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
|
||||
else sp.remove(R.string.key_ns_device_status_last_synced_id)
|
||||
}
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedBoluses() {
|
||||
val lastDbId = appRepository.getLastBolusId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bolusesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
bolus.first.onlyNsIdAdded(bolus.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed: ${bolus.second.id} ")
|
||||
// without nsId = create new
|
||||
bolus.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId") ?: false
|
||||
// with nsId = update if it's modified record
|
||||
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastBolusIdIfGreater(bolus.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedCarbs() {
|
||||
val lastDbId = appRepository.getLastCarbsId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.carbsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
carb.first.onlyNsIdAdded(carb.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.second.id} ")
|
||||
// without nsId = create new
|
||||
carb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update if it's modified record
|
||||
carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastCarbsIdIfGreater(carb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedBolusCalculatorResults() {
|
||||
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bcrRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.second.id} ")
|
||||
// without nsId = create new
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
) ?: false
|
||||
// with nsId = update if it's modified record
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
) ?: false
|
||||
}
|
||||
confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTempTargets() {
|
||||
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ttsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
tt.first.onlyNsIdAdded(tt.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.second.id} ")
|
||||
// without nsId = create new
|
||||
tt.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") ?: false
|
||||
// existing with nsId = update
|
||||
tt.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTempTargetsIdIfGreater(tt.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedFoods() {
|
||||
val lastDbId = appRepository.getLastFoodId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.foodsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
food.first.onlyNsIdAdded(food.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.second.id} ")
|
||||
// without nsId = create new
|
||||
food.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
food.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastFoodIdIfGreater(food.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedGlucoseValues() {
|
||||
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.gvsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
|
||||
//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
|
||||
gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
gv.first.onlyNsIdAdded(gv.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.second.id} ")
|
||||
// without nsId = create new
|
||||
gv.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
else -> // gv.first.interfaceIDs.nightscoutId != null
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
}
|
||||
confirmLastGlucoseValueIdIfGreater(gv.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTherapyEvents() {
|
||||
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
te.first.onlyNsIdAdded(te.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.second.id} ")
|
||||
// without nsId = create new
|
||||
te.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") ?: false
|
||||
// nsId = update
|
||||
te.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTherapyEventIdIfGreater(te.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedDeviceStatuses() {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.dssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
|
||||
// without nsId = create new
|
||||
if (deviceStatus.interfaceIDs.nightscoutId == null) {
|
||||
if (activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId), "$startId/$lastDbId") == true)
|
||||
confirmLastDeviceStatusIdIfGreater(lastDbId)
|
||||
}
|
||||
// with nsId = ignore
|
||||
}
|
||||
queueCounter.dssRemaining = 0
|
||||
}
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTemporaryBasals() {
|
||||
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tbrsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
|
||||
//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} ")
|
||||
// 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} ")
|
||||
// without nsId = create new
|
||||
tb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
tb.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTemporaryBasalIdIfGreater(tb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedExtendedBoluses() {
|
||||
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ebsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
eb.first.onlyNsIdAdded(eb.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.second.id} ")
|
||||
// without nsId = create new
|
||||
eb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
eb.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
} else aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.second.id} ")
|
||||
confirmLastExtendedBolusIdIfGreater(eb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedProfileSwitches() {
|
||||
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.pssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
ps.first.onlyNsIdAdded(ps.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastProfileSwitchIdIfGreater(ps.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedEffectiveProfileSwitches() {
|
||||
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.epssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
ps.first.onlyNsIdAdded(ps.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedOfflineEvents() {
|
||||
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.oesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
|
||||
//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.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
oe.first.onlyNsIdAdded(oe.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.second.id} ")
|
||||
// without nsId = create new
|
||||
oe.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") ?: false
|
||||
// existing with nsId = update
|
||||
oe.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastOfflineEventIdIfGreater(oe.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long) {
|
||||
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
suspend 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 profileStore = activePlugin.activeProfileSource.profile
|
||||
val profileJson = profileStore?.data ?: return
|
||||
// add for v3
|
||||
if (JsonHelper.safeGetLongAllowNull(profileJson, "date") == null)
|
||||
profileJson.put("date", profileStore.getStartDate())
|
||||
val now = dateUtil.now()
|
||||
if (activePlugin.activeNsClient?.nsAdd("profile", DataSyncSelector.PairProfileStore(profileJson, now), "") == true)
|
||||
confirmLastProfileStore(now)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.SystemClock
|
||||
import android.text.Spanned
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreference
|
||||
|
@ -17,7 +16,6 @@ import com.google.gson.GsonBuilder
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
|
@ -25,23 +23,24 @@ import info.nightscout.interfaces.Config
|
|||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
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.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiInsert
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus
|
||||
|
@ -59,10 +58,12 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
|
|||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
|
||||
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.LoadFoodsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadProfileStoreWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
|
@ -90,18 +91,16 @@ import io.socket.client.Ack
|
|||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import io.socket.emitter.Emitter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.net.URISyntaxException
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class NSClientV3Plugin @Inject constructor(
|
||||
|
@ -117,14 +116,13 @@ class NSClientV3Plugin @Inject constructor(
|
|||
private val config: Config,
|
||||
private val dateUtil: DateUtil,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val dataSyncSelector: DataSyncSelector,
|
||||
private val dataSyncSelectorV3: DataSyncSelectorV3,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val repository: AppRepository,
|
||||
private val nsDeviceStatusHandler: NSDeviceStatusHandler,
|
||||
private val workManager: WorkManager,
|
||||
private val workerClasses: WorkerClasses,
|
||||
private val dataWorkerStorage: DataWorkerStorage,
|
||||
private val nsClientSource: NSClientSource
|
||||
private val nsClientSource: NSClientSource,
|
||||
private val nsIncomingDataProcessor: NsIncomingDataProcessor,
|
||||
private val storeDataForDb: StoreDataForDb
|
||||
) : NsClient, Sync, PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.SYNC)
|
||||
|
@ -146,10 +144,10 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private lateinit var runLoop: Runnable
|
||||
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
private val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val dataSyncSelector: DataSyncSelector get() = dataSyncSelectorV3
|
||||
override val status
|
||||
get() =
|
||||
when {
|
||||
|
@ -159,7 +157,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && !wsConnected -> "WS: " + rh.gs(R.string.not_connected)
|
||||
lastOperationError != null -> rh.gs(info.nightscout.core.ui.R.string.error)
|
||||
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
||||
workIsRunning() -> rh.gs(R.string.working)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
|
||||
else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
|
||||
|
@ -196,6 +194,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(EventNSClientNewLog("● CONNECTIVITY", ev.blockingReason))
|
||||
setClient("CONNECTIVITY")
|
||||
if (isAllowed) executeLoop("CONNECTIVITY", forceNew = false)
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
|
@ -290,10 +289,14 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
override val hasWritePermission: Boolean get() = nsAndroidClient?.lastStatus?.apiPermissions?.isFull() ?: false
|
||||
override val connected: Boolean get() = nsAndroidClient?.lastStatus != null
|
||||
override fun clearLog() {
|
||||
handler.post {
|
||||
synchronized(listLog) { listLog.clear() }
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(0, ev)
|
||||
rxBus.send(EventNSClientUpdateGuiInsert(0))
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(listLog.size - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,40 +436,21 @@ class NSClientV3Plugin @Inject constructor(
|
|||
when (collection) {
|
||||
"devicestatus" -> docString.toNSDeviceStatus().let { nsDeviceStatusHandler.handleNewData(arrayOf(it)) }
|
||||
"entries" -> docString.toNSSgvV3()?.let {
|
||||
workManager.beginUniqueWork(
|
||||
JOB_NAME + collection,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processSgvs(listOf(it))
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
}
|
||||
|
||||
"profile" ->
|
||||
workManager.enqueueUniqueWork(
|
||||
JOB_NAME + collection,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsProfileWorker).setInputData(dataWorkerStorage.storeInputData(docJson)).build()
|
||||
)
|
||||
nsIncomingDataProcessor.processProfile(docJson)
|
||||
|
||||
"treatments" -> docString.toNSTreatment()?.let {
|
||||
workManager.beginUniqueWork(
|
||||
JOB_NAME + collection,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processTreatments(listOf(it))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
}
|
||||
|
||||
"foods" -> docString.toNSFood()?.let {
|
||||
workManager.beginUniqueWork(
|
||||
JOB_NAME + collection,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessFoodWorker::class.java).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreFoodWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processFood(listOf(it))
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
}
|
||||
|
||||
"settings" -> {}
|
||||
|
@ -565,30 +549,6 @@ class NSClientV3Plugin @Inject constructor(
|
|||
WS code end
|
||||
**********************/
|
||||
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(0)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
|
||||
override fun textLog(): Spanned {
|
||||
try {
|
||||
val newTextLog = StringBuilder()
|
||||
synchronized(listLog) {
|
||||
for (log in listLog) newTextLog.append(log.toPreparedHtml())
|
||||
}
|
||||
return HtmlHelper.fromHtml(newTextLog.toString())
|
||||
} catch (e: OutOfMemoryError) {
|
||||
uiInteraction.showToastAndNotification(context, "Out of memory!\nStop using this phone !!!", info.nightscout.core.ui.R.raw.error)
|
||||
}
|
||||
return HtmlHelper.fromHtml("")
|
||||
}
|
||||
|
||||
override fun resend(reason: String) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true))
|
||||
executeUpload("RESEND", forceNew = false)
|
||||
|
@ -626,23 +586,26 @@ class NSClientV3Plugin @Inject constructor(
|
|||
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
||||
initialLoadFinished = false
|
||||
storeLastLoadedSrvModified()
|
||||
dataSyncSelector.resetToNextFullSync()
|
||||
dataSyncSelectorV3.resetToNextFullSync()
|
||||
}
|
||||
|
||||
override fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean =
|
||||
dbOperation(collection, dataPair, progress, Operation.CREATE)
|
||||
}
|
||||
|
||||
override fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean =
|
||||
dbOperation(collection, dataPair, progress, Operation.UPDATE)
|
||||
}
|
||||
|
||||
enum class Operation { CREATE, UPDATE }
|
||||
|
||||
private val gson: Gson = GsonBuilder().create()
|
||||
private fun dbOperationProfileStore(collection: String = "profile", dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
|
||||
private suspend fun slowDown() {
|
||||
if (sp.getBoolean(R.string.key_ns_sync_slow, false)) SystemClock.sleep(250)
|
||||
else SystemClock.sleep(10)
|
||||
}
|
||||
|
||||
private suspend fun dbOperationProfileStore(collection: String = "profile", dataPair: DataSyncSelector.DataPair, progress: String): Boolean {
|
||||
val data = (dataPair as DataSyncSelector.PairProfileStore).value
|
||||
scope.launch {
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>$data</i> $progress"))
|
||||
nsAndroidClient?.createProfileStore(data)?.let { result ->
|
||||
|
@ -653,27 +616,21 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "ProfileStore"))
|
||||
return@launch
|
||||
return true
|
||||
}
|
||||
}
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdDeviceStatuses.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastProfileStore(dataPair.id)
|
||||
dataSyncSelector.processChangedProfileStore()
|
||||
slowDown()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun dbOperationDeviceStatus(collection: String = "devicestatus", dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
|
||||
scope.launch {
|
||||
private suspend fun dbOperationDeviceStatus(collection: String = "devicestatus", dataPair: DataSyncSelector.PairDeviceStatus, progress: String): Boolean {
|
||||
try {
|
||||
val data = dataPair.value.toNSDeviceStatus()
|
||||
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"))
|
||||
nsAndroidClient?.createDeviceStatus(data)?.let { result ->
|
||||
when (result.response) {
|
||||
|
@ -683,35 +640,28 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
return true
|
||||
}
|
||||
}
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdDeviceStatuses.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastDeviceStatusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedDeviceStatuses()
|
||||
result.identifier?.let {
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdDeviceStatuses.add(dataPair.value)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun dbOperationEntries(collection: String = "entries", dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
private suspend fun dbOperationEntries(collection: String = "entries", dataPair: DataSyncSelector.PairGlucoseValue, progress: String, operation: Operation): Boolean {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createSvg }
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createSgv }
|
||||
Operation.UPDATE -> nsAndroidClient?.let { return@let it::updateSvg }
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toNSSvgV3()
|
||||
else -> null
|
||||
}?.let { data ->
|
||||
scope.launch {
|
||||
try {
|
||||
val id = if (dataPair.value is TraceableDBEntry) (dataPair.value as TraceableDBEntry).interfaceIDs.nightscoutId else ""
|
||||
val data = dataPair.value.toNSSvgV3()
|
||||
val id = dataPair.value.interfaceIDs.nightscoutId
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
|
@ -733,40 +683,30 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
return true
|
||||
}
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairGlucoseValue -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdGlucoseValues.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedGlucoseValues()
|
||||
}
|
||||
result.identifier?.let {
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdGlucoseValues.add(dataPair.value)
|
||||
}
|
||||
slowDown()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun dbOperationFood(collection: String = "food", dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
private suspend fun dbOperationFood(collection: String = "food", dataPair: DataSyncSelector.PairFood, progress: String, operation: Operation): Boolean {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createFood }
|
||||
Operation.UPDATE -> nsAndroidClient?.let { return@let it::updateFood }
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairFood -> dataPair.value.toNSFood()
|
||||
else -> null
|
||||
}?.let { data ->
|
||||
scope.launch {
|
||||
try {
|
||||
val id = if (dataPair.value is TraceableDBEntry) (dataPair.value as TraceableDBEntry).interfaceIDs.nightscoutId else ""
|
||||
val data = dataPair.value.toNSFood()
|
||||
val id = dataPair.value.interfaceIDs.nightscoutId
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
|
@ -788,29 +728,23 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
return true
|
||||
}
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairFood -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdFoods.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedFoods()
|
||||
}
|
||||
result.identifier?.let {
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdFoods.add(dataPair.value)
|
||||
}
|
||||
slowDown()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun dbOperationTreatments(collection: String = "treatments", dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
private suspend fun dbOperationTreatments(collection: String = "treatments", dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation): Boolean {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createTreatment }
|
||||
Operation.UPDATE -> nsAndroidClient?.let { return@let it::updateTreatment }
|
||||
|
@ -823,22 +757,12 @@ class NSClientV3Plugin @Inject constructor(
|
|||
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toNSTherapyEvent()
|
||||
|
||||
is DataSyncSelector.PairTemporaryBasal -> {
|
||||
val profile = profileFunction.getProfile(dataPair.value.timestamp)
|
||||
if (profile == null) {
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
return
|
||||
}
|
||||
val profile = profileFunction.getProfile(dataPair.value.timestamp) ?: return true
|
||||
dataPair.value.toNSTemporaryBasal(profile)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairExtendedBolus -> {
|
||||
val profile = profileFunction.getProfile(dataPair.value.timestamp)
|
||||
if (profile == null) {
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
return
|
||||
}
|
||||
val profile = profileFunction.getProfile(dataPair.value.timestamp) ?: return true
|
||||
dataPair.value.toNSExtendedBolus(profile)
|
||||
}
|
||||
|
||||
|
@ -847,7 +771,6 @@ class NSClientV3Plugin @Inject constructor(
|
|||
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toNSOfflineEvent()
|
||||
else -> null
|
||||
}?.let { data ->
|
||||
scope.launch {
|
||||
try {
|
||||
val id = if (dataPair.value is TraceableDBEntry) (dataPair.value as TraceableDBEntry).interfaceIDs.nightscoutId else ""
|
||||
rxBus.send(
|
||||
|
@ -871,126 +794,85 @@ class NSClientV3Plugin @Inject constructor(
|
|||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
return true
|
||||
}
|
||||
}
|
||||
result.identifier?.let {
|
||||
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)
|
||||
dataSyncSelector.processChangedBoluses()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdBoluses.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairCarbs -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdCarbs.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedCarbs()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdCarbs.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairBolusCalculatorResult -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdBolusCalculatorResults.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedBolusCalculatorResults()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdBolusCalculatorResults.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairTemporaryTarget -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdTemporaryTargets.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTempTargets()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdTemporaryTargets.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairTherapyEvent -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdTherapyEvents.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTherapyEvents()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdTherapyEvents.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairTemporaryBasal -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdTemporaryBasals.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdTemporaryBasals.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairExtendedBolus -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdExtendedBoluses.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdExtendedBoluses.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairProfileSwitch -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdProfileSwitches.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedProfileSwitches()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdProfileSwitches.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairEffectiveProfileSwitch -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdEffectiveProfileSwitches.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitches()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdEffectiveProfileSwitches.add(dataPair.value)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairOfflineEvent -> {
|
||||
// if (result.response == 201) { // created
|
||||
// dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
// storeDataForDb.nsIdOfflineEvents.add(dataPair.value)
|
||||
// storeDataForDb.scheduleNsIdUpdate()
|
||||
// }
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(dataPair.id)
|
||||
dataSyncSelector.processChangedOfflineEvents()
|
||||
dataPair.value.interfaceIDs.nightscoutId = it
|
||||
storeDataForDb.nsIdOfflineEvents.add(dataPair.value)
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw InvalidParameterException()
|
||||
}
|
||||
}
|
||||
}
|
||||
slowDown()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun dbOperation(collection: String, dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
private suspend fun dbOperation(collection: String, dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation): Boolean =
|
||||
when (collection) {
|
||||
"profile" -> dbOperationProfileStore(dataPair = dataPair, progress = progress)
|
||||
"devicestatus" -> dbOperationDeviceStatus(dataPair = dataPair, progress = progress)
|
||||
"entries" -> dbOperationEntries(dataPair = dataPair, progress = progress, operation = operation)
|
||||
"food" -> dbOperationFood(dataPair = dataPair, progress = progress, operation = operation)
|
||||
"devicestatus" -> dbOperationDeviceStatus(dataPair = dataPair as DataSyncSelector.PairDeviceStatus, progress = progress)
|
||||
"entries" -> dbOperationEntries(dataPair = dataPair as DataSyncSelector.PairGlucoseValue, progress = progress, operation = operation)
|
||||
"food" -> dbOperationFood(dataPair = dataPair as DataSyncSelector.PairFood, progress = progress, operation = operation)
|
||||
"treatments" -> dbOperationTreatments(dataPair = dataPair, progress = progress, operation = operation)
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun storeLastLoadedSrvModified() {
|
||||
|
@ -1007,13 +889,14 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(EventNSClientNewLog("● RUN", "$blockingReason $origin"))
|
||||
return
|
||||
}
|
||||
if (workIsRunning(arrayOf(JOB_NAME))) {
|
||||
if (workIsRunning()) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
|
||||
if (!forceNew) return
|
||||
// Wait for end and start new cycle
|
||||
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
|
||||
while (workIsRunning()) Thread.sleep(5000)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Starting next round $origin"))
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
JOB_NAME,
|
||||
|
@ -1022,12 +905,11 @@ class NSClientV3Plugin @Inject constructor(
|
|||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadLastModificationWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build())
|
||||
// Other Workers are enqueued after BG finish
|
||||
// LoadTreatmentsWorker
|
||||
// LoadFoodsWorker
|
||||
// LoadProfileStoreWorker
|
||||
// LoadDeviceStatusWorker
|
||||
// DataSyncWorker
|
||||
.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build())
|
||||
.enqueue()
|
||||
}
|
||||
|
||||
|
@ -1040,11 +922,11 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(EventNSClientNewLog("● RUN", blockingReason))
|
||||
return
|
||||
}
|
||||
if (workIsRunning(arrayOf(JOB_NAME))) {
|
||||
if (workIsRunning()) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
|
||||
if (!forceNew) return
|
||||
// Wait for end and start new cycle
|
||||
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
|
||||
while (workIsRunning()) Thread.sleep(5000)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Starting upload $origin"))
|
||||
WorkManager.getInstance(context)
|
||||
|
@ -1055,8 +937,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun workIsRunning(workNames: Array<String>): Boolean {
|
||||
for (workName in workNames)
|
||||
private fun workIsRunning(workName: String = JOB_NAME): Boolean {
|
||||
for (workInfo in WorkManager.getInstance(context).getWorkInfosForUniqueWork(workName).get())
|
||||
if (workInfo.state == WorkInfo.State.BLOCKED || workInfo.state == WorkInfo.State.ENQUEUED || workInfo.state == WorkInfo.State.RUNNING)
|
||||
return true
|
||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
import info.nightscout.shared.utils.T
|
||||
import java.security.InvalidParameterException
|
||||
|
||||
// copy of NSClientSourcePlugin for testing
|
||||
fun NSSgvV3.toTransactionGlucoseValue(): TransactionGlucoseValue {
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = date ?: throw InvalidParameterException(),
|
||||
|
|
|
@ -5,8 +5,7 @@ import androidx.work.WorkerParameters
|
|||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -18,7 +17,7 @@ class DataSyncWorker(
|
|||
context: Context, params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV3: DataSyncSelectorV3
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
@ -26,14 +25,13 @@ class DataSyncWorker(
|
|||
override suspend fun doWorkAndLog(): Result {
|
||||
if (activePlugin.activeNsClient?.hasWritePermission == true || nsClientV3Plugin.wsConnected) {
|
||||
rxBus.send(EventNSClientNewLog("► UPL", "Start"))
|
||||
dataSyncSelector.doUpload()
|
||||
dataSyncSelectorV3.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("► UPL", "End"))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("► ERROR", "Not connected or write permission"))
|
||||
// refresh token
|
||||
nsClientV3Plugin.scheduleIrregularExecution(refreshToken = true)
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
return Result.success()
|
||||
}
|
||||
}
|
|
@ -1,18 +1,13 @@
|
|||
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
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.core.utils.worker.then
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -29,29 +24,23 @@ class LoadBgWorker(
|
|||
context: Context, params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
@Inject lateinit var nsClientSource: NSClientSource
|
||||
@Inject lateinit var workerClasses: WorkerClasses
|
||||
@Inject lateinit var workManager: WorkManager
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
if (!nsClientSource.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false)) {
|
||||
workManager
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()
|
||||
)
|
||||
if (!nsClientSource.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false))
|
||||
return Result.success(workDataOf("Result" to "Load not enabled"))
|
||||
}
|
||||
|
||||
try {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var continueLoading = true
|
||||
try {
|
||||
while (continueLoading) {
|
||||
val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.ENTRIES)
|
||||
val lastLoaded =
|
||||
if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
|
@ -70,22 +59,13 @@ class LoadBgWorker(
|
|||
sgvs = response.values
|
||||
aapsLogger.debug(LTag.NSCLIENT, "SGVS: $sgvs")
|
||||
if (sgvs.isNotEmpty()) {
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
val action = if (isFirstLoad) "RCV-F" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog("◄ $action", "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Objective0
|
||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
val stopLoading = sgvs.size != NSClientV3Plugin.RECORDS_TO_LOAD || response.code == 304
|
||||
workManager
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build()
|
||||
)
|
||||
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
|
||||
.then(!stopLoading, OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build())
|
||||
.then(stopLoading, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.enqueue()
|
||||
continueLoading = !(sgvs.size != NSClientV3Plugin.RECORDS_TO_LOAD || response.code == 304)
|
||||
nsIncomingDataProcessor.processSgvs(sgvs)
|
||||
} else {
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
|
@ -93,14 +73,8 @@ class LoadBgWorker(
|
|||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
workManager
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.enqueue()
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
continueLoading = false
|
||||
}
|
||||
} else {
|
||||
// End first load
|
||||
|
@ -109,14 +83,9 @@ class LoadBgWorker(
|
|||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
workManager
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.enqueue()
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
continueLoading = false
|
||||
}
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
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
|
||||
|
@ -46,12 +43,6 @@ class LoadDeviceStatusWorker(
|
|||
} else {
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV DS END", "No data 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)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
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
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -24,12 +20,12 @@ class LoadFoodsWorker(
|
|||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
|
@ -42,24 +38,10 @@ class LoadFoodsWorker(
|
|||
aapsLogger.debug(LTag.NSCLIENT, "FOODS: $foods")
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV", "${foods.size} FOODs"))
|
||||
// Schedule processing of fetched data
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessFoodWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(foods))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreFoodWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processFood(foods)
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("● RCV FOOD", "skipped"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build()
|
||||
)
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
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
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -32,7 +29,7 @@ class LoadProfileStoreWorker(
|
|||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var workerClasses: WorkerClasses
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
|
@ -59,32 +56,12 @@ class LoadProfileStoreWorker(
|
|||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
aapsLogger.debug(LTag.NSCLIENT, "PROFILE: $profile")
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder((workerClasses.nsProfileWorker))
|
||||
.setInputData(dataWorkerStorage.storeInputData(profile))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processProfile(profile)
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build()
|
||||
)
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
|
@ -94,4 +71,5 @@ class LoadProfileStoreWorker(
|
|||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -28,9 +29,11 @@ class LoadStatusWorker(
|
|||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
nsClientV3Plugin.lastOperationError = null
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
return Result.success()
|
||||
}
|
||||
}
|
|
@ -1,17 +1,12 @@
|
|||
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
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.core.utils.worker.then
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -28,17 +23,19 @@ class LoadTreatmentsWorker(
|
|||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
|
||||
var continueLoading = true
|
||||
try {
|
||||
while (continueLoading) {
|
||||
val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.TREATMENTS)
|
||||
val lastLoaded =
|
||||
if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
|
@ -58,22 +55,11 @@ class LoadTreatmentsWorker(
|
|||
treatments = response.values
|
||||
aapsLogger.debug(LTag.NSCLIENT, "TREATMENTS: $treatments")
|
||||
if (treatments.isNotEmpty()) {
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
val action = if (isFirstLoad) "RCV-F" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog("◄ $action", "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
val stopLoading = treatments.size != NSClientV3Plugin.RECORDS_TO_LOAD || response.code == 304
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(response.values))
|
||||
.build()
|
||||
)
|
||||
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
|
||||
.then(!stopLoading, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.then(stopLoading, OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.enqueue()
|
||||
continueLoading = !(treatments.size != NSClientV3Plugin.RECORDS_TO_LOAD || response.code == 304)
|
||||
nsIncomingDataProcessor.processTreatments(response.values)
|
||||
} else {
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
|
@ -81,14 +67,8 @@ class LoadTreatmentsWorker(
|
|||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.enqueue()
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
continueLoading = false
|
||||
}
|
||||
} else {
|
||||
// End first load
|
||||
|
@ -97,14 +77,9 @@ class LoadTreatmentsWorker(
|
|||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.enqueue()
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
continueLoading = false
|
||||
}
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.workers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.extensions.foodFromJson
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.Food
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toFood
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.food.NSFood
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProcessFoodWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
aapsLogger.debug(LTag.DATABASE, "Received Food Data: $data")
|
||||
|
||||
try {
|
||||
val foods = mutableListOf<Food>()
|
||||
if (data is JSONArray) {
|
||||
for (index in 0 until data.length()) {
|
||||
val jsonFood: JSONObject = data.getJSONObject(index)
|
||||
|
||||
if (JsonHelper.safeGetString(jsonFood, "type") != "food") continue
|
||||
|
||||
when (JsonHelper.safeGetString(jsonFood, "action")) {
|
||||
"remove" -> {
|
||||
val delFood = Food(
|
||||
name = "",
|
||||
portion = 0.0,
|
||||
carbs = 0,
|
||||
isValid = false
|
||||
).also { it.interfaceIDs.nightscoutId = JsonHelper.safeGetString(jsonFood, "_id") }
|
||||
foods += delFood
|
||||
}
|
||||
|
||||
else -> {
|
||||
val food = foodFromJson(jsonFood)
|
||||
if (food != null) foods += food
|
||||
else aapsLogger.error(LTag.DATABASE, "Error parsing food", jsonFood.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (data is List<*>) {
|
||||
for (i in 0 until data.size)
|
||||
foods += (data[i] as NSFood).toFood()
|
||||
}
|
||||
storeDataForDb.foods.addAll(foods)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.workers
|
||||
|
||||
import android.content.Context
|
||||
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.impl.AppRepository
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toBolus
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toBolusCalculatorResult
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toCarbs
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toEffectiveProfileSwitch
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toExtendedBolus
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toOfflineEvent
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toProfileSwitch
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toTemporaryBasal
|
||||
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.events.EventNSClientNewLog
|
||||
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.sdk.localmodel.treatment.NSTreatment
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProcessTreatmentsWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List<NSTreatment>?
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
try {
|
||||
var latestDateInReceivedData: Long = 0
|
||||
for (treatment in treatments) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
val date = treatment.date ?: continue
|
||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||
|
||||
when (treatment) {
|
||||
is NSBolus ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_insulin, false) || config.NSCLIENT)
|
||||
storeDataForDb.boluses.add(treatment.toBolus())
|
||||
|
||||
is NSCarbs ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_carbs, false) || config.NSCLIENT)
|
||||
storeDataForDb.carbs.add(treatment.toCarbs())
|
||||
|
||||
is NSTemporaryTarget ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_temp_target, false) || config.NSCLIENT) {
|
||||
if (treatment.duration > 0L) {
|
||||
// not ending event
|
||||
if (treatment.targetBottomAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > treatment.targetTopAsMgdl()
|
||||
) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Ignored TemporaryTarget $treatment")
|
||||
continue
|
||||
}
|
||||
}
|
||||
storeDataForDb.temporaryTargets.add(treatment.toTemporaryTarget())
|
||||
}
|
||||
|
||||
is NSTemporaryBasal ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
storeDataForDb.temporaryBasals.add(treatment.toTemporaryBasal())
|
||||
|
||||
is NSEffectiveProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toEffectiveProfileSwitch(dateUtil)?.let { effectiveProfileSwitch ->
|
||||
storeDataForDb.effectiveProfileSwitches.add(effectiveProfileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toProfileSwitch(activePlugin, dateUtil)?.let { profileSwitch ->
|
||||
storeDataForDb.profileSwitches.add(profileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSBolusWizard ->
|
||||
treatment.toBolusCalculatorResult()?.let { bolusCalculatorResult ->
|
||||
storeDataForDb.bolusCalculatorResults.add(bolusCalculatorResult)
|
||||
}
|
||||
|
||||
is NSTherapyEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
treatment.toTherapyEvent().let { therapyEvent ->
|
||||
storeDataForDb.therapyEvents.add(therapyEvent)
|
||||
}
|
||||
|
||||
is NSOfflineEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_offline_event, false) && config.isEngineeringMode() || config.NSCLIENT)
|
||||
treatment.toOfflineEvent().let { offlineEvent ->
|
||||
storeDataForDb.offlineEvents.add(offlineEvent)
|
||||
}
|
||||
|
||||
is NSExtendedBolus ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
treatment.toExtendedBolus().let { extendedBolus ->
|
||||
storeDataForDb.extendedBoluses.add(extendedBolus)
|
||||
}
|
||||
}
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData)
|
||||
// xDripBroadcast.sendTreatments(treatments)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.plugins.sync.tidepool.utils
|
||||
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import javax.inject.Inject
|
||||
|
@ -21,7 +20,7 @@ class RateLimit @Inject constructor(
|
|||
// check if over limit
|
||||
rateLimits[name]?.let {
|
||||
if (dateUtil.now() - it < T.secs(seconds.toLong()).msecs()) {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "$name rate limited: $seconds seconds")
|
||||
//aapsLogger.debug(LTag.TIDEPOOL, "$name rate limited: $seconds seconds")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package info.nightscout.plugins.sync.xdrip
|
||||
|
||||
import dagger.Lazy
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -18,7 +18,7 @@ import javax.inject.Inject
|
|||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class XdripDataSyncSelectorImplementation @Inject constructor(
|
||||
class DataSyncSelectorXdripImpl @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val dateUtil: DateUtil,
|
||||
|
@ -26,7 +26,7 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
private val activePlugin: ActivePlugin,
|
||||
private val xdripBroadcast: Lazy<XDripBroadcast>,
|
||||
private val appRepository: AppRepository
|
||||
) : DataSyncSelector {
|
||||
) : DataSyncSelectorXdrip {
|
||||
|
||||
class QueueCounter(
|
||||
var bolusesRemaining: Long = -1L,
|
||||
|
@ -72,7 +72,7 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override fun doUpload() {
|
||||
override suspend fun doUpload() {
|
||||
if (isEnabled) {
|
||||
processChangedGlucoseValues()
|
||||
processChangedBoluses()
|
||||
|
@ -113,22 +113,21 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sp.remove(R.string.key_xdrip_offline_event_last_synced_id)
|
||||
sp.remove(R.string.key_xdrip_profile_store_last_synced_timestamp)
|
||||
|
||||
val lastDeviceStatusDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
if (lastDeviceStatusDbIdWrapped is ValueWrapper.Existing) sp.putLong(R.string.key_xdrip_device_status_last_synced_id, lastDeviceStatusDbIdWrapped.value)
|
||||
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
|
||||
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_xdrip_device_status_last_synced_id, lastDeviceStatusDbId)
|
||||
else sp.remove(R.string.key_xdrip_device_status_last_synced_id)
|
||||
}
|
||||
|
||||
override fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_glucose_value_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting GlucoseValue data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_glucose_value_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedGlucoseValues() {
|
||||
private fun processChangedGlucoseValues() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_glucose_value_last_synced_id, 0)
|
||||
|
@ -170,17 +169,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting Bolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedBoluses() {
|
||||
private fun processChangedBoluses() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_bolus_last_synced_id, 0)
|
||||
|
@ -201,17 +199,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_carbs_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting Carbs data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_carbs_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedCarbs() {
|
||||
private fun processChangedCarbs() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastCarbsId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_carbs_last_synced_id, 0)
|
||||
|
@ -232,17 +229,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_bolus_calculator_result_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting BolusCalculatorResult data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_bolus_calculator_result_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedBolusCalculatorResults() {
|
||||
private fun processChangedBolusCalculatorResults() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_bolus_calculator_result_last_synced_id, 0)
|
||||
|
@ -263,17 +259,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_temporary_target_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting TemporaryTarget data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_temporary_target_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedTempTargets() {
|
||||
private fun processChangedTempTargets() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_temporary_target_last_synced_id, 0)
|
||||
|
@ -294,17 +289,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastFoodIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_food_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting Food data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_food_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedFoods() {
|
||||
private fun processChangedFoods() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastFoodId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_food_last_synced_id, 0)
|
||||
|
@ -324,17 +318,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendFoods(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_therapy_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting TherapyEvents data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_therapy_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedTherapyEvents() {
|
||||
private fun processChangedTherapyEvents() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_therapy_event_last_synced_id, 0)
|
||||
|
@ -355,16 +348,15 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_device_status_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting DeviceStatus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_device_status_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedDeviceStatuses() {
|
||||
val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
private fun processChangedDeviceStatuses() {
|
||||
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_device_status_last_synced_id, 0)
|
||||
|
@ -382,17 +374,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_temporary_basal_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting TemporaryBasal data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_temporary_basal_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedTemporaryBasals() {
|
||||
private fun processChangedTemporaryBasals() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_temporary_basal_last_synced_id, 0)
|
||||
|
@ -413,17 +404,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_extended_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting ExtendedBolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_extended_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedExtendedBoluses() {
|
||||
private fun processChangedExtendedBoluses() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_extended_bolus_last_synced_id, 0)
|
||||
|
@ -447,17 +437,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting ProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedProfileSwitches() {
|
||||
private fun processChangedProfileSwitches() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_profile_switch_last_synced_id, 0)
|
||||
|
@ -478,17 +467,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_effective_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting EffectiveProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_effective_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedEffectiveProfileSwitches() {
|
||||
private fun processChangedEffectiveProfileSwitches() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_effective_profile_switch_last_synced_id, 0)
|
||||
|
@ -509,17 +497,16 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_xdrip_offline_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.XDRIP, "Setting OfflineEvent data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_xdrip_offline_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processChangedOfflineEvents() {
|
||||
private fun processChangedOfflineEvents() {
|
||||
var progress: String
|
||||
val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
|
||||
while (true) {
|
||||
if (!isEnabled) return
|
||||
var startId = sp.getLong(R.string.key_xdrip_offline_event_last_synced_id, 0)
|
||||
|
@ -540,11 +527,11 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
sendTreatments(force = true, progress)
|
||||
}
|
||||
|
||||
override fun confirmLastProfileStore(lastSynced: Long) {
|
||||
fun confirmLastProfileStore(lastSynced: Long) {
|
||||
sp.putLong(R.string.key_xdrip_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
override fun processChangedProfileStore() {
|
||||
private fun processChangedProfileStore() {
|
||||
if (!isEnabled) return
|
||||
val lastSync = sp.getLong(R.string.key_xdrip_profile_store_last_synced_timestamp, 0)
|
||||
val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
|
@ -556,7 +543,10 @@ class XdripDataSyncSelectorImplementation @Inject constructor(
|
|||
// add for v3
|
||||
if (JsonHelper.safeGetLongAllowNull(profileJson, "date") == null)
|
||||
profileJson.put("date", profileStore.getStartDate())
|
||||
xdripPlugin.sendToXdrip("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
|
||||
val now = dateUtil.now()
|
||||
xdripPlugin.sendToXdrip("profile", DataSyncSelector.PairProfileStore(profileJson, now), "")
|
||||
confirmLastProfileStore(now)
|
||||
processChangedProfileStore()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ class XdripFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dataSyncSelector: XdripDataSyncSelectorImplementation
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelectorXdripImpl
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var xdripPlugin: XdripPlugin
|
||||
@Inject lateinit var config: Config
|
||||
|
|
|
@ -29,6 +29,7 @@ import info.nightscout.interfaces.profile.Profile
|
|||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.receivers.Intents
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.DecimalFormatter
|
||||
|
@ -54,6 +55,10 @@ 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 kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONArray
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
|
@ -74,7 +79,7 @@ class XdripPlugin @Inject constructor(
|
|||
private val iobCobCalculator: IobCobCalculator,
|
||||
private val rxBus: RxBus,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val dataSyncSelector: XdripDataSyncSelectorImplementation,
|
||||
private val dataSyncSelector: DataSyncSelectorXdrip,
|
||||
private val dateUtil: DateUtil,
|
||||
aapsLogger: AAPSLogger
|
||||
) : XDripBroadcast, Sync, PluginBase(
|
||||
|
@ -92,6 +97,7 @@ class XdripPlugin @Inject constructor(
|
|||
@Suppress("PrivatePropertyName")
|
||||
private val XDRIP_JOB_NAME: String = this::class.java.simpleName
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private val disposable = CompositeDisposable()
|
||||
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
private val listLog: MutableList<EventXdripNewLog> = ArrayList()
|
||||
|
@ -316,14 +322,17 @@ class XdripPlugin @Inject constructor(
|
|||
*/
|
||||
|
||||
override fun sendToXdrip(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
scope.launch {
|
||||
when (collection) {
|
||||
"profile" -> sendProfileStore(dataPair = dataPair, progress = progress)
|
||||
"devicestatus" -> sendDeviceStatus(dataPair = dataPair, progress = progress)
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendToXdrip(collection: String, dataPairs: List<DataSyncSelector.DataPair>, progress: String) {
|
||||
scope.launch {
|
||||
when (collection) {
|
||||
"entries" -> sendEntries(dataPairs = dataPairs, progress = progress)
|
||||
"food" -> sendFood(dataPairs = dataPairs, progress = progress)
|
||||
|
@ -331,8 +340,9 @@ class XdripPlugin @Inject constructor(
|
|||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendProfileStore(dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
private suspend fun sendProfileStore(dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
val data = (dataPair as DataSyncSelector.PairProfileStore).value
|
||||
rxBus.send(EventXdripNewLog("SENDING", "Sent 1 PROFILE ($progress)"))
|
||||
broadcast(
|
||||
|
@ -340,8 +350,6 @@ class XdripPlugin @Inject constructor(
|
|||
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
.putExtras(Bundle().apply { putString("profile", data.toString()) })
|
||||
)
|
||||
dataSyncSelector.confirmLastProfileStore(dataPair.id)
|
||||
dataSyncSelector.processChangedProfileStore()
|
||||
}
|
||||
|
||||
private fun sendDeviceStatus(dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import androidx.work.WorkerParameters
|
|||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.plugins.sync.xdrip.XdripDataSyncSelectorImplementation
|
||||
import info.nightscout.plugins.sync.xdrip.DataSyncSelectorXdripImpl
|
||||
import info.nightscout.plugins.sync.xdrip.events.EventXdripUpdateGUI
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventXdripNewLog
|
||||
|
@ -17,7 +17,7 @@ class XdripDataSyncWorker(
|
|||
context: Context, params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var dataSyncSelector: XdripDataSyncSelectorImplementation
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelectorXdripImpl
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
|
||||
|
|
|
@ -96,18 +96,14 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/log_scrollview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fadeScrollbars="true"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/log"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="" />
|
||||
</ScrollView>
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
29
plugins/sync/src/main/res/layout/ns_client_log_item.xml
Normal file
29
plugins/sync/src/main/res/layout/ns_client_log_item.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/log_card"
|
||||
style="@style/Widget.MaterialComponents.CardView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="1dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:contentPadding="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/log_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:text="LogText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,11 +1,9 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3
|
||||
|
||||
import androidx.work.WorkManager
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.core.extensions.fromConstant
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.database.entities.Carbs
|
||||
|
@ -20,7 +18,6 @@ import info.nightscout.database.entities.TemporaryBasal
|
|||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
|
@ -28,16 +25,15 @@ import info.nightscout.interfaces.pump.VirtualPump
|
|||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclient.extensions.fromConstant
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
|
@ -51,17 +47,14 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
|
||||
@Mock lateinit var receiverDelegate: ReceiverDelegate
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
@Mock lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3Impl
|
||||
@Mock lateinit var nsAndroidClient: NSAndroidClient
|
||||
@Mock lateinit var uel: UserEntryLogger
|
||||
@Mock lateinit var nsClientSource: NSClientSource
|
||||
@Mock lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Mock lateinit var virtualPump: VirtualPump
|
||||
@Mock lateinit var mockedProfileFunction: ProfileFunction
|
||||
@Mock lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
|
||||
@Mock lateinit var workManager: WorkManager
|
||||
@Mock lateinit var workerClasses: WorkerClasses
|
||||
@Mock lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Mock lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
|
||||
private lateinit var storeDataForDb: StoreDataForDb
|
||||
private lateinit var sut: NSClientV3Plugin
|
||||
|
@ -77,8 +70,8 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
sut =
|
||||
NSClientV3Plugin(
|
||||
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, mockedProfileFunction, repository,
|
||||
nsDeviceStatusHandler, workManager, workerClasses, dataWorkerStorage, nsClientSource
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, mockedProfileFunction, repository,
|
||||
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb
|
||||
)
|
||||
sut.nsAndroidClient = nsAndroidClient
|
||||
`when`(mockedProfileFunction.getProfile(anyLong())).thenReturn(validProfile)
|
||||
|
@ -87,7 +80,6 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddDeviceStatus() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val deviceStatus = DeviceStatus(
|
||||
timestamp = 10000,
|
||||
suggested = "{\"temp\":\"absolute\",\"bg\":133,\"tick\":-6,\"eventualBG\":67,\"targetBG\":99,\"insulinReq\":0,\"deliverAt\":\"2023-01-02T15:29:33.374Z\",\"sensitivityRatio\":1,\"variable_sens\":97.5,\"predBGs\":{\"IOB\":[133,127,121,116,111,106,101,97,93,89,85,81,78,75,72,69,67,65,62,60,58,57,55,54,52,51,50,49,48,47,46,45,45,44,43,43,42,42,41,41,41,41,40,40,40,40,39],\"ZT\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39,39,39,39,39,39,39],\"UAM\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39]},\"reason\":\"COB: 0, Dev: 0.1, BGI: -0.3, ISF: 5.4, CR: 13, Target: 5.5, minPredBG 2.2, minGuardBG 2.1, IOBpredBG 2.2, UAMpredBG 2.2; minGuardBG 2.1<4.0\",\"COB\":0,\"IOB\":0.692,\"duration\":90,\"rate\":0,\"timestamp\":\"2023-01-02T15:29:39.460Z\"}",
|
||||
|
@ -103,23 +95,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairDeviceStatus(deviceStatus, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createDeviceStatus(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createDeviceStatus(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("devicestatus", dataPair, "1/3")
|
||||
// Assertions.assertEquals(1, storeDataForDb.nsIdDeviceStatuses.size)
|
||||
verify(dataSyncSelector, Times(1)).confirmLastDeviceStatusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedDeviceStatuses()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdDeviceStatuses.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.createDeviceStatus(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.createDeviceStatus(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsAdd("devicestatus", dataPair, "1/3")
|
||||
// Assertions.assertEquals(1, storeDataForDb.nsIdDeviceStatuses.size) // still only 1
|
||||
verify(dataSyncSelector, Times(2)).confirmLastDeviceStatusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedDeviceStatuses()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdDeviceStatuses.size) // still only 1
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddEntries() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val glucoseValue = GlucoseValue(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -134,21 +121,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairGlucoseValue(glucoseValue, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createSvg(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createSgv(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("entries", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastGlucoseValueIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedGlucoseValues()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdGlucoseValues.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateSvg(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateSvg(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("entries", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastGlucoseValueIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedGlucoseValues()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdGlucoseValues.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddFood() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val food = Food(
|
||||
isValid = true,
|
||||
name = "name",
|
||||
|
@ -167,21 +151,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairFood(food, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createFood(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createFood(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("food", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastFoodIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedFoods()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdFoods.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateFood(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateFood(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("food", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastFoodIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedFoods()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdFoods.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddBolus() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val bolus = Bolus(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -198,21 +179,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairBolus(bolus, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastBolusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedBoluses()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdBoluses.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastBolusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedBoluses()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdBoluses.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddCarbs() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val carbs = Carbs(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -228,21 +206,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairCarbs(carbs, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastCarbsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedCarbs()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdCarbs.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastCarbsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedCarbs()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdCarbs.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddBolusCalculatorResult() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val bolus = BolusCalculatorResult(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -284,21 +259,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairBolusCalculatorResult(bolus, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastBolusCalculatorResultsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedBolusCalculatorResults()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdBolusCalculatorResults.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastBolusCalculatorResultsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedBolusCalculatorResults()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdBolusCalculatorResults.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddEffectiveProfileSwitch() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val profileSwitch = EffectiveProfileSwitch(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -325,21 +297,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairEffectiveProfileSwitch(profileSwitch, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastEffectiveProfileSwitchIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedEffectiveProfileSwitches()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdEffectiveProfileSwitches.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastEffectiveProfileSwitchIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedEffectiveProfileSwitches()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdEffectiveProfileSwitches.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddProfileSwitch() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val profileSwitch = ProfileSwitch(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -364,21 +333,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairProfileSwitch(profileSwitch, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastProfileSwitchIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedProfileSwitches()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdProfileSwitches.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastProfileSwitchIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedProfileSwitches()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdProfileSwitches.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddExtendedBolus() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val extendedBolus = ExtendedBolus(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -394,21 +360,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairExtendedBolus(extendedBolus, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastExtendedBolusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedExtendedBoluses()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdExtendedBoluses.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastExtendedBolusIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedExtendedBoluses()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdExtendedBoluses.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddOffilineEvent() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val offlineEvent = OfflineEvent(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -423,21 +386,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairOfflineEvent(offlineEvent, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastOfflineEventIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedOfflineEvents()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdOfflineEvents.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastOfflineEventIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedOfflineEvents()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdOfflineEvents.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddTemporaryBasal() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val temporaryBasal = TemporaryBasal(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -454,21 +414,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairTemporaryBasal(temporaryBasal, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastTemporaryBasalIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedTemporaryBasals()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdTemporaryBasals.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastTemporaryBasalIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedTemporaryBasals()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdTemporaryBasals.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddTemporaryTarget() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val temporaryTarget = TemporaryTarget(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -485,21 +442,18 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairTemporaryTarget(temporaryTarget, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastTempTargetsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedTempTargets()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdTemporaryTargets.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastTempTargetsIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedTempTargets()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdTemporaryTargets.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddTherapyEvent() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
val therapyEvent = TherapyEvent(
|
||||
timestamp = 10000,
|
||||
isValid = true,
|
||||
|
@ -519,32 +473,29 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
val dataPair = DataSyncSelector.PairTherapyEvent(therapyEvent, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createTreatment(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastTherapyEventIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedTherapyEvents()
|
||||
Assertions.assertEquals(1, storeDataForDb.nsIdTherapyEvents.size)
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("treatments", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastTherapyEventIdIfGreater(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedTherapyEvents()
|
||||
Assertions.assertEquals(2, storeDataForDb.nsIdTherapyEvents.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
fun nsAddProfile() = runTest {
|
||||
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
|
||||
|
||||
val dataPair = DataSyncSelector.PairProfileStore(getValidProfileStore().data, 1000)
|
||||
// create
|
||||
`when`(nsAndroidClient.createProfileStore(anyObject())).thenReturn(CreateUpdateResponse(201, null))
|
||||
`when`(nsAndroidClient.createProfileStore(anyObject())).thenReturn(CreateUpdateResponse(201, "aaa"))
|
||||
sut.nsAdd("profile", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(1)).confirmLastProfileStore(1000)
|
||||
verify(dataSyncSelector, Times(1)).processChangedProfileStore()
|
||||
// verify(dataSyncSelectorV3, Times(1)).confirmLastProfileStore(1000)
|
||||
// verify(dataSyncSelectorV3, Times(1)).processChangedProfileStore()
|
||||
// update
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, null))
|
||||
`when`(nsAndroidClient.updateTreatment(anyObject())).thenReturn(CreateUpdateResponse(200, "aaa"))
|
||||
sut.nsUpdate("profile", dataPair, "1/3")
|
||||
verify(dataSyncSelector, Times(2)).confirmLastProfileStore(1000)
|
||||
verify(dataSyncSelector, Times(2)).processChangedProfileStore()
|
||||
// verify(dataSyncSelectorV3, Times(2)).confirmLastProfileStore(1000)
|
||||
// verify(dataSyncSelectorV3, Times(2)).processChangedProfileStore()
|
||||
}
|
||||
}
|
|
@ -7,8 +7,8 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3Impl
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
@ -24,7 +24,7 @@ import org.mockito.Mockito.`when`
|
|||
internal class DataSyncWorkerTest : TestBase() {
|
||||
|
||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Mock lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3Impl
|
||||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
@Mock lateinit var nsClient: NsClient
|
||||
@Mock lateinit var rxBus: RxBus
|
||||
|
@ -37,7 +37,7 @@ internal class DataSyncWorkerTest : TestBase() {
|
|||
if (it is DataSyncWorker) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.fabricPrivacy = fabricPrivacy
|
||||
it.dataSyncSelector = dataSyncSelector
|
||||
it.dataSyncSelectorV3 = dataSyncSelectorV3
|
||||
it.activePlugin = activePlugin
|
||||
it.rxBus = rxBus
|
||||
it.nsClientV3Plugin = nsClientV3Plugin
|
||||
|
@ -57,11 +57,11 @@ internal class DataSyncWorkerTest : TestBase() {
|
|||
sut = TestListenableWorkerBuilder<DataSyncWorker>(context).build()
|
||||
`when`(nsClient.hasWritePermission).thenReturn(false)
|
||||
sut.doWorkAndLog()
|
||||
Mockito.verify(dataSyncSelector, Mockito.times(0)).doUpload()
|
||||
Mockito.verify(dataSyncSelectorV3, Mockito.times(0)).doUpload()
|
||||
|
||||
`when`(nsClient.hasWritePermission).thenReturn(true)
|
||||
val result = sut.doWorkAndLog()
|
||||
Mockito.verify(dataSyncSelector, Mockito.times(1)).doUpload()
|
||||
Mockito.verify(dataSyncSelectorV3, Mockito.times(1)).doUpload()
|
||||
Assertions.assertTrue(result is Success)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.workers
|
||||
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.WorkContinuation
|
||||
|
@ -11,17 +10,17 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
|
@ -41,14 +40,12 @@ import org.mockito.ArgumentMatchers.any
|
|||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class LoadBgWorkerTest : TestBase() {
|
||||
|
||||
@Mock lateinit var workerClasses: WorkerClasses
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Mock lateinit var dateUtil: DateUtil
|
||||
|
@ -57,13 +54,15 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
@Mock lateinit var profileFunction: ProfileFunction
|
||||
@Mock lateinit var config: Config
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
@Mock lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3
|
||||
@Mock lateinit var repository: AppRepository
|
||||
@Mock lateinit var receiverStatusStore: ReceiverStatusStore
|
||||
@Mock lateinit var nsClientSource: NSClientSource
|
||||
@Mock lateinit var workManager: WorkManager
|
||||
@Mock lateinit var workContinuation: WorkContinuation
|
||||
@Mock lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
|
||||
@Mock lateinit var storeDataForDb: StoreDataForDb
|
||||
@Mock lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
|
||||
private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger)
|
||||
private lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
@ -78,15 +77,13 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
if (it is LoadBgWorker) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.fabricPrivacy = fabricPrivacy
|
||||
it.dataWorkerStorage = dataWorkerStorage
|
||||
it.sp = sp
|
||||
it.rxBus = rxBus
|
||||
it.context = context
|
||||
it.dateUtil = dateUtil
|
||||
it.nsClientV3Plugin = nsClientV3Plugin
|
||||
it.workerClasses = workerClasses
|
||||
it.nsClientSource = nsClientSource
|
||||
it.workManager = workManager
|
||||
it.storeDataForDb = storeDataForDb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,8 +98,8 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
receiverDelegate = ReceiverDelegate(rxBus, rh, sp, receiverStatusStore, aapsSchedulers, fabricPrivacy)
|
||||
nsClientV3Plugin = NSClientV3Plugin(
|
||||
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, profileFunction, repository,
|
||||
nsDeviceStatusHandler, workManager, workerClasses, dataWorkerStorage, nsClientSource
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, profileFunction, repository,
|
||||
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb
|
||||
)
|
||||
nsClientV3Plugin.newestDataOnServer = LastModified(LastModified.Collections())
|
||||
}
|
||||
|
@ -124,11 +121,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Assertions.assertTrue(result.outputData.getString("Result") == "Load not enabled")
|
||||
Mockito.verify(workManager, Mockito.times(1)).enqueueUniqueWork(
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -144,13 +136,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertEquals(now - 1000, nsClientV3Plugin.lastLoadedSrvModified.collections.entries)
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).then(any<OneTimeWorkRequest>())
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).enqueue()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -171,7 +156,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
|
||||
Mockito.`when`(workManager.beginUniqueWork(anyString(), any(), any<OneTimeWorkRequest>())).thenReturn(workContinuation)
|
||||
Mockito.`when`(workContinuation.then(any<OneTimeWorkRequest>())).thenReturn(workContinuation)
|
||||
Mockito.`when`(workerClasses.nsClientSourceWorker).thenReturn(LoggingWorker::class.java)
|
||||
nsClientV3Plugin.nsAndroidClient = nsAndroidClient
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = 0L // first load
|
||||
nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries = now - 1000
|
||||
|
@ -180,13 +164,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
|
||||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).then(any<OneTimeWorkRequest>())
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).enqueue()
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,12 +180,5 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertEquals(now - 1000, nsClientV3Plugin.lastLoadedSrvModified.collections.entries)
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).then(any<OneTimeWorkRequest>())
|
||||
Mockito.verify(workContinuation, Mockito.times(1)).enqueue()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue