Merge branch 'epssync' into dev
This commit is contained in:
commit
45b58719a6
14 changed files with 262 additions and 8 deletions
|
@ -34,6 +34,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
processChangedTemporaryBasalsCompat()
|
processChangedTemporaryBasalsCompat()
|
||||||
processChangedExtendedBolusesCompat()
|
processChangedExtendedBolusesCompat()
|
||||||
processChangedProfileSwitchesCompat()
|
processChangedProfileSwitchesCompat()
|
||||||
|
processChangedEffectiveProfileSwitchesCompat()
|
||||||
processChangedGlucoseValuesCompat()
|
processChangedGlucoseValuesCompat()
|
||||||
processChangedTempTargetsCompat()
|
processChangedTempTargetsCompat()
|
||||||
processChangedFoodsCompat()
|
processChangedFoodsCompat()
|
||||||
|
@ -56,6 +57,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
|
sp.remove(R.string.key_ns_extended_bolus_last_synced_id)
|
||||||
sp.remove(R.string.key_ns_therapy_event_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_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_offline_event_last_synced_id)
|
||||||
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
sp.remove(R.string.key_ns_profile_store_last_synced_timestamp)
|
||||||
}
|
}
|
||||||
|
@ -555,6 +557,48 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun changedEffectiveProfileSwitch(): List<EffectiveProfileSwitch> {
|
||||||
|
val startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||||
|
return appRepository.getModifiedEffectiveProfileSwitchDataFromId(startId).blockingGet().also {
|
||||||
|
aapsLogger.debug(LTag.NSCLIENT, "Loading EffectiveProfileSwitch data for sync from $startId. Records ${it.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Volatile private var lastEpsId = -1L
|
||||||
|
@Volatile private var lastEpsTime = -1L
|
||||||
|
override fun processChangedEffectiveProfileSwitchesCompat(): Boolean {
|
||||||
|
val lastDbIdWrapped = appRepository.getLastEffectiveProfileSwitchIdWrapped().blockingGet()
|
||||||
|
val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L
|
||||||
|
var startId = sp.getLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||||
|
if (startId > lastDbId) {
|
||||||
|
sp.putLong(R.string.key_ns_effective_profile_switch_last_synced_id, 0)
|
||||||
|
startId = 0
|
||||||
|
}
|
||||||
|
if (startId == lastEpsId && dateUtil.now() - lastEpsTime < 5000) return false
|
||||||
|
lastEpsId = startId
|
||||||
|
lastEpsTime = dateUtil.now()
|
||||||
|
appRepository.getNextSyncElementEffectiveProfileSwitch(startId).blockingGet()?.let { ps ->
|
||||||
|
aapsLogger.info(LTag.DATABASE, "Loading EffectiveProfileSwitch data Start: $startId ID: ${ps.first.id} HistoryID: ${ps.second} ")
|
||||||
|
when {
|
||||||
|
// without nsId = create new
|
||||||
|
ps.first.interfaceIDs.nightscoutId == null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbAdd("treatments", ps.first.toJson(true, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second), "$startId/$lastDbId")
|
||||||
|
// with nsId = update
|
||||||
|
ps.first.interfaceIDs.nightscoutId != null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbUpdate("treatments", ps.first.interfaceIDs.nightscoutId, ps.first.toJson(false, dateUtil), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second), "$startId/$lastDbId")
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
override fun confirmLastOfflineEventIdIfGreater(lastSynced: Long) {
|
||||||
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
|
if (lastSynced > sp.getLong(R.string.key_ns_offline_event_last_synced_id, 0)) {
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
|
aapsLogger.debug(LTag.NSCLIENT, "Setting OfflineEvent data sync from $lastSynced")
|
||||||
|
|
|
@ -228,6 +228,25 @@ class NSClientAddAckWorker(
|
||||||
dataSyncSelector.processChangedProfileSwitchesCompat()
|
dataSyncSelector.processChangedProfileSwitchesCompat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is PairEffectiveProfileSwitch -> {
|
||||||
|
val pair = ack.originalObject
|
||||||
|
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||||
|
repository.runTransactionForResult(UpdateNsIdEffectiveProfileSwitchTransaction(pair.value))
|
||||||
|
.doOnError { error ->
|
||||||
|
aapsLogger.error(LTag.DATABASE, "Updated ns id of EffectiveProfileSwitch failed", error)
|
||||||
|
ret = Result.failure((workDataOf("Error" to error.toString())))
|
||||||
|
}
|
||||||
|
.doOnSuccess {
|
||||||
|
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Updated ns id of EffectiveProfileSwitch " + pair.value)
|
||||||
|
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||||
|
}
|
||||||
|
.blockingGet()
|
||||||
|
rxBus.send(EventNSClientNewLog("DBADD", "Acked EffectiveProfileSwitch " + pair.value.interfaceIDs.nightscoutId))
|
||||||
|
// Send new if waiting
|
||||||
|
dataSyncSelector.processChangedEffectiveProfileSwitchesCompat()
|
||||||
|
}
|
||||||
|
|
||||||
is DeviceStatus -> {
|
is DeviceStatus -> {
|
||||||
val deviceStatus = ack.originalObject
|
val deviceStatus = ack.originalObject
|
||||||
deviceStatus.interfaceIDs.nightscoutId = ack.id
|
deviceStatus.interfaceIDs.nightscoutId = ack.id
|
||||||
|
|
|
@ -185,6 +185,32 @@ class NSClientAddUpdateWorker(
|
||||||
}
|
}
|
||||||
} ?: aapsLogger.error("Error parsing TT json $json")
|
} ?: aapsLogger.error("Error parsing TT json $json")
|
||||||
}
|
}
|
||||||
|
eventType == TherapyEvent.Type.NOTE.text && json.isEffectiveProfileSwitch() -> // replace this by new Type when available in NS
|
||||||
|
if (sp.getBoolean(R.string.key_ns_receive_profile_switch, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||||
|
effectiveProfileSwitchFromJson(json, dateUtil, activePlugin)?.let { effectiveProfileSwitch ->
|
||||||
|
repository.runTransactionForResult(SyncNsEffectiveProfileSwitchTransaction(effectiveProfileSwitch, invalidateByNsOnly = false))
|
||||||
|
.doOnError {
|
||||||
|
aapsLogger.error(LTag.DATABASE, "Error while saving EffectiveProfileSwitch", it)
|
||||||
|
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||||
|
}
|
||||||
|
.blockingGet()
|
||||||
|
.also { result ->
|
||||||
|
result.inserted.forEach {
|
||||||
|
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
|
||||||
|
ValueWithUnit.Timestamp(it.timestamp))
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Inserted EffectiveProfileSwitch $it")
|
||||||
|
}
|
||||||
|
result.invalidated.forEach {
|
||||||
|
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||||
|
ValueWithUnit.Timestamp(it.timestamp))
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Invalidated EffectiveProfileSwitch $it")
|
||||||
|
}
|
||||||
|
result.updatedNsId.forEach {
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Updated nsId EffectiveProfileSwitch $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: aapsLogger.error("Error parsing EffectiveProfileSwitch json $json")
|
||||||
|
}
|
||||||
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
|
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
|
||||||
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
|
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
|
||||||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
|
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
|
||||||
|
|
|
@ -126,6 +126,15 @@ class NSClientUpdateRemoveAckWorker(
|
||||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is PairEffectiveProfileSwitch -> {
|
||||||
|
val pair = ack.originalObject
|
||||||
|
dataSyncSelector.confirmLastEffectiveProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||||
|
rxBus.send(EventNSClientNewLog("DBUPDATE", "Acked EffectiveProfileSwitch " + ack._id))
|
||||||
|
// Send new if waiting
|
||||||
|
dataSyncSelector.processChangedEffectiveProfileSwitchesCompat()
|
||||||
|
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
is PairOfflineEvent -> {
|
is PairOfflineEvent -> {
|
||||||
val pair = ack.originalObject
|
val pair = ack.originalObject
|
||||||
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId)
|
dataSyncSelector.confirmLastOfflineEventIdIfGreater(pair.updateRecordId)
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
|
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
|
||||||
<string name="key_ns_extended_bolus_last_synced_id" translatable="false">ns_extended_bolus_last_synced_id</string>
|
<string name="key_ns_extended_bolus_last_synced_id" translatable="false">ns_extended_bolus_last_synced_id</string>
|
||||||
<string name="key_ns_profile_switch_last_synced_id" translatable="false">profile_switch_last_synced_id</string>
|
<string name="key_ns_profile_switch_last_synced_id" translatable="false">profile_switch_last_synced_id</string>
|
||||||
|
<string name="key_ns_effective_profile_switch_last_synced_id" translatable="false">ns_effective_profile_switch_last_synced_id</string>
|
||||||
<string name="key_ns_offline_event_last_synced_id" translatable="false">ns_offline_event_last_synced_id</string>
|
<string name="key_ns_offline_event_last_synced_id" translatable="false">ns_offline_event_last_synced_id</string>
|
||||||
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
|
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
|
||||||
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
|
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
package info.nightscout.androidaps.extensions
|
package info.nightscout.androidaps.extensions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.data.ProfileSealed
|
||||||
|
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
||||||
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
||||||
|
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import info.nightscout.androidaps.utils.T.Companion.mins
|
import info.nightscout.androidaps.utils.T.Companion.mins
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
fun List<EffectiveProfileSwitch>.isEPSEvent5minBack(time: Long): Boolean {
|
fun List<EffectiveProfileSwitch>.isEPSEvent5minBack(time: Long): Boolean {
|
||||||
for (event in this) {
|
for (event in this) {
|
||||||
|
@ -15,3 +22,72 @@ fun List<EffectiveProfileSwitch>.isEPSEvent5minBack(time: Long): Boolean {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun EffectiveProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
|
||||||
|
JSONObject()
|
||||||
|
.put("created_at", dateUtil.toISOString(timestamp))
|
||||||
|
.put("enteredBy", "openaps://" + "AndroidAPS")
|
||||||
|
.put("isValid", isValid)
|
||||||
|
.put("eventType", TherapyEvent.Type.NOTE.text) // move to separate collection when available in NS
|
||||||
|
.put("profileJson", ProfileSealed.EPS(this).toPureNsJson(dateUtil).toString())
|
||||||
|
.put("originalProfileName", originalProfileName)
|
||||||
|
.put("originalCustomizedName", originalCustomizedName)
|
||||||
|
.put("originalTimeshift", originalTimeshift)
|
||||||
|
.put("originalPercentage", originalPercentage)
|
||||||
|
.put("originalDuration", originalDuration)
|
||||||
|
.put("originalEnd", originalEnd)
|
||||||
|
.also {
|
||||||
|
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId)
|
||||||
|
if (interfaceIDs.pumpType != null) it.put("pumpType", interfaceIDs.pumpType!!.name)
|
||||||
|
if (interfaceIDs.pumpSerial != null) it.put("pumpSerial", interfaceIDs.pumpSerial)
|
||||||
|
if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun effectiveProfileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil, activePlugin: ActivePlugin): EffectiveProfileSwitch? {
|
||||||
|
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
|
||||||
|
val originalTimeshift = JsonHelper.safeGetLong(jsonObject, "originalTimeshift")
|
||||||
|
val originalDuration = JsonHelper.safeGetLong(jsonObject, "originalDuration")
|
||||||
|
val originalEnd = JsonHelper.safeGetLong(jsonObject, "originalEnd")
|
||||||
|
val originalPercentage = JsonHelper.safeGetInt(jsonObject, "originalPercentage", 100)
|
||||||
|
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
|
||||||
|
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null)
|
||||||
|
val originalProfileName = JsonHelper.safeGetStringAllowNull(jsonObject, "originalProfileName", null) ?: return null
|
||||||
|
val originalCustomizedName = JsonHelper.safeGetStringAllowNull(jsonObject, "originalCustomizedName", null) ?: return null
|
||||||
|
val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null) ?: return null
|
||||||
|
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
|
||||||
|
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
|
||||||
|
val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null)
|
||||||
|
|
||||||
|
if (timestamp == 0L) return null
|
||||||
|
val pureProfile = pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null
|
||||||
|
val profileSealed = ProfileSealed.Pure(pureProfile)
|
||||||
|
|
||||||
|
|
||||||
|
return EffectiveProfileSwitch(
|
||||||
|
timestamp = timestamp,
|
||||||
|
basalBlocks = profileSealed.basalBlocks,
|
||||||
|
isfBlocks = profileSealed.isfBlocks,
|
||||||
|
icBlocks = profileSealed.icBlocks,
|
||||||
|
targetBlocks = profileSealed.targetBlocks,
|
||||||
|
glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.fromConstant(profileSealed.units),
|
||||||
|
originalProfileName = originalProfileName,
|
||||||
|
originalCustomizedName = originalCustomizedName,
|
||||||
|
originalTimeshift = originalTimeshift,
|
||||||
|
originalPercentage = originalPercentage,
|
||||||
|
originalDuration = originalDuration,
|
||||||
|
originalEnd = originalEnd,
|
||||||
|
insulinConfiguration = profileSealed.insulinConfiguration,
|
||||||
|
isValid = isValid
|
||||||
|
).also {
|
||||||
|
it.interfaceIDs.nightscoutId = id
|
||||||
|
it.interfaceIDs.pumpId = pumpId
|
||||||
|
it.interfaceIDs.pumpType = pumpType
|
||||||
|
it.interfaceIDs.pumpSerial = pumpSerial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EffectiveProfileSwitch.GlucoseUnit.Companion.fromConstant(units: GlucoseUnit): EffectiveProfileSwitch.GlucoseUnit =
|
||||||
|
if (units == GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL
|
||||||
|
else EffectiveProfileSwitch.GlucoseUnit.MMOL
|
||||||
|
|
||||||
|
fun JSONObject.isEffectiveProfileSwitch() = has("originalProfileName")
|
|
@ -16,6 +16,7 @@ interface DataSyncSelector {
|
||||||
data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long)
|
data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long)
|
||||||
data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long)
|
data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long)
|
||||||
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long)
|
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long)
|
||||||
|
data class PairEffectiveProfileSwitch(val value: EffectiveProfileSwitch, val updateRecordId: Long)
|
||||||
data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long)
|
data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long)
|
||||||
data class PairProfileStore(val value: JSONObject, val timestampSync: Long)
|
data class PairProfileStore(val value: JSONObject, val timestampSync: Long)
|
||||||
|
|
||||||
|
@ -78,6 +79,11 @@ interface DataSyncSelector {
|
||||||
// Until NS v3
|
// Until NS v3
|
||||||
fun processChangedProfileSwitchesCompat(): Boolean
|
fun processChangedProfileSwitchesCompat(): Boolean
|
||||||
|
|
||||||
|
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||||
|
fun changedEffectiveProfileSwitch() : List<EffectiveProfileSwitch>
|
||||||
|
// Until NS v3
|
||||||
|
fun processChangedEffectiveProfileSwitchesCompat(): Boolean
|
||||||
|
|
||||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||||
fun changedOfflineEvents() : List<OfflineEvent>
|
fun changedOfflineEvents() : List<OfflineEvent>
|
||||||
// Until NS v3
|
// Until NS v3
|
||||||
|
|
|
@ -263,6 +263,10 @@ open class AppRepository @Inject internal constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getModifiedEffectiveProfileSwitchDataFromId(lastId: Long): Single<List<EffectiveProfileSwitch>> =
|
||||||
|
database.effectiveProfileSwitchDao.getModifiedFrom(lastId)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
fun createEffectiveProfileSwitch(profileSwitch: EffectiveProfileSwitch) {
|
fun createEffectiveProfileSwitch(profileSwitch: EffectiveProfileSwitch) {
|
||||||
database.effectiveProfileSwitchDao.insert(profileSwitch)
|
database.effectiveProfileSwitchDao.insert(profileSwitch)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ package info.nightscout.androidaps.database.daos
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import info.nightscout.androidaps.database.TABLE_CARBS
|
|
||||||
import info.nightscout.androidaps.database.TABLE_EFFECTIVE_PROFILE_SWITCHES
|
import info.nightscout.androidaps.database.TABLE_EFFECTIVE_PROFILE_SWITCHES
|
||||||
import info.nightscout.androidaps.database.entities.Carbs
|
|
||||||
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
@ -22,6 +20,12 @@ internal interface EffectiveProfileSwitchDao : TraceableDao<EffectiveProfileSwit
|
||||||
@Query("SELECT id FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
@Query("SELECT id FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
|
||||||
fun getLastId(): Maybe<Long>
|
fun getLastId(): Maybe<Long>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||||
|
fun findByTimestamp(timestamp: Long): EffectiveProfileSwitch?
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||||
|
fun findByNSId(nsId: String): EffectiveProfileSwitch?
|
||||||
|
|
||||||
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
|
@Query("SELECT * FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
|
||||||
fun getOldestEffectiveProfileSwitchRecord(): EffectiveProfileSwitch?
|
fun getOldestEffectiveProfileSwitchRecord(): EffectiveProfileSwitch?
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@ package info.nightscout.androidaps.database.daos
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import info.nightscout.androidaps.database.TABLE_GLUCOSE_VALUES
|
|
||||||
import info.nightscout.androidaps.database.TABLE_PROFILE_SWITCHES
|
import info.nightscout.androidaps.database.TABLE_PROFILE_SWITCHES
|
||||||
import info.nightscout.androidaps.database.daos.workaround.ProfileSwitchDaoWorkaround
|
import info.nightscout.androidaps.database.daos.workaround.ProfileSwitchDaoWorkaround
|
||||||
import info.nightscout.androidaps.database.data.checkSanity
|
import info.nightscout.androidaps.database.data.checkSanity
|
||||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
|
||||||
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
|
|
@ -54,6 +54,8 @@ data class EffectiveProfileSwitch(
|
||||||
|
|
||||||
enum class GlucoseUnit {
|
enum class GlucoseUnit {
|
||||||
MGDL,
|
MGDL,
|
||||||
MMOL
|
MMOL;
|
||||||
|
|
||||||
|
companion object
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync the EffectiveProfileSwitch from NS
|
||||||
|
*/
|
||||||
|
class SyncNsEffectiveProfileSwitchTransaction(private val effectiveProfileSwitch: EffectiveProfileSwitch, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsEffectiveProfileSwitchTransaction.TransactionResult>() {
|
||||||
|
|
||||||
|
override fun run(): TransactionResult {
|
||||||
|
val result = TransactionResult()
|
||||||
|
|
||||||
|
val current: EffectiveProfileSwitch? =
|
||||||
|
effectiveProfileSwitch.interfaceIDs.nightscoutId?.let {
|
||||||
|
database.effectiveProfileSwitchDao.findByNSId(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current != null) {
|
||||||
|
// nsId exists, allow only invalidation
|
||||||
|
if (current.isValid && !effectiveProfileSwitch.isValid) {
|
||||||
|
current.isValid = false
|
||||||
|
database.effectiveProfileSwitchDao.updateExistingEntry(current)
|
||||||
|
result.invalidated.add(current)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidateByNsOnly) return result
|
||||||
|
|
||||||
|
// not known nsId
|
||||||
|
val existing = database.effectiveProfileSwitchDao.findByTimestamp(effectiveProfileSwitch.timestamp)
|
||||||
|
if (existing != null && existing.interfaceIDs.nightscoutId == null) {
|
||||||
|
// the same record, update nsId only
|
||||||
|
existing.interfaceIDs.nightscoutId = effectiveProfileSwitch.interfaceIDs.nightscoutId
|
||||||
|
existing.isValid = effectiveProfileSwitch.isValid
|
||||||
|
database.effectiveProfileSwitchDao.updateExistingEntry(existing)
|
||||||
|
result.updatedNsId.add(existing)
|
||||||
|
} else {
|
||||||
|
database.effectiveProfileSwitchDao.insertNewEntry(effectiveProfileSwitch)
|
||||||
|
result.inserted.add(effectiveProfileSwitch)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
class TransactionResult {
|
||||||
|
|
||||||
|
val updatedNsId = mutableListOf<EffectiveProfileSwitch>()
|
||||||
|
val inserted = mutableListOf<EffectiveProfileSwitch>()
|
||||||
|
val invalidated = mutableListOf<EffectiveProfileSwitch>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
||||||
|
|
||||||
|
class UpdateNsIdEffectiveProfileSwitchTransaction(val effectiveProfileSwitch: EffectiveProfileSwitch) : Transaction<Unit>() {
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val current = database.effectiveProfileSwitchDao.findById(effectiveProfileSwitch.id)
|
||||||
|
if (current != null && current.interfaceIDs.nightscoutId != effectiveProfileSwitch.interfaceIDs.nightscoutId) {
|
||||||
|
current.interfaceIDs.nightscoutId = effectiveProfileSwitch.interfaceIDs.nightscoutId
|
||||||
|
database.effectiveProfileSwitchDao.updateExistingEntry(current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
|
||||||
|
|
||||||
private val MAX_COMMAND_TRIES = 3
|
private val MAX_COMMAND_TRIES = 3
|
||||||
private val DEFAULT_TIMEOUT = 2000
|
private val DEFAULT_TIMEOUT = 2000
|
||||||
private val RILEYLINK_TIMEOUT: Long = 15 * 60 * 1000 // 15 min
|
private val RILEYLINK_TIMEOUT: Long = 15 * 60 * 1000L // 15 min
|
||||||
|
|
||||||
var errorResponse: String? = null
|
var errorResponse: String? = null
|
||||||
private set
|
private set
|
||||||
|
@ -64,7 +64,7 @@ class MedtronicCommunicationManager // This empty constructor must be kept, oth
|
||||||
private var doWakeUpBeforeCommand = true
|
private var doWakeUpBeforeCommand = true
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
fun onInit(): Unit {
|
fun onInit() {
|
||||||
// we can't do this in the constructor, as sp only gets injected after the constructor has returned
|
// we can't do this in the constructor, as sp only gets injected after the constructor has returned
|
||||||
medtronicPumpStatus.previousConnection = sp.getLong(
|
medtronicPumpStatus.previousConnection = sp.getLong(
|
||||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L)
|
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L)
|
||||||
|
|
Loading…
Reference in a new issue