diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/DeviceStatusMapper.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/DeviceStatusMapper.kt
index e2ca241a48..2b4334183f 100644
--- a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/DeviceStatusMapper.kt
+++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/DeviceStatusMapper.kt
@@ -1,5 +1,6 @@
package info.nightscout.sdk.mapper
+import com.google.gson.Gson
import com.google.gson.JsonParser
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
@@ -8,6 +9,9 @@ import org.json.JSONObject
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
toRemoteDeviceStatus().toNSDeviceStatus()
+fun String.toNSDeviceStatus(): NSDeviceStatus =
+ Gson().fromJson(this, RemoteDeviceStatus::class.java).toNSDeviceStatus()
+
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
NSDeviceStatus(
app = app,
diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/FoodMapper.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/FoodMapper.kt
index 15bb3978c9..49ebe6456c 100644
--- a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/FoodMapper.kt
+++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/FoodMapper.kt
@@ -1,5 +1,6 @@
package info.nightscout.sdk.mapper
+import com.google.gson.Gson
import info.nightscout.sdk.localmodel.food.NSFood
import info.nightscout.sdk.remotemodel.RemoteFood
@@ -12,6 +13,9 @@ import info.nightscout.sdk.remotemodel.RemoteFood
fun NSFood.convertToRemoteAndBack(): NSFood? =
toRemoteFood().toNSFood()
+fun String.toNSFood(): NSFood? =
+ Gson().fromJson(this, RemoteFood::class.java).toNSFood()
+
internal fun RemoteFood.toNSFood(): NSFood? {
when (type) {
"food" ->
diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/SvgMapper.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/SvgMapper.kt
index b37a600a86..bc08e4e6f2 100644
--- a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/SvgMapper.kt
+++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/SvgMapper.kt
@@ -1,5 +1,6 @@
package info.nightscout.sdk.mapper
+import com.google.gson.Gson
import info.nightscout.sdk.localmodel.entry.Direction
import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.sdk.localmodel.entry.NsUnits
@@ -8,6 +9,9 @@ import info.nightscout.sdk.remotemodel.RemoteEntry
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
toRemoteEntry().toSgv()
+fun String.toNSSgvV3(): NSSgvV3? =
+ Gson().fromJson(this, RemoteEntry::class.java).toSgv()
+
internal fun RemoteEntry.toSgv(): NSSgvV3? {
this.sgv ?: return null
diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/TreatmentMapper.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/TreatmentMapper.kt
index 2dbd17f74b..64a500aa81 100644
--- a/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/TreatmentMapper.kt
+++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/mapper/TreatmentMapper.kt
@@ -1,5 +1,6 @@
package info.nightscout.sdk.mapper
+import com.google.gson.Gson
import info.nightscout.sdk.localmodel.entry.NsUnits
import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSBolus
@@ -26,6 +27,9 @@ import java.util.concurrent.TimeUnit
fun NSTreatment.convertToRemoteAndBack(): NSTreatment? =
toRemoteTreatment()?.toTreatment()
+fun String.toNSTreatment(): NSTreatment? =
+ Gson().fromJson(this, RemoteTreatment::class.java).toTreatment()
+
internal fun RemoteTreatment.toTreatment(): NSTreatment? {
val treatmentTimestamp = timestamp()
when {
diff --git a/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/LastModified.kt b/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/LastModified.kt
index 2a9716adc6..4d48a5f46d 100644
--- a/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/LastModified.kt
+++ b/core/ns-sdk/src/main/java/info/nightscout/sdk/remotemodel/LastModified.kt
@@ -22,4 +22,15 @@ data class LastModified(
@SerializedName("foods") var foods: Long = 0, // foods collection
@SerializedName("settings") var settings: Long = 0 // settings collection
)
+
+ fun set(colName: String, value: Long) {
+ when (colName) {
+ "devicestatus" -> collections.devicestatus = value
+ "entries" -> collections.entries = value
+ "profile" -> collections.profile = value
+ "treatments" -> collections.treatments = value
+ "foods" -> collections.foods = value
+ "settings" -> collections.settings = value
+ }
+ }
}
diff --git a/core/utils/src/main/res/values/keys.xml b/core/utils/src/main/res/values/keys.xml
index 8377c4b5d7..2ea8eb2c02 100644
--- a/core/utils/src/main/res/values/keys.xml
+++ b/core/utils/src/main/res/values/keys.xml
@@ -85,6 +85,7 @@
ns_receive_profile_store
nsclientinternal_url
nsclientinternal_api_secret
+ ns_use_ws
ns_receive_insulin
ns_receive_carbs
ns_receive_therapy_events
diff --git a/plugins/configuration/src/main/java/info/nightscout/configuration/configBuilder/RunningConfigurationImpl.kt b/plugins/configuration/src/main/java/info/nightscout/configuration/configBuilder/RunningConfigurationImpl.kt
index 81643a8d2d..1696e5c6a0 100644
--- a/plugins/configuration/src/main/java/info/nightscout/configuration/configBuilder/RunningConfigurationImpl.kt
+++ b/plugins/configuration/src/main/java/info/nightscout/configuration/configBuilder/RunningConfigurationImpl.kt
@@ -75,7 +75,7 @@ class RunningConfigurationImpl @Inject constructor(
assert(config.NSCLIENT)
configuration.version?.let {
- rxBus.send(EventNSClientNewLog("VERSION", "Received AAPS version $it"))
+ rxBus.send(EventNSClientNewLog("◄ VERSION", "Received AAPS version $it"))
if (config.VERSION_NAME.startsWith(it).not())
uiInteraction.addNotification(Notification.NSCLIENT_VERSION_DOES_NOT_MATCH, rh.gs(R.string.nsclient_version_does_not_match), Notification.NORMAL)
}
diff --git a/plugins/source/src/main/java/info/nightscout/source/NSClientSourcePlugin.kt b/plugins/source/src/main/java/info/nightscout/source/NSClientSourcePlugin.kt
index 9863eff071..b5ccfe6387 100644
--- a/plugins/source/src/main/java/info/nightscout/source/NSClientSourcePlugin.kt
+++ b/plugins/source/src/main/java/info/nightscout/source/NSClientSourcePlugin.kt
@@ -116,7 +116,7 @@ class NSClientSourcePlugin @Inject constructor(
return TransactionGlucoseValue(
timestamp = sgv.date ?: throw InvalidParameterException(),
value = sgv.sgv,
- noise = sgv.noise?.toDouble(),
+ noise = sgv.noise,
raw = sgv.filtered,
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
nightscoutId = sgv.identifier,
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt
index 731d4b729a..f1ef1bece4 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/di/SyncModule.kt
@@ -60,6 +60,7 @@ abstract class SyncModule {
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
+ @ContributesAndroidInjector abstract fun contributesStoreTreatmentsWorker(): StoreDataForDbImpl.StoreTreatmentsWorker
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt
index 60562c323c..91ec86fca5 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/DataSyncSelectorImplementation.kt
@@ -57,7 +57,7 @@ class DataSyncSelectorImplementation @Inject constructor(
}
private val queueCounter = QueueCounter()
- private val isPaused get() = sp.getBoolean(R.string.key_ns_client_paused, false)
+ private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
override fun queueSize(): Long = queueCounter.size()
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt
index b3736b070e..ecd92f2270 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/NSClientFragment.kt
@@ -81,7 +81,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
updateGui()
}
- binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_paused, false)
+ binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
binding.paused.setOnCheckedChangeListener { _, isChecked ->
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
nsClientPlugin?.pause(isChecked)
@@ -143,7 +143,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
private fun updateGui() {
if (_binding == null) return
- binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_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)
binding.url.text = nsClientPlugin?.address
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt
index 445c934835..e47281cd5e 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/StoreDataForDbImpl.kt
@@ -147,13 +147,24 @@ class StoreDataForDbImpl @Inject constructor(
}
}
+ 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 HashMap.inc(key: T) =
if (containsKey(key)) merge(key, 1, Long::plus)
else put(key, 1)
override fun storeGlucoseValuesToDb() {
- rxBus.send(EventNSClientNewLog("PROCESSING BG", ""))
-
if (glucoseValues.isNotEmpty())
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
.doOnError {
@@ -184,12 +195,10 @@ class StoreDataForDbImpl @Inject constructor(
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
SystemClock.sleep(pause)
- rxBus.send(EventNSClientNewLog("DONE BG", ""))
+ rxBus.send(EventNSClientNewLog("● DONE PROCESSING BG", ""))
}
override fun storeFoodsToDb() {
- rxBus.send(EventNSClientNewLog("PROCESSING FOOD", ""))
-
if (foods.isNotEmpty())
repository.runTransactionForResult(SyncNsFoodTransaction(foods))
.doOnError {
@@ -214,12 +223,10 @@ class StoreDataForDbImpl @Inject constructor(
sendLog("Food", Food::class.java.simpleName)
SystemClock.sleep(pause)
- rxBus.send(EventNSClientNewLog("DONE FOOD", ""))
+ rxBus.send(EventNSClientNewLog("● DONE PROCESSING FOOD", ""))
}
override fun storeTreatmentsToDb() {
- rxBus.send(EventNSClientNewLog("PROCESSING TR", ""))
-
if (boluses.isNotEmpty())
repository.runTransactionForResult(SyncNsBolusTransaction(boluses))
.doOnError {
@@ -796,7 +803,7 @@ class StoreDataForDbImpl @Inject constructor(
SystemClock.sleep(pause)
uel.log(userEntries)
- rxBus.send(EventNSClientNewLog("DONE TR", ""))
+ rxBus.send(EventNSClientNewLog("● DONE PROCESSING TR", ""))
}
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
@@ -996,7 +1003,7 @@ class StoreDataForDbImpl @Inject constructor(
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName)
- rxBus.send(EventNSClientNewLog("DONE NSIDs", ""))
+ rxBus.send(EventNSClientNewLog("● DONE NSIDs", ""))
}
private fun sendLog(item: String, clazz: String) {
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/events/EventNSConnectivityOptionChanged.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/events/EventNSConnectivityOptionChanged.kt
new file mode 100644
index 0000000000..e5a50ba7d5
--- /dev/null
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsShared/events/EventNSConnectivityOptionChanged.kt
@@ -0,0 +1,5 @@
+package info.nightscout.plugins.sync.nsShared.events
+
+import info.nightscout.rx.events.Event
+
+class EventNSConnectivityOptionChanged(val blockingReason: String) : Event()
\ No newline at end of file
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt
index 53ca1d3e73..7adc85cf6a 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NSClientPlugin.kt
@@ -14,7 +14,6 @@ import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toJson
import info.nightscout.core.utils.fabric.FabricPrivacy
-import info.nightscout.core.validators.ValidatingEditTextPreference
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.nsclient.NSAlarm
@@ -41,9 +40,7 @@ import info.nightscout.plugins.sync.nsclient.services.NSClientService
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit
-import info.nightscout.rx.events.EventChargingState
import info.nightscout.rx.events.EventNSClientNewLog
-import info.nightscout.rx.events.EventNetworkChange
import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventSWSyncStatus
import info.nightscout.rx.logging.AAPSLogger
@@ -109,14 +106,6 @@ class NSClientPlugin @Inject constructor(
// Pass to setup wizard
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
}, fabricPrivacy::logException)
- disposable += rxBus
- .toObservable(EventNetworkChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
- disposable += rxBus
- .toObservable(EventPreferenceChange::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventAppExit::class.java)
.observeOn(aapsSchedulers.io)
@@ -128,10 +117,6 @@ class NSClientPlugin @Inject constructor(
addToLog(event)
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
}, fabricPrivacy::logException)
- disposable += rxBus
- .toObservable(EventChargingState::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventNSClientResend::class.java)
.observeOn(aapsSchedulers.io)
@@ -181,7 +166,7 @@ class NSClientPlugin @Inject constructor(
}
}
- override fun detectedNsVersion(): String? = nsSettingsStatus.getVersion()
+ override fun detectedNsVersion(): String = nsSettingsStatus.getVersion()
private fun addToLog(ev: EventNSClientNewLog) {
synchronized(listLog) {
@@ -212,8 +197,8 @@ class NSClientPlugin @Inject constructor(
}
override fun pause(newState: Boolean) {
- sp.putBoolean(R.string.key_ns_client_paused, newState)
- rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
+ sp.putBoolean(R.string.key_ns_paused, newState)
+ rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
}
override val address: String get() = nsClientService?.nsURL ?: ""
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NsClientReceiverDelegate.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NsClientReceiverDelegate.kt
index b515ee08ab..bae5c3fe4b 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NsClientReceiverDelegate.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/NsClientReceiverDelegate.kt
@@ -1,14 +1,19 @@
package info.nightscout.plugins.sync.nsclient
import info.nightscout.androidaps.annotations.OpenForTesting
+import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.plugins.sync.R
+import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
+import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventChargingState
import info.nightscout.rx.events.EventNetworkChange
import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.kotlin.plusAssign
import javax.inject.Inject
import javax.inject.Singleton
@@ -18,26 +23,45 @@ class NsClientReceiverDelegate @Inject constructor(
private val rxBus: RxBus,
private val rh: ResourceHelper,
private val sp: SP,
- private val receiverStatusStore: ReceiverStatusStore
+ private val receiverStatusStore: ReceiverStatusStore,
+ aapsSchedulers: AapsSchedulers,
+ fabricPrivacy: FabricPrivacy
) {
- private var allowedChargingState = true
- private var allowedNetworkState = true
- var allowed = true
- var blockingReason = ""
+ private var allowedChargingState: Boolean? = null
+ private var allowedNetworkState: Boolean? = null
+ var allowed: Boolean = false
+ var blockingReason = "Status not available"
+
+ private val disposable = CompositeDisposable()
+
+ init {
+ disposable += rxBus
+ .toObservable(EventPreferenceChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ ev -> onPreferenceChange(ev) }, fabricPrivacy::logException)
+ disposable += rxBus
+ .toObservable(EventNetworkChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ ev -> onNetworkChange(ev) }, fabricPrivacy::logException)
+ disposable += rxBus
+ .toObservable(EventChargingState::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ ev -> onChargingStateChange(ev) }, fabricPrivacy::logException)
+ }
fun grabReceiversState() {
receiverStatusStore.updateNetworkStatus()
}
- fun onStatusEvent(ev: EventPreferenceChange) {
+ private fun onPreferenceChange(ev: EventPreferenceChange) {
when {
ev.isChanged(rh.gs(R.string.key_ns_wifi)) ||
ev.isChanged(rh.gs(R.string.key_ns_cellular)) ||
ev.isChanged(rh.gs(R.string.key_ns_wifi_ssids)) ||
ev.isChanged(rh.gs(R.string.key_ns_allow_roaming)) -> {
receiverStatusStore.updateNetworkStatus()
- receiverStatusStore.lastNetworkEvent?.let { onStatusEvent(it) }
+ receiverStatusStore.lastNetworkEvent?.let { onNetworkChange(it) }
}
ev.isChanged(rh.gs(R.string.key_ns_charging)) ||
@@ -47,29 +71,30 @@ class NsClientReceiverDelegate @Inject constructor(
}
}
- fun onStatusEvent(ev: EventChargingState) {
+ private fun onChargingStateChange(ev: EventChargingState) {
val newChargingState = calculateStatus(ev)
if (newChargingState != allowedChargingState) {
allowedChargingState = newChargingState
- blockingReason = rh.gs(R.string.blocked_by_charging)
+ if (!newChargingState) blockingReason = rh.gs(R.string.blocked_by_charging)
processStateChange()
}
}
- fun onStatusEvent(ev: EventNetworkChange) {
+ private fun onNetworkChange(ev: EventNetworkChange) {
val newNetworkState = calculateStatus(ev)
if (newNetworkState != allowedNetworkState) {
allowedNetworkState = newNetworkState
- blockingReason = rh.gs(R.string.blocked_by_connectivity)
+ if (!newNetworkState) blockingReason = rh.gs(R.string.blocked_by_connectivity)
processStateChange()
}
}
private fun processStateChange() {
- val newAllowedState = allowedChargingState && allowedNetworkState
+ val newAllowedState = allowedChargingState == true && allowedNetworkState == true
if (newAllowedState != allowed) {
allowed = newAllowedState
- rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
+ if (allowed) blockingReason = ""
+ rxBus.send(EventNSConnectivityOptionChanged(blockingReason))
}
}
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt
index 24aeeaec0b..affb7e1ab2 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclient/services/NSClientService.kt
@@ -33,6 +33,7 @@ import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
+import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
@@ -140,13 +141,21 @@ class NSClientService : DaggerService() {
.subscribe({ event: EventPreferenceChange ->
if (event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_api_secret)) ||
- event.isChanged(rh.gs(R.string.key_ns_client_paused))
+ event.isChanged(rh.gs(R.string.key_ns_paused))
) {
latestDateInReceivedData = 0
destroy()
initialize()
}
}, fabricPrivacy::logException)
+ disposable += rxBus
+ .toObservable(EventNSConnectivityOptionChanged::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({
+ latestDateInReceivedData = 0
+ destroy()
+ initialize()
+ }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventAppExit::class.java)
.observeOn(aapsSchedulers.io)
@@ -218,10 +227,10 @@ class NSClientService : DaggerService() {
@Suppress("DEPRECATION")
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
rxBus.send(EventNSClientStatus("Initializing"))
- if (!nsClientPlugin.isAllowed) {
+ if (nsClientPlugin.isAllowed != true) {
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
- } else if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
+ } else if (sp.getBoolean(R.string.key_ns_paused, false)) {
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
rxBus.send(EventNSClientStatus("Paused"))
} else if (!nsEnabled) {
@@ -230,9 +239,7 @@ class NSClientService : DaggerService() {
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
try {
rxBus.send(EventNSClientStatus("Connecting ..."))
- val opt = IO.Options()
- opt.forceNew = true
- opt.reconnection = true
+ val opt = IO.Options().also { it.forceNew = true }
socket = IO.socket(nsURL, opt).also { socket ->
socket.on(Socket.EVENT_CONNECT, onConnect)
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt
index 894c2ad86a..b80cb08de1 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/NSClientV3Plugin.kt
@@ -3,6 +3,7 @@ package info.nightscout.plugins.sync.nsclientV3
import android.content.Context
import android.os.Handler
import android.os.HandlerThread
+import android.os.SystemClock
import android.text.Spanned
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceScreen
@@ -16,26 +17,34 @@ import com.google.gson.GsonBuilder
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.utils.fabric.FabricPrivacy
+import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.database.ValueWrapper
import info.nightscout.database.entities.interfaces.TraceableDBEntry
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
+import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.nsclient.NSAlarm
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.ProfileFunction
+import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.HtmlHelper
+import info.nightscout.interfaces.utils.JsonHelper
+import info.nightscout.interfaces.workflow.WorkerClasses
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.NSClientFragment
+import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
+import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
+import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
@@ -49,16 +58,17 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryBasal
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
+import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
+import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
+import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit
-import info.nightscout.rx.events.EventChargingState
+import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.events.EventNSClientNewLog
-import info.nightscout.rx.events.EventNetworkChange
-import info.nightscout.rx.events.EventNewBG
import info.nightscout.rx.events.EventNewHistoryData
import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventSWSyncStatus
@@ -66,6 +76,10 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.sdk.NSAndroidClientImpl
import info.nightscout.sdk.interfaces.NSAndroidClient
+import info.nightscout.sdk.mapper.toNSDeviceStatus
+import info.nightscout.sdk.mapper.toNSFood
+import info.nightscout.sdk.mapper.toNSSgvV3
+import info.nightscout.sdk.mapper.toNSTreatment
import info.nightscout.sdk.remotemodel.LastModified
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
@@ -73,15 +87,19 @@ import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
+import io.socket.client.Ack
+import io.socket.client.IO
+import io.socket.client.Socket
+import io.socket.emitter.Emitter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
-import java.util.concurrent.Executors
-import java.util.concurrent.ScheduledFuture
-import java.util.concurrent.TimeUnit
+import org.json.JSONArray
+import org.json.JSONObject
+import java.net.URISyntaxException
import javax.inject.Inject
import javax.inject.Singleton
@@ -102,7 +120,12 @@ class NSClientV3Plugin @Inject constructor(
private val uiInteraction: UiInteraction,
private val dataSyncSelector: DataSyncSelector,
private val profileFunction: ProfileFunction,
- private val repository: AppRepository
+ private val repository: AppRepository,
+ private val nsDeviceStatusHandler: NSDeviceStatusHandler,
+ private val workManager: WorkManager,
+ private val workerClasses: WorkerClasses,
+ private val dataWorkerStorage: DataWorkerStorage,
+ private val nsClientSource: NSClientSource
) : NsClient, Sync, PluginBase(
PluginDescription()
.mainType(PluginType.SYNC)
@@ -118,7 +141,6 @@ class NSClientV3Plugin @Inject constructor(
companion object {
val JOB_NAME: String = this::class.java.simpleName
- val REFRESH_INTERVAL = T.secs(30).msecs()
const val RECORDS_TO_LOAD = 500L
}
@@ -130,14 +152,16 @@ class NSClientV3Plugin @Inject constructor(
override val status
get() =
when {
- sp.getBoolean(R.string.key_ns_client_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
- isAllowed.not() -> blockingReason
- lastOperationError != null -> rh.gs(info.nightscout.core.ui.R.string.error)
- nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
- workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
- nsAndroidClient?.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
- nsAndroidClient?.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
- else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
+ sp.getBoolean(R.string.key_ns_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
+ isAllowed.not() -> blockingReason
+ sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && wsConnected -> "WS: " + rh.gs(info.nightscout.shared.R.string.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)
+ nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
+ workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
+ nsAndroidClient?.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
+ nsAndroidClient?.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
+ else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
}
var lastOperationError: String? = null
@@ -161,26 +185,30 @@ class NSClientV3Plugin @Inject constructor(
)
)
- setClient()
+ setClient("START")
nsClientReceiverDelegate.grabReceiversState()
disposable += rxBus
- .toObservable(EventNetworkChange::class.java)
+ .toObservable(EventNSConnectivityOptionChanged::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ ev ->
- nsClientReceiverDelegate.onStatusEvent(ev)
- setClient()
- rxBus.send(EventNSClientUpdateGUI())
+ rxBus.send(EventNSClientNewLog("● CONNECTIVITY CHANGE", ev.blockingReason))
+ setClient("CONNECTIVITY_CHANGE")
+ if (isAllowed) executeLoop("CONNECTIVITY_CHANGE", forceNew = false)
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ ev ->
- nsClientReceiverDelegate.onStatusEvent(ev)
- if (ev.isChanged(rh.gs(R.string.key_ns_client_token)) || ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)))
- setClient()
+ if (ev.isChanged(rh.gs(R.string.key_ns_client_token)) ||
+ ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
+ ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_ns_use_ws)) ||
+ ev.isChanged(rh.gs(R.string.key_ns_paused))
+ )
+ setClient("SETTING CHANGE")
if (ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_local_profile_last_change)))
- delayAndScheduleExecution("PROFILE_CHANGE")
+ executeUpload("PROFILE_CHANGE", forceNew = true)
+
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventAppExit::class.java)
@@ -193,47 +221,55 @@ class NSClientV3Plugin @Inject constructor(
addToLog(event)
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
}, fabricPrivacy::logException)
- disposable += rxBus
- .toObservable(EventChargingState::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ ev ->
- nsClientReceiverDelegate.onStatusEvent(ev)
- rxBus.send(EventNSClientUpdateGUI())
- }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventNSClientResend::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
- disposable += rxBus
- .toObservable(EventNewBG::class.java)
- .observeOn(aapsSchedulers.io)
- .subscribe({ delayAndScheduleExecution("NEW_BG") }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventNewHistoryData::class.java)
.observeOn(aapsSchedulers.io)
- .subscribe({ delayAndScheduleExecution("NEW_DATA") }, fabricPrivacy::logException)
+ .subscribe({ executeUpload("NEW_DATA", forceNew = false) }, fabricPrivacy::logException)
runLoop = Runnable {
- handler.postDelayed(runLoop, REFRESH_INTERVAL)
+ var refreshInterval = T.mins(5).msecs()
repository.getLastGlucoseValueWrapped().blockingGet().let {
// if last value is older than 5 min or there is no bg
if (it is ValueWrapper.Existing) {
- if (it.value.timestamp < dateUtil.now() - T.mins(5).plus(T.secs(20)).msecs())
+ if (it.value.timestamp < dateUtil.now() - T.mins(5).plus(T.secs(20)).msecs()) {
+ refreshInterval = T.mins(1).msecs()
executeLoop("MAIN_LOOP", forceNew = false)
- else {
- if (isAllowed) rxBus.send(EventNSClientNewLog("RECENT", "No need to load"))
}
} else executeLoop("MAIN_LOOP", forceNew = false)
}
+ handler.postDelayed(runLoop, refreshInterval)
+ rxBus.send(EventNSClientNewLog("● TICK", ""))
+ }
+ handler.postDelayed(runLoop, T.mins(2).msecs())
+ }
+
+ fun scheduleIrregularExecution(refreshToken: Boolean = false) {
+ if (refreshToken) {
+ handler.post { executeLoop("REFRESH TOKEN", forceNew = true) }
+ return
+ }
+ if (config.NSCLIENT || nsClientSource.isEnabled()) {
+ var origin = "5_MIN_AFTER_BG"
+ var forceNew = true
+ var toTime = lastLoadedSrvModified.collections.entries + T.mins(5).plus(T.secs(10)).msecs()
+ if (toTime < dateUtil.now()) {
+ toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
+ origin = "1_MIN_OLD_DATA"
+ forceNew = false
+ }
+ handler.postDelayed({ executeLoop(origin, forceNew = forceNew) }, toTime - dateUtil.now())
+ rxBus.send(EventNSClientNewLog("● NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
}
- handler.postDelayed(runLoop, REFRESH_INTERVAL)
- executeLoop("START", forceNew = false)
}
override fun onStop() {
- // context.applicationContext.unbindService(mConnection)
handler.removeCallbacksAndMessages(null)
disposable.clear()
+ socket?.disconnect()
super.onStop()
}
@@ -257,16 +293,269 @@ class NSClientV3Plugin @Inject constructor(
}
}
- private fun setClient() {
+ private fun setClient(reason: String) {
nsAndroidClient = NSAndroidClientImpl(
baseUrl = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace("https://", "").replace(Regex("/$"), ""),
accessToken = sp.getString(R.string.key_ns_client_token, ""),
context = context,
logging = true
)
+ if (wsConnected)
+ socket?.disconnect()
+ SystemClock.sleep(2000)
+ initializeWebSockets(reason)
rxBus.send(EventSWSyncStatus(status))
}
+ /**********************
+ WS code
+ **********************/
+ private var connectCounter = 0
+ private var socket: Socket? = null
+ var wsConnected = false
+ internal var initialLoadFinished = false
+ private fun initializeWebSockets(reason: String) {
+ if (!sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true)) return
+ val url = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace(Regex("/$"), "") + "/storage"
+ if (!isAllowed) {
+ rxBus.send(EventNSClientNewLog("● WS", blockingReason))
+ } else if (sp.getBoolean(R.string.key_ns_paused, false)) {
+ rxBus.send(EventNSClientNewLog("● WS", "paused"))
+ } else if (url != "") {
+ try {
+ //rxBus.send(EventNSClientStatus("Connecting ..."))
+ val opt = IO.Options().also {
+ it.forceNew = true
+ //it.webSocketFactory = nsAndroidClient.
+ }
+ socket = IO.socket(url, opt).also { socket ->
+ socket.on(Socket.EVENT_CONNECT, onConnect)
+ socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
+ rxBus.send(EventNSClientNewLog("► WS", "do connect $reason"))
+ socket.connect()
+ socket.on("create", onDataCreateUpdate)
+ socket.on("update", onDataCreateUpdate)
+ socket.on("delete", onDataDelete)
+ socket.on("announcement", onAnnouncement)
+ socket.on("alarm", onAlarm)
+ socket.on("urgent_alarm", onUrgentAlarm)
+ socket.on("clear_alarm", onClearAlarm)
+ }
+ } catch (e: URISyntaxException) {
+ rxBus.send(EventNSClientNewLog("● WS", "Wrong URL syntax"))
+ } catch (e: RuntimeException) {
+ rxBus.send(EventNSClientNewLog("● WS", "RuntimeException"))
+ }
+ } else {
+ rxBus.send(EventNSClientNewLog("● WS", "No NS URL specified"))
+ }
+ }
+
+ private val onConnect = Emitter.Listener {
+ connectCounter++
+ val socketId = socket?.id() ?: "NULL"
+ rxBus.send(EventNSClientNewLog("◄ WS", "connect #$connectCounter event. ID: $socketId"))
+ if (socket != null) {
+ val authMessage = JSONObject().also {
+ it.put("accessToken", sp.getString(R.string.key_ns_client_token, ""))
+ it.put("collections", JSONArray(arrayOf("devicestatus", "entries", "profile", "treatments", "foods", "settings")))
+ }
+ rxBus.send(EventNSClientNewLog("► WS", "requesting auth"))
+ socket?.emit("subscribe", authMessage, Ack { args ->
+ val response = args[0] as JSONObject
+ wsConnected = if (response.optBoolean("success")) {
+ rxBus.send(EventNSClientNewLog("◄ WS", "Subscribed for: ${response.optString("collections")}"))
+ true
+ } else {
+ rxBus.send(EventNSClientNewLog("◄ WS", "Auth failed"))
+ false
+ }
+ })
+ }
+ }
+
+ private val onDisconnect = Emitter.Listener { args ->
+ aapsLogger.debug(LTag.NSCLIENT, "disconnect reason: ${args[0]}")
+ rxBus.send(EventNSClientNewLog("◄ WS", "disconnect event"))
+ wsConnected = false
+ initialLoadFinished = false
+ socket = null
+ }
+
+ private val onDataCreateUpdate = Emitter.Listener { args ->
+ val response = args[0] as JSONObject
+ aapsLogger.debug(LTag.NSCLIENT, "onDataCreateUpdate: $response")
+ val collection = response.getString("colName")
+ val docJson = response.getJSONObject("doc")
+ val docString = response.getString("doc")
+ rxBus.send(EventNSClientNewLog("◄ WS CREATE/UPDATE", "$collection $docString"))
+ val srvModified = docJson.getLong("srvModified")
+ lastLoadedSrvModified.set(collection, srvModified)
+ storeLastLoadedSrvModified()
+ when (collection) {
+ "devicestatus" -> docString.toNSDeviceStatus().let { nsDeviceStatusHandler.handleNewData(arrayOf(it)) }
+ "entries" -> docString.toNSSgvV3()?.let {
+ workManager.beginUniqueWork(
+ JOB_NAME + collection,
+ ExistingWorkPolicy.APPEND_OR_REPLACE,
+ OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
+ )
+ .then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build())
+ .enqueue()
+ }
+
+ "profile" ->
+ workManager.enqueueUniqueWork(
+ JOB_NAME + collection,
+ ExistingWorkPolicy.APPEND_OR_REPLACE,
+ OneTimeWorkRequest.Builder(workerClasses.nsProfileWorker).setInputData(dataWorkerStorage.storeInputData(docJson)).build()
+ )
+
+ "treatments" -> docString.toNSTreatment()?.let {
+ workManager.beginUniqueWork(
+ JOB_NAME + collection,
+ ExistingWorkPolicy.APPEND_OR_REPLACE,
+ OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
+ )
+ .then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build())
+ .enqueue()
+ }
+
+ "foods" -> docString.toNSFood()?.let {
+ workManager.beginUniqueWork(
+ JOB_NAME + collection,
+ ExistingWorkPolicy.APPEND_OR_REPLACE,
+ OneTimeWorkRequest.Builder(ProcessFoodWorker::class.java).setInputData(dataWorkerStorage.storeInputData(listOf(it))).build()
+ )
+ .then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreFoodWorker::class.java).build())
+ .enqueue()
+ }
+
+ "settings" -> {}
+ }
+ }
+
+ private val onDataDelete = Emitter.Listener { args ->
+ val response = args[0] as JSONObject
+ aapsLogger.debug(LTag.NSCLIENT, "onDataDelete: $response")
+ rxBus.send(EventNSClientNewLog("◄ WS DELETE", "${response.optString("collection")} ${response.optString("doc")}"))
+ }
+
+ private val onAnnouncement = Emitter.Listener { args ->
+
+ /*
+ {
+ "level":0,
+ "title":"Announcement",
+ "message":"test",
+ "plugin":{"name":"treatmentnotify","label":"Treatment Notifications","pluginType":"notification","enabled":true},
+ "group":"Announcement",
+ "isAnnouncement":true,
+ "key":"9ac46ad9a1dcda79dd87dae418fce0e7955c68da"
+ }
+ */
+ val data: JSONObject
+ try {
+ data = args[0] as JSONObject
+ handleAnnouncement(data)
+ } catch (e: Exception) {
+ aapsLogger.error("Unhandled exception", e)
+ }
+ }
+ private val onAlarm = Emitter.Listener { args ->
+
+ /*
+ {
+ "level":1,
+ "title":"Warning HIGH",
+ "message":"BG Now: 5 -0.2 → mmol\/L\nRaw BG: 4.8 mmol\/L Čistý\nBG 15m: 4.8 mmol\/L\nIOB: -0.02U\nCOB: 0g",
+ "eventName":"high",
+ "plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true},
+ "pushoverSound":"climb",
+ "debug":{"lastSGV":5,"thresholds":{"bgHigh":180,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}},
+ "group":"default",
+ "key":"simplealarms_1"
+ }
+ */
+ val data: JSONObject
+ try {
+ data = args[0] as JSONObject
+ handleAlarm(data)
+ } catch (e: Exception) {
+ aapsLogger.error("Unhandled exception", e)
+ }
+ }
+ private val onUrgentAlarm = Emitter.Listener { args: Array ->
+ val data: JSONObject
+ try {
+ data = args[0] as JSONObject
+ handleUrgentAlarm(data)
+ } catch (e: Exception) {
+ aapsLogger.error("Unhandled exception", e)
+ }
+ }
+ private val onClearAlarm = Emitter.Listener { args ->
+
+ /*
+ {
+ "clear":true,
+ "title":"All Clear",
+ "message":"default - Urgent was ack'd",
+ "group":"default"
+ }
+ */
+ val data: JSONObject
+ try {
+ data = args[0] as JSONObject
+ rxBus.send(EventNSClientNewLog("CLEARALARM", "received"))
+ rxBus.send(EventDismissNotification(Notification.NS_ALARM))
+ rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
+ aapsLogger.debug(LTag.NSCLIENT, data.toString())
+ } catch (e: Exception) {
+ aapsLogger.error("Unhandled exception", e)
+ }
+ }
+
+ private fun handleAnnouncement(announcement: JSONObject) {
+ val defaultVal = config.NSCLIENT
+ if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_announcements, defaultVal)) {
+ val nsAlarm = NSAlarm(announcement)
+ uiInteraction.addNotificationWithAction(injector, nsAlarm)
+ rxBus.send(EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(announcement, "message", "received")))
+ aapsLogger.debug(LTag.NSCLIENT, announcement.toString())
+ }
+ }
+
+ private fun handleAlarm(alarm: JSONObject) {
+ val defaultVal = config.NSCLIENT
+ if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, defaultVal)) {
+ val snoozedTo = sp.getLong(info.nightscout.core.utils.R.string.key_snoozed_to, 0L)
+ if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
+ val nsAlarm = NSAlarm(alarm)
+ uiInteraction.addNotificationWithAction(injector, nsAlarm)
+ }
+ rxBus.send(EventNSClientNewLog("ALARM", JsonHelper.safeGetString(alarm, "message", "received")))
+ aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
+ }
+ }
+
+ private fun handleUrgentAlarm(alarm: JSONObject) {
+ val defaultVal = config.NSCLIENT
+ if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, defaultVal)) {
+ val snoozedTo = sp.getLong(info.nightscout.core.utils.R.string.key_snoozed_to, 0L)
+ if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
+ val nsAlarm = NSAlarm(alarm)
+ uiInteraction.addNotificationWithAction(injector, nsAlarm)
+ }
+ rxBus.send(EventNSClientNewLog("URGENTALARM", JsonHelper.safeGetString(alarm, "message", "received")))
+ aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
+ }
+ }
+
+ /**********************
+ WS code end
+ **********************/
+
private fun addToLog(ev: EventNSClientNewLog) {
synchronized(listLog) {
listLog.add(ev)
@@ -292,12 +581,15 @@ class NSClientV3Plugin @Inject constructor(
}
override fun resend(reason: String) {
- executeLoop("RESEND", forceNew = false)
+ if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true))
+ executeUpload("RESEND", forceNew = false)
+ else
+ executeLoop("RESEND", forceNew = false)
}
override fun pause(newState: Boolean) {
- sp.putBoolean(R.string.key_ns_client_paused, newState)
- rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
+ sp.putBoolean(R.string.key_ns_paused, newState)
+ rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
}
override fun detectedNsVersion(): String? = nsAndroidClient?.lastStatus?.version
@@ -337,6 +629,7 @@ class NSClientV3Plugin @Inject constructor(
override fun resetToFullSync() {
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
lastLoadedSrvModified = LastModified(LastModified.Collections())
+ initialLoadFinished = false
storeLastLoadedSrvModified()
}
@@ -355,15 +648,15 @@ class NSClientV3Plugin @Inject constructor(
val data = (dataPair as DataSyncSelector.PairProfileStore).value
scope.launch {
try {
- rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} $data $progress"))
+ rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} $data $progress"))
nsAndroidClient?.createProfileStore(data)?.let { result ->
when (result.response) {
- 200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ProfileStore"))
- 201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ProfileStore"))
- 404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ProfileStore"))
+ 201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ProfileStore"))
+ 404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
- rxBus.send(EventNSClientNewLog("ERROR", "ProfileStore"))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", "ProfileStore"))
return@launch
}
}
@@ -385,15 +678,15 @@ class NSClientV3Plugin @Inject constructor(
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
scope.launch {
try {
- rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"))
+ rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"))
nsAndroidClient?.createDeviceStatus(data)?.let { result ->
when (result.response) {
- 200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
- 201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
- 404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
+ 404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
- rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
return@launch
}
}
@@ -426,24 +719,24 @@ class NSClientV3Plugin @Inject constructor(
rxBus.send(
EventNSClientNewLog(
when (operation) {
- Operation.CREATE -> "ADD $collection"
- Operation.UPDATE -> "UPDATE $collection"
+ Operation.CREATE -> "► ADD $collection"
+ Operation.UPDATE -> "► UPDATE $collection"
},
when (operation) {
- Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
- Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
+ Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
+ Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
}
)
)
call?.let { it(data) }?.let { result ->
when (result.response) {
- 200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
- 201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
- 400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
- 404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
- rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
return@launch
}
}
@@ -481,24 +774,24 @@ class NSClientV3Plugin @Inject constructor(
rxBus.send(
EventNSClientNewLog(
when (operation) {
- Operation.CREATE -> "ADD $collection"
- Operation.UPDATE -> "UPDATE $collection"
+ Operation.CREATE -> "► ADD $collection"
+ Operation.UPDATE -> "► UPDATE $collection"
},
when (operation) {
- Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
- Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
+ Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
+ Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
}
)
)
call?.let { it(data) }?.let { result ->
when (result.response) {
- 200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
- 201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
- 400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
- 404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
- rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
return@launch
}
}
@@ -564,24 +857,24 @@ class NSClientV3Plugin @Inject constructor(
rxBus.send(
EventNSClientNewLog(
when (operation) {
- Operation.CREATE -> "ADD $collection"
- Operation.UPDATE -> "UPDATE $collection"
+ Operation.CREATE -> "► ADD $collection"
+ Operation.UPDATE -> "► UPDATE $collection"
},
when (operation) {
- Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
- Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
+ Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
+ Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
}
)
)
call?.let { it(data) }?.let { result ->
when (result.response) {
- 200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
- 201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
- 400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
- 404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
+ 400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
+ 404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
else -> {
- rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
return@launch
}
}
@@ -708,35 +1001,23 @@ class NSClientV3Plugin @Inject constructor(
sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastLoadedSrvModified))
}
- fun scheduleIrregularExecution() {
- var origin = "5_MIN_AFTER_BG"
- var forceNew = true
- var toTime = lastLoadedSrvModified.collections.entries + T.mins(5).plus(T.secs(10)).msecs()
- if (toTime < dateUtil.now()) {
- toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
- origin = "1_MIN_OLD_DATA"
- forceNew = false
- }
- handler.postDelayed({ executeLoop(origin, forceNew = forceNew) }, toTime - dateUtil.now())
- rxBus.send(EventNSClientNewLog("NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
- }
-
private fun executeLoop(origin: String, forceNew: Boolean) {
- if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
- rxBus.send(EventNSClientNewLog("RUN", "paused"))
+ if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && initialLoadFinished) return
+ if (sp.getBoolean(R.string.key_ns_paused, false)) {
+ rxBus.send(EventNSClientNewLog("● RUN", "paused $origin"))
return
}
if (!isAllowed) {
- rxBus.send(EventNSClientNewLog("RUN", blockingReason))
+ rxBus.send(EventNSClientNewLog("● RUN", "$blockingReason $origin"))
return
}
if (workIsRunning(arrayOf(JOB_NAME))) {
- rxBus.send(EventNSClientNewLog("RUN", "Already running $origin"))
+ rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
if (!forceNew) return
// Wait for end and start new cycle
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
}
- rxBus.send(EventNSClientNewLog("RUN", "Starting next round $origin"))
+ rxBus.send(EventNSClientNewLog("● RUN", "Starting next round $origin"))
WorkManager.getInstance(context)
.beginUniqueWork(
JOB_NAME,
@@ -754,6 +1035,30 @@ class NSClientV3Plugin @Inject constructor(
.enqueue()
}
+ private fun executeUpload(origin: String, forceNew: Boolean) {
+ if (sp.getBoolean(R.string.key_ns_paused, false)) {
+ rxBus.send(EventNSClientNewLog("● RUN", "paused"))
+ return
+ }
+ if (!isAllowed) {
+ rxBus.send(EventNSClientNewLog("● RUN", blockingReason))
+ return
+ }
+ if (workIsRunning(arrayOf(JOB_NAME))) {
+ rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
+ if (!forceNew) return
+ // Wait for end and start new cycle
+ while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
+ }
+ rxBus.send(EventNSClientNewLog("● RUN", "Starting upload $origin"))
+ WorkManager.getInstance(context)
+ .enqueueUniqueWork(
+ JOB_NAME,
+ ExistingWorkPolicy.REPLACE,
+ OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build()
+ )
+ }
+
private fun workIsRunning(workNames: Array): Boolean {
for (workName in workNames)
for (workInfo in WorkManager.getInstance(context).getWorkInfosForUniqueWork(workName).get())
@@ -761,20 +1066,4 @@ class NSClientV3Plugin @Inject constructor(
return true
return false
}
-
- private val eventWorker = Executors.newSingleThreadScheduledExecutor()
- private var scheduledEventPost: ScheduledFuture<*>? = null
- private fun delayAndScheduleExecution(origin: String) {
- class PostRunnable : Runnable {
-
- override fun run() {
- scheduledEventPost = null
- executeLoop(origin, forceNew = true)
- }
- }
- // cancel waiting task to prevent sending multiple posts
- scheduledEventPost?.cancel(false)
- val task: Runnable = PostRunnable()
- scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
- }
}
\ No newline at end of file
diff --git a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt
index 0c446063b6..69b1d5204f 100644
--- a/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt
+++ b/plugins/sync/src/main/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorker.kt
@@ -7,6 +7,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
+import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import kotlinx.coroutines.Dispatchers
@@ -20,12 +21,17 @@ class DataSyncWorker(
@Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rxBus: RxBus
+ @Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
override suspend fun doWorkAndLog(): Result {
- if (activePlugin.activeNsClient?.hasWritePermission == true) {
- rxBus.send(EventNSClientNewLog("UPL", "Start"))
+ if (activePlugin.activeNsClient?.hasWritePermission == true || nsClientV3Plugin.wsConnected) {
+ rxBus.send(EventNSClientNewLog("► UPL", "Start"))
dataSyncSelector.doUpload()
- rxBus.send(EventNSClientNewLog("UPL", "End"))
+ rxBus.send(EventNSClientNewLog("► UPL", "End"))
+ } else {
+ rxBus.send(EventNSClientNewLog("► ERROR", "Not connected or write permission"))
+ // refresh token
+ nsClientV3Plugin.scheduleIrregularExecution(refreshToken = true)
}
rxBus.send(EventNSClientUpdateGUI())
return Result.success()
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 93afbb4d5f..3c1451eee8 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
@@ -70,7 +70,7 @@ class LoadBgWorker(
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)}"))
+ 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
@@ -90,7 +90,7 @@ class LoadBgWorker(
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
nsClientV3Plugin.storeLastLoadedSrvModified()
}
- rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
workManager
.beginUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -106,7 +106,7 @@ class LoadBgWorker(
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
nsClientV3Plugin.storeLastLoadedSrvModified()
}
- rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
workManager
.beginUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -118,7 +118,7 @@ class LoadBgWorker(
}
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 437f2acae2..4a3acdfce1 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
@@ -33,15 +33,18 @@ class LoadDeviceStatusWorker(
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
try {
+ // Notify plugin we loaded al missed data
+ nsClientV3Plugin.initialLoadFinished = true
+
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)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray())
- rxBus.send(EventNSClientNewLog("DONE DS", ""))
+ rxBus.send(EventNSClientNewLog("● DONE PROCESSING DS", ""))
} else {
- rxBus.send(EventNSClientNewLog("RCV END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV DS END", "No data from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
}
WorkManager.getInstance(context)
.enqueueUniqueWork(
@@ -51,7 +54,7 @@ class LoadDeviceStatusWorker(
)
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 8a92a1f703..74b3b5ff25 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
@@ -40,7 +40,7 @@ class LoadFoodsWorker(
if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) {
val foods: List = nsAndroidClient.getFoods(1000).values
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
WorkManager.getInstance(context)
.beginUniqueWork(
@@ -53,7 +53,7 @@ class LoadFoodsWorker(
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
.enqueue()
} else {
- rxBus.send(EventNSClientNewLog("RCV", "FOOD skipped"))
+ rxBus.send(EventNSClientNewLog("● RCV FOOD", "skipped"))
WorkManager.getInstance(context)
.enqueueUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -63,7 +63,7 @@ class LoadFoodsWorker(
}
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 c4333ab28b..addcf27ce6 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
@@ -27,7 +27,7 @@ class LoadLastModificationWorker(
aapsLogger.debug(LTag.NSCLIENT, "LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}")
} catch (error: Exception) {
aapsLogger.error(LTag.NSCLIENT, "Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 0acae4ffc4..84b3cf245d 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
@@ -57,7 +57,7 @@ class LoadProfileStoreWorker(
{ nsClientV3Plugin.lastLoadedSrvModified.collections.profile = dateUtil.now() }
nsClientV3Plugin.storeLastLoadedSrvModified()
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)
.beginUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -68,7 +68,7 @@ class LoadProfileStoreWorker(
).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
.enqueue()
} else {
- rxBus.send(EventNSClientNewLog("RCV END", "No new PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
WorkManager.getInstance(context)
.enqueueUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -77,7 +77,7 @@ class LoadProfileStoreWorker(
)
}
} else {
- rxBus.send(EventNSClientNewLog("RCV END", "No PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
+ rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
WorkManager.getInstance(context)
.enqueueUniqueWork(
NSClientV3Plugin.JOB_NAME,
@@ -87,7 +87,7 @@ class LoadProfileStoreWorker(
}
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 d51a286306..806e743f1d 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
@@ -26,7 +26,7 @@ class LoadStatusWorker(
aapsLogger.debug(LTag.NSCLIENT, "STATUS: $status")
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 b5159fa9bf..7e91ed9281 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
@@ -11,6 +11,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.core.utils.worker.then
import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.sync.NsClient
+import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
@@ -57,14 +58,14 @@ class LoadTreatmentsWorker(
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)}"))
+ 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))
+ .setInputData(dataWorkerStorage.storeInputData(response.values))
.build()
)
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
@@ -77,14 +78,15 @@ class LoadTreatmentsWorker(
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
nsClientV3Plugin.storeLastLoadedSrvModified()
}
- rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
- storeDataForDb.storeTreatmentsToDb()
+ rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
WorkManager.getInstance(context)
- .enqueueUniqueWork(
+ .beginUniqueWork(
NSClientV3Plugin.JOB_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE,
- OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()
+ OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
)
+ .then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
+ .enqueue()
}
} else {
// End first load
@@ -92,18 +94,19 @@ class LoadTreatmentsWorker(
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
nsClientV3Plugin.storeLastLoadedSrvModified()
}
- rxBus.send(EventNSClientNewLog("RCV END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
- storeDataForDb.storeTreatmentsToDb()
+ rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
WorkManager.getInstance(context)
- .enqueueUniqueWork(
+ .beginUniqueWork(
NSClientV3Plugin.JOB_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE,
- OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()
+ OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
)
+ .then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
+ .enqueue()
}
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
nsClientV3Plugin.lastOperationError = error.localizedMessage
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 32bdc3ac54..b6254b7931 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
@@ -72,7 +72,7 @@ class ProcessFoodWorker(
storeDataForDb.foods.addAll(foods)
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
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 3f96ad4922..fb1e1e3cde 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
@@ -24,7 +24,6 @@ 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
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
import info.nightscout.sdk.localmodel.treatment.NSCarbs
@@ -57,12 +56,12 @@ class ProcessTreatmentsWorker(
override suspend fun doWorkAndLog(): Result {
@Suppress("UNCHECKED_CAST")
- val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse>?
+ val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List?
?: return Result.failure(workDataOf("Error" to "missing input data"))
try {
var latestDateInReceivedData: Long = 0
- for (treatment in treatments.values) {
+ for (treatment in treatments) {
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
val date = treatment.date ?: continue
if (date > latestDateInReceivedData) latestDateInReceivedData = date
@@ -139,7 +138,7 @@ class ProcessTreatmentsWorker(
// xDripBroadcast.sendTreatments(treatments)
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
- rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
+ rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
return Result.failure(workDataOf("Error" to error.localizedMessage))
}
return Result.success()
diff --git a/plugins/sync/src/main/res/values/strings.xml b/plugins/sync/src/main/res/values/strings.xml
index ce19f868b7..44263daa2d 100644
--- a/plugins/sync/src/main/res/values/strings.xml
+++ b/plugins/sync/src/main/res/values/strings.xml
@@ -48,7 +48,7 @@
ns_client_autoscroll
- ns_client_paused
+ ns_client_paused
ns_log_app_started_event
NSCLIENT has no write permission. Wrong API secret?
@@ -171,5 +171,7 @@
Data Broadcaster
+ Connect to websockets
+ Enabling means: faster updates, receiving alarms and announcements and higher battery consumption similar to v1. All other uploaderds to NS must use v3 protocol.
\ No newline at end of file
diff --git a/plugins/sync/src/main/res/xml/pref_ns_client_v3.xml b/plugins/sync/src/main/res/xml/pref_ns_client_v3.xml
index 79f5b522af..974a2b89d9 100644
--- a/plugins/sync/src/main/res/xml/pref_ns_client_v3.xml
+++ b/plugins/sync/src/main/res/xml/pref_ns_client_v3.xml
@@ -9,7 +9,7 @@
app:initialExpandedChildrenCount="0">
+ validate:testType="minLength" />
+
+