Merge branch 'dev' into smoothing
This commit is contained in:
commit
37510088c5
|
@ -349,6 +349,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
|
|||
message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n"
|
||||
message += "${rh.gs(info.nightscout.configuration.R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.getVersion()}"
|
||||
if (config.isEngineeringMode()) message += "\n${rh.gs(info.nightscout.configuration.R.string.engineering_mode_enabled)}"
|
||||
if (config.isUnfinishedMode()) message += "\nUnfinished mode enabled"
|
||||
if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(R.string.fabric_upload_disabled)}"
|
||||
message += rh.gs(info.nightscout.pump.combo.R.string.about_link_urls)
|
||||
val messageSpanned = SpannableString(message)
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.insight.database.InsightDatabaseDao
|
|||
import info.nightscout.androidaps.insight.database.InsightDbHelper
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
|
@ -274,13 +275,13 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
// 2x Safety & Objectives
|
||||
@Test
|
||||
fun isClosedLoopAllowedTest() {
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
|
||||
var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed()
|
||||
aapsLogger.debug("Reason list: " + c.reasonList.toString())
|
||||
// Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
|
||||
Assertions.assertEquals(false, c.value())
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||
c = constraintChecker.isClosedLoopAllowed()
|
||||
Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
|
||||
// Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
|
||||
|
@ -323,7 +324,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
|
||||
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
|
||||
val c = constraintChecker.isSMBModeEnabled()
|
||||
Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
|
||||
|
@ -430,7 +431,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
@Test
|
||||
fun iobAMAShouldBeLimited() {
|
||||
// No limit by default
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
|
||||
openAPSAMAPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
|
@ -446,7 +447,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
@Test
|
||||
fun iobSMBShouldBeLimited() {
|
||||
// No limit by default
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
|
||||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
|
|
|
@ -7,6 +7,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.configBuilder.RunningConfiguration
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
|
@ -70,7 +71,7 @@ class LoopPluginTest : TestBase() {
|
|||
fun testPluginInterface() {
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.loop)).thenReturn("Loop")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.loop_shortname)).thenReturn("LOOP")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
val pumpDescription = PumpDescription()
|
||||
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
|
||||
Assert.assertEquals(LoopFragment::class.java.name, loopPlugin.pluginDescription.fragmentClass)
|
||||
|
|
|
@ -5,6 +5,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.HardLimitsMock
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
|
@ -98,7 +99,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
|
||||
@Test
|
||||
fun disabledEngineeringModeShouldLimitClosedLoop() {
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
||||
|
@ -108,7 +109,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
|
||||
@Test
|
||||
fun setOpenLoopInPreferencesShouldLimitClosedLoop() {
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
||||
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
|
||||
|
@ -278,7 +279,7 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
//`when`(openAPSSMBPlugin.isEnabled()).thenReturn(true)
|
||||
//`when`(openAPSAMAPlugin.isEnabled()).thenReturn(false)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("lgs")
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.LGS.name)
|
||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5)
|
||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
||||
</manifest>
|
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.interfaces
|
||||
|
||||
enum class ApsMode() {
|
||||
OPEN,
|
||||
CLOSED,
|
||||
LGS,
|
||||
UNDEFINED;
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromString(stringValue: String?) = values().firstOrNull { it.name == stringValue?.uppercase() } ?: UNDEFINED
|
||||
}
|
||||
}
|
|
@ -17,21 +17,24 @@ import org.json.JSONObject
|
|||
|
||||
interface DataSyncSelector {
|
||||
|
||||
interface DataPair
|
||||
data class PairTemporaryTarget(val value: TemporaryTarget, val updateRecordId: Long): DataPair
|
||||
data class PairGlucoseValue(val value: GlucoseValue, val updateRecordId: Long): DataPair
|
||||
data class PairTherapyEvent(val value: TherapyEvent, val updateRecordId: Long): DataPair
|
||||
data class PairFood(val value: Food, val updateRecordId: Long): DataPair
|
||||
data class PairBolus(val value: Bolus, val updateRecordId: Long): DataPair
|
||||
data class PairCarbs(val value: Carbs, val updateRecordId: Long): DataPair
|
||||
data class PairBolusCalculatorResult(val value: BolusCalculatorResult, val updateRecordId: Long): DataPair
|
||||
data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long): DataPair
|
||||
data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long): DataPair
|
||||
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long): DataPair
|
||||
data class PairEffectiveProfileSwitch(val value: EffectiveProfileSwitch, val updateRecordId: Long): DataPair
|
||||
data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long): DataPair
|
||||
data class PairProfileStore(val value: JSONObject, val timestampSync: Long): DataPair
|
||||
data class PairDeviceStatus(val value: DeviceStatus, val unused: Long?): DataPair
|
||||
interface DataPair {
|
||||
val value: Any
|
||||
val id: Long
|
||||
}
|
||||
data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long): DataPair
|
||||
data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long): DataPair
|
||||
data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long): DataPair
|
||||
data class PairFood(override val value: Food, override val id: Long): DataPair
|
||||
data class PairBolus(override val value: Bolus, override val id: Long): DataPair
|
||||
data class PairCarbs(override val value: Carbs, override val id: Long): DataPair
|
||||
data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long): DataPair
|
||||
data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long): DataPair
|
||||
data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long): DataPair
|
||||
data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long): DataPair
|
||||
data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long): DataPair
|
||||
data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long): DataPair
|
||||
data class PairProfileStore(override val value: JSONObject, override val id: Long): DataPair
|
||||
data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long): DataPair
|
||||
|
||||
fun queueSize(): Long
|
||||
|
||||
|
|
|
@ -16,7 +16,31 @@ interface NsClient : Sync {
|
|||
fun textLog(): Spanned
|
||||
fun clearLog()
|
||||
|
||||
enum class Collection { ENTRIES, TREATMENTS}
|
||||
/**
|
||||
* NSC v3 does first load of all data
|
||||
* next loads are using srvModified property for sync
|
||||
* not used for NSCv1
|
||||
*
|
||||
* @return true if inside first load of NSCv3, true for NSCv1
|
||||
*/
|
||||
fun isFirstLoad(collection: Collection): Boolean = true
|
||||
|
||||
/**
|
||||
* Update newest loaded timestamp for entries collection (first load or NSCv1)
|
||||
* Update newest srvModified (sync loads)
|
||||
*
|
||||
* @param latestReceived timestamp
|
||||
*
|
||||
*/
|
||||
fun updateLatestBgReceivedIfNewer(latestReceived: Long)
|
||||
/**
|
||||
* Update newest loaded timestamp for treatments collection (first load or NSCv1)
|
||||
* Update newest srvModified (sync loads)
|
||||
*
|
||||
* @param latestReceived timestamp
|
||||
*
|
||||
*/
|
||||
fun updateLatestTreatmentReceivedIfNewer(latestReceived: Long)
|
||||
fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long)
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package info.nightscout.interfaces.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.provider.AlarmClock
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
open class TimerUtil @Inject constructor(
|
||||
private val context: Context
|
||||
) {
|
||||
|
||||
/**
|
||||
* Schedule alarm in @seconds
|
||||
*/
|
||||
fun scheduleReminder(seconds: Int, text: String) {
|
||||
Intent(AlarmClock.ACTION_SET_TIMER).apply {
|
||||
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
putExtra(AlarmClock.EXTRA_LENGTH, seconds)
|
||||
putExtra(AlarmClock.EXTRA_SKIP_UI, true)
|
||||
putExtra(AlarmClock.EXTRA_MESSAGE, text)
|
||||
context.startActivity(this)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||
import info.nightscout.sdk.exceptions.DateHeaderOutOfToleranceException
|
||||
import info.nightscout.sdk.exceptions.InvalidAccessTokenException
|
||||
import info.nightscout.sdk.exceptions.InvalidFormatNightscoutException
|
||||
import info.nightscout.sdk.exceptions.TodoNightscoutException
|
||||
import info.nightscout.sdk.exceptions.UnsuccessfullNightscoutException
|
||||
import info.nightscout.sdk.exceptions.UnknownResponseNightscoutException
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.Status
|
||||
|
@ -101,9 +101,9 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.lastModified()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result ?: throw TodoNightscoutException()
|
||||
return@callWrapper response.body()?.result ?: throw UnsuccessfullNightscoutException()
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,17 +114,19 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSgvsModifiedSince(from: Long): List<NSSgvV3> = callWrapper(dispatcher) {
|
||||
override suspend fun getSgvsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSSgvV3>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getSgvsModifiedSince(from)
|
||||
val response = api.getSgvsModifiedSince(from, limit)
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw UnsuccessfullNightscoutException()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,17 +136,29 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment> = callWrapper(dispatcher) {
|
||||
override suspend fun getTreatmentsNewerThan(from: Long, limit: Long): List<NSTreatment> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getTreatmentsModifiedSince(from, limit)
|
||||
val response = api.getTreatmentsNewerThan(from, limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSTreatment>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getTreatmentsModifiedSince(from, limit)
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw UnsuccessfullNightscoutException()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
|
||||
} else {
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,23 +168,25 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result.toNotNull()
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException()
|
||||
remoteTreatment.app = "AAPS"
|
||||
val response = api.createTreatment(remoteTreatment)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier ?: throw UnknownResponseNightscoutException(),
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
)
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,13 +196,14 @@ class NSAndroidClientImpl(
|
|||
val response = api.updateTreatment(remoteTreatment)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier ?: throw UnknownResponseNightscoutException(),
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
)
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,15 @@ import info.nightscout.sdk.remotemodel.LastModified
|
|||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kotlinx.coroutines.rx3.rxSingle
|
||||
import retrofit2.http.Query
|
||||
|
||||
class NSAndroidRxClientImpl(private val client: NSAndroidClient) : NSAndroidRxClient {
|
||||
|
||||
override fun getVersion(): Single<String> = rxSingle { client.getVersion() }
|
||||
override fun getStatus(): Single<Status> = rxSingle { client.getStatus() }
|
||||
override fun getLastModified(): Single<LastModified> = rxSingle { client.getLastModified() }
|
||||
override fun getSgvsModifiedSince(from: Long): Single<List<NSSgvV3>> = rxSingle { client.getSgvsModifiedSince(from) }
|
||||
override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<List<NSTreatment>> =
|
||||
override fun getSgvsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSSgvV3>>> = rxSingle { client.getSgvsModifiedSince(from, limit) }
|
||||
override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSTreatment>>> =
|
||||
rxSingle { client.getTreatmentsModifiedSince(from, limit) }
|
||||
override fun getDeviceStatusModifiedSince(from: Long): Single<List<RemoteDeviceStatus>> =
|
||||
rxSingle { client.getDeviceStatusModifiedSince(from) }
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
package info.nightscout.sdk.exceptions
|
||||
|
||||
class TodoNightscoutException : NightscoutException()
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.sdk.exceptions
|
||||
|
||||
class UnsuccessfullNightscoutException : NightscoutException()
|
|
@ -9,6 +9,11 @@ import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
|||
|
||||
interface NSAndroidClient {
|
||||
|
||||
class ReadResponse<T>(
|
||||
val lastServerModified: Long,
|
||||
val values: T
|
||||
)
|
||||
|
||||
val lastStatus: Status?
|
||||
suspend fun getVersion(): String
|
||||
suspend fun getStatus(): Status
|
||||
|
@ -16,9 +21,10 @@ interface NSAndroidClient {
|
|||
|
||||
suspend fun getLastModified(): LastModified
|
||||
suspend fun getSgvs(): List<NSSgvV3>
|
||||
suspend fun getSgvsModifiedSince(from: Long): List<NSSgvV3>
|
||||
suspend fun getSgvsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3>
|
||||
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment>
|
||||
suspend fun getTreatmentsNewerThan(from: Long, limit: Long): List<NSTreatment>
|
||||
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>>
|
||||
suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus>
|
||||
suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
|
||||
suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
|
||||
|
|
|
@ -12,8 +12,8 @@ interface NSAndroidRxClient {
|
|||
fun getVersion(): Single<String>
|
||||
fun getStatus(): Single<Status>
|
||||
fun getLastModified(): Single<LastModified>
|
||||
fun getSgvsModifiedSince(from: Long): Single<List<NSSgvV3>>
|
||||
fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<List<NSTreatment>>
|
||||
fun getSgvsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSSgvV3>>>
|
||||
fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSTreatment>>>
|
||||
fun getDeviceStatusModifiedSince(from: Long): Single<List<RemoteDeviceStatus>>
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
class CreateUpdateResponse(
|
||||
val response: Int,
|
||||
val identifier: String?,
|
||||
val isDeduplication: Boolean? = false,
|
||||
val deduplicatedIdentifier: String? = null,
|
||||
|
|
|
@ -19,6 +19,7 @@ data class NSBolus(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val insulin: Double,
|
||||
val type: BolusType
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import org.json.JSONObject
|
||||
|
||||
data class NSBolusWizard(
|
||||
override val date: Long,
|
||||
|
@ -20,6 +19,7 @@ data class NSBolusWizard(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val bolusCalculatorResult: String?,
|
||||
val glucose: Double?,
|
||||
) : NSTreatment
|
|
@ -4,14 +4,14 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
|
||||
data class NSCarbs(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
override val eventType: EventType,
|
||||
override val notes: String?,
|
||||
|
@ -19,6 +19,7 @@ data class NSCarbs(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val carbs: Double,
|
||||
val duration: Long
|
||||
val duration: Long?
|
||||
) : NSTreatment
|
|
@ -5,14 +5,14 @@ import org.json.JSONObject
|
|||
|
||||
data class NSEffectiveProfileSwitch(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String? = null,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
override val subject: String? = null ,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
override val eventType: EventType,
|
||||
override val notes: String?,
|
||||
|
@ -20,6 +20,7 @@ data class NSEffectiveProfileSwitch(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val profileJson: JSONObject,
|
||||
val originalProfileName: String,
|
||||
val originalCustomizedName: String,
|
||||
|
|
|
@ -19,6 +19,7 @@ data class NSExtendedBolus(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val enteredinsulin: Double,
|
||||
val isEmulatingTempBasal: Boolean?
|
||||
|
|
|
@ -19,6 +19,7 @@ data class NSOfflineEvent(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val reason: Reason
|
||||
) : NSTreatment {
|
||||
|
|
|
@ -5,23 +5,24 @@ import org.json.JSONObject
|
|||
|
||||
data class NSProfileSwitch(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val device: String? = null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val units: NsUnits? = null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
override val eventType: EventType,
|
||||
override val notes: String?,
|
||||
override val notes: String? = null,
|
||||
override val pumpId: Long?,
|
||||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val profileJson: JSONObject?,
|
||||
val profileName: String,
|
||||
val profile: String,
|
||||
val originalProfileName: String?,
|
||||
val timeShift: Long?,
|
||||
val percentage: Int?,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import org.json.JSONObject
|
||||
|
||||
data class NSTemporaryBasal(
|
||||
override val date: Long,
|
||||
|
@ -20,6 +19,7 @@ data class NSTemporaryBasal(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val rate: Double, // when sending to NS always convertedToAbsolute(timestamp, profile)
|
||||
val isAbsolute: Boolean,
|
||||
|
|
|
@ -19,6 +19,7 @@ data class NSTemporaryTarget(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val targetBottom: Double,
|
||||
val targetTop: Double,
|
||||
|
|
|
@ -20,6 +20,7 @@ data class NSTherapyEvent(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
var enteredBy: String? = null,
|
||||
var glucose: Double? = null,
|
||||
|
|
|
@ -19,6 +19,7 @@ interface NSTreatment {
|
|||
val endId: Long?
|
||||
val pumpType: String?
|
||||
val pumpSerial: String?
|
||||
var app: String?
|
||||
|
||||
fun Double.asMgdl() =
|
||||
when (units) {
|
||||
|
|
|
@ -210,7 +210,7 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
|||
pumpType = this.pumpType,
|
||||
pumpSerial = this.pumpSerial,
|
||||
profileJson = this.profileJson?.let { JSONObject(this.profileJson) },
|
||||
profileName = this.profile,
|
||||
profile = this.profile,
|
||||
originalProfileName = this.originalProfileName,
|
||||
originalDuration = this.originalDuration,
|
||||
duration = this.duration,
|
||||
|
@ -496,7 +496,7 @@ internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
|
|||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
profileJson = profileJson.toString(), // must be de-customized
|
||||
profile = profileName,
|
||||
profile = profile,
|
||||
originalProfileName = originalProfileName,
|
||||
originalDuration = originalDuration,
|
||||
duration = duration,
|
||||
|
|
|
@ -2,18 +2,15 @@ package info.nightscout.sdk.networking
|
|||
|
||||
import com.google.gson.JsonElement
|
||||
import info.nightscout.sdk.remotemodel.LastModified
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.NSResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteCreateUpdateResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.RemoteEntry
|
||||
import info.nightscout.sdk.remotemodel.RemoteStatusResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteTreatment
|
||||
import okhttp3.RequestBody
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Path
|
||||
|
@ -48,7 +45,10 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getSgvsNewerThan(@Query(value = "date\$gt", encoded = true) date: Long, @Query("limit") limit: Long): Response<NSResponse<List<RemoteEntry>>>
|
||||
|
||||
@GET("v3/entries/history/{from}")
|
||||
suspend fun getSgvsModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteEntry>>>
|
||||
suspend fun getSgvsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Long): Response<NSResponse<List<RemoteEntry>>>
|
||||
|
||||
@GET("v3/treatments")
|
||||
suspend fun getTreatmentsNewerThan(@Query(value = "date\$gt", encoded = true) date: Long, @Query("limit") limit: Long): Response<NSResponse<List<RemoteTreatment>>>
|
||||
|
||||
@GET("v3/treatments/history/{from}")
|
||||
suspend fun getTreatmentsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Long): Response<NSResponse<List<RemoteTreatment>>>
|
||||
|
@ -57,9 +57,9 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>>
|
||||
|
||||
@POST("v3/treatments")
|
||||
fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@PUT("v3/treatments")
|
||||
fun updateTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ data class LastModified(
|
|||
@Serializable
|
||||
data class Collections(
|
||||
|
||||
@SerializedName("devicestatus") var devicestatus: Long, // devicestatus collection
|
||||
@SerializedName("entries") var entries: Long, // entries collection
|
||||
@SerializedName("profile") var profile: Long, // profile collection
|
||||
@SerializedName("treatments") var treatments: Long // treatments collection
|
||||
@SerializedName("devicestatus") var devicestatus: Long = 0, // devicestatus collection
|
||||
@SerializedName("entries") var entries: Long = 0, // entries collection
|
||||
@SerializedName("profile") var profile: Long = 0, // profile collection
|
||||
@SerializedName("treatments") var treatments: Long = 0 // treatments collection
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package info.nightscout.sdk.remotemodel
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.format.ISODateTimeFormat
|
||||
import org.json.JSONObject
|
||||
|
||||
/*
|
||||
* Depending on the type, different other fields are present.
|
||||
|
@ -23,7 +21,7 @@ internal data class RemoteTreatment(
|
|||
@SerializedName("timestamp") val timestamp: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("created_at") val created_at: String? = null, // integer($int64) or string timestamp on previous version of api, in my examples, a lot of treatments don't have date, only created_at, some of them with string others with long...
|
||||
@SerializedName("utcOffset") val utcOffset: Long? = null, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is automatically parsed from the date field.
|
||||
// @SerializedName("app") val app : String, // TODO required ? Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("app") var app : String? = null, // Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("device") val device: String? = null, // string The device from which the data originated (including serial number of the device, if it is relevant and safe).
|
||||
@SerializedName("srvCreated") val srvCreated: Long? = null, // integer($int64) example: 1525383610088 The server's timestamp of document insertion into the database (Unix epoch in ms). This field appears only for documents which were inserted by API v3.
|
||||
@SerializedName("subject") val subject: String? = null, // string Name of the security subject (within Nightscout scope) which has created the document. This field is automatically set by the server from the passed token or JWT.
|
||||
|
|
|
@ -31,6 +31,7 @@ import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineE
|
|||
import info.nightscout.database.impl.transactions.InsertTherapyEventAnnouncementTransaction
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.aps.APSResult
|
||||
import info.nightscout.interfaces.aps.Loop
|
||||
import info.nightscout.interfaces.aps.Loop.LastRun
|
||||
|
@ -182,10 +183,10 @@ class LoopPlugin @Inject constructor(
|
|||
get() {
|
||||
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
|
||||
val maxIobAllowed = constraintChecker.getMaxIOBAllowed().value()
|
||||
val apsMode = sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")
|
||||
val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||
val pump = activePlugin.activePump
|
||||
var isLGS = false
|
||||
if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == HardLimits.MAX_IOB_LGS || apsMode == "lgs") isLGS = true
|
||||
if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == HardLimits.MAX_IOB_LGS || apsMode == ApsMode.LGS) isLGS = true
|
||||
return isLGS
|
||||
}
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ class AutotuneFragment : DaggerFragment() {
|
|||
|
||||
private val textWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
updateGui()
|
||||
_binding?.let { updateGui() }
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
|
|
@ -53,7 +53,7 @@ import info.nightscout.interfaces.plugin.PluginBase
|
|||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.queue.Callback
|
||||
import info.nightscout.interfaces.utils.TimerUtil
|
||||
import info.nightscout.automation.ui.TimerUtil
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventBTChange
|
||||
|
|
|
@ -12,7 +12,7 @@ import info.nightscout.interfaces.Config
|
|||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
import info.nightscout.interfaces.queue.Callback
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.interfaces.utils.TimerUtil
|
||||
import info.nightscout.automation.ui.TimerUtil
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import org.json.JSONObject
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.automation.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.provider.AlarmClock
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.automation.R
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
open class TimerUtil @Inject constructor(
|
||||
private val context: Context
|
||||
) {
|
||||
|
||||
/**
|
||||
* Schedule alarm in android
|
||||
*
|
||||
* @param seconds
|
||||
*/
|
||||
fun scheduleReminder(seconds: Int, text: String) {
|
||||
try {
|
||||
Intent(AlarmClock.ACTION_SET_TIMER).apply {
|
||||
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
putExtra(AlarmClock.EXTRA_LENGTH, seconds)
|
||||
putExtra(AlarmClock.EXTRA_SKIP_UI, true)
|
||||
putExtra(AlarmClock.EXTRA_MESSAGE, text)
|
||||
context.startActivity(this)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.errorToast(context, R.string.error_setting_reminder)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,5 +134,6 @@
|
|||
<!-- Reminders-->
|
||||
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
|
||||
<string name="time_to_bolus">Time to bolus!\nRun Bolus wizard and do calculation again.</string>
|
||||
<string name="error_setting_reminder">Error while setting future alarm</string>
|
||||
|
||||
</resources>
|
|
@ -13,7 +13,7 @@ import info.nightscout.interfaces.aps.Loop
|
|||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.utils.TimerUtil
|
||||
import info.nightscout.automation.ui.TimerUtil
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
|
|
@ -13,7 +13,7 @@ import info.nightscout.interfaces.aps.Loop
|
|||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.utils.TimerUtil
|
||||
import info.nightscout.automation.ui.TimerUtil
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
|
|
@ -9,7 +9,7 @@ import info.nightscout.automation.elements.InputString
|
|||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
import info.nightscout.interfaces.queue.Callback
|
||||
import info.nightscout.interfaces.utils.TimerUtil
|
||||
import info.nightscout.automation.ui.TimerUtil
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
|
|
|
@ -75,7 +75,7 @@ class RunningConfigurationImpl @Inject constructor(
|
|||
assert(config.NSCLIENT)
|
||||
|
||||
configuration.version?.let {
|
||||
rxBus.send(EventNSClientNewLog("VERSION", "Received AndroidAPS 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)
|
||||
}
|
||||
|
|
|
@ -2,24 +2,38 @@ package info.nightscout.plugins.constraints.di
|
|||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.plugins.constraints.objectives.ObjectivesFragment
|
||||
import info.nightscout.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
||||
import info.nightscout.plugins.constraints.objectives.dialogs.NtpProgressDialog
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective0
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective1
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective10
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective2
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective3
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective4
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective5
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective6
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective7
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective9
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ObjectivesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): info.nightscout.plugins.constraints.objectives.ObjectivesFragment
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): info.nightscout.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
||||
@ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): info.nightscout.plugins.constraints.objectives.dialogs.NtpProgressDialog
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): ObjectivesExamDialog
|
||||
@ContributesAndroidInjector abstract fun contributesNtpProgressDialog(): NtpProgressDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun objectiveInjector(): info.nightscout.plugins.constraints.objectives.objectives.Objective
|
||||
@ContributesAndroidInjector abstract fun objective0Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective0
|
||||
@ContributesAndroidInjector abstract fun objective1Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective1
|
||||
@ContributesAndroidInjector abstract fun objective2Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective2
|
||||
@ContributesAndroidInjector abstract fun objective3Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective3
|
||||
@ContributesAndroidInjector abstract fun objective4Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective4
|
||||
@ContributesAndroidInjector abstract fun objective5Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective5
|
||||
@ContributesAndroidInjector abstract fun objective6Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective6
|
||||
@ContributesAndroidInjector abstract fun objective7Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective7
|
||||
@ContributesAndroidInjector abstract fun objective9Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective9
|
||||
@ContributesAndroidInjector abstract fun objective10Injector(): info.nightscout.plugins.constraints.objectives.objectives.Objective10
|
||||
@ContributesAndroidInjector abstract fun objectiveInjector(): Objective
|
||||
@ContributesAndroidInjector abstract fun objective0Injector(): Objective0
|
||||
@ContributesAndroidInjector abstract fun objective1Injector(): Objective1
|
||||
@ContributesAndroidInjector abstract fun objective2Injector(): Objective2
|
||||
@ContributesAndroidInjector abstract fun objective3Injector(): Objective3
|
||||
@ContributesAndroidInjector abstract fun objective4Injector(): Objective4
|
||||
@ContributesAndroidInjector abstract fun objective5Injector(): Objective5
|
||||
@ContributesAndroidInjector abstract fun objective6Injector(): Objective6
|
||||
@ContributesAndroidInjector abstract fun objective7Injector(): Objective7
|
||||
@ContributesAndroidInjector abstract fun objective9Injector(): Objective9
|
||||
@ContributesAndroidInjector abstract fun objective10Injector(): Objective10
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.plugins.constraints.objectives
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
|
@ -159,13 +160,13 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
if (objective.objective != 0) {
|
||||
holder.binding.objective.visibility = View.VISIBLE
|
||||
holder.binding.objective.text = rh.gs(objective.objective)
|
||||
} else
|
||||
holder.binding.objective.visibility = View.GONE
|
||||
} else holder.binding.objective.visibility = View.GONE
|
||||
|
||||
if (objective.gate != 0) {
|
||||
holder.binding.gate.visibility = View.VISIBLE
|
||||
holder.binding.gate.text = rh.gs(objective.gate)
|
||||
} else
|
||||
holder.binding.gate.visibility = View.GONE
|
||||
} else holder.binding.gate.visibility = View.GONE
|
||||
|
||||
if (!objective.isStarted) {
|
||||
holder.binding.gate.setTextColor(rh.gac(context, info.nightscout.core.ui.R.attr.defaultTextColor))
|
||||
holder.binding.verify.visibility = View.GONE
|
||||
|
@ -173,6 +174,8 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
holder.binding.accomplished.visibility = View.GONE
|
||||
holder.binding.unfinish.visibility = View.GONE
|
||||
holder.binding.unstart.visibility = View.GONE
|
||||
holder.binding.learnedLabel.visibility = View.GONE
|
||||
holder.binding.learned.removeAllViews()
|
||||
if (position == 0 || objectivesPlugin.allPriorAccomplished(position))
|
||||
holder.binding.start.visibility = View.VISIBLE
|
||||
else
|
||||
|
@ -185,6 +188,14 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
holder.binding.accomplished.visibility = View.VISIBLE
|
||||
holder.binding.unfinish.visibility = View.VISIBLE
|
||||
holder.binding.unstart.visibility = View.GONE
|
||||
holder.binding.learnedLabel.visibility = View.VISIBLE
|
||||
holder.binding.learned.removeAllViews()
|
||||
for (task in objective.tasks) {
|
||||
if (task.shouldBeIgnored()) continue
|
||||
for (learned in task.learned) {
|
||||
holder.binding.learned.addView(TextView(context).also { it.text = rh.gs(learned.learned) })
|
||||
}
|
||||
}
|
||||
} else if (objective.isStarted) {
|
||||
holder.binding.gate.setTextColor(rh.gac(context, info.nightscout.core.ui.R.attr.defaultTextColor))
|
||||
holder.binding.verify.visibility = View.VISIBLE
|
||||
|
@ -195,12 +206,14 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
holder.binding.unstart.visibility = View.VISIBLE
|
||||
holder.binding.progress.visibility = View.VISIBLE
|
||||
holder.binding.progress.removeAllViews()
|
||||
holder.binding.learnedLabel.visibility = View.GONE
|
||||
holder.binding.learned.removeAllViews()
|
||||
for (task in objective.tasks) {
|
||||
if (task.shouldBeIgnored()) continue
|
||||
// name
|
||||
val name = TextView(holder.binding.progress.context)
|
||||
name.text = "${rh.gs(task.task)}:"
|
||||
name.setTextColor(rh.gac(context, info.nightscout.core.ui.R.attr.defaultTextColor) )
|
||||
name.setTextColor(rh.gac(context, info.nightscout.core.ui.R.attr.defaultTextColor))
|
||||
holder.binding.progress.addView(name, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
// hint
|
||||
task.hints.forEach { h ->
|
||||
|
@ -226,6 +239,16 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
dialog.show(childFragmentManager, "ObjectivesFragment")
|
||||
}
|
||||
}
|
||||
if (task.isCompleted()) {
|
||||
if (task.learned.isNotEmpty())
|
||||
holder.binding.progress.addView(
|
||||
TextView(context).also {
|
||||
it.text = rh.gs(R.string.what_i_ve_learned)
|
||||
it.setTypeface(it.typeface, Typeface.BOLD)
|
||||
})
|
||||
for (learned in task.learned)
|
||||
holder.binding.progress.addView(TextView(context).also { it.text = rh.gs(learned.learned) })
|
||||
}
|
||||
// horizontal line
|
||||
val separator = View(holder.binding.progress.context)
|
||||
separator.setBackgroundColor(rh.gac(context, info.nightscout.core.ui.R.attr.separatorColor))
|
||||
|
@ -325,26 +348,6 @@ class ObjectivesFragment : DaggerFragment() {
|
|||
rxBus.send(EventObjectivesUpdateGui())
|
||||
rxBus.send(EventSWUpdate(false))
|
||||
}
|
||||
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
|
||||
// generate random request code if none exists
|
||||
val request = sp.getString(R.string.key_objectives_request_code, String.format("%1$05d", (Math.random() * 99999).toInt()))
|
||||
sp.putString(R.string.key_objectives_request_code, request)
|
||||
holder.binding.requestcode.text = rh.gs(R.string.requestcode, request)
|
||||
holder.binding.requestcode.visibility = View.VISIBLE
|
||||
holder.binding.enterbutton.visibility = View.VISIBLE
|
||||
holder.binding.input.visibility = View.VISIBLE
|
||||
holder.binding.inputhint.visibility = View.VISIBLE
|
||||
holder.binding.enterbutton.setOnClickListener {
|
||||
val input = holder.binding.input.text.toString()
|
||||
activity?.let { activity -> objective.specialAction(activity, input) }
|
||||
rxBus.send(EventObjectivesUpdateGui())
|
||||
}
|
||||
} else {
|
||||
holder.binding.enterbutton.visibility = View.GONE
|
||||
holder.binding.input.visibility = View.GONE
|
||||
holder.binding.inputhint.visibility = View.GONE
|
||||
holder.binding.requestcode.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
|
|
|
@ -37,8 +37,6 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
|
||||
var tasks: MutableList<Task> = ArrayList()
|
||||
|
||||
var hasSpecialInput = false
|
||||
|
||||
val isCompleted: Boolean
|
||||
get() {
|
||||
for (task in tasks) {
|
||||
|
@ -81,6 +79,7 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
abstract inner class Task(var objective: Objective, @StringRes val task: Int) {
|
||||
|
||||
var hints = ArrayList<Hint>()
|
||||
var learned = ArrayList<Learned>()
|
||||
|
||||
abstract fun isCompleted(): Boolean
|
||||
|
||||
|
@ -94,6 +93,11 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
return this
|
||||
}
|
||||
|
||||
fun learned(learned: Learned): Task {
|
||||
this.learned.add(learned)
|
||||
return this
|
||||
}
|
||||
|
||||
open fun shouldBeIgnored(): Boolean = false
|
||||
}
|
||||
|
||||
|
@ -179,4 +183,14 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
return textView
|
||||
}
|
||||
}
|
||||
|
||||
inner class Learned internal constructor(@StringRes var learned: Int) {
|
||||
|
||||
fun generate(context: Context): TextView {
|
||||
val textView = TextView(context)
|
||||
textView.setText(learned)
|
||||
textView.setLinkTextColor(rh.gac(context, com.google.android.material.R.attr.colorSecondary))
|
||||
return textView
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,11 +39,13 @@ class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R
|
|||
return !virtualPumpPlugin.isEnabled()
|
||||
}
|
||||
})
|
||||
tasks.add(object : Task(this, R.string.objectives_pumpstatusavailableinns) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getBoolean(info.nightscout.core.utils.R.string.key_objectives_pump_status_is_available_in_ns, false)
|
||||
}
|
||||
})
|
||||
tasks.add(
|
||||
object : Task(this, R.string.objectives_pumpstatusavailableinns) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getBoolean(info.nightscout.core.utils.R.string.key_objectives_pump_status_is_available_in_ns, false)
|
||||
}
|
||||
}.learned(Learned(R.string.objectives_0_learned))
|
||||
)
|
||||
tasks.add(object : Task(this, R.string.hasbgdata) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return iobCobCalculator.ads.lastBg() != null
|
||||
|
|
|
@ -44,10 +44,13 @@ class Objective1 @Inject constructor(injector: HasAndroidInjector) : Objective(i
|
|||
return sp.getBoolean(info.nightscout.core.utils.R.string.key_objectiveuseloop, false)
|
||||
}
|
||||
}.hint(Hint(R.string.useaction_hint)))
|
||||
tasks.add(object : Task(this, R.string.objectives_usescale) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getBoolean(info.nightscout.core.utils.R.string.key_objectiveusescale, false)
|
||||
}
|
||||
}.hint(Hint(R.string.usescale_hint)))
|
||||
tasks.add(
|
||||
object : Task(this, R.string.objectives_usescale) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getBoolean(info.nightscout.core.utils.R.string.key_objectiveusescale, false)
|
||||
}
|
||||
}.hint(Hint(R.string.usescale_hint))
|
||||
.learned(Learned(R.string.objectives_usage_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@ import info.nightscout.shared.utils.T
|
|||
class Objective10(injector: HasAndroidInjector) : Objective(injector, "auto", R.string.objectives_auto_objective, R.string.objectives_auto_gate) {
|
||||
|
||||
init {
|
||||
tasks.add(MinimumDurationTask(this, T.days(28).msecs()))
|
||||
tasks.add(
|
||||
MinimumDurationTask(this, T.days(28).msecs())
|
||||
.learned(Learned(R.string.objectives_autosens_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,216 +7,271 @@ import info.nightscout.plugins.constraints.R
|
|||
class Objective2(injector: HasAndroidInjector) : Objective(injector, "exam", R.string.objectives_exam_objective, R.string.objectives_exam_gate) {
|
||||
|
||||
init {
|
||||
tasks.add(ExamTask(this, R.string.prerequisites_label, R.string.prerequisites_what, "prerequisites")
|
||||
.option(Option(R.string.prerequisites_nightscout, true))
|
||||
.option(Option(R.string.prerequisites_computer, true))
|
||||
.option(Option(R.string.prerequisites_pump, true))
|
||||
.option(Option(R.string.prerequisites_beanandroiddeveloper, false))
|
||||
.hint(Hint(R.string.prerequisites_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.prerequisites_label, R.string.prerequisites_what, "prerequisites")
|
||||
.option(Option(R.string.prerequisites_nightscout, true))
|
||||
.option(Option(R.string.prerequisites_computer, true))
|
||||
.option(Option(R.string.prerequisites_pump, true))
|
||||
.option(Option(R.string.prerequisites_beanandroiddeveloper, false))
|
||||
.hint(Hint(R.string.prerequisites_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_prerequisites))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.prerequisites2_label, R.string.prerequisites2_what, "prerequisites2")
|
||||
.option(Option(R.string.prerequisites2_profile, true))
|
||||
.option(Option(R.string.prerequisites2_device, true))
|
||||
.option(Option(R.string.prerequisites2_internet, false))
|
||||
.option(Option(R.string.prerequisites2_supportedcgm, true))
|
||||
.hint(Hint(R.string.prerequisites2_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.prerequisites2_label, R.string.prerequisites2_what, "prerequisites2")
|
||||
.option(Option(R.string.prerequisites2_profile, true))
|
||||
.option(Option(R.string.prerequisites2_device, true))
|
||||
.option(Option(R.string.prerequisites2_internet, false))
|
||||
.option(Option(R.string.prerequisites2_supportedcgm, true))
|
||||
.hint(Hint(R.string.prerequisites2_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_prerequisites2))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.basaltest_label, R.string.basaltest_when, "basaltest")
|
||||
.option(Option(R.string.basaltest_fixed, false))
|
||||
.option(Option(R.string.basaltest_havingregularhighlow, true))
|
||||
.option(Option(R.string.basaltest_weekly, false))
|
||||
.option(Option(R.string.basaltest_beforeloop, true))
|
||||
.hint(Hint(R.string.basaltest_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.basaltest_label, R.string.basaltest_when, "basaltest")
|
||||
.option(Option(R.string.basaltest_fixed, false))
|
||||
.option(Option(R.string.basaltest_havingregularhighlow, true))
|
||||
.option(Option(R.string.basaltest_weekly, false))
|
||||
.option(Option(R.string.basaltest_beforeloop, true))
|
||||
.hint(Hint(R.string.basaltest_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_basaltest))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.dia_label_exam, R.string.dia_whatmeansdia, "dia")
|
||||
.option(Option(R.string.dia_profile, true))
|
||||
.option(Option(R.string.dia_minimumis5h, true))
|
||||
.option(Option(R.string.dia_meaningisequaltodiapump, false))
|
||||
.option(Option(R.string.dia_valuemustbedetermined, true))
|
||||
.hint(Hint(R.string.dia_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.dia_label_exam, R.string.dia_whatmeansdia, "dia")
|
||||
.option(Option(R.string.dia_profile, true))
|
||||
.option(Option(R.string.dia_minimumis5h, true))
|
||||
.option(Option(R.string.dia_meaningisequaltodiapump, false))
|
||||
.option(Option(R.string.dia_valuemustbedetermined, true))
|
||||
.hint(Hint(R.string.dia_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_dia))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.isf_label_exam, R.string.blank, "isf")
|
||||
.option(Option(R.string.isf_decreasingvalue, true))
|
||||
.option(Option(R.string.isf_preferences, false))
|
||||
.option(Option(R.string.isf_increasingvalue, false))
|
||||
.option(Option(R.string.isf_noeffect, false))
|
||||
.hint(Hint(R.string.isf_hint1))
|
||||
.hint(Hint(R.string.isf_hint2))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.isf_label_exam, R.string.blank, "isf")
|
||||
.option(Option(R.string.isf_decreasingvalue, true))
|
||||
.option(Option(R.string.isf_preferences, false))
|
||||
.option(Option(R.string.isf_increasingvalue, false))
|
||||
.option(Option(R.string.isf_noeffect, false))
|
||||
.hint(Hint(R.string.isf_hint1))
|
||||
.hint(Hint(R.string.isf_hint2))
|
||||
.learned(Learned(R.string.objectives_exam_learned_isf))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.ic_label_exam, R.string.blank, "ic")
|
||||
.option(Option(R.string.ic_increasingvalue, true))
|
||||
.option(Option(R.string.ic_decreasingvalue, false))
|
||||
.option(Option(R.string.ic_multiple, true))
|
||||
.option(Option(R.string.ic_isf, false))
|
||||
.hint(Hint(R.string.ic_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.ic_label_exam, R.string.blank, "ic")
|
||||
.option(Option(R.string.ic_increasingvalue, true))
|
||||
.option(Option(R.string.ic_decreasingvalue, false))
|
||||
.option(Option(R.string.ic_multiple, true))
|
||||
.option(Option(R.string.ic_isf, false))
|
||||
.hint(Hint(R.string.ic_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_ic))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.hypott_label, R.string.hypott_whenhypott, "hypott")
|
||||
.option(Option(R.string.hypott_preventoversmb, true))
|
||||
.option(Option(R.string.hypott_exercise, false))
|
||||
.option(Option(R.string.hypott_wrongbasal, false))
|
||||
.option(Option(R.string.hypott_0basal, false))
|
||||
.hint(Hint(R.string.hypott_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.hypott_label, R.string.hypott_whenhypott, "hypott")
|
||||
.option(Option(R.string.hypott_preventoversmb, true))
|
||||
.option(Option(R.string.hypott_exercise, false))
|
||||
.option(Option(R.string.hypott_wrongbasal, false))
|
||||
.option(Option(R.string.hypott_0basal, false))
|
||||
.hint(Hint(R.string.hypott_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_hypott))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.profileswitch_label, R.string.profileswitch_pctwillchange, "profileswitch")
|
||||
.option(Option(R.string.profileswitch_basallower, true))
|
||||
.option(Option(R.string.profileswitch_isfhigher, true))
|
||||
.option(Option(R.string.profileswitch_iclower, false))
|
||||
.option(Option(R.string.profileswitch_unchanged, false))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.profileswitch_label, R.string.profileswitch_pctwillchange, "profileswitch")
|
||||
.option(Option(R.string.profileswitch_basallower, true))
|
||||
.option(Option(R.string.profileswitch_isfhigher, true))
|
||||
.option(Option(R.string.profileswitch_iclower, false))
|
||||
.option(Option(R.string.profileswitch_unchanged, false))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_profileswitch))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.profileswitch2_label, R.string.profileswitch2_pctwillchange, "profileswitch2")
|
||||
.option(Option(R.string.profileswitch2_bghigher, false))
|
||||
.option(Option(R.string.profileswitch2_basalhigher, true))
|
||||
.option(Option(R.string.profileswitch2_bgunchanged, true))
|
||||
.option(Option(R.string.profileswitch2_isfhigher, false))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.profileswitch2_label, R.string.profileswitch2_pctwillchange, "profileswitch2")
|
||||
.option(Option(R.string.profileswitch2_bghigher, false))
|
||||
.option(Option(R.string.profileswitch2_basalhigher, true))
|
||||
.option(Option(R.string.profileswitch2_bgunchanged, true))
|
||||
.option(Option(R.string.profileswitch2_isfhigher, false))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.profileswitchtime_label, R.string.profileswitchtime_iwant, "profileswitchtime")
|
||||
.option(Option(R.string.profileswitchtime_2, false))
|
||||
.option(Option(R.string.profileswitchtime__2, true))
|
||||
.option(Option(R.string.profileswitchtime_tt, false))
|
||||
.option(Option(R.string.profileswitchtime_100, false))
|
||||
.hint(Hint(R.string.profileswitchtime_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.profileswitchtime_label, R.string.profileswitchtime_iwant, "profileswitchtime")
|
||||
.option(Option(R.string.profileswitchtime_2, false))
|
||||
.option(Option(R.string.profileswitchtime__2, true))
|
||||
.option(Option(R.string.profileswitchtime_tt, false))
|
||||
.option(Option(R.string.profileswitchtime_100, false))
|
||||
.hint(Hint(R.string.profileswitchtime_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_profileswitchtime))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.profileswitch4_label, R.string.blank, "profileswitch4")
|
||||
.option(Option(R.string.profileswitch4_rates, true))
|
||||
.option(Option(R.string.profileswitch4_internet, true))
|
||||
.option(Option(R.string.profileswitch4_sufficient, false))
|
||||
.option(Option(R.string.profileswitch4_multi, true))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.profileswitch4_label, R.string.blank, "profileswitch4")
|
||||
.option(Option(R.string.profileswitch4_rates, true))
|
||||
.option(Option(R.string.profileswitch4_internet, true))
|
||||
.option(Option(R.string.profileswitch4_sufficient, false))
|
||||
.option(Option(R.string.profileswitch4_multi, true))
|
||||
.hint(Hint(R.string.profileswitch_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_profileswitch4))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.exerciseprofile_label, R.string.exerciseprofile_whattodo, "exercise")
|
||||
.option(Option(R.string.exerciseprofile_switchprofileabove100, false))
|
||||
.option(Option(R.string.exerciseprofile_switchprofilebelow100, true))
|
||||
.option(Option(R.string.exerciseprofile_suspendloop, false))
|
||||
.option(Option(R.string.exerciseprofile_leaveat100, false))
|
||||
.hint(Hint(R.string.exerciseprofile_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.exerciseprofile_label, R.string.exerciseprofile_whattodo, "exercise")
|
||||
.option(Option(R.string.exerciseprofile_switchprofileabove100, false))
|
||||
.option(Option(R.string.exerciseprofile_switchprofilebelow100, true))
|
||||
.option(Option(R.string.exerciseprofile_suspendloop, false))
|
||||
.option(Option(R.string.exerciseprofile_leaveat100, false))
|
||||
.hint(Hint(R.string.exerciseprofile_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_exercise))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.exercise_label, R.string.exercise_whattodo, "exercise2")
|
||||
.option(Option(R.string.exercise_settt, true))
|
||||
.option(Option(R.string.exercise_setfinished, false))
|
||||
.option(Option(R.string.exercise_setunchanged, false))
|
||||
.option(Option(R.string.exercise_15g, false))
|
||||
.hint(Hint(R.string.exercise_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.exercise_label, R.string.exercise_whattodo, "exercise2")
|
||||
.option(Option(R.string.exercise_settt, true))
|
||||
.option(Option(R.string.exercise_setfinished, false))
|
||||
.option(Option(R.string.exercise_setunchanged, false))
|
||||
.option(Option(R.string.exercise_15g, false))
|
||||
.hint(Hint(R.string.exercise_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_exercise2))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.noisycgm_label, R.string.noisycgm_whattodo, "noisycgm")
|
||||
.option(Option(R.string.noisycgm_nothing, false))
|
||||
.option(Option(R.string.noisycgm_pause, true))
|
||||
.option(Option(R.string.noisycgm_replacesensor, true))
|
||||
.option(Option(R.string.noisycgm_checksmoothing, true))
|
||||
.hint(Hint(R.string.noisycgm_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.noisycgm_label, R.string.noisycgm_whattodo, "noisycgm")
|
||||
.option(Option(R.string.noisycgm_nothing, false))
|
||||
.option(Option(R.string.noisycgm_pause, true))
|
||||
.option(Option(R.string.noisycgm_replacesensor, true))
|
||||
.option(Option(R.string.noisycgm_checksmoothing, true))
|
||||
.hint(Hint(R.string.noisycgm_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_noisycgm))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.pumpdisconnect_label, R.string.blank, "pumpdisconnect")
|
||||
.option(Option(R.string.pumpdisconnect_unnecessary, false))
|
||||
.option(Option(R.string.pumpdisconnect_missinginsulin, true))
|
||||
.option(Option(R.string.pumpdisconnect_notstop, false))
|
||||
.option(Option(R.string.pumpdisconnect_openloop, false))
|
||||
.hint(Hint(R.string.pumpdisconnect_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.pumpdisconnect_label, R.string.blank, "pumpdisconnect")
|
||||
.option(Option(R.string.pumpdisconnect_unnecessary, false))
|
||||
.option(Option(R.string.pumpdisconnect_missinginsulin, true))
|
||||
.option(Option(R.string.pumpdisconnect_notstop, false))
|
||||
.option(Option(R.string.pumpdisconnect_openloop, false))
|
||||
.hint(Hint(R.string.pumpdisconnect_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_pumpdisconnect))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.insulin_plugins, R.string.insulin_ultrarapid, "insulin")
|
||||
.option(Option(R.string.insulin_novorapid, false))
|
||||
.option(Option(R.string.insulin_humalog, false))
|
||||
.option(Option(R.string.insulin_actrapid, false))
|
||||
.option(Option(R.string.insulin_fiasp, true))
|
||||
.hint(Hint(R.string.insulin_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.insulin_plugins, R.string.insulin_ultrarapid, "insulin")
|
||||
.option(Option(R.string.insulin_novorapid, false))
|
||||
.option(Option(R.string.insulin_humalog, false))
|
||||
.option(Option(R.string.insulin_actrapid, false))
|
||||
.option(Option(R.string.insulin_fiasp, true))
|
||||
.hint(Hint(R.string.insulin_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_insulin))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.sensitivity_label, R.string.blank, "sensitivity")
|
||||
.option(Option(R.string.sensitivity_adjust, true))
|
||||
.option(Option(R.string.sensitivity_edit, false))
|
||||
.option(Option(R.string.sensitivity_cannula, true))
|
||||
.option(Option(R.string.sensitivity_time, true))
|
||||
.hint(Hint(R.string.sensitivity_hint1))
|
||||
.hint(Hint(R.string.sensitivity_hint2))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.sensitivity_label, R.string.blank, "sensitivity")
|
||||
.option(Option(R.string.sensitivity_adjust, true))
|
||||
.option(Option(R.string.sensitivity_edit, false))
|
||||
.option(Option(R.string.sensitivity_cannula, true))
|
||||
.option(Option(R.string.sensitivity_time, true))
|
||||
.hint(Hint(R.string.sensitivity_hint1))
|
||||
.hint(Hint(R.string.sensitivity_hint2))
|
||||
.learned(Learned(R.string.objectives_exam_learned_sensitivity))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.objectives_label, R.string.objectives_howtosave, "objectives")
|
||||
.option(Option(R.string.objectives_notesettings, false))
|
||||
.option(Option(R.string.objectives_afterobjective, true))
|
||||
.option(Option(R.string.objectives_afterchange, true))
|
||||
.option(Option(R.string.objectives_afterinitialsetup, true))
|
||||
.hint(Hint(R.string.objectives_hint1))
|
||||
.hint(Hint(R.string.objectives_hint2))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.objectives_label, R.string.objectives_howtosave, "objectives")
|
||||
.option(Option(R.string.objectives_notesettings, false))
|
||||
.option(Option(R.string.objectives_afterobjective, true))
|
||||
.option(Option(R.string.objectives_afterchange, true))
|
||||
.option(Option(R.string.objectives_afterinitialsetup, true))
|
||||
.hint(Hint(R.string.objectives_hint1))
|
||||
.hint(Hint(R.string.objectives_hint2))
|
||||
.learned(Learned(R.string.objectives_exam_learned_objectives))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.objectives2_label, R.string.objectives_howtosave, "objectives2")
|
||||
.option(Option(R.string.objectives2_maintenance, true))
|
||||
.option(Option(R.string.objectives2_internalstorage, true))
|
||||
.option(Option(R.string.objectives2_cloud, true))
|
||||
.option(Option(R.string.objectives2_easyrestore, false))
|
||||
.hint(Hint(R.string.objectives_hint1))
|
||||
.hint(Hint(R.string.objectives_hint2))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.objectives2_label, R.string.objectives_howtosave, "objectives2")
|
||||
.option(Option(R.string.objectives2_maintenance, true))
|
||||
.option(Option(R.string.objectives2_internalstorage, true))
|
||||
.option(Option(R.string.objectives2_cloud, true))
|
||||
.option(Option(R.string.objectives2_easyrestore, false))
|
||||
.hint(Hint(R.string.objectives_hint1))
|
||||
.hint(Hint(R.string.objectives_hint2))
|
||||
.learned(Learned(R.string.objectives_exam_learned_objectives2))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.update_label, R.string.blank, "update")
|
||||
.option(Option(R.string.update_git, true))
|
||||
.option(Option(R.string.update_askfriend, false))
|
||||
.option(Option(R.string.update_keys, true))
|
||||
.option(Option(R.string.update_asap, true))
|
||||
.hint(Hint(R.string.update_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.update_label, R.string.blank, "update")
|
||||
.option(Option(R.string.update_git, true))
|
||||
.option(Option(R.string.update_askfriend, false))
|
||||
.option(Option(R.string.update_keys, true))
|
||||
.option(Option(R.string.update_asap, true))
|
||||
.hint(Hint(R.string.update_hint1))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.troubleshooting_label, R.string.troubleshooting_wheretoask, "troubleshooting")
|
||||
.option(Option(R.string.troubleshooting_fb, true))
|
||||
.option(Option(R.string.troubleshooting_wiki, true))
|
||||
.option(Option(R.string.troubleshooting_gitter, true))
|
||||
.option(Option(R.string.troubleshooting_yourendo, false))
|
||||
.hint(Hint(R.string.troubleshooting_hint1))
|
||||
.hint(Hint(R.string.troubleshooting_hint2))
|
||||
.hint(Hint(R.string.troubleshooting_hint3))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.troubleshooting_label, R.string.troubleshooting_wheretoask, "troubleshooting")
|
||||
.option(Option(R.string.troubleshooting_fb, true))
|
||||
.option(Option(R.string.troubleshooting_wiki, true))
|
||||
.option(Option(R.string.troubleshooting_gitter, true))
|
||||
.option(Option(R.string.troubleshooting_yourendo, false))
|
||||
.hint(Hint(R.string.troubleshooting_hint1))
|
||||
.hint(Hint(R.string.troubleshooting_hint2))
|
||||
.hint(Hint(R.string.troubleshooting_hint3))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.wrongcarbs_label, R.string.wrongcarbs_whattodo, "wrongcarbs")
|
||||
.option(Option(R.string.wrongcarbs_addinsulin, false))
|
||||
.option(Option(R.string.wrongcarbs_treatmentstab, true))
|
||||
.option(Option(R.string.wrongcarbs_donothing, false))
|
||||
.option(Option(R.string.wrongcarbs_bolus, false))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.wrongcarbs_label, R.string.wrongcarbs_whattodo, "wrongcarbs")
|
||||
.option(Option(R.string.wrongcarbs_addinsulin, false))
|
||||
.option(Option(R.string.wrongcarbs_treatmentstab, true))
|
||||
.option(Option(R.string.wrongcarbs_donothing, false))
|
||||
.option(Option(R.string.wrongcarbs_bolus, false))
|
||||
.learned(Learned(R.string.objectives_exam_learned_wrongcarbs))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.wronginsulin_label, R.string.wronginsulin_whattodo, "wronginsulin")
|
||||
.option(Option(R.string.wronginsulin_careportal, false))
|
||||
.option(Option(R.string.wronginsulin_compare, true))
|
||||
.option(Option(R.string.wronginsulin_prime, true))
|
||||
.option(Option(R.string.wrongcarbs_donothing, false))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.wronginsulin_label, R.string.wronginsulin_whattodo, "wronginsulin")
|
||||
.option(Option(R.string.wronginsulin_careportal, false))
|
||||
.option(Option(R.string.wronginsulin_compare, true))
|
||||
.option(Option(R.string.wronginsulin_prime, true))
|
||||
.option(Option(R.string.wrongcarbs_donothing, false))
|
||||
)
|
||||
tasks.add(ExamTask(this, info.nightscout.core.ui.R.string.iob_label, R.string.blank, "iob")
|
||||
.option(Option(R.string.iob_value, true))
|
||||
.option(Option(R.string.iob_hightemp, false))
|
||||
.option(Option(R.string.iob_negiob, true))
|
||||
.option(Option(R.string.iob_posiob, true))
|
||||
tasks.add(
|
||||
ExamTask(this, info.nightscout.core.ui.R.string.iob_label, R.string.blank, "iob")
|
||||
.option(Option(R.string.iob_value, true))
|
||||
.option(Option(R.string.iob_hightemp, false))
|
||||
.option(Option(R.string.iob_negiob, true))
|
||||
.option(Option(R.string.iob_posiob, true))
|
||||
.learned(Learned(R.string.objectives_exam_learned_iob))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.cob_label, R.string.cob_question, "cob1")
|
||||
.option(Option(R.string.cob_longer, true))
|
||||
.option(Option(R.string.cob_shorter, false))
|
||||
.option(Option(R.string.cob_no_effect, false))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.cob_label, R.string.cob_question, "cob1")
|
||||
.option(Option(R.string.cob_longer, true))
|
||||
.option(Option(R.string.cob_shorter, false))
|
||||
.option(Option(R.string.cob_no_effect, false))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.cob_label, R.string.cob2_question, "cob2")
|
||||
.option(Option(R.string.cob2_longer, false))
|
||||
.option(Option(R.string.cob2_shorter, true))
|
||||
.option(Option(R.string.cob2_no_effect, false))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.cob_label, R.string.cob2_question, "cob2")
|
||||
.option(Option(R.string.cob2_longer, false))
|
||||
.option(Option(R.string.cob2_shorter, true))
|
||||
.option(Option(R.string.cob2_no_effect, false))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.cob_label, R.string.cob3_question, "cob3")
|
||||
.option(Option(R.string.cob3_longer, false))
|
||||
.option(Option(R.string.cob3_shorter, false))
|
||||
.option(Option(R.string.cob3_no_effect, true))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.cob_label, R.string.cob3_question, "cob3")
|
||||
.option(Option(R.string.cob3_longer, false))
|
||||
.option(Option(R.string.cob3_shorter, false))
|
||||
.option(Option(R.string.cob3_no_effect, true))
|
||||
.learned(Learned(R.string.objectives_exam_learned_cob))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.breadgrams_label, R.string.blank, "breadgrams")
|
||||
.option(Option(R.string.breadgrams_grams, true))
|
||||
.option(Option(R.string.breadgrams_exchange, false))
|
||||
.option(Option(R.string.breadgrams_decay, true))
|
||||
.option(Option(R.string.breadgrams_calc, true))
|
||||
.hint(Hint(R.string.breadgrams_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.breadgrams_label, R.string.blank, "breadgrams")
|
||||
.option(Option(R.string.breadgrams_grams, true))
|
||||
.option(Option(R.string.breadgrams_exchange, false))
|
||||
.option(Option(R.string.breadgrams_decay, true))
|
||||
.option(Option(R.string.breadgrams_calc, true))
|
||||
.hint(Hint(R.string.breadgrams_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_breadgrams))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.extendedcarbs_label, R.string.extendedcarbs_handling, "extendedcarbs")
|
||||
.option(Option(R.string.extendedcarbs_future, true))
|
||||
.option(Option(R.string.extendedcarbs_free, false))
|
||||
.option(Option(R.string.extendedcarbs_fat, true))
|
||||
.option(Option(R.string.extendedcarbs_rescue, false))
|
||||
.hint(Hint(R.string.extendedcarbs_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.extendedcarbs_label, R.string.extendedcarbs_handling, "extendedcarbs")
|
||||
.option(Option(R.string.extendedcarbs_future, true))
|
||||
.option(Option(R.string.extendedcarbs_free, false))
|
||||
.option(Option(R.string.extendedcarbs_fat, true))
|
||||
.option(Option(R.string.extendedcarbs_rescue, false))
|
||||
.hint(Hint(R.string.extendedcarbs_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_ecarbs))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.nsclient_label, R.string.nsclient_howcanyou, "nsclient")
|
||||
.option(Option(R.string.nsclient_nightscout, true))
|
||||
.option(Option(R.string.nsclient_dexcomfollow, true))
|
||||
.option(Option(R.string.nsclient_data, true))
|
||||
.option(Option(R.string.nsclient_fullcontrol, false))
|
||||
.hint(Hint(R.string.nsclient_hint1))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.nsclient_label, R.string.nsclient_howcanyou, "nsclient")
|
||||
.option(Option(R.string.nsclient_nightscout, true))
|
||||
.option(Option(R.string.nsclient_dexcomfollow, true))
|
||||
.option(Option(R.string.nsclient_data, true))
|
||||
.option(Option(R.string.nsclient_fullcontrol, false))
|
||||
.hint(Hint(R.string.nsclient_hint1))
|
||||
.learned(Learned(R.string.objectives_exam_learned_nsclient))
|
||||
)
|
||||
tasks.add(ExamTask(this, R.string.other_medication_label, R.string.other_medication_text, "otherMedicationWarning")
|
||||
.option(Option(info.nightscout.core.ui.R.string.yes, true))
|
||||
.option(Option(info.nightscout.core.ui.R.string.no, false))
|
||||
tasks.add(
|
||||
ExamTask(this, R.string.other_medication_label, R.string.other_medication_text, "otherMedicationWarning")
|
||||
.option(Option(info.nightscout.core.ui.R.string.yes, true))
|
||||
.option(Option(info.nightscout.core.ui.R.string.no, false))
|
||||
)
|
||||
for (task in tasks) (task as ExamTask).options.shuffle()
|
||||
|
||||
|
|
|
@ -13,15 +13,19 @@ class Objective3 @Inject constructor(injector: HasAndroidInjector) : Objective(i
|
|||
|
||||
init {
|
||||
tasks.add(MinimumDurationTask(this, T.days(7).msecs()))
|
||||
tasks.add(object : Task(this, R.string.objectives_manualenacts) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0) >= MANUAL_ENACTS_NEEDED
|
||||
}
|
||||
tasks.add(
|
||||
object : Task(this, R.string.objectives_manualenacts) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0) >= MANUAL_ENACTS_NEEDED
|
||||
}
|
||||
|
||||
override val progress: String
|
||||
get() = if (sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0) >= MANUAL_ENACTS_NEEDED) rh.gs(R.string.completed_well_done) else sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0)
|
||||
.toString() + " / " + MANUAL_ENACTS_NEEDED
|
||||
})
|
||||
override val progress: String
|
||||
get() =
|
||||
if (sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0) >= MANUAL_ENACTS_NEEDED)
|
||||
rh.gs(R.string.completed_well_done)
|
||||
else sp.getInt(info.nightscout.core.utils.R.string.key_ObjectivesmanualEnacts, 0).toString() + " / " + MANUAL_ENACTS_NEEDED
|
||||
}.learned(Learned(R.string.objectives_openloop_learned))
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -1,7 +1,29 @@
|
|||
package info.nightscout.plugins.constraints.objectives.objectives
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.plugins.constraints.R
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
class Objective4(injector: HasAndroidInjector) : Objective(injector, "maxbasal", R.string.objectives_maxbasal_objective, R.string.objectives_maxbasal_gate)
|
||||
class Objective4(injector: HasAndroidInjector) : Objective(injector, "maxbasal", R.string.objectives_maxbasal_objective, R.string.objectives_maxbasal_gate) {
|
||||
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
init {
|
||||
tasks.add(
|
||||
object : Task(this, R.string.objectives_maxbasal_gate) {
|
||||
override fun isCompleted(): Boolean {
|
||||
val profile = profileFunction.getProfile() ?: return false
|
||||
val maxBasalSet = (activePlugin.activeAPS as Constraints).applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile)
|
||||
val maxDailyBasal = profile.getMaxDailyBasal()
|
||||
return maxBasalSet.value() > 2.8 * maxDailyBasal
|
||||
}
|
||||
}.learned(Learned(R.string.objectives_maxbasal_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -14,12 +14,14 @@ class Objective5(injector: HasAndroidInjector) : Objective(injector, "maxiobzero
|
|||
|
||||
init {
|
||||
tasks.add(MinimumDurationTask(this, T.days(5).msecs()))
|
||||
tasks.add(object : Task(this, R.string.closedmodeenabled) {
|
||||
override fun isCompleted(): Boolean {
|
||||
val closedLoopEnabled = Constraint(true)
|
||||
safetyPlugin.isClosedLoopAllowed(closedLoopEnabled)
|
||||
return closedLoopEnabled.value()
|
||||
}
|
||||
})
|
||||
tasks.add(
|
||||
object : Task(this, R.string.closedmodeenabled) {
|
||||
override fun isCompleted(): Boolean {
|
||||
val closedLoopEnabled = Constraint(true)
|
||||
safetyPlugin.isClosedLoopAllowed(closedLoopEnabled)
|
||||
return closedLoopEnabled.value()
|
||||
}
|
||||
}.learned(Learned(R.string.objectives_maxiobzero_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.plugins.constraints.objectives.objectives
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.plugins.constraints.R
|
||||
import info.nightscout.shared.utils.T
|
||||
|
@ -15,7 +16,7 @@ class Objective6(injector: HasAndroidInjector) : Objective(injector, "maxiob", R
|
|||
tasks.add(MinimumDurationTask(this, T.days(1).msecs()))
|
||||
tasks.add(
|
||||
object : Task(this, R.string.closedmodeenabled) {
|
||||
override fun isCompleted(): Boolean = sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open") == "closed"
|
||||
override fun isCompleted(): Boolean = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)) == ApsMode.CLOSED
|
||||
})
|
||||
tasks.add(
|
||||
object : Task(this, R.string.maxiobset) {
|
||||
|
@ -24,6 +25,7 @@ class Objective6(injector: HasAndroidInjector) : Objective(injector, "maxiob", R
|
|||
val maxIOB = constraintChecker.getMaxIOBAllowed().value()
|
||||
return maxIOB > 0
|
||||
}
|
||||
})
|
||||
}.learned(Learned(R.string.objectives_maxiob_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@ import info.nightscout.shared.utils.T
|
|||
class Objective7(injector: HasAndroidInjector) : Objective(injector, "autosens", R.string.objectives_autosens_objective, R.string.objectives_autosens_gate) {
|
||||
|
||||
init {
|
||||
tasks.add(MinimumDurationTask(this, T.days(7).msecs()))
|
||||
tasks.add(
|
||||
MinimumDurationTask(this, T.days(7).msecs())
|
||||
.learned(Learned(R.string.objectives_autosens_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,6 +7,9 @@ import info.nightscout.shared.utils.T
|
|||
class Objective9(injector: HasAndroidInjector) : Objective(injector, "smb", R.string.objectives_smb_objective, R.string.objectives_smb_gate) {
|
||||
|
||||
init {
|
||||
tasks.add(MinimumDurationTask(this, T.days(28).msecs()))
|
||||
tasks.add(
|
||||
MinimumDurationTask(this, T.days(28).msecs())
|
||||
.learned(Learned(R.string.objectives_smb_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import info.nightscout.core.utils.extensions.storeDouble
|
|||
import info.nightscout.core.utils.extensions.storeInt
|
||||
import info.nightscout.core.utils.extensions.storeString
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.constraints.Safety
|
||||
|
@ -67,8 +68,8 @@ class SafetyPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val mode = sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")
|
||||
if (mode == "open") value.set(aapsLogger, false, rh.gs(R.string.closedmodedisabledinpreferences), this)
|
||||
val mode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||
if (mode == ApsMode.OPEN) value.set(aapsLogger, false, rh.gs(R.string.closedmodedisabledinpreferences), this)
|
||||
if (!config.isEngineeringModeOrRelease()) {
|
||||
if (value.value()) {
|
||||
uiInteraction.addNotification(Notification.TOAST_ALARM, rh.gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL)
|
||||
|
@ -159,8 +160,8 @@ class SafetyPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||
val apsMode = sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")
|
||||
if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.limiting_iob, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)), this)
|
||||
val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||
if (apsMode == ApsMode.LGS) maxIob.setIfSmaller(aapsLogger, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.limiting_iob, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)), this)
|
||||
return maxIob
|
||||
}
|
||||
|
||||
|
|
|
@ -85,42 +85,6 @@
|
|||
android:layout_gravity="end"
|
||||
android:text="@string/objectives_button_unstart" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inputhint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/requestcode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Request code: XXXXX" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/input"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ems="10"
|
||||
android:inputType="text"
|
||||
tools:hint="XXXXXXXXXX"
|
||||
android:importantForAutofill="no" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/enterbutton"
|
||||
style="@style/OkCancelButton.Text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/objectives_button_enter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accomplished"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -128,6 +92,23 @@
|
|||
android:layout_marginTop="8dp"
|
||||
tools:text="Accomplished" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/learned_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="@string/what_i_ve_learned"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/learned"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
@ -4,61 +4,138 @@
|
|||
<string name="dia_label_exam">Duración de la acción de insulina (DAI)</string>
|
||||
<string name="dia_profile">Debes establecer el valor de DAI en tu perfil.</string>
|
||||
<string name="dia_minimumis5h">El valor mínimo permitido es de 5 horas.</string>
|
||||
<string name="dia_hint1">https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html?#insulin</string>
|
||||
<string name="dia_meaningisequaltodiapump">Si estás satisfecho con el valor de DAI que utilizas en tu bomba antes de utilizar AAPS y te funcionó bien, no hay necesidad de cambiarlo cuando empieces a usar el bucle cerrado.</string>
|
||||
<string name="dia_valuemustbedetermined">Deberás determinar por ti mismo el valor apropiado para DAI.</string>
|
||||
<string name="hypott_label">Objetivo temporal ante Hipoglucemia</string>
|
||||
<string name="hypott_whenhypott">¿Cuál es la razón principal para establecer un objetivo temporal por hipoglucemia?</string>
|
||||
<string name="hypott_wrongbasal">Para corregir hipoglucemias causadas por ajustes incorrectos de la tasa basal.</string>
|
||||
<string name="hypott_preventoversmb">Para evitar que AAPS corrija de forma excesiva ante un rápido aumento de la glucosa por consumir carbohidratos simples para recuperarse de una hipoglucemia.</string>
|
||||
<string name="hypott_exercise">Para corregir una hipoglucemia que sucedió como resultando del ejercicio.</string>
|
||||
<string name="hypott_0basal">Para evitar que la glucosa sanguínea continue bajando si ya hay una tasa basal temporal igual a 0% actividad.</string>
|
||||
<string name="hypott_hint1">https://androidaps.readthedocs.io/es/latest/Usage/temptarget.html</string>
|
||||
<string name="offlineprofile_whatprofile">¿Qué perfil puede ser usado y configurado estando sin conexión de Internet?</string>
|
||||
<string name="offlineprofile_label">Tema: Perfil Local</string>
|
||||
<string name="offlineprofile_nsprofile">El perfil que proviene de Nightscout (NS) puede ser utilizado, pero no configurado.</string>
|
||||
<string name="offlineprofile_hint1">https://androidaps.readthedocs.io/es/latest/Configuration/Config-Builder.html#profile</string>
|
||||
<string name="pumpdisconnect_label">Razones para seleccionar \"Desconectar bomba\" en AAPS</string>
|
||||
<string name="pumpdisconnect_whattodo">¿Qué se debe hacer al desconectar la bomba de insulina?</string>
|
||||
<string name="pumpdisconnect_unnecessary">Esto es innecesario, ya que no se entregará insulina si la bomba está físicamente desconectada.</string>
|
||||
<string name="pumpdisconnect_missinginsulin">Evita que AAPS considere la insulina que no se suministró cuando la bomba estaba físicamente desconectada</string>
|
||||
<string name="pumpdisconnect_notstop">Si la bomba permanece conectada, no se detendrá el suministro de insulina.</string>
|
||||
<string name="pumpdisconnect_openloop">Se activará el modo de bucle abierto en AAPS.</string>
|
||||
<string name="pumpdisconnect_hint1">https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/FAQ.html#other-settings</string>
|
||||
<string name="objectives_label">Ajustes de AAPS</string>
|
||||
<string name="objectives2_label">Ajustes de AAPS</string>
|
||||
<string name="objectives_howtosave">¿Cuáles son las mejores prácticas para hacer copias de seguridad de sus configuraciones?</string>
|
||||
<string name="objectives_notesettings">No necesita exportar sus configuraciones siempre que haga las tenga anotadas.</string>
|
||||
<string name="objectives_afterobjective">Exportar tu configuración después de completar un objetivo.</string>
|
||||
<string name="objectives_afterchange">Exportar las configuraciones después de cambiar cualquiera de sus ajustes.</string>
|
||||
<string name="objectives_afterinitialsetup">Exportar las configuraciones una vez finalizada la configuración inicial y haber establecido sus preferencias.</string>
|
||||
<string name="objectives2_maintenance">Exportar la configuración localmente usando el menú de mantenimiento.</string>
|
||||
<string name="objectives2_internalstorage">El archivo de configuración se encuentra en la carpeta Almacenamiento/AAPS/preferencias en el teléfono.</string>
|
||||
<string name="objectives2_cloud">Copie el archivo de preferencias a una ubicación segura fuera de su teléfono (p.e. mediante el uso del almacenamiento en la nube, conectando su teléfono con un cable a una computadora, correo electrónico, etc.)</string>
|
||||
<string name="objectives2_easyrestore">Si su teléfono es dañado o perdido, hay formas fáciles de recuperar remotamente su configuración sin hacer una copia de seguridad.</string>
|
||||
<string name="objectives_hint1">https://androidaps.readthedocs.io/es/latest/Usage/ExportImportSettings.html</string>
|
||||
<string name="objectives_hint2">https://androidaps.readthedocs.io/es/latest/Getting-Started/FAQ.html#what-emergency-equipment-is-recommended-to-take-with-me</string>
|
||||
<string name="noisycgm_label">Lecturas CGM con mucha variabilidad</string>
|
||||
<string name="noisycgm_whattodo">¿Qué se debe hacer si los datos de CGM tienen mucha variabilidad?</string>
|
||||
<string name="noisycgm_nothing">No hacer nada: AAPS se ocupará de ello.</string>
|
||||
<string name="noisycgm_pause">Deshabilitar el bucle cerrado para evitar posibles sobredosis o subdosis.</string>
|
||||
<string name="noisycgm_replacesensor">Sustituya el sensor con valores muy variables o inexactos.</string>
|
||||
<string name="noisycgm_checksmoothing">Comprueba que tu aplicación del CGM proporciona datos suavizados.</string>
|
||||
<string name="noisycgm_hint1">https://androidaps.readthedocs.io/es/latest/Usage/Smoothing-Blood-Glucose-Data-in-xDrip.html#smoothing-blood-glucose-data</string>
|
||||
<string name="exerciseprofile_label">Ejercicio y perfiles</string>
|
||||
<string name="exerciseprofile_whattodo">¿Cómo puede usar los perfiles para mejorar el sistema durante el ejercicio aeróbico?</string>
|
||||
<string name="exerciseprofile_switchprofilebelow100">Cambie el perfil por un valor menor a 100%.</string>
|
||||
<string name="exerciseprofile_switchprofileabove100">Cambie el perfil por un valor mayor a 100%.</string>
|
||||
<string name="exerciseprofile_leaveat100">Dejar el perfil configurado al 100%.</string>
|
||||
<string name="exerciseprofile_suspendloop">Suspender el bucle.</string>
|
||||
<string name="exerciseprofile_hint1">https://androidaps.readthedocs.io/es/latest/Usage/temptarget.html#activity-temp-target</string>
|
||||
<string name="exercise_label">Ejercicios y objetivos temporales</string>
|
||||
<string name="exercise_whattodo">¿Cómo se puede usar el objetivo temporal de glucosa para ayudar al sistema durante los ejercicios aeróbicos?</string>
|
||||
<string name="exercise_settt">Establezca el objetivo de tipo actividad antes de comenzar el ejercicio, considerando un tiempo razonable antes de la actividad.</string>
|
||||
<string name="exercise_setfinished">Establezca un objetivo de tipo actividad después de finalizar el ejercicio.</string>
|
||||
<string name="exercise_setunchanged">Deja tu objetivo de glucosa sin cambios.</string>
|
||||
<string name="exercise_15g">Espere hasta que los valores de glucosa se encuentren por debajo del valor definido en el objetivo de tipo hipoglicemia. Luego consuma 15 g de carbohidratos de rápida absorción.</string>
|
||||
<string name="exercise_hint1">https://androidaps.readthedocs.io/es/latest/Usage/temptarget.html#activity-temp-target</string>
|
||||
<string name="suspendloop_doigetinsulin">¿Puedo recibir insulina cuando el bucle está desactivado/suspendido?</string>
|
||||
<string name="suspendloop_yes">Sí, la insulina basal sigue siendo suministrada.</string>
|
||||
<string name="suspendloop_no">No, la administración de la insulina se detiene.</string>
|
||||
<string name="basaltest_label">Pruebas para basales, I:C y FSI</string>
|
||||
<string name="basaltest_when">¿Cada cuándo se deben validar estos valores?</string>
|
||||
<string name="basaltest_beforeloop">Antes de empezar cualquier bucle.</string>
|
||||
<string name="basaltest_havingregularhighlow">Cuando los valores de glucosa son muy altos o bajos de manera frecuente.</string>
|
||||
<string name="basaltest_weekly">Al menos una vez a la semana.</string>
|
||||
<string name="basaltest_fixed">Una vez establecidos y validados, estos valores no deberían cambiar a lo largo del tiempo.</string>
|
||||
<string name="basaltest_hint1">https://androidaps.readthedocs.io/es/latest/Getting-Started/FAQ.html#androidaps-settings</string>
|
||||
<string name="prerequisites_label">Requisitos previos</string>
|
||||
<string name="prerequisites_what">¿Qué es esencial para configurar y utilizar AAPS?</string>
|
||||
<string name="prerequisites_determinedcorrectprofile">Información de perfil previamente validada (Basal, IC, FSI, DAI).</string>
|
||||
<string name="prerequisites_computer">Una computadora con Android Studio instalado y configurado.</string>
|
||||
<string name="prerequisites_phone">Un teléfono compatible.</string>
|
||||
<string name="prerequisites_pump">Una bomba de insulina compatible, si planeas usar el sistema en modo bucle cerrado.</string>
|
||||
<string name="prerequisites_nightscout">Nightscout, para tener un registro de los datos y revisar los parámetros de configuración.</string>
|
||||
<string name="prerequisites_tidepoolaccount">Una cuenta de Tidepool.</string>
|
||||
<string name="prerequisites_googleaccount">Una cuenta de Google.</string>
|
||||
<string name="prerequisites_githubaccount">Una cuenta de Github.</string>
|
||||
<string name="prerequisites_beanandroiddeveloper">Experiencia programando o editando código.</string>
|
||||
<string name="prerequisites_own670g">Una bomba MiniMed 670G.</string>
|
||||
<string name="prerequisites_hint1">https://androidaps.readthedocs.io/es/latest/Module/module.html</string>
|
||||
<string name="prerequisites_smartwatch">Un Smartwatch.</string>
|
||||
<string name="prerequisites_supportedcgm">Un MCG soportado.</string>
|
||||
<string name="prerequisites2_label">Requisitos previos</string>
|
||||
<string name="prerequisites2_what">¿Qué es esencial para configurar y utilizar AAPS?</string>
|
||||
<string name="prerequisites2_profile">Parámetros validados para poder configurar un perfil (FSI, I:C, perfil basal, DAI etc.).</string>
|
||||
<string name="prerequisites2_device">Un dispositivo Android compatible (e.j. un móvil, un smartwatch Android compatible o una tablet).</string>
|
||||
<string name="prerequisites2_internet">AAPS requiere una conexión a Internet para funcionar con el modo bucle cerrado.</string>
|
||||
<string name="prerequisites2_supportedcgm">Un medidor continuo de glucosa (MCG) y una aplicación capaz de recibir los valores proporcionados por el medidor en el móvil o tablet.</string>
|
||||
<string name="prerequisites2_hint1">https://androidaps.readthedocs.io/en/latest/EN/Module/module.html</string>
|
||||
<string name="update_label">Actualizando AAPS</string>
|
||||
<string name="whatistrue">Seleccione todas las respuestas correctas.</string>
|
||||
<string name="update_git">Es necesario tener Git instalado y configurado en la computadora.</string>
|
||||
<string name="update_asap">Cuando esté disponible una versión más reciente de AAPS, las funciones de las versiones anteriores pueden ser limitadas de forma remota después de una fecha especifica.</string>
|
||||
<string name="update_keys">Se debe guardar en un lugar seguro de su computadora la \"keystore\" (archivo.jks) que se ha empleado previamente y usar la misma \"keystore\" para futuras actualizaciones.</string>
|
||||
<string name="update_neverupdate">Nunca se debe actualizar AAPS si el sistema está funcionando bien.</string>
|
||||
<string name="update_askfriend">Si tienes problemas creando la aplicación (. apk), puedes instalar el mismo archivo. apk compilado por un amigo.</string>
|
||||
<string name="update_hint1">https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#update-to-a-new-version-or-branch</string>
|
||||
<string name="troubleshooting_label">Solucionando problemas</string>
|
||||
<string name="troubleshooting_wheretoask">¿Dónde puedes buscar ayuda con AAPS?</string>
|
||||
<string name="troubleshooting_fb">Puede solicitar asesoramiento en el grupo de usuarios de AAPS en Facebook.</string>
|
||||
<string name="troubleshooting_wiki">Deberías leer (y volver a leer) la documentación de AAPS.</string>
|
||||
<string name="troubleshooting_gitter">Puedes solicitar asesoramiento y registrar problemas técnicos o incidencias en el grupo de Discord de AAPS.</string>
|
||||
<string name="troubleshooting_yourendo">Debes preguntar a tu endocrinólogo o educador en diabetes.</string>
|
||||
<string name="troubleshooting_hint1">https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Update-to-new-version.html#troubleshooting</string>
|
||||
<string name="troubleshooting_hint2">https://www.facebook.com/groups/AndroidAPSUsers/</string>
|
||||
<string name="troubleshooting_hint3">https://discord.gg/4fQUWHZ4Mw</string>
|
||||
<string name="insulin_plugins">Plugins de insulina</string>
|
||||
<string name="insulin_ultrarapid">¿Qué insulina debes usar con el plugin Ultra-Rapid Oref?</string>
|
||||
<string name="insulin_fiasp">Fiasp®</string>
|
||||
<string name="insulin_novorapid">NovoRapid®/Novolog®</string>
|
||||
<string name="insulin_humalog">Humalog®</string>
|
||||
<string name="insulin_actrapid">Actrapid®/Humalin R®/\"insulina humana estándar\".</string>
|
||||
<string name="insulin_hint1">https://androidaps.readthedocs.io/en/latest/EN/Configuration/Config-Builder.html#insulin</string>
|
||||
<string name="sensitivity_label">Plugins de sensibilidad</string>
|
||||
<string name="sensitivity_which">Seleccione todas las respuestas correctas.</string>
|
||||
<string name="sensitivity_adjust">Los plugins de sensibilidad permiten a AAPS ajustarse para cambios temporales o de corta duración en la sensibilidad a la insulina (por ejemplo, cambios hormonales o problemas con la absorción en el sitio de infusión).</string>
|
||||
<string name="sensitivity_edit">Los plugins de sensibilidad sugieren al usuario cambios en la cantidad de insulina basal a suministrar, en el factor de sensibilidad a la insulina (ISF) y en el ratio I:C y pueden ser incorporados al perfil definido.</string>
|
||||
<string name="sensitivity_cannula">Registrar el cámbio de cánula reinicia Autosens, volviendo de nuevo al 100%.</string>
|
||||
<string name="sensitivity_time">Algunas de las opciones del plugin tienen rangos de tiempo configurables que pueden ser definidos por el usuario.</string>
|
||||
<string name="sensitivity_hint1">https://androidaps.readthedocs.io/en/latest/EN/Configuration/Sensitivity-detection-and-COB.html</string>
|
||||
<string name="sensitivity_hint2">https://androidaps.readthedocs.io/es/latest/Usage/Open-APS-features.html?highlight=Autosens#autosens</string>
|
||||
<string name="wrongcarbs_label">Error de ingreso de Carbohidratos</string>
|
||||
<string name="wrongcarbs_whattodo">¿Qué deberías hacer si has cometido un error al ingresar carbohidratos?</string>
|
||||
<string name="wrongcarbs_treatmentstab">Elimina la entrada incorrecta en pestaña de tratamientos e introduce el valor correcto.</string>
|
||||
<string name="wrongcarbs_addinsulin">Darse un bolo desde el menú de llenado de la infusión.</string>
|
||||
<string name="wrongcarbs_donothing">No hacer nada - AAPS realizará los ajustes necesarios.</string>
|
||||
<string name="wrongcarbs_bolus">Darse un bolo usando el botón de Insulina (bolus) en página general.</string>
|
||||
<string name="wronginsulin_label">Errores de entrega/entrada de insulina</string>
|
||||
<string name="wronginsulin_whattodo">¿Qué debes hacer si recibiste menos insulina de la que sugiere la historia de la bomba p.ej. debido a una oclusión, una cánula fallida o olvidarse de reponer la bomba después de una ducha?</string>
|
||||
<string name="wronginsulin_careportal">Elimina los valores de insulina del portal de Nightscout o Careportal para eliminarlos del historial de la bomba.</string>
|
||||
<string name="wronginsulin_compare">Comparar valores en AAPS con el historial de la bomba (si la bomba los registra).</string>
|
||||
<string name="wronginsulin_prime">Bolo una proporción de la insulina calculada “perdida” por jeringa/pluma o usando menú de Insulina.</string>
|
||||
<string name="wronginsulin_donothing">No hacer nada y permite que AAPS corrija cualquier resultado de nivel alto de glucosa.</string>
|
||||
<string name="cob_label">Carbohidratos activos (COB)</string>
|
||||
<string name="cob_question">¿Cómo afecta el cambio del valor FSI al cálculo de COB?</string>
|
||||
<string name="cob_longer">Incrementar el FSI hará que los carbohidratos se absorban más lentamente</string>
|
||||
<string name="cob_shorter">Incrementar el FSI hará que los carbohidratos se absorban más rápidamente</string>
|
||||
|
|
|
@ -9,26 +9,35 @@
|
|||
<string name="objectivenotfinished">Objective %1$d not finished</string>
|
||||
<string name="objectives_0_objective">Setting up visualization and monitoring, and analyzing basals and ratios</string>
|
||||
<string name="objectives_0_gate">Verify that BG is available in Nightscout, and pump insulin data is being uploaded</string>
|
||||
<string name="objectives_0_learned">You made basic setup of AAPS ecosystem. Nightscout is not necessary for AAPS to run but it\'s very useful for reporting or monitoring of other patients. It\'s not necessary to be connected to NS all the time if you use NS only for yourself. You can setup to upload for example only on home wifi and save battery.</string>
|
||||
<string name="objectives_openloop_objective">Starting on an open loop</string>
|
||||
<string name="objectives_openloop_gate">Run in Open Loop mode for a few days and manually enact lots of temp basals. Set up and use temporary and default temporary targets (e.g. for activity or hypo treatment carbs)</string>
|
||||
<string name="objectives_openloop_learned">Open loop can be used for recommendations if you don\'t have compatible pump or you are not ready to close the loop.</string>
|
||||
<string name="objectives_maxbasal_objective">Understanding your open loop, including its temp basal recommendations</string>
|
||||
<string name="objectives_maxbasal_gate">Based on that experience, decide what max basal should be, and set it on the pump and preferences</string>
|
||||
<string name="objectives_maxbasal_learned">Take care about safety features and adjust safety parameters when necessary.</string>
|
||||
<string name="objectives_maxiobzero_objective">Starting to close the loop with Low Glucose Suspend</string>
|
||||
<string name="objectives_maxiobzero_gate">Run in closed loop with max IOB = 0 for a few days without too many LGS events</string>
|
||||
<string name="objectives_maxiobzero_learned">Setting MaxIOB to zero prevents you from hypo and will not add more insulin above basal rate (except situation with negative IOB)</string>
|
||||
<string name="objectives_maxiob_objective">Tuning the closed loop, raising max IOB above 0 and gradually lowering BG targets</string>
|
||||
<string name="objectives_maxiob_gate">Run for a few days, and at least one night with no low BG alarms, before dropping BG</string>
|
||||
<string name="objectives_maxiob_learned">Update MaxIOB as a child grows. Do not allow to the system give you more insulin than you can cover by food = really high value is a bad idea.</string>
|
||||
<string name="objectives_autosens_objective">Adjust basals and ratios if needed, and then enable auto-sens</string>
|
||||
<string name="objectives_autosens_gate">1 week successful daytime looping with regular carb entry</string>
|
||||
<string name="objectives_autosens_learned">If your autosens result is not oscillating around 100% your profile probably wrong.</string>
|
||||
<string name="objectives_smb_objective">Enabling additional features for daytime use, such as SMB</string>
|
||||
<string name="objectives_auto_objective">Enabling automation</string>
|
||||
<string name="objectives_smb_gate">You must read the wiki and rise maxIOB to get SMBs working fine! A good start is maxIOB=average mealbolus + 3 x max daily basal</string>
|
||||
<string name="objectives_smb_learned">Using SMB is your goal. Oref1 algorithm was designed to help you with your boluses as well. You should not give full bolus for your food but only part of it and let AAPS give you the rest if needed. This way you have more space for miscalculated carbs. Did you know that you can set a percentage of bolus calculator result to reduce the size of bolus?</string>
|
||||
<string name="objectives_auto_objective">Enabling automation</string>
|
||||
<string name="objectives_auto_gate">Read the docs on how automation works. Set up your first simple rules. Instead of action let AAPS display only notification. When you are sure automation is triggered at the right time replace notification by real action. (https://androidaps.readthedocs.io/en/latest/EN/Usage/Automation.html)</string>
|
||||
<string name="objectives_auto_learned">Automation can be a good servant but a bad master. Don\'t overuse it. Do not try to replace underlying algorithm. Test the rule with message only before use. It depends on order.</string>
|
||||
<string name="objectives_bgavailableinns">BG available in NS</string>
|
||||
<string name="objectives_pumpstatusavailableinns">Pump status available in NS</string>
|
||||
<string name="objectives_manualenacts">Manual enacts</string>
|
||||
<string name="accomplished">Accomplished: %1$s</string>
|
||||
<string name="objectives_usage_objective">Learn how to control AAPS</string>
|
||||
<string name="objectives_usage_gate">Perform different actions in AAPS</string>
|
||||
<string name="objectives_usage_learned">You learned how to handle basics of AAPS. Main controls are on Overview screen accessible on click or long click, more controls is on Action screen. You should know how to put a screen of plugin to top scrollable menu or let it show in top-left list of enabled plugins.</string>
|
||||
<string name="objectives_useprofileswitch">Set profile 90% for 10 min (Long-press profile name on Overview)</string>
|
||||
<string name="objectives_usedisconnectpump">Simulate shower. Disconnect pump for 1h (Long-press on Open Loop)</string>
|
||||
<string name="objectives_usereconnectpump">... and reconnect back the same way</string>
|
||||
|
@ -36,12 +45,32 @@
|
|||
<string name="objectives_useactions">In Config Builder enable Actions plugin, make it visible and display its content from top menu</string>
|
||||
<string name="objectives_useloop">Display content of Loop plugin</string>
|
||||
<string name="objectives_usescale">Use scale function by long-pressing BG chart</string>
|
||||
<string name="objectives_button_enter">Enter</string>
|
||||
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">If you have at least 3 months of closed loop experience with other systems you might qualify for a code to skip objectives. See https://androidaps.readthedocs.io/en/latest/EN/Usage/Objectives.html#skip-objectives for details.</string>
|
||||
<string name="codeaccepted">Code accepted</string>
|
||||
<string name="codeinvalid">Code invalid</string>
|
||||
<string name="objectives_exam_objective">Prove your knowledge</string>
|
||||
<string name="objectives_exam_gate">Study the questions. You are given four possible answers for each question. There may be more than one correct answer. Please check all those that are correct and select VERIFY.</string>
|
||||
<string name="objectives_exam_learned_prerequisites">You don\'t need to be a developer but you need NS to pass Objectives, compatible pump and computer to build AAPS for the first time and for every update.</string>
|
||||
<string name="objectives_exam_learned_prerequisites2">AAPS can be run offline.</string>
|
||||
<string name="objectives_exam_learned_basaltest">Profile should be reviewed and updated. Better profile = better results.</string>
|
||||
<string name="objectives_exam_learned_dia">DIA in looping has different meaning (time until all insulin is absorbed) then in classic pump therapy (time until most insulin is absorbed).</string>
|
||||
<string name="objectives_exam_learned_isf">You learned meaning of ISF value and it affects amount of insulin used for BG correction.</string>
|
||||
<string name="objectives_exam_learned_ic">You learned meaning of IC value and it affects amount of insulin needed to cover carbs.</string>
|
||||
<string name="objectives_exam_learned_hypott">Hypo temp target is used only to prevent overcorrection after hypo, when there is usually stacked negative IOB. Additional actions should be evaluated to prevent this situation again in the future.</string>
|
||||
<string name="objectives_exam_learned_profileswitch">Using percentage doesn\'t affect targets BGs but basal, ISF and IC are adjusted to give more insulin (above 100%) or less insulin (under 100%).</string>
|
||||
<string name="objectives_exam_learned_profileswitchtime">By using timeshift in profile switch you can adapt circadian profile to irregularities like late wake up.</string>
|
||||
<string name="objectives_exam_learned_profileswitch4">Editing profile itself is not sufficient to make a change. You still need to do a profile switch to activate changes.</string>
|
||||
<string name="objectives_exam_learned_exercise">You should reduce amount of insulin in the body at least 1 hour before starting exercise by selecting profile under 100%.</string>
|
||||
<string name="objectives_exam_learned_exercise2">Setting of higher temp target at least 1 hour before exercise helps with reducing of amount of insulin in the body as well.</string>
|
||||
<string name="objectives_exam_learned_noisycgm">Wen you cannot trust CGM values you should not use loop unattended.</string>
|
||||
<string name="objectives_exam_learned_pumpdisconnect">AAPS must know that pump is not connected to count IOB correctly.</string>
|
||||
<string name="objectives_exam_learned_insulin">Letting know which insulin is in pump is necessary because it does affect IOB calculation.</string>
|
||||
<string name="objectives_exam_learned_sensitivity">Sensitivity detection is part of the algorithm which allows adapt insulin dosage to different situations.</string>
|
||||
<string name="objectives_exam_learned_objectives">Your progress in Objectives is stored along with other settings and it should be backed up.</string>
|
||||
<string name="objectives_exam_learned_objectives2">Always keep exported settings and generated APK also outside phone. Phone can be lost, damaged etc. Good place can be any cloud accessible from phone. In this case you can restore AAPS on another device in a few minutes. Good practice is store used master password on a safe place too. Without it is your backup useless. The same is valid for signing keys (.jks file) and passwords used to build AAPS. The rest is not important - it can be anytime downloaded from internet again.</string>
|
||||
<string name="objectives_exam_learned_wrongcarbs">If you made wrong input to AAPS or it doesn\'t match reality, resolve it asap. It could lead to overdosing. AAPS should be always informed the best possible way about carbs, insulin etc.</string>
|
||||
<string name="objectives_exam_learned_iob">If you analyze if AAPS is working well for you watching IOB graph can give you a lof of useful information.</string>
|
||||
<string name="objectives_exam_learned_cob">COB calculation depends on relation between ISF an IC. Increasing ISF or decreasing IC will lead to longer absorption times. But profile switch with percentage change both values at the same time and absorption time is not affected.</string>
|
||||
<string name="objectives_exam_learned_breadgrams">Only grams are allowed for entry of carbohydrates.</string>
|
||||
<string name="objectives_exam_learned_ecarbs">E-carbs is a replacement for extended bolus in pump world.</string>
|
||||
<string name="objectives_exam_learned_nsclient">Remote monitoring and control is possible but not all features must be available remotely.</string>
|
||||
<string name="answerdisabledto">Answering disabled until: %1$s</string>
|
||||
<string name="wronganswer">Wrong answer!</string>
|
||||
<string name="unfinshed_button">Next unfinished</string>
|
||||
|
@ -54,5 +83,6 @@
|
|||
<string name="notconnected">Not connected to the internet</string>
|
||||
<string name="failedretrievetime">Failed retrieve time</string>
|
||||
<string name="requirementnotmet">Objective requirements not met</string>
|
||||
<string name="what_i_ve_learned">What I\'ve learned:</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1092,15 +1092,16 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
|
||||
private fun updateSensitivity() {
|
||||
_binding ?: return
|
||||
if (constraintChecker.isAutosensModeEnabled().value() || !(config.NSCLIENT && overviewData.lastAutosensData(iobCobCalculator) == null)) {
|
||||
val lastAutosensData = overviewData.lastAutosensData(iobCobCalculator)
|
||||
if (constraintChecker.isAutosensModeEnabled().value() || !(config.NSCLIENT && lastAutosensData == null)) {
|
||||
binding.infoLayout.sensitivityIcon.setImageResource(info.nightscout.core.main.R.drawable.ic_swap_vert_black_48dp_green)
|
||||
} else {
|
||||
binding.infoLayout.sensitivityIcon.setImageResource(info.nightscout.core.main.R.drawable.ic_x_swap_vert)
|
||||
}
|
||||
|
||||
binding.infoLayout.sensitivity.text =
|
||||
overviewData.lastAutosensData(iobCobCalculator)?.let { autosensData ->
|
||||
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
|
||||
lastAutosensData?.let {
|
||||
String.format(Locale.ENGLISH, "%.0f%%", it.autosensResult.ratio * 100)
|
||||
} ?: ""
|
||||
// Show variable sensitivity
|
||||
val profile = profileFunction.getProfile()
|
||||
|
|
|
@ -29,6 +29,7 @@ import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAny
|
|||
import info.nightscout.database.impl.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
|
||||
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
||||
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
|
@ -125,7 +126,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
|||
|
||||
val commands = mapOf(
|
||||
"BG" to "BG",
|
||||
"LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20",
|
||||
"LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS/CLOSED/LGS\nLOOP SUSPEND 20",
|
||||
"NSCLIENT" to "NSCLIENT RESTART",
|
||||
"PUMP" to "PUMP\nPUMP CONNECT\nPUMP DISCONNECT 30\n",
|
||||
"BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n",
|
||||
|
@ -416,10 +417,10 @@ class SmsCommunicatorPlugin @Inject constructor(
|
|||
receivedSms.processed = true
|
||||
}
|
||||
|
||||
"STATUS" -> {
|
||||
"STATUS" -> {
|
||||
val reply = if (loop.enabled) {
|
||||
if (loop.isSuspended) rh.gs(R.string.sms_loop_suspended_for, loop.minutesToEndOfSuspend())
|
||||
else rh.gs(R.string.smscommunicator_loop_is_enabled)
|
||||
else rh.gs(R.string.smscommunicator_loop_is_enabled) + " - " + getApsModeText()
|
||||
} else
|
||||
rh.gs(info.nightscout.core.ui.R.string.loopisdisabled)
|
||||
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||
|
@ -454,7 +455,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
|||
})
|
||||
}
|
||||
|
||||
"SUSPEND" -> {
|
||||
"SUSPEND" -> {
|
||||
var duration = 0
|
||||
if (divided.size == 3) duration = SafeParse.stringToInt(divided[2])
|
||||
duration = max(0, duration)
|
||||
|
@ -502,7 +503,37 @@ class SmsCommunicatorPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||
"LGS" -> {
|
||||
val passCode = generatePassCode()
|
||||
val reply = rh.gs(R.string.smscommunicator_set_lgs_reply_with_code, passCode)
|
||||
receivedSms.processed = true
|
||||
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) {
|
||||
override fun run() {
|
||||
uel.log(Action.LGS_LOOP_MODE, Sources.SMS)
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.LGS.name)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)))
|
||||
val replyText = rh.gs(R.string.smscommunicator_current_loop_mode, getApsModeText())
|
||||
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
"CLOSED" -> {
|
||||
val passCode = generatePassCode()
|
||||
val reply = rh.gs(R.string.smscommunicator_set_closed_loop_reply_with_code, passCode)
|
||||
receivedSms.processed = true
|
||||
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) {
|
||||
override fun run() {
|
||||
uel.log(Action.CLOSED_LOOP_MODE, Sources.SMS)
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.CLOSED.name)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(info.nightscout.core.ui.R.string.closedloop)))
|
||||
val replyText = rh.gs(R.string.smscommunicator_current_loop_mode, getApsModeText())
|
||||
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1251,4 +1282,12 @@ class SmsCommunicatorPlugin @Inject constructor(
|
|||
knownNumbers.size > 1
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
|
||||
private fun getApsModeText(): String =
|
||||
when (ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))) {
|
||||
ApsMode.OPEN -> rh.gs(info.nightscout.core.ui.R.string.openloop)
|
||||
ApsMode.CLOSED -> rh.gs(info.nightscout.core.ui.R.string.closedloop)
|
||||
ApsMode.LGS -> rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)
|
||||
else -> rh.gs(info.nightscout.core.ui.R.string.unknown)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,8 @@ class StatusLightHandler @Inject constructor(
|
|||
private fun handleLevel(view: TextView?, criticalSetting: Int, criticalDefaultValue: Double, warnSetting: Int, warnDefaultValue: Double, level: Double, units: String) {
|
||||
val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue)
|
||||
val resWarn = sp.getDouble(warnSetting, warnDefaultValue)
|
||||
view?.text = " " + DecimalFormatter.to0Decimal(level, units)
|
||||
if (level > 0) view?.text = " " + DecimalFormatter.to0Decimal(level, units)
|
||||
else view?.text = ""
|
||||
warnColors.setColorInverse(view, level, resWarn, resUrgent)
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingStart="4sp"
|
||||
android:paddingEnd="4sp"
|
||||
android:text="Pump: running"
|
||||
tools:text="Pump: running"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
|
@ -146,7 +146,7 @@
|
|||
android:layout_weight="1"
|
||||
android:paddingStart="4sp"
|
||||
android:paddingEnd="4sp"
|
||||
android:text="OpenAPS: 3 min ago"
|
||||
tools:text="OpenAPS: 3 min ago"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
|
@ -157,7 +157,7 @@
|
|||
android:layout_weight="1"
|
||||
android:paddingStart="4sp"
|
||||
android:paddingEnd="4sp"
|
||||
android:text="Uploader: 84%"
|
||||
tools:text="Uploader: 84%"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
|
|
|
@ -172,8 +172,8 @@
|
|||
<string name="pb_label">Batería de la bomba</string>
|
||||
<string name="cannula">Cánula</string>
|
||||
<string name="ebstopsloop">El uso de la función de bolo extendido detendrá el modo de bucle cerrado durante el tiempo de ejecución del bolo extendido. ¿Realmente quieres esto?</string>
|
||||
<string name="statuslights_cannula_age">edad de la cánula</string>
|
||||
<string name="statuslights_patch_pump_age">edad del parche de la bomba</string>
|
||||
<string name="statuslights_cannula_age">Edad de la cánula</string>
|
||||
<string name="statuslights_patch_pump_age">Edad de la bomba parche</string>
|
||||
<string name="patch_pump">Bomba parche</string>
|
||||
<!-- Overview -->
|
||||
<string name="show_statuslights">Mostrar luces de estado en la pantalla de inicio</string>
|
||||
|
@ -309,7 +309,7 @@
|
|||
<string name="largedisplay_description">Pantalla grande</string>
|
||||
<string name="skin">Tema</string>
|
||||
<!-- DataBroadcast-->
|
||||
<string name="cannula_usage">uso:</string>
|
||||
<string name="cannula_usage">Uso:</string>
|
||||
<!-- Iob-->
|
||||
<string name="send_logfiles">Enviar los archivos de registro de hoy a los desarrolladores. Situación inesperada.</string>
|
||||
<!-- Wear-->
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
<string name="smscommunicator_message_body">Błędny tekst wiadomości</string>
|
||||
<string name="smscommunicator_report_pump_unreachable_summary">Wyślij SMS, jeśli wyzwolone jest zdarzenie pompy nieosiągalnej</string>
|
||||
<string name="smscommunicator_pump_unreachable">Zgłoś nieosiągalną pompę</string>
|
||||
<string name="smscommunicator_set_lgs_reply_with_code">Aby przełączyć pętlę w tryb LGS (zawieszenie przy niskiej glikemii) wprowadź kod %1$s</string>
|
||||
<string name="smscommunicator_set_closed_loop_reply_with_code">Aby przełączyć pętlę w tryb pętli zamkniętej wprowadź kod %1$s</string>
|
||||
<string name="smscommunicator_current_loop_mode">Obecny tryb pętli: %1$s</string>
|
||||
<string name="wrong_format">Błędny format</string>
|
||||
<string name="sms_actual_bg">BG:</string>
|
||||
<string name="sms_last_bg">Ostatnia BG:</string>
|
||||
|
|
|
@ -95,6 +95,9 @@
|
|||
<string name="smscommunicator_message_body">Invalid message body</string>
|
||||
<string name="smscommunicator_report_pump_unreachable_summary">Send SMS if unreachable pump event is triggered</string>
|
||||
<string name="smscommunicator_pump_unreachable">Report pump unreachable</string>
|
||||
<string name="smscommunicator_set_lgs_reply_with_code">In order to switch Loop mode to LGS (Low Glucose Suspend) reply with code %1$s</string>
|
||||
<string name="smscommunicator_set_closed_loop_reply_with_code">In order to switch Loop mode to Closed loop reply with code %1$s</string>
|
||||
<string name="smscommunicator_current_loop_mode">Current loop mode: %1$s</string>
|
||||
<string name="wrong_format">Wrong format</string>
|
||||
<string name="sms_actual_bg">BG:</string>
|
||||
<string name="sms_last_bg">Last BG:</string>
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAny
|
|||
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
||||
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.database.impl.transactions.Transaction
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
|
@ -85,6 +86,10 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
|
||||
private lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
||||
private var hasBeenRun = false
|
||||
private val modeClosed = "Closed Loop"
|
||||
private val modeOpen = "Open Loop"
|
||||
private val modeLgs = "Low Glucose Suspend"
|
||||
private val modeUnknown = "unknown"
|
||||
|
||||
@BeforeEach fun prepareTests() {
|
||||
val reading = GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT)
|
||||
|
@ -248,7 +253,13 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
`when`(rh.gsNotLocalised(R.string.smscommunicator_tempbasal_canceled)).thenReturn("Temp basal canceled")
|
||||
`when`(rh.gsNotLocalised(R.string.smscommunicator_calibration_sent)).thenReturn("Calibration sent. Receiving must be enabled in xDrip+.")
|
||||
`when`(rh.gsNotLocalised(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully")
|
||||
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.closedloop)).thenReturn(modeClosed)
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.openloop)).thenReturn(modeOpen)
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)).thenReturn(modeLgs)
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.unknown)).thenReturn(modeUnknown)
|
||||
`when`(rh.gs(R.string.smscommunicator_set_closed_loop_reply_with_code)).thenReturn("In order to switch Loop mode to Closed loop reply with code %1\$s")
|
||||
`when`(rh.gs(R.string.smscommunicator_current_loop_mode)).thenReturn("Current loop mode: %1\$s")
|
||||
`when`(rh.gs(R.string.smscommunicator_set_lgs_reply_with_code)).thenReturn("In order to switch Loop mode to LGS (Low Glucose Suspend) reply with code %1\$s")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -329,15 +340,40 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
Assertions.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Suspended (10 m)", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP STATUS : enabled
|
||||
//LOOP STATUS : enabled - APS mode - Closed
|
||||
`when`(loop.enabled).thenReturn(true)
|
||||
`when`(loop.isSuspended).thenReturn(false)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
sms = Sms("1234", "LOOP STATUS")
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Loop is enabled", smsCommunicatorPlugin.messages[1].text)
|
||||
Assertions.assertEquals("Loop is enabled - $modeClosed", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP STATUS : enabled - APS mode - Open
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Loop is enabled - $modeOpen", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP STATUS : enabled - APS mode - LGS
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.LGS.name)
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Loop is enabled - $modeLgs", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP STATUS : enabled - APS mode - unknown
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn("some wrong value")
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Loop is enabled - $modeUnknown", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP : wrong format
|
||||
`when`(loop.enabled).thenReturn(true)
|
||||
|
@ -480,6 +516,37 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
Assertions.assertEquals("LOOP BLABLA", smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
|
||||
|
||||
//LOOP CLOSED
|
||||
var smsCommand = "LOOP CLOSED"
|
||||
val replyClosed = "In order to switch Loop mode to Closed loop reply with code "
|
||||
`when`(loop.enabled).thenReturn(true)
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
sms = Sms("1234", smsCommand)
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals(smsCommand, smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertTrue(smsCommunicatorPlugin.messages[1].text.contains(replyClosed))
|
||||
passCode = smsCommunicatorPlugin.messageToConfirm?.confirmCode!!
|
||||
smsCommunicatorPlugin.processSms(Sms("1234", passCode))
|
||||
Assertions.assertEquals(passCode, smsCommunicatorPlugin.messages[2].text)
|
||||
Assertions.assertEquals("Current loop mode: $modeClosed", smsCommunicatorPlugin.messages[3].text)
|
||||
|
||||
//LOOP LGS
|
||||
smsCommand = "LOOP LGS"
|
||||
val replyLgs = "In order to switch Loop mode to LGS (Low Glucose Suspend) reply with code "
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.LGS.name)
|
||||
smsCommunicatorPlugin.messages = ArrayList()
|
||||
sms = Sms("1234", smsCommand)
|
||||
smsCommunicatorPlugin.processSms(sms)
|
||||
Assertions.assertFalse(sms.ignored)
|
||||
Assertions.assertEquals(smsCommand, smsCommunicatorPlugin.messages[0].text)
|
||||
Assertions.assertTrue(smsCommunicatorPlugin.messages[1].text.contains(replyLgs))
|
||||
passCode = smsCommunicatorPlugin.messageToConfirm?.confirmCode!!
|
||||
smsCommunicatorPlugin.processSms(Sms("1234", passCode))
|
||||
Assertions.assertEquals(passCode, smsCommunicatorPlugin.messages[2].text)
|
||||
Assertions.assertEquals("Current loop mode: $modeLgs", smsCommunicatorPlugin.messages[3].text)
|
||||
|
||||
//NSCLIENT RESTART
|
||||
`when`(loop.isEnabled()).thenReturn(true)
|
||||
`when`(loop.isSuspended).thenReturn(false)
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Source -->
|
||||
<string name="ns_client_bg">NSClient Glucosa</string>
|
||||
<string name="ns_client_bg_short">NS BG</string>
|
||||
<string name="description_source_ns_client">Recibir los datos de glucosa de Nightscout</string>
|
||||
<string name="xdrip">xDrip+</string>
|
||||
<string name="description_source_xdrip">Recibir los valores de glucosa de xDrip+</string>
|
||||
<string name="dexcom_app_patched">Dexcom (BYODA)</string>
|
||||
<string name="dexcom_short">BYODA</string>
|
||||
<string name="description_source_dexcom">Recibir los valores de glucosa de la aplicación Dexcom \'Build Your Own Device\'</string>
|
||||
<string name="eversense">Eversense App (parchada)</string>
|
||||
<string name="description_source_eversense">Recibir los valores de glucosa de la aplicación Eversense parchada.</string>
|
||||
<string name="glimp">Glimp</string>
|
||||
<string name="description_source_glimp">Recibir valores de glucosa de Glimp.</string>
|
||||
<string name="mm640g">MM640g</string>
|
||||
<string name="description_source_mm640g">Recibir los valores de glucosa del 600SeriesAndroidUploader.</string>
|
||||
<string name="poctech">Poctech</string>
|
||||
<string name="description_source_poctech">Recibir los valores de glucosa de Poctech</string>
|
||||
<string name="glunovo">Glunovo</string>
|
||||
<string name="description_source_glunovo">Recibir los valores de glucosa de la aplicación Glunovo</string>
|
||||
<string name="intelligo">Intelligo</string>
|
||||
|
|
|
@ -35,4 +35,5 @@
|
|||
<string name="bgsource_upload">Innstillinger for opplasting av BS</string>
|
||||
<string name="dexcom_log_ns_sensor_change_title">Logg sensor bytte til NS</string>
|
||||
<string name="dexcom_log_ns_sensor_change_summary">Opprett hendelse \"Sensor bytte\" automatisk i NS ved start av sensoren</string>
|
||||
<string name="direction">retning</string>
|
||||
</resources>
|
||||
|
|
|
@ -7,9 +7,9 @@ import info.nightscout.interfaces.nsclient.NSSettingsStatus
|
|||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.plugins.sync.nsShared.DataSyncSelectorImplementation
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorImplementation
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl
|
||||
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
|
||||
import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
||||
|
@ -17,6 +17,7 @@ import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker
|
|||
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientUpdateRemoveAckWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.DataSyncWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadBgWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadDeviceStatusWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||
|
@ -49,6 +50,7 @@ abstract class SyncModule {
|
|||
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDataSyncWorker(): DataSyncWorker
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.plugins.sync.nsclient
|
||||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
|
@ -56,11 +56,12 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
private val queueCounter = QueueCounter()
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override fun doUpload() {
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true)) {
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
|
||||
processChangedBolusesCompat()
|
||||
processChangedCarbsCompat()
|
||||
processChangedBolusCalculatorResultsCompat()
|
||||
|
@ -106,6 +107,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedBolusesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
|
@ -158,6 +160,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedCarbsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
|
@ -206,6 +209,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedBolusCalculatorResultsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
|
@ -257,6 +261,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedTempTargetsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
|
@ -309,6 +314,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedFoodsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
|
@ -357,6 +363,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedGlucoseValuesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
|
@ -369,7 +376,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ")
|
||||
if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) {
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null -> {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ")
|
||||
confirmLastGlucoseValueIdIfGreater(gv.second.id)
|
||||
|
@ -410,6 +417,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedTherapyEventsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
|
@ -458,6 +466,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override fun processChangedDeviceStatusesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
|
@ -471,7 +480,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
when {
|
||||
// without nsId = create new
|
||||
deviceStatus.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.dbAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, null), "$startId/$lastDbId")
|
||||
activePlugin.activeNsClient?.dbAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, 0), "$startId/$lastDbId")
|
||||
// with nsId = ignore
|
||||
deviceStatus.interfaceIDs.nightscoutId != null -> Any()
|
||||
}
|
||||
|
@ -487,6 +496,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedTemporaryBasalsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
|
@ -539,6 +549,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedExtendedBolusesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
|
@ -599,6 +610,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedProfileSwitchesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
|
@ -647,6 +659,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedEffectiveProfileSwitchesCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
|
@ -699,6 +712,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override tailrec fun processChangedOfflineEventsCompat() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
|
@ -744,6 +758,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
override fun processChangedProfileStore() {
|
||||
if (isPaused) return
|
||||
val lastSync = sp.getLong(R.string.key_ns_profile_store_last_synced_timestamp, 0)
|
||||
val lastChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
if (lastChange == 0L) return
|
||||
|
@ -753,4 +768,4 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.dbAdd("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@ import info.nightscout.interfaces.sync.NsClient
|
|||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.databinding.NsClientFragmentBinding
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
|
@ -56,7 +55,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
const val ID_MENU_RESTART = 508
|
||||
const val ID_MENU_SEND_NOW = 509
|
||||
const val ID_MENU_FULL_SYNC = 510
|
||||
const val ID_MENU_TEST = 601
|
||||
}
|
||||
|
||||
override var plugin: PluginBase? = null
|
||||
|
@ -97,8 +95,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
}
|
||||
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
if (config.isUnfinishedMode())
|
||||
menu.add(Menu.FIRST, ID_MENU_TEST, 0, "Test").setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_CLEAR_LOG, 0, rh.gs(R.string.clear_log)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_RESTART, 0, rh.gs(R.string.restart)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(Menu.FIRST, ID_MENU_SEND_NOW, 0, rh.gs(R.string.deliver_now)).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
|
@ -133,11 +129,6 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
true
|
||||
}
|
||||
|
||||
ID_MENU_TEST -> {
|
||||
nsClientPlugin?.let { plugin -> if (plugin is NSClientV3Plugin) handler.post { plugin.test() } }
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
|
|
@ -58,16 +58,6 @@ import info.nightscout.rx.bus.RxBus
|
|||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolusWizard
|
||||
import info.nightscout.sdk.localmodel.treatment.NSCarbs
|
||||
import info.nightscout.sdk.localmodel.treatment.NSEffectiveProfileSwitch
|
||||
import info.nightscout.sdk.localmodel.treatment.NSExtendedBolus
|
||||
import info.nightscout.sdk.localmodel.treatment.NSOfflineEvent
|
||||
import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTemporaryBasal
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTemporaryTarget
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTherapyEvent
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import java.util.concurrent.Executors
|
||||
|
@ -203,7 +193,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it")
|
||||
inserted.inc(NSBolus::class.java.simpleName)
|
||||
inserted.inc(Bolus::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -216,19 +206,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it")
|
||||
invalidated.inc(NSBolus::class.java.simpleName)
|
||||
invalidated.inc(Bolus::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of bolus $it")
|
||||
nsIdUpdated.inc(NSBolus::class.java.simpleName)
|
||||
nsIdUpdated.inc(Bolus::class.java.simpleName)
|
||||
}
|
||||
result.updated.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated amount of bolus $it")
|
||||
updated.inc(NSBolus::class.java.simpleName)
|
||||
updated.inc(Bolus::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("Bolus", NSBolus::class.java.simpleName)
|
||||
sendLog("Bolus", Bolus::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (carbs.isNotEmpty())
|
||||
|
@ -250,7 +240,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it")
|
||||
inserted.inc(NSCarbs::class.java.simpleName)
|
||||
inserted.inc(Carbs::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -263,7 +253,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it")
|
||||
invalidated.inc(NSCarbs::class.java.simpleName)
|
||||
invalidated.inc(Carbs::class.java.simpleName)
|
||||
}
|
||||
result.updated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -276,16 +266,16 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated carbs $it")
|
||||
updated.inc(NSCarbs::class.java.simpleName)
|
||||
updated.inc(Carbs::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it")
|
||||
nsIdUpdated.inc(NSCarbs::class.java.simpleName)
|
||||
nsIdUpdated.inc(Carbs::class.java.simpleName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sendLog("Carbs", NSCarbs::class.java.simpleName)
|
||||
sendLog("Carbs", Carbs::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (temporaryTargets.isNotEmpty())
|
||||
|
@ -312,7 +302,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt")
|
||||
inserted.inc(NSTemporaryTarget::class.java.simpleName)
|
||||
inserted.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach { tt ->
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -330,7 +320,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt")
|
||||
invalidated.inc(NSTemporaryTarget::class.java.simpleName)
|
||||
invalidated.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
result.ended.forEach { tt ->
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -348,19 +338,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt")
|
||||
ended.inc(NSTemporaryTarget::class.java.simpleName)
|
||||
ended.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it")
|
||||
nsIdUpdated.inc(NSTemporaryTarget::class.java.simpleName)
|
||||
nsIdUpdated.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
result.updatedDuration.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated duration TemporaryTarget $it")
|
||||
durationUpdated.inc(NSTemporaryTarget::class.java.simpleName)
|
||||
durationUpdated.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("TemporaryTarget", NSTemporaryTarget::class.java.simpleName)
|
||||
sendLog("TemporaryTarget", TemporaryTarget::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (temporaryBasals.isNotEmpty())
|
||||
|
@ -386,7 +376,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it")
|
||||
inserted.inc(NSTemporaryBasal::class.java.simpleName)
|
||||
inserted.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -403,7 +393,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
invalidated.inc(NSTemporaryBasal::class.java.simpleName)
|
||||
invalidated.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
result.ended.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -420,19 +410,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it")
|
||||
ended.inc(NSTemporaryBasal::class.java.simpleName)
|
||||
ended.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it")
|
||||
nsIdUpdated.inc(NSTemporaryBasal::class.java.simpleName)
|
||||
nsIdUpdated.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
result.updatedDuration.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated duration TemporaryBasal $it")
|
||||
durationUpdated.inc(NSTemporaryBasal::class.java.simpleName)
|
||||
durationUpdated.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("TemporaryBasal", NSTemporaryBasal::class.java.simpleName)
|
||||
sendLog("TemporaryBasal", TemporaryBasal::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (effectiveProfileSwitches.isNotEmpty())
|
||||
|
@ -454,7 +444,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted EffectiveProfileSwitch $it")
|
||||
inserted.inc(NSEffectiveProfileSwitch::class.java.simpleName)
|
||||
inserted.inc(EffectiveProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -467,15 +457,15 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated EffectiveProfileSwitch $it")
|
||||
invalidated.inc(NSEffectiveProfileSwitch::class.java.simpleName)
|
||||
invalidated.inc(EffectiveProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId EffectiveProfileSwitch $it")
|
||||
nsIdUpdated.inc(NSEffectiveProfileSwitch::class.java.simpleName)
|
||||
nsIdUpdated.inc(EffectiveProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("EffectiveProfileSwitch", NSEffectiveProfileSwitch::class.java.simpleName)
|
||||
sendLog("EffectiveProfileSwitch", EffectiveProfileSwitch::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (profileSwitches.isNotEmpty())
|
||||
|
@ -497,7 +487,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
|
||||
inserted.inc(NSProfileSwitch::class.java.simpleName)
|
||||
inserted.inc(ProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -510,15 +500,15 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||
invalidated.inc(NSProfileSwitch::class.java.simpleName)
|
||||
invalidated.inc(ProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||
nsIdUpdated.inc(NSProfileSwitch::class.java.simpleName)
|
||||
nsIdUpdated.inc(ProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("ProfileSwitch", NSProfileSwitch::class.java.simpleName)
|
||||
sendLog("ProfileSwitch", ProfileSwitch::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (bolusCalculatorResults.isNotEmpty())
|
||||
|
@ -531,19 +521,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
bolusCalculatorResults.clear()
|
||||
result.inserted.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted BolusCalculatorResult $it")
|
||||
inserted.inc(NSBolusWizard::class.java.simpleName)
|
||||
inserted.inc(BolusCalculatorResult::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated BolusCalculatorResult $it")
|
||||
invalidated.inc(NSBolusWizard::class.java.simpleName)
|
||||
invalidated.inc(BolusCalculatorResult::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId BolusCalculatorResult $it")
|
||||
nsIdUpdated.inc(NSBolusWizard::class.java.simpleName)
|
||||
nsIdUpdated.inc(BolusCalculatorResult::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("BolusCalculatorResult", NSBolusWizard::class.java.simpleName)
|
||||
sendLog("BolusCalculatorResult", BolusCalculatorResult::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
|
@ -583,7 +573,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $therapyEvent")
|
||||
inserted.inc(NSTherapyEvent::class.java.simpleName)
|
||||
inserted.inc(TherapyEvent::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach { therapyEvent ->
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -599,19 +589,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $therapyEvent")
|
||||
invalidated.inc(NSTherapyEvent::class.java.simpleName)
|
||||
invalidated.inc(TherapyEvent::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
nsIdUpdated.inc(NSTherapyEvent::class.java.simpleName)
|
||||
nsIdUpdated.inc(TherapyEvent::class.java.simpleName)
|
||||
}
|
||||
result.updatedDuration.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
durationUpdated.inc(NSTherapyEvent::class.java.simpleName)
|
||||
durationUpdated.inc(TherapyEvent::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("TherapyEvent", NSTherapyEvent::class.java.simpleName)
|
||||
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (offlineEvents.isNotEmpty())
|
||||
|
@ -635,7 +625,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $oe")
|
||||
inserted.inc(NSOfflineEvent::class.java.simpleName)
|
||||
inserted.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach { oe ->
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -651,7 +641,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated OfflineEvent $oe")
|
||||
invalidated.inc(NSOfflineEvent::class.java.simpleName)
|
||||
invalidated.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
result.ended.forEach { oe ->
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -667,19 +657,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $oe")
|
||||
ended.inc(NSOfflineEvent::class.java.simpleName)
|
||||
ended.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId OfflineEvent $it")
|
||||
nsIdUpdated.inc(NSOfflineEvent::class.java.simpleName)
|
||||
nsIdUpdated.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
result.updatedDuration.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated duration OfflineEvent $it")
|
||||
durationUpdated.inc(NSOfflineEvent::class.java.simpleName)
|
||||
durationUpdated.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("OfflineEvent", NSOfflineEvent::class.java.simpleName)
|
||||
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
if (extendedBoluses.isNotEmpty())
|
||||
|
@ -706,7 +696,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
if (it.isEmulatingTempBasal) virtualPump.fakeDataDetected = true
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it")
|
||||
inserted.inc(NSExtendedBolus::class.java.simpleName)
|
||||
inserted.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -724,7 +714,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it")
|
||||
invalidated.inc(NSExtendedBolus::class.java.simpleName)
|
||||
invalidated.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
result.ended.forEach {
|
||||
if (config.NSCLIENT.not()) userEntries.add(
|
||||
|
@ -742,19 +732,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it")
|
||||
ended.inc(NSExtendedBolus::class.java.simpleName)
|
||||
ended.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it")
|
||||
nsIdUpdated.inc(NSExtendedBolus::class.java.simpleName)
|
||||
nsIdUpdated.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
result.updatedDuration.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated duration ExtendedBolus $it")
|
||||
durationUpdated.inc(NSExtendedBolus::class.java.simpleName)
|
||||
durationUpdated.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
sendLog("ExtendedBolus", NSExtendedBolus::class.java.simpleName)
|
||||
sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
|
||||
uel.log(userEntries)
|
||||
|
@ -775,7 +765,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
// cancel waiting task to prevent sending multiple posts
|
||||
scheduledEventPost?.cancel(false)
|
||||
val task: Runnable = PostRunnable()
|
||||
scheduledEventPost = eventWorker.schedule(task, 30, TimeUnit.SECONDS)
|
||||
scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
|
||||
}
|
||||
|
||||
private fun updateNsIds() {
|
||||
|
@ -787,6 +777,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of TemporaryTarget $it")
|
||||
nsIdUpdated.inc(TemporaryTarget::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,6 +789,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of GlucoseValue $it")
|
||||
nsIdUpdated.inc(GlucoseValue::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -809,6 +801,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of Food $it")
|
||||
nsIdUpdated.inc(Food::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -820,6 +813,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of TherapyEvent $it")
|
||||
nsIdUpdated.inc(TherapyEvent::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,6 +825,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of Bolus $it")
|
||||
nsIdUpdated.inc(Bolus::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,6 +837,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of Carbs $it")
|
||||
nsIdUpdated.inc(Carbs::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -853,6 +849,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of BolusCalculatorResult $it")
|
||||
nsIdUpdated.inc(BolusCalculatorResult::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -864,6 +861,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of TemporaryBasal $it")
|
||||
nsIdUpdated.inc(TemporaryBasal::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -875,6 +873,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of ExtendedBolus $it")
|
||||
nsIdUpdated.inc(ExtendedBolus::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -886,6 +885,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of ProfileSwitch $it")
|
||||
nsIdUpdated.inc(ProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,6 +897,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of EffectiveProfileSwitch $it")
|
||||
nsIdUpdated.inc(EffectiveProfileSwitch::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -908,6 +909,7 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of DeviceStatus $it")
|
||||
nsIdUpdated.inc(DeviceStatus::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -919,8 +921,21 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId of OfflineEvent $it")
|
||||
nsIdUpdated.inc(OfflineEvent::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
|
||||
sendLog("Bolus", Bolus::class.java.simpleName)
|
||||
sendLog("Carbs", Carbs::class.java.simpleName)
|
||||
sendLog("TemporaryTarget", TemporaryTarget::class.java.simpleName)
|
||||
sendLog("TemporaryBasal", TemporaryBasal::class.java.simpleName)
|
||||
sendLog("EffectiveProfileSwitch", EffectiveProfileSwitch::class.java.simpleName)
|
||||
sendLog("ProfileSwitch", ProfileSwitch::class.java.simpleName)
|
||||
sendLog("BolusCalculatorResult", BolusCalculatorResult::class.java.simpleName)
|
||||
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
||||
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
||||
sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName)
|
||||
rxBus.send(EventNSClientNewLog("DONE NSIDs", ""))
|
||||
}
|
||||
|
||||
private fun sendLog(item: String, clazz: String) {
|
||||
|
|
|
@ -36,32 +36,33 @@ class ProcessedDeviceStatusDataImpl @Inject constructor(
|
|||
|
||||
// test warning level // color
|
||||
override fun pumpStatus(nsSettingsStatus: NSSettingsStatus): Spanned {
|
||||
val pumpData = pumpData ?: return HtmlHelper.fromHtml("")
|
||||
|
||||
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
|
||||
val string = StringBuilder()
|
||||
.append("<span style=\"color:${rh.gac(info.nightscout.core.ui.R.attr.nsTitleColor)}\">")
|
||||
.append(rh.gs(info.nightscout.core.ui.R.string.pump))
|
||||
.append(": </span>")
|
||||
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
|
||||
val string = StringBuilder()
|
||||
.append("<span style=\"color:${rh.gac(info.nightscout.core.ui.R.attr.nsTitleColor)}\">")
|
||||
.append(rh.gs(info.nightscout.core.ui.R.string.pump))
|
||||
.append(": </span>")
|
||||
|
||||
// test warning level
|
||||
val level = when {
|
||||
pumpData.clock + nsSettingsStatus.extendedPumpSettings("urgentClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("urgentRes") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("urgentBattP") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("urgentBattV") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.clock + nsSettingsStatus.extendedPumpSettings("warnClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.WARN
|
||||
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("warnRes") -> ProcessedDeviceStatusData.Levels.WARN
|
||||
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("warnBattP") -> ProcessedDeviceStatusData.Levels.WARN
|
||||
val pumpData = pumpData ?: return HtmlHelper.fromHtml(string.toString())
|
||||
|
||||
// test warning level
|
||||
val level = when {
|
||||
pumpData.clock + nsSettingsStatus.extendedPumpSettings("urgentClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("urgentRes") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("urgentBattP") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("urgentBattV") -> ProcessedDeviceStatusData.Levels.URGENT
|
||||
pumpData.clock + nsSettingsStatus.extendedPumpSettings("warnClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.WARN
|
||||
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("warnRes") -> ProcessedDeviceStatusData.Levels.WARN
|
||||
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("warnBattP") -> ProcessedDeviceStatusData.Levels.WARN
|
||||
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("warnBattV") -> ProcessedDeviceStatusData.Levels.WARN
|
||||
else -> ProcessedDeviceStatusData.Levels.INFO
|
||||
}
|
||||
string.append("<span style=\"color:${level.toColor()}\">")
|
||||
val insulinUnit = rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname)
|
||||
// val insulinUnit = rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname)
|
||||
val fields = nsSettingsStatus.pumpExtendedSettingsFields()
|
||||
if (pumpData.reservoirDisplayOverride != "")
|
||||
string.append(pumpData.reservoirDisplayOverride).append("$insulinUnit ")
|
||||
else if (fields.contains("reservoir")) string.append(pumpData.reservoir.toInt()).append("$insulinUnit ")
|
||||
// Removed here. Same value is in StatusLights
|
||||
// if (pumpData.reservoirDisplayOverride != "") string.append(pumpData.reservoirDisplayOverride).append("$insulinUnit ")
|
||||
// else if (fields.contains("reservoir")) string.append(pumpData.reservoir.toInt()).append("$insulinUnit ")
|
||||
if (fields.contains("battery") && pumpData.isPercent) string.append(pumpData.percent).append("% ")
|
||||
if (fields.contains("battery") && !pumpData.isPercent) string.append(Round.roundTo(pumpData.voltage, 0.001)).append(" ")
|
||||
if (fields.contains("clock")) string.append(dateUtil.minAgo(rh, pumpData.clock)).append(" ")
|
||||
|
@ -139,13 +140,19 @@ class ProcessedDeviceStatusDataImpl @Inject constructor(
|
|||
string.append(": </span>")
|
||||
val iterator: Iterator<*> = uploaderMap.entries.iterator()
|
||||
var minBattery = 100
|
||||
var found = false
|
||||
while (iterator.hasNext()) {
|
||||
val pair = iterator.next() as Map.Entry<*, *>
|
||||
val uploader = pair.value as ProcessedDeviceStatusData.Uploader
|
||||
if (minBattery > uploader.battery) minBattery = uploader.battery
|
||||
if (minBattery > uploader.battery) {
|
||||
minBattery = uploader.battery
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
string.append(minBattery)
|
||||
string.append("%")
|
||||
}
|
||||
string.append(minBattery)
|
||||
string.append("%")
|
||||
return HtmlHelper.fromHtml(string.toString())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.plugins.sync.nsclient.extensions
|
||||
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
|
@ -8,7 +9,7 @@ import org.json.JSONObject
|
|||
|
||||
fun Carbs.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
|
||||
JSONObject()
|
||||
.put("eventType", if (amount < 12) info.nightscout.database.entities.TherapyEvent.Type.CARBS_CORRECTION.text else info.nightscout.database.entities.TherapyEvent.Type.MEAL_BOLUS.text)
|
||||
.put("eventType", if (amount < 12) TherapyEvent.Type.CARBS_CORRECTION.text else TherapyEvent.Type.MEAL_BOLUS.text)
|
||||
.put("carbs", amount)
|
||||
.put("notes", notes)
|
||||
.put("created_at", dateUtil.toISOString(timestamp))
|
||||
|
|
|
@ -580,7 +580,7 @@ class NSClientService : DaggerService() {
|
|||
socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject))
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"DBUPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"" + _id + " " + data + progress
|
||||
)
|
||||
)
|
||||
|
@ -596,7 +596,7 @@ class NSClientService : DaggerService() {
|
|||
message.put("collection", collection)
|
||||
message.put("data", data)
|
||||
socket?.emit("dbAdd", message, NSAddAck(aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject))
|
||||
rxBus.send(EventNSClientNewLog("DBADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress))
|
||||
rxBus.send(EventNSClientNewLog("ADD $collection", "Sent " + originalObject.javaClass.simpleName + " " + data + " " + progress))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryTargets.add(pair.value)
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -66,7 +66,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdGlucoseValues.add(pair.value)
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -77,7 +77,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdFoods.add(pair.value)
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -88,7 +88,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTherapyEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -99,7 +99,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -110,7 +110,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdCarbs.add(pair.value)
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -121,7 +121,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBolusCalculatorResults.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -132,7 +132,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryBasals.add(pair.value)
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -143,7 +143,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdExtendedBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -154,7 +154,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -165,7 +165,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
@ -184,7 +184,7 @@ class NSClientAddAckWorker(
|
|||
}
|
||||
|
||||
is PairProfileStore -> {
|
||||
dataSyncSelector.confirmLastProfileStore(ack.originalObject.timestampSync)
|
||||
dataSyncSelector.confirmLastProfileStore(ack.originalObject.id)
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileStore " + ack.id))
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdOfflineEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
|
|
|
@ -46,7 +46,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
when (ack.originalObject) {
|
||||
is PairTemporaryTarget -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryTarget" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTempTargetsCompat()
|
||||
|
@ -55,7 +55,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairGlucoseValue -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked GlucoseValue " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedGlucoseValuesCompat()
|
||||
|
@ -64,7 +64,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairFood -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Food " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedFoodsCompat()
|
||||
|
@ -73,7 +73,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairTherapyEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TherapyEvent " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTherapyEventsCompat()
|
||||
|
@ -82,7 +82,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Bolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusesCompat()
|
||||
|
@ -91,7 +91,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairCarbs -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Carbs " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbsCompat()
|
||||
|
@ -100,7 +100,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairBolusCalculatorResult -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat()
|
||||
|
@ -109,7 +109,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairTemporaryBasal -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryBasal " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
|
@ -118,7 +118,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairExtendedBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ExtendedBolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedExtendedBolusesCompat()
|
||||
|
@ -127,7 +127,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedProfileSwitchesCompat()
|
||||
|
@ -136,7 +136,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairEffectiveProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitchesCompat()
|
||||
|
@ -145,7 +145,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
|
||||
is PairOfflineEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId)
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked OfflineEvent" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedOfflineEventsCompat()
|
||||
|
|
|
@ -11,11 +11,15 @@ import androidx.work.ExistingWorkPolicy
|
|||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -30,14 +34,20 @@ 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.nsclientV3.extensions.toNSBolus
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSCarbs
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSEffectiveProfileSwitch
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSProfileSwitch
|
||||
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.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.EventNewBG
|
||||
import info.nightscout.rx.events.EventNewHistoryData
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventSWSyncStatus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -54,9 +64,11 @@ import io.reactivex.rxjava3.kotlin.plusAssign
|
|||
import kotlinx.coroutines.runBlocking
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.max
|
||||
|
||||
@Singleton
|
||||
class NSClientV3Plugin @Inject constructor(
|
||||
|
@ -71,7 +83,9 @@ class NSClientV3Plugin @Inject constructor(
|
|||
private val nsClientReceiverDelegate: NsClientReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val dateUtil: DateUtil,
|
||||
private val uiInteraction: UiInteraction
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val storeDataForDb: StoreDataForDb,
|
||||
private val dataSyncSelector: DataSyncSelector
|
||||
) : NsClient, Sync, PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.SYNC)
|
||||
|
@ -99,48 +113,33 @@ class NSClientV3Plugin @Inject constructor(
|
|||
when {
|
||||
sp.getBoolean(R.string.key_ns_client_paused, false) -> rh.gs(info.nightscout.core.ui.R.string.paused)
|
||||
isAllowed.not() -> blockingReason
|
||||
nsAndroidClient.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||
nsAndroidClient?.lastStatus == null -> rh.gs(R.string.not_connected)
|
||||
workIsRunning(arrayOf(JOB_NAME)) -> rh.gs(R.string.working)
|
||||
nsAndroidClient.lastStatus?.apiPermissions?.isFull() == true -> rh.gs(info.nightscout.shared.R.string.connected)
|
||||
nsAndroidClient.lastStatus?.apiPermissions?.isRead() == true -> rh.gs(R.string.read_only)
|
||||
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)
|
||||
}
|
||||
|
||||
internal lateinit var nsAndroidClient: NSAndroidClient
|
||||
// private lateinit var nsAndroidRxClient: NSAndroidRxClient
|
||||
internal var nsAndroidClient: NSAndroidClient? = null
|
||||
|
||||
val isAllowed get() = nsClientReceiverDelegate.allowed
|
||||
val blockingReason get() = nsClientReceiverDelegate.blockingReason
|
||||
private val isAllowed get() = nsClientReceiverDelegate.allowed
|
||||
private val blockingReason get() = nsClientReceiverDelegate.blockingReason
|
||||
|
||||
private val maxAge = T.days(77).msecs()
|
||||
internal var lastModified: LastModified? = null // timestamp of last modification for every collection
|
||||
internal var lastFetched =
|
||||
LastModified(
|
||||
LastModified.Collections(
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge
|
||||
)
|
||||
) // timestamp of last fetched data for every collection
|
||||
val maxAge = T.days(77).msecs()
|
||||
internal var newestDataOnServer: LastModified? = null // timestamp of last modification for every collection provided by server
|
||||
internal var lastLoadedSrvModified = LastModified(LastModified.Collections()) // max srvLastModified timestamp of last fetched data for every collection
|
||||
internal var firstLoadContinueTimestamp = LastModified(LastModified.Collections()) // timestamp of last fetched data for every collection during initial load
|
||||
|
||||
override fun onStart() {
|
||||
// context.bindService(Intent(context, NSClientService::class.java), mConnection, Context.BIND_AUTO_CREATE)
|
||||
super.onStart()
|
||||
|
||||
lastFetched = Json.decodeFromString(
|
||||
lastLoadedSrvModified = Json.decodeFromString(
|
||||
sp.getString(
|
||||
R.string.key_ns_client_v3_last_modified,
|
||||
Json.encodeToString(
|
||||
LastModified.serializer(),
|
||||
LastModified(LastModified.Collections(dateUtil.now() - maxAge, dateUtil.now() - maxAge, dateUtil.now() - maxAge, dateUtil.now() - maxAge))
|
||||
)
|
||||
Json.encodeToString(LastModified.serializer(), LastModified(LastModified.Collections()))
|
||||
)
|
||||
)
|
||||
lastFetched.collections.entries = max(dateUtil.now() - maxAge, lastFetched.collections.entries)
|
||||
lastFetched.collections.treatments = max(dateUtil.now() - maxAge, lastFetched.collections.treatments)
|
||||
lastFetched.collections.profile = max(dateUtil.now() - maxAge, lastFetched.collections.profile)
|
||||
lastFetched.collections.devicestatus = max(dateUtil.now() - maxAge, lastFetched.collections.devicestatus)
|
||||
|
||||
setClient()
|
||||
|
||||
|
@ -160,10 +159,10 @@ class NSClientV3Plugin @Inject constructor(
|
|||
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()
|
||||
}, fabricPrivacy::logException)
|
||||
// disposable += rxBus
|
||||
// .toObservable(EventAppExit::class.java)
|
||||
// .observeOn(aapsSchedulers.io)
|
||||
// .subscribe({ if (nsClientService != null) context.unbindService(mConnection) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ WorkManager.getInstance(context).cancelUniqueWork(JOB_NAME) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientNewLog::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -179,10 +178,18 @@ class NSClientV3Plugin @Inject constructor(
|
|||
.toObservable(EventNSClientResend::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event -> resend(event.reason) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewBG::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ scheduleExecution() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewHistoryData::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ scheduleExecution() }, fabricPrivacy::logException)
|
||||
|
||||
runLoop = Runnable {
|
||||
executeLoop()
|
||||
handler.postDelayed(runLoop, REFRESH_INTERVAL)
|
||||
executeLoop()
|
||||
}
|
||||
handler.postDelayed(runLoop, REFRESH_INTERVAL)
|
||||
executeLoop()
|
||||
|
@ -206,9 +213,8 @@ class NSClientV3Plugin @Inject constructor(
|
|||
preferenceFragment.findPreference<SwitchPreference>(rh.gs(R.string.key_ns_receive_tbr_eb))?.isVisible = config.isEngineeringMode()
|
||||
}
|
||||
|
||||
override val hasWritePermission: Boolean get() = nsAndroidClient.lastStatus?.apiPermissions?.isFull() ?: false
|
||||
override val connected: Boolean get() = nsAndroidClient.lastStatus != null
|
||||
|
||||
override val hasWritePermission: Boolean get() = nsAndroidClient?.lastStatus?.apiPermissions?.isFull() ?: false
|
||||
override val connected: Boolean get() = nsAndroidClient?.lastStatus != null
|
||||
override fun clearLog() {
|
||||
handler.post {
|
||||
synchronized(listLog) { listLog.clear() }
|
||||
|
@ -251,7 +257,7 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun resend(reason: String) {
|
||||
// nsClientService?.resend(reason)
|
||||
executeLoop()
|
||||
}
|
||||
|
||||
override fun pause(newState: Boolean) {
|
||||
|
@ -277,34 +283,45 @@ class NSClientV3Plugin @Inject constructor(
|
|||
// })
|
||||
}
|
||||
|
||||
override fun updateLatestBgReceivedIfNewer(latestReceived: Long) {
|
||||
if (latestReceived > lastFetched.collections.entries) {
|
||||
lastFetched.collections.entries = latestReceived
|
||||
storeLastFetched()
|
||||
override fun isFirstLoad(collection: NsClient.Collection) =
|
||||
when (collection) {
|
||||
NsClient.Collection.ENTRIES -> lastLoadedSrvModified.collections.entries == 0L
|
||||
NsClient.Collection.TREATMENTS -> lastLoadedSrvModified.collections.treatments == 0L
|
||||
}
|
||||
|
||||
override fun updateLatestBgReceivedIfNewer(latestReceived: Long) {
|
||||
if (isFirstLoad(NsClient.Collection.ENTRIES)) firstLoadContinueTimestamp.collections.entries = latestReceived
|
||||
}
|
||||
|
||||
override fun updateLatestTreatmentReceivedIfNewer(latestReceived: Long) {
|
||||
lastFetched.collections.treatments = latestReceived
|
||||
storeLastFetched()
|
||||
if (isFirstLoad(NsClient.Collection.TREATMENTS)) firstLoadContinueTimestamp.collections.treatments = latestReceived
|
||||
}
|
||||
|
||||
override fun resetToFullSync() {
|
||||
lastFetched = LastModified(
|
||||
LastModified.Collections(
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge,
|
||||
dateUtil.now() - maxAge
|
||||
)
|
||||
)
|
||||
firstLoadContinueTimestamp = LastModified(LastModified.Collections())
|
||||
lastLoadedSrvModified = LastModified(LastModified.Collections())
|
||||
storeLastFetched()
|
||||
}
|
||||
|
||||
override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
dbOperation(collection, dataPair, progress, Operation.CREATE)
|
||||
}
|
||||
|
||||
override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
dbOperation(collection, dataPair, progress, Operation.UPDATE)
|
||||
}
|
||||
|
||||
enum class Operation { CREATE, UPDATE }
|
||||
|
||||
private val gson: Gson = GsonBuilder().create()
|
||||
private fun dbOperation(collection: String, dataPair: DataSyncSelector.DataPair, progress: String, operation: Operation) {
|
||||
val call = when (operation) {
|
||||
Operation.CREATE -> nsAndroidClient?.let { return@let it::createTreatment }
|
||||
Operation.UPDATE -> nsAndroidClient?.let { return@let it::updateTreatment }
|
||||
}
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.toNSBolus()
|
||||
// is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil)
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.toNSBolus()
|
||||
is DataSyncSelector.PairCarbs -> dataPair.value.toNSCarbs()
|
||||
// is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction)
|
||||
// is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil)
|
||||
// is DataSyncSelector.PairFood -> dataPair.value.toJson(false)
|
||||
|
@ -312,25 +329,82 @@ class NSClientV3Plugin @Inject constructor(
|
|||
// is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil)
|
||||
// is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil)
|
||||
// is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil)
|
||||
// is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil)
|
||||
// is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil)
|
||||
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toNSProfileSwitch(dateUtil)
|
||||
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toNSEffectiveProfileSwitch(dateUtil)
|
||||
// is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil)
|
||||
else -> null
|
||||
else -> null
|
||||
}?.let { data ->
|
||||
runBlocking {
|
||||
if (collection == "treatments") {
|
||||
val result = nsAndroidClient.createTreatment(data)
|
||||
try {
|
||||
val id = if (dataPair.value is TraceableDBEntry) (dataPair.value as TraceableDBEntry).interfaceIDs.nightscoutId else ""
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
when (operation) {
|
||||
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"
|
||||
}
|
||||
)
|
||||
)
|
||||
call?.let { it(data) }?.let { result ->
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdBoluses.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(dataPair.id)
|
||||
}
|
||||
is DataSyncSelector.PairCarbs -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdCarbs.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(dataPair.id)
|
||||
}
|
||||
// is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction)
|
||||
// is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil)
|
||||
// is DataSyncSelector.PairFood -> dataPair.value.toJson(false)
|
||||
// is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil)
|
||||
// is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil)
|
||||
// is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil)
|
||||
// is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profileFunction.getProfile(dataPair.value.timestamp), dateUtil)
|
||||
is DataSyncSelector.PairProfileSwitch -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdProfileSwitches.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(dataPair.id)
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairEffectiveProfileSwitch -> {
|
||||
if (result.response == 201) { // created
|
||||
dataPair.value.interfaceIDs.nightscoutId = result.identifier
|
||||
storeDataForDb.nsIdEffectiveProfileSwitches.add(dataPair.value)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
}
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(dataPair.id)
|
||||
}
|
||||
// is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error(LTag.NSCLIENT, "Upload exception", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun storeLastFetched() {
|
||||
sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastFetched))
|
||||
fun storeLastFetched() {
|
||||
sp.putString(R.string.key_ns_client_v3_last_modified, Json.encodeToString(LastModified.serializer(), lastLoadedSrvModified))
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
@ -338,20 +412,19 @@ class NSClientV3Plugin @Inject constructor(
|
|||
}
|
||||
|
||||
fun scheduleNewExecution() {
|
||||
val toTime = lastFetched.collections.entries + T.mins(6).plus(T.secs(0)).msecs()
|
||||
if (toTime > dateUtil.now()) {
|
||||
handler.postDelayed({ executeLoop() }, toTime - dateUtil.now())
|
||||
rxBus.send(EventNSClientNewLog("NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
|
||||
}
|
||||
var toTime = lastLoadedSrvModified.collections.entries + T.mins(6).plus(T.secs(0)).msecs()
|
||||
if (toTime < dateUtil.now()) toTime = dateUtil.now() + T.mins(1).plus(T.secs(0)).msecs()
|
||||
handler.postDelayed({ executeLoop() }, toTime - dateUtil.now())
|
||||
rxBus.send(EventNSClientNewLog("NEXT", dateUtil.dateAndTimeAndSecondsString(toTime)))
|
||||
}
|
||||
|
||||
private fun executeLoop() {
|
||||
if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientNewLog("RUN", "paused"))
|
||||
return
|
||||
}
|
||||
if (!isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", blockingReason))
|
||||
rxBus.send(EventNSClientNewLog("RUN", blockingReason))
|
||||
return
|
||||
}
|
||||
if (workIsRunning(arrayOf(JOB_NAME)))
|
||||
|
@ -366,8 +439,10 @@ class NSClientV3Plugin @Inject constructor(
|
|||
)
|
||||
.then(OneTimeWorkRequest.Builder(LoadLastModificationWorker::class.java).build())
|
||||
.then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build())
|
||||
// LoadTreatmentsWorker is enqueued after BG finish
|
||||
//.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
// Other Workers are enqueued after BG finish
|
||||
// LoadTreatmentsWorker
|
||||
// LoadDeviceStatusWorker
|
||||
// DataSyncWorker
|
||||
.enqueue()
|
||||
}
|
||||
}
|
||||
|
@ -379,4 +454,20 @@ class NSClientV3Plugin @Inject constructor(
|
|||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||
private var scheduledEventPost: ScheduledFuture<*>? = null
|
||||
private fun scheduleExecution() {
|
||||
class PostRunnable : Runnable {
|
||||
|
||||
override fun run() {
|
||||
scheduledEventPost = null
|
||||
executeLoop()
|
||||
}
|
||||
}
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
scheduledEventPost?.cancel(false)
|
||||
val task: Runnable = PostRunnable()
|
||||
scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.extensions
|
||||
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import info.nightscout.sdk.localmodel.treatment.NSCarbs
|
||||
|
||||
fun NSCarbs.toCarbs(): Carbs =
|
||||
|
@ -11,6 +13,22 @@ fun NSCarbs.toCarbs(): Carbs =
|
|||
utcOffset = utcOffset,
|
||||
amount = carbs,
|
||||
notes = notes,
|
||||
duration = duration,
|
||||
duration = duration ?: 0L,
|
||||
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
|
||||
)
|
||||
|
||||
fun Carbs.toNSCarbs(): NSCarbs =
|
||||
NSCarbs(
|
||||
eventType = EventType.fromString(if (amount < 12) TherapyEvent.Type.CARBS_CORRECTION.text else TherapyEvent.Type.MEAL_BOLUS.text),
|
||||
isValid = isValid,
|
||||
date = timestamp,
|
||||
utcOffset = utcOffset,
|
||||
carbs = amount,
|
||||
notes = notes,
|
||||
duration = if (duration != 0L) duration else null,
|
||||
identifier = interfaceIDs.nightscoutId,
|
||||
pumpId = interfaceIDs.pumpId,
|
||||
pumpType = interfaceIDs.pumpType?.name,
|
||||
pumpSerial = interfaceIDs.pumpSerial,
|
||||
endId = interfaceIDs.endId
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ import info.nightscout.core.profile.ProfileSealed
|
|||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.plugins.sync.nsclient.extensions.fromConstant
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import info.nightscout.sdk.localmodel.treatment.NSEffectiveProfileSwitch
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
|
||||
|
@ -30,4 +31,25 @@ fun NSEffectiveProfileSwitch.toEffectiveProfileSwitch(dateUtil: DateUtil): Effec
|
|||
insulinConfiguration = profileSealed.insulinConfiguration,
|
||||
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun EffectiveProfileSwitch.toNSEffectiveProfileSwitch(dateUtil: DateUtil) : NSEffectiveProfileSwitch =
|
||||
NSEffectiveProfileSwitch(
|
||||
eventType = EventType.NOTE,
|
||||
isValid = isValid,
|
||||
date = timestamp,
|
||||
utcOffset = utcOffset,
|
||||
profileJson = ProfileSealed.EPS(this).toPureNsJson(dateUtil),
|
||||
originalProfileName = originalProfileName,
|
||||
originalCustomizedName = originalCustomizedName,
|
||||
originalTimeshift = originalTimeshift,
|
||||
originalPercentage = originalPercentage,
|
||||
originalDuration = originalDuration,
|
||||
originalEnd = originalEnd,
|
||||
notes = originalCustomizedName,
|
||||
identifier = interfaceIDs.nightscoutId,
|
||||
pumpId = interfaceIDs.pumpId,
|
||||
pumpType = interfaceIDs.pumpType?.name,
|
||||
pumpSerial = interfaceIDs.pumpSerial,
|
||||
endId = interfaceIDs.endId
|
||||
)
|
|
@ -1,11 +1,14 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.extensions
|
||||
|
||||
import info.nightscout.core.extensions.fromConstant
|
||||
import info.nightscout.core.extensions.getCustomizedName
|
||||
import info.nightscout.core.extensions.pureProfileFromJson
|
||||
import info.nightscout.core.profile.ProfileSealed
|
||||
import info.nightscout.database.entities.ProfileSwitch
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
|
@ -13,7 +16,7 @@ import info.nightscout.shared.utils.T
|
|||
fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUtil): ProfileSwitch? {
|
||||
val pureProfile =
|
||||
profileJson?.let { pureProfileFromJson(it, dateUtil) ?: return null }
|
||||
?: activePlugin.activeProfileSource.profile?.getSpecificProfile(profileName) ?: return null
|
||||
?: activePlugin.activeProfileSource.profile?.getSpecificProfile(profile) ?: return null
|
||||
|
||||
val profileSealed = ProfileSealed.Pure(pureProfile)
|
||||
|
||||
|
@ -26,11 +29,39 @@ fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUt
|
|||
icBlocks = profileSealed.icBlocks,
|
||||
targetBlocks = profileSealed.targetBlocks,
|
||||
glucoseUnit = ProfileSwitch.GlucoseUnit.fromConstant(profileSealed.units),
|
||||
profileName = originalProfileName ?: profileName,
|
||||
profileName = originalProfileName ?: profile,
|
||||
timeshift = timeShift ?: 0,
|
||||
percentage = percentage ?: 100,
|
||||
duration = originalDuration ?: T.mins(duration ?: 0).msecs(),
|
||||
insulinConfiguration = profileSealed.insulinConfiguration,
|
||||
interfaceIDs_backing = InterfaceIDs(nightscoutId = identifier, pumpId = pumpId, pumpType = InterfaceIDs.PumpType.fromString(pumpType), pumpSerial = pumpSerial, endId = endId)
|
||||
)
|
||||
}
|
||||
|
||||
fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil): NSProfileSwitch {
|
||||
val unmodifiedCustomizedName = getCustomizedName()
|
||||
// ProfileSealed.PS doesn't provide unmodified json -> reset it
|
||||
val unmodifiedTimeshift = timeshift
|
||||
val unmodifiedPercentage = percentage
|
||||
timeshift = 0
|
||||
percentage = 100
|
||||
|
||||
return NSProfileSwitch(
|
||||
eventType = EventType.fromString(TherapyEvent.Type.PROFILE_SWITCH.text),
|
||||
isValid = isValid,
|
||||
date = timestamp,
|
||||
utcOffset = utcOffset,
|
||||
timeShift = unmodifiedTimeshift,
|
||||
percentage = unmodifiedPercentage,
|
||||
duration = T.mins(duration).msecs(),
|
||||
profile = unmodifiedCustomizedName,
|
||||
originalProfileName = profileName,
|
||||
originalDuration = duration,
|
||||
profileJson = ProfileSealed.PS(this).toPureNsJson(dateUtil),
|
||||
identifier = interfaceIDs.nightscoutId,
|
||||
pumpId = interfaceIDs.pumpId,
|
||||
pumpType = interfaceIDs.pumpType?.name,
|
||||
pumpSerial = interfaceIDs.pumpSerial,
|
||||
endId = interfaceIDs.endId
|
||||
)
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.workers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkerParameters
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import javax.inject.Inject
|
||||
|
||||
class DataSyncWorker(
|
||||
context: Context, params: WorkerParameters
|
||||
) : LoggingWorker(context, params) {
|
||||
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
if (activePlugin.activeNsClient?.hasWritePermission == true) dataSyncSelector.doUpload()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
|
@ -8,15 +8,19 @@ import androidx.work.WorkerParameters
|
|||
import androidx.work.workDataOf
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
|
||||
class LoadBgWorker(
|
||||
context: Context, params: WorkerParameters
|
||||
|
@ -36,21 +40,28 @@ class LoadBgWorker(
|
|||
}
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var ret = Result.success()
|
||||
|
||||
val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.ENTRIES)
|
||||
val lastLoaded =
|
||||
if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
else max(nsClientV3Plugin.lastLoadedSrvModified.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
runBlocking {
|
||||
if ((nsClientV3Plugin.lastModified?.collections?.entries ?: Long.MAX_VALUE) > nsClientV3Plugin.lastFetched.collections.entries)
|
||||
if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > lastLoaded)
|
||||
try {
|
||||
//val sgvs = nsClientV3Plugin.nsAndroidClient.getSgvsModifiedSince(nsClientV3Plugin.lastFetched.collections.entries)
|
||||
val sgvs = nsClientV3Plugin.nsAndroidClient.getSgvsNewerThan(nsClientV3Plugin.lastFetched.collections.entries, 500)
|
||||
val sgvs: List<NSSgvV3>
|
||||
val response: NSAndroidClient.ReadResponse<List<NSSgvV3>>?
|
||||
if (isFirstLoad) sgvs = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500)
|
||||
else {
|
||||
response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500)
|
||||
sgvs = response.values
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = response.lastServerModified
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
aapsLogger.debug("SGVS: $sgvs")
|
||||
if (sgvs.isNotEmpty()) {
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"RCV",
|
||||
"${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}"
|
||||
)
|
||||
)
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog(action, "${sgvs.size} SVGs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Objective0
|
||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
|
@ -60,7 +71,13 @@ class LoadBgWorker(
|
|||
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build()
|
||||
).then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()).enqueue()
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("END", "No SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}"))
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No SGVs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
NSClientV3Plugin.JOB_NAME,
|
||||
|
@ -75,7 +92,13 @@ class LoadBgWorker(
|
|||
ret = Result.failure(workDataOf("Error" to error.toString()))
|
||||
}
|
||||
else {
|
||||
rxBus.send(EventNSClientNewLog("END", "No new SGVs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.entries)}"))
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.entries = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new SGVs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
nsClientV3Plugin.scheduleNewExecution() // Idea is to run after 5 min after last BG
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3.workers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
|
@ -27,19 +30,27 @@ class LoadDeviceStatusWorker(
|
|||
@Inject lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var ret = Result.success()
|
||||
|
||||
runBlocking {
|
||||
try {
|
||||
val from = dateUtil.now() - T.mins(7).msecs()
|
||||
val deviceStatuses = nsClientV3Plugin.nsAndroidClient.getDeviceStatusModifiedSince(from)
|
||||
val deviceStatuses = nsAndroidClient.getDeviceStatusModifiedSince(from)
|
||||
aapsLogger.debug("DEVICESTATUSES: $deviceStatuses")
|
||||
if (deviceStatuses.isNotEmpty()) {
|
||||
rxBus.send(EventNSClientNewLog("RCV", "${deviceStatuses.size} DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
nsDeviceStatusHandler.handleNewData(deviceStatuses.toTypedArray())
|
||||
rxBus.send(EventNSClientNewLog("DONE DS", ""))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No DSs from ${dateUtil.dateAndTimeAndSecondsString(from)}"))
|
||||
}
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
NSClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(DataSyncWorker::class.java).build()
|
||||
)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
ret = Result.failure(workDataOf("Error" to error.toString()))
|
||||
|
|
|
@ -15,13 +15,14 @@ class LoadLastModificationWorker(
|
|||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var ret = Result.success()
|
||||
|
||||
runBlocking {
|
||||
try {
|
||||
val lm = nsClientV3Plugin.nsAndroidClient.getLastModified()
|
||||
nsClientV3Plugin.lastModified = lm
|
||||
aapsLogger.debug("LAST MODIFIED: ${nsClientV3Plugin.lastModified}")
|
||||
val lm = nsAndroidClient.getLastModified()
|
||||
nsClientV3Plugin.newestDataOnServer = lm
|
||||
aapsLogger.debug("LAST MODIFIED: ${nsClientV3Plugin.newestDataOnServer}")
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
ret = Result.failure(workDataOf("Error" to error.toString()))
|
||||
|
|
|
@ -15,11 +15,12 @@ class LoadStatusWorker(
|
|||
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var ret = Result.success()
|
||||
|
||||
runBlocking {
|
||||
try {
|
||||
val status = nsClientV3Plugin.nsAndroidClient.getStatus()
|
||||
val status = nsAndroidClient.getStatus()
|
||||
aapsLogger.debug("STATUS: $status")
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
|
|
|
@ -9,12 +9,16 @@ import androidx.work.workDataOf
|
|||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTreatment
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
|
||||
class LoadTreatmentsWorker(
|
||||
context: Context,
|
||||
|
@ -29,36 +33,50 @@ class LoadTreatmentsWorker(
|
|||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override fun doWorkAndLog(): Result {
|
||||
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
|
||||
var ret = Result.success()
|
||||
|
||||
val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.TREATMENTS)
|
||||
val lastLoaded =
|
||||
if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
else max(nsClientV3Plugin.lastLoadedSrvModified.collections.treatments, dateUtil.now() - nsClientV3Plugin.maxAge)
|
||||
runBlocking {
|
||||
if ((nsClientV3Plugin.lastModified?.collections?.treatments ?: Long.MAX_VALUE) > nsClientV3Plugin.lastFetched.collections.treatments)
|
||||
if ((nsClientV3Plugin.newestDataOnServer?.collections?.treatments ?: Long.MAX_VALUE) > lastLoaded)
|
||||
try {
|
||||
val treatments = nsClientV3Plugin.nsAndroidClient.getTreatmentsModifiedSince(nsClientV3Plugin.lastFetched.collections.treatments, 500)
|
||||
val treatments: List<NSTreatment>
|
||||
val response: NSAndroidClient.ReadResponse<List<NSTreatment>>?
|
||||
if (isFirstLoad) {
|
||||
treatments = nsAndroidClient.getTreatmentsNewerThan(lastLoaded, 500)
|
||||
response = NSAndroidClient.ReadResponse(0, treatments)
|
||||
}
|
||||
else {
|
||||
response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500)
|
||||
treatments = response.values
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = response.lastServerModified
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
aapsLogger.debug("TREATMENTS: $treatments")
|
||||
if (treatments.isNotEmpty()) {
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"RCV",
|
||||
"${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}"
|
||||
)
|
||||
)
|
||||
val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
|
||||
rxBus.send(EventNSClientNewLog(action, "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
// Schedule processing of fetched data and continue of loading
|
||||
WorkManager.getInstance(context)
|
||||
.beginUniqueWork(
|
||||
NSClientV3Plugin.JOB_NAME,
|
||||
ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(treatments))
|
||||
.setInputData(dataWorkerStorage.storeInputData(response))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
|
||||
.enqueue()
|
||||
} else {
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"END", "No TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}"
|
||||
)
|
||||
)
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No TRs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
|
@ -72,7 +90,13 @@ class LoadTreatmentsWorker(
|
|||
ret = Result.failure(workDataOf("Error" to error.toString()))
|
||||
}
|
||||
else {
|
||||
rxBus.send(EventNSClientNewLog("END", "No new TRs from ${dateUtil.dateAndTimeAndSecondsString(nsClientV3Plugin.lastFetched.collections.treatments)}"))
|
||||
// End first load
|
||||
if (isFirstLoad) {
|
||||
nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = lastLoaded
|
||||
nsClientV3Plugin.storeLastFetched()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("RCV END", "No new TRs from ${dateUtil
|
||||
.dateAndTimeAndSecondsString(lastLoaded)}"))
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
|
|
|
@ -25,6 +25,7 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toTemporaryTarget
|
|||
import info.nightscout.plugins.sync.nsclientV3.extensions.toTherapyEvent
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.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
|
||||
|
@ -58,19 +59,14 @@ class ProcessTreatmentsWorker(
|
|||
|
||||
override fun doWorkAndLog(): Result {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as List<NSTreatment>?
|
||||
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse<List<NSTreatment>>?
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
var latestDateInReceivedData: Long = 0
|
||||
val ret = Result.success()
|
||||
var latestDateInReceivedData = 0L
|
||||
|
||||
for (treatment in treatments) {
|
||||
for (treatment in treatments.values) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
|
||||
//Find latest date in treatment
|
||||
val mills = treatment.date
|
||||
if (mills != 0L && mills < dateUtil.now())
|
||||
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
|
||||
if (treatment.date > latestDateInReceivedData) latestDateInReceivedData = treatment.date
|
||||
|
||||
when (treatment) {
|
||||
is NSBolus ->
|
||||
|
|
|
@ -97,4 +97,7 @@
|
|||
<string name="remove_all">Fjern alt</string>
|
||||
<string name="reset_start">Tilbakestill til oppstart</string>
|
||||
<string name="upload_now">Last opp nå</string>
|
||||
<string name="not_connected">Ikke tilkoblet</string>
|
||||
<string name="read_only">Skrivebeskyttet</string>
|
||||
<string name="working">Prosesserer</string>
|
||||
</resources>
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
android:title="@string/connection_settings_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_cellular"
|
||||
android:title="@string/ns_cellular" />
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import info.nightscout.interfaces.pump.defs.PumpType
|
|||
import info.nightscout.interfaces.queue.CommandQueue
|
||||
import info.nightscout.interfaces.queue.CustomCommand
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.Round
|
||||
import info.nightscout.interfaces.utils.TimeChangeType
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
|
@ -44,6 +45,7 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject
|
|||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -311,10 +313,10 @@ class EopatchPumpPlugin @Inject constructor(
|
|||
|
||||
disposable.dispose()
|
||||
|
||||
return if (isSuccess && askedInsulin == detailedBolusInfo.insulin)
|
||||
PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin)
|
||||
return if (isSuccess && abs(askedInsulin - detailedBolusInfo.insulin) < pumpDescription.bolusStep)
|
||||
PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(askedInsulin)
|
||||
else
|
||||
PumpEnactResult(injector).success(false)/*.enacted(false)*/.bolusDelivered(detailedBolusInfo.insulin)
|
||||
PumpEnactResult(injector).success(false)/*.enacted(false)*/.bolusDelivered(Round.roundTo(detailedBolusInfo.insulin, 0.01))
|
||||
|
||||
} else {
|
||||
// no bolus required
|
||||
|
|
|
@ -191,7 +191,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
if (podStateManager.isSuspended) {
|
||||
showNotification(
|
||||
Notification.OMNIPOD_POD_SUSPENDED,
|
||||
"Insulin delivery suspended",
|
||||
rh.gs(R.string.insulin_delivery_suspended),
|
||||
Notification.NORMAL,
|
||||
info.nightscout.core.ui.R.raw.boluserror
|
||||
)
|
||||
|
@ -200,9 +200,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
if (!podStateManager.sameTimeZone) {
|
||||
uiInteraction.addNotification(
|
||||
Notification.OMNIPOD_TIME_OUT_OF_SYNC,
|
||||
"Timezone on pod is different from the timezone on phone. " +
|
||||
"Basal rate is incorrect" +
|
||||
"Switch profile to fix",
|
||||
rh.gs(R.string.timezone_on_pod_is_different_from_the_timezone),
|
||||
Notification.NORMAL
|
||||
)
|
||||
}
|
||||
|
@ -425,22 +423,21 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
if (deliverySuspended) {
|
||||
showNotification(
|
||||
Notification.FAILED_UPDATE_PROFILE,
|
||||
"Failed to set the new basal profile. Delivery suspended",
|
||||
rh.gs(R.string.failed_to_set_the_new_basal_profile),
|
||||
Notification.URGENT,
|
||||
info.nightscout.core.ui.R.raw.boluserror
|
||||
)
|
||||
} else {
|
||||
showNotification(
|
||||
Notification.FAILED_UPDATE_PROFILE,
|
||||
"Setting basal profile might have failed. Delivery might be suspended!" +
|
||||
" Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.",
|
||||
rh.gs(R.string.setting_basal_profile_might_have_failed),
|
||||
Notification.URGENT,
|
||||
info.nightscout.core.ui.R.raw.boluserror
|
||||
)
|
||||
}
|
||||
Completable.error(java.lang.IllegalStateException("Command not confirmed"))
|
||||
} else {
|
||||
showNotification(Notification.PROFILE_SET_OK, "Profile set OK", Notification.INFO, null)
|
||||
showNotification(Notification.PROFILE_SET_OK, rh.gs(R.string.profile_set_ok), Notification.INFO, null)
|
||||
|
||||
Completable.complete()
|
||||
}
|
||||
|
@ -466,8 +463,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.FAILED_UPDATE_PROFILE,
|
||||
"Suspend delivery is unconfirmed! " +
|
||||
"Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.",
|
||||
rh.gs(R.string.suspend_delivery_is_unconfirmed),
|
||||
info.nightscout.core.ui.R.raw.boluserror,
|
||||
)
|
||||
}
|
||||
|
@ -644,7 +640,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
) info.nightscout.core.ui.R.raw.boluserror
|
||||
else 0
|
||||
|
||||
showErrorDialog("Bolus delivery status uncertain. Refresh pod status to confirm or deny.", sound)
|
||||
showErrorDialog(rh.gs(R.string.bolus_delivery_status_uncertain), sound)
|
||||
}
|
||||
}
|
||||
}.toSingle {
|
||||
|
@ -724,7 +720,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
for (tryNumber in 1..BOLUS_RETRIES) {
|
||||
updateBolusProgressDialog("Checking delivery status", 100)
|
||||
updateBolusProgressDialog(rh.gs(R.string.checking_delivery_status), 100)
|
||||
|
||||
val cmd = if (bolusCanceled)
|
||||
cancelBolus()
|
||||
|
@ -856,8 +852,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.OMNIPOD_TBR_ALERTS,
|
||||
"Setting temp basal might have basal failed. If a temp basal was previously running, " +
|
||||
"it has been cancelled. Please manually refresh the Pod status from the Omnipod tab.",
|
||||
rh.gs(R.string.setting_temp_basal_might_have_basal_failed),
|
||||
info.nightscout.core.ui.R.raw.boluserror,
|
||||
)
|
||||
}.toPumpEnactResultImpl()
|
||||
|
@ -917,9 +912,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.OMNIPOD_TBR_ALERTS,
|
||||
"Cancelling temp basal might have failed." +
|
||||
"If a temp basal was previously running, it might have been cancelled." +
|
||||
"Please manually refresh the Pod status from the Omnipod tab.", // TODO: i8n
|
||||
rh.gs(R.string.cancelling_temp_basal_might_have_failed),
|
||||
info.nightscout.core.ui.R.raw.boluserror,
|
||||
)
|
||||
}
|
||||
|
@ -967,7 +960,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
).doOnComplete {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.OMNIPOD_TBR_ALERTS,
|
||||
"Cancel temp basal result is uncertain", // TODO: i8n,
|
||||
rh.gs(R.string.cancel_temp_basal_result_is_uncertain),
|
||||
info.nightscout.core.ui.R.raw.boluserror, // TODO: add setting for this
|
||||
)
|
||||
}.toPumpEnactResultImpl()
|
||||
|
@ -1188,7 +1181,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
).doFinally {
|
||||
notifyOnUnconfirmed(
|
||||
Notification.FAILED_UPDATE_PROFILE,
|
||||
"Unconfirmed resumeDelivery command. Please refresh pod status",
|
||||
rh.gs(R.string.unconfirmed_resumedelivery_command_please_refresh_pod_status),
|
||||
info.nightscout.core.ui.R.raw.boluserror
|
||||
)
|
||||
}.toPumpEnactResultImpl()
|
||||
|
|
|
@ -53,5 +53,17 @@
|
|||
|
||||
<string name="unconfirmed_command" comment="26 characters max for translation">Unconfirmed command</string>
|
||||
<string name="requested_by_user" comment="26 characters max for translation">Requested by user</string>
|
||||
<string name="profile_set_ok">Profile set OK</string>
|
||||
<string name="suspend_delivery_is_unconfirmed">Suspend delivery is unconfirmed! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
|
||||
<string name="insulin_delivery_suspended">Insulin delivery suspended</string>
|
||||
<string name="timezone_on_pod_is_different_from_the_timezone">Timezone on pod is different from the timezone on phone. Basal rate is incorrect. Switch profile to fix</string>
|
||||
<string name="failed_to_set_the_new_basal_profile">Failed to set the new basal profile. Delivery suspended</string>
|
||||
<string name="setting_basal_profile_might_have_failed">Setting basal profile might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
|
||||
<string name="bolus_delivery_status_uncertain">Bolus delivery status uncertain. Refresh pod status to confirm or deny.</string>
|
||||
<string name="checking_delivery_status">Checking delivery status</string>
|
||||
<string name="setting_temp_basal_might_have_basal_failed">Setting temp basal might have basal failed. If a temp basal was previously running, it has been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
|
||||
<string name="cancel_temp_basal_result_is_uncertain">Cancel temp basal result is uncertain</string>
|
||||
<string name="unconfirmed_resumedelivery_command_please_refresh_pod_status">Unconfirmed resumeDelivery command. Please refresh pod status</string>
|
||||
<string name="cancelling_temp_basal_might_have_failed">Cancelling temp basal might have failed. If a temp basal was previously running, it might have been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -12,6 +12,7 @@ import info.nightscout.core.utils.fabric.InstanceId
|
|||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
|
@ -62,7 +63,8 @@ open class VirtualPumpPlugin @Inject constructor(
|
|||
commandQueue: CommandQueue,
|
||||
private val pumpSync: PumpSync,
|
||||
private val config: Config,
|
||||
private val dateUtil: DateUtil
|
||||
private val dateUtil: DateUtil,
|
||||
private val processedDeviceStatusData: ProcessedDeviceStatusData
|
||||
) : PumpPluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.PUMP)
|
||||
|
@ -169,7 +171,9 @@ open class VirtualPumpPlugin @Inject constructor(
|
|||
get() = profileFunction.getProfile()?.getBasal() ?: 0.0
|
||||
|
||||
override val reservoirLevel: Double
|
||||
get() = reservoirInUnits.toDouble()
|
||||
get() =
|
||||
if (config.NSCLIENT) processedDeviceStatusData.pumpData?.reservoir ?: -1.0
|
||||
else reservoirInUnits.toDouble()
|
||||
|
||||
override val batteryLevel: Int
|
||||
get() = batteryPercent
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- VirtualPump -->
|
||||
<string name="virtual_pump_type">Virtuell pumpe</string>
|
||||
<string name="virtual_pump_definition">Pumpedefinisjon</string>
|
||||
<string name="virtual_pump_pump_def">Bolus: Step=%1$s\nForlenget bolus: [Step=%2$s, Varighet=%3$smin-%4$sh]\nBasal: Step=%5$s\nTBR: %6$s (av %7$s), Varighet=%8$smin-%9$sh\n%10$s</string>
|
||||
<string name="virtual_pump_shortname">VPUMP</string>
|
||||
|
|
|
@ -5,6 +5,7 @@ import info.nightscout.androidaps.TestBase
|
|||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.pump.defs.PumpType
|
||||
|
@ -31,12 +32,17 @@ class VirtualPumpPluginUTest : TestBase() {
|
|||
@Mock lateinit var dateUtil: DateUtil
|
||||
@Mock lateinit var pumpSync: PumpSync
|
||||
@Mock lateinit var config: Config
|
||||
@Mock lateinit var processedDeviceStatusData: ProcessedDeviceStatusData
|
||||
|
||||
private lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
||||
|
||||
@BeforeEach
|
||||
fun prepareMocks() {
|
||||
virtualPumpPlugin = VirtualPumpPlugin({ AndroidInjector { } }, aapsLogger, rxBus, fabricPrivacy, rh, aapsSchedulers, sp, profileFunction, iobCobCalculator, commandQueue, pumpSync, config, dateUtil)
|
||||
virtualPumpPlugin = VirtualPumpPlugin(
|
||||
{ AndroidInjector { } },
|
||||
aapsLogger, rxBus, fabricPrivacy, rh, aapsSchedulers, sp, profileFunction, iobCobCalculator,
|
||||
commandQueue, pumpSync, config, dateUtil, processedDeviceStatusData
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -72,7 +72,9 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
validateInputs()
|
||||
_binding?.let {
|
||||
validateInputs()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
|
|
@ -80,7 +80,9 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
validateInputs()
|
||||
_binding?.let {
|
||||
validateInputs()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
|
|
@ -21,6 +21,7 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction
|
||||
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
||||
import info.nightscout.interfaces.ConfigBuilder
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.aps.Loop
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
|
@ -161,7 +162,7 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(Constraint(true))
|
||||
val closedLoopAllowed2 = activePlugin.activeObjectives?.isAccomplished(Objectives.MAXIOB_OBJECTIVE) ?: false
|
||||
val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true))
|
||||
val apsMode = sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")
|
||||
val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||
val pump = activePlugin.activePump
|
||||
|
||||
binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility()
|
||||
|
@ -210,27 +211,27 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
else -> {
|
||||
binding.overviewLoop.visibility = View.VISIBLE
|
||||
binding.overviewEnable.visibility = View.GONE
|
||||
when {
|
||||
apsMode == "closed" -> {
|
||||
when (apsMode) {
|
||||
ApsMode.CLOSED -> {
|
||||
binding.overviewCloseloop.visibility = View.GONE
|
||||
binding.overviewLgsloop.visibility = View.VISIBLE
|
||||
binding.overviewOpenloop.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
apsMode == "lgs" -> {
|
||||
ApsMode.LGS -> {
|
||||
binding.overviewCloseloop.visibility = closedLoopAllowed.value().toVisibility() //show Close loop button only if Close loop allowed
|
||||
binding.overviewLgsloop.visibility = View.GONE
|
||||
binding.overviewOpenloop.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
apsMode == "open" -> {
|
||||
ApsMode.OPEN -> {
|
||||
binding.overviewCloseloop.visibility =
|
||||
closedLoopAllowed2.toVisibility() //show CloseLoop button only if Objective 6 is completed (closedLoopAllowed always false in open loop mode)
|
||||
binding.overviewLgsloop.visibility = lgsEnabled.value().toVisibility()
|
||||
binding.overviewOpenloop.visibility = View.GONE
|
||||
}
|
||||
|
||||
else -> {
|
||||
else -> {
|
||||
binding.overviewCloseloop.visibility = View.GONE
|
||||
binding.overviewLgsloop.visibility = View.GONE
|
||||
binding.overviewOpenloop.visibility = View.GONE
|
||||
|
@ -282,21 +283,21 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
when (v.id) {
|
||||
R.id.overview_closeloop -> {
|
||||
uel.log(UserEntry.Action.CLOSED_LOOP_MODE, UserEntry.Sources.LoopDialog)
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, "closed")
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.CLOSED.name)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(info.nightscout.core.ui.R.string.closedloop)))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_lgsloop -> {
|
||||
uel.log(UserEntry.Action.LGS_LOOP_MODE, UserEntry.Sources.LoopDialog)
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, "lgs")
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.LGS.name)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_openloop -> {
|
||||
uel.log(UserEntry.Action.OPEN_LOOP_MODE, UserEntry.Sources.LoopDialog)
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, "open")
|
||||
sp.putString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)))
|
||||
return true
|
||||
}
|
||||
|
@ -449,7 +450,7 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if(!queryingProtection) {
|
||||
if (!queryingProtection) {
|
||||
queryingProtection = true
|
||||
activity?.let { activity ->
|
||||
val cancelFail = {
|
||||
|
|
|
@ -65,9 +65,11 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
|
|||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val isDuration = binding.duration.value > 0
|
||||
val isLowerPercentage = binding.percentage.value < 100
|
||||
binding.ttLayout.visibility = (isDuration && isLowerPercentage).toVisibility()
|
||||
_binding?.let { binding ->
|
||||
val isDuration = binding.duration.value > 0
|
||||
val isLowerPercentage = binding.percentage.value < 100
|
||||
binding.ttLayout.visibility = (isDuration && isLowerPercentage).toVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue