ProfileSwitch NS sync
This commit is contained in:
parent
9b4653ac74
commit
e48d317d55
16 changed files with 278 additions and 56 deletions
|
@ -35,6 +35,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
|
sp.remove(R.string.key_ns_temporary_basal_last_synced_id)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||||
|
@ -408,4 +409,40 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun changedProfileSwitch(): List<ProfileSwitch> {
|
||||||
|
val startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||||
|
return appRepository.getModifiedProfileSwitchDataFromId(startId).blockingGet().also {
|
||||||
|
aapsLogger.debug(LTag.NSCLIENT, "Loading ProfileSwitch data for sync from $startId. Records ${it.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processChangedProfileSwitchesCompat(): Boolean {
|
||||||
|
val startId = sp.getLong(R.string.key_ns_profile_switch_last_synced_id, 0)
|
||||||
|
appRepository.getNextSyncElementProfileSwitch(startId).blockingGet()?.let { eb ->
|
||||||
|
aapsLogger.info(LTag.DATABASE, "Loading ProfileSwitch data Start: $startId ID: ${eb.first.id} HistoryID: ${eb.second} ")
|
||||||
|
when {
|
||||||
|
// removed and not uploaded yet = ignore
|
||||||
|
!eb.first.isValid && eb.first.interfaceIDs.nightscoutId == null -> Any()
|
||||||
|
// removed and already uploaded = send for removal
|
||||||
|
!eb.first.isValid && eb.first.interfaceIDs.nightscoutId != null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbRemove("treatments", eb.first.interfaceIDs.nightscoutId, DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
|
||||||
|
// existing without nsId = create new
|
||||||
|
eb.first.isValid && eb.first.interfaceIDs.nightscoutId == null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbAdd("treatments", eb.first.toJson(dateUtil), DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
|
||||||
|
// existing with nsId = update
|
||||||
|
eb.first.isValid && eb.first.interfaceIDs.nightscoutId != null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbUpdate("treatments", eb.first.interfaceIDs.nightscoutId, eb.first.toJson(dateUtil), DataSyncSelector.PairProfileSwitch(eb.first, eb.second))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,25 @@ class NSClientAddAckWorker(
|
||||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is PairProfileSwitch -> {
|
||||||
|
val pair = ack.originalObject
|
||||||
|
pair.value.interfaceIDs.nightscoutId = ack.id
|
||||||
|
repository.runTransactionForResult(UpdateNsIdProfileSwitchTransaction(pair.value))
|
||||||
|
.doOnError { error ->
|
||||||
|
aapsLogger.error(LTag.DATABASE, "Updated ns id of ProfileSwitch 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 ProfileSwitch " + pair.value)
|
||||||
|
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||||
|
}
|
||||||
|
.blockingGet()
|
||||||
|
rxBus.send(EventNSClientNewLog("DBADD", "Acked ProfileSwitch" + pair.value.interfaceIDs.nightscoutId))
|
||||||
|
// Send new if waiting
|
||||||
|
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||||
|
}
|
||||||
|
|
||||||
is DeviceStatus -> {
|
is DeviceStatus -> {
|
||||||
val deviceStatus = ack.originalObject
|
val deviceStatus = ack.originalObject
|
||||||
deviceStatus.interfaceIDs.nightscoutId = ack.id
|
deviceStatus.interfaceIDs.nightscoutId = ack.id
|
||||||
|
|
|
@ -15,7 +15,6 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||||
import info.nightscout.androidaps.database.transactions.*
|
import info.nightscout.androidaps.database.transactions.*
|
||||||
import info.nightscout.androidaps.extensions.*
|
import info.nightscout.androidaps.extensions.*
|
||||||
import info.nightscout.androidaps.interfaces.Config
|
import info.nightscout.androidaps.interfaces.Config
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
|
@ -44,7 +43,6 @@ class NSClientAddUpdateWorker(
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var config: Config
|
@Inject lateinit var config: Config
|
||||||
@Inject lateinit var repository: AppRepository
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
|
||||||
@Inject lateinit var rxBus: RxBusWrapper
|
@Inject lateinit var rxBus: RxBusWrapper
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
|
|
||||||
|
@ -305,8 +303,30 @@ class NSClientAddUpdateWorker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||||
eventType == TherapyEvent.Type.PROFILE_SWITCH.text -> Any()
|
eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
|
||||||
// TODO("databaseHelper.createProfileSwitchFromJsonIfNotExists(json)")
|
profileSwitchFromJson(json, dateUtil)?.let { profileSwitch ->
|
||||||
|
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
|
||||||
|
.doOnError {
|
||||||
|
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", 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 ProfileSwitch $it")
|
||||||
|
}
|
||||||
|
result.invalidated.forEach {
|
||||||
|
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||||
|
ValueWithUnit.Timestamp(it.timestamp))
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||||
|
}
|
||||||
|
result.updatedNsId.forEach {
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||||
}
|
}
|
||||||
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
||||||
val date = safeGetLong(json, "mills")
|
val date = safeGetLong(json, "mills")
|
||||||
|
|
|
@ -156,8 +156,20 @@ class NSClientRemoveWorker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// old DB model
|
// room ProfileSwitch
|
||||||
//databaseHelper.deleteProfileSwitchById(nsId)
|
repository.runTransactionForResult(InvalidateNsIdProfileSwitchTransaction(nsId))
|
||||||
|
.doOnError {
|
||||||
|
aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it)
|
||||||
|
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||||
|
}
|
||||||
|
.blockingGet()
|
||||||
|
.also { result ->
|
||||||
|
result.invalidated.forEach {
|
||||||
|
uel.log(
|
||||||
|
Action.CAREPORTAL_REMOVED, Sources.NSClient,
|
||||||
|
ValueWithUnit.Timestamp(it.timestamp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -116,6 +116,15 @@ class NSClientUpdateRemoveAckWorker(
|
||||||
dataSyncSelector.processChangedExtendedBolusesCompat()
|
dataSyncSelector.processChangedExtendedBolusesCompat()
|
||||||
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is PairProfileSwitch -> {
|
||||||
|
val pair = ack.originalObject
|
||||||
|
dataSyncSelector.confirmLastProfileSwitchIdIfGreater(pair.updateRecordId)
|
||||||
|
rxBus.send(EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked ProfileSwitch " + ack._id))
|
||||||
|
// Send new if waiting
|
||||||
|
dataSyncSelector.processChangedProfileSwitchesCompat()
|
||||||
|
ret = Result.success(workDataOf("ProcessedData" to pair.toString()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,28 +86,6 @@ public class UploadQueue implements UploadQueueAdminInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeByNsClientIdIfExists(final JSONObject record) {
|
|
||||||
startService();
|
|
||||||
if (NSClientService.handler != null) {
|
|
||||||
NSClientService.handler.post(() -> {
|
|
||||||
try {
|
|
||||||
String id;
|
|
||||||
if (record.has("NSCLIENT_ID")) {
|
|
||||||
id = record.getString("NSCLIENT_ID");
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (databaseHelper.deleteDbRequest(id) == 1) {
|
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "Removed item from UploadQueue. " + status());
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeByMongoId(final String action, final String _id) {
|
public void removeByMongoId(final String action, final String _id) {
|
||||||
if (_id == null || _id.equals(""))
|
if (_id == null || _id.equals(""))
|
||||||
|
|
|
@ -220,36 +220,18 @@ public class NSClientService extends DaggerService {
|
||||||
|
|
||||||
public void processAddAck(NSAddAck ack) {
|
public void processAddAck(NSAddAck ack) {
|
||||||
lastAckTime = dateUtil.now();
|
lastAckTime = dateUtil.now();
|
||||||
// new room way
|
|
||||||
dataWorker.enqueue(
|
dataWorker.enqueue(
|
||||||
new OneTimeWorkRequest.Builder(NSClientAddAckWorker.class)
|
new OneTimeWorkRequest.Builder(NSClientAddAckWorker.class)
|
||||||
.setInputData(dataWorker.storeInputData(ack, null))
|
.setInputData(dataWorker.storeInputData(ack, null))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
// old way
|
|
||||||
if (ack.nsClientID != null) {
|
|
||||||
uploadQueue.removeByNsClientIdIfExists(ack.json);
|
|
||||||
rxBus.send(new EventNSClientNewLog("DBADD", "Acked " + ack.nsClientID));
|
|
||||||
} else {
|
|
||||||
rxBus.send(new EventNSClientNewLog("ERROR", "DBADD Unknown response"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processUpdateAck(NSUpdateAck ack) {
|
public void processUpdateAck(NSUpdateAck ack) {
|
||||||
lastAckTime = dateUtil.now();
|
lastAckTime = dateUtil.now();
|
||||||
// new room way
|
|
||||||
dataWorker.enqueue(
|
dataWorker.enqueue(
|
||||||
new OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker.class)
|
new OneTimeWorkRequest.Builder(NSClientUpdateRemoveAckWorker.class)
|
||||||
.setInputData(dataWorker.storeInputData(ack, null))
|
.setInputData(dataWorker.storeInputData(ack, null))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
// old way
|
|
||||||
if (ack.getResult()) {
|
|
||||||
uploadQueue.removeByMongoId(ack.getAction(), ack.get_id());
|
|
||||||
rxBus.send(new EventNSClientNewLog("DBUPDATE/DBREMOVE", "Acked " + ack.get_id()));
|
|
||||||
} else {
|
|
||||||
rxBus.send(new EventNSClientNewLog("ERROR", "DBUPDATE/DBREMOVE Unknown response"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processAuthAck(NSAuthAck ack) {
|
public void processAuthAck(NSAuthAck ack) {
|
||||||
|
@ -811,6 +793,7 @@ public class NSClientService extends DaggerService {
|
||||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
||||||
dataSyncSelector.processChangedTemporaryBasalsCompat();
|
dataSyncSelector.processChangedTemporaryBasalsCompat();
|
||||||
dataSyncSelector.processChangedExtendedBolusesCompat();
|
dataSyncSelector.processChangedExtendedBolusesCompat();
|
||||||
|
dataSyncSelector.processChangedProfileSwitchesCompat();
|
||||||
dataSyncSelector.processChangedGlucoseValuesCompat();
|
dataSyncSelector.processChangedGlucoseValuesCompat();
|
||||||
dataSyncSelector.processChangedTempTargetsCompat();
|
dataSyncSelector.processChangedTempTargetsCompat();
|
||||||
dataSyncSelector.processChangedFoodsCompat();
|
dataSyncSelector.processChangedFoodsCompat();
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
<string name="key_ns_device_status_last_synced_id" translatable="false">ns_device_status_last_synced_id</string>
|
<string name="key_ns_device_status_last_synced_id" translatable="false">ns_device_status_last_synced_id</string>
|
||||||
<string name="key_ns_temporary_basal_last_synced_id" translatable="false">ns_temporary_basal_last_synced_id</string>
|
<string name="key_ns_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="treatmentssafety_title">Treatments safety</string>
|
<string name="treatmentssafety_title">Treatments safety</string>
|
||||||
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
|
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
|
||||||
|
|
|
@ -5,29 +5,70 @@ import info.nightscout.androidaps.data.ProfileSealed
|
||||||
import info.nightscout.androidaps.data.PureProfile
|
import info.nightscout.androidaps.data.PureProfile
|
||||||
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
||||||
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||||
|
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||||
|
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal
|
import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal
|
||||||
import info.nightscout.androidaps.utils.JsonHelper
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.lang.Exception
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun profileSwitchFromProfileSwitchJson(jsonObject: JSONObject): ProfileSwitch? {
|
fun ProfileSwitch.toJson(dateUtil: DateUtil): JSONObject =
|
||||||
|
JSONObject()
|
||||||
|
.put("created_at", dateUtil.toISOString(timestamp))
|
||||||
|
.put("enteredBy", "openaps://" + "AndroidAPS")
|
||||||
|
.put("eventType", TherapyEvent.Type.PROFILE_SWITCH.text)
|
||||||
|
.put("duration", T.msecs(duration).mins())
|
||||||
|
.put("profile", getCustomizedName())
|
||||||
|
.put("profileJson", ProfileSealed.PS(this).toPureNsJson(dateUtil))
|
||||||
|
.put("timeshift", T.msecs(timeshift).hours())
|
||||||
|
.put("percentage", percentage)
|
||||||
|
.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 (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSwitch? {
|
||||||
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
|
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
|
||||||
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
|
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
|
||||||
val timeshift = JsonHelper.safeGetInt(jsonObject, "timeshift", 0)
|
val timeshift = JsonHelper.safeGetLong(jsonObject, "timeshift")
|
||||||
val percentage = JsonHelper.safeGetInt(jsonObject, "duration", 100)
|
val percentage = JsonHelper.safeGetInt(jsonObject, "percentage", 100)
|
||||||
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
|
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
|
||||||
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null)
|
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null)
|
||||||
|
val profileName = JsonHelper.safeGetStringAllowNull(jsonObject, "profile", null) ?: return null
|
||||||
|
val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null) ?: return null
|
||||||
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
|
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
|
||||||
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
|
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
|
||||||
val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null)
|
val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null)
|
||||||
|
|
||||||
if (timestamp == 0L) return null
|
if (timestamp == 0L) return null
|
||||||
|
val pureProfile = pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null
|
||||||
|
val profileSealed = ProfileSealed.Pure(pureProfile)
|
||||||
|
|
||||||
return null
|
return ProfileSwitch(
|
||||||
|
timestamp = timestamp,
|
||||||
|
basalBlocks = profileSealed.basalBlocks,
|
||||||
|
isfBlocks = profileSealed.isfBlocks,
|
||||||
|
icBlocks = profileSealed.icBlocks,
|
||||||
|
targetBlocks = profileSealed.targetBlocks,
|
||||||
|
glucoseUnit = ProfileSwitch.GlucoseUnit.fromConstant(profileSealed.units),
|
||||||
|
profileName = profileName,
|
||||||
|
timeshift = T.hours(timeshift).msecs(),
|
||||||
|
percentage = percentage,
|
||||||
|
duration = T.mins(duration).msecs(),
|
||||||
|
insulinConfiguration = profileSealed.insulinConfiguration,
|
||||||
|
isValid = isValid
|
||||||
|
).also {
|
||||||
|
it.interfaceIDs.nightscoutId = id
|
||||||
|
it.interfaceIDs.pumpId = pumpId
|
||||||
|
it.interfaceIDs.pumpType = pumpType
|
||||||
|
it.interfaceIDs.pumpSerial = pumpSerial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,6 +14,7 @@ interface DataSyncSelector {
|
||||||
data class PairBolusCalculatorResult(val value: BolusCalculatorResult, val updateRecordId: Long)
|
data class PairBolusCalculatorResult(val value: BolusCalculatorResult, val updateRecordId: Long)
|
||||||
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)
|
||||||
|
|
||||||
fun resetToNextFullSync()
|
fun resetToNextFullSync()
|
||||||
|
|
||||||
|
@ -66,4 +67,9 @@ interface DataSyncSelector {
|
||||||
fun changedExtendedBoluses() : List<ExtendedBolus>
|
fun changedExtendedBoluses() : List<ExtendedBolus>
|
||||||
// Until NS v3
|
// Until NS v3
|
||||||
fun processChangedExtendedBolusesCompat(): Boolean
|
fun processChangedExtendedBolusesCompat(): Boolean
|
||||||
|
|
||||||
|
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||||
|
fun changedProfileSwitch() : List<ProfileSwitch>
|
||||||
|
// Until NS v3
|
||||||
|
fun processChangedProfileSwitchesCompat(): Boolean
|
||||||
}
|
}
|
|
@ -10,8 +10,6 @@ public interface UploadQueueInterface {
|
||||||
|
|
||||||
void add(DbRequest dbRequest);
|
void add(DbRequest dbRequest);
|
||||||
|
|
||||||
void removeByNsClientIdIfExists(JSONObject record);
|
|
||||||
|
|
||||||
void removeByMongoId(final String action, final String _id);
|
void removeByMongoId(final String action, final String _id);
|
||||||
|
|
||||||
String textList();
|
String textList();
|
||||||
|
|
|
@ -170,6 +170,22 @@ open class AppRepository @Inject internal constructor(
|
||||||
|
|
||||||
// PROFILE SWITCH
|
// PROFILE SWITCH
|
||||||
|
|
||||||
|
fun getNextSyncElementProfileSwitch(id: Long): Maybe<Pair<ProfileSwitch, Long>> =
|
||||||
|
database.profileSwitchDao.getNextModifiedOrNewAfter(id)
|
||||||
|
.flatMap { nextIdElement ->
|
||||||
|
val nextIdElemReferenceId = nextIdElement.referenceId
|
||||||
|
if (nextIdElemReferenceId == null) {
|
||||||
|
Maybe.just(nextIdElement to nextIdElement.id)
|
||||||
|
} else {
|
||||||
|
database.profileSwitchDao.getCurrentFromHistoric(nextIdElemReferenceId)
|
||||||
|
.map { it to nextIdElement.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getModifiedProfileSwitchDataFromId(lastId: Long): Single<List<ProfileSwitch>> =
|
||||||
|
database.profileSwitchDao.getModifiedFrom(lastId)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
fun getActiveProfileSwitch(timestamp: Long): ProfileSwitch? {
|
fun getActiveProfileSwitch(timestamp: Long): ProfileSwitch? {
|
||||||
val tps = database.profileSwitchDao.getTemporaryProfileSwitchActiveAt(timestamp)
|
val tps = database.profileSwitchDao.getTemporaryProfileSwitchActiveAt(timestamp)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
|
@ -19,6 +19,12 @@ internal interface ProfileSwitchDao : ProfileSwitchDaoWorkaround {
|
||||||
@Query("DELETE FROM $TABLE_PROFILE_SWITCHES")
|
@Query("DELETE FROM $TABLE_PROFILE_SWITCHES")
|
||||||
override fun deleteAllEntries()
|
override fun deleteAllEntries()
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp = :timestamp AND referenceId IS NULL")
|
||||||
|
fun findByTimestamp(timestamp: Long): ProfileSwitch?
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE nightscoutId = :nsId AND referenceId IS NULL")
|
||||||
|
fun findByNSId(nsId: String): ProfileSwitch?
|
||||||
|
|
||||||
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp <= :timestamp AND (timestamp + duration) > :timestamp AND referenceId IS NULL AND isValid = 1 ORDER BY timestamp DESC LIMIT 1")
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp <= :timestamp AND (timestamp + duration) > :timestamp AND referenceId IS NULL AND isValid = 1 ORDER BY timestamp DESC LIMIT 1")
|
||||||
fun getTemporaryProfileSwitchActiveAt(timestamp: Long): Maybe<ProfileSwitch>
|
fun getTemporaryProfileSwitchActiveAt(timestamp: Long): Maybe<ProfileSwitch>
|
||||||
|
|
||||||
|
@ -34,6 +40,16 @@ internal interface ProfileSwitchDao : ProfileSwitchDaoWorkaround {
|
||||||
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp >= :timestamp AND isValid = 1 AND referenceId IS NULL ORDER BY timestamp ASC")
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE timestamp >= :timestamp AND isValid = 1 AND referenceId IS NULL ORDER BY timestamp ASC")
|
||||||
fun getProfileSwitchDataFromTime(timestamp: Long): Single<List<ProfileSwitch>>
|
fun getProfileSwitchDataFromTime(timestamp: Long): Single<List<ProfileSwitch>>
|
||||||
|
|
||||||
|
// This query will be used with v3 to get all changed records
|
||||||
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE id > :id AND referenceId IS NULL OR id IN (SELECT DISTINCT referenceId FROM $TABLE_PROFILE_SWITCHES WHERE id > :id) ORDER BY id ASC")
|
||||||
|
fun getModifiedFrom(id: Long): Single<List<ProfileSwitch>>
|
||||||
|
|
||||||
|
// for WS we need 1 record only
|
||||||
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE id > :id ORDER BY id ASC limit 1")
|
||||||
|
fun getNextModifiedOrNewAfter(id: Long): Maybe<ProfileSwitch>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_PROFILE_SWITCHES WHERE id = :referenceId")
|
||||||
|
fun getCurrentFromHistoric(referenceId: Long): Maybe<ProfileSwitch>
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ProfileSwitchDao.insertNewEntryImpl(entry: ProfileSwitch): Long {
|
internal fun ProfileSwitchDao.insertNewEntryImpl(entry: ProfileSwitch): Long {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.Food
|
||||||
|
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||||
|
|
||||||
|
class InvalidateNsIdProfileSwitchTransaction(val nsId: String) : Transaction<InvalidateNsIdProfileSwitchTransaction.TransactionResult>() {
|
||||||
|
|
||||||
|
override fun run() : TransactionResult{
|
||||||
|
val result = TransactionResult()
|
||||||
|
val current = database.profileSwitchDao.findByNSId(nsId)
|
||||||
|
if (current != null) {
|
||||||
|
current.isValid = false
|
||||||
|
database.profileSwitchDao.updateExistingEntry(current)
|
||||||
|
result.invalidated.add(current)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
class TransactionResult {
|
||||||
|
val invalidated = mutableListOf<ProfileSwitch>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync the ProfileSwitch from NS
|
||||||
|
*/
|
||||||
|
class SyncNsProfileSwitchTransaction(private val profileSwitch: ProfileSwitch, private val invalidateByNsOnly: Boolean) : Transaction<SyncNsProfileSwitchTransaction.TransactionResult>() {
|
||||||
|
|
||||||
|
override fun run(): TransactionResult {
|
||||||
|
val result = TransactionResult()
|
||||||
|
|
||||||
|
val current: ProfileSwitch? =
|
||||||
|
profileSwitch.interfaceIDs.nightscoutId?.let {
|
||||||
|
database.profileSwitchDao.findByNSId(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current != null) {
|
||||||
|
// nsId exists, allow only invalidation
|
||||||
|
if (current.isValid && !profileSwitch.isValid) {
|
||||||
|
current.isValid = false
|
||||||
|
database.profileSwitchDao.updateExistingEntry(current)
|
||||||
|
result.invalidated.add(current)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidateByNsOnly) return result
|
||||||
|
|
||||||
|
// not known nsId
|
||||||
|
val existing = database.profileSwitchDao.findByTimestamp(profileSwitch.timestamp)
|
||||||
|
if (existing != null && existing.interfaceIDs.nightscoutId == null) {
|
||||||
|
// the same record, update nsId only
|
||||||
|
existing.interfaceIDs.nightscoutId = profileSwitch.interfaceIDs.nightscoutId
|
||||||
|
existing.isValid = profileSwitch.isValid
|
||||||
|
database.profileSwitchDao.updateExistingEntry(existing)
|
||||||
|
result.updatedNsId.add(existing)
|
||||||
|
} else {
|
||||||
|
database.profileSwitchDao.insertNewEntry(profileSwitch)
|
||||||
|
result.inserted.add(profileSwitch)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
class TransactionResult {
|
||||||
|
|
||||||
|
val updatedNsId = mutableListOf<ProfileSwitch>()
|
||||||
|
val inserted = mutableListOf<ProfileSwitch>()
|
||||||
|
val invalidated = mutableListOf<ProfileSwitch>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.ProfileSwitch
|
||||||
|
|
||||||
|
class UpdateNsIdProfileSwitchTransaction(val profileSwitch: ProfileSwitch) : Transaction<Unit>() {
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val current = database.profileSwitchDao.findById(profileSwitch.id)
|
||||||
|
if (current != null && current.interfaceIDs.nightscoutId != profileSwitch.interfaceIDs.nightscoutId)
|
||||||
|
database.profileSwitchDao.updateExistingEntry(profileSwitch)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue