NSCv3: websockets support
This commit is contained in:
parent
9757428577
commit
89ad9e21dd
29 changed files with 576 additions and 210 deletions
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.sdk.mapper
|
package info.nightscout.sdk.mapper
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
||||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||||
|
@ -8,6 +9,9 @@ import org.json.JSONObject
|
||||||
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
|
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
|
||||||
toRemoteDeviceStatus().toNSDeviceStatus()
|
toRemoteDeviceStatus().toNSDeviceStatus()
|
||||||
|
|
||||||
|
fun String.toNSDeviceStatus(): NSDeviceStatus =
|
||||||
|
Gson().fromJson(this, RemoteDeviceStatus::class.java).toNSDeviceStatus()
|
||||||
|
|
||||||
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
|
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
|
||||||
NSDeviceStatus(
|
NSDeviceStatus(
|
||||||
app = app,
|
app = app,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.sdk.mapper
|
package info.nightscout.sdk.mapper
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
import info.nightscout.sdk.localmodel.food.NSFood
|
import info.nightscout.sdk.localmodel.food.NSFood
|
||||||
import info.nightscout.sdk.remotemodel.RemoteFood
|
import info.nightscout.sdk.remotemodel.RemoteFood
|
||||||
|
|
||||||
|
@ -12,6 +13,9 @@ import info.nightscout.sdk.remotemodel.RemoteFood
|
||||||
fun NSFood.convertToRemoteAndBack(): NSFood? =
|
fun NSFood.convertToRemoteAndBack(): NSFood? =
|
||||||
toRemoteFood().toNSFood()
|
toRemoteFood().toNSFood()
|
||||||
|
|
||||||
|
fun String.toNSFood(): NSFood? =
|
||||||
|
Gson().fromJson(this, RemoteFood::class.java).toNSFood()
|
||||||
|
|
||||||
internal fun RemoteFood.toNSFood(): NSFood? {
|
internal fun RemoteFood.toNSFood(): NSFood? {
|
||||||
when (type) {
|
when (type) {
|
||||||
"food" ->
|
"food" ->
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.sdk.mapper
|
package info.nightscout.sdk.mapper
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
import info.nightscout.sdk.localmodel.entry.Direction
|
import info.nightscout.sdk.localmodel.entry.Direction
|
||||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||||
|
@ -8,6 +9,9 @@ import info.nightscout.sdk.remotemodel.RemoteEntry
|
||||||
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
|
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
|
||||||
toRemoteEntry().toSgv()
|
toRemoteEntry().toSgv()
|
||||||
|
|
||||||
|
fun String.toNSSgvV3(): NSSgvV3? =
|
||||||
|
Gson().fromJson(this, RemoteEntry::class.java).toSgv()
|
||||||
|
|
||||||
internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
||||||
|
|
||||||
this.sgv ?: return null
|
this.sgv ?: return null
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.sdk.mapper
|
package info.nightscout.sdk.mapper
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||||
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
||||||
|
@ -26,6 +27,9 @@ import java.util.concurrent.TimeUnit
|
||||||
fun NSTreatment.convertToRemoteAndBack(): NSTreatment? =
|
fun NSTreatment.convertToRemoteAndBack(): NSTreatment? =
|
||||||
toRemoteTreatment()?.toTreatment()
|
toRemoteTreatment()?.toTreatment()
|
||||||
|
|
||||||
|
fun String.toNSTreatment(): NSTreatment? =
|
||||||
|
Gson().fromJson(this, RemoteTreatment::class.java).toTreatment()
|
||||||
|
|
||||||
internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
||||||
val treatmentTimestamp = timestamp()
|
val treatmentTimestamp = timestamp()
|
||||||
when {
|
when {
|
||||||
|
|
|
@ -22,4 +22,15 @@ data class LastModified(
|
||||||
@SerializedName("foods") var foods: Long = 0, // foods collection
|
@SerializedName("foods") var foods: Long = 0, // foods collection
|
||||||
@SerializedName("settings") var settings: Long = 0 // settings 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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
||||||
<string name="key_nsclientinternal_url" translatable="false">nsclientinternal_url</string>
|
<string name="key_nsclientinternal_url" translatable="false">nsclientinternal_url</string>
|
||||||
<string name="key_nsclientinternal_api_secret" translatable="false">nsclientinternal_api_secret</string>
|
<string name="key_nsclientinternal_api_secret" translatable="false">nsclientinternal_api_secret</string>
|
||||||
|
<string name="key_ns_use_ws" translatable="false">ns_use_ws</string>
|
||||||
<string name="key_ns_receive_insulin" translatable="false">ns_receive_insulin</string>
|
<string name="key_ns_receive_insulin" translatable="false">ns_receive_insulin</string>
|
||||||
<string name="key_ns_receive_carbs" translatable="false">ns_receive_carbs</string>
|
<string name="key_ns_receive_carbs" translatable="false">ns_receive_carbs</string>
|
||||||
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
||||||
|
|
|
@ -75,7 +75,7 @@ class RunningConfigurationImpl @Inject constructor(
|
||||||
assert(config.NSCLIENT)
|
assert(config.NSCLIENT)
|
||||||
|
|
||||||
configuration.version?.let {
|
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())
|
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)
|
uiInteraction.addNotification(Notification.NSCLIENT_VERSION_DOES_NOT_MATCH, rh.gs(R.string.nsclient_version_does_not_match), Notification.NORMAL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ class NSClientSourcePlugin @Inject constructor(
|
||||||
return TransactionGlucoseValue(
|
return TransactionGlucoseValue(
|
||||||
timestamp = sgv.date ?: throw InvalidParameterException(),
|
timestamp = sgv.date ?: throw InvalidParameterException(),
|
||||||
value = sgv.sgv,
|
value = sgv.sgv,
|
||||||
noise = sgv.noise?.toDouble(),
|
noise = sgv.noise,
|
||||||
raw = sgv.filtered,
|
raw = sgv.filtered,
|
||||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
|
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
|
||||||
nightscoutId = sgv.identifier,
|
nightscoutId = sgv.identifier,
|
||||||
|
|
|
@ -60,6 +60,7 @@ abstract class SyncModule {
|
||||||
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
|
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
|
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
|
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
|
||||||
|
@ContributesAndroidInjector abstract fun contributesStoreTreatmentsWorker(): StoreDataForDbImpl.StoreTreatmentsWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
||||||
|
|
|
@ -57,7 +57,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private val queueCounter = QueueCounter()
|
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()
|
override fun queueSize(): Long = queueCounter.size()
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
||||||
updateGui()
|
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 ->
|
binding.paused.setOnCheckedChangeListener { _, isChecked ->
|
||||||
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
|
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
|
||||||
nsClientPlugin?.pause(isChecked)
|
nsClientPlugin?.pause(isChecked)
|
||||||
|
@ -143,7 +143,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
||||||
|
|
||||||
private fun updateGui() {
|
private fun updateGui() {
|
||||||
if (_binding == null) return
|
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()
|
binding.log.text = nsClientPlugin?.textLog()
|
||||||
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||||
binding.url.text = nsClientPlugin?.address
|
binding.url.text = nsClientPlugin?.address
|
||||||
|
|
|
@ -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 <T> HashMap<T, Long>.inc(key: T) =
|
fun <T> HashMap<T, Long>.inc(key: T) =
|
||||||
if (containsKey(key)) merge(key, 1, Long::plus)
|
if (containsKey(key)) merge(key, 1, Long::plus)
|
||||||
else put(key, 1)
|
else put(key, 1)
|
||||||
|
|
||||||
override fun storeGlucoseValuesToDb() {
|
override fun storeGlucoseValuesToDb() {
|
||||||
rxBus.send(EventNSClientNewLog("PROCESSING BG", ""))
|
|
||||||
|
|
||||||
if (glucoseValues.isNotEmpty())
|
if (glucoseValues.isNotEmpty())
|
||||||
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
||||||
.doOnError {
|
.doOnError {
|
||||||
|
@ -184,12 +195,10 @@ class StoreDataForDbImpl @Inject constructor(
|
||||||
|
|
||||||
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
|
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
|
||||||
SystemClock.sleep(pause)
|
SystemClock.sleep(pause)
|
||||||
rxBus.send(EventNSClientNewLog("DONE BG", ""))
|
rxBus.send(EventNSClientNewLog("● DONE PROCESSING BG", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeFoodsToDb() {
|
override fun storeFoodsToDb() {
|
||||||
rxBus.send(EventNSClientNewLog("PROCESSING FOOD", ""))
|
|
||||||
|
|
||||||
if (foods.isNotEmpty())
|
if (foods.isNotEmpty())
|
||||||
repository.runTransactionForResult(SyncNsFoodTransaction(foods))
|
repository.runTransactionForResult(SyncNsFoodTransaction(foods))
|
||||||
.doOnError {
|
.doOnError {
|
||||||
|
@ -214,12 +223,10 @@ class StoreDataForDbImpl @Inject constructor(
|
||||||
|
|
||||||
sendLog("Food", Food::class.java.simpleName)
|
sendLog("Food", Food::class.java.simpleName)
|
||||||
SystemClock.sleep(pause)
|
SystemClock.sleep(pause)
|
||||||
rxBus.send(EventNSClientNewLog("DONE FOOD", ""))
|
rxBus.send(EventNSClientNewLog("● DONE PROCESSING FOOD", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeTreatmentsToDb() {
|
override fun storeTreatmentsToDb() {
|
||||||
rxBus.send(EventNSClientNewLog("PROCESSING TR", ""))
|
|
||||||
|
|
||||||
if (boluses.isNotEmpty())
|
if (boluses.isNotEmpty())
|
||||||
repository.runTransactionForResult(SyncNsBolusTransaction(boluses))
|
repository.runTransactionForResult(SyncNsBolusTransaction(boluses))
|
||||||
.doOnError {
|
.doOnError {
|
||||||
|
@ -796,7 +803,7 @@ class StoreDataForDbImpl @Inject constructor(
|
||||||
SystemClock.sleep(pause)
|
SystemClock.sleep(pause)
|
||||||
|
|
||||||
uel.log(userEntries)
|
uel.log(userEntries)
|
||||||
rxBus.send(EventNSClientNewLog("DONE TR", ""))
|
rxBus.send(EventNSClientNewLog("● DONE PROCESSING TR", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||||
|
@ -996,7 +1003,7 @@ class StoreDataForDbImpl @Inject constructor(
|
||||||
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
||||||
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
||||||
sendLog("ExtendedBolus", ExtendedBolus::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) {
|
private fun sendLog(item: String, clazz: String) {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.plugins.sync.nsShared.events
|
||||||
|
|
||||||
|
import info.nightscout.rx.events.Event
|
||||||
|
|
||||||
|
class EventNSConnectivityOptionChanged(val blockingReason: String) : Event()
|
|
@ -14,7 +14,6 @@ import androidx.preference.SwitchPreference
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.core.extensions.toJson
|
import info.nightscout.core.extensions.toJson
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.core.validators.ValidatingEditTextPreference
|
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
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.AapsSchedulers
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventAppExit
|
import info.nightscout.rx.events.EventAppExit
|
||||||
import info.nightscout.rx.events.EventChargingState
|
|
||||||
import info.nightscout.rx.events.EventNSClientNewLog
|
import info.nightscout.rx.events.EventNSClientNewLog
|
||||||
import info.nightscout.rx.events.EventNetworkChange
|
|
||||||
import info.nightscout.rx.events.EventPreferenceChange
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
import info.nightscout.rx.events.EventSWSyncStatus
|
import info.nightscout.rx.events.EventSWSyncStatus
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
|
@ -109,14 +106,6 @@ class NSClientPlugin @Inject constructor(
|
||||||
// Pass to setup wizard
|
// Pass to setup wizard
|
||||||
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
||||||
}, fabricPrivacy::logException)
|
}, 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
|
disposable += rxBus
|
||||||
.toObservable(EventAppExit::class.java)
|
.toObservable(EventAppExit::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
|
@ -128,10 +117,6 @@ class NSClientPlugin @Inject constructor(
|
||||||
addToLog(event)
|
addToLog(event)
|
||||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventChargingState::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNSClientResend::class.java)
|
.toObservable(EventNSClientResend::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.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) {
|
private fun addToLog(ev: EventNSClientNewLog) {
|
||||||
synchronized(listLog) {
|
synchronized(listLog) {
|
||||||
|
@ -212,8 +197,8 @@ class NSClientPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pause(newState: Boolean) {
|
override fun pause(newState: Boolean) {
|
||||||
sp.putBoolean(R.string.key_ns_client_paused, newState)
|
sp.putBoolean(R.string.key_ns_paused, newState)
|
||||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override val address: String get() = nsClientService?.nsURL ?: ""
|
override val address: String get() = nsClientService?.nsURL ?: ""
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
package info.nightscout.plugins.sync.nsclient
|
package info.nightscout.plugins.sync.nsclient
|
||||||
|
|
||||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.plugins.sync.R
|
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.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventChargingState
|
import info.nightscout.rx.events.EventChargingState
|
||||||
import info.nightscout.rx.events.EventNetworkChange
|
import info.nightscout.rx.events.EventNetworkChange
|
||||||
import info.nightscout.rx.events.EventPreferenceChange
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -18,26 +23,45 @@ class NsClientReceiverDelegate @Inject constructor(
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val rh: ResourceHelper,
|
private val rh: ResourceHelper,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val receiverStatusStore: ReceiverStatusStore
|
private val receiverStatusStore: ReceiverStatusStore,
|
||||||
|
aapsSchedulers: AapsSchedulers,
|
||||||
|
fabricPrivacy: FabricPrivacy
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private var allowedChargingState = true
|
private var allowedChargingState: Boolean? = null
|
||||||
private var allowedNetworkState = true
|
private var allowedNetworkState: Boolean? = null
|
||||||
var allowed = true
|
var allowed: Boolean = false
|
||||||
var blockingReason = ""
|
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() {
|
fun grabReceiversState() {
|
||||||
receiverStatusStore.updateNetworkStatus()
|
receiverStatusStore.updateNetworkStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onStatusEvent(ev: EventPreferenceChange) {
|
private fun onPreferenceChange(ev: EventPreferenceChange) {
|
||||||
when {
|
when {
|
||||||
ev.isChanged(rh.gs(R.string.key_ns_wifi)) ||
|
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_cellular)) ||
|
||||||
ev.isChanged(rh.gs(R.string.key_ns_wifi_ssids)) ||
|
ev.isChanged(rh.gs(R.string.key_ns_wifi_ssids)) ||
|
||||||
ev.isChanged(rh.gs(R.string.key_ns_allow_roaming)) -> {
|
ev.isChanged(rh.gs(R.string.key_ns_allow_roaming)) -> {
|
||||||
receiverStatusStore.updateNetworkStatus()
|
receiverStatusStore.updateNetworkStatus()
|
||||||
receiverStatusStore.lastNetworkEvent?.let { onStatusEvent(it) }
|
receiverStatusStore.lastNetworkEvent?.let { onNetworkChange(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
ev.isChanged(rh.gs(R.string.key_ns_charging)) ||
|
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)
|
val newChargingState = calculateStatus(ev)
|
||||||
if (newChargingState != allowedChargingState) {
|
if (newChargingState != allowedChargingState) {
|
||||||
allowedChargingState = newChargingState
|
allowedChargingState = newChargingState
|
||||||
blockingReason = rh.gs(R.string.blocked_by_charging)
|
if (!newChargingState) blockingReason = rh.gs(R.string.blocked_by_charging)
|
||||||
processStateChange()
|
processStateChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onStatusEvent(ev: EventNetworkChange) {
|
private fun onNetworkChange(ev: EventNetworkChange) {
|
||||||
val newNetworkState = calculateStatus(ev)
|
val newNetworkState = calculateStatus(ev)
|
||||||
if (newNetworkState != allowedNetworkState) {
|
if (newNetworkState != allowedNetworkState) {
|
||||||
allowedNetworkState = newNetworkState
|
allowedNetworkState = newNetworkState
|
||||||
blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
if (!newNetworkState) blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
||||||
processStateChange()
|
processStateChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processStateChange() {
|
private fun processStateChange() {
|
||||||
val newAllowedState = allowedChargingState && allowedNetworkState
|
val newAllowedState = allowedChargingState == true && allowedNetworkState == true
|
||||||
if (newAllowedState != allowed) {
|
if (newAllowedState != allowed) {
|
||||||
allowed = newAllowedState
|
allowed = newAllowedState
|
||||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
if (allowed) blockingReason = ""
|
||||||
|
rxBus.send(EventNSConnectivityOptionChanged(blockingReason))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import info.nightscout.plugins.sync.R
|
||||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
||||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||||
|
import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
|
||||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||||
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
||||||
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
|
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
|
||||||
|
@ -140,13 +141,21 @@ class NSClientService : DaggerService() {
|
||||||
.subscribe({ event: EventPreferenceChange ->
|
.subscribe({ event: EventPreferenceChange ->
|
||||||
if (event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
|
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(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
|
latestDateInReceivedData = 0
|
||||||
destroy()
|
destroy()
|
||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
|
disposable += rxBus
|
||||||
|
.toObservable(EventNSConnectivityOptionChanged::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.subscribe({
|
||||||
|
latestDateInReceivedData = 0
|
||||||
|
destroy()
|
||||||
|
initialize()
|
||||||
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventAppExit::class.java)
|
.toObservable(EventAppExit::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
|
@ -218,10 +227,10 @@ class NSClientService : DaggerService() {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
||||||
rxBus.send(EventNSClientStatus("Initializing"))
|
rxBus.send(EventNSClientStatus("Initializing"))
|
||||||
if (!nsClientPlugin.isAllowed) {
|
if (nsClientPlugin.isAllowed != true) {
|
||||||
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
|
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
|
||||||
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
|
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
|
||||||
} else if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
} else if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||||
rxBus.send(EventNSClientStatus("Paused"))
|
rxBus.send(EventNSClientStatus("Paused"))
|
||||||
} else if (!nsEnabled) {
|
} else if (!nsEnabled) {
|
||||||
|
@ -230,9 +239,7 @@ class NSClientService : DaggerService() {
|
||||||
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
|
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
|
||||||
try {
|
try {
|
||||||
rxBus.send(EventNSClientStatus("Connecting ..."))
|
rxBus.send(EventNSClientStatus("Connecting ..."))
|
||||||
val opt = IO.Options()
|
val opt = IO.Options().also { it.forceNew = true }
|
||||||
opt.forceNew = true
|
|
||||||
opt.reconnection = true
|
|
||||||
socket = IO.socket(nsURL, opt).also { socket ->
|
socket = IO.socket(nsURL, opt).also { socket ->
|
||||||
socket.on(Socket.EVENT_CONNECT, onConnect)
|
socket.on(Socket.EVENT_CONNECT, onConnect)
|
||||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.plugins.sync.nsclientV3
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
|
import android.os.SystemClock
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
|
@ -16,26 +17,34 @@ import com.google.gson.GsonBuilder
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
|
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||||
import info.nightscout.database.ValueWrapper
|
import info.nightscout.database.ValueWrapper
|
||||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.interfaces.Constants
|
||||||
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
import info.nightscout.interfaces.source.NSClientSource
|
||||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||||
import info.nightscout.interfaces.sync.NsClient
|
import info.nightscout.interfaces.sync.NsClient
|
||||||
import info.nightscout.interfaces.sync.Sync
|
import info.nightscout.interfaces.sync.Sync
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.interfaces.utils.HtmlHelper
|
import info.nightscout.interfaces.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.R
|
||||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||||
|
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
|
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
|
||||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||||
|
import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
|
||||||
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
|
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.toNSBolus
|
||||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
|
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
|
||||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
|
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.toNSTemporaryBasal
|
||||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
|
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
|
||||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
|
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
|
||||||
|
import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker
|
||||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
|
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
|
||||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
||||||
|
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||||
|
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||||
import info.nightscout.rx.AapsSchedulers
|
import info.nightscout.rx.AapsSchedulers
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventAppExit
|
import info.nightscout.rx.events.EventAppExit
|
||||||
import info.nightscout.rx.events.EventChargingState
|
import info.nightscout.rx.events.EventDismissNotification
|
||||||
import info.nightscout.rx.events.EventNSClientNewLog
|
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.EventNewHistoryData
|
||||||
import info.nightscout.rx.events.EventPreferenceChange
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
import info.nightscout.rx.events.EventSWSyncStatus
|
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.rx.logging.LTag
|
||||||
import info.nightscout.sdk.NSAndroidClientImpl
|
import info.nightscout.sdk.NSAndroidClientImpl
|
||||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
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.sdk.remotemodel.LastModified
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
@ -73,15 +87,19 @@ import info.nightscout.shared.utils.DateUtil
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
import io.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.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.util.concurrent.Executors
|
import org.json.JSONArray
|
||||||
import java.util.concurrent.ScheduledFuture
|
import org.json.JSONObject
|
||||||
import java.util.concurrent.TimeUnit
|
import java.net.URISyntaxException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -102,7 +120,12 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
private val uiInteraction: UiInteraction,
|
private val uiInteraction: UiInteraction,
|
||||||
private val dataSyncSelector: DataSyncSelector,
|
private val dataSyncSelector: DataSyncSelector,
|
||||||
private val profileFunction: ProfileFunction,
|
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(
|
) : NsClient, Sync, PluginBase(
|
||||||
PluginDescription()
|
PluginDescription()
|
||||||
.mainType(PluginType.SYNC)
|
.mainType(PluginType.SYNC)
|
||||||
|
@ -118,7 +141,6 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val JOB_NAME: String = this::class.java.simpleName
|
val JOB_NAME: String = this::class.java.simpleName
|
||||||
val REFRESH_INTERVAL = T.secs(30).msecs()
|
|
||||||
const val RECORDS_TO_LOAD = 500L
|
const val RECORDS_TO_LOAD = 500L
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +152,10 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
override val status
|
override val status
|
||||||
get() =
|
get() =
|
||||||
when {
|
when {
|
||||||
sp.getBoolean(R.string.key_ns_client_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
|
sp.getBoolean(R.string.key_ns_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
|
||||||
isAllowed.not() -> blockingReason
|
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)
|
lastOperationError != null -> rh.gs(info.nightscout.core.ui.R.string.error)
|
||||||
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||||
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
||||||
|
@ -161,26 +185,30 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
setClient()
|
setClient("START")
|
||||||
|
|
||||||
nsClientReceiverDelegate.grabReceiversState()
|
nsClientReceiverDelegate.grabReceiversState()
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNetworkChange::class.java)
|
.toObservable(EventNSConnectivityOptionChanged::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ ev ->
|
.subscribe({ ev ->
|
||||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
rxBus.send(EventNSClientNewLog("● CONNECTIVITY CHANGE", ev.blockingReason))
|
||||||
setClient()
|
setClient("CONNECTIVITY_CHANGE")
|
||||||
rxBus.send(EventNSClientUpdateGUI())
|
if (isAllowed) executeLoop("CONNECTIVITY_CHANGE", forceNew = false)
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventPreferenceChange::class.java)
|
.toObservable(EventPreferenceChange::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ ev ->
|
.subscribe({ ev ->
|
||||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
if (ev.isChanged(rh.gs(R.string.key_ns_client_token)) ||
|
||||||
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_nsclientinternal_url)) ||
|
||||||
setClient()
|
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)))
|
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)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventAppExit::class.java)
|
.toObservable(EventAppExit::class.java)
|
||||||
|
@ -193,47 +221,55 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
addToLog(event)
|
addToLog(event)
|
||||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventChargingState::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ ev ->
|
|
||||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
|
||||||
rxBus.send(EventNSClientUpdateGUI())
|
|
||||||
}, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNSClientResend::class.java)
|
.toObservable(EventNSClientResend::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
|
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
|
||||||
disposable += rxBus
|
|
||||||
.toObservable(EventNewBG::class.java)
|
|
||||||
.observeOn(aapsSchedulers.io)
|
|
||||||
.subscribe({ delayAndScheduleExecution("NEW_BG") }, fabricPrivacy::logException)
|
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewHistoryData::class.java)
|
.toObservable(EventNewHistoryData::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ delayAndScheduleExecution("NEW_DATA") }, fabricPrivacy::logException)
|
.subscribe({ executeUpload("NEW_DATA", forceNew = false) }, fabricPrivacy::logException)
|
||||||
|
|
||||||
runLoop = Runnable {
|
runLoop = Runnable {
|
||||||
handler.postDelayed(runLoop, REFRESH_INTERVAL)
|
var refreshInterval = T.mins(5).msecs()
|
||||||
repository.getLastGlucoseValueWrapped().blockingGet().let {
|
repository.getLastGlucoseValueWrapped().blockingGet().let {
|
||||||
// if last value is older than 5 min or there is no bg
|
// if last value is older than 5 min or there is no bg
|
||||||
if (it is ValueWrapper.Existing) {
|
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)
|
executeLoop("MAIN_LOOP", forceNew = false)
|
||||||
else {
|
|
||||||
if (isAllowed) rxBus.send(EventNSClientNewLog("RECENT", "No need to load"))
|
|
||||||
}
|
}
|
||||||
} else executeLoop("MAIN_LOOP", forceNew = false)
|
} 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() {
|
override fun onStop() {
|
||||||
// context.applicationContext.unbindService(mConnection)
|
|
||||||
handler.removeCallbacksAndMessages(null)
|
handler.removeCallbacksAndMessages(null)
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
|
socket?.disconnect()
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,16 +293,269 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setClient() {
|
private fun setClient(reason: String) {
|
||||||
nsAndroidClient = NSAndroidClientImpl(
|
nsAndroidClient = NSAndroidClientImpl(
|
||||||
baseUrl = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace("https://", "").replace(Regex("/$"), ""),
|
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, ""),
|
accessToken = sp.getString(R.string.key_ns_client_token, ""),
|
||||||
context = context,
|
context = context,
|
||||||
logging = true
|
logging = true
|
||||||
)
|
)
|
||||||
|
if (wsConnected)
|
||||||
|
socket?.disconnect()
|
||||||
|
SystemClock.sleep(2000)
|
||||||
|
initializeWebSockets(reason)
|
||||||
rxBus.send(EventSWSyncStatus(status))
|
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<String>("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 <i>$docString</i>"))
|
||||||
|
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<Any> ->
|
||||||
|
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) {
|
private fun addToLog(ev: EventNSClientNewLog) {
|
||||||
synchronized(listLog) {
|
synchronized(listLog) {
|
||||||
listLog.add(ev)
|
listLog.add(ev)
|
||||||
|
@ -292,12 +581,15 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resend(reason: String) {
|
override fun resend(reason: String) {
|
||||||
|
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true))
|
||||||
|
executeUpload("RESEND", forceNew = false)
|
||||||
|
else
|
||||||
executeLoop("RESEND", forceNew = false)
|
executeLoop("RESEND", forceNew = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pause(newState: Boolean) {
|
override fun pause(newState: Boolean) {
|
||||||
sp.putBoolean(R.string.key_ns_client_paused, newState)
|
sp.putBoolean(R.string.key_ns_paused, newState)
|
||||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun detectedNsVersion(): String? = nsAndroidClient?.lastStatus?.version
|
override fun detectedNsVersion(): String? = nsAndroidClient?.lastStatus?.version
|
||||||
|
@ -337,6 +629,7 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
override fun resetToFullSync() {
|
override fun resetToFullSync() {
|
||||||
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
|
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
|
||||||
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
||||||
|
initialLoadFinished = false
|
||||||
storeLastLoadedSrvModified()
|
storeLastLoadedSrvModified()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,15 +648,15 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
val data = (dataPair as DataSyncSelector.PairProfileStore).value
|
val data = (dataPair as DataSyncSelector.PairProfileStore).value
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} $data $progress"))
|
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>$data</i> $progress"))
|
||||||
nsAndroidClient?.createProfileStore(data)?.let { result ->
|
nsAndroidClient?.createProfileStore(data)?.let { result ->
|
||||||
when (result.response) {
|
when (result.response) {
|
||||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ProfileStore"))
|
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ProfileStore"))
|
||||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ProfileStore"))
|
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ProfileStore"))
|
||||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", "ProfileStore"))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", "ProfileStore"))
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,15 +678,15 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
|
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
|
||||||
scope.launch {
|
scope.launch {
|
||||||
try {
|
try {
|
||||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"))
|
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"))
|
||||||
nsAndroidClient?.createDeviceStatus(data)?.let { result ->
|
nsAndroidClient?.createDeviceStatus(data)?.let { result ->
|
||||||
when (result.response) {
|
when (result.response) {
|
||||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
|
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
|
||||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,24 +719,24 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
rxBus.send(
|
rxBus.send(
|
||||||
EventNSClientNewLog(
|
EventNSClientNewLog(
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "ADD $collection"
|
Operation.CREATE -> "► ADD $collection"
|
||||||
Operation.UPDATE -> "UPDATE $collection"
|
Operation.UPDATE -> "► UPDATE $collection"
|
||||||
},
|
},
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
call?.let { it(data) }?.let { result ->
|
call?.let { it(data) }?.let { result ->
|
||||||
when (result.response) {
|
when (result.response) {
|
||||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "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}"))
|
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,24 +774,24 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
rxBus.send(
|
rxBus.send(
|
||||||
EventNSClientNewLog(
|
EventNSClientNewLog(
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "ADD $collection"
|
Operation.CREATE -> "► ADD $collection"
|
||||||
Operation.UPDATE -> "UPDATE $collection"
|
Operation.UPDATE -> "► UPDATE $collection"
|
||||||
},
|
},
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
call?.let { it(data) }?.let { result ->
|
call?.let { it(data) }?.let { result ->
|
||||||
when (result.response) {
|
when (result.response) {
|
||||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "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}"))
|
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,24 +857,24 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
rxBus.send(
|
rxBus.send(
|
||||||
EventNSClientNewLog(
|
EventNSClientNewLog(
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "ADD $collection"
|
Operation.CREATE -> "► ADD $collection"
|
||||||
Operation.UPDATE -> "UPDATE $collection"
|
Operation.UPDATE -> "► UPDATE $collection"
|
||||||
},
|
},
|
||||||
when (operation) {
|
when (operation) {
|
||||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
call?.let { it(data) }?.let { result ->
|
call?.let { it(data) }?.let { result ->
|
||||||
when (result.response) {
|
when (result.response) {
|
||||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "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}"))
|
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||||
return@launch
|
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))
|
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) {
|
private fun executeLoop(origin: String, forceNew: Boolean) {
|
||||||
if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && initialLoadFinished) return
|
||||||
rxBus.send(EventNSClientNewLog("RUN", "paused"))
|
if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||||
|
rxBus.send(EventNSClientNewLog("● RUN", "paused $origin"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!isAllowed) {
|
if (!isAllowed) {
|
||||||
rxBus.send(EventNSClientNewLog("RUN", blockingReason))
|
rxBus.send(EventNSClientNewLog("● RUN", "$blockingReason $origin"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (workIsRunning(arrayOf(JOB_NAME))) {
|
if (workIsRunning(arrayOf(JOB_NAME))) {
|
||||||
rxBus.send(EventNSClientNewLog("RUN", "Already running $origin"))
|
rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
|
||||||
if (!forceNew) return
|
if (!forceNew) return
|
||||||
// Wait for end and start new cycle
|
// Wait for end and start new cycle
|
||||||
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
|
while (workIsRunning(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)
|
WorkManager.getInstance(context)
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
JOB_NAME,
|
JOB_NAME,
|
||||||
|
@ -754,6 +1035,30 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
.enqueue()
|
.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<String>): Boolean {
|
private fun workIsRunning(workNames: Array<String>): Boolean {
|
||||||
for (workName in workNames)
|
for (workName in workNames)
|
||||||
for (workInfo in WorkManager.getInstance(context).getWorkInfosForUniqueWork(workName).get())
|
for (workInfo in WorkManager.getInstance(context).getWorkInfosForUniqueWork(workName).get())
|
||||||
|
@ -761,20 +1066,4 @@ class NSClientV3Plugin @Inject constructor(
|
||||||
return true
|
return true
|
||||||
return false
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
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.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventNSClientNewLog
|
import info.nightscout.rx.events.EventNSClientNewLog
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -20,12 +21,17 @@ class DataSyncWorker(
|
||||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var rxBus: RxBus
|
@Inject lateinit var rxBus: RxBus
|
||||||
|
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||||
|
|
||||||
override suspend fun doWorkAndLog(): Result {
|
override suspend fun doWorkAndLog(): Result {
|
||||||
if (activePlugin.activeNsClient?.hasWritePermission == true) {
|
if (activePlugin.activeNsClient?.hasWritePermission == true || nsClientV3Plugin.wsConnected) {
|
||||||
rxBus.send(EventNSClientNewLog("UPL", "Start"))
|
rxBus.send(EventNSClientNewLog("► UPL", "Start"))
|
||||||
dataSyncSelector.doUpload()
|
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())
|
rxBus.send(EventNSClientUpdateGUI())
|
||||||
return Result.success()
|
return Result.success()
|
||||||
|
|
|
@ -70,7 +70,7 @@ class LoadBgWorker(
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "SGVS: $sgvs")
|
aapsLogger.debug(LTag.NSCLIENT, "SGVS: $sgvs")
|
||||||
if (sgvs.isNotEmpty()) {
|
if (sgvs.isNotEmpty()) {
|
||||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
val action = if (isFirstLoad) "RCV-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
|
// Objective0
|
||||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||||
// Schedule processing of fetched data and continue of loading
|
// Schedule processing of fetched data and continue of loading
|
||||||
|
@ -90,7 +90,7 @@ class LoadBgWorker(
|
||||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
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
|
workManager
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -106,7 +106,7 @@ class LoadBgWorker(
|
||||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
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
|
workManager
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -118,7 +118,7 @@ class LoadBgWorker(
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,15 +33,18 @@ class LoadDeviceStatusWorker(
|
||||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Notify plugin we loaded al missed data
|
||||||
|
nsClientV3Plugin.initialLoadFinished = true
|
||||||
|
|
||||||
val from = dateUtil.now() - T.mins(7).msecs()
|
val from = dateUtil.now() - T.mins(7).msecs()
|
||||||
val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from)
|
val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from)
|
||||||
aapsLogger.debug("DEVICESTATUSES: $deviceStatuses")
|
aapsLogger.debug("DEVICESTATUSES: $deviceStatuses")
|
||||||
if (deviceStatuses.isNotEmpty()) {
|
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())
|
nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray())
|
||||||
rxBus.send(EventNSClientNewLog("DONE DS", ""))
|
rxBus.send(EventNSClientNewLog("● DONE PROCESSING DS", ""))
|
||||||
} else {
|
} 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)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.enqueueUniqueWork(
|
||||||
|
@ -51,7 +54,7 @@ class LoadDeviceStatusWorker(
|
||||||
)
|
)
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ class LoadFoodsWorker(
|
||||||
if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) {
|
if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) {
|
||||||
val foods: List<NSFood> = nsAndroidClient.getFoods(1000).values
|
val foods: List<NSFood> = nsAndroidClient.getFoods(1000).values
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "FOODS: $foods")
|
aapsLogger.debug(LTag.NSCLIENT, "FOODS: $foods")
|
||||||
rxBus.send(EventNSClientNewLog("RCV", "${foods.size} FOODs"))
|
rxBus.send(EventNSClientNewLog("◄ RCV", "${foods.size} FOODs"))
|
||||||
// Schedule processing of fetched data
|
// Schedule processing of fetched data
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
|
@ -53,7 +53,7 @@ class LoadFoodsWorker(
|
||||||
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
|
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
|
||||||
.enqueue()
|
.enqueue()
|
||||||
} else {
|
} else {
|
||||||
rxBus.send(EventNSClientNewLog("RCV", "FOOD skipped"))
|
rxBus.send(EventNSClientNewLog("● RCV FOOD", "skipped"))
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.enqueueUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -63,7 +63,7 @@ class LoadFoodsWorker(
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class LoadLastModificationWorker(
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}")
|
aapsLogger.debug(LTag.NSCLIENT, "LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}")
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error(LTag.NSCLIENT, "Error: ", error)
|
aapsLogger.error(LTag.NSCLIENT, "Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class LoadProfileStoreWorker(
|
||||||
{ nsClientV3Plugin.lastLoadedSrvModified.collections.profile = dateUtil.now() }
|
{ nsClientV3Plugin.lastLoadedSrvModified.collections.profile = dateUtil.now() }
|
||||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "PROFILE: $profile")
|
aapsLogger.debug(LTag.NSCLIENT, "PROFILE: $profile")
|
||||||
rxBus.send(EventNSClientNewLog("RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
rxBus.send(EventNSClientNewLog("◄ RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -68,7 +68,7 @@ class LoadProfileStoreWorker(
|
||||||
).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
|
).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
|
||||||
.enqueue()
|
.enqueue()
|
||||||
} else {
|
} 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)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.enqueueUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -77,7 +77,7 @@ class LoadProfileStoreWorker(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.enqueueUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
|
@ -87,7 +87,7 @@ class LoadProfileStoreWorker(
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class LoadStatusWorker(
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "STATUS: $status")
|
aapsLogger.debug(LTag.NSCLIENT, "STATUS: $status")
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
|
||||||
import info.nightscout.core.utils.worker.then
|
import info.nightscout.core.utils.worker.then
|
||||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||||
import info.nightscout.interfaces.sync.NsClient
|
import info.nightscout.interfaces.sync.NsClient
|
||||||
|
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventNSClientNewLog
|
import info.nightscout.rx.events.EventNSClientNewLog
|
||||||
|
@ -57,14 +58,14 @@ class LoadTreatmentsWorker(
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "TREATMENTS: $treatments")
|
aapsLogger.debug(LTag.NSCLIENT, "TREATMENTS: $treatments")
|
||||||
if (treatments.isNotEmpty()) {
|
if (treatments.isNotEmpty()) {
|
||||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
val action = if (isFirstLoad) "RCV-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
|
// Schedule processing of fetched data and continue of loading
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.beginUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||||
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
|
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
|
||||||
.setInputData(dataWorkerStorage.storeInputData(response))
|
.setInputData(dataWorkerStorage.storeInputData(response.values))
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
|
// 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.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||||
}
|
}
|
||||||
rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||||
storeDataForDb.storeTreatmentsToDb()
|
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
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 {
|
} else {
|
||||||
// End first load
|
// End first load
|
||||||
|
@ -92,18 +94,19 @@ class LoadTreatmentsWorker(
|
||||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||||
}
|
}
|
||||||
rxBus.send(EventNSClientNewLog("RCV END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||||
storeDataForDb.storeTreatmentsToDb()
|
|
||||||
WorkManager.getInstance(context)
|
WorkManager.getInstance(context)
|
||||||
.enqueueUniqueWork(
|
.beginUniqueWork(
|
||||||
NSClientV3Plugin.JOB_NAME,
|
NSClientV3Plugin.JOB_NAME,
|
||||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
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) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class ProcessFoodWorker(
|
||||||
storeDataForDb.foods.addAll(foods)
|
storeDataForDb.foods.addAll(foods)
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toTherapyEvent
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventNSClientNewLog
|
import info.nightscout.rx.events.EventNSClientNewLog
|
||||||
import info.nightscout.rx.logging.LTag
|
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.NSBolus
|
||||||
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
|
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
|
||||||
import info.nightscout.sdk.localmodel.treatment.NSCarbs
|
import info.nightscout.sdk.localmodel.treatment.NSCarbs
|
||||||
|
@ -57,12 +56,12 @@ class ProcessTreatmentsWorker(
|
||||||
|
|
||||||
override suspend fun doWorkAndLog(): Result {
|
override suspend fun doWorkAndLog(): Result {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse<List<NSTreatment>>?
|
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List<NSTreatment>?
|
||||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var latestDateInReceivedData: Long = 0
|
var latestDateInReceivedData: Long = 0
|
||||||
for (treatment in treatments.values) {
|
for (treatment in treatments) {
|
||||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||||
val date = treatment.date ?: continue
|
val date = treatment.date ?: continue
|
||||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||||
|
@ -139,7 +138,7 @@ class ProcessTreatmentsWorker(
|
||||||
// xDripBroadcast.sendTreatments(treatments)
|
// xDripBroadcast.sendTreatments(treatments)
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
aapsLogger.error("Error: ", error)
|
aapsLogger.error("Error: ", error)
|
||||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||||
}
|
}
|
||||||
return Result.success()
|
return Result.success()
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
<!-- NSClient -->
|
<!-- NSClient -->
|
||||||
<string name="key_ns_client_autoscroll" translatable="false">ns_client_autoscroll</string>
|
<string name="key_ns_client_autoscroll" translatable="false">ns_client_autoscroll</string>
|
||||||
<string name="key_ns_client_paused" translatable="false">ns_client_paused</string>
|
<string name="key_ns_paused" translatable="false">ns_client_paused</string>
|
||||||
<string name="key_ns_log_app_started_event" translatable="false">ns_log_app_started_event</string>
|
<string name="key_ns_log_app_started_event" translatable="false">ns_log_app_started_event</string>
|
||||||
|
|
||||||
<string name="no_write_permission">NSCLIENT has no write permission. Wrong API secret?</string>
|
<string name="no_write_permission">NSCLIENT has no write permission. Wrong API secret?</string>
|
||||||
|
@ -171,5 +171,7 @@
|
||||||
|
|
||||||
<!-- DataBroadcast-->
|
<!-- DataBroadcast-->
|
||||||
<string name="data_broadcaster" translatable="false">Data Broadcaster</string>
|
<string name="data_broadcaster" translatable="false">Data Broadcaster</string>
|
||||||
|
<string name="ns_use_ws_title">Connect to websockets</string>
|
||||||
|
<string name="ns_use_ws_summary">Enabling means: faster updates, receiving alarms and announcements and higher battery consumption similar to v1. All other uploaderds to NS must use v3 protocol.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -9,7 +9,7 @@
|
||||||
app:initialExpandedChildrenCount="0">
|
app:initialExpandedChildrenCount="0">
|
||||||
|
|
||||||
<info.nightscout.core.validators.ValidatingEditTextPreference
|
<info.nightscout.core.validators.ValidatingEditTextPreference
|
||||||
android:defaultValue="https://{YOUR-SITE}.azurewebsites.net/"
|
android:defaultValue="https://{YOUR-SITE}.azurewebsites.net"
|
||||||
android:dialogMessage="@string/ns_client_url_dialog_message"
|
android:dialogMessage="@string/ns_client_url_dialog_message"
|
||||||
android:inputType="textUri"
|
android:inputType="textUri"
|
||||||
android:key="@string/key_nsclientinternal_url"
|
android:key="@string/key_nsclientinternal_url"
|
||||||
|
@ -26,6 +26,12 @@
|
||||||
validate:minLength="17"
|
validate:minLength="17"
|
||||||
validate:testType="minLength" />
|
validate:testType="minLength" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="@string/key_ns_use_ws"
|
||||||
|
android:summary="@string/ns_use_ws_summary"
|
||||||
|
android:title="@string/ns_use_ws_title" />
|
||||||
|
|
||||||
<androidx.preference.PreferenceScreen
|
<androidx.preference.PreferenceScreen
|
||||||
android:key="@string/ns_sync_options"
|
android:key="@string/ns_sync_options"
|
||||||
android:title="@string/ns_sync_options">
|
android:title="@string/ns_sync_options">
|
||||||
|
|
Loading…
Reference in a new issue