commit
2c71401418
143 changed files with 4090 additions and 2640 deletions
|
@ -4,6 +4,8 @@
|
|||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<JetCodeStyleSettings>
|
||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
|
|
|
@ -15,7 +15,6 @@ class EventNSClientNewLog(val action: String, val logText: String?) : Event() {
|
|||
stringBuilder.append(action)
|
||||
stringBuilder.append("</b> ")
|
||||
stringBuilder.append(logText)
|
||||
stringBuilder.append("<br>")
|
||||
return stringBuilder
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.rx.events
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class EventXdripNewLog(val action: String, val logText: String?) : Event() {
|
||||
var date = System.currentTimeMillis()
|
||||
|
||||
private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
|
||||
|
||||
fun toPreparedHtml(): StringBuilder {
|
||||
val stringBuilder = StringBuilder()
|
||||
stringBuilder.append(timeFormat.format(date))
|
||||
stringBuilder.append(" <b>")
|
||||
stringBuilder.append(action)
|
||||
stringBuilder.append("</b> ")
|
||||
stringBuilder.append(logText)
|
||||
stringBuilder.append("<br>")
|
||||
return stringBuilder
|
||||
}
|
||||
}
|
|
@ -28,5 +28,6 @@ enum class LTag(val tag: String, val defaultValue : Boolean = true, val requires
|
|||
UI("UI", defaultValue = false),
|
||||
WEAR("WEAR"),
|
||||
WIDGET("WIDGET"),
|
||||
WORKER("WORKER")
|
||||
WORKER("WORKER"),
|
||||
XDRIP("XDRIP")
|
||||
}
|
|
@ -111,7 +111,7 @@ android {
|
|||
defaultConfig {
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "3.1.0.3-dev-g"
|
||||
version "3.1.0.3-dev-h"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||
|
|
|
@ -34,14 +34,14 @@ open class AppModule {
|
|||
@PluginsListModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>
|
||||
//@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>
|
||||
)
|
||||
: List<@JvmSuppressWildcards PluginBase> {
|
||||
val plugins = allConfigs.toMutableMap()
|
||||
if (config.PUMPDRIVERS) plugins += pumpDrivers.get()
|
||||
if (config.APS) plugins += aps.get()
|
||||
if (!config.NSCLIENT) plugins += notNsClient.get()
|
||||
if (config.isUnfinishedMode()) plugins += unfinished.get()
|
||||
//if (config.isUnfinishedMode()) plugins += unfinished.get()
|
||||
return plugins.toList().sortedBy { it.first }.map { it.second }
|
||||
}
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@ abstract class PluginsListModule {
|
|||
abstract fun bindNSClientV3Plugin(plugin: NSClientV3Plugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@Unfinished
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
@IntKey(360)
|
||||
abstract fun bindTidepoolPlugin(plugin: TidepoolPlugin): PluginBase
|
||||
|
|
|
@ -15,7 +15,7 @@ class ConfigImpl @Inject constructor(
|
|||
fileListProvider: PrefFileListProvider
|
||||
) : Config {
|
||||
|
||||
override val SUPPORTED_NS_VERSION = 140206 // 14.2.6
|
||||
override val SUPPORTED_NS_VERSION = 150000 // 15.0.0
|
||||
override val APS = BuildConfig.FLAVOR == "full"
|
||||
override val NSCLIENT = BuildConfig.FLAVOR == "aapsclient" || BuildConfig.FLAVOR == "aapsclient2"
|
||||
override val PUMPCONTROL = BuildConfig.FLAVOR == "pumpcontrol"
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package info.nightscout.androidaps.workflow
|
||||
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
import info.nightscout.source.NSClientSourcePlugin
|
||||
import javax.inject.Inject
|
||||
|
||||
class WorkerClassesImpl @Inject constructor(): WorkerClasses{
|
||||
class WorkerClassesImpl @Inject constructor() : WorkerClasses {
|
||||
|
||||
override val nsClientSourceWorker = NSClientSourcePlugin.NSClientSourceWorker::class.java
|
||||
override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
|
||||
//override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
|
||||
}
|
|
@ -2,6 +2,7 @@ package info.nightscout.core.graph.data
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
||||
import info.nightscout.interfaces.profile.DefaultValueHelper
|
||||
|
@ -35,7 +36,7 @@ internal class InMemoryGlucoseValueDataPointTest {
|
|||
}
|
||||
@Test
|
||||
fun alphaShouldBeAddedForFilledGaps() {
|
||||
val gv = InMemoryGlucoseValue(1000, 100.0)
|
||||
val gv = InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN)
|
||||
val sut = InMemoryGlucoseValueDataPoint(gv, defaultValueHelper, profileFunction, rh)
|
||||
|
||||
var alpha = sut.color(context).ushr(24)
|
||||
|
|
|
@ -1,18 +1,6 @@
|
|||
package info.nightscout.interfaces
|
||||
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.DeviceStatus
|
||||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.ExtendedBolus
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.OfflineEvent
|
||||
import info.nightscout.database.entities.ProfileSwitch
|
||||
import info.nightscout.database.entities.TemporaryBasal
|
||||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
|
||||
/**
|
||||
* Send data to xDrip+ via Inter-app settings
|
||||
|
@ -24,64 +12,19 @@ interface XDripBroadcast {
|
|||
* Accepting must be enabled in Inter-app settings - Accept Calibrations
|
||||
*/
|
||||
fun sendCalibration(bg: Double): Boolean
|
||||
fun sendIn640gMode(glucoseValue: GlucoseValue)
|
||||
fun sendProfile(profileStoreJson: JSONObject)
|
||||
fun sendTreatments(addedOrUpdatedTreatments: JSONArray)
|
||||
fun sendSgvs(sgvs: JSONArray)
|
||||
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept Glucose
|
||||
*
|
||||
* Accepting must be enabled in Inter-app settings - Accept Glucose/Treatments
|
||||
*/
|
||||
fun send(gv: GlucoseValue)
|
||||
fun sendToXdrip(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*
|
||||
* Accepting must be enabled in Inter-app settings - Accept Glucose/Treatments
|
||||
*/
|
||||
fun send(bolus: Bolus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(carbs: Carbs)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(tt: TemporaryTarget)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(te: TherapyEvent)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(deviceStatus: DeviceStatus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(tb: TemporaryBasal)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(eb: ExtendedBolus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: ProfileSwitch)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: EffectiveProfileSwitch)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: OfflineEvent)
|
||||
fun sendToXdrip(collection: String, dataPairs: List<DataSyncSelector.DataPair>, progress:
|
||||
String)
|
||||
}
|
|
@ -47,4 +47,5 @@ interface StoreDataForDb {
|
|||
fun storeGlucoseValuesToDb()
|
||||
fun storeFoodsToDb()
|
||||
fun scheduleNsIdUpdate()
|
||||
fun updateNsIds()
|
||||
}
|
|
@ -36,5 +36,6 @@ interface ProfileSource {
|
|||
var currentProfileIndex: Int
|
||||
fun currentProfile(): SingleProfile?
|
||||
fun storeSettings(activity: FragmentActivity? = null, emptyCreated: Boolean = false)
|
||||
fun loadFromStore(store: ProfileStore)
|
||||
|
||||
}
|
|
@ -8,6 +8,8 @@ interface Intents {
|
|||
// AAPS -> Xdrip
|
||||
const val ACTION_NEW_TREATMENT = "info.nightscout.client.NEW_TREATMENT"
|
||||
const val ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE"
|
||||
const val ACTION_NEW_DEVICE_STATUS = "info.nightscout.client.NEW_DEVICESTATUS"
|
||||
const val ACTION_NEW_FOOD = "info.nightscout.client.NEW_FOOD"
|
||||
const val ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV"
|
||||
|
||||
const val EXTRA_STATUSLINE = "com.eveningoutpost.dexdrip.Extras.Statusline"
|
||||
|
|
|
@ -17,70 +17,30 @@ import org.json.JSONObject
|
|||
|
||||
interface DataSyncSelector {
|
||||
|
||||
interface 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
|
||||
|
||||
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
|
||||
|
||||
fun doUpload()
|
||||
|
||||
fun resetToNextFullSync()
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedBoluses()
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedCarbs()
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedBolusCalculatorResults()
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTempTargets()
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
|
||||
fun processChangedGlucoseValues()
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTherapyEvents()
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long)
|
||||
fun processChangedFoods()
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedDeviceStatuses()
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
|
||||
fun processChangedTemporaryBasals()
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
|
||||
fun processChangedExtendedBoluses()
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun processChangedProfileSwitches()
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun processChangedEffectiveProfileSwitches()
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||
fun processChangedOfflineEvents()
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
fun processChangedProfileStore()
|
||||
suspend fun doUpload()
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorV1 : DataSyncSelector {
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedBoluses()
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedCarbs()
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedBolusCalculatorResults()
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTempTargets()
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedGlucoseValues()
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTherapyEvents()
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedFoods()
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedDeviceStatuses()
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedTemporaryBasals()
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedExtendedBoluses()
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedProfileSwitches()
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedEffectiveProfileSwitches()
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||
suspend fun processChangedOfflineEvents()
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
suspend fun processChangedProfileStore()
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorV3 : DataSyncSelector
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
interface DataSyncSelectorXdrip : DataSyncSelector
|
|
@ -1,7 +1,7 @@
|
|||
package info.nightscout.interfaces.sync
|
||||
|
||||
import android.text.Spanned
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
|
||||
/**
|
||||
* Plugin providing communication with Nightscout server
|
||||
|
@ -24,14 +24,14 @@ interface NsClient : Sync {
|
|||
fun resend(reason: String)
|
||||
|
||||
/**
|
||||
* @return List last of messages for fragment in HTML format
|
||||
* List of log messages for fragment
|
||||
*/
|
||||
fun textLog(): Spanned
|
||||
val listLog: MutableList<EventNSClientNewLog>
|
||||
|
||||
/**
|
||||
* Clear list of stored messages displayed in fragment
|
||||
* Used data sync selector
|
||||
*/
|
||||
fun clearLog()
|
||||
val dataSyncSelector: DataSyncSelector
|
||||
|
||||
/**
|
||||
* Version of NS server
|
||||
|
@ -89,8 +89,9 @@ interface NsClient : Sync {
|
|||
* @param collection target ns collection
|
||||
* @param dataPair data to upload (data.first) and id of changed record (data.second)
|
||||
* @param progress progress of sync in format "number/number". Only for display in fragment
|
||||
* @return true for successful upload
|
||||
*/
|
||||
fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
|
||||
|
||||
/**
|
||||
* Upload updated record to NS
|
||||
|
@ -98,6 +99,7 @@ interface NsClient : Sync {
|
|||
* @param collection target ns collection
|
||||
* @param dataPair data to upload (data.first) and id of changed record (data.second)
|
||||
* @param progress progress of sync in format "number/number". Only for display in fragment
|
||||
* @return true for successful upload
|
||||
*/
|
||||
fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package info.nightscout.interfaces.workflow
|
||||
|
||||
import androidx.work.ListenableWorker
|
||||
|
||||
interface WorkerClasses {
|
||||
val nsClientSourceWorker: Class<out ListenableWorker>
|
||||
val nsProfileWorker: Class<out ListenableWorker>
|
||||
// val nsProfileWorker: Class<out ListenableWorker>
|
||||
}
|
|
@ -119,7 +119,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getSgvs()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -132,7 +136,11 @@ class NSAndroidClientImpl(
|
|||
if (response.isSuccessful) {
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = eTag, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = eTag,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -143,39 +151,37 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getSgvsNewerThan(from, limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
override suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
override suspend fun createSgv(nsSgvV3: NSSgvV3): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteEntry = nsSgvV3.toRemoteEntry()
|
||||
remoteEntry.app = "AAPS"
|
||||
val response = api.createEntry(remoteEntry)
|
||||
val responseBody = response.body()
|
||||
val errorResponse = response.errorBody()?.string()
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = responseBody?.result?.identifier,
|
||||
isDeduplication = responseBody?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = responseBody?.result?.deduplicatedIdentifier,
|
||||
lastModified = responseBody?.result?.lastModified
|
||||
identifier = responseBody?.identifier,
|
||||
isDeduplication = responseBody?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = responseBody?.deduplicatedIdentifier,
|
||||
lastModified = responseBody?.lastModified
|
||||
)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("Bad or missing utcOffset field") == true && nsSgvV3.utcOffset != 0L) {
|
||||
// Record can be originally uploaded without utcOffset
|
||||
// because utcOffset is mandatory and cannot be change, try 0
|
||||
nsSgvV3.utcOffset = 0
|
||||
return@callWrapper createSvg(nsSgvV3)
|
||||
return@callWrapper createSgv(nsSgvV3)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("cannot be modified by the client") == true) {
|
||||
// there is different field to field in AAPS
|
||||
// not possible to upload
|
||||
|
@ -234,7 +240,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getTreatmentsNewerThan(createdAt, limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -273,22 +283,13 @@ class NSAndroidClientImpl(
|
|||
nsDeviceStatus.app = "AAPS"
|
||||
val response = api.createDeviceStatus(nsDeviceStatus.toRemoteDeviceStatus())
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
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
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnknownResponseNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -307,19 +308,13 @@ class NSAndroidClientImpl(
|
|||
remoteTreatment.app = "AAPS"
|
||||
val response = api.createTreatment(remoteTreatment)
|
||||
val errorResponse = response.errorBody()?.string()
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else if (response.code() == 400 && errorResponse?.contains("Bad or missing utcOffset field") == true && nsTreatment.utcOffset != 0L) {
|
||||
// Record can be originally uploaded without utcOffset
|
||||
|
@ -384,7 +379,11 @@ class NSAndroidClientImpl(
|
|||
|
||||
val response = api.getFoods(limit)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteFood::toNSFood).toNotNull())
|
||||
return@callWrapper NSAndroidClient.ReadResponse(
|
||||
code = response.raw().networkResponse?.code ?: response.code(),
|
||||
lastServerModified = 0,
|
||||
values = response.body()?.result?.map(RemoteFood::toNSFood).toNotNull()
|
||||
)
|
||||
} else if (response.code() in 400..499)
|
||||
throw InvalidParameterNightscoutException(response.errorBody()?.string() ?: response.message())
|
||||
else
|
||||
|
@ -410,21 +409,13 @@ class NSAndroidClientImpl(
|
|||
remoteFood.app = "AAPS"
|
||||
val response = api.createFood(remoteFood)
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -474,21 +465,13 @@ class NSAndroidClientImpl(
|
|||
remoteProfileStore.put("app", "AAPS")
|
||||
val response = api.createProfile(JsonParser.parseString(remoteProfileStore.toString()).asJsonObject)
|
||||
if (response.isSuccessful) {
|
||||
if (response.code() == 200) {
|
||||
if (response.code() == 200 || response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = null,
|
||||
isDeduplication = true,
|
||||
deduplicatedIdentifier = null,
|
||||
lastModified = null
|
||||
)
|
||||
} else if (response.code() == 201) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier,
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
identifier = response.body()?.identifier,
|
||||
isDeduplication = response.body()?.isDeduplication,
|
||||
deduplicatedIdentifier = response.body()?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.lastModified
|
||||
)
|
||||
} else throw UnsuccessfullNightscoutException()
|
||||
} else if (response.code() in 400..499) {
|
||||
|
@ -514,7 +497,6 @@ class NSAndroidClientImpl(
|
|||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getProfileModifiedSince(from: Long): NSAndroidClient.ReadResponse<List<JSONObject>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getProfileModifiedSince(from)
|
||||
|
@ -528,7 +510,6 @@ class NSAndroidClientImpl(
|
|||
throw UnsuccessfullNightscoutException()
|
||||
}
|
||||
|
||||
|
||||
private suspend fun <T> callWrapper(dispatcher: CoroutineDispatcher, block: suspend () -> T): T =
|
||||
withContext(dispatcher) {
|
||||
retry(
|
||||
|
|
|
@ -25,7 +25,7 @@ interface NSAndroidClient {
|
|||
suspend fun getSgvs(): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsModifiedSince(from: Long, limit: Int): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun getSgvsNewerThan(from: Long, limit: Int): ReadResponse<List<NSSgvV3>>
|
||||
suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun createSgv(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
|
||||
|
||||
suspend fun getTreatmentsNewerThan(createdAt: String, limit: Int): ReadResponse<List<NSTreatment>>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
|
@ -8,6 +9,9 @@ import org.json.JSONObject
|
|||
fun NSDeviceStatus.convertToRemoteAndBack(): NSDeviceStatus =
|
||||
toRemoteDeviceStatus().toNSDeviceStatus()
|
||||
|
||||
fun String.toNSDeviceStatus(): NSDeviceStatus =
|
||||
Gson().fromJson(this, RemoteDeviceStatus::class.java).toNSDeviceStatus()
|
||||
|
||||
internal fun RemoteDeviceStatus.toNSDeviceStatus(): NSDeviceStatus =
|
||||
NSDeviceStatus(
|
||||
app = app,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.food.NSFood
|
||||
import info.nightscout.sdk.remotemodel.RemoteFood
|
||||
|
||||
|
@ -12,6 +13,9 @@ import info.nightscout.sdk.remotemodel.RemoteFood
|
|||
fun NSFood.convertToRemoteAndBack(): NSFood? =
|
||||
toRemoteFood().toNSFood()
|
||||
|
||||
fun String.toNSFood(): NSFood? =
|
||||
Gson().fromJson(this, RemoteFood::class.java).toNSFood()
|
||||
|
||||
internal fun RemoteFood.toNSFood(): NSFood? {
|
||||
when (type) {
|
||||
"food" ->
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.entry.Direction
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
|
@ -8,6 +9,9 @@ import info.nightscout.sdk.remotemodel.RemoteEntry
|
|||
fun NSSgvV3.convertToRemoteAndBack(): NSSgvV3? =
|
||||
toRemoteEntry().toSgv()
|
||||
|
||||
fun String.toNSSgvV3(): NSSgvV3? =
|
||||
Gson().fromJson(this, RemoteEntry::class.java).toSgv()
|
||||
|
||||
internal fun RemoteEntry.toSgv(): NSSgvV3? {
|
||||
|
||||
this.sgv ?: return null
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.sdk.mapper
|
||||
|
||||
import com.google.gson.Gson
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import info.nightscout.sdk.localmodel.treatment.NSBolus
|
||||
|
@ -26,6 +27,9 @@ import java.util.concurrent.TimeUnit
|
|||
fun NSTreatment.convertToRemoteAndBack(): NSTreatment? =
|
||||
toRemoteTreatment()?.toTreatment()
|
||||
|
||||
fun String.toNSTreatment(): NSTreatment? =
|
||||
Gson().fromJson(this, RemoteTreatment::class.java).toTreatment()
|
||||
|
||||
internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
||||
val treatmentTimestamp = timestamp()
|
||||
when {
|
||||
|
|
|
@ -48,7 +48,7 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getSgvsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteEntry>>>
|
||||
|
||||
@POST("v3/entries")
|
||||
suspend fun createEntry(@Body remoteEntry: RemoteEntry): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createEntry(@Body remoteEntry: RemoteEntry): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/entries/{identifier}")
|
||||
suspend fun updateEntry(@Body remoteEntry: RemoteEntry, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
@ -63,16 +63,16 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getTreatmentsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteTreatment>>>
|
||||
|
||||
@POST("v3/treatments")
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/treatments/{identifier}")
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment, @Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@DELETE("v3/treatments/{identifier}")
|
||||
suspend fun deleteTreatment(@Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun deleteTreatment(@Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@POST("v3/devicestatus")
|
||||
suspend fun createDeviceStatus(@Body remoteDeviceStatus: RemoteDeviceStatus): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createDeviceStatus(@Body remoteDeviceStatus: RemoteDeviceStatus): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@GET("v3/devicestatus/history/{from}")
|
||||
suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>>
|
||||
|
@ -85,13 +85,13 @@ internal interface NightscoutRemoteService {
|
|||
suspend fun getFoodsModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int): Response<NSResponse<List<RemoteFood>>>
|
||||
*/
|
||||
@POST("v3/food")
|
||||
suspend fun createFood(@Body remoteFood: RemoteFood): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createFood(@Body remoteFood: RemoteFood): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@PATCH("v3/food")
|
||||
suspend fun updateFood(@Body remoteFood: RemoteFood, @Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun updateFood(@Body remoteFood: RemoteFood, @Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@DELETE("v3/food")
|
||||
suspend fun deleteFood(@Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun deleteFood(@Path("identifier") identifier: String): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
@GET("v3/profile/history/{from}")
|
||||
suspend fun getProfileModifiedSince(@Path("from") from: Long, @Query("limit") limit: Int = 10): Response<NSResponse<List<JSONObject>>>
|
||||
|
@ -100,8 +100,7 @@ internal interface NightscoutRemoteService {
|
|||
@GET("v3/profile?sort\$desc=date&limit=1")
|
||||
suspend fun getLastProfile(): Response<NSResponse<List<JSONObject>>>
|
||||
|
||||
|
||||
@POST("v3/profile")
|
||||
suspend fun createProfile(@Body profile: JsonObject): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
suspend fun createProfile(@Body profile: JsonObject): Response<RemoteCreateUpdateResponse>
|
||||
|
||||
}
|
||||
|
|
|
@ -22,4 +22,15 @@ data class LastModified(
|
|||
@SerializedName("foods") var foods: Long = 0, // foods collection
|
||||
@SerializedName("settings") var settings: Long = 0 // settings collection
|
||||
)
|
||||
|
||||
fun set(colName: String, value: Long) {
|
||||
when (colName) {
|
||||
"devicestatus" -> collections.devicestatus = value
|
||||
"entries" -> collections.entries = value
|
||||
"profile" -> collections.profile = value
|
||||
"treatments" -> collections.treatments = value
|
||||
"foods" -> collections.foods = value
|
||||
"settings" -> collections.settings = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,28 @@ object OKDialog {
|
|||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun show(context: Context, title: String, message: Spanned, runnable: Runnable? = null) {
|
||||
var okClicked = false
|
||||
var notEmptyTitle = title
|
||||
if (notEmptyTitle.isEmpty()) notEmptyTitle = context.getString(R.string.message)
|
||||
|
||||
MaterialAlertDialogBuilder(context, R.style.DialogTheme)
|
||||
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, notEmptyTitle))
|
||||
.setMessage(message)
|
||||
.setPositiveButton(context.getString(R.string.ok)) { dialog: DialogInterface, _: Int ->
|
||||
if (okClicked) return@setPositiveButton
|
||||
else {
|
||||
okClicked = true
|
||||
dialog.dismiss()
|
||||
SystemClock.sleep(100)
|
||||
runOnUiThread(runnable)
|
||||
}
|
||||
}
|
||||
.show()
|
||||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun show(activity: FragmentActivity, title: String, message: Spanned, runnable: Runnable? = null) {
|
||||
var okClicked = false
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<string name="mute5min">Mute for 5 minutes</string>
|
||||
<string name="mute">Mute</string>
|
||||
<string name="success">Success</string>
|
||||
<string name="advancedsettings_title">Advanced Settings</string>
|
||||
<string name="advanced_settings_title">Advanced Settings</string>
|
||||
<string name="extendedbolusdeliveryerror">Extended bolus delivery error</string>
|
||||
<string name="aps_mode_title">APS Mode</string>
|
||||
<string name="extended_bolus">Extended bolus</string>
|
||||
|
@ -620,4 +620,9 @@
|
|||
<item quantity="other">%1$d minutes</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Maintenance-->
|
||||
<string name="cleanup_db_confirm">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.</string>
|
||||
<string name="cleanup_db_confirm_sync">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.\nDoing it will speedup full synchronization dramatically.</string>
|
||||
<string name="cleared_entries">Cleared entries</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -70,8 +70,7 @@
|
|||
<string name="key_autotune_additional_log" translatable="false">autotune_additional_log</string>
|
||||
<string name="key_autotune_plugin" translatable="false">key_autotune_plugin</string>
|
||||
<string name="key_autotune_last_run" translatable="false">key_autotune_last_run</string>
|
||||
<string name="key_dexcomg5_xdripupload" translatable="false">dexcomg5_xdripupload</string>
|
||||
<string name="key_nsclient_localbroadcasts" translatable="false">nsclient_localbroadcasts</string>
|
||||
<string name="key_xdrip_local_broadcasts" translatable="false">xdrip_local_broadcasts</string>
|
||||
<string name="key_usebolusreminder" translatable="false">use_bolus_reminder</string>
|
||||
<string name="key_carbs_button_increment_1" translatable="false">carbs_button_increment_1</string>
|
||||
<string name="key_carbs_button_increment_2" translatable="false">carbs_button_increment_2</string>
|
||||
|
@ -85,6 +84,7 @@
|
|||
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
||||
<string name="key_nsclientinternal_url" translatable="false">nsclientinternal_url</string>
|
||||
<string name="key_nsclientinternal_api_secret" translatable="false">nsclientinternal_api_secret</string>
|
||||
<string name="key_ns_use_ws" translatable="false">ns_use_ws</string>
|
||||
<string name="key_ns_receive_insulin" translatable="false">ns_receive_insulin</string>
|
||||
<string name="key_ns_receive_carbs" translatable="false">ns_receive_carbs</string>
|
||||
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.room.PrimaryKey
|
|||
import info.nightscout.database.entities.embedments.InterfaceIDs
|
||||
import info.nightscout.database.entities.interfaces.DBEntryWithTimeAndDuration
|
||||
import info.nightscout.database.entities.interfaces.TraceableDBEntry
|
||||
import info.nightscout.database.entities.interfaces.end
|
||||
import java.util.TimeZone
|
||||
|
||||
@Entity(
|
||||
|
@ -53,9 +54,6 @@ data class OfflineEvent(
|
|||
previous.interfaceIDs.nightscoutId == null &&
|
||||
interfaceIDs.nightscoutId != null
|
||||
|
||||
fun isRecordDeleted(other: OfflineEvent): Boolean =
|
||||
isValid && !other.isValid
|
||||
|
||||
enum class Reason {
|
||||
DISCONNECT_PUMP,
|
||||
SUSPEND,
|
||||
|
|
|
@ -123,7 +123,7 @@ import kotlin.math.roundToInt
|
|||
val ret = StringBuilder()
|
||||
removed
|
||||
.filter { it.second > 0 }
|
||||
.map { ret.append(it.first + " " + it.second + "\n") }
|
||||
.map { ret.append(it.first + " " + it.second + "<br>") }
|
||||
return ret.toString()
|
||||
}
|
||||
|
||||
|
@ -150,10 +150,8 @@ import kotlin.math.roundToInt
|
|||
database.glucoseValueDao.getModifiedFrom(lastId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastGlucoseValueIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastGlucoseValueId(): Long? =
|
||||
database.glucoseValueDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
fun getLastGlucoseValueWrapped(): Single<ValueWrapper<GlucoseValue>> =
|
||||
database.glucoseValueDao.getLast()
|
||||
|
@ -233,10 +231,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllTempTargetEntries() =
|
||||
database.temporaryTargetDao.deleteAllEntries()
|
||||
|
||||
fun getLastTempTargetIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTempTargetId(): Long? =
|
||||
database.temporaryTargetDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// USER ENTRY
|
||||
fun getAllUserEntries(): Single<List<UserEntry>> =
|
||||
|
@ -309,10 +305,8 @@ import kotlin.math.roundToInt
|
|||
.map { if (!ascending) it.reversed() else it }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastProfileSwitchIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastProfileSwitchId(): Long? =
|
||||
database.profileSwitchDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// EFFECTIVE PROFILE SWITCH
|
||||
/*
|
||||
|
@ -368,10 +362,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllEffectiveProfileSwitches() =
|
||||
database.effectiveProfileSwitchDao.deleteAllEntries()
|
||||
|
||||
fun getLastEffectiveProfileSwitchIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastEffectiveProfileSwitchId(): Long? =
|
||||
database.effectiveProfileSwitchDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// THERAPY EVENT
|
||||
/*
|
||||
|
@ -435,10 +427,8 @@ import kotlin.math.roundToInt
|
|||
database.therapyEventDao.compatGetTherapyEventDataFromToTime(from, to)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastTherapyEventIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTherapyEventId(): Long? =
|
||||
database.therapyEventDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// FOOD
|
||||
/*
|
||||
|
@ -471,10 +461,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllFoods() =
|
||||
database.foodDao.deleteAllEntries()
|
||||
|
||||
fun getLastFoodIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastFoodId(): Long? =
|
||||
database.foodDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// BOLUS
|
||||
/*
|
||||
|
@ -539,10 +527,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllBoluses() =
|
||||
database.bolusDao.deleteAllEntries()
|
||||
|
||||
fun getLastBolusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastBolusId(): Long? =
|
||||
database.bolusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
// CARBS
|
||||
|
||||
private fun expandCarbs(carbs: Carbs): List<Carbs> =
|
||||
|
@ -656,10 +642,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllCarbs() =
|
||||
database.carbsDao.deleteAllEntries()
|
||||
|
||||
fun getLastCarbsIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastCarbsId(): Long? =
|
||||
database.carbsDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// BOLUS CALCULATOR RESULT
|
||||
/*
|
||||
|
@ -698,10 +682,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllBolusCalculatorResults() =
|
||||
database.bolusCalculatorResultDao.deleteAllEntries()
|
||||
|
||||
fun getLastBolusCalculatorResultIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastBolusCalculatorResultId(): Long? =
|
||||
database.bolusCalculatorResultDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// DEVICE STATUS
|
||||
fun insert(deviceStatus: DeviceStatus): Long =
|
||||
|
@ -723,10 +705,8 @@ import kotlin.math.roundToInt
|
|||
database.deviceStatusDao.getModifiedFrom(lastId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun getLastDeviceStatusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastDeviceStatusId(): Long? =
|
||||
database.deviceStatusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// TEMPORARY BASAL
|
||||
/*
|
||||
|
@ -789,10 +769,8 @@ import kotlin.math.roundToInt
|
|||
fun getOldestTemporaryBasalRecord(): TemporaryBasal? =
|
||||
database.temporaryBasalDao.getOldestRecord()
|
||||
|
||||
fun getLastTemporaryBasalIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastTemporaryBasalId(): Long? =
|
||||
database.temporaryBasalDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// EXTENDED BOLUS
|
||||
/*
|
||||
|
@ -847,10 +825,8 @@ import kotlin.math.roundToInt
|
|||
fun getOldestExtendedBolusRecord(): ExtendedBolus? =
|
||||
database.extendedBolusDao.getOldestRecord()
|
||||
|
||||
fun getLastExtendedBolusIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastExtendedBolusId(): Long? =
|
||||
database.extendedBolusDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
// TotalDailyDose
|
||||
fun getLastTotalDailyDoses(count: Int, ascending: Boolean): Single<List<TotalDailyDose>> =
|
||||
|
@ -918,10 +894,8 @@ import kotlin.math.roundToInt
|
|||
fun deleteAllOfflineEventEntries() =
|
||||
database.offlineEventDao.deleteAllEntries()
|
||||
|
||||
fun getLastOfflineEventIdWrapped(): Single<ValueWrapper<Long>> =
|
||||
fun getLastOfflineEventId(): Long? =
|
||||
database.offlineEventDao.getLastId()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.toWrappedSingle()
|
||||
|
||||
suspend fun collectNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int) = NewEntries(
|
||||
apsResults = database.apsResultDao.getNewEntriesSince(since, until, limit, offset),
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface BolusCalculatorResultDao : TraceableDao<BolusCalculatorResult
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_BOLUS_CALCULATOR_RESULTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): BolusCalculatorResult?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface BolusDao : TraceableDao<Bolus> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_BOLUSES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_BOLUSES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): Bolus?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface CarbsDao : TraceableDao<Carbs> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_CARBS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CARBS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): Carbs?
|
||||
|
|
|
@ -29,7 +29,7 @@ internal interface DeviceStatusDao {
|
|||
fun deleteOlderThan(than: Long): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_DEVICE_STATUS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("DELETE FROM $TABLE_DEVICE_STATUS WHERE id NOT IN (SELECT MAX(id) FROM $TABLE_DEVICE_STATUS)")
|
||||
fun deleteAllEntriesExceptLast()
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface EffectiveProfileSwitchDao : TraceableDao<EffectiveProfileSwit
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): EffectiveProfileSwitch?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface ExtendedBolusDao : TraceableDao<ExtendedBolus> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_EXTENDED_BOLUSES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_EXTENDED_BOLUSES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): ExtendedBolus?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface FoodDao : TraceableDao<Food> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_FOODS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_FOODS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): Food?
|
||||
|
|
|
@ -26,7 +26,7 @@ internal interface GlucoseValueDao : TraceableDao<GlucoseValue> {
|
|||
fun getLast(): Maybe<GlucoseValue>
|
||||
|
||||
@Query("SELECT id FROM $TABLE_GLUCOSE_VALUES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_GLUCOSE_VALUES WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSIdMaybe(nsId: String): Maybe<GlucoseValue>
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface OfflineEventDao : TraceableDao<OfflineEvent> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_OFFLINE_EVENTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_OFFLINE_EVENTS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): OfflineEvent?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface ProfileSwitchDao : info.nightscout.database.impl.daos.workaro
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(timestamp: Long): ProfileSwitch?
|
||||
|
|
|
@ -24,7 +24,7 @@ internal interface TemporaryBasalDao : TraceableDao<TemporaryBasal> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_TEMPORARY_BASALS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_TEMPORARY_BASALS WHERE temporaryId = :temporaryId")
|
||||
fun findByTempId(temporaryId: Long): TemporaryBasal?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface TemporaryTargetDao : TraceableDao<TemporaryTarget> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_TEMPORARY_TARGETS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_TEMPORARY_TARGETS WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||
fun findByNSId(nsId: String): TemporaryTarget?
|
||||
|
|
|
@ -23,7 +23,7 @@ internal interface TherapyEventDao : TraceableDao<TherapyEvent> {
|
|||
override fun deleteTrackedChanges(): Int
|
||||
|
||||
@Query("SELECT id FROM $TABLE_THERAPY_EVENTS ORDER BY id DESC limit 1")
|
||||
fun getLastId(): Maybe<Long>
|
||||
fun getLastId(): Long?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_THERAPY_EVENTS WHERE type = :type AND timestamp = :timestamp AND referenceId IS NULL")
|
||||
fun findByTimestamp(type: TherapyEvent.Type, timestamp: Long): TherapyEvent?
|
||||
|
|
|
@ -31,7 +31,7 @@ class PersistenceLayerImpl @Inject constructor(
|
|||
|
||||
private val disposable = CompositeDisposable()
|
||||
override fun clearDatabases() = repository.clearDatabases()
|
||||
override fun cleanupDatabase(keepDays: Long, deleteTrackedChanges: Boolean): String = cleanupDatabase(keepDays, deleteTrackedChanges)
|
||||
override fun cleanupDatabase(keepDays: Long, deleteTrackedChanges: Boolean): String = repository.cleanupDatabase(keepDays, deleteTrackedChanges)
|
||||
|
||||
override fun insertOrUpdate(bolusCalculatorResult: BolusCalculatorResult) {
|
||||
disposable += repository.runTransactionForResult(InsertOrUpdateBolusCalculatorResultTransaction(bolusCalculatorResult))
|
||||
|
|
|
@ -142,14 +142,14 @@ class GlucoseStatusTest : TestBase() {
|
|||
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
|
||||
private fun generateValidBgData(): MutableList<InMemoryGlucoseValue> {
|
||||
val list: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 216.0, timestamp = 1514766600000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 219.0, timestamp = 1514766300000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 223.0, timestamp = 1514766000000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 222.0, timestamp = 1514765700000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 224.0, timestamp = 1514765400000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 226.0, timestamp = 1514765100000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 216.0, timestamp = 1514766600000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 219.0, timestamp = 1514766300000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 223.0, timestamp = 1514766000000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 222.0, timestamp = 1514765700000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 224.0, timestamp = 1514765400000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 226.0, timestamp = 1514765100000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
return list
|
||||
}
|
||||
|
||||
|
@ -159,13 +159,13 @@ class GlucoseStatusTest : TestBase() {
|
|||
|
||||
private fun generateOldBgData(): MutableList<InMemoryGlucoseValue> {
|
||||
val list: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
return list
|
||||
}
|
||||
|
||||
private fun generateOneCurrentRecordBgData(): MutableList<InMemoryGlucoseValue> {
|
||||
val list: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
return list
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_ama_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_smb_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_smb_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<Preference android:summary="@string/openapsama_link_to_preference_json_doc_txt">
|
||||
<intent
|
||||
|
|
|
@ -82,7 +82,7 @@ class TriggerBgTest : TriggerTestBase() {
|
|||
|
||||
private fun generateOneCurrentRecordBgData(): MutableList<InMemoryGlucoseValue> {
|
||||
val list: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = now - 1, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = now - 1, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
return list
|
||||
}
|
||||
}
|
|
@ -91,14 +91,14 @@ class TriggerDeltaTest : TriggerTestBase() {
|
|||
|
||||
private fun generateValidBgData(): MutableList<InMemoryGlucoseValue> {
|
||||
val list: MutableList<InMemoryGlucoseValue> = ArrayList()
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 216.0, timestamp = 1514766600000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 219.0, timestamp = 1514766300000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 223.0, timestamp = 1514766000000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 222.0, timestamp = 1514765700000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 224.0, timestamp = 1514765400000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 226.0, timestamp = 1514765100000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
list.add(InMemoryGlucoseValue(value = 214.0, timestamp = 1514766900000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 216.0, timestamp = 1514766600000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 219.0, timestamp = 1514766300000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 223.0, timestamp = 1514766000000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 222.0, timestamp = 1514765700000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 224.0, timestamp = 1514765400000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 226.0, timestamp = 1514765100000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
list.add(InMemoryGlucoseValue(value = 228.0, timestamp = 1514764800000, trendArrow = GlucoseValue.TrendArrow.FLAT, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))
|
||||
return list
|
||||
}
|
||||
}
|
|
@ -75,7 +75,7 @@ class RunningConfigurationImpl @Inject constructor(
|
|||
assert(config.NSCLIENT)
|
||||
|
||||
configuration.version?.let {
|
||||
rxBus.send(EventNSClientNewLog("VERSION", "Received AAPS version $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ VERSION", "Received AAPS version $it"))
|
||||
if (config.VERSION_NAME.startsWith(it).not())
|
||||
uiInteraction.addNotification(Notification.NSCLIENT_VERSION_DOES_NOT_MATCH, rh.gs(R.string.nsclient_version_does_not_match), Notification.NORMAL)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import info.nightscout.interfaces.plugin.OwnDatabasePlugin
|
|||
import info.nightscout.interfaces.protection.ProtectionCheck
|
||||
import info.nightscout.interfaces.protection.ProtectionCheck.Protection.PREFERENCES
|
||||
import info.nightscout.interfaces.pump.PumpSync
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
|
@ -51,7 +51,7 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
@Inject lateinit var persistenceLayer: PersistenceLayer
|
||||
@Inject lateinit var protectionCheck: ProtectionCheck
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorXdrip: DataSyncSelectorXdrip
|
||||
@Inject lateinit var pumpSync: PumpSync
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var overviewData: OverviewData
|
||||
|
@ -93,7 +93,8 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
for (plugin in activePlugin.getSpecificPluginsListByInterface(OwnDatabasePlugin::class.java)) {
|
||||
(plugin as OwnDatabasePlugin).clearAllTables()
|
||||
}
|
||||
dataSyncSelector.resetToNextFullSync()
|
||||
activePlugin.activeNsClient?.dataSyncSelector?.resetToNextFullSync()
|
||||
dataSyncSelectorXdrip.resetToNextFullSync()
|
||||
pumpSync.connectNewPump()
|
||||
overviewData.reset()
|
||||
iobCobCalculator.ads.reset()
|
||||
|
@ -111,7 +112,7 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
binding.cleanupDb.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
var result = ""
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.maintenance), rh.gs(R.string.cleanup_db_confirm), Runnable {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.maintenance), rh.gs(info.nightscout.core.ui.R.string.cleanup_db_confirm), Runnable {
|
||||
disposable += Completable.fromAction { result = persistenceLayer.cleanupDatabase(93, deleteTrackedChanges = true) }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -119,7 +120,12 @@ class MaintenanceFragment : DaggerFragment() {
|
|||
onError = { aapsLogger.error("Error cleaning up databases", it) },
|
||||
onComplete = {
|
||||
if (result.isNotEmpty())
|
||||
OKDialog.show(activity, rh.gs(info.nightscout.core.ui.R.string.result), HtmlHelper.fromHtml("<b>" + rh.gs(R.string.cleared_entries) + "</b>\n" + result).toSpanned())
|
||||
OKDialog.show(
|
||||
activity,
|
||||
rh.gs(info.nightscout.core.ui.R.string.result),
|
||||
HtmlHelper.fromHtml("<b>" + rh.gs(info.nightscout.core.ui.R.string.cleared_entries) + "</b><br>" + result)
|
||||
.toSpanned()
|
||||
)
|
||||
aapsLogger.info(LTag.CORE, "Cleaned up databases with result: $result")
|
||||
}
|
||||
)
|
||||
|
|
|
@ -122,8 +122,6 @@
|
|||
<string name="maintenance_shortname">MAINT</string>
|
||||
<string name="description_maintenance">Provides several functions for maintenance (eg. log sending, log deletion).</string>
|
||||
<string name="database_cleanup">Database cleanup</string>
|
||||
<string name="cleanup_db_confirm">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.</string>
|
||||
<string name="cleared_entries">Cleared entries</string>
|
||||
<string name="reset_db_confirm">Do you really want to reset the databases?</string>
|
||||
<string name="maintenance_settings">Maintenance Settings</string>
|
||||
<string name="maintenance_email">Email recipient</string>
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
|
|||
FoodModule::class,
|
||||
SMSCommunicatorModule::class,
|
||||
ProfileModule::class,
|
||||
ProfileModule.Bindings::class,
|
||||
SkinsModule::class,
|
||||
SkinsUiModule::class,
|
||||
ActionsModule::class,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package info.nightscout.plugins.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.interfaces.profile.ProfileSource
|
||||
import info.nightscout.plugins.profile.ProfileFragment
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
|
||||
|
@ -9,6 +11,12 @@ import info.nightscout.plugins.profile.ProfilePlugin
|
|||
@Suppress("unused")
|
||||
abstract class ProfileModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): ProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): ProfileFragment
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds fun bindProfileSource(profilePlugin: ProfilePlugin): ProfileSource
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.DefaultValueHelper
|
||||
import info.nightscout.plugins.R
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
|
@ -21,7 +20,6 @@ class NotificationWithAction constructor(
|
|||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
|
||||
init {
|
||||
|
@ -66,7 +64,7 @@ class NotificationWithAction constructor(
|
|||
aapsLogger.debug(LTag.NOTIFICATION, "Notification text is: $text")
|
||||
val msToSnooze = sp.getInt(info.nightscout.core.utils.R.string.key_ns_alarm_stale_data_value, 15) * 60 * 1000L
|
||||
aapsLogger.debug(LTag.NOTIFICATION, "snooze nsalarm_staledatavalue in minutes is ${T.msecs(msToSnooze).mins()} currentTimeMillis is: ${System.currentTimeMillis()}")
|
||||
sp.putLong(info.nightscout.core.utils.R.string.key_snoozed_to, System.currentTimeMillis() + msToSnooze)
|
||||
sp.putLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + nsAlarm.level(), System.currentTimeMillis() + msToSnooze)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package info.nightscout.plugins.profile
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.extensions.blockFromJsonArray
|
||||
|
@ -11,12 +8,9 @@ import info.nightscout.core.extensions.pureProfileFromJson
|
|||
import info.nightscout.core.profile.ProfileSealed
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
|
@ -40,7 +34,6 @@ import info.nightscout.rx.logging.LTag
|
|||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
@ -235,7 +228,7 @@ class ProfilePlugin @Inject constructor(
|
|||
}
|
||||
|
||||
@Synchronized
|
||||
fun loadFromStore(store: ProfileStore) {
|
||||
override fun loadFromStore(store: ProfileStore) {
|
||||
try {
|
||||
val newProfiles: ArrayList<ProfileSource.SingleProfile> = ArrayList()
|
||||
for (p in store.getProfileList()) {
|
||||
|
@ -429,41 +422,4 @@ class ProfilePlugin @Inject constructor(
|
|||
get() = rawProfile?.getDefaultProfile()?.let {
|
||||
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
|
||||
} ?: "INVALID"
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var profilePlugin: ProfilePlugin
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Inject lateinit var instantiator: Instantiator
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
val profileJson = dataWorkerStorage.pickupJSONObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
xDripBroadcast.sendProfile(profileJson)
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_store, true) || config.NSCLIENT) {
|
||||
val store = instantiator.provideProfileStore(profileJson)
|
||||
val createdAt = store.getStartDate()
|
||||
val lastLocalChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange")
|
||||
@Suppress("LiftReturnOrAssignment")
|
||||
if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS
|
||||
profilePlugin.loadFromStore(store)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
return Result.success(workDataOf("Data" to profileJson.toString().substring(0..Integer.min(5000, profileJson.length()))))
|
||||
} else
|
||||
return Result.success(workDataOf("Result" to "Unchanged. Ignoring"))
|
||||
}
|
||||
return Result.success(workDataOf("Result" to "Sync not enabled"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -496,7 +496,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="overview_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<application>
|
||||
<activity
|
||||
android:name=".ui.OHLoginActivity"
|
||||
|
|
|
@ -30,6 +30,7 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -67,7 +68,7 @@ class OpenHumansUploaderPlugin @Inject internal constructor(
|
|||
counterDelegate: OHCounterDelegate,
|
||||
appIdDelegate: OHAppIDDelegate,
|
||||
private val rxBus: RxBus
|
||||
) : PluginBase(
|
||||
) : Sync, PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.SYNC)
|
||||
.pluginIcon(R.drawable.open_humans_white)
|
||||
|
@ -85,6 +86,11 @@ class OpenHumansUploaderPlugin @Inject internal constructor(
|
|||
|
||||
private val preferenceChangeDisposable = CompositeDisposable()
|
||||
|
||||
// Not used Sync interface members
|
||||
override val hasWritePermission: Boolean = true
|
||||
override val connected: Boolean = true
|
||||
override val status: String = ""
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setupNotificationChannels()
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_aaps_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
android:defaultValue="1.2"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="absorption_oref1_advanced"
|
||||
android:title="@string/advancedsettings_title">
|
||||
android:title="@string/advanced_settings_title">
|
||||
|
||||
<info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
android:defaultValue="1.2"
|
||||
|
|
|
@ -35,6 +35,7 @@ import info.nightscout.rx.events.EventNewBG
|
|||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.extensions.toVisibility
|
||||
import info.nightscout.shared.extensions.toVisibilityKeepSpace
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
|
@ -135,7 +136,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
|
|||
|
||||
override fun onBindViewHolder(holder: GlucoseValuesViewHolder, position: Int) {
|
||||
val glucoseValue = glucoseValues[position]
|
||||
holder.binding.ns.visibility = (glucoseValue.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.ns.visibility = (glucoseValue.interfaceIDs.nightscoutId != null).toVisibilityKeepSpace()
|
||||
holder.binding.invalid.visibility = (!glucoseValue.isValid).toVisibility()
|
||||
val newDay = position == 0 || !dateUtil.isSameDay(glucoseValue.timestamp, glucoseValues[position - 1].timestamp)
|
||||
holder.binding.date.visibility = newDay.toVisibility()
|
||||
|
@ -201,7 +202,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
|
|||
R.string.tomato -> Sources.Tomato
|
||||
R.string.glunovo -> Sources.Glunovo
|
||||
R.string.intelligo -> Sources.Intelligo
|
||||
R.string.xdrip -> Sources.Xdrip
|
||||
R.string.source_xdrip -> Sources.Xdrip
|
||||
R.string.aidex -> Sources.Aidex
|
||||
else -> Sources.Unknown
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
|||
import info.nightscout.database.impl.transactions.InvalidateGlucoseValueTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
|
@ -91,7 +90,6 @@ class DexcomPlugin @Inject constructor(
|
|||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
|
@ -185,11 +183,9 @@ class DexcomPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
xDripBroadcast.sendIn640gMode(result.inserted[i])
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg ${result.inserted[i]}")
|
||||
}
|
||||
result.updated.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated bg $it")
|
||||
}
|
||||
result.sensorInsertionsInserted.forEach {
|
||||
|
|
|
@ -12,7 +12,6 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyEventTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -61,7 +60,6 @@ class EversensePlugin @Inject constructor(
|
|||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
|
@ -114,7 +112,6 @@ class EversensePlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import info.nightscout.database.entities.GlucoseValue
|
|||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -50,7 +49,6 @@ class GlimpPlugin @Inject constructor(
|
|||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var glimpPlugin: GlimpPlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
|
@ -74,7 +72,6 @@ class GlimpPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
|
@ -38,7 +37,6 @@ class GlunovoPlugin @Inject constructor(
|
|||
private val sp: SP,
|
||||
private val context: Context,
|
||||
private val repository: AppRepository,
|
||||
private val xDripBroadcast: XDripBroadcast,
|
||||
private val dateUtil: DateUtil,
|
||||
private val uel: UserEntryLogger,
|
||||
private val fabricPrivacy: FabricPrivacy
|
||||
|
@ -148,7 +146,6 @@ class GlunovoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
savedValues.calibrationsInserted.forEach { calibration ->
|
||||
|
|
|
@ -16,7 +16,6 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
|
@ -41,7 +40,6 @@ class IntelligoPlugin @Inject constructor(
|
|||
private val sp: SP,
|
||||
private val context: Context,
|
||||
private val repository: AppRepository,
|
||||
private val xDripBroadcast: XDripBroadcast,
|
||||
private val dateUtil: DateUtil,
|
||||
private val uel: UserEntryLogger,
|
||||
private val fabricPrivacy: FabricPrivacy
|
||||
|
@ -159,7 +157,6 @@ class IntelligoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
savedValues.calibrationsInserted.forEach { calibration ->
|
||||
|
|
|
@ -4,13 +4,11 @@ import android.content.Context
|
|||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -51,9 +49,7 @@ class MM640gPlugin @Inject constructor(
|
|||
@Inject lateinit var mM640gPlugin: MM640gPlugin
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
|
@ -90,7 +86,6 @@ class MM640gPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.all().forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +1,16 @@
|
|||
package info.nightscout.source
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSSgv
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.source.BgSource
|
||||
import info.nightscout.interfaces.source.DoingOwnUploadSource
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -50,21 +27,15 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
.pluginIcon(info.nightscout.core.main.R.drawable.ic_nsclient_bg)
|
||||
.pluginName(R.string.ns_client_bg)
|
||||
.shortName(R.string.ns_client_bg_short)
|
||||
.description(R.string.description_source_ns_client),
|
||||
.description(R.string.description_source_ns_client)
|
||||
.alwaysEnabled(config.NSCLIENT)
|
||||
.setDefault(config.NSCLIENT),
|
||||
aapsLogger, rh, injector
|
||||
), BgSource, NSClientSource, DoingOwnUploadSource {
|
||||
|
||||
private var lastBGTimeStamp: Long = 0
|
||||
private var isAdvancedFilteringEnabled = false
|
||||
|
||||
init {
|
||||
if (config.NSCLIENT) {
|
||||
pluginDescription
|
||||
.alwaysEnabled(true)
|
||||
.setDefault()
|
||||
}
|
||||
}
|
||||
|
||||
override fun advancedFilteringSupported(): Boolean = isAdvancedFilteringEnabled
|
||||
|
||||
override fun shouldUploadToNs(glucoseValue: GlucoseValue): Boolean = false
|
||||
|
@ -81,96 +52,4 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
lastBGTimeStamp = glucoseValue.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSClientSourceWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.IO) {
|
||||
|
||||
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
private fun toGv(jsonObject: JSONObject): TransactionGlucoseValue? {
|
||||
val sgv = NSSgv(jsonObject)
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.mills ?: return null,
|
||||
value = sgv.mgdl?.toDouble() ?: return null,
|
||||
noise = null,
|
||||
raw = sgv.filtered?.toDouble(),
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction),
|
||||
nightscoutId = sgv.id,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device)
|
||||
)
|
||||
}
|
||||
|
||||
private fun toGv(sgv: NSSgvV3): TransactionGlucoseValue {
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.date ?: throw InvalidParameterException(),
|
||||
value = sgv.sgv,
|
||||
noise = sgv.noise?.toDouble(),
|
||||
raw = sgv.filtered,
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction?.nsName),
|
||||
nightscoutId = sgv.identifier,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device),
|
||||
isValid = sgv.isValid,
|
||||
utcOffset = T.mins(sgv.utcOffset ?: 0L).msecs()
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
val sgvs = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false))
|
||||
return Result.success(workDataOf("Result" to "Sync not enabled"))
|
||||
|
||||
var latestDateInReceivedData: Long = 0
|
||||
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvs")
|
||||
val glucoseValues = mutableListOf<TransactionGlucoseValue>()
|
||||
|
||||
try {
|
||||
if (sgvs is JSONArray) { // V1 client
|
||||
xDripBroadcast.sendSgvs(sgvs)
|
||||
|
||||
for (i in 0 until sgvs.length()) {
|
||||
val sgv = toGv(sgvs.getJSONObject(i)) ?: continue
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
|
||||
} else if (sgvs is List<*>) { // V3 client
|
||||
|
||||
for (i in 0 until sgvs.size) {
|
||||
val sgv = toGv(sgvs[i] as NSSgvV3)
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestBgReceivedIfNewer(latestDateInReceivedData)
|
||||
// Was that sgv more less 5 mins ago ?
|
||||
if (T.msecs(dateUtil.now() - latestDateInReceivedData).mins() < 5L) {
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
}
|
||||
|
||||
storeDataForDb.glucoseValues.addAll(glucoseValues)
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
ret = Result.failure(workDataOf("Error" to e.toString()))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -52,7 +51,6 @@ class PoctechPlugin @Inject constructor(
|
|||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var poctechPlugin: PoctechPlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
var ret = Result.success()
|
||||
|
@ -83,7 +81,6 @@ class PoctechPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import info.nightscout.database.impl.AppRepository
|
|||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -38,7 +37,6 @@ class RandomBgPlugin @Inject constructor(
|
|||
aapsLogger: AAPSLogger,
|
||||
private val sp: SP,
|
||||
private val repository: AppRepository,
|
||||
private val xDripBroadcast: XDripBroadcast,
|
||||
private val virtualPump: VirtualPump,
|
||||
private val config: Config
|
||||
) : PluginBase(
|
||||
|
@ -119,7 +117,6 @@ class RandomBgPlugin @Inject constructor(
|
|||
disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
||||
.subscribe({ savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}, { aapsLogger.error(LTag.DATABASE, "Error while saving values from Random plugin", it) }
|
||||
|
|
|
@ -9,7 +9,6 @@ import info.nightscout.database.entities.GlucoseValue
|
|||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.database.impl.transactions.CgmSourceTransaction
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginDescription
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
|
@ -50,7 +49,6 @@ class TomatoPlugin @Inject constructor(
|
|||
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
|
@ -74,7 +72,6 @@ class TomatoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ class XdripSourcePlugin @Inject constructor(
|
|||
.mainType(PluginType.BGSOURCE)
|
||||
.fragmentClass(BGSourceFragment::class.java.name)
|
||||
.pluginIcon((info.nightscout.core.main.R.drawable.ic_blooddrop_48))
|
||||
.pluginName(R.string.xdrip)
|
||||
.pluginName(R.string.source_xdrip)
|
||||
.description(R.string.description_source_xdrip),
|
||||
aapsLogger, rh, injector
|
||||
), BgSource, DoingOwnUploadSource, XDrip {
|
||||
|
|
|
@ -29,7 +29,6 @@ abstract class SourceModule {
|
|||
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesXdripWorker(): XdripSourcePlugin.XdripSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDexcomWorker(): DexcomPlugin.DexcomWorker
|
||||
@ContributesAndroidInjector abstract fun contributesMM640gWorker(): MM640gPlugin.MM640gWorker
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<string name="ns_client_bg">NSClient BG</string>
|
||||
<string name="ns_client_bg_short">NS BG</string>
|
||||
<string name="description_source_ns_client">Downloads BG data from Nightscout</string>
|
||||
<string name="xdrip">xDrip+</string>
|
||||
<string name="source_xdrip">xDrip+ BG</string>
|
||||
<string name="description_source_xdrip">Receive BG values from xDrip+.</string>
|
||||
<string name="dexcom_app_patched">BYODA</string>
|
||||
<string name="dexcom_short">BYODA</string>
|
||||
|
|
|
@ -12,12 +12,6 @@
|
|||
android:key="@string/key_do_ns_upload"
|
||||
android:title="@string/do_ns_upload_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_dexcomg5_xdripupload"
|
||||
android:summary="@string/do_xdrip_upload_summary"
|
||||
android:title="@string/do_xdrip_upload_title" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -12,12 +12,6 @@
|
|||
android:key="@string/key_do_ns_upload"
|
||||
android:title="@string/do_ns_upload_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_dexcomg5_xdripupload"
|
||||
android:summary="@string/do_xdrip_upload_summary"
|
||||
android:title="@string/do_xdrip_upload_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_dexcom_log_ns_sensor_change"
|
||||
|
|
|
@ -32,10 +32,7 @@ dependencies {
|
|||
testImplementation project(':plugins:aps')
|
||||
|
||||
// NSClient, Tidepool
|
||||
api("io.socket:socket.io-client:1.0.2") {
|
||||
// excluding org.json which is provided by Android
|
||||
exclude group: "org.json", module: "json"
|
||||
}
|
||||
api("io.socket:socket.io-client:2.1.0")
|
||||
api "com.squareup.okhttp3:okhttp:$okhttp3_version"
|
||||
api "com.squareup.okhttp3:logging-interceptor:$okhttp3_version"
|
||||
//api "com.squareup.retrofit2:retrofit:$retrofit2_version"
|
||||
|
|
|
@ -11,10 +11,12 @@ import info.nightscout.interfaces.XDripBroadcast
|
|||
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.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorXdrip
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorV1Impl
|
||||
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl
|
||||
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
|
||||
import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
||||
|
@ -22,18 +24,13 @@ 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.LoadFoodsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadLastModificationWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadProfileStoreWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadStatusWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3Impl
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.*
|
||||
import info.nightscout.plugins.sync.tidepool.TidepoolFragment
|
||||
import info.nightscout.plugins.sync.xdrip.DataSyncSelectorXdripImpl
|
||||
import info.nightscout.plugins.sync.xdrip.XdripFragment
|
||||
import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
||||
import info.nightscout.plugins.sync.xdrip.workers.XdripDataSyncWorker
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
|
@ -58,15 +55,13 @@ abstract class SyncModule {
|
|||
@ContributesAndroidInjector abstract fun contributesLoadBgWorker(): LoadBgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadFoodsWorker(): LoadFoodsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadProfileStoreWorker(): LoadProfileStoreWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreBgWorker(): StoreDataForDbImpl.StoreBgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesStoreFoodWorker(): StoreDataForDbImpl.StoreFoodWorker
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentWorker(): LoadTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesProcessTreatmentsWorker(): ProcessTreatmentsWorker
|
||||
@ContributesAndroidInjector abstract fun contributesLoadDeviceStatusWorker(): LoadDeviceStatusWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDataSyncWorker(): DataSyncWorker
|
||||
@ContributesAndroidInjector abstract fun contributesFoodWorker(): ProcessFoodWorker
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
@ContributesAndroidInjector abstract fun contributesXdripFragment(): XdripFragment
|
||||
@ContributesAndroidInjector abstract fun contributesXdripDataSyncWorker(): XdripDataSyncWorker
|
||||
|
||||
@Module
|
||||
open class Provide {
|
||||
|
@ -80,7 +75,9 @@ abstract class SyncModule {
|
|||
|
||||
@Binds fun bindProcessedDeviceStatusData(processedDeviceStatusDataImpl: ProcessedDeviceStatusDataImpl): ProcessedDeviceStatusData
|
||||
@Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus
|
||||
@Binds fun bindDataSyncSelectorInterface(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
|
||||
@Binds fun bindDataSyncSelectorV1Interface(dataSyncSelectorV1Impl: DataSyncSelectorV1Impl): DataSyncSelectorV1
|
||||
@Binds fun bindDataSyncSelectorV3Interface(dataSyncSelectorV3Impl: DataSyncSelectorV3Impl): DataSyncSelectorV3
|
||||
@Binds fun bindDataSyncSelectorXdripInterface(dataSyncSelectorXdripImpl: DataSyncSelectorXdripImpl): DataSyncSelectorXdrip
|
||||
@Binds fun bindStoreDataForDb(storeDataForDbImpl: StoreDataForDbImpl): StoreDataForDb
|
||||
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XdripPlugin): XDripBroadcast
|
||||
}
|
||||
|
|
|
@ -1,36 +1,50 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ScrollView
|
||||
import androidx.core.text.toSpanned
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.database.entities.UserEntry
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.db.PersistenceLayer
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginFragment
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.utils.HtmlHelper
|
||||
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.databinding.NsClientLogItemBinding
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiData
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.rxjava3.core.Completable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
||||
|
@ -40,11 +54,11 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var persistenceLayer: PersistenceLayer
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -61,11 +75,19 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var _binding: NsClientFragmentBinding? = null
|
||||
private lateinit var logAdapter: RecyclerViewAdapter
|
||||
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
// https://stackoverflow.com/questions/31759171/recyclerview-and-java-lang-indexoutofboundsexception-inconsistency-detected-in
|
||||
class FixedLinearLayoutManager(context: Context?, @RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL, reverseLayout: Boolean = false) :
|
||||
LinearLayoutManager(context, orientation, reverseLayout) {
|
||||
|
||||
override fun supportsPredictiveItemAnimations(): Boolean = false
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
NsClientFragmentBinding.inflate(inflater, container, false).also {
|
||||
_binding = it
|
||||
|
@ -75,18 +97,15 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.autoscroll.isChecked = sp.getBoolean(R.string.key_ns_client_autoscroll, true)
|
||||
binding.autoscroll.setOnCheckedChangeListener { _, isChecked ->
|
||||
sp.putBoolean(R.string.key_ns_client_autoscroll, isChecked)
|
||||
updateGui()
|
||||
}
|
||||
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.paused.setOnCheckedChangeListener { _, isChecked ->
|
||||
uel.log(if (isChecked) UserEntry.Action.NS_PAUSED else UserEntry.Action.NS_RESUME, UserEntry.Sources.NSClient)
|
||||
nsClientPlugin?.pause(isChecked)
|
||||
updateGui()
|
||||
}
|
||||
|
||||
logAdapter = RecyclerViewAdapter(nsClientPlugin?.listLog ?: emptyList())
|
||||
binding.recyclerview.layoutManager = FixedLinearLayoutManager(context)
|
||||
binding.recyclerview.adapter = logAdapter
|
||||
}
|
||||
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -100,7 +119,12 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
override fun onMenuItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
ID_MENU_CLEAR_LOG -> {
|
||||
nsClientPlugin?.clearLog()
|
||||
nsClientPlugin?.listLog?.let {
|
||||
synchronized(it) {
|
||||
it.clear()
|
||||
_binding?.recyclerview?.swapAdapter(RecyclerViewAdapter(it), true)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -115,10 +139,40 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
}
|
||||
|
||||
ID_MENU_FULL_SYNC -> {
|
||||
var result = ""
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(
|
||||
context, rh.gs(R.string.ns_client), rh.gs(R.string.full_sync_comment),
|
||||
Runnable { nsClientPlugin?.resetToFullSync() }
|
||||
Runnable {
|
||||
OKDialog.showConfirmation(requireContext(), rh.gs(R.string.ns_client), rh.gs(info.nightscout.core.ui.R.string.cleanup_db_confirm_sync), Runnable {
|
||||
disposable += Completable.fromAction { result = persistenceLayer.cleanupDatabase(93, deleteTrackedChanges = true) }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error cleaning up databases", it) },
|
||||
onComplete = {
|
||||
if (result.isNotEmpty())
|
||||
OKDialog.show(
|
||||
requireContext(),
|
||||
rh.gs(info.nightscout.core.ui.R.string.result),
|
||||
HtmlHelper.fromHtml("<b>" + rh.gs(info.nightscout.core.ui.R.string.cleared_entries) + "</b><br>" + result)
|
||||
.toSpanned()
|
||||
)
|
||||
aapsLogger.info(LTag.CORE, "Cleaned up databases with result: $result")
|
||||
handler.post {
|
||||
nsClientPlugin?.resetToFullSync()
|
||||
nsClientPlugin?.resend("FULL_SYNC")
|
||||
}
|
||||
}
|
||||
)
|
||||
uel.log(UserEntry.Action.CLEANUP_DATABASES, UserEntry.Sources.NSClient)
|
||||
}, Runnable {
|
||||
handler.post {
|
||||
nsClientPlugin?.resetToFullSync()
|
||||
nsClientPlugin?.resend("FULL_SYNC")
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
true
|
||||
|
@ -127,28 +181,69 @@ class NSClientFragment : DaggerFragment(), MenuProvider, PluginFragment {
|
|||
else -> false
|
||||
}
|
||||
|
||||
@Synchronized override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGUI::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateGui() }, fabricPrivacy::logException)
|
||||
updateGui()
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
@Synchronized override fun onPause() {
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiData::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe(
|
||||
{
|
||||
_binding?.recyclerview?.swapAdapter(RecyclerViewAdapter(nsClientPlugin?.listLog ?: arrayListOf()), true)
|
||||
}, fabricPrivacy::logException
|
||||
)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiQueue::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateQueue() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientUpdateGuiStatus::class.java)
|
||||
.debounce(3L, TimeUnit.SECONDS)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateStatus() }, fabricPrivacy::logException)
|
||||
updateStatus()
|
||||
updateQueue()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun updateGui() {
|
||||
private fun updateQueue() {
|
||||
val size = nsClientPlugin?.dataSyncSelector?.queueSize() ?: 0L
|
||||
_binding?.queue?.text = if (size >= 0) size.toString() else rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
|
||||
}
|
||||
|
||||
private fun updateStatus() {
|
||||
if (_binding == null) return
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
binding.log.text = nsClientPlugin?.textLog()
|
||||
if (sp.getBoolean(R.string.key_ns_client_autoscroll, true)) binding.logScrollview.fullScroll(ScrollView.FOCUS_DOWN)
|
||||
binding.paused.isChecked = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
binding.url.text = nsClientPlugin?.address
|
||||
binding.status.text = nsClientPlugin?.status
|
||||
val size = dataSyncSelector.queueSize()
|
||||
binding.queue.text = if (size >= 0) size.toString() else rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
|
||||
}
|
||||
|
||||
private inner class RecyclerViewAdapter(private var logList: List<EventNSClientNewLog>) : RecyclerView.Adapter<RecyclerViewAdapter.NsClientLogViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): NsClientLogViewHolder =
|
||||
NsClientLogViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.ns_client_log_item, viewGroup, false))
|
||||
|
||||
override fun onBindViewHolder(holder: NsClientLogViewHolder, position: Int) {
|
||||
holder.binding.logText.text = HtmlHelper.fromHtml(logList[position].toPreparedHtml().toString())
|
||||
}
|
||||
|
||||
override fun getItemCount() = logList.size
|
||||
|
||||
inner class NsClientLogViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = NsClientLogItemBinding.bind(view)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.extensions.foodFromJson
|
||||
import info.nightscout.database.entities.Food
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSSgv
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.profile.ProfileSource
|
||||
import info.nightscout.interfaces.source.NSClientSource
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclientV3.extensions.*
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.food.NSFood
|
||||
import info.nightscout.sdk.localmodel.treatment.*
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class NsIncomingDataProcessor @Inject constructor(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val nsClientSource: NSClientSource,
|
||||
private val sp: SP,
|
||||
private val rxBus: RxBus,
|
||||
private val dateUtil: DateUtil,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val storeDataForDb: StoreDataForDb,
|
||||
private val config: Config,
|
||||
private val instantiator: Instantiator,
|
||||
private val profileSource: ProfileSource
|
||||
) {
|
||||
|
||||
private fun toGv(jsonObject: JSONObject): TransactionGlucoseValue? {
|
||||
val sgv = NSSgv(jsonObject)
|
||||
return TransactionGlucoseValue(
|
||||
timestamp = sgv.mills ?: return null,
|
||||
value = sgv.mgdl?.toDouble() ?: return null,
|
||||
noise = null,
|
||||
raw = sgv.filtered?.toDouble(),
|
||||
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction),
|
||||
nightscoutId = sgv.id,
|
||||
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device)
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
fun processSgvs(sgvs: Any) {
|
||||
|
||||
if (!nsClientSource.isEnabled() && !sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_cgm, false)) return
|
||||
|
||||
var latestDateInReceivedData: Long = 0
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Received NS Data: $sgvs")
|
||||
val glucoseValues = mutableListOf<TransactionGlucoseValue>()
|
||||
|
||||
if (sgvs is JSONArray) { // V1 client
|
||||
for (i in 0 until sgvs.length()) {
|
||||
val sgv = toGv(sgvs.getJSONObject(i)) ?: continue
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
} else if (sgvs is List<*>) { // V3 client
|
||||
|
||||
for (i in 0 until sgvs.size) {
|
||||
val sgv = (sgvs[i] as NSSgvV3).toTransactionGlucoseValue()
|
||||
if (sgv.timestamp < dateUtil.now() && sgv.timestamp > latestDateInReceivedData) latestDateInReceivedData = sgv.timestamp
|
||||
glucoseValues += sgv
|
||||
}
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestBgReceivedIfNewer(latestDateInReceivedData)
|
||||
// Was that sgv more less 5 mins ago ?
|
||||
if (T.msecs(dateUtil.now() - latestDateInReceivedData).mins() < 5L) {
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
}
|
||||
storeDataForDb.glucoseValues.addAll(glucoseValues)
|
||||
}
|
||||
|
||||
fun processTreatments(treatments: List<NSTreatment>) {
|
||||
try {
|
||||
var latestDateInReceivedData: Long = 0
|
||||
for (treatment in treatments) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received NS treatment: $treatment")
|
||||
val date = treatment.date ?: continue
|
||||
if (date > latestDateInReceivedData) latestDateInReceivedData = date
|
||||
|
||||
when (treatment) {
|
||||
is NSBolus ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_insulin, false) || config.NSCLIENT)
|
||||
storeDataForDb.boluses.add(treatment.toBolus())
|
||||
|
||||
is NSCarbs ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_carbs, false) || config.NSCLIENT)
|
||||
storeDataForDb.carbs.add(treatment.toCarbs())
|
||||
|
||||
is NSTemporaryTarget ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_temp_target, false) || config.NSCLIENT) {
|
||||
if (treatment.duration > 0L) {
|
||||
// not ending event
|
||||
if (treatment.targetBottomAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() < Constants.MIN_TT_MGDL
|
||||
|| treatment.targetTopAsMgdl() > Constants.MAX_TT_MGDL
|
||||
|| treatment.targetBottomAsMgdl() > treatment.targetTopAsMgdl()
|
||||
) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Ignored TemporaryTarget $treatment")
|
||||
continue
|
||||
}
|
||||
}
|
||||
storeDataForDb.temporaryTargets.add(treatment.toTemporaryTarget())
|
||||
}
|
||||
|
||||
is NSTemporaryBasal ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
storeDataForDb.temporaryBasals.add(treatment.toTemporaryBasal())
|
||||
|
||||
is NSEffectiveProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toEffectiveProfileSwitch(dateUtil)?.let { effectiveProfileSwitch ->
|
||||
storeDataForDb.effectiveProfileSwitches.add(effectiveProfileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSProfileSwitch ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_switch, false) || config.NSCLIENT) {
|
||||
treatment.toProfileSwitch(activePlugin, dateUtil)?.let { profileSwitch ->
|
||||
storeDataForDb.profileSwitches.add(profileSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
is NSBolusWizard ->
|
||||
treatment.toBolusCalculatorResult()?.let { bolusCalculatorResult ->
|
||||
storeDataForDb.bolusCalculatorResults.add(bolusCalculatorResult)
|
||||
}
|
||||
|
||||
is NSTherapyEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
treatment.toTherapyEvent().let { therapyEvent ->
|
||||
storeDataForDb.therapyEvents.add(therapyEvent)
|
||||
}
|
||||
|
||||
is NSOfflineEvent ->
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_offline_event, false) && config.isEngineeringMode() || config.NSCLIENT)
|
||||
treatment.toOfflineEvent().let { offlineEvent ->
|
||||
storeDataForDb.offlineEvents.add(offlineEvent)
|
||||
}
|
||||
|
||||
is NSExtendedBolus ->
|
||||
if (config.isEngineeringMode() && sp.getBoolean(R.string.key_ns_receive_tbr_eb, false) || config.NSCLIENT)
|
||||
treatment.toExtendedBolus().let { extendedBolus ->
|
||||
storeDataForDb.extendedBoluses.add(extendedBolus)
|
||||
}
|
||||
}
|
||||
}
|
||||
activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
}
|
||||
}
|
||||
|
||||
fun processFood(data: Any) {
|
||||
aapsLogger.debug(LTag.DATABASE, "Received Food Data: $data")
|
||||
|
||||
try {
|
||||
val foods = mutableListOf<Food>()
|
||||
if (data is JSONArray) {
|
||||
for (index in 0 until data.length()) {
|
||||
val jsonFood: JSONObject = data.getJSONObject(index)
|
||||
|
||||
if (JsonHelper.safeGetString(jsonFood, "type") != "food") continue
|
||||
|
||||
when (JsonHelper.safeGetString(jsonFood, "action")) {
|
||||
"remove" -> {
|
||||
val delFood = Food(
|
||||
name = "",
|
||||
portion = 0.0,
|
||||
carbs = 0,
|
||||
isValid = false
|
||||
).also { it.interfaceIDs.nightscoutId = JsonHelper.safeGetString(jsonFood, "_id") }
|
||||
foods += delFood
|
||||
}
|
||||
|
||||
else -> {
|
||||
val food = foodFromJson(jsonFood)
|
||||
if (food != null) foods += food
|
||||
else aapsLogger.error(LTag.DATABASE, "Error parsing food", jsonFood.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (data is List<*>) {
|
||||
for (i in 0 until data.size)
|
||||
foods += (data[i] as NSFood).toFood()
|
||||
}
|
||||
storeDataForDb.foods.addAll(foods)
|
||||
} catch (error: Exception) {
|
||||
aapsLogger.error("Error: ", error)
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
|
||||
}
|
||||
}
|
||||
|
||||
fun processProfile(profileJson: JSONObject) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_profile_store, true) || config.NSCLIENT) {
|
||||
val store = instantiator.provideProfileStore(profileJson)
|
||||
val createdAt = store.getStartDate()
|
||||
val lastLocalChange = sp.getLong(info.nightscout.core.utils.R.string.key_local_profile_last_change, 0)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: createdAt: $createdAt Local last modification: $lastLocalChange")
|
||||
@Suppress("LiftReturnOrAssignment")
|
||||
if (createdAt > lastLocalChange || createdAt % 1000 == 0L) {// whole second means edited in NS
|
||||
profileSource.loadFromStore(store)
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
|
||||
import android.content.Context
|
||||
import android.os.SystemClock
|
||||
import androidx.work.WorkerParameters
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.database.entities.Carbs
|
||||
|
@ -48,7 +45,6 @@ import info.nightscout.database.impl.transactions.UpdateNsIdTherapyEventTransact
|
|||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
|
@ -61,7 +57,6 @@ import info.nightscout.rx.logging.AAPSLogger
|
|||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -78,7 +73,6 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
private val dateUtil: DateUtil,
|
||||
private val config: Config,
|
||||
private val nsClientSource: NSClientSource,
|
||||
private val xDripBroadcast: XDripBroadcast,
|
||||
private val virtualPump: VirtualPump,
|
||||
private val uiInteraction: UiInteraction
|
||||
) : StoreDataForDb {
|
||||
|
@ -121,39 +115,11 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
private val pause = 1000L // to slow down db operations
|
||||
|
||||
class StoreBgWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
class StoreFoodWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : LoggingWorker(context, params, Dispatchers.Default) {
|
||||
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> HashMap<T, Long>.inc(key: T) =
|
||||
if (containsKey(key)) merge(key, 1, Long::plus)
|
||||
else put(key, 1)
|
||||
|
||||
override fun storeGlucoseValuesToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING BG", ""))
|
||||
|
||||
if (glucoseValues.isNotEmpty())
|
||||
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
||||
.doOnError {
|
||||
|
@ -163,19 +129,16 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
glucoseValues.clear()
|
||||
result.updated.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated bg $it")
|
||||
updated.inc(GlucoseValue::class.java.simpleName)
|
||||
}
|
||||
result.inserted.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
inserted.inc(GlucoseValue::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bg $it")
|
||||
nsIdUpdated.inc(GlucoseValue::class.java.simpleName)
|
||||
|
@ -184,12 +147,10 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
sendLog("GlucoseValue", GlucoseValue::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
rxBus.send(EventNSClientNewLog("DONE BG", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING BG", ""))
|
||||
}
|
||||
|
||||
override fun storeFoodsToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING FOOD", ""))
|
||||
|
||||
if (foods.isNotEmpty())
|
||||
repository.runTransactionForResult(SyncNsFoodTransaction(foods))
|
||||
.doOnError {
|
||||
|
@ -214,12 +175,10 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
|
||||
sendLog("Food", Food::class.java.simpleName)
|
||||
SystemClock.sleep(pause)
|
||||
rxBus.send(EventNSClientNewLog("DONE FOOD", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING FOOD", ""))
|
||||
}
|
||||
|
||||
override fun storeTreatmentsToDb() {
|
||||
rxBus.send(EventNSClientNewLog("PROCESSING TR", ""))
|
||||
|
||||
if (boluses.isNotEmpty())
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(boluses))
|
||||
.doOnError {
|
||||
|
@ -796,11 +755,13 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
SystemClock.sleep(pause)
|
||||
|
||||
uel.log(userEntries)
|
||||
rxBus.send(EventNSClientNewLog("DONE TR", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE PROCESSING TR", ""))
|
||||
}
|
||||
|
||||
private val eventWorker = Executors.newSingleThreadScheduledExecutor()
|
||||
private var scheduledEventPost: ScheduledFuture<*>? = null
|
||||
|
||||
@Synchronized
|
||||
override fun scheduleNsIdUpdate() {
|
||||
class PostRunnable : Runnable {
|
||||
|
||||
|
@ -816,7 +777,8 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
scheduledEventPost = eventWorker.schedule(task, 10, TimeUnit.SECONDS)
|
||||
}
|
||||
|
||||
private fun updateNsIds() {
|
||||
@Synchronized
|
||||
override fun updateNsIds() {
|
||||
repository.runTransactionForResult(UpdateNsIdTemporaryTargetTransaction(nsIdTemporaryTargets))
|
||||
.doOnError { error ->
|
||||
aapsLogger.error(LTag.DATABASE, "Updated nsId of TemporaryTarget failed", error)
|
||||
|
@ -996,32 +958,32 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
sendLog("TherapyEvent", TherapyEvent::class.java.simpleName)
|
||||
sendLog("OfflineEvent", OfflineEvent::class.java.simpleName)
|
||||
sendLog("ExtendedBolus", ExtendedBolus::class.java.simpleName)
|
||||
rxBus.send(EventNSClientNewLog("DONE NSIDs", ""))
|
||||
rxBus.send(EventNSClientNewLog("● DONE NSIDs", ""))
|
||||
}
|
||||
|
||||
private fun sendLog(item: String, clazz: String) {
|
||||
inserted[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("INSERT", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ INSERT", "$item $it"))
|
||||
}
|
||||
inserted.remove(clazz)
|
||||
updated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("UPDATE", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ UPDATE", "$item $it"))
|
||||
}
|
||||
updated.remove(clazz)
|
||||
invalidated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("INVALIDATE", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ INVALIDATE", "$item $it"))
|
||||
}
|
||||
invalidated.remove(clazz)
|
||||
nsIdUpdated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("NS_ID", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ NS_ID", "$item $it"))
|
||||
}
|
||||
nsIdUpdated.remove(clazz)
|
||||
durationUpdated[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("DURATION", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DURATION", "$item $it"))
|
||||
}
|
||||
durationUpdated.remove(clazz)
|
||||
ended[clazz]?.let {
|
||||
rxBus.send(EventNSClientNewLog("CUT", "$item $it"))
|
||||
rxBus.send(EventNSClientNewLog("◄ CUT", "$item $it"))
|
||||
}
|
||||
ended.remove(clazz)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.Event
|
||||
|
||||
class EventConnectivityOptionChanged(val blockingReason: String) : Event()
|
|
@ -2,4 +2,4 @@ package info.nightscout.plugins.sync.nsShared.events
|
|||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGUI : EventUpdateGui()
|
||||
class EventNSClientUpdateGuiData : EventUpdateGui()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGuiQueue : EventUpdateGui()
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.plugins.sync.nsShared.events
|
||||
|
||||
import info.nightscout.rx.events.EventUpdateGui
|
||||
|
||||
class EventNSClientUpdateGuiStatus : EventUpdateGui()
|
|
@ -1,12 +1,15 @@
|
|||
package info.nightscout.plugins.sync.nsShared
|
||||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -15,14 +18,15 @@ import javax.inject.Inject
|
|||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class DataSyncSelectorImplementation @Inject constructor(
|
||||
class DataSyncSelectorV1Impl @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val appRepository: AppRepository
|
||||
) : DataSyncSelector {
|
||||
private val appRepository: AppRepository,
|
||||
private val rxBus: RxBus
|
||||
) : DataSyncSelectorV1 {
|
||||
|
||||
class QueueCounter(
|
||||
var bolusesRemaining: Long = -1L,
|
||||
|
@ -57,12 +61,27 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
|
||||
private val queueCounter = QueueCounter()
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_client_paused, false)
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override fun doUpload() {
|
||||
override suspend fun doUpload() {
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
|
||||
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
processChangedBoluses()
|
||||
processChangedCarbs()
|
||||
processChangedBolusCalculatorResults()
|
||||
|
@ -78,6 +97,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
processChangedOfflineEvents()
|
||||
processChangedProfileStore()
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
|
@ -95,8 +115,8 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
sp.remove(R.string.key_ns_offline_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||
|
||||
val lastDeviceStatusDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
if (lastDeviceStatusDbIdWrapped is ValueWrapper.Existing) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbIdWrapped.value)
|
||||
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
|
||||
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
|
||||
else sp.remove(R.string.key_ns_device_status_last_synced_id)
|
||||
}
|
||||
|
||||
|
@ -107,16 +127,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedBoluses() {
|
||||
override tailrec suspend fun processChangedBoluses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bolusesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ")
|
||||
when {
|
||||
|
@ -136,18 +156,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
bolus.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
|
||||
" $startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId")
|
||||
// with nsId = update if it's modified record
|
||||
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -160,16 +172,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedCarbs() {
|
||||
override tailrec suspend fun processChangedCarbs() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastCarbsId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.carbsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ")
|
||||
when {
|
||||
|
@ -209,16 +221,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedBolusCalculatorResults() {
|
||||
override tailrec suspend fun processChangedBolusCalculatorResults() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bcrRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ")
|
||||
when {
|
||||
|
@ -238,17 +250,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update if it's modified record
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -261,16 +266,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTempTargets() {
|
||||
override tailrec suspend fun processChangedTempTargets() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ttsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ")
|
||||
when {
|
||||
|
@ -290,18 +295,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
tt.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
|
||||
// existing with nsId = update
|
||||
tt.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -314,16 +311,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedFoods() {
|
||||
override tailrec suspend fun processChangedFoods() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastFoodId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.foodsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ")
|
||||
when {
|
||||
|
@ -346,11 +343,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
food.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"food",
|
||||
DataSyncSelector.PairFood(food.first, food.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -363,16 +356,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedGlucoseValues() {
|
||||
override tailrec suspend fun processChangedGlucoseValues() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.gvsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading GlucoseValue data Start: $startId ${gv.first} forID: ${gv.second.id} ")
|
||||
if (activePlugin.activeBgSource.shouldUploadToNs(gv.first)) {
|
||||
|
@ -396,11 +389,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
else -> // gv.first.interfaceIDs.nightscoutId != null
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"entries",
|
||||
DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
} else {
|
||||
confirmLastGlucoseValueIdIfGreater(gv.second.id)
|
||||
|
@ -417,16 +406,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTherapyEvents() {
|
||||
override tailrec suspend fun processChangedTherapyEvents() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ")
|
||||
when {
|
||||
|
@ -449,11 +438,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
|
||||
// nsId = update
|
||||
te.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTherapyEvent(te.first, te.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -466,16 +451,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun processChangedDeviceStatuses() {
|
||||
override suspend fun processChangedDeviceStatuses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.dssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
|
||||
when {
|
||||
|
@ -496,16 +481,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedTemporaryBasals() {
|
||||
override tailrec suspend fun processChangedTemporaryBasals() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tbrsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ")
|
||||
when {
|
||||
|
@ -525,18 +510,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
tb.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
tb.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -549,16 +526,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedExtendedBoluses() {
|
||||
override tailrec suspend fun processChangedExtendedBoluses() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ebsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ")
|
||||
val profile = profileFunction.getProfile(eb.first.timestamp)
|
||||
|
@ -580,18 +557,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
eb.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
eb.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
} else {
|
||||
|
@ -610,16 +579,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedProfileSwitches() {
|
||||
override tailrec suspend fun processChangedProfileSwitches() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.pssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
|
@ -642,11 +611,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -659,16 +624,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedEffectiveProfileSwitches() {
|
||||
override tailrec suspend fun processChangedEffectiveProfileSwitches() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.epssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
|
@ -688,18 +653,10 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -712,16 +669,16 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override tailrec fun processChangedOfflineEvents() {
|
||||
override tailrec suspend fun processChangedOfflineEvents() {
|
||||
if (isPaused) return
|
||||
val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet()
|
||||
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.oesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ")
|
||||
when {
|
||||
|
@ -744,11 +701,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
|
||||
// existing with nsId = update
|
||||
oe.first.interfaceIDs.nightscoutId != null ->
|
||||
activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id),
|
||||
"$startId/$lastDbId"
|
||||
)
|
||||
activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -758,7 +711,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
override fun processChangedProfileStore() {
|
||||
override suspend 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)
|
|
@ -4,17 +4,13 @@ import android.content.ComponentName
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.IBinder
|
||||
import android.text.Spanned
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreference
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.extensions.toJson
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.core.validators.ValidatingEditTextPreference
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
|
@ -26,24 +22,22 @@ import info.nightscout.interfaces.plugin.PluginType
|
|||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.source.DoingOwnUploadSource
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.sync.NsClient
|
||||
import info.nightscout.interfaces.sync.Sync
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HtmlHelper.fromHtml
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.NSClientFragment
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientResend
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiData
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclient.data.AlarmAck
|
||||
import info.nightscout.plugins.sync.nsclient.extensions.toJson
|
||||
import info.nightscout.plugins.sync.nsclient.services.NSClientService
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventSWSyncStatus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
|
@ -66,10 +60,9 @@ class NSClientPlugin @Inject constructor(
|
|||
private val context: Context,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val sp: SP,
|
||||
private val nsClientReceiverDelegate: NsClientReceiverDelegate,
|
||||
private val receiverDelegate: ReceiverDelegate,
|
||||
private val config: Config,
|
||||
private val dataSyncSelector: DataSyncSelector,
|
||||
private val uiInteraction: UiInteraction,
|
||||
private val dataSyncSelectorV1: DataSyncSelectorV1,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
|
@ -87,36 +80,28 @@ class NSClientPlugin @Inject constructor(
|
|||
) {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
private val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val listLog: MutableList<EventNSClientNewLog> = ArrayList()
|
||||
override val dataSyncSelector: DataSyncSelector get() = dataSyncSelectorV1
|
||||
override var status = ""
|
||||
var nsClientService: NSClientService? = null
|
||||
val isAllowed: Boolean
|
||||
get() = nsClientReceiverDelegate.allowed
|
||||
get() = receiverDelegate.allowed
|
||||
val blockingReason: String
|
||||
get() = nsClientReceiverDelegate.blockingReason
|
||||
get() = receiverDelegate.blockingReason
|
||||
|
||||
override fun onStart() {
|
||||
context.bindService(Intent(context, NSClientService::class.java), mConnection, Context.BIND_AUTO_CREATE)
|
||||
super.onStart()
|
||||
nsClientReceiverDelegate.grabReceiversState()
|
||||
receiverDelegate.grabReceiversState()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientStatus::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ event ->
|
||||
status = event.getStatus(context)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
// Pass to setup wizard
|
||||
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
||||
status = event.getStatus(context)
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
// Pass to setup wizard
|
||||
rxBus.send(EventSWSyncStatus(event.getStatus(context)))
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -128,10 +113,6 @@ class NSClientPlugin @Inject constructor(
|
|||
addToLog(event)
|
||||
aapsLogger.debug(LTag.NSCLIENT, event.action + " " + event.logText)
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> nsClientReceiverDelegate.onStatusEvent(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSClientResend::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -174,37 +155,17 @@ class NSClientPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun clearLog() {
|
||||
handler.post {
|
||||
synchronized(listLog) { listLog.clear() }
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
}
|
||||
|
||||
override fun detectedNsVersion(): String? = nsSettingsStatus.getVersion()
|
||||
override fun detectedNsVersion(): String = nsSettingsStatus.getVersion()
|
||||
|
||||
private fun addToLog(ev: EventNSClientNewLog) {
|
||||
synchronized(listLog) {
|
||||
listLog.add(ev)
|
||||
listLog.add(0, ev)
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size >= Constants.MAX_LOG_LINES) {
|
||||
listLog.removeAt(0)
|
||||
listLog.removeAt(listLog.size - 1)
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGuiData())
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
}
|
||||
|
||||
override fun textLog(): Spanned {
|
||||
try {
|
||||
val newTextLog = StringBuilder()
|
||||
synchronized(listLog) {
|
||||
for (log in listLog) newTextLog.append(log.toPreparedHtml())
|
||||
}
|
||||
return fromHtml(newTextLog.toString())
|
||||
} catch (e: OutOfMemoryError) {
|
||||
uiInteraction.showToastAndNotification(context, "Out of memory!\nStop using this phone !!!", info.nightscout.core.ui.R.raw.error)
|
||||
}
|
||||
return fromHtml("")
|
||||
}
|
||||
|
||||
override fun resend(reason: String) {
|
||||
|
@ -212,8 +173,8 @@ class NSClientPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
override fun pause(newState: Boolean) {
|
||||
sp.putBoolean(R.string.key_ns_client_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
||||
sp.putBoolean(R.string.key_ns_paused, newState)
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_paused)))
|
||||
}
|
||||
|
||||
override val address: String get() = nsClientService?.nsURL ?: ""
|
||||
|
@ -244,7 +205,7 @@ class NSClientPlugin @Inject constructor(
|
|||
dataSyncSelector.resetToNextFullSync()
|
||||
}
|
||||
|
||||
override fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean {
|
||||
when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
|
||||
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
|
||||
|
@ -264,9 +225,10 @@ class NSClientPlugin @Inject constructor(
|
|||
}?.let { data ->
|
||||
nsClientService?.dbAdd(collection, data, dataPair, progress)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
|
||||
override suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean {
|
||||
val id = when (dataPair) {
|
||||
is DataSyncSelector.PairBolus -> dataPair.value.interfaceIDs.nightscoutId
|
||||
is DataSyncSelector.PairCarbs -> dataPair.value.interfaceIDs.nightscoutId
|
||||
|
@ -299,5 +261,6 @@ class NSClientPlugin @Inject constructor(
|
|||
}?.let { data ->
|
||||
nsClientService?.dbUpdate(collection, id, data, dataPair, progress)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,43 +1,67 @@
|
|||
package info.nightscout.plugins.sync.nsclient
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventChargingState
|
||||
import info.nightscout.rx.events.EventNetworkChange
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class NsClientReceiverDelegate @Inject constructor(
|
||||
class ReceiverDelegate @Inject constructor(
|
||||
private val rxBus: RxBus,
|
||||
private val rh: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val receiverStatusStore: ReceiverStatusStore
|
||||
private val receiverStatusStore: ReceiverStatusStore,
|
||||
aapsSchedulers: AapsSchedulers,
|
||||
fabricPrivacy: FabricPrivacy
|
||||
) {
|
||||
|
||||
private var allowedChargingState = true
|
||||
private var allowedNetworkState = true
|
||||
var allowed = true
|
||||
var blockingReason = ""
|
||||
private var allowedChargingState: Boolean? = null
|
||||
private var allowedNetworkState: Boolean? = null
|
||||
var allowed: Boolean = false
|
||||
var blockingReason = "Status not available"
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
init {
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onPreferenceChange(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNetworkChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onNetworkChange(ev) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventChargingState::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ev -> onChargingStateChange(ev) }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
fun grabReceiversState() {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventPreferenceChange) {
|
||||
private fun onPreferenceChange(ev: EventPreferenceChange) {
|
||||
when {
|
||||
ev.isChanged(rh.gs(R.string.key_ns_wifi)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_cellular)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_wifi_ssids)) ||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_allow_roaming)) -> {
|
||||
receiverStatusStore.updateNetworkStatus()
|
||||
receiverStatusStore.lastNetworkEvent?.let { onStatusEvent(it) }
|
||||
receiverStatusStore.lastNetworkEvent?.let { onNetworkChange(it) }
|
||||
}
|
||||
|
||||
ev.isChanged(rh.gs(R.string.key_ns_charging)) ||
|
||||
|
@ -47,29 +71,30 @@ class NsClientReceiverDelegate @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventChargingState) {
|
||||
private fun onChargingStateChange(ev: EventChargingState) {
|
||||
val newChargingState = calculateStatus(ev)
|
||||
if (newChargingState != allowedChargingState) {
|
||||
allowedChargingState = newChargingState
|
||||
blockingReason = rh.gs(R.string.blocked_by_charging)
|
||||
if (!newChargingState) blockingReason = rh.gs(R.string.blocked_by_charging)
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
fun onStatusEvent(ev: EventNetworkChange) {
|
||||
private fun onNetworkChange(ev: EventNetworkChange) {
|
||||
val newNetworkState = calculateStatus(ev)
|
||||
if (newNetworkState != allowedNetworkState) {
|
||||
allowedNetworkState = newNetworkState
|
||||
blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
||||
if (!newNetworkState) blockingReason = rh.gs(R.string.blocked_by_connectivity)
|
||||
processStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
private fun processStateChange() {
|
||||
val newAllowedState = allowedChargingState && allowedNetworkState
|
||||
val newAllowedState = allowedChargingState == true && allowedNetworkState == true
|
||||
if (newAllowedState != allowed) {
|
||||
allowed = newAllowedState
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.key_ns_client_paused)))
|
||||
if (allowed) blockingReason = ""
|
||||
rxBus.send(EventConnectivityOptionChanged(blockingReason))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.plugins.sync.nsclient.data
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.configBuilder.RunningConfiguration
|
||||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
|
@ -65,6 +66,7 @@ import javax.inject.Singleton
|
|||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Singleton
|
||||
@OpenForTesting
|
||||
class NSDeviceStatusHandler @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val config: Config,
|
||||
|
|
|
@ -24,15 +24,16 @@ import info.nightscout.interfaces.Config
|
|||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import info.nightscout.interfaces.nsclient.NSSettingsStatus
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.JsonHelper.safeGetString
|
||||
import info.nightscout.interfaces.utils.JsonHelper.safeGetStringAllowNull
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
|
||||
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventConnectivityOptionChanged
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAuthAck
|
||||
|
@ -41,15 +42,9 @@ import info.nightscout.plugins.sync.nsclient.data.AlarmAck
|
|||
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker
|
||||
import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppExit
|
||||
import info.nightscout.rx.events.EventConfigBuilderChange
|
||||
import info.nightscout.rx.events.EventDismissNotification
|
||||
import info.nightscout.rx.events.EventNSClientNewLog
|
||||
import info.nightscout.rx.events.EventNSClientRestart
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.*
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
|
||||
|
@ -62,14 +57,19 @@ import io.reactivex.rxjava3.kotlin.plusAssign
|
|||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import io.socket.emitter.Emitter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.net.URISyntaxException
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSClientService : DaggerService() {
|
||||
@Suppress("SpellCheckingInspection") class NSClientService : DaggerService() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
@ -84,10 +84,11 @@ class NSClientService : DaggerService() {
|
|||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uiInteraction: UiInteraction
|
||||
@Inject lateinit var workerClasses: WorkerClasses
|
||||
@Inject lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -97,6 +98,7 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
private var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private val binder: IBinder = LocalBinder()
|
||||
|
@ -139,13 +141,21 @@ class NSClientService : DaggerService() {
|
|||
.subscribe({ event: EventPreferenceChange ->
|
||||
if (event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_url)) ||
|
||||
event.isChanged(rh.gs(info.nightscout.core.utils.R.string.key_nsclientinternal_api_secret)) ||
|
||||
event.isChanged(rh.gs(R.string.key_ns_client_paused))
|
||||
event.isChanged(rh.gs(R.string.key_ns_paused))
|
||||
) {
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventConnectivityOptionChanged::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
latestDateInReceivedData = 0
|
||||
destroy()
|
||||
initialize()
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAppExit::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
|
@ -165,6 +175,10 @@ class NSClientService : DaggerService() {
|
|||
.toObservable(NSAuthAck::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ ack -> processAuthAck(ack) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventNewHistoryData::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ resend("NEW_DATA") }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -182,12 +196,12 @@ class NSClientService : DaggerService() {
|
|||
isConnected = true
|
||||
hasWriteAuth = ack.write && ack.writeTreatment
|
||||
rxBus.send(EventNSClientStatus(connectionStatus))
|
||||
rxBus.send(EventNSClientNewLog("AUTH", connectionStatus))
|
||||
rxBus.send(EventNSClientNewLog("◄ AUTH", connectionStatus))
|
||||
if (!ack.write) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write permission not granted "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Write permission not granted "))
|
||||
}
|
||||
if (!ack.writeTreatment) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Write treatment permission not granted "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Write treatment permission not granted "))
|
||||
}
|
||||
if (!hasWriteAuth) {
|
||||
val noWritePerm = Notification(Notification.NSCLIENT_NO_WRITE_PERMISSION, rh.gs(R.string.no_write_permission), Notification.URGENT)
|
||||
|
@ -214,28 +228,22 @@ class NSClientService : DaggerService() {
|
|||
if (nsAPISecret != "") nsApiHashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString()
|
||||
rxBus.send(EventNSClientStatus("Initializing"))
|
||||
if (!nsClientPlugin.isAllowed) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", nsClientPlugin.blockingReason))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", nsClientPlugin.blockingReason))
|
||||
rxBus.send(EventNSClientStatus(nsClientPlugin.blockingReason))
|
||||
} else if (sp.getBoolean(R.string.key_ns_client_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "paused"))
|
||||
} else if (sp.getBoolean(R.string.key_ns_paused, false)) {
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "paused"))
|
||||
rxBus.send(EventNSClientStatus("Paused"))
|
||||
} else if (!nsEnabled) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disabled"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "disabled"))
|
||||
rxBus.send(EventNSClientStatus("Disabled"))
|
||||
} else if (nsURL != "" && (nsURL.lowercase(Locale.getDefault()).startsWith("https://"))) {
|
||||
try {
|
||||
rxBus.send(EventNSClientStatus("Connecting ..."))
|
||||
val opt = IO.Options()
|
||||
opt.forceNew = true
|
||||
opt.reconnection = true
|
||||
val opt = IO.Options().also { it.forceNew = true }
|
||||
socket = IO.socket(nsURL, opt).also { socket ->
|
||||
socket.on(Socket.EVENT_CONNECT, onConnect)
|
||||
socket.on(Socket.EVENT_DISCONNECT, onDisconnect)
|
||||
socket.on(Socket.EVENT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_ERROR, onError)
|
||||
socket.on(Socket.EVENT_CONNECT_TIMEOUT, onError)
|
||||
socket.on(Socket.EVENT_PING, onPing)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "do connect"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "do connect"))
|
||||
socket.connect()
|
||||
socket.on("dataUpdate", onDataUpdate)
|
||||
socket.on("announcement", onAnnouncement)
|
||||
|
@ -244,17 +252,17 @@ class NSClientService : DaggerService() {
|
|||
socket.on("clear_alarm", onClearAlarm)
|
||||
}
|
||||
} catch (e: URISyntaxException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
} catch (e: RuntimeException) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "Wrong URL syntax"))
|
||||
rxBus.send(EventNSClientStatus("Wrong URL syntax"))
|
||||
}
|
||||
} else if (nsURL.lowercase(Locale.getDefault()).startsWith("http://")) {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "NS URL not encrypted"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "NS URL not encrypted"))
|
||||
rxBus.send(EventNSClientStatus("Not encrypted"))
|
||||
} else {
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "No NS URL specified"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "No NS URL specified"))
|
||||
rxBus.send(EventNSClientStatus("Not configured"))
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +270,7 @@ class NSClientService : DaggerService() {
|
|||
private val onConnect = Emitter.Listener {
|
||||
connectCounter++
|
||||
val socketId = socket?.id() ?: "NULL"
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "connect #$connectCounter event. ID: $socketId"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "connect #$connectCounter event. ID: $socketId"))
|
||||
if (socket != null) sendAuthMessage(NSAuthAck(rxBus))
|
||||
watchdog()
|
||||
}
|
||||
|
@ -276,16 +284,16 @@ class NSClientService : DaggerService() {
|
|||
reconnections.remove(r)
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " minutes: " + reconnections.size + "/" + WATCHDOG_MAX_CONNECTIONS))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " minutes: " + reconnections.size + "/" + WATCHDOG_MAX_CONNECTIONS))
|
||||
if (reconnections.size >= WATCHDOG_MAX_CONNECTIONS) {
|
||||
val n = Notification(Notification.NS_MALFUNCTION, rh.gs(R.string.ns_malfunction), Notification.URGENT)
|
||||
rxBus.send(EventNewNotification(n))
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "pausing for $WATCHDOG_RECONNECT_IN minutes"))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "pausing for $WATCHDOG_RECONNECT_IN minutes"))
|
||||
nsClientPlugin.pause(true)
|
||||
rxBus.send(EventNSClientUpdateGUI())
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
Thread {
|
||||
SystemClock.sleep(mins(WATCHDOG_RECONNECT_IN.toLong()).msecs())
|
||||
rxBus.send(EventNSClientNewLog("WATCHDOG", "re-enabling NSClient"))
|
||||
rxBus.send(EventNSClientNewLog("● WATCHDOG", "re-enabling NSClient"))
|
||||
nsClientPlugin.pause(false)
|
||||
}.start()
|
||||
}
|
||||
|
@ -294,19 +302,18 @@ class NSClientService : DaggerService() {
|
|||
|
||||
private val onDisconnect = Emitter.Listener { args ->
|
||||
aapsLogger.debug(LTag.NSCLIENT, "disconnect reason: {}", *args)
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "disconnect event"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "disconnect event"))
|
||||
}
|
||||
|
||||
@Synchronized fun destroy() {
|
||||
socket?.off(Socket.EVENT_CONNECT)
|
||||
socket?.off(Socket.EVENT_DISCONNECT)
|
||||
socket?.off(Socket.EVENT_PING)
|
||||
socket?.off("dataUpdate")
|
||||
socket?.off("announcement")
|
||||
socket?.off("alarm")
|
||||
socket?.off("urgent_alarm")
|
||||
socket?.off("clear_alarm")
|
||||
rxBus.send(EventNSClientNewLog("NSCLIENT", "destroy"))
|
||||
rxBus.send(EventNSClientNewLog("● NSCLIENT", "destroy"))
|
||||
isConnected = false
|
||||
hasWriteAuth = false
|
||||
socket?.disconnect()
|
||||
|
@ -325,7 +332,7 @@ class NSClientService : DaggerService() {
|
|||
aapsLogger.error("Unhandled exception", e)
|
||||
return
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("AUTH", "requesting auth"))
|
||||
rxBus.send(EventNSClientNewLog("► AUTH", "requesting auth"))
|
||||
socket?.emit("authorize", authMessage, ack)
|
||||
}
|
||||
|
||||
|
@ -336,18 +343,6 @@ class NSClientService : DaggerService() {
|
|||
nsDevice = sp.getString("careportal_enteredby", "")
|
||||
}
|
||||
|
||||
private val onError = Emitter.Listener { args ->
|
||||
var msg = "Unknown Error"
|
||||
if (args.isNotEmpty() && args[0] != null) {
|
||||
msg = args[0].toString()
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ERROR", msg))
|
||||
}
|
||||
private val onPing = Emitter.Listener {
|
||||
rxBus.send(EventNSClientNewLog("PING", "received"))
|
||||
// send data if there is something waiting
|
||||
resend("Ping received")
|
||||
}
|
||||
private val onAnnouncement = Emitter.Listener { args ->
|
||||
|
||||
/*
|
||||
|
@ -414,7 +409,7 @@ class NSClientService : DaggerService() {
|
|||
val data: JSONObject
|
||||
try {
|
||||
data = args[0] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("CLEARALARM", "received"))
|
||||
rxBus.send(EventNSClientNewLog("◄ CLEARALARM", "received"))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_ALARM))
|
||||
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
|
||||
aapsLogger.debug(LTag.NSCLIENT, data.toString())
|
||||
|
@ -433,30 +428,26 @@ class NSClientService : DaggerService() {
|
|||
try {
|
||||
// delta means only increment/changes are coming
|
||||
val isDelta = data.has("delta")
|
||||
rxBus.send(EventNSClientNewLog("DATA", "Data packet #" + dataCounter++ + if (isDelta) " delta" else " full"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "Data packet #" + dataCounter++ + if (isDelta) " delta" else " full"))
|
||||
if (data.has("status")) {
|
||||
val status = data.getJSONObject("status")
|
||||
nsSettingsStatus.handleNewData(status)
|
||||
} else if (!isDelta) {
|
||||
rxBus.send(EventNSClientNewLog("ERROR", "Unsupported Nightscout version "))
|
||||
rxBus.send(EventNSClientNewLog("◄ ERROR", "Unsupported Nightscout version "))
|
||||
}
|
||||
if (data.has("profiles")) {
|
||||
val profiles = data.getJSONArray("profiles")
|
||||
if (profiles.length() > 0) {
|
||||
// take the newest
|
||||
val profileStoreJson = profiles[profiles.length() - 1] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("PROFILE", "profile received"))
|
||||
dataWorkerStorage.enqueue(
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsProfileWorker)
|
||||
.setInputData(dataWorkerStorage.storeInputData(profileStoreJson))
|
||||
.build()
|
||||
)
|
||||
rxBus.send(EventNSClientNewLog("◄ PROFILE", "profile received"))
|
||||
nsIncomingDataProcessor.processProfile(profileStoreJson)
|
||||
}
|
||||
}
|
||||
if (data.has("treatments")) {
|
||||
val treatments = data.getJSONArray("treatments")
|
||||
val addedOrUpdatedTreatments = JSONArray()
|
||||
if (treatments.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"))
|
||||
if (treatments.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + treatments.length() + " treatments"))
|
||||
for (index in 0 until treatments.length()) {
|
||||
val jsonTreatment = treatments.getJSONObject(index)
|
||||
val action = safeGetStringAllowNull(jsonTreatment, "action", null)
|
||||
|
@ -502,7 +493,7 @@ class NSClientService : DaggerService() {
|
|||
aapsLogger.warn(
|
||||
LTag.NSCLIENT,
|
||||
"JSON devicestatus object #$arrayIndex (out of ${devicestatusJsonArray.length()}) " +
|
||||
"has invalid value \"$batteryValue\" (expected integer); replacing with hardcoded integer 100"
|
||||
"has invalid value \"$batteryValue\" (expected integer); replacing with hardcoded integer 100"
|
||||
)
|
||||
uploaderObject.put("battery", 100)
|
||||
}
|
||||
|
@ -512,7 +503,7 @@ class NSClientService : DaggerService() {
|
|||
|
||||
val devicestatuses = gson.fromJson(data.getString("devicestatus"), Array<NSDeviceStatus>::class.java)
|
||||
if (devicestatuses.isNotEmpty()) {
|
||||
rxBus.send(EventNSClientNewLog("DATA", "received " + devicestatuses.size + " device statuses"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "received " + devicestatuses.size + " device statuses"))
|
||||
nsDeviceStatusHandler.handleNewData(devicestatuses)
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
|
@ -521,19 +512,13 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
if (data.has("food")) {
|
||||
val foods = data.getJSONArray("food")
|
||||
if (foods.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + foods.length() + " foods"))
|
||||
dataWorkerStorage
|
||||
.beginUniqueWork(
|
||||
"ProcessFoods",
|
||||
OneTimeWorkRequest.Builder(ProcessFoodWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(foods))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreFoodWorker::class.java).build())
|
||||
.enqueue()
|
||||
if (foods.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + foods.length() + " foods"))
|
||||
nsIncomingDataProcessor.processFood(foods)
|
||||
storeDataForDb.storeFoodsToDb()
|
||||
}
|
||||
if (data.has("mbgs")) {
|
||||
val mbgArray = data.getJSONArray("mbgs")
|
||||
if (mbgArray.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + mbgArray.length() + " mbgs"))
|
||||
if (mbgArray.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + mbgArray.length() + " mbgs"))
|
||||
dataWorkerStorage.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSClientMbgWorker::class.java)
|
||||
.setInputData(dataWorkerStorage.storeInputData(mbgArray))
|
||||
|
@ -542,26 +527,20 @@ class NSClientService : DaggerService() {
|
|||
}
|
||||
if (data.has("cals")) {
|
||||
val cals = data.getJSONArray("cals")
|
||||
if (cals.length() > 0) rxBus.send(EventNSClientNewLog("DATA", "received " + cals.length() + " cals"))
|
||||
if (cals.length() > 0) rxBus.send(EventNSClientNewLog("◄ DATA", "received " + cals.length() + " cals"))
|
||||
// Calibrations ignored
|
||||
}
|
||||
if (data.has("sgvs")) {
|
||||
val sgvs = data.getJSONArray("sgvs")
|
||||
if (sgvs.length() > 0) {
|
||||
rxBus.send(EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs"))
|
||||
rxBus.send(EventNSClientNewLog("◄ DATA", "received " + sgvs.length() + " sgvs"))
|
||||
// Objective0
|
||||
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
|
||||
dataWorkerStorage
|
||||
.beginUniqueWork(
|
||||
"ProcessBg",
|
||||
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker)
|
||||
.setInputData(dataWorkerStorage.storeInputData(sgvs))
|
||||
.build()
|
||||
).then(OneTimeWorkRequest.Builder(StoreDataForDbImpl.StoreBgWorker::class.java).build())
|
||||
.enqueue()
|
||||
nsIncomingDataProcessor.processSgvs(sgvs)
|
||||
storeDataForDb.storeGlucoseValuesToDb()
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
|
||||
rxBus.send(EventNSClientNewLog("◄ LAST", dateUtil.dateAndTimeString(latestDateInReceivedData)))
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
|
@ -583,7 +562,7 @@ class NSClientService : DaggerService() {
|
|||
socket?.emit("dbUpdate", message, NSUpdateAck("dbUpdate", _id, aapsLogger, rxBus, this, dateUtil, dataWorkerStorage, originalObject))
|
||||
rxBus.send(
|
||||
EventNSClientNewLog(
|
||||
"UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"► UPDATE $collection", "Sent " + originalObject.javaClass.simpleName + " " +
|
||||
"" + _id + " " + data + progress
|
||||
)
|
||||
)
|
||||
|
@ -599,7 +578,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("ADD $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)
|
||||
}
|
||||
|
@ -608,29 +587,22 @@ class NSClientService : DaggerService() {
|
|||
fun sendAlarmAck(alarmAck: AlarmAck) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
socket?.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime)
|
||||
rxBus.send(EventNSClientNewLog("ALARMACK ", alarmAck.level.toString() + " " + alarmAck.group + " " + alarmAck.silenceTime))
|
||||
rxBus.send(EventNSClientNewLog("► ALARMACK ", alarmAck.level.toString() + " " + alarmAck.group + " " + alarmAck.silenceTime))
|
||||
}
|
||||
|
||||
fun resend(reason: String) {
|
||||
if (!isConnected || !hasWriteAuth) return
|
||||
handler.post {
|
||||
if (socket?.connected() != true) return@post
|
||||
@Synchronized
|
||||
fun resend(reason: String) = runBlocking {
|
||||
if (!isConnected || !hasWriteAuth) return@runBlocking
|
||||
scope.async {
|
||||
if (socket?.connected() != true) return@async
|
||||
if (lastAckTime > System.currentTimeMillis() - 10 * 1000L) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Skipping resend by lastAckTime: " + (System.currentTimeMillis() - lastAckTime) / 1000L + " sec")
|
||||
return@post
|
||||
return@async
|
||||
}
|
||||
// val powerManager = getSystemService(POWER_SERVICE) as PowerManager
|
||||
// val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
// "AndroidAPS:NSClientService_onDataUpdate")
|
||||
// wakeLock.acquire(mins(10).msecs())
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelector.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend ended: $reason"))
|
||||
} finally {
|
||||
// if (wakeLock.isHeld) wakeLock.release()
|
||||
}
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelectorV1.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("● QUEUE", "Resend ended: $reason"))
|
||||
}.join()
|
||||
}
|
||||
|
||||
fun restart() {
|
||||
|
@ -643,7 +615,7 @@ class NSClientService : DaggerService() {
|
|||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_announcements, defaultVal)) {
|
||||
val nsAlarm = NSAlarm(announcement)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
rxBus.send(EventNSClientNewLog("ANNOUNCEMENT", safeGetString(announcement, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ ANNOUNCEMENT", safeGetString(announcement, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, announcement.toString())
|
||||
}
|
||||
}
|
||||
|
@ -651,12 +623,12 @@ class NSClientService : DaggerService() {
|
|||
private fun handleAlarm(alarm: JSONObject) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, defaultVal)) {
|
||||
val snoozedTo = sp.getLong(info.nightscout.core.utils.R.string.key_snoozed_to, 0L)
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + alarm.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("ALARM", safeGetString(alarm, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ ALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
@ -664,12 +636,12 @@ class NSClientService : DaggerService() {
|
|||
private fun handleUrgentAlarm(alarm: JSONObject) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_alarms, defaultVal)) {
|
||||
val snoozedTo = sp.getLong(info.nightscout.core.utils.R.string.key_snoozed_to, 0L)
|
||||
val snoozedTo = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_snoozed_to) + alarm.optString("level"), 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val nsAlarm = NSAlarm(alarm)
|
||||
uiInteraction.addNotificationWithAction(injector, nsAlarm)
|
||||
}
|
||||
rxBus.send(EventNSClientNewLog("URGENTALARM", safeGetString(alarm, "message", "received")))
|
||||
rxBus.send(EventNSClientNewLog("◄ URGENTALARM", safeGetString(alarm, "message", "received")))
|
||||
aapsLogger.debug(LTag.NSCLIENT, alarm.toString())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
|
|||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSAddAck
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
|
@ -39,7 +40,7 @@ class NSClientAddAckWorker(
|
|||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
@ -60,148 +61,148 @@ class NSClientAddAckWorker(
|
|||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryTargets.add(pair.value)
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryTarget " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTempTargets()
|
||||
dataSyncSelectorV1.processChangedTempTargets()
|
||||
}
|
||||
|
||||
is PairGlucoseValue -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdGlucoseValues.add(pair.value)
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked GlucoseValue " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedGlucoseValues()
|
||||
dataSyncSelectorV1.processChangedGlucoseValues()
|
||||
}
|
||||
|
||||
is PairFood -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdFoods.add(pair.value)
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Food " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedFoods()
|
||||
dataSyncSelectorV1.processChangedFoods()
|
||||
}
|
||||
|
||||
is PairTherapyEvent -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTherapyEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TherapyEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTherapyEvents()
|
||||
dataSyncSelectorV1.processChangedTherapyEvents()
|
||||
}
|
||||
|
||||
is PairBolus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Bolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBoluses()
|
||||
dataSyncSelectorV1.processChangedBoluses()
|
||||
}
|
||||
|
||||
is PairCarbs -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdCarbs.add(pair.value)
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked Carbs " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbs()
|
||||
dataSyncSelectorV1.processChangedCarbs()
|
||||
}
|
||||
|
||||
is PairBolusCalculatorResult -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdBolusCalculatorResults.add(pair.value)
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked BolusCalculatorResult " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResults()
|
||||
dataSyncSelectorV1.processChangedBolusCalculatorResults()
|
||||
}
|
||||
|
||||
is PairTemporaryBasal -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdTemporaryBasals.add(pair.value)
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked TemporaryBasal " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
dataSyncSelectorV1.processChangedTemporaryBasals()
|
||||
}
|
||||
|
||||
is PairExtendedBolus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdExtendedBoluses.add(pair.value)
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ExtendedBolus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
dataSyncSelectorV1.processChangedExtendedBoluses()
|
||||
}
|
||||
|
||||
is PairProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedProfileSwitches()
|
||||
}
|
||||
|
||||
is PairEffectiveProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdEffectiveProfileSwitches.add(pair.value)
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
|
||||
}
|
||||
|
||||
is DataSyncSelector.PairDeviceStatus -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdDeviceStatuses.add(pair.value)
|
||||
dataSyncSelector.confirmLastDeviceStatusIdIfGreater(pair.value.id)
|
||||
dataSyncSelectorV1.confirmLastDeviceStatusIdIfGreater(pair.value.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked DeviceStatus " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedDeviceStatuses()
|
||||
dataSyncSelectorV1.processChangedDeviceStatuses()
|
||||
}
|
||||
|
||||
is PairProfileStore -> {
|
||||
dataSyncSelector.confirmLastProfileStore(ack.originalObject.id)
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileStore " + ack.id))
|
||||
dataSyncSelectorV1.confirmLastProfileStore(ack.originalObject.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked ProfileStore " + ack.id))
|
||||
}
|
||||
|
||||
is PairOfflineEvent -> {
|
||||
val pair = ack.originalObject
|
||||
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||
storeDataForDb.nsIdOfflineEvents.add(pair.value)
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
storeDataForDb.scheduleNsIdUpdate()
|
||||
rxBus.send(EventNSClientNewLog("DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
rxBus.send(EventNSClientNewLog("◄ DBADD", "Acked OfflineEvent " + pair.value.interfaceIDs.nightscoutId))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedOfflineEvents()
|
||||
dataSyncSelectorV1.processChangedOfflineEvents()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ class NSClientAddUpdateWorker(
|
|||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Inject lateinit var storeDataForDb: StoreDataForDb
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
|
@ -164,7 +163,6 @@ class NSClientAddUpdateWorker(
|
|||
}
|
||||
storeDataForDb.storeTreatmentsToDb()
|
||||
activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData)
|
||||
xDripBroadcast.sendTreatments(treatments)
|
||||
return ret
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import androidx.work.workDataOf
|
|||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.core.utils.worker.LoggingWorker
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairBolus
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairBolusCalculatorResult
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairCarbs
|
||||
|
@ -19,6 +18,7 @@ import info.nightscout.interfaces.sync.DataSyncSelector.PairProfileSwitch
|
|||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryBasal
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTemporaryTarget
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector.PairTherapyEvent
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV1
|
||||
import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
|
@ -34,7 +34,7 @@ class NSClientUpdateRemoveAckWorker(
|
|||
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dataSyncSelector: DataSyncSelector
|
||||
@Inject lateinit var dataSyncSelectorV1: DataSyncSelectorV1
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
|
||||
override suspend fun doWorkAndLog(): Result {
|
||||
|
@ -47,109 +47,109 @@ class NSClientUpdateRemoveAckWorker(
|
|||
when (ack.originalObject) {
|
||||
is PairTemporaryTarget -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryTarget" + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTempTargetsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryTarget" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTempTargets()
|
||||
dataSyncSelectorV1.processChangedTempTargets()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairGlucoseValue -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked GlucoseValue " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastGlucoseValueIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked GlucoseValue " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedGlucoseValues()
|
||||
dataSyncSelectorV1.processChangedGlucoseValues()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairFood -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastFoodIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Food " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastFoodIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Food " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedFoods()
|
||||
dataSyncSelectorV1.processChangedFoods()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairTherapyEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TherapyEvent " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTherapyEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TherapyEvent " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTherapyEvents()
|
||||
dataSyncSelectorV1.processChangedTherapyEvents()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Bolus " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Bolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBoluses()
|
||||
dataSyncSelectorV1.processChangedBoluses()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairCarbs -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastCarbsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked Carbs " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastCarbsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked Carbs " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedCarbs()
|
||||
dataSyncSelectorV1.processChangedCarbs()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairBolusCalculatorResult -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastBolusCalculatorResultsIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked BolusCalculatorResult " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedBolusCalculatorResults()
|
||||
dataSyncSelectorV1.processChangedBolusCalculatorResults()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairTemporaryBasal -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked TemporaryBasal " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastTemporaryBasalIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked TemporaryBasal " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedTemporaryBasals()
|
||||
dataSyncSelectorV1.processChangedTemporaryBasals()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairExtendedBolus -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ExtendedBolus " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastExtendedBolusIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ExtendedBolus " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedExtendedBoluses()
|
||||
dataSyncSelectorV1.processChangedExtendedBoluses()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked ProfileSwitch " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked ProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedProfileSwitches()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairEffectiveProfileSwitch -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||
dataSyncSelectorV1.confirmLastEffectiveProfileSwitchIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedEffectiveProfileSwitches()
|
||||
dataSyncSelectorV1.processChangedEffectiveProfileSwitches()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
|
||||
is PairOfflineEvent -> {
|
||||
val pair = ack.originalObject
|
||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked OfflineEvent" + ack._id))
|
||||
dataSyncSelectorV1.confirmLastOfflineEventIdIfGreater(pair.id)
|
||||
rxBus.send(EventNSClientNewLog("◄ DBUPDATE", "Acked OfflineEvent" + ack._id))
|
||||
// Send new if waiting
|
||||
dataSyncSelector.processChangedOfflineEvents()
|
||||
dataSyncSelectorV1.processChangedOfflineEvents()
|
||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,708 @@
|
|||
package info.nightscout.plugins.sync.nsclientV3
|
||||
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.sync.DataSyncSelector
|
||||
import info.nightscout.interfaces.sync.DataSyncSelectorV3
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiQueue
|
||||
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGuiStatus
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class DataSyncSelectorV3Impl @Inject constructor(
|
||||
private val sp: SP,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val dateUtil: DateUtil,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val appRepository: AppRepository,
|
||||
private val rxBus: RxBus,
|
||||
private val storeDataForDb: StoreDataForDb
|
||||
) : DataSyncSelectorV3 {
|
||||
|
||||
class QueueCounter(
|
||||
var bolusesRemaining: Long = -1L,
|
||||
var carbsRemaining: Long = -1L,
|
||||
var bcrRemaining: Long = -1L,
|
||||
var ttsRemaining: Long = -1L,
|
||||
var foodsRemaining: Long = -1L,
|
||||
var gvsRemaining: Long = -1L,
|
||||
var tesRemaining: Long = -1L,
|
||||
var dssRemaining: Long = -1L,
|
||||
var tbrsRemaining: Long = -1L,
|
||||
var ebsRemaining: Long = -1L,
|
||||
var pssRemaining: Long = -1L,
|
||||
var epssRemaining: Long = -1L,
|
||||
var oesRemaining: Long = -1L
|
||||
) {
|
||||
|
||||
fun size(): Long =
|
||||
bolusesRemaining +
|
||||
carbsRemaining +
|
||||
bcrRemaining +
|
||||
ttsRemaining +
|
||||
foodsRemaining +
|
||||
gvsRemaining +
|
||||
tesRemaining +
|
||||
dssRemaining +
|
||||
tbrsRemaining +
|
||||
ebsRemaining +
|
||||
pssRemaining +
|
||||
epssRemaining +
|
||||
oesRemaining
|
||||
}
|
||||
|
||||
private val queueCounter = QueueCounter()
|
||||
private val isPaused get() = sp.getBoolean(R.string.key_ns_paused, false)
|
||||
|
||||
override fun queueSize(): Long = queueCounter.size()
|
||||
|
||||
override suspend fun doUpload() {
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true) && !isPaused) {
|
||||
queueCounter.bolusesRemaining = (appRepository.getLastBolusId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
queueCounter.carbsRemaining = (appRepository.getLastCarbsId() ?: 0L) - sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
queueCounter.bcrRemaining = (appRepository.getLastBolusCalculatorResultId() ?: 0L) - sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
queueCounter.ttsRemaining = (appRepository.getLastTempTargetId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
queueCounter.foodsRemaining = (appRepository.getLastFoodId() ?: 0L) - sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
queueCounter.gvsRemaining = (appRepository.getLastGlucoseValueId() ?: 0L) - sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
queueCounter.tesRemaining = (appRepository.getLastTherapyEventId() ?: 0L) - sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
queueCounter.dssRemaining = (appRepository.getLastDeviceStatusId() ?: 0L) - sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
queueCounter.tbrsRemaining = (appRepository.getLastTemporaryBasalId() ?: 0L) - sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
queueCounter.ebsRemaining = (appRepository.getLastExtendedBolusId() ?: 0L) - sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
queueCounter.pssRemaining = (appRepository.getLastProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
queueCounter.epssRemaining = (appRepository.getLastEffectiveProfileSwitchId() ?: 0L) - sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
queueCounter.oesRemaining = (appRepository.getLastOfflineEventId() ?: 0L) - sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
processChangedGlucoseValues()
|
||||
processChangedBoluses()
|
||||
processChangedCarbs()
|
||||
processChangedBolusCalculatorResults()
|
||||
processChangedTemporaryBasals()
|
||||
processChangedExtendedBoluses()
|
||||
processChangedProfileSwitches()
|
||||
processChangedEffectiveProfileSwitches()
|
||||
processChangedTempTargets()
|
||||
processChangedFoods()
|
||||
processChangedTherapyEvents()
|
||||
processChangedDeviceStatuses()
|
||||
processChangedOfflineEvents()
|
||||
processChangedProfileStore()
|
||||
storeDataForDb.updateNsIds()
|
||||
}
|
||||
rxBus.send(EventNSClientUpdateGuiStatus())
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
|
||||
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
|
||||
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
|
||||
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
|
||||
sp.remove(R.string.key_ns_food_last_synced_id)
|
||||
sp.remove(R.string.key_ns_bolus_last_synced_id)
|
||||
sp.remove(R.string.key_ns_carbs_last_synced_id)
|
||||
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
|
||||
sp.remove(R.string.key_ns_therapy_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_switch_last_synced_id)
|
||||
sp.remove(R.string.key_ns_effective_profile_switch_last_synced_id)
|
||||
sp.remove(R.string.key_ns_offline_event_last_synced_id)
|
||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||
|
||||
val lastDeviceStatusDbId = appRepository.getLastDeviceStatusId()
|
||||
if (lastDeviceStatusDbId != null) sp.putLong(R.string.key_ns_device_status_last_synced_id, lastDeviceStatusDbId)
|
||||
else sp.remove(R.string.key_ns_device_status_last_synced_id)
|
||||
}
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Bolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedBoluses() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bolusesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolus(startId).blockingGet()?.let { bolus ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading Bolus data Start: $startId ${bolus.first} forID: ${bolus.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
bolus.first.id == bolus.second.id && bolus.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Loaded from NS: ${bolus.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
bolus.first.onlyNsIdAdded(bolus.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Bolus. Only NS id changed: ${bolus.second.id} ")
|
||||
// without nsId = create new
|
||||
bolus.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), " $startId/$lastDbId") ?: false
|
||||
// with nsId = update if it's modified record
|
||||
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairBolus(bolus.first, bolus.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastBolusIdIfGreater(bolus.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Carbs data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedCarbs() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastCarbsId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_carbs_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.carbsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementCarbs(startId).blockingGet()?.let { carb ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading Carbs data Start: $startId ${carb.first} forID: ${carb.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
carb.first.id == carb.second.id && carb.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Loaded from NS: ${carb.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
carb.first.onlyNsIdAdded(carb.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Carbs. Only NS id changed ID: ${carb.second.id} ")
|
||||
// without nsId = create new
|
||||
carb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update if it's modified record
|
||||
carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastCarbsIdIfGreater(carb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting BolusCalculatorResult data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedBolusCalculatorResults() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastBolusCalculatorResultId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_bolus_calculator_result_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.bcrRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementBolusCalculatorResult(startId).blockingGet()?.let { bolusCalculatorResult ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading BolusCalculatorResult data Start: $startId ${bolusCalculatorResult.first} forID: ${bolusCalculatorResult.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
bolusCalculatorResult.first.id == bolusCalculatorResult.second.id && bolusCalculatorResult.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Loaded from NS: ${bolusCalculatorResult.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
bolusCalculatorResult.first.onlyNsIdAdded(bolusCalculatorResult.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring BolusCalculatorResult. Only NS id changed ID: ${bolusCalculatorResult.second.id} ")
|
||||
// without nsId = create new
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
) ?: false
|
||||
// with nsId = update if it's modified record
|
||||
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate(
|
||||
"treatments",
|
||||
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
|
||||
"$startId/$lastDbId"
|
||||
) ?: false
|
||||
}
|
||||
confirmLastBolusCalculatorResultsIdIfGreater(bolusCalculatorResult.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryTarget data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTempTargets() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastTempTargetId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_temporary_target_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ttsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryTarget(startId).blockingGet()?.let { tt ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryTarget data Start: $startId ${tt.first} forID: ${tt.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
tt.first.id == tt.second.id && tt.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Loaded from NS: ${tt.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
tt.first.onlyNsIdAdded(tt.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryTarget. Only NS id changed ID: ${tt.second.id} ")
|
||||
// without nsId = create new
|
||||
tt.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") ?: false
|
||||
// existing with nsId = update
|
||||
tt.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTempTargetsIdIfGreater(tt.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_food_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting Food data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedFoods() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastFoodId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_food_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.foodsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementFood(startId).blockingGet()?.let { food ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading Food data Start: $startId ${food.first} forID: ${food.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
food.first.id == food.second.id && food.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Loaded from NS: ${food.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
food.first.onlyNsIdAdded(food.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring Food. Only NS id changed ID: ${food.second.id} ")
|
||||
// without nsId = create new
|
||||
food.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
food.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastFoodIdIfGreater(food.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting GlucoseValue data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedGlucoseValues() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastGlucoseValueId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_glucose_value_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.gvsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementGlucoseValue(startId).blockingGet()?.let { gv ->
|
||||
//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
|
||||
gv.first.id == gv.second.id && gv.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Loaded from NS: ${gv.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
gv.first.onlyNsIdAdded(gv.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring GlucoseValue. Only NS id changed ID: ${gv.second.id} ")
|
||||
// without nsId = create new
|
||||
gv.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
else -> // gv.first.interfaceIDs.nightscoutId != null
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
}
|
||||
confirmLastGlucoseValueIdIfGreater(gv.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TherapyEvents data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTherapyEvents() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastTherapyEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_therapy_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTherapyEvent(startId).blockingGet()?.let { te ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading TherapyEvents data Start: $startId ${te.first} forID: ${te.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
te.first.id == te.second.id && te.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Loaded from NS: ${te.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
te.first.onlyNsIdAdded(te.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TherapyEvent. Only NS id changed ID: ${te.second.id} ")
|
||||
// without nsId = create new
|
||||
te.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") ?: false
|
||||
// nsId = update
|
||||
te.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTherapyEventIdIfGreater(te.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedDeviceStatuses() {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastDeviceStatusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.dssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading DeviceStatus data Start: $startId $deviceStatus")
|
||||
// without nsId = create new
|
||||
if (deviceStatus.interfaceIDs.nightscoutId == null) {
|
||||
if (activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, lastDbId), "$startId/$lastDbId") == true)
|
||||
confirmLastDeviceStatusIdIfGreater(lastDbId)
|
||||
}
|
||||
// with nsId = ignore
|
||||
}
|
||||
queueCounter.dssRemaining = 0
|
||||
}
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting TemporaryBasal data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedTemporaryBasals() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastTemporaryBasalId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_temporary_basal_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.tbrsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementTemporaryBasal(startId).blockingGet()?.let { tb ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading TemporaryBasal data Start: $startId ${tb.first} forID: ${tb.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
tb.first.id == tb.second.id && tb.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Loaded from NS: ${tb.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
tb.first.onlyNsIdAdded(tb.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring TemporaryBasal. Only NS id changed ID: ${tb.second.id} ")
|
||||
// without nsId = create new
|
||||
tb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
tb.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastTemporaryBasalIdIfGreater(tb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting ExtendedBolus data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedExtendedBoluses() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastExtendedBolusId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_extended_bolus_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.ebsRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementExtendedBolus(startId).blockingGet()?.let { eb ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading ExtendedBolus data Start: $startId ${eb.first} forID: ${eb.second.id} ")
|
||||
val profile = profileFunction.getProfile(eb.first.timestamp)
|
||||
if (profile != null) {
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
eb.first.id == eb.second.id && eb.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Loaded from NS: ${eb.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
eb.first.onlyNsIdAdded(eb.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. Only NS id changed ID: ${eb.second.id} ")
|
||||
// without nsId = create new
|
||||
eb.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
eb.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
} else aapsLogger.info(LTag.NSCLIENT, "Ignoring ExtendedBolus. No profile: ${eb.second.id} ")
|
||||
confirmLastExtendedBolusIdIfGreater(eb.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting ProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedProfileSwitches() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.pssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading ProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Loaded from NS: ${ps.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
ps.first.onlyNsIdAdded(ps.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring ProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastProfileSwitchIdIfGreater(ps.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting EffectiveProfileSwitch data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedEffectiveProfileSwitches() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastEffectiveProfileSwitchId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.epssRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data Start: $startId ${ps.first} forID: ${ps.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
ps.first.id == ps.second.id && ps.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Loaded from NS: ${ps.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
ps.first.onlyNsIdAdded(ps.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring EffectiveProfileSwitch. Only NS id changed ID: ${ps.second.id} ")
|
||||
// without nsId = create new
|
||||
ps.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
// with nsId = update
|
||||
ps.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastEffectiveProfileSwitchIdIfGreater(ps.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
||||
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
|
||||
//aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, lastSynced)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processChangedOfflineEvents() {
|
||||
var cont = true
|
||||
while (cont) {
|
||||
if (isPaused) return
|
||||
val lastDbId = appRepository.getLastOfflineEventId() ?: 0L
|
||||
var startId = sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
if (startId > lastDbId) {
|
||||
aapsLogger.info(LTag.NSCLIENT, "Resetting startId: $startId lastDbId: $lastDbId")
|
||||
sp.putLong(R.string.key_ns_offline_event_last_synced_id, 0)
|
||||
startId = 0
|
||||
}
|
||||
queueCounter.oesRemaining = lastDbId - startId
|
||||
rxBus.send(EventNSClientUpdateGuiQueue())
|
||||
appRepository.getNextSyncElementOfflineEvent(startId).blockingGet()?.let { oe ->
|
||||
//aapsLogger.info(LTag.NSCLIENT, "Loading OfflineEvent data Start: $startId ${oe.first} forID: ${oe.second.id} ")
|
||||
when {
|
||||
// new record with existing NS id => must be coming from NS => ignore
|
||||
oe.first.id == oe.second.id && oe.first.interfaceIDs.nightscoutId != null ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Loaded from NS: ${oe.second.id} ")
|
||||
// only NsId changed, no need to upload
|
||||
oe.first.onlyNsIdAdded(oe.second) ->
|
||||
aapsLogger.info(LTag.NSCLIENT, "Ignoring OfflineEvent. Only NS id changed ID: ${oe.second.id} ")
|
||||
// without nsId = create new
|
||||
oe.first.interfaceIDs.nightscoutId == null ->
|
||||
cont = activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") ?: false
|
||||
// existing with nsId = update
|
||||
oe.first.interfaceIDs.nightscoutId != null ->
|
||||
cont = activePlugin.activeNsClient?.nsUpdate("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") ?: false
|
||||
}
|
||||
confirmLastOfflineEventIdIfGreater(oe.second.id)
|
||||
} ?: run {
|
||||
cont = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long) {
|
||||
sp.putLong(R.string.key_ns_profile_store_last_synced_timestamp, lastSynced)
|
||||
}
|
||||
|
||||
suspend 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
|
||||
if (lastChange > lastSync) {
|
||||
if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
val profileJson = profileStore?.data ?: return
|
||||
// add for v3
|
||||
if (JsonHelper.safeGetLongAllowNull(profileJson, "date") == null)
|
||||
profileJson.put("date", profileStore.getStartDate())
|
||||
val now = dateUtil.now()
|
||||
if (activePlugin.activeNsClient?.nsAdd("profile", DataSyncSelector.PairProfileStore(profileJson, now), "") == true)
|
||||
confirmLastProfileStore(now)
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue