From a3711f0c0c020bd8dd2e6d13ff7ac5306c5f4426 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 15 Jan 2023 20:08:00 +0100 Subject: [PATCH] NSCv3: improve error handling --- .../rx/events/EventNSClientNewLog.kt | 2 +- .../sync/nsclientV3/workers/LoadBgWorker.kt | 108 +++++++------ .../workers/LoadDeviceStatusWorker.kt | 46 +++--- .../nsclientV3/workers/LoadFoodsWorker.kt | 11 +- .../workers/LoadLastModificationWorker.kt | 25 +-- .../workers/LoadProfileStoreWorker.kt | 73 +++++---- .../nsclientV3/workers/LoadStatusWorker.kt | 23 +-- .../workers/LoadTreatmentsWorker.kt | 108 +++++++------ .../nsclientV3/workers/ProcessFoodWorker.kt | 38 +++-- .../workers/ProcessTreatmentsWorker.kt | 142 +++++++++--------- 10 files changed, 298 insertions(+), 278 deletions(-) diff --git a/app-wear-shared/shared/src/main/java/info/nightscout/rx/events/EventNSClientNewLog.kt b/app-wear-shared/shared/src/main/java/info/nightscout/rx/events/EventNSClientNewLog.kt index 379d2750ff..c88bfec8b3 100644 --- a/app-wear-shared/shared/src/main/java/info/nightscout/rx/events/EventNSClientNewLog.kt +++ b/app-wear-shared/shared/src/main/java/info/nightscout/rx/events/EventNSClientNewLog.kt @@ -3,7 +3,7 @@ package info.nightscout.rx.events import java.text.SimpleDateFormat import java.util.Locale -class EventNSClientNewLog(val action: String, val logText: String) : Event() { +class EventNSClientNewLog(val action: String, val logText: String?) : Event() { var date = System.currentTimeMillis() private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt index 4da54b0625..8246cbf3fb 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorker.kt @@ -16,6 +16,7 @@ import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientNewLog +import info.nightscout.rx.logging.LTag import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.sdk.localmodel.entry.NSSgvV3 import info.nightscout.shared.sharedPreferences.SP @@ -49,46 +50,63 @@ class LoadBgWorker( return Result.success(workDataOf("Result" to "Load not enabled")) } - val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.ENTRIES) - val lastLoaded = - if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge) - else max(nsClientV3Plugin.lastLoadedSrvModified.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge) - if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > lastLoaded) { - val sgvs: List - val response: NSAndroidClient.ReadResponse>? - if (isFirstLoad) response = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500) - else { - response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500) - response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = it } - nsClientV3Plugin.storeLastLoadedSrvModified() - nsClientV3Plugin.scheduleIrregularExecution() // Idea is to run after 5 min after last BG - } - sgvs = response.values - aapsLogger.debug("SGVS: $sgvs") - if (sgvs.isNotEmpty()) { - val action = if (isFirstLoad) "RCV-FIRST" else "RCV" - rxBus.send(EventNSClientNewLog(action, "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - // Objective0 - sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true) - // Schedule processing of fetched data and continue of loading - workManager - .beginUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build() - ) - // response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload - .then(response.code != 304, OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()) - .then(response.code == 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) - .enqueue() + try { + val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) + val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.ENTRIES) + val lastLoaded = + if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge) + else max(nsClientV3Plugin.lastLoadedSrvModified.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge) + if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > lastLoaded) { + val sgvs: List + val response: NSAndroidClient.ReadResponse>? + if (isFirstLoad) response = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500) + else { + response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500) + response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = it } + nsClientV3Plugin.storeLastLoadedSrvModified() + nsClientV3Plugin.scheduleIrregularExecution() // Idea is to run after 5 min after last BG + } + sgvs = response.values + aapsLogger.debug(LTag.NSCLIENT, "SGVS: $sgvs") + if (sgvs.isNotEmpty()) { + val action = if (isFirstLoad) "RCV-FIRST" else "RCV" + rxBus.send(EventNSClientNewLog(action, "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + // Objective0 + sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true) + // Schedule processing of fetched data and continue of loading + workManager + .beginUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build() + ) + // response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload + .then(response.code != 304, OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()) + .then(response.code == 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) + .enqueue() + } else { + // End first load + if (isFirstLoad) { + nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded + nsClientV3Plugin.storeLastLoadedSrvModified() + } + rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + workManager + .beginUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build() + ) + .then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) + .enqueue() + } } else { // End first load if (isFirstLoad) { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded nsClientV3Plugin.storeLastLoadedSrvModified() } - rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) workManager .beginUniqueWork( NSClientV3Plugin.JOB_NAME, @@ -98,22 +116,12 @@ class LoadBgWorker( .then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) .enqueue() } - } else { - // End first load - if (isFirstLoad) { - nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded - nsClientV3Plugin.storeLastLoadedSrvModified() - } - rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - workManager - .beginUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build() - ) - .then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) - .enqueue() - } + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) + } + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt index 4c5948ab2c..a54663f17b 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadDeviceStatusWorker.kt @@ -15,7 +15,6 @@ import info.nightscout.rx.events.EventNSClientNewLog import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.T import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import javax.inject.Inject class LoadDeviceStatusWorker( @@ -32,31 +31,30 @@ class LoadDeviceStatusWorker( override suspend fun doWorkAndLog(): Result { val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - var ret = Result.success() - runBlocking { - try { - val from = dateUtil.now() - T.mins(7).msecs() - val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from) - aapsLogger.debug("DEVICESTATUSES: $deviceStatuses") - if (deviceStatuses.isNotEmpty()) { - rxBus.send(EventNSClientNewLog("RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}")) - nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray()) - rxBus.send(EventNSClientNewLog("DONE DS", "")) - } else { - rxBus.send(EventNSClientNewLog("RCV END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}")) - } - WorkManager.getInstance(context) - .enqueueUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build() - ) - } catch (error: Exception) { - aapsLogger.error("Error: ", error) - ret = Result.failure(workDataOf("Error" to error.toString())) + try { + val from = dateUtil.now() - T.mins(7).msecs() + val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from) + aapsLogger.debug("DEVICESTATUSES: $deviceStatuses") + if (deviceStatuses.isNotEmpty()) { + rxBus.send(EventNSClientNewLog("RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}")) + nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray()) + rxBus.send(EventNSClientNewLog("DONE DS", "")) + } else { + rxBus.send(EventNSClientNewLog("RCV END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}")) } + WorkManager.getInstance(context) + .enqueueUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build() + ) + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } - return ret + + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadFoodsWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadFoodsWorker.kt index 05fcd6346f..f993f2e9f3 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadFoodsWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadFoodsWorker.kt @@ -13,10 +13,10 @@ import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin 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.utils.DateUtil import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import javax.inject.Inject class LoadFoodsWorker( @@ -36,10 +36,10 @@ class LoadFoodsWorker( // Food database doesn't provide last record modification // Read full collection every 5th attempt - runBlocking { + try { if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) { val foods: List = nsAndroidClient.getFoods(1000).values - aapsLogger.debug("FOODS: $foods") + aapsLogger.debug(LTag.NSCLIENT, "FOODS: $foods") rxBus.send(EventNSClientNewLog("RCV", "${foods.size} FOODs")) // Schedule processing of fetched data WorkManager.getInstance(context) @@ -61,7 +61,12 @@ class LoadFoodsWorker( OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build() ) } + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt index cb0ab57c37..bfcb3b0292 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadLastModificationWorker.kt @@ -5,8 +5,10 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin +import info.nightscout.rx.bus.RxBus +import info.nightscout.rx.events.EventNSClientNewLog +import info.nightscout.rx.logging.LTag import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import javax.inject.Inject class LoadLastModificationWorker( @@ -14,21 +16,20 @@ class LoadLastModificationWorker( ) : LoggingWorker(context, params, Dispatchers.IO) { @Inject lateinit var nsClientV3Plugin: NSClientV3Plugin + @Inject lateinit var rxBus: RxBus override suspend fun doWorkAndLog(): Result { val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - var ret = Result.success() - runBlocking { - try { - val lm = nsAndroidClient.getLastModified() - nsClientV3Plugin.newestDataOnServer = lm - aapsLogger.debug("LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}") - } catch (error: Exception) { - aapsLogger.error("Error: ", error) - ret = Result.failure(workDataOf("Error" to error.toString())) - } + try { + val lm = nsAndroidClient.getLastModified() + nsClientV3Plugin.newestDataOnServer = lm + aapsLogger.debug(LTag.NSCLIENT, "LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}") + } catch (error: Exception) { + aapsLogger.error(LTag.NSCLIENT, "Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } - return ret + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadProfileStoreWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadProfileStoreWorker.kt index e7cf0683dc..953eac9351 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadProfileStoreWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadProfileStoreWorker.kt @@ -13,10 +13,10 @@ import info.nightscout.interfaces.workflow.WorkerClasses import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientNewLog +import info.nightscout.rx.logging.LTag import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.shared.utils.DateUtil import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import org.json.JSONObject import javax.inject.Inject import kotlin.math.max @@ -35,43 +35,37 @@ class LoadProfileStoreWorker( override suspend fun doWorkAndLog(): Result { val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - var ret = Result.success() - val lastLoaded = max(nsClientV3Plugin.lastLoadedSrvModified.collections.profile, 0) - runBlocking { - if ((nsClientV3Plugin.newestDataOnServer?.collections?.profile ?: Long.MAX_VALUE) > lastLoaded) - try { - val response: NSAndroidClient.ReadResponse> = nsAndroidClient.getLastProfileStore() - val profiles = response.values - if (profiles.size == 1) { - val profile = profiles[0] - JsonHelper.safeGetLongAllowNull(profile, "srvModified")?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.profile = it } - nsClientV3Plugin.storeLastLoadedSrvModified() - aapsLogger.debug("PROFILE: $profile") - rxBus.send(EventNSClientNewLog("RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - WorkManager.getInstance(context) - .beginUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder((workerClasses.nsProfileWorker)) - .setInputData(dataWorkerStorage.storeInputData(profile)) - .build() - ).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build()) - .enqueue() - } else { - rxBus.send(EventNSClientNewLog("RCV END", "No new PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - WorkManager.getInstance(context) - .enqueueUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build() - ) - } - } catch (error: Exception) { - aapsLogger.error("Error: ", error) - ret = Result.failure(workDataOf("Error" to error.toString())) + try { + val lastLoaded = max(nsClientV3Plugin.lastLoadedSrvModified.collections.profile, 0) + if ((nsClientV3Plugin.newestDataOnServer?.collections?.profile ?: Long.MAX_VALUE) > lastLoaded) { + val response: NSAndroidClient.ReadResponse> = nsAndroidClient.getLastProfileStore() + val profiles = response.values + if (profiles.size == 1) { + val profile = profiles[0] + JsonHelper.safeGetLongAllowNull(profile, "srvModified")?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.profile = it } + nsClientV3Plugin.storeLastLoadedSrvModified() + aapsLogger.debug(LTag.NSCLIENT, "PROFILE: $profile") + rxBus.send(EventNSClientNewLog("RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + WorkManager.getInstance(context) + .beginUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder((workerClasses.nsProfileWorker)) + .setInputData(dataWorkerStorage.storeInputData(profile)) + .build() + ).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build()) + .enqueue() + } else { + rxBus.send(EventNSClientNewLog("RCV END", "No new PROFILE 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 END", "No PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) WorkManager.getInstance(context) .enqueueUniqueWork( @@ -80,7 +74,12 @@ class LoadProfileStoreWorker( OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build() ) } + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } - return ret + + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadStatusWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadStatusWorker.kt index 90efd3f57b..74488391fa 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadStatusWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadStatusWorker.kt @@ -5,8 +5,10 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin +import info.nightscout.rx.bus.RxBus +import info.nightscout.rx.events.EventNSClientNewLog +import info.nightscout.rx.logging.LTag import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import javax.inject.Inject class LoadStatusWorker( @@ -14,20 +16,19 @@ class LoadStatusWorker( ) : LoggingWorker(context, params, Dispatchers.IO) { @Inject lateinit var nsClientV3Plugin: NSClientV3Plugin + @Inject lateinit var rxBus: RxBus override suspend fun doWorkAndLog(): Result { val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - var ret = Result.success() - runBlocking { - try { - val status = nsAndroidClient.getStatus() - aapsLogger.debug("STATUS: $status") - } catch (error: Exception) { - aapsLogger.error("Error: ", error) - ret = Result.failure(workDataOf("Error" to error.toString())) - } + try { + val status = nsAndroidClient.getStatus() + aapsLogger.debug(LTag.NSCLIENT, "STATUS: $status") + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } - return ret + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt index a4e706b2a6..596e20b022 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadTreatmentsWorker.kt @@ -14,11 +14,11 @@ import info.nightscout.interfaces.sync.NsClient import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventNSClientNewLog +import info.nightscout.rx.logging.LTag import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.sdk.localmodel.treatment.NSTreatment import info.nightscout.shared.utils.DateUtil import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import javax.inject.Inject import kotlin.math.max @@ -36,64 +36,57 @@ class LoadTreatmentsWorker( override suspend fun doWorkAndLog(): Result { val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null")) - var ret = Result.success() - val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.TREATMENTS) - val lastLoaded = - if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge) - else max(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge) - runBlocking { - if ((nsClientV3Plugin.newestDataOnServer?.collections?.treatments ?: Long.MAX_VALUE) > lastLoaded) - try { - val treatments: List - val response: NSAndroidClient.ReadResponse>? + try { + val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.TREATMENTS) + val lastLoaded = + if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge) + else max(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge) + if ((nsClientV3Plugin.newestDataOnServer?.collections?.treatments ?: Long.MAX_VALUE) > lastLoaded) { + val treatments: List + val response: NSAndroidClient.ReadResponse>? + if (isFirstLoad) { + val lastLoadedIso = dateUtil.toISOString(lastLoaded) + response = nsAndroidClient.getTreatmentsNewerThan(lastLoadedIso, 500) + } else { + response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500) + response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = it } + nsClientV3Plugin.storeLastLoadedSrvModified() + } + treatments = response.values + aapsLogger.debug(LTag.NSCLIENT, "TREATMENTS: $treatments") + if (treatments.isNotEmpty()) { + val action = if (isFirstLoad) "RCV-FIRST" else "RCV" + rxBus.send(EventNSClientNewLog(action, "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + // Schedule processing of fetched data and continue of loading + WorkManager.getInstance(context) + .beginUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java) + .setInputData(dataWorkerStorage.storeInputData(response)) + .build() + ) + // response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload + .then(response.code != 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) + .then(response.code == 304, OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()) + .enqueue() + } else { + // End first load if (isFirstLoad) { - val lastLoadedIso = dateUtil.toISOString(lastLoaded) - response = nsAndroidClient.getTreatmentsNewerThan(lastLoadedIso, 500) - } - else { - response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500) - response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = it } + nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded nsClientV3Plugin.storeLastLoadedSrvModified() } - treatments = response.values - aapsLogger.debug("TREATMENTS: $treatments") - if (treatments.isNotEmpty()) { - val action = if (isFirstLoad) "RCV-FIRST" else "RCV" - rxBus.send(EventNSClientNewLog(action, "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - // Schedule processing of fetched data and continue of loading - WorkManager.getInstance(context) - .beginUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java) - .setInputData(dataWorkerStorage.storeInputData(response)) - .build() - ) - // response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload - .then(response.code != 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) - .then(response.code == 304, OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()) - .enqueue() - } else { - // End first load - if (isFirstLoad) { - nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded - nsClientV3Plugin.storeLastLoadedSrvModified() - } - rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) - storeDataForDb.storeTreatmentsToDb() - WorkManager.getInstance(context) - .enqueueUniqueWork( - NSClientV3Plugin.JOB_NAME, - ExistingWorkPolicy.APPEND_OR_REPLACE, - OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build() - ) - } - } catch (error: Exception) { - aapsLogger.error("Error: ", error) - ret = Result.failure(workDataOf("Error" to error.toString())) + rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}")) + storeDataForDb.storeTreatmentsToDb() + WorkManager.getInstance(context) + .enqueueUniqueWork( + NSClientV3Plugin.JOB_NAME, + ExistingWorkPolicy.APPEND_OR_REPLACE, + OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build() + ) } - else { + } else { // End first load if (isFirstLoad) { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded @@ -108,7 +101,12 @@ class LoadTreatmentsWorker( OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build() ) } + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) } - return ret + + return Result.success() } } \ No newline at end of file diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessFoodWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessFoodWorker.kt index 5ed1f3be35..32bdc3ac54 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessFoodWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessFoodWorker.kt @@ -12,6 +12,8 @@ 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 @@ -30,24 +32,24 @@ class ProcessFoodWorker( @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") - val ret = Result.success() - val foods = mutableListOf() + try { + val foods = mutableListOf() + if (data is JSONArray) { + for (index in 0 until data.length()) { + val jsonFood: JSONObject = data.getJSONObject(index) - if (data is JSONArray) { - for (index in 0 until data.length()) { - val jsonFood: JSONObject = data.getJSONObject(index) + if (JsonHelper.safeGetString(jsonFood, "type") != "food") continue - if (JsonHelper.safeGetString(jsonFood, "type") != "food") continue - - when (JsonHelper.safeGetString(jsonFood, "action")) { - "remove" -> { - val delFood = Food( + when (JsonHelper.safeGetString(jsonFood, "action")) { + "remove" -> { + val delFood = Food( name = "", portion = 0.0, carbs = 0, @@ -61,13 +63,19 @@ class ProcessFoodWorker( 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() } - } 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)) } - storeDataForDb.foods.addAll(foods) - return ret + + return Result.success() } } diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt index 22946b1d89..3f96ad4922 100644 --- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt +++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/ProcessTreatmentsWorker.kt @@ -8,8 +8,6 @@ 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.XDripBroadcast -import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.plugins.sync.R @@ -24,6 +22,7 @@ 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.interfaces.NSAndroidClient import info.nightscout.sdk.localmodel.treatment.NSBolus @@ -54,8 +53,6 @@ class ProcessTreatmentsWorker( @Inject lateinit var repository: AppRepository @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var rxBus: RxBus - @Inject lateinit var uel: UserEntryLogger - @Inject lateinit var xDripBroadcast: XDripBroadcast @Inject lateinit var storeDataForDb: StoreDataForDb override suspend fun doWorkAndLog(): Result { @@ -63,83 +60,88 @@ class ProcessTreatmentsWorker( val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse>? ?: return Result.failure(workDataOf("Error" to "missing input data")) - var latestDateInReceivedData: Long = 0 - val ret = Result.success() - for (treatment in treatments.values) { - aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment") - val date = treatment.date ?: continue - if (date > latestDateInReceivedData) latestDateInReceivedData = date + try { + var latestDateInReceivedData: Long = 0 + for (treatment in treatments.values) { + 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()) + 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 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 + 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) } } - 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 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 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 NSBolusWizard -> + treatment.toBolusCalculatorResult()?.let { bolusCalculatorResult -> + storeDataForDb.bolusCalculatorResults.add(bolusCalculatorResult) } - 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) - } + 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) + activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData) // xDripBroadcast.sendTreatments(treatments) - return ret + } catch (error: Exception) { + aapsLogger.error("Error: ", error) + rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage)) + return Result.failure(workDataOf("Error" to error.localizedMessage)) + } + return Result.success() } } \ No newline at end of file