Merge branch 'ns15' into xdrip
This commit is contained in:
commit
b5d03ff897
|
@ -34,14 +34,14 @@ open class AppModule {
|
|||
@PluginsListModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>
|
||||
//@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>
|
||||
)
|
||||
: List<@JvmSuppressWildcards PluginBase> {
|
||||
val plugins = allConfigs.toMutableMap()
|
||||
if (config.PUMPDRIVERS) plugins += pumpDrivers.get()
|
||||
if (config.APS) plugins += aps.get()
|
||||
if (!config.NSCLIENT) plugins += notNsClient.get()
|
||||
if (config.isUnfinishedMode()) plugins += unfinished.get()
|
||||
//if (config.isUnfinishedMode()) plugins += unfinished.get()
|
||||
return plugins.toList().sortedBy { it.first }.map { it.second }
|
||||
}
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@ abstract class PluginsListModule {
|
|||
abstract fun bindNSClientV3Plugin(plugin: NSClientV3Plugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@Unfinished
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
@IntKey(360)
|
||||
abstract fun bindTidepoolPlugin(plugin: TidepoolPlugin): PluginBase
|
||||
|
|
|
@ -15,7 +15,7 @@ class ConfigImpl @Inject constructor(
|
|||
fileListProvider: PrefFileListProvider
|
||||
) : Config {
|
||||
|
||||
override val SUPPORTED_NS_VERSION = 140206 // 14.2.6
|
||||
override val SUPPORTED_NS_VERSION = 150000 // 15.0.0
|
||||
override val APS = BuildConfig.FLAVOR == "full"
|
||||
override val NSCLIENT = BuildConfig.FLAVOR == "aapsclient" || BuildConfig.FLAVOR == "aapsclient2"
|
||||
override val PUMPCONTROL = BuildConfig.FLAVOR == "pumpcontrol"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
|
@ -8,6 +9,9 @@ import org.json.JSONObject
|
|||
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
|
||||
toRemoteDeviceStatus().toNSDeviceStatus()
|
||||
|
||||
fun String.toNSDeviceStatus(): NSDeviceStatus =
|
||||
Gson().fromJson(this, RemoteDeviceStatus::class.java).toNSDeviceStatus()
|
||||
|
||||
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
|
||||
NSDeviceStatus(
|
||||
app = app,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.food.NSFood
|
||||
import info.nightscout.sdk.remotemodel.RemoteFood
|
||||
|
||||
|
@ -12,6 +13,9 @@ import info.nightscout.sdk.remotemodel.RemoteFood
|
|||
fun NSFood.convertToRemoteAndBack(): NSFood? =
|
||||
toRemoteFood().toNSFood()
|
||||
|
||||
fun String.toNSFood(): NSFood? =
|
||||
Gson().fromJson(this, RemoteFood::class.java).toNSFood()
|
||||
|
||||
internal fun RemoteFood.toNSFood(): NSFood? {
|
||||
when (type) {
|
||||
"food" ->
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.entry.Direction
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
@ -8,6 +9,9 @@ import info.nightscout.sdk.remotemodel.RemoteEntry
|
|||
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
|
||||
toRemoteEntry().toSgv()
|
||||
|
||||
fun String.toNSSgvV3(): NSSgvV3? =
|
||||
Gson().fromJson(this, RemoteEntry::class.java).toSgv()
|
||||
|
||||
internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
||||
|
||||
this.sgv ?: return null
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
||||
|
@ -26,6 +27,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun NSTreatment.convertToRemoteAndBack(): NSTreatment? =
|
||||
toRemoteTreatment()?.toTreatment()
|
||||
|
||||
fun String.toNSTreatment(): NSTreatment? =
|
||||
Gson().fromJson(this, RemoteTreatment::class.java).toTreatment()
|
||||
|
||||
internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
||||
val treatmentTimestamp = timestamp()
|
||||
when {
|
||||
|
|
|
@ -22,4 +22,15 @@ data class LastModified(
|
|||
@SerializedName("foods") var foods: Long = 0, // foods collection
|
||||
@SerializedName("settings") var settings: Long = 0 // settings collection
|
||||
)
|
||||
|
||||
fun set(colName: String, value: Long) {
|
||||
when (colName) {
|
||||
"devicestatus" -> collections.devicestatus = value
|
||||
"entries" -> collections.entries = value
|
||||
"profile" -> collections.profile = value
|
||||
"treatments" -> collections.treatments = value
|
||||
"foods" -> collections.foods = value
|
||||
"settings" -> collections.settings = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<string name="mute5min">Mute for 5 minutes</string>
|
||||
<string name="mute">Mute</string>
|
||||
<string name="success">Success</string>
|
||||
<string name="advancedsettings_title">Advanced Settings</string>
|
||||
<string name="advanced_settings_title">Advanced Settings</string>
|
||||
<string name="extendedbolusdeliveryerror">Extended bolus delivery error</string>
|
||||
<string name="aps_mode_title">APS Mode</string>
|
||||
<string name="extended_bolus">Extended bolus</string>
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
<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_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_carbs" translatable="false">ns_receive_carbs</string>
|
||||
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.room.PrimaryKey
|
|||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.database.entities.interfaces.DBEntryWithTimeAndDuration
|
||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||
import info.nightscout.database.entities.interfaces.end
|
||||
import java.util.TimeZone
|
||||
|
||||
@Entity(
|
||||
|
@ -53,9 +54,6 @@ data class OfflineEvent(
|
|||
previous.interfaceIDs.nightscoutId == null &&
|
||||
interfaceIDs.nightscoutId != null
|
||||
|
||||
fun isRecordDeleted(other: OfflineEvent): Boolean =
|
||||
isValid && !other.isValid
|
||||
|
||||
enum class Reason {
|
||||
DISCONNECT_PUMP,
|
||||
SUSPEND,
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_ama_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_smb_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_smb_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -75,7 +75,7 @@ class RunningConfigurationImpl @Inject constructor(
|
|||
assert(config.NSCLIENT)
|
||||
|
||||
configuration.version?.let {
|
||||
rxBus.send(EventNSClientNewLog("VERSION", "Received AAPS version $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ VERSION", "Received AAPS version $it"))
|
||||
if (config.VERSION_NAME.startsWith(it).not())
|
||||
uiInteraction.addNotification(Notification.NSCLIENT_VERSION_DOES_NOT_MATCH, rh.gs(R.string.nsclient_version_does_not_match), Notification.NORMAL)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.DefaultValueHelper
|
||||
import info.nightscout.plugins.R
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
|
@ -21,7 +20,6 @@ class NotificationWithAction constructor(
|
|||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
|
||||
init {
|
||||
|
@ -66,7 +64,7 @@ class NotificationWithAction constructor(
|
|||
aapsLogger.debug(LTag.NOTIFICATION, "Notification text is: $text")
|
||||
val msToSnooze = sp.getInt(info.nightscout.core.utils.R.string.key_ns_alarm_stale_data_value, 15) * 60 * 1000L
|
||||
aapsLogger.debug(LTag.NOTIFICATION, "snooze nsalarm_staledatavalue in minutes is ${T.msecs(msToSnooze).mins()} currentTimeMillis is: ${System.currentTimeMillis()}")
|
||||
sp.putLong(info.nightscout.core.utils.R.string.key_snoozed_to, System.currentTimeMillis() + msToSnooze)
|
||||
sp.putLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + nsAlarm.level(), System.currentTimeMillis() + msToSnooze)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="overview_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_aaps_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
android:defaultValue="1.2"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_oref1_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
android:defaultValue="1.2"
|
||||
|
|
|
@ -32,10 +32,7 @@ dependencies {
|
|||
testImplementation project(':plugins:aps')
|
||||
|
||||
// NSClient, Tidepool
|
||||
api("io.socket:socket.io-client:1.0.2") {
|
||||
// excluding org.json which is provided by Android
|
||||
exclude group: "org.json", module: "json"
|
||||
}
|
||||
api("io.socket:socket.io-client:2.1.0")
|
||||
api "com.squareup.okhttp3:okhttp:$okhttp3_version"
|
||||
api "com.squareup.okhttp3:logging-interceptor:$okhttp3_version"
|
||||
//api "com.squareup.retrofit2:retrofit:$retrofit2_version"
|
||||
|
|
|
@ -62,6 +62,7 @@ abstract class SyncModule {
|
|||
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreTreatmentsWorker(): StoreDataForDbImpl.StoreTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
||||
|
|
|
@ -57,7 +57,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
private val queueCounter = QueueCounter()
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
updateGui()
|
||||
}
|
||||
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.paused.setOnCheckedChangeListener { _, isChecked ->
|
||||
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
|
||||
nsClientPlugin?.pause(isChecked)
|
||||
|
@ -143,7 +143,7 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
|
||||
private fun updateGui() {
|
||||
if (_binding == null) return
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.log.text = nsClientPlugin?.textLog()
|
||||
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
binding.url.text = nsClientPlugin?.address
|
||||
|
|
|
@ -145,13 +145,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) =
|
||||
if (containsKey(key)) merge(key, 1, Long::plus)
|
||||
else put(key, 1)
|
||||
|
||||
override fun storeGlucoseValuesToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING BG", ""))
|
||||
|
||||
if (glucoseValues.isNotEmpty())
|
||||
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
||||
.doOnError {
|
||||
|
@ -179,12 +190,10 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
rxBus.send(EventNSClientNewLog("DONE BG", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING BG", ""))
|
||||
}
|
||||
|
||||
override fun storeFoodsToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING FOOD", ""))
|
||||
|
||||
if (foods.isNotEmpty())
|
||||
repository.runTransactionForResult(SyncNsFoodTransaction(foods))
|
||||
.doOnError {
|
||||
|
@ -209,12 +218,10 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
sendLog("Food", Food::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
rxBus.send(EventNSClientNewLog("DONE FOOD", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING FOOD", ""))
|
||||
}
|
||||
|
||||
override fun storeTreatmentsToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING TR", ""))
|
||||
|
||||
if (boluses.isNotEmpty())
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(boluses))
|
||||
.doOnError {
|
||||
|
@ -791,7 +798,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
SystemClock.sleep(pause)
|
||||
|
||||
uel.log(userEntries)
|
||||
rxBus.send(EventNSClientNewLog("DONE TR", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING TR", ""))
|
||||
}
|
||||
|
||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||
|
@ -991,7 +998,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
||||
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
||||
sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName)
|
||||
rxBus.send(EventNSClientNewLog("DONE NSIDs", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE NSIDs", ""))
|
||||
}
|
||||
|
||||
private fun sendLog(item: String, clazz: String) {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.Event
|
||||
|
||||
class EventConnectivityOptionChanged(val blockingReason: String) : Event()
|
|
@ -14,7 +14,6 @@ import androidx.preference.SwitchPreference
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.extensions.toJson
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
|
@ -41,9 +40,7 @@ import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
|||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventSWSyncStatus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -66,7 +63,7 @@ class NSClientPlugin @Inject constructor(
|
|||
private val context: Context,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val sp: SP,
|
||||
private val nsClientReceiverDelegate: NsClientReceiverDelegate,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val dataSyncSelector: DataSyncSelector,
|
||||
private val uiInteraction: UiInteraction,
|
||||
|
@ -92,14 +89,14 @@ class NSClientPlugin @Inject constructor(
|
|||
override var status = ""
|
||||
var nsClientService: NSClientService? = null
|
||||
val isAllowed: Boolean
|
||||
get() = nsClientReceiverDelegate.allowed
|
||||
get() = receiverDelegate.allowed
|
||||
val blockingReason: String
|
||||
get() = nsClientReceiverDelegate.blockingReason
|
||||
get() = receiverDelegate.blockingReason
|
||||
|
||||
override fun onStart() {
|
||||
context.bindService(Intent(context, NSClientService::class.java), mConnection, Context.BIND_AUTO_CREATE)
|
||||
super.onStart()
|
||||
nsClientReceiverDelegate.grabReceiversState()
|
||||
receiverDelegate.grabReceiversState()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientStatus::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -109,14 +106,6 @@ class NSClientPlugin @Inject constructor(
|
|||
// Pass to setup wizard
|
||||
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -128,10 +117,6 @@ class NSClientPlugin @Inject constructor(
|
|||
addToLog(event)
|
||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientResend::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -181,7 +166,7 @@ class NSClientPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun detectedNsVersion(): String? = nsSettingsStatus.getVersion()
|
||||
override fun detectedNsVersion(): String = nsSettingsStatus.getVersion()
|
||||
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
|
@ -212,8 +197,8 @@ class NSClientPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun pause(newState: Boolean) {
|
||||
sp.putBoolean(R.string.key_ns_client_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
||||
sp.putBoolean(R.string.key_ns_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
|
||||
}
|
||||
|
||||
override val address: String get() = nsClientService?.nsURL ?: ""
|
||||
|
|
|
@ -1,43 +1,67 @@
|
|||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class NsClientReceiverDelegate @Inject constructor(
|
||||
class ReceiverDelegate @Inject constructor(
|
||||
private val rxBus: RxBus,
|
||||
private val rh: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val receiverStatusStore: ReceiverStatusStore
|
||||
private val receiverStatusStore: ReceiverStatusStore,
|
||||
aapsSchedulers: AapsSchedulers,
|
||||
fabricPrivacy: FabricPrivacy
|
||||
) {
|
||||
|
||||
private var allowedChargingState = true
|
||||
private var allowedNetworkState = true
|
||||
var allowed = true
|
||||
var blockingReason = ""
|
||||
private var allowedChargingState: Boolean? = null
|
||||
private var allowedNetworkState: Boolean? = null
|
||||
var allowed: Boolean = false
|
||||
var blockingReason = "Status not available"
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
init {
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onPreferenceChange(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onNetworkChange(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onChargingStateChange(ev) }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
fun grabReceiversState() {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventPreferenceChange) {
|
||||
private fun onPreferenceChange(ev: EventPreferenceChange) {
|
||||
when {
|
||||
ev.isChanged(rh.gs(R.string.key_ns_wifi)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_cellular)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_wifi_ssids)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_allow_roaming)) -> {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
receiverStatusStore.lastNetworkEvent?.let { onStatusEvent(it) }
|
||||
receiverStatusStore.lastNetworkEvent?.let { onNetworkChange(it) }
|
||||
}
|
||||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_charging)) ||
|
||||
|
@ -47,29 +71,30 @@ class NsClientReceiverDelegate @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventChargingState) {
|
||||
private fun onChargingStateChange(ev: EventChargingState) {
|
||||
val newChargingState = calculateStatus(ev)
|
||||
if (newChargingState != allowedChargingState) {
|
||||
allowedChargingState = newChargingState
|
||||
blockingReason = rh.gs(R.string.blocked_by_charging)
|
||||
if (!newChargingState) blockingReason = rh.gs(R.string.blocked_by_charging)
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventNetworkChange) {
|
||||
private fun onNetworkChange(ev: EventNetworkChange) {
|
||||
val newNetworkState = calculateStatus(ev)
|
||||
if (newNetworkState != allowedNetworkState) {
|
||||
allowedNetworkState = newNetworkState
|
||||
blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
||||
if (!newNetworkState) blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
private fun processStateChange() {
|
||||
val newAllowedState = allowedChargingState && allowedNetworkState
|
||||
val newAllowedState = allowedChargingState == true && allowedNetworkState == true
|
||||
if (newAllowedState != allowed) {
|
||||
allowed = newAllowedState
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
||||
if (allowed) blockingReason = ""
|
||||
rxBus.send(EventConnectivityOptionChanged(blockingReason))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.plugins.sync.nsclient.data
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.configBuilder.RunningConfiguration
|
||||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
|
@ -65,6 +66,7 @@ import javax.inject.Singleton
|
|||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Singleton
|
||||
@OpenForTesting
|
||||
class NSDeviceStatusHandler @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val config: Config,
|
||||
|
|
|
@ -31,6 +31,7 @@ import info.nightscout.interfaces.utils.JsonHelper.safeGetStringAllowNull
|
|||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||
|
@ -49,6 +50,7 @@ import info.nightscout.rx.events.EventConfigBuilderChange
|
|||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
import info.nightscout.rx.events.EventNewHistoryData
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
|
@ -139,13 +141,21 @@ class NSClientService : DaggerService() {
|
|||
.subscribe({ event: EventPreferenceChange ->
|
||||
if (event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
|
||||
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_api_secret)) ||
|
||||
event.isChanged(rh.gs(R.string.key_ns_client_paused))
|
||||
event.isChanged(rh.gs(R.string.key_ns_paused))
|
||||
) {
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventConnectivityOptionChanged::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -165,6 +175,10 @@ class NSClientService : DaggerService() {
|
|||
.toObservable(NSAuthAck::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewHistoryData::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ resend("NEW_DATA") }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -213,10 +227,10 @@ class NSClientService : DaggerService() {
|
|||
@Suppress("DEPRECATION")
|
||||
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
||||
rxBus.send(EventNSClientStatus("Initializing"))
|
||||
if (!nsClientPlugin.isAllowed) {
|
||||
if (nsClientPlugin.isAllowed != true) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
|
||||
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
|
||||
} else if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
||||
} else if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientStatus("Paused"))
|
||||
} else if (!nsEnabled) {
|
||||
|
@ -225,16 +239,10 @@ class NSClientService : DaggerService() {
|
|||
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
|
||||
try {
|
||||
rxBus.send(EventNSClientStatus("Connecting ..."))
|
||||
val opt = IO.Options()
|
||||
opt.forceNew = true
|
||||
opt.reconnection = true
|
||||
val opt = IO.Options().also { it.forceNew = true }
|
||||
socket = IO.socket(nsURL, opt).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnect)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
||||
socket.on(Socket.EVENT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_TIMEOUT, onError)
|
||||
socket.on(Socket.EVENT_PING, onPing)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "do connect"))
|
||||
socket.connect()
|
||||
socket.on("dataUpdate", onDataUpdate)
|
||||
|
@ -300,7 +308,6 @@ class NSClientService : DaggerService() {
|
|||
@Synchronized fun destroy() {
|
||||
socket?.off(Socket.EVENT_CONNECT)
|
||||
socket?.off(Socket.EVENT_DISCONNECT)
|
||||
socket?.off(Socket.EVENT_PING)
|
||||
socket?.off("dataUpdate")
|
||||
socket?.off("announcement")
|
||||
socket?.off("alarm")
|
||||
|
@ -336,18 +343,6 @@ class NSClientService : DaggerService() {
|
|||
nsDevice = sp.getString("careportal_enteredby", "")
|
||||
}
|
||||
|
||||
private val onError = Emitter.Listener { args ->
|
||||
var msg = "Unknown Error"
|
||||
if (args.isNotEmpty() && args[0] != null) {
|
||||
msg = args[0].toString()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ERROR", msg))
|
||||
}
|
||||
private val onPing = Emitter.Listener {
|
||||
rxBus.send(EventNSClientNewLog("PING", "received"))
|
||||
// send data if there is something waiting
|
||||
resend("Ping received")
|
||||
}
|
||||
private val onAnnouncement = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
|
@ -651,7 +646,7 @@ class NSClientService : DaggerService() {
|
|||
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)
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + alarm.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
|
@ -664,7 +659,7 @@ class NSClientService : DaggerService() {
|
|||
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)
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + alarm.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.plugins.sync.nsclientV3
|
|||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.SystemClock
|
||||
import android.text.Spanned
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
|
@ -16,26 +17,33 @@ import com.google.gson.GsonBuilder
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolus
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSBolusWizard
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
|
||||
|
@ -49,16 +57,17 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
|
|||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryBasal
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTemporaryTarget
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSTherapyEvent
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventNewBG
|
||||
import info.nightscout.rx.events.EventNewHistoryData
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventSWSyncStatus
|
||||
|
@ -66,6 +75,10 @@ import info.nightscout.rx.logging.AAPSLogger
|
|||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.NSAndroidClientImpl
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.mapper.toNSDeviceStatus
|
||||
import info.nightscout.sdk.mapper.toNSFood
|
||||
import info.nightscout.sdk.mapper.toNSSgvV3
|
||||
import info.nightscout.sdk.mapper.toNSTreatment
|
||||
import info.nightscout.sdk.remotemodel.LastModified
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -73,15 +86,19 @@ import info.nightscout.shared.utils.DateUtil
|
|||
import info.nightscout.shared.utils.T
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.socket.client.Ack
|
||||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import io.socket.emitter.Emitter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.net.URISyntaxException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -96,13 +113,18 @@ class NSClientV3Plugin @Inject constructor(
|
|||
private val context: Context,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val sp: SP,
|
||||
private val nsClientReceiverDelegate: NsClientReceiverDelegate,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val dateUtil: DateUtil,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val dataSyncSelector: DataSyncSelector,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val repository: AppRepository
|
||||
private val repository: AppRepository,
|
||||
private val nsDeviceStatusHandler: NSDeviceStatusHandler,
|
||||
private val workManager: WorkManager,
|
||||
private val workerClasses: WorkerClasses,
|
||||
private val dataWorkerStorage: DataWorkerStorage,
|
||||
private val nsClientSource: NSClientSource
|
||||
) : NsClient, Sync, PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.SYNC)
|
||||
|
@ -115,13 +137,14 @@ class NSClientV3Plugin @Inject constructor(
|
|||
aapsLogger, rh, injector
|
||||
) {
|
||||
|
||||
@Suppress("PropertyName")
|
||||
val JOB_NAME: String = this::class.java.simpleName
|
||||
|
||||
companion object {
|
||||
|
||||
val REFRESH_INTERVAL = T.secs(30).msecs()
|
||||
const val RECORDS_TO_LOAD = 500
|
||||
}
|
||||
|
||||
@Suppress("PropertyName") val JOB_NAME: String = this::class.java.simpleName
|
||||
private val disposable = CompositeDisposable()
|
||||
var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private lateinit var runLoop: Runnable
|
||||
|
@ -130,21 +153,23 @@ class NSClientV3Plugin @Inject constructor(
|
|||
override val status
|
||||
get() =
|
||||
when {
|
||||
sp.getBoolean(R.string.key_ns_client_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
|
||||
isAllowed.not() -> blockingReason
|
||||
lastOperationError != null -> rh.gs(info.nightscout.core.ui.R.string.error)
|
||||
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
|
||||
else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
|
||||
sp.getBoolean(R.string.key_ns_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
|
||||
isAllowed.not() -> blockingReason
|
||||
sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && wsConnected -> "WS: " + rh.gs(info.nightscout.shared.R.string.connected)
|
||||
sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && !wsConnected -> "WS: " + rh.gs(R.string.not_connected)
|
||||
lastOperationError != null -> rh.gs(info.nightscout.core.ui.R.string.error)
|
||||
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
|
||||
nsAndroidClient?.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
|
||||
else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
|
||||
}
|
||||
var lastOperationError: String? = null
|
||||
|
||||
internal var nsAndroidClient: NSAndroidClient? = null
|
||||
|
||||
private val isAllowed get() = nsClientReceiverDelegate.allowed
|
||||
private val blockingReason get() = nsClientReceiverDelegate.blockingReason
|
||||
private val isAllowed get() = receiverDelegate.allowed
|
||||
private val blockingReason get() = receiverDelegate.blockingReason
|
||||
|
||||
val maxAge = T.days(77).msecs()
|
||||
internal var newestDataOnServer: LastModified? = null // timestamp of last modification for every collection provided by server
|
||||
|
@ -161,24 +186,32 @@ class NSClientV3Plugin @Inject constructor(
|
|||
)
|
||||
)
|
||||
|
||||
setClient()
|
||||
setClient("START")
|
||||
|
||||
nsClientReceiverDelegate.grabReceiversState()
|
||||
receiverDelegate.grabReceiversState()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.toObservable(EventConnectivityOptionChanged::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev ->
|
||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
||||
setClient()
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
rxBus.send(EventNSClientNewLog("● CONNECTIVITY", ev.blockingReason))
|
||||
setClient("CONNECTIVITY")
|
||||
if (isAllowed) executeLoop("CONNECTIVITY", forceNew = false)
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev ->
|
||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
||||
if (ev.isChanged(rh.gs(R.string.key_ns_client_token)) || ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)))
|
||||
setClient()
|
||||
if (ev.isChanged(rh.gs(R.string.key_ns_client_token)) ||
|
||||
ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
|
||||
ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_ns_use_ws)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_paused)) ||
|
||||
ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_ns_alarms)) ||
|
||||
ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_ns_announcements))
|
||||
)
|
||||
setClient("SETTING CHANGE")
|
||||
if (ev.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_local_profile_last_change)))
|
||||
executeUpload("PROFILE_CHANGE", forceNew = true)
|
||||
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
|
@ -191,46 +224,56 @@ class NSClientV3Plugin @Inject constructor(
|
|||
addToLog(event)
|
||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev ->
|
||||
nsClientReceiverDelegate.onStatusEvent(ev)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientResend::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewBG::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ delayAndScheduleExecution("NEW_BG") }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewHistoryData::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ delayAndScheduleExecution("NEW_DATA") }, fabricPrivacy::logException)
|
||||
.subscribe({ executeUpload("NEW_DATA", forceNew = false) }, fabricPrivacy::logException)
|
||||
|
||||
runLoop = Runnable {
|
||||
handler.postDelayed(runLoop, REFRESH_INTERVAL)
|
||||
var refreshInterval = T.mins(5).msecs()
|
||||
repository.getLastGlucoseValueWrapped().blockingGet().let {
|
||||
// if last value is older than 5 min or there is no bg
|
||||
if (it is ValueWrapper.Existing) {
|
||||
if (it.value.timestamp < dateUtil.now() - T.mins(5).plus(T.secs(20)).msecs())
|
||||
if (it.value.timestamp < dateUtil.now() - T.mins(5).plus(T.secs(20)).msecs()) {
|
||||
refreshInterval = T.mins(1).msecs()
|
||||
executeLoop("MAIN_LOOP", forceNew = false)
|
||||
else {
|
||||
if (isAllowed) rxBus.send(EventNSClientNewLog("RECENT", "No need to load"))
|
||||
}
|
||||
} else executeLoop("MAIN_LOOP", forceNew = false)
|
||||
}
|
||||
handler.postDelayed(runLoop, refreshInterval)
|
||||
rxBus.send(EventNSClientNewLog("● TICK", ""))
|
||||
}
|
||||
handler.postDelayed(runLoop, T.mins(2).msecs())
|
||||
}
|
||||
|
||||
fun scheduleIrregularExecution(refreshToken: Boolean = false) {
|
||||
if (refreshToken) {
|
||||
handler.post { executeLoop("REFRESH TOKEN", forceNew = true) }
|
||||
return
|
||||
}
|
||||
if (config.NSCLIENT || nsClientSource.isEnabled()) {
|
||||
var origin = "5_MIN_AFTER_BG"
|
||||
var forceNew = true
|
||||
var toTime = lastLoadedSrvModified.collections.entries + T.mins(5).plus(T.secs(10)).msecs()
|
||||
if (toTime < dateUtil.now()) {
|
||||
toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
|
||||
origin = "1_MIN_OLD_DATA"
|
||||
forceNew = false
|
||||
}
|
||||
handler.postDelayed({ executeLoop(origin, forceNew = forceNew) }, toTime - dateUtil.now())
|
||||
rxBus.send(EventNSClientNewLog("● NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
|
||||
}
|
||||
handler.postDelayed(runLoop, REFRESH_INTERVAL)
|
||||
executeLoop("START", forceNew = false)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
disposable.clear()
|
||||
storageSocket?.disconnect()
|
||||
alarmSocket?.disconnect()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
|
@ -254,7 +297,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun setClient() {
|
||||
private fun setClient(reason: String) {
|
||||
nsAndroidClient = NSAndroidClientImpl(
|
||||
baseUrl = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace("https://", "").replace(Regex("/$"), ""),
|
||||
accessToken = sp.getString(R.string.key_ns_client_token, ""),
|
||||
|
@ -262,9 +305,266 @@ class NSClientV3Plugin @Inject constructor(
|
|||
logging = true,
|
||||
logger = { msg -> aapsLogger.debug(LTag.HTTP, msg) }
|
||||
)
|
||||
if (wsConnected) {
|
||||
storageSocket?.disconnect()
|
||||
alarmSocket?.disconnect()
|
||||
}
|
||||
SystemClock.sleep(2000)
|
||||
initializeWebSockets(reason)
|
||||
rxBus.send(EventSWSyncStatus(status))
|
||||
}
|
||||
|
||||
/**********************
|
||||
WS code
|
||||
**********************/
|
||||
private var storageSocket: Socket? = null
|
||||
private var alarmSocket: 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
|
||||
if (sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").isEmpty()) return
|
||||
val urlStorage = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace(Regex("/$"), "") + "/storage"
|
||||
val urlAlarm = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "").lowercase().replace(Regex("/$"), "") + "/alarm"
|
||||
if (!isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("● WS", blockingReason))
|
||||
} else if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("● WS", "paused"))
|
||||
} else {
|
||||
try {
|
||||
// java io.client doesn't support multiplexing. create 2 sockets
|
||||
storageSocket = IO.socket(urlStorage).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnectStorage)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnectStorage)
|
||||
rxBus.send(EventNSClientNewLog("► WS", "do connect storage $reason"))
|
||||
socket.connect()
|
||||
socket.on("create", onDataCreateUpdate)
|
||||
socket.on("update", onDataCreateUpdate)
|
||||
socket.on("delete", onDataDelete)
|
||||
}
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_announcements, config.NSCLIENT) ||
|
||||
sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, config.NSCLIENT)
|
||||
)
|
||||
alarmSocket = IO.socket(urlAlarm).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnectAlarms)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnectAlarm)
|
||||
rxBus.send(EventNSClientNewLog("► WS", "do connect alarm $reason"))
|
||||
socket.connect()
|
||||
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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val onConnectStorage = Emitter.Listener {
|
||||
val socketId = storageSocket?.id() ?: "NULL"
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", "connected storage ID: $socketId"))
|
||||
if (storageSocket != null) {
|
||||
val authMessage = JSONObject().also {
|
||||
it.put("accessToken", sp.getString(R.string.key_ns_client_token, ""))
|
||||
it.put("collections", JSONArray(arrayOf("devicestatus", "entries", "profile", "treatments", "foods", "settings")))
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("► WS", "requesting auth for storage"))
|
||||
storageSocket?.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 onConnectAlarms = Emitter.Listener {
|
||||
val socketId = alarmSocket?.id() ?: "NULL"
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", "connected alarms ID: $socketId"))
|
||||
if (alarmSocket != null) {
|
||||
val authMessage = JSONObject().also {
|
||||
it.put("accessToken", sp.getString(R.string.key_ns_client_token, ""))
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("► WS", "requesting auth for alarms"))
|
||||
alarmSocket?.emit("subscribe", authMessage, Ack { args ->
|
||||
val response = args[0] as JSONObject
|
||||
wsConnected = if (response.optBoolean("success")) {
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", response.optString("message")))
|
||||
true
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", "Auth failed"))
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private val onDisconnectStorage = Emitter.Listener { args ->
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect storage reason: ${args[0]}")
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", "disconnect storage event"))
|
||||
wsConnected = false
|
||||
initialLoadFinished = false
|
||||
storageSocket = null
|
||||
}
|
||||
|
||||
private val onDisconnectAlarm = Emitter.Listener { args ->
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect alarm reason: ${args[0]}")
|
||||
rxBus.send(EventNSClientNewLog("◄ WS", "disconnect alarm event"))
|
||||
alarmSocket = 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 = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("◄ ANNOUNCEMENT", data.optString("message")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_announcements, config.NSCLIENT))
|
||||
uiInteraction.addNotificationWithAction(injector, NSAlarm(data))
|
||||
}
|
||||
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 = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("◄ ALARM", data.optString("message")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, config.NSCLIENT)) {
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + data.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo)
|
||||
uiInteraction.addNotificationWithAction(injector, NSAlarm(data))
|
||||
}
|
||||
}
|
||||
|
||||
private val onUrgentAlarm = Emitter.Listener { args: Array<Any> ->
|
||||
val data = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("◄ URGENT ALARM", data.optString("message")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, config.NSCLIENT)) {
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + data.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo)
|
||||
uiInteraction.addNotificationWithAction(injector, NSAlarm(data))
|
||||
}
|
||||
}
|
||||
|
||||
private val onClearAlarm = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
{
|
||||
"clear":true,
|
||||
"title":"All Clear",
|
||||
"message":"default - Urgent was ack'd",
|
||||
"group":"default"
|
||||
}
|
||||
*/
|
||||
val data = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("◄ CLEARALARM", data.optString("title")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
}
|
||||
|
||||
override fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long) {
|
||||
if (!isEnabled()) return
|
||||
if (!sp.getBoolean(R.string.key_ns_upload, true)) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Upload disabled. Message dropped")
|
||||
return
|
||||
}
|
||||
alarmSocket?.emit("ack", originalAlarm.level(), originalAlarm.group(), silenceTimeInMilliseconds)
|
||||
rxBus.send(EventNSClientNewLog("► ALARMACK ", "${originalAlarm.level()} ${originalAlarm.group()} $silenceTimeInMilliseconds"))
|
||||
}
|
||||
|
||||
/**********************
|
||||
WS code end
|
||||
**********************/
|
||||
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
|
@ -290,32 +590,21 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun resend(reason: String) {
|
||||
executeLoop("RESEND", forceNew = false)
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true))
|
||||
executeUpload("RESEND", forceNew = false)
|
||||
else
|
||||
executeLoop("RESEND", forceNew = false)
|
||||
}
|
||||
|
||||
override fun pause(newState: Boolean) {
|
||||
sp.putBoolean(R.string.key_ns_client_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
||||
sp.putBoolean(R.string.key_ns_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
|
||||
}
|
||||
|
||||
override fun detectedNsVersion(): String? = nsAndroidClient?.lastStatus?.version
|
||||
|
||||
override val address: String get() = sp.getString(info.nightscout.core.utils.R.string.key_nsclientinternal_url, "")
|
||||
|
||||
override fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long) {
|
||||
if (!isEnabled()) return
|
||||
if (!sp.getBoolean(R.string.key_ns_upload, true)) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Upload disabled. Message dropped")
|
||||
return
|
||||
}
|
||||
// nsClientService?.sendAlarmAck(
|
||||
// AlarmAck().also { ack ->
|
||||
// ack.level = originalAlarm.level()
|
||||
// ack.group = originalAlarm.group()
|
||||
// ack.silenceTime = silenceTimeInMilliseconds
|
||||
// })
|
||||
}
|
||||
|
||||
override fun isFirstLoad(collection: NsClient.Collection) =
|
||||
when (collection) {
|
||||
NsClient.Collection.ENTRIES -> lastLoadedSrvModified.collections.entries == 0L
|
||||
|
@ -335,6 +624,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
override fun resetToFullSync() {
|
||||
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
|
||||
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
||||
initialLoadFinished = false
|
||||
storeLastLoadedSrvModified()
|
||||
dataSyncSelector.resetToNextFullSync()
|
||||
}
|
||||
|
@ -354,15 +644,15 @@ class NSClientV3Plugin @Inject constructor(
|
|||
val data = (dataPair as DataSyncSelector.PairProfileStore).value
|
||||
scope.launch {
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} $data $progress"))
|
||||
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>$data</i> $progress"))
|
||||
nsAndroidClient?.createProfileStore(data)?.let { result ->
|
||||
when (result.response) {
|
||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ProfileStore"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ProfileStore"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ProfileStore"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ProfileStore"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "ProfileStore"))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "ProfileStore"))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -384,15 +674,15 @@ class NSClientV3Plugin @Inject constructor(
|
|||
val data = (dataPair as DataSyncSelector.PairDeviceStatus).value.toNSDeviceStatus()
|
||||
scope.launch {
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"))
|
||||
rxBus.send(EventNSClientNewLog("► ADD $collection", "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"))
|
||||
nsAndroidClient?.createDeviceStatus(data)?.let { result ->
|
||||
when (result.response) {
|
||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName} ${result.identifier}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -425,24 +715,24 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
Operation.CREATE -> "ADD $collection"
|
||||
Operation.UPDATE -> "UPDATE $collection"
|
||||
Operation.CREATE -> "► ADD $collection"
|
||||
Operation.UPDATE -> "► UPDATE $collection"
|
||||
},
|
||||
when (operation) {
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||
}
|
||||
)
|
||||
)
|
||||
call?.let { it(data) }?.let { result ->
|
||||
when (result.response) {
|
||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -480,24 +770,24 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
Operation.CREATE -> "ADD $collection"
|
||||
Operation.UPDATE -> "UPDATE $collection"
|
||||
Operation.CREATE -> "► ADD $collection"
|
||||
Operation.UPDATE -> "► UPDATE $collection"
|
||||
},
|
||||
when (operation) {
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||
}
|
||||
)
|
||||
)
|
||||
call?.let { it(data) }?.let { result ->
|
||||
when (result.response) {
|
||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -563,24 +853,24 @@ class NSClientV3Plugin @Inject constructor(
|
|||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
Operation.CREATE -> "ADD $collection"
|
||||
Operation.UPDATE -> "UPDATE $collection"
|
||||
Operation.CREATE -> "► ADD $collection"
|
||||
Operation.UPDATE -> "► UPDATE $collection"
|
||||
},
|
||||
when (operation) {
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} ${gson.toJson(data)} $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id ${gson.toJson(data)} $progress"
|
||||
Operation.CREATE -> "Sent ${dataPair.javaClass.simpleName} <i>${gson.toJson(data)}</i> $progress"
|
||||
Operation.UPDATE -> "Sent ${dataPair.javaClass.simpleName} $id <i>${gson.toJson(data)}</i> $progress"
|
||||
}
|
||||
)
|
||||
)
|
||||
call?.let { it(data) }?.let { result ->
|
||||
when (result.response) {
|
||||
200 -> rxBus.send(EventNSClientNewLog("UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
200 -> rxBus.send(EventNSClientNewLog("◄ UPDATED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
201 -> rxBus.send(EventNSClientNewLog("◄ ADDED", "OK ${dataPair.value.javaClass.simpleName}"))
|
||||
400 -> rxBus.send(EventNSClientNewLog("◄ FAIL", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
404 -> rxBus.send(EventNSClientNewLog("◄ NOT_FOUND", "${dataPair.value.javaClass.simpleName} ${result.errorResponse}"))
|
||||
|
||||
else -> {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "${dataPair.value.javaClass.simpleName} "))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -707,35 +997,23 @@ class NSClientV3Plugin @Inject constructor(
|
|||
sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastLoadedSrvModified))
|
||||
}
|
||||
|
||||
fun scheduleIrregularExecution() {
|
||||
var origin = "5_MIN_AFTER_BG"
|
||||
var forceNew = true
|
||||
var toTime = lastLoadedSrvModified.collections.entries + T.mins(5).plus(T.secs(10)).msecs()
|
||||
if (toTime < dateUtil.now()) {
|
||||
toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
|
||||
origin = "1_MIN_OLD_DATA"
|
||||
forceNew = false
|
||||
}
|
||||
handler.postDelayed({ executeLoop(origin, forceNew = forceNew) }, toTime - dateUtil.now())
|
||||
rxBus.send(EventNSClientNewLog("NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
|
||||
}
|
||||
|
||||
private fun executeLoop(origin: String, forceNew: Boolean) {
|
||||
if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("RUN", "paused"))
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_use_ws, true) && initialLoadFinished) return
|
||||
if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "paused $origin"))
|
||||
return
|
||||
}
|
||||
if (!isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("RUN", blockingReason))
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "$blockingReason $origin"))
|
||||
return
|
||||
}
|
||||
if (workIsRunning(arrayOf(JOB_NAME))) {
|
||||
rxBus.send(EventNSClientNewLog("RUN", "Already running $origin"))
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
|
||||
if (!forceNew) return
|
||||
// Wait for end and start new cycle
|
||||
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RUN", "Starting next round $origin"))
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Starting next round $origin"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
JOB_NAME,
|
||||
|
@ -753,6 +1031,30 @@ class NSClientV3Plugin @Inject constructor(
|
|||
.enqueue()
|
||||
}
|
||||
|
||||
private fun executeUpload(origin: String, forceNew: Boolean) {
|
||||
if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "paused"))
|
||||
return
|
||||
}
|
||||
if (!isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", blockingReason))
|
||||
return
|
||||
}
|
||||
if (workIsRunning(arrayOf(JOB_NAME))) {
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Already running $origin"))
|
||||
if (!forceNew) return
|
||||
// Wait for end and start new cycle
|
||||
while (workIsRunning(arrayOf(JOB_NAME))) Thread.sleep(5000)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("● RUN", "Starting upload $origin"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
JOB_NAME,
|
||||
ExistingWorkPolicy.REPLACE,
|
||||
OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun workIsRunning(workNames: Array<String>): Boolean {
|
||||
for (workName in workNames)
|
||||
for (workInfo in WorkManager.getInstance(context).getWorkInfosForUniqueWork(workName).get())
|
||||
|
@ -760,20 +1062,4 @@ class NSClientV3Plugin @Inject constructor(
|
|||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||
private var scheduledEventPost: ScheduledFuture<*>? = null
|
||||
private fun delayAndScheduleExecution(origin: String) {
|
||||
class PostRunnable : Runnable {
|
||||
|
||||
override fun run() {
|
||||
scheduledEventPost = null
|
||||
executeLoop(origin, forceNew = true)
|
||||
}
|
||||
}
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
scheduledEventPost?.cancel(false)
|
||||
val task: Runnable = PostRunnable()
|
||||
scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -20,12 +21,17 @@ class DataSyncWorker(
|
|||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
if (activePlugin.activeNsClient?.hasWritePermission == true) {
|
||||
rxBus.send(EventNSClientNewLog("UPL", "Start"))
|
||||
if (activePlugin.activeNsClient?.hasWritePermission == true || nsClientV3Plugin.wsConnected) {
|
||||
rxBus.send(EventNSClientNewLog("► UPL", "Start"))
|
||||
dataSyncSelector.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("UPL", "End"))
|
||||
rxBus.send(EventNSClientNewLog("► UPL", "End"))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("► ERROR", "Not connected or write permission"))
|
||||
// refresh token
|
||||
nsClientV3Plugin.scheduleIrregularExecution(refreshToken = true)
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
return Result.success()
|
||||
|
|
|
@ -71,7 +71,7 @@ class LoadBgWorker(
|
|||
aapsLogger.debug(LTag.NSCLIENT, "SGVS: $sgvs")
|
||||
if (sgvs.isNotEmpty()) {
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog(action, "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ $action", "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Objective0
|
||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
|
@ -92,7 +92,7 @@ class LoadBgWorker(
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
workManager
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -108,7 +108,7 @@ class LoadBgWorker(
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV BG END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
workManager
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -120,7 +120,7 @@ class LoadBgWorker(
|
|||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -33,15 +33,18 @@ class LoadDeviceStatusWorker(
|
|||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
|
||||
try {
|
||||
// Notify plugin we loaded al missed data
|
||||
nsClientV3Plugin.initialLoadFinished = true
|
||||
|
||||
val from = dateUtil.now() - T.mins(7).msecs()
|
||||
val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from)
|
||||
aapsLogger.debug("DEVICESTATUSES: $deviceStatuses")
|
||||
if (deviceStatuses.isNotEmpty()) {
|
||||
rxBus.send(EventNSClientNewLog("RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray())
|
||||
rxBus.send(EventNSClientNewLog("DONE DS", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING DS", ""))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV DS END", "No data from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
}
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
|
@ -51,7 +54,7 @@ class LoadDeviceStatusWorker(
|
|||
)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class LoadFoodsWorker(
|
|||
if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) {
|
||||
val foods: List<NSFood> = nsAndroidClient.getFoods(1000).values
|
||||
aapsLogger.debug(LTag.NSCLIENT, "FOODS: $foods")
|
||||
rxBus.send(EventNSClientNewLog("RCV", "${foods.size} FOODs"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV", "${foods.size} FOODs"))
|
||||
// Schedule processing of fetched data
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
|
@ -53,7 +53,7 @@ class LoadFoodsWorker(
|
|||
.then(OneTimeWorkRequest.Builder(LoadProfileStoreWorker::class.java).build())
|
||||
.enqueue()
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("RCV", "FOOD skipped"))
|
||||
rxBus.send(EventNSClientNewLog("● RCV FOOD", "skipped"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -63,7 +63,7 @@ class LoadFoodsWorker(
|
|||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class LoadLastModificationWorker(
|
|||
aapsLogger.debug(LTag.NSCLIENT, "LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}")
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class LoadProfileStoreWorker(
|
|||
{ nsClientV3Plugin.lastLoadedSrvModified.collections.profile = dateUtil.now() }
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
aapsLogger.debug(LTag.NSCLIENT, "PROFILE: $profile")
|
||||
rxBus.send(EventNSClientNewLog("RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV", "1 PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -69,7 +69,7 @@ class LoadProfileStoreWorker(
|
|||
).then(OneTimeWorkRequest.Builder(LoadDeviceStatusWorker::class.java).build())
|
||||
.enqueue()
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -78,7 +78,7 @@ class LoadProfileStoreWorker(
|
|||
)
|
||||
}
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No PROFILE from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV PROFILE END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
|
@ -88,7 +88,7 @@ class LoadProfileStoreWorker(
|
|||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class LoadStatusWorker(
|
|||
aapsLogger.debug(LTag.NSCLIENT, "STATUS: $status")
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.core.utils.worker.LoggingWorker
|
|||
import info.nightscout.core.utils.worker.then
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
@ -58,7 +59,7 @@ class LoadTreatmentsWorker(
|
|||
aapsLogger.debug(LTag.NSCLIENT, "TREATMENTS: $treatments")
|
||||
if (treatments.isNotEmpty()) {
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog(action, "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
rxBus.send(EventNSClientNewLog("◄ $action", "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
val stopLoading = treatments.size != NSClientV3Plugin.RECORDS_TO_LOAD || response.code == 304
|
||||
WorkManager.getInstance(context)
|
||||
|
@ -66,7 +67,7 @@ class LoadTreatmentsWorker(
|
|||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(response))
|
||||
.setInputData(dataWorkerStorage.storeInputData(response.values))
|
||||
.build()
|
||||
)
|
||||
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
|
||||
|
@ -79,14 +80,15 @@ class LoadTreatmentsWorker(
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.enqueue()
|
||||
}
|
||||
} else {
|
||||
// End first load
|
||||
|
@ -94,18 +96,19 @@ class LoadTreatmentsWorker(
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastLoadedSrvModified()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
rxBus.send(EventNSClientNewLog("◄ RCV TR END", "No new data from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
.beginUniqueWork(
|
||||
nsClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build()
|
||||
OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreTreatmentsWorker::class.java).build()
|
||||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
|
||||
.enqueue()
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
nsClientV3Plugin.lastOperationError = error.localizedMessage
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ class ProcessFoodWorker(
|
|||
storeDataForDb.foods.addAll(foods)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toTherapyEvent
|
|||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
|
||||
import info.nightscout.sdk.localmodel.treatment.NSCarbs
|
||||
|
@ -57,12 +56,12 @@ class ProcessTreatmentsWorker(
|
|||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse<List<NSTreatment>>?
|
||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List<NSTreatment>?
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
try {
|
||||
var latestDateInReceivedData: Long = 0
|
||||
for (treatment in treatments.values) {
|
||||
for (treatment in treatments) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
val date = treatment.date ?: continue
|
||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||
|
@ -139,7 +138,7 @@ class ProcessTreatmentsWorker(
|
|||
// xDripBroadcast.sendTreatments(treatments)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("ERROR", error.localizedMessage))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
return Result.failure(workDataOf("Error" to error.localizedMessage))
|
||||
}
|
||||
return Result.success()
|
||||
|
|
|
@ -2,9 +2,14 @@ package info.nightscout.plugins.sync.tidepool
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ScrollView
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.plugins.sync.R
|
||||
|
@ -15,12 +20,13 @@ import info.nightscout.plugins.sync.tidepool.events.EventTidepoolResetData
|
|||
import info.nightscout.plugins.sync.tidepool.events.EventTidepoolUpdateGUI
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
|
||||
class TidepoolFragment : DaggerFragment() {
|
||||
class TidepoolFragment : DaggerFragment(), MenuProvider {
|
||||
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var tidepoolPlugin: TidepoolPlugin
|
||||
|
@ -28,6 +34,15 @@ class TidepoolFragment : DaggerFragment() {
|
|||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
|
||||
companion object {
|
||||
|
||||
const val ID_MENU_LOGIN = 530
|
||||
const val ID_MENU_SEND_NOW = 531
|
||||
const val ID_MENU_REMOVE_ALL = 532
|
||||
const val ID_MENU_FULL_SYNC = 533
|
||||
}
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
|
@ -39,31 +54,59 @@ class TidepoolFragment : DaggerFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
_binding = TidepoolFragmentBinding.inflate(inflater, container, false)
|
||||
requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.login.setOnClickListener { tidepoolUploader.doLogin(false) }
|
||||
binding.uploadnow.setOnClickListener { rxBus.send(EventTidepoolDoUpload()) }
|
||||
binding.removeall.setOnClickListener { rxBus.send(EventTidepoolResetData()) }
|
||||
binding.resertstart.setOnClickListener { sp.putLong(R.string.key_tidepool_last_end, 0) }
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
menu.add(Menu.FIRST, ID_MENU_LOGIN, 0, rh.gs(info.nightscout.core.ui.R.string.login)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_SEND_NOW, 0, rh.gs(R.string.upload_now)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_REMOVE_ALL, 0, rh.gs(R.string.remove_all)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_FULL_SYNC, 0, rh.gs(R.string.full_sync)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.setGroupDividerEnabled(true)
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
ID_MENU_LOGIN -> {
|
||||
tidepoolUploader.doLogin(false)
|
||||
true
|
||||
}
|
||||
|
||||
ID_MENU_SEND_NOW -> {
|
||||
rxBus.send(EventTidepoolDoUpload())
|
||||
true
|
||||
}
|
||||
|
||||
ID_MENU_REMOVE_ALL -> {
|
||||
rxBus.send(EventTidepoolResetData())
|
||||
true
|
||||
}
|
||||
|
||||
ID_MENU_FULL_SYNC -> {
|
||||
sp.putLong(R.string.key_tidepool_last_end, 0)
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventTidepoolUpdateGUI::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
if (_binding == null) return@subscribe
|
||||
tidepoolPlugin.updateLog()
|
||||
binding.log.text = tidepoolPlugin.textLog
|
||||
binding.status.text = tidepoolUploader.connectionStatus.name
|
||||
binding.log.text = tidepoolPlugin.textLog
|
||||
binding.logscrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
}, fabricPrivacy::logException)
|
||||
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||
updateGui()
|
||||
}
|
||||
|
||||
private fun updateGui() {
|
||||
tidepoolPlugin.updateLog()
|
||||
_binding?.log?.text = tidepoolPlugin.textLog
|
||||
_binding?.status?.text = tidepoolUploader.connectionStatus.name
|
||||
_binding?.log?.text = tidepoolPlugin.textLog
|
||||
_binding?.logScrollview?.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -77,5 +120,4 @@ class TidepoolFragment : DaggerFragment() {
|
|||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,11 +10,12 @@ import info.nightscout.interfaces.Constants
|
|||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.tidepool.comm.TidepoolUploader
|
||||
import info.nightscout.plugins.sync.tidepool.comm.UploadChunk
|
||||
import info.nightscout.plugins.sync.tidepool.events.EventTidepoolDoUpload
|
||||
|
@ -24,7 +25,7 @@ import info.nightscout.plugins.sync.tidepool.events.EventTidepoolUpdateGUI
|
|||
import info.nightscout.plugins.sync.tidepool.utils.RateLimit
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNewBG
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -50,7 +51,7 @@ class TidepoolPlugin @Inject constructor(
|
|||
private val uploadChunk: UploadChunk,
|
||||
private val sp: SP,
|
||||
private val rateLimit: RateLimit,
|
||||
private val receiverStatusStore: ReceiverStatusStore,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val uiInteraction: UiInteraction
|
||||
) : Sync, PluginBase(
|
||||
PluginDescription()
|
||||
|
@ -67,10 +68,18 @@ class TidepoolPlugin @Inject constructor(
|
|||
|
||||
private val listLog = ArrayList<EventTidepoolStatus>()
|
||||
var textLog: Spanned = HtmlHelper.fromHtml("")
|
||||
private val isAllowed get() = receiverDelegate.allowed
|
||||
|
||||
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
disposable += rxBus
|
||||
.toObservable(EventConnectivityOptionChanged::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev ->
|
||||
rxBus.send(EventNSClientNewLog("● CONNECTIVITY", ev.blockingReason))
|
||||
tidepoolUploader.resetInstance()
|
||||
if (isAllowed) doUpload()
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventTidepoolDoUpload::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -94,17 +103,13 @@ class TidepoolPlugin @Inject constructor(
|
|||
disposable += rxBus
|
||||
.toObservable(EventNewBG::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.filter { it.glucoseValueTimestamp != null } // better would be optional in API level >24
|
||||
.map { it.glucoseValueTimestamp!! }
|
||||
.subscribe({ bgReadingTimestamp ->
|
||||
if (bgReadingTimestamp < uploadChunk.getLastEnd())
|
||||
uploadChunk.setLastEnd(bgReadingTimestamp)
|
||||
if (isEnabled()
|
||||
&& (!sp.getBoolean(R.string.key_tidepool_only_while_charging, false) || receiverStatusStore.isCharging)
|
||||
&& (!sp.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || receiverStatusStore.isWifiConnected)
|
||||
&& rateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt())
|
||||
)
|
||||
doUpload()
|
||||
.subscribe({
|
||||
it.glucoseValueTimestamp?.let { bgReadingTimestamp ->
|
||||
if (bgReadingTimestamp < uploadChunk.getLastEnd())
|
||||
uploadChunk.setLastEnd(bgReadingTimestamp)
|
||||
if (isAllowed && rateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt()))
|
||||
doUpload()
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
|
@ -116,11 +121,6 @@ class TidepoolPlugin @Inject constructor(
|
|||
)
|
||||
tidepoolUploader.resetInstance()
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({}, fabricPrivacy::logException) // TODO start upload on wifi connect
|
||||
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
|
|
|
@ -8,7 +8,7 @@ import okhttp3.Response
|
|||
import okio.Buffer
|
||||
import java.io.IOException
|
||||
|
||||
class InfoInterceptor(val tag: String = "interceptor", val aapsLogger: AAPSLogger) : Interceptor {
|
||||
class InfoInterceptor(val aapsLogger: AAPSLogger) : Interceptor {
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
|
|
|
@ -4,38 +4,37 @@ import info.nightscout.plugins.sync.tidepool.messages.AuthReplyMessage
|
|||
import info.nightscout.plugins.sync.tidepool.messages.DatasetReplyMessage
|
||||
import okhttp3.Headers
|
||||
|
||||
class Session(val authHeader: String?,
|
||||
private val sessionTokenHeader: String,
|
||||
val service: TidepoolApiService?) {
|
||||
class Session(
|
||||
val authHeader: String?,
|
||||
private val sessionTokenHeader: String,
|
||||
val service: TidepoolApiService?
|
||||
) {
|
||||
|
||||
internal var token: String? = null
|
||||
internal var authReply: AuthReplyMessage? = null
|
||||
internal var datasetReply: DatasetReplyMessage? = null
|
||||
internal var start: Long = 0
|
||||
internal var end: Long = 0
|
||||
|
||||
@Volatile
|
||||
internal var iterations: Int = 0
|
||||
|
||||
fun populateHeaders(headers: Headers) {
|
||||
if (this.token == null) {
|
||||
this.token = headers.get(sessionTokenHeader)
|
||||
this.token = headers[sessionTokenHeader]
|
||||
}
|
||||
}
|
||||
|
||||
fun populateBody(obj: Any?) {
|
||||
if (obj == null) return
|
||||
if (obj is AuthReplyMessage) {
|
||||
authReply = obj
|
||||
} else if (obj is List<*>) {
|
||||
val list = obj as? List<*>?
|
||||
when (obj) {
|
||||
is AuthReplyMessage -> authReply = obj
|
||||
|
||||
list?.getOrNull(0)?.let {
|
||||
if (it is DatasetReplyMessage) {
|
||||
datasetReply = it
|
||||
is List<*> ->
|
||||
(obj as? List<*>?)?.getOrNull(0)?.let {
|
||||
if (it is DatasetReplyMessage) datasetReply = it
|
||||
}
|
||||
}
|
||||
} else if (obj is DatasetReplyMessage) {
|
||||
datasetReply = obj
|
||||
|
||||
is DatasetReplyMessage -> datasetReply = obj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,14 @@ import retrofit2.Call
|
|||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
internal class TidepoolCallback<T>(private val aapsLogger: AAPSLogger, private val rxBus: RxBus, private val session: Session, val name: String, val onSuccess: () -> Unit, val onFail: () -> Unit) :
|
||||
internal class TidepoolCallback<T>(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val rxBus: RxBus,
|
||||
private val session: Session,
|
||||
private val name: String,
|
||||
private val onSuccess: () -> Unit,
|
||||
private val onFail: () -> Unit
|
||||
) :
|
||||
Callback<T> {
|
||||
|
||||
override fun onResponse(call: Call<T>, response: Response<T>) {
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.os.PowerManager
|
|||
import android.os.SystemClock
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.tidepool.events.EventTidepoolStatus
|
||||
import info.nightscout.plugins.sync.tidepool.messages.AuthReplyMessage
|
||||
import info.nightscout.plugins.sync.tidepool.messages.AuthRequestMessage
|
||||
|
@ -37,11 +37,12 @@ class TidepoolUploader @Inject constructor(
|
|||
private val rh: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val uploadChunk: UploadChunk,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val dateUtil: DateUtil,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val config: Config
|
||||
) {
|
||||
|
||||
private val isAllowed get() = receiverDelegate.allowed
|
||||
private var wl: PowerManager.WakeLock? = null
|
||||
|
||||
companion object {
|
||||
|
@ -57,7 +58,7 @@ class TidepoolUploader @Inject constructor(
|
|||
private var session: Session? = null
|
||||
|
||||
enum class ConnectionStatus {
|
||||
DISCONNECTED, CONNECTING, CONNECTED, FAILED
|
||||
BLOCKED, DISCONNECTED, CONNECTING, CONNECTED, FAILED
|
||||
}
|
||||
|
||||
var connectionStatus: ConnectionStatus = ConnectionStatus.DISCONNECTED
|
||||
|
@ -70,7 +71,7 @@ class TidepoolUploader @Inject constructor(
|
|||
|
||||
val client = OkHttpClient.Builder()
|
||||
.addInterceptor(httpLoggingInterceptor)
|
||||
.addInterceptor(InfoInterceptor(TidepoolUploader::class.java.name, aapsLogger))
|
||||
.addInterceptor(InfoInterceptor(aapsLogger))
|
||||
.build()
|
||||
|
||||
retrofit = Retrofit.Builder()
|
||||
|
@ -87,7 +88,6 @@ class TidepoolUploader @Inject constructor(
|
|||
return Session(AuthRequestMessage.getAuthRequestHeader(sp), SESSION_TOKEN_HEADER, service)
|
||||
}
|
||||
|
||||
// TODO: call on preference change
|
||||
fun resetInstance() {
|
||||
retrofit = null
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Instance reset")
|
||||
|
@ -96,6 +96,11 @@ class TidepoolUploader @Inject constructor(
|
|||
|
||||
@Synchronized
|
||||
fun doLogin(doUpload: Boolean = false) {
|
||||
if (!isAllowed) {
|
||||
connectionStatus = ConnectionStatus.BLOCKED
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Blocked by connectivity settings")
|
||||
return
|
||||
}
|
||||
if (connectionStatus == ConnectionStatus.CONNECTED || connectionStatus == ConnectionStatus.CONNECTING) {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Already connected")
|
||||
return
|
||||
|
@ -109,12 +114,15 @@ class TidepoolUploader @Inject constructor(
|
|||
rxBus.send(EventTidepoolStatus(("Connecting")))
|
||||
val call = session?.service?.getLogin(authHeader)
|
||||
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(aapsLogger, rxBus, session!!, "Login", {
|
||||
startSession(session!!, doUpload)
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
releaseWakeLock()
|
||||
}))
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(
|
||||
aapsLogger, rxBus, session!!, "Login",
|
||||
{
|
||||
startSession(session!!, doUpload)
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
releaseWakeLock()
|
||||
})
|
||||
)
|
||||
return
|
||||
} else {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Cannot do login as user credentials have not been set correctly")
|
||||
|
@ -130,16 +138,14 @@ class TidepoolUploader @Inject constructor(
|
|||
session.authHeader?.let {
|
||||
val call = session.service?.getLogin(it)
|
||||
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(aapsLogger, rxBus, session, "Login", {
|
||||
OKDialog.show(rootContext, rh.gs(R.string.tidepool), "Successfully logged into Tidepool.")
|
||||
}, {
|
||||
OKDialog.show(
|
||||
rootContext,
|
||||
rh.gs(R.string.tidepool),
|
||||
"Failed to log into Tidepool.\nCheck that your user name and password are correct."
|
||||
)
|
||||
}))
|
||||
|
||||
call?.enqueue(TidepoolCallback<AuthReplyMessage>(
|
||||
aapsLogger, rxBus, session, "Login",
|
||||
{
|
||||
OKDialog.show(rootContext, rh.gs(R.string.tidepool), "Successfully logged into Tidepool.")
|
||||
}, {
|
||||
OKDialog.show(rootContext, rh.gs(R.string.tidepool), "Failed to log into Tidepool.\nCheck that your user name and password are correct.")
|
||||
})
|
||||
)
|
||||
}
|
||||
?: OKDialog.show(rootContext, rh.gs(R.string.tidepool), "Cannot do login as user credentials have not been set correctly")
|
||||
|
||||
|
@ -154,39 +160,41 @@ class TidepoolUploader @Inject constructor(
|
|||
session.authReply!!.userid!!, "AAPS", 1
|
||||
)
|
||||
|
||||
datasetCall.enqueue(TidepoolCallback<List<DatasetReplyMessage>>(aapsLogger, rxBus, session, "Get Open Datasets", {
|
||||
if (session.datasetReply == null) {
|
||||
rxBus.send(EventTidepoolStatus(("Creating new dataset")))
|
||||
val call = session.service.openDataSet(
|
||||
session.token!!, session.authReply!!.userid!!,
|
||||
OpenDatasetRequestMessage(config, dateUtil).getBody()
|
||||
)
|
||||
call.enqueue(TidepoolCallback<DatasetReplyMessage>(aapsLogger, rxBus, session, "Open New Dataset", {
|
||||
connectionStatus = ConnectionStatus.CONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("New dataset OK")))
|
||||
if (doUpload) doUpload()
|
||||
else
|
||||
releaseWakeLock()
|
||||
datasetCall.enqueue(
|
||||
TidepoolCallback<List<DatasetReplyMessage>>(
|
||||
aapsLogger, rxBus, session, "Get Open Datasets",
|
||||
{
|
||||
if (session.datasetReply == null) {
|
||||
rxBus.send(EventTidepoolStatus(("Creating new dataset")))
|
||||
val call = session.service.openDataSet(session.token!!, session.authReply!!.userid!!, OpenDatasetRequestMessage(config, dateUtil).getBody())
|
||||
call.enqueue(TidepoolCallback<DatasetReplyMessage>(
|
||||
aapsLogger, rxBus, session, "Open New Dataset",
|
||||
{
|
||||
connectionStatus = ConnectionStatus.CONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("New dataset OK")))
|
||||
if (doUpload) doUpload()
|
||||
else releaseWakeLock()
|
||||
}, {
|
||||
rxBus.send(EventTidepoolStatus(("New dataset FAILED")))
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
releaseWakeLock()
|
||||
})
|
||||
)
|
||||
} else {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Existing Dataset: " + session.datasetReply!!.getUploadId())
|
||||
// TODO: Wouldn't need to do this if we could block on the above `call.enqueue`.
|
||||
// ie, do the openDataSet conditionally, and then do `doUpload` either way.
|
||||
connectionStatus = ConnectionStatus.CONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Appending to existing dataset")))
|
||||
if (doUpload) doUpload()
|
||||
else releaseWakeLock()
|
||||
}
|
||||
}, {
|
||||
rxBus.send(EventTidepoolStatus(("New dataset FAILED")))
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
releaseWakeLock()
|
||||
}))
|
||||
} else {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Existing Dataset: " + session.datasetReply!!.getUploadId())
|
||||
// TODO: Wouldn't need to do this if we could block on the above `call.enqueue`.
|
||||
// ie, do the openDataSet conditionally, and then do `doUpload` either way.
|
||||
connectionStatus = ConnectionStatus.CONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Appending to existing dataset")))
|
||||
if (doUpload) doUpload()
|
||||
else
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
rxBus.send(EventTidepoolStatus(("Open dataset FAILED")))
|
||||
releaseWakeLock()
|
||||
}
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
rxBus.send(EventTidepoolStatus(("Open dataset FAILED")))
|
||||
releaseWakeLock()
|
||||
}))
|
||||
})
|
||||
)
|
||||
} else {
|
||||
aapsLogger.error("Got login response but cannot determine userId - cannot proceed")
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
|
@ -197,6 +205,11 @@ class TidepoolUploader @Inject constructor(
|
|||
|
||||
@Synchronized
|
||||
fun doUpload() {
|
||||
if (!isAllowed) {
|
||||
connectionStatus = ConnectionStatus.BLOCKED
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Blocked by connectivity settings")
|
||||
return
|
||||
}
|
||||
session.let { session ->
|
||||
if (session == null) {
|
||||
aapsLogger.error("Session is null, cannot proceed")
|
||||
|
@ -225,16 +238,20 @@ class TidepoolUploader @Inject constructor(
|
|||
rxBus.send(EventTidepoolStatus(("Uploading")))
|
||||
if (session.service != null && session.token != null && session.datasetReply != null) {
|
||||
val call = session.service.doUpload(session.token!!, session.datasetReply!!.getUploadId()!!, body)
|
||||
call.enqueue(TidepoolCallback<UploadReplyMessage>(aapsLogger, rxBus, session, "Data Upload", {
|
||||
uploadChunk.setLastEnd(session.end)
|
||||
rxBus.send(EventTidepoolStatus(("Upload completed OK")))
|
||||
releaseWakeLock()
|
||||
uploadNext()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.FAILED
|
||||
rxBus.send(EventTidepoolStatus(("Upload FAILED")))
|
||||
releaseWakeLock()
|
||||
}))
|
||||
call.enqueue(TidepoolCallback<UploadReplyMessage>(
|
||||
aapsLogger, rxBus, session, "Data Upload",
|
||||
{
|
||||
uploadChunk.setLastEnd(session.end)
|
||||
connectionStatus = ConnectionStatus.CONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Upload completed OK")))
|
||||
releaseWakeLock()
|
||||
uploadNext()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Upload FAILED")))
|
||||
releaseWakeLock()
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +259,12 @@ class TidepoolUploader @Inject constructor(
|
|||
}
|
||||
|
||||
private fun uploadNext() {
|
||||
if (uploadChunk.getLastEnd() < dateUtil.now() - T.mins(1).msecs()) {
|
||||
if (!isAllowed) {
|
||||
connectionStatus = ConnectionStatus.BLOCKED
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Blocked by connectivity settings")
|
||||
return
|
||||
}
|
||||
if (uploadChunk.getLastEnd() < dateUtil.now() - T.hours(3).msecs() - T.mins(1).msecs()) {
|
||||
SystemClock.sleep(3000)
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Restarting doUpload. Last: " + dateUtil.dateAndTimeString(uploadChunk.getLastEnd()))
|
||||
doUpload()
|
||||
|
@ -253,15 +275,18 @@ class TidepoolUploader @Inject constructor(
|
|||
if (session?.datasetReply?.id != null) {
|
||||
extendWakeLock(60000)
|
||||
val call = session!!.service?.deleteDataSet(session!!.token!!, session!!.datasetReply!!.id!!)
|
||||
call?.enqueue(TidepoolCallback(aapsLogger, rxBus, session!!, "Delete Dataset", {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Dataset removed OK")))
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Dataset remove FAILED")))
|
||||
releaseWakeLock()
|
||||
}))
|
||||
call?.enqueue(TidepoolCallback(
|
||||
aapsLogger, rxBus, session!!, "Delete Dataset",
|
||||
{
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Dataset removed OK")))
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("Dataset remove FAILED")))
|
||||
releaseWakeLock()
|
||||
})
|
||||
)
|
||||
} else {
|
||||
aapsLogger.error("Got login response but cannot determine datasetId - cannot proceed")
|
||||
}
|
||||
|
@ -278,15 +303,19 @@ class TidepoolUploader @Inject constructor(
|
|||
requireNotNull(userId)
|
||||
extendWakeLock(60000)
|
||||
val call = session.service?.deleteAllData(token, userId)
|
||||
call?.enqueue(TidepoolCallback(aapsLogger, rxBus, session, "Delete all data", {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("All data removed OK")))
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("All data remove FAILED")))
|
||||
releaseWakeLock()
|
||||
}))
|
||||
call?.enqueue(
|
||||
TidepoolCallback(
|
||||
aapsLogger, rxBus, session, "Delete all data",
|
||||
{
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("All data removed OK")))
|
||||
releaseWakeLock()
|
||||
}, {
|
||||
connectionStatus = ConnectionStatus.DISCONNECTED
|
||||
rxBus.send(EventTidepoolStatus(("All data remove FAILED")))
|
||||
releaseWakeLock()
|
||||
})
|
||||
)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
aapsLogger.error("Got login response but cannot determine userId - cannot proceed")
|
||||
}
|
||||
|
@ -307,13 +336,12 @@ class TidepoolUploader @Inject constructor(
|
|||
@Synchronized
|
||||
private fun releaseWakeLock() {
|
||||
wl?.let {
|
||||
if (it.isHeld) {
|
||||
if (it.isHeld)
|
||||
try {
|
||||
it.release()
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Error releasing wakelock: $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,21 +41,21 @@ class UploadChunk @Inject constructor(
|
|||
private val maxUploadSize = T.days(7).msecs() // don't change this
|
||||
|
||||
fun getNext(session: Session?): String? {
|
||||
if (session == null)
|
||||
return null
|
||||
session ?: return null
|
||||
|
||||
session.start = getLastEnd()
|
||||
session.end = min(session.start + maxUploadSize, dateUtil.now())
|
||||
// do not upload last 3h, TBR can be still running
|
||||
session.end = min(session.start + maxUploadSize, dateUtil.now() - T.hours(3).msecs())
|
||||
|
||||
val result = get(session.start, session.end)
|
||||
if (result.length < 3) {
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "No records in this time period, setting start to best end time")
|
||||
setLastEnd(max(session.end, getOldestRecordTimeStamp()))
|
||||
setLastEnd(session.end)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun get(start: Long, end: Long): String {
|
||||
fun get(start: Long, end: Long): String {
|
||||
|
||||
aapsLogger.debug(LTag.TIDEPOOL, "Syncing data between: " + dateUtil.dateAndTimeString(start) + " -> " + dateUtil.dateAndTimeString(end))
|
||||
if (end <= start) {
|
||||
|
@ -69,16 +69,11 @@ class UploadChunk @Inject constructor(
|
|||
|
||||
val records = LinkedList<BaseElement>()
|
||||
|
||||
if (sp.getBoolean(R.string.key_tidepool_upload_bolus, true))
|
||||
records.addAll(getTreatments(start, end))
|
||||
if (sp.getBoolean(R.string.key_tidepool_upload_bg, true))
|
||||
records.addAll(getBloodTests(start, end))
|
||||
if (sp.getBoolean(R.string.key_tidepool_upload_tbr, true))
|
||||
records.addAll(getBasals(start, end))
|
||||
if (sp.getBoolean(R.string.key_tidepool_upload_cgm, true))
|
||||
records.addAll(getBgReadings(start, end))
|
||||
if (sp.getBoolean(R.string.key_tidepool_upload_profile, true))
|
||||
records.addAll(getProfiles(start, end))
|
||||
records.addAll(getTreatments(start, end))
|
||||
records.addAll(getBloodTests(start, end))
|
||||
records.addAll(getBasals(start, end))
|
||||
records.addAll(getBgReadings(start, end))
|
||||
records.addAll(getProfiles(start, end))
|
||||
|
||||
return GsonInstance.defaultGsonInstance().toJson(records)
|
||||
}
|
||||
|
@ -99,21 +94,6 @@ class UploadChunk @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// numeric limits must match max time windows
|
||||
|
||||
private fun getOldestRecordTimeStamp(): Long {
|
||||
// TODO we could make sure we include records older than the first bg record for completeness
|
||||
|
||||
val start: Long = 0
|
||||
val end = dateUtil.now()
|
||||
|
||||
val bgReadingList = repository.compatGetBgReadingsDataFromTime(start, end, true)
|
||||
.blockingGet()
|
||||
return if (bgReadingList.isNotEmpty())
|
||||
bgReadingList[0].timestamp
|
||||
else -1
|
||||
}
|
||||
|
||||
private fun getTreatments(start: Long, end: Long): List<BaseElement> {
|
||||
val result = LinkedList<BaseElement>()
|
||||
repository.getBolusesDataFromTimeToTime(start, end, true)
|
||||
|
|
|
@ -7,7 +7,7 @@ import info.nightscout.interfaces.profile.Profile
|
|||
import info.nightscout.shared.utils.DateUtil
|
||||
import java.util.UUID
|
||||
|
||||
class BasalElement(tbr: TemporaryBasal, private val profile: Profile, dateUtil: DateUtil)
|
||||
class BasalElement(tbr: TemporaryBasal, profile: Profile, dateUtil: DateUtil)
|
||||
: BaseElement(tbr.timestamp, UUID.nameUUIDFromBytes(("AAPS-basal" + tbr.timestamp).toByteArray()).toString(), dateUtil) {
|
||||
|
||||
internal var timestamp: Long = 0 // not exposed
|
||||
|
|
|
@ -35,14 +35,21 @@ class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil:
|
|||
init {
|
||||
type = "pumpSettings"
|
||||
val profile: Profile = ProfileSealed.EPS(ps)
|
||||
for (br in profile.getBasalValues())
|
||||
basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value))
|
||||
for (target in profile.getSingleTargetsMgdl())
|
||||
bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, target.value.toInt()))
|
||||
for (ic in profile.getIcsValues())
|
||||
carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value.toInt()))
|
||||
for (isf in profile.getIsfsMgdlValues())
|
||||
insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, isf.value.toInt()))
|
||||
// for (br in profile.getBasalValues())
|
||||
// basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value))
|
||||
// for (target in profile.getSingleTargetsMgdl())
|
||||
// bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, target.value.toInt()))
|
||||
// for (ic in profile.getIcsValues())
|
||||
// carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value.toInt()))
|
||||
// for (isf in profile.getIsfsMgdlValues())
|
||||
// insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, isf.value.toInt()))
|
||||
for (hour in 0..23) {
|
||||
val seconds = hour * 3600
|
||||
basalSchedules.Normal.add(BasalRate(seconds * 1000, profile.getBasalTimeFromMidnight(seconds)))
|
||||
bgTargets.Normal.add(Target(seconds * 1000, Profile.toMgdl((((profile.getTargetLowMgdlTimeFromMidnight(seconds) + profile.getTargetLowMgdlTimeFromMidnight(seconds))) / 2)).toInt()))
|
||||
carbRatios.Normal.add(Ratio(seconds * 1000, profile.getIcTimeFromMidnight(seconds).toInt()))
|
||||
insulinSensitivities.Normal.add(Ratio(seconds * 1000, profile.getIsfMgdlTimeFromMidnight(seconds).toInt()))
|
||||
}
|
||||
}
|
||||
|
||||
inner class BasalProfile internal constructor(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".sync.nsShared.NSClientFragment">
|
||||
tools:context="info.nightscout.plugins.sync.nsShared.NSClientFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,82 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
tools:context="info.nightscout.plugins.sync.tidepool.TidepoolFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="0dp"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="1dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="-"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="HardcodedText" />
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/login"
|
||||
style="@style/GrayButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/login"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:text="@string/status"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/uploadnow"
|
||||
style="@style/GrayButton"
|
||||
android:layout_width="113dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/upload_now"
|
||||
app:layout_constraintStart_toEndOf="@+id/login"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status" />
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="normal|bold" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/removeall"
|
||||
style="@style/GrayButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/remove_all"
|
||||
app:layout_constraintStart_toEndOf="@+id/uploadnow"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/resertstart"
|
||||
style="@style/GrayButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/reset_start"
|
||||
app:layout_constraintStart_toEndOf="@+id/removeall"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/logscrollview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/login"
|
||||
app:layout_constraintVertical_bias="0.023">
|
||||
android:id="@+id/log_scrollview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="-- logs --"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
android:text="" />
|
||||
</ScrollView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<string name="key_ns_device_status_last_synced_id" translatable="false">ns_device_status_last_synced_id</string>
|
||||
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
|
||||
<string name="key_ns_extended_bolus_last_synced_id" translatable="false">ns_extended_bolus_last_synced_id</string>
|
||||
<string name="key_ns_profile_switch_last_synced_id" translatable="false">profile_switch_last_synced_id</string>
|
||||
<string name="key_ns_profile_switch_last_synced_id" translatable="false">ns_profile_switch_last_synced_id</string>
|
||||
<string name="key_ns_effective_profile_switch_last_synced_id" translatable="false">ns_effective_profile_switch_last_synced_id</string>
|
||||
<string name="key_ns_offline_event_last_synced_id" translatable="false">ns_offline_event_last_synced_id</string>
|
||||
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
<!-- NSClient -->
|
||||
<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="no_write_permission">NSCLIENT has no write permission. Wrong API secret?</string>
|
||||
|
@ -113,14 +113,7 @@
|
|||
<string name="key_tidepool_password" translatable="false">tidepool_password</string>
|
||||
<string name="key_tidepool_dev_servers" translatable="false">tidepool_dev_servers</string>
|
||||
<string name="key_tidepool_test_login" translatable="false">tidepool_test_login</string>
|
||||
<string name="key_tidepool_only_while_charging" translatable="false">tidepool_only_while_charging</string>
|
||||
<string name="key_tidepool_only_while_unmetered" translatable="false">tidepool_only_while_unmetered</string>
|
||||
<string name="key_tidepool_last_end" translatable="false">tidepool_last_end</string>
|
||||
<string name="key_tidepool_upload_profile" translatable="false">tidepool_upload_profile</string>
|
||||
<string name="key_tidepool_upload_tbr" translatable="false">tidepool_upload_tbr</string>
|
||||
<string name="key_tidepool_upload_cgm" translatable="false">tidepool_upload_cgm</string>
|
||||
<string name="key_tidepool_upload_bolus" translatable="false">tidepool_upload_bolus</string>
|
||||
<string name="key_tidepool_upload_bg" translatable="false">tidepool_upload_bg</string>
|
||||
|
||||
<string name="summary_tidepool_username">Your Tidepool login user name, normally your email address</string>
|
||||
<string name="title_tidepool_username">Login User Name</string>
|
||||
|
@ -187,5 +180,7 @@
|
|||
|
||||
<!-- DataBroadcast-->
|
||||
<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>
|
|
@ -178,14 +178,13 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="nsclient_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_log_app_started_event"
|
||||
android:title="@string/ns_log_app_started_event"
|
||||
android:summary="@string/ns_log_app_started_event"
|
||||
/>
|
||||
android:summary="@string/ns_log_app_started_event" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
app:initialExpandedChildrenCount="0">
|
||||
|
||||
<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:inputType="textUri"
|
||||
android:key="@string/key_nsclientinternal_url"
|
||||
|
@ -24,7 +24,13 @@
|
|||
android:key="@string/key_ns_client_token"
|
||||
android:title="@string/nsclient_token_title"
|
||||
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
|
||||
android:key="@string/ns_sync_options"
|
||||
|
@ -178,14 +184,13 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="nsclient_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_log_app_started_event"
|
||||
android:title="@string/ns_log_app_started_event"
|
||||
android:summary="@string/ns_log_app_started_event"
|
||||
/>
|
||||
android:summary="@string/ns_log_app_started_event" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
|
|
|
@ -24,49 +24,57 @@
|
|||
android:key="@string/key_tidepool_test_login"
|
||||
android:title="@string/title_tidepool_test_login" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_tidepool_upload_cgm"
|
||||
android:title="@string/tidepool_upload_cgm" />
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="@string/connection_settings_title"
|
||||
android:title="@string/connection_settings_title">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_tidepool_upload_bolus"
|
||||
android:title="@string/tidepool_upload_bolus" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_cellular"
|
||||
android:title="@string/ns_cellular" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_tidepool_upload_bg"
|
||||
android:title="@string/tidepool_upload_bg" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:dependency="@string/key_ns_cellular"
|
||||
android:key="@string/key_ns_allow_roaming"
|
||||
android:title="@string/ns_allow_roaming" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_tidepool_upload_tbr"
|
||||
android:title="@string/tidepool_upload_tbr" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_wifi"
|
||||
android:title="@string/ns_wifi" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_tidepool_upload_profile"
|
||||
android:title="@string/tidepool_upload_profile" />
|
||||
<EditTextPreference
|
||||
android:dialogMessage="@string/ns_wifi_allowed_ssids"
|
||||
android:dependency="@string/key_ns_wifi"
|
||||
android:inputType="text"
|
||||
android:key="@string/key_ns_wifi_ssids"
|
||||
android:title="@string/ns_wifi_ssids" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:enabled="false"
|
||||
android:key="@string/key_tidepool_dev_servers"
|
||||
android:summary="@string/summary_tidepool_dev_servers"
|
||||
android:title="@string/title_tidepool_dev_servers" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_battery"
|
||||
android:title="@string/ns_battery" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_tidepool_only_while_charging"
|
||||
android:summary="Upload data only when charging"
|
||||
android:title="Only when charging" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_charging"
|
||||
android:title="@string/ns_charging" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_tidepool_only_while_unmetered"
|
||||
android:summary="Upload data only when connected to an unmetered network like Wifi"
|
||||
android:title="Only on Wifi" />
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="nsclient_advanced"
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_tidepool_dev_servers"
|
||||
android:summary="@string/summary_tidepool_dev_servers"
|
||||
android:title="@string/title_tidepool_dev_servers" />
|
||||
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.junit.Assert
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
|
||||
class NsClientReceiverDelegateTest : TestBase() {
|
||||
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var rh: ResourceHelper
|
||||
val rxBus = RxBus(aapsSchedulers, aapsLogger)
|
||||
|
||||
@Mock private lateinit var receiverStatusStore: ReceiverStatusStore
|
||||
private lateinit var sut: NsClientReceiverDelegate
|
||||
|
||||
|
||||
@BeforeEach
|
||||
fun prepare() {
|
||||
//receiverStatusStore = ReceiverStatusStore(context, rxBus)
|
||||
sut = NsClientReceiverDelegate(rxBus, rh, sp, receiverStatusStore)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCalculateStatusChargingState() {
|
||||
`when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(false)
|
||||
Assert.assertTrue(sut.calculateStatus(EventChargingState(false, 0)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventChargingState(true, 0)))
|
||||
`when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(false)
|
||||
`when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(true)
|
||||
Assert.assertTrue(sut.calculateStatus(EventChargingState(true, 0)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventChargingState(false, 0)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCalculateStatusNetworkState() {
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = true, wifiConnected = true)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = false, wifiConnected = true)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("test")
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = true, wifiConnected = true)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = false, wifiConnected = true)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = true, wifiConnected = true)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = false, wifiConnected = true)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(false)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(wifiConnected = true)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true)))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(false)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false)))
|
||||
Assert.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true)))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false)))
|
||||
Assert.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true)))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
|
||||
class ReceiverDelegateTest : TestBase() {
|
||||
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var rh: ResourceHelper
|
||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
private val rxBus = RxBus(aapsSchedulers, aapsLogger)
|
||||
|
||||
@Mock private lateinit var receiverStatusStore: ReceiverStatusStore
|
||||
private lateinit var sut: ReceiverDelegate
|
||||
|
||||
@BeforeEach
|
||||
fun prepare() {
|
||||
//receiverStatusStore = ReceiverStatusStore(context, rxBus)
|
||||
sut = ReceiverDelegate(rxBus, rh, sp, receiverStatusStore, aapsSchedulers, fabricPrivacy)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCalculateStatusChargingState() {
|
||||
`when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(false)
|
||||
Assertions.assertTrue(sut.calculateStatus(EventChargingState(false, 0)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventChargingState(true, 0)))
|
||||
`when`(sp.getBoolean(R.string.key_ns_battery, true)).thenReturn(false)
|
||||
`when`(sp.getBoolean(R.string.key_ns_charging, true)).thenReturn(true)
|
||||
Assertions.assertTrue(sut.calculateStatus(EventChargingState(true, 0)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventChargingState(false, 0)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCalculateStatusNetworkState() {
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = true, wifiConnected = true)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = false, wifiConnected = true)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("test")
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = true)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, wifiConnected = false, roaming = false)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = true, wifiConnected = true)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange(ssid = "<unknown ssid>", mobileConnected = false, wifiConnected = true)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = true, wifiConnected = true)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(ssid = "test", mobileConnected = false, wifiConnected = true)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(false)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(wifiConnected = true)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange()))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true)))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(false)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false)))
|
||||
Assertions.assertFalse(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true)))
|
||||
|
||||
`when`(sp.getBoolean(R.string.key_ns_cellular, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_wifi, true)).thenReturn(true)
|
||||
`when`(sp.getBoolean(R.string.key_ns_allow_roaming, true)).thenReturn(true)
|
||||
`when`(sp.getString(R.string.key_ns_wifi_ssids, "")).thenReturn("")
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = false)))
|
||||
Assertions.assertTrue(sut.calculateStatus(EventNetworkChange(mobileConnected = true, roaming = true)))
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3
|
||||
|
||||
import androidx.work.WorkManager
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.core.extensions.fromConstant
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.database.entities.Carbs
|
||||
|
@ -26,8 +28,10 @@ import info.nightscout.interfaces.pump.VirtualPump
|
|||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclient.extensions.fromConstant
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
|
||||
|
@ -45,7 +49,7 @@ import org.mockito.internal.verification.Times
|
|||
@Suppress("SpellCheckingInspection")
|
||||
internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
||||
|
||||
@Mock lateinit var nsClientReceiverDelegate: NsClientReceiverDelegate
|
||||
@Mock lateinit var receiverDelegate: ReceiverDelegate
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
@Mock lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Mock lateinit var nsAndroidClient: NSAndroidClient
|
||||
|
@ -54,6 +58,10 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Mock lateinit var virtualPump: VirtualPump
|
||||
@Mock lateinit var mockedProfileFunction: ProfileFunction
|
||||
@Mock lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
|
||||
@Mock lateinit var workManager: WorkManager
|
||||
@Mock lateinit var workerClasses: WorkerClasses
|
||||
@Mock lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
|
||||
private lateinit var storeDataForDb: StoreDataForDb
|
||||
private lateinit var sut: NSClientV3Plugin
|
||||
|
@ -65,11 +73,12 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
|
|||
|
||||
@BeforeEach
|
||||
fun prepare() {
|
||||
storeDataForDb = StoreDataForDbImpl(aapsLogger, rxBus, repository, sp, uel, dateUtil, config, nsClientSource, xDripBroadcast, virtualPump, uiInteraction)
|
||||
storeDataForDb = StoreDataForDbImpl(aapsLogger, rxBus, repository, sp, uel, dateUtil, config, nsClientSource, virtualPump, uiInteraction)
|
||||
sut =
|
||||
NSClientV3Plugin(
|
||||
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
|
||||
sp, nsClientReceiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, mockedProfileFunction, repository
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, mockedProfileFunction, repository,
|
||||
nsDeviceStatusHandler, workManager, workerClasses, dataWorkerStorage, nsClientSource
|
||||
)
|
||||
sut.nsAndroidClient = nsAndroidClient
|
||||
`when`(mockedProfileFunction.getProfile(anyLong())).thenReturn(validProfile)
|
||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
@ -27,6 +28,7 @@ internal class DataSyncWorkerTest : TestBase() {
|
|||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
@Mock lateinit var nsClient: NsClient
|
||||
@Mock lateinit var rxBus: RxBus
|
||||
@Mock lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
||||
private lateinit var sut: DataSyncWorker
|
||||
|
||||
|
@ -38,6 +40,7 @@ internal class DataSyncWorkerTest : TestBase() {
|
|||
it.dataSyncSelector = dataSyncSelector
|
||||
it.activePlugin = activePlugin
|
||||
it.rxBus = rxBus
|
||||
it.nsClientV3Plugin = nsClientV3Plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ import info.nightscout.interfaces.source.NSClientSource
|
|||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
|
@ -37,6 +38,7 @@ import org.junit.jupiter.api.Assertions
|
|||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
|
@ -49,7 +51,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
@Mock lateinit var workerClasses: WorkerClasses
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Mock lateinit var rxBus: RxBus
|
||||
@Mock lateinit var dateUtil: DateUtil
|
||||
@Mock lateinit var nsAndroidClient: NSAndroidClient
|
||||
@Mock lateinit var rh: ResourceHelper
|
||||
|
@ -62,9 +63,11 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
@Mock lateinit var nsClientSource: NSClientSource
|
||||
@Mock lateinit var workManager: WorkManager
|
||||
@Mock lateinit var workContinuation: WorkContinuation
|
||||
@Mock lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
|
||||
|
||||
private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger)
|
||||
private lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
private lateinit var nsClientReceiverDelegate: NsClientReceiverDelegate
|
||||
private lateinit var receiverDelegate: ReceiverDelegate
|
||||
private lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
private lateinit var sut: LoadBgWorker
|
||||
|
||||
|
@ -95,10 +98,11 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
Mockito.`when`(dateUtil.now()).thenReturn(now)
|
||||
Mockito.`when`(nsClientSource.isEnabled()).thenReturn(true)
|
||||
dataWorkerStorage = DataWorkerStorage(context)
|
||||
nsClientReceiverDelegate = NsClientReceiverDelegate(rxBus, rh, sp, receiverStatusStore)
|
||||
receiverDelegate = ReceiverDelegate(rxBus, rh, sp, receiverStatusStore, aapsSchedulers, fabricPrivacy)
|
||||
nsClientV3Plugin = NSClientV3Plugin(
|
||||
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy, sp, nsClientReceiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector,
|
||||
profileFunction, repository
|
||||
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
|
||||
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, profileFunction, repository,
|
||||
nsDeviceStatusHandler, workManager, workerClasses, dataWorkerStorage, nsClientSource
|
||||
)
|
||||
nsClientV3Plugin.newestDataOnServer = LastModified(LastModified.Collections())
|
||||
}
|
||||
|
@ -121,7 +125,7 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Assertions.assertTrue(result.outputData.getString("Result") == "Load not enabled")
|
||||
Mockito.verify(workManager, Mockito.times(1)).enqueueUniqueWork(
|
||||
eq(NSClientV3Plugin.JOB_NAME),
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
|
@ -135,13 +139,13 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = 0L // first load
|
||||
nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries = now - 1000
|
||||
sut = TestListenableWorkerBuilder<LoadBgWorker>(context).build()
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyLong())).thenReturn(NSAndroidClient.ReadResponse(200, 0, emptyList()))
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyInt())).thenReturn(NSAndroidClient.ReadResponse(200, 0, emptyList()))
|
||||
|
||||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertEquals(now - 1000, nsClientV3Plugin.lastLoadedSrvModified.collections.entries)
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(NSClientV3Plugin.JOB_NAME),
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
|
@ -172,12 +176,12 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = 0L // first load
|
||||
nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries = now - 1000
|
||||
sut = TestListenableWorkerBuilder<LoadBgWorker>(context).build()
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyLong())).thenReturn(NSAndroidClient.ReadResponse(200, 0, listOf(glucoseValue.toNSSvgV3())))
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyInt())).thenReturn(NSAndroidClient.ReadResponse(200, 0, listOf(glucoseValue.toNSSvgV3())))
|
||||
|
||||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(NSClientV3Plugin.JOB_NAME),
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
|
@ -194,13 +198,13 @@ internal class LoadBgWorkerTest : TestBase() {
|
|||
nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries = now - 1000
|
||||
nsClientV3Plugin.newestDataOnServer?.collections?.entries = now - 2000
|
||||
sut = TestListenableWorkerBuilder<LoadBgWorker>(context).build()
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyLong())).thenReturn(NSAndroidClient.ReadResponse(200, 0, emptyList()))
|
||||
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyInt())).thenReturn(NSAndroidClient.ReadResponse(200, 0, emptyList()))
|
||||
|
||||
val result = sut.doWorkAndLog()
|
||||
Assertions.assertEquals(now - 1000, nsClientV3Plugin.lastLoadedSrvModified.collections.entries)
|
||||
Assertions.assertTrue(result is ListenableWorker.Result.Success)
|
||||
Mockito.verify(workManager, Mockito.times(1)).beginUniqueWork(
|
||||
eq(NSClientV3Plugin.JOB_NAME),
|
||||
eq(nsClientV3Plugin.JOB_NAME),
|
||||
eq(ExistingWorkPolicy.APPEND_OR_REPLACE),
|
||||
any<OneTimeWorkRequest>()
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue