Tidepool: improve settings, upload & and enable

This commit is contained in:
Milos Kozak 2023-01-29 22:33:23 +01:00
parent 8db9891140
commit 26c0b7c896
28 changed files with 234 additions and 213 deletions

View file

@ -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 }
}

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -2,4 +2,4 @@ package info.nightscout.plugins.sync.nsShared.events
import info.nightscout.rx.events.Event
class EventNSConnectivityOptionChanged(val blockingReason: String) : Event()
class EventConnectivityOptionChanged(val blockingReason: String) : Event()

View file

@ -63,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,
@ -89,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)

View file

@ -4,7 +4,7 @@ import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.events.EventNSConnectivityOptionChanged
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventChargingState
@ -19,7 +19,7 @@ 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,
@ -94,7 +94,7 @@ class NsClientReceiverDelegate @Inject constructor(
if (newAllowedState != allowed) {
allowed = newAllowedState
if (allowed) blockingReason = ""
rxBus.send(EventNSConnectivityOptionChanged(blockingReason))
rxBus.send(EventConnectivityOptionChanged(blockingReason))
}
}

View file

@ -31,9 +31,9 @@ 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.nsShared.events.EventNSConnectivityOptionChanged
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
@ -149,7 +149,7 @@ class NSClientService : DaggerService() {
}
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventNSConnectivityOptionChanged::class.java)
.toObservable(EventConnectivityOptionChanged::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
latestDateInReceivedData = 0

View file

@ -39,10 +39,10 @@ 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.nsShared.events.EventNSConnectivityOptionChanged
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
@ -113,7 +113,7 @@ 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,
@ -166,8 +166,8 @@ class NSClientV3Plugin @Inject constructor(
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
@ -186,9 +186,9 @@ class NSClientV3Plugin @Inject constructor(
setClient("START")
nsClientReceiverDelegate.grabReceiversState()
receiverDelegate.grabReceiversState()
disposable += rxBus
.toObservable(EventNSConnectivityOptionChanged::class.java)
.toObservable(EventConnectivityOptionChanged::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ ev ->
rxBus.send(EventNSClientNewLog("● CONNECTIVITY", ev.blockingReason))

View file

@ -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
}
}

View file

@ -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() {

View file

@ -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
@ -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
@ -139,7 +144,6 @@ class TidepoolUploader @Inject constructor(
"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")
@ -197,6 +201,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")
@ -231,7 +240,7 @@ class TidepoolUploader @Inject constructor(
releaseWakeLock()
uploadNext()
}, {
connectionStatus = ConnectionStatus.FAILED
connectionStatus = ConnectionStatus.DISCONNECTED
rxBus.send(EventTidepoolStatus(("Upload FAILED")))
releaseWakeLock()
}))
@ -242,6 +251,11 @@ class TidepoolUploader @Inject constructor(
}
private fun uploadNext() {
if (!isAllowed) {
connectionStatus = ConnectionStatus.BLOCKED
aapsLogger.debug(LTag.TIDEPOOL, "Blocked by connectivity settings")
return
}
if (uploadChunk.getLastEnd() < dateUtil.now() - T.mins(1).msecs()) {
SystemClock.sleep(3000)
aapsLogger.debug(LTag.TIDEPOOL, "Restarting doUpload. Last: " + dateUtil.dateAndTimeString(uploadChunk.getLastEnd()))

View file

@ -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)
}

View file

@ -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(

View file

@ -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"

View file

@ -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>

View file

@ -115,14 +115,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>

View file

@ -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"

View file

@ -184,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"

View file

@ -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>

View file

@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
class NsClientReceiverDelegateTest : TestBase() {
class ReceiverDelegateTest : TestBase() {
@Mock lateinit var sp: SP
@Mock lateinit var rh: ResourceHelper
@ -23,12 +23,12 @@ class NsClientReceiverDelegateTest : TestBase() {
private val rxBus = RxBus(aapsSchedulers, aapsLogger)
@Mock private lateinit var receiverStatusStore: ReceiverStatusStore
private lateinit var sut: NsClientReceiverDelegate
private lateinit var sut: ReceiverDelegate
@BeforeEach
fun prepare() {
//receiverStatusStore = ReceiverStatusStore(context, rxBus)
sut = NsClientReceiverDelegate(rxBus, rh, sp, receiverStatusStore, aapsSchedulers, fabricPrivacy)
sut = ReceiverDelegate(rxBus, rh, sp, receiverStatusStore, aapsSchedulers, fabricPrivacy)
}
@Test

View file

@ -30,7 +30,7 @@ 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
@ -49,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
@ -77,7 +77,7 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
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

View file

@ -22,7 +22,7 @@ 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
@ -66,7 +66,7 @@ internal class LoadBgWorkerTest : TestBase() {
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
@ -97,10 +97,10 @@ 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, aapsSchedulers, fabricPrivacy)
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,
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector, profileFunction, repository,
nsDeviceStatusHandler, workManager, workerClasses, dataWorkerStorage, nsClientSource
)
nsClientV3Plugin.newestDataOnServer = LastModified(LastModified.Collections())