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