Remove Tratment.class where possible

This commit is contained in:
Milos Kozak 2021-03-30 19:37:26 +02:00
parent cb298a2646
commit e9f4f87894
95 changed files with 1004 additions and 680 deletions

View file

@ -50,11 +50,11 @@ class CompatDBHelper @Inject constructor(
} }
it.filterIsInstance<Carbs>().firstOrNull()?.let { it.filterIsInstance<Carbs>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange(null)) rxBus.send(EventTreatmentChange())
} }
it.filterIsInstance<Bolus>().firstOrNull()?.let { it.filterIsInstance<Bolus>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange(null)) rxBus.send(EventTreatmentChange())
} }
} }
} }

View file

@ -277,13 +277,13 @@ class CarbsDialog : DialogFragmentWithDate() {
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble() detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
detailedBolusInfo.context = context detailedBolusInfo.context = context
detailedBolusInfo.notes = notes detailedBolusInfo.notes = notes
detailedBolusInfo.carbsDuration = T.mins(duration.toLong()).msecs() detailedBolusInfo.carbsDuration = T.hours(duration.toLong()).msecs()
detailedBolusInfo.carbsTimestamp = time detailedBolusInfo.carbsTimestamp = time
uel.log(Action.CARBS, detailedBolusInfo.notes, uel.log(Action.CARBS, detailedBolusInfo.notes,
ValueWithUnit(detailedBolusInfo.timestamp, Units.Timestamp), ValueWithUnit(detailedBolusInfo.timestamp, Units.Timestamp),
ValueWithUnit(detailedBolusInfo.carbs, Units.G), ValueWithUnit(detailedBolusInfo.carbs, Units.G),
ValueWithUnit(detailedBolusInfo.carbTime, Units.M, detailedBolusInfo.carbTime != 0), ValueWithUnit(detailedBolusInfo.carbTime, Units.M, detailedBolusInfo.carbTime != 0),
ValueWithUnit(detailedBolusInfo.carbsDuration, Units.H, detailedBolusInfo.carbsDuration != 0L) ValueWithUnit(T.msecs(detailedBolusInfo.carbsDuration).hours(), Units.H, detailedBolusInfo.carbsDuration != 0L)
) )
commandQueue.bolus(detailedBolusInfo, object : Callback() { commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() { override fun run() {

View file

@ -177,7 +177,7 @@ class InsulinDialog : DialogFragmentWithDate() {
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, eatingSoonTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation)) actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, eatingSoonTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation))
val timeOffset = binding.time.value.toInt() val timeOffset = binding.time.value.toInt()
val time = DateUtil.now() + T.mins(timeOffset.toLong()).msecs() val time = dateUtil._now() + T.mins(timeOffset.toLong()).msecs()
if (timeOffset != 0) if (timeOffset != 0)
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time)) actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time))

View file

@ -1,21 +0,0 @@
package info.nightscout.androidaps.events
import org.json.JSONObject
/**
* Event which is published with data fetched from NightScout specific for the
* Treatment-class.
*
*
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
class EventNsTreatment(val mode: Int, val payload: JSONObject) : Event() {
companion object {
val ADD = 0
val UPDATE = 1
val REMOVE = 2
}
}

View file

@ -1,5 +1,3 @@
package info.nightscout.androidaps.events package info.nightscout.androidaps.events
import info.nightscout.androidaps.db.Treatment class EventTreatmentChange : EventLoop()
class EventTreatmentChange(val treatment: Treatment?) : EventLoop()

View file

@ -233,7 +233,9 @@ open class LoopPlugin @Inject constructor(
private fun treatmentTimeThreshold(durationMinutes: Int): Boolean { private fun treatmentTimeThreshold(durationMinutes: Int): Boolean {
val threshold = System.currentTimeMillis() + durationMinutes * 60 * 1000 val threshold = System.currentTimeMillis() + durationMinutes * 60 * 1000
var bool = false var bool = false
if (treatmentsPlugin.lastBolusTime > threshold || treatmentsPlugin.lastCarbTime > threshold) bool = true val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
val lastCarbsTime = repository.getLastCarbsRecord()?.timestamp ?: 0L
if (lastBolusTime > threshold || lastCarbsTime > threshold) bool = true
return bool return bool
} }
@ -295,7 +297,7 @@ open class LoopPlugin @Inject constructor(
resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint!!).value() resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint!!).value()
// safety check for multiple SMBs // safety check for multiple SMBs
val lastBolusTime = treatmentsPlugin.lastBolusTime val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastBolusTime != 0L && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) { if (lastBolusTime != 0L && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) {
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval") aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
resultAfterConstraints.smb = 0.0 resultAfterConstraints.smb = 0.0
@ -573,7 +575,7 @@ open class LoopPlugin @Inject constructor(
return return
} }
val pump = activePlugin.activePump val pump = activePlugin.activePump
val lastBolusTime = treatmentsPlugin.lastBolusTime val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval") aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
callback?.result(PumpEnactResult(injector) callback?.result(PumpEnactResult(injector)
@ -595,7 +597,7 @@ open class LoopPlugin @Inject constructor(
// deliver SMB // deliver SMB
val detailedBolusInfo = DetailedBolusInfo() val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.lastBolusTime detailedBolusInfo.lastKnownBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS
detailedBolusInfo.insulin = request.smb detailedBolusInfo.insulin = request.smb
detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.SMB detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.SMB

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.aps.openAPSAMA
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.loop.APSResult import info.nightscout.androidaps.plugins.aps.loop.APSResult
import info.nightscout.androidaps.utils.DateUtil
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
@ -14,7 +13,7 @@ class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector)
private var snoozeBG = 0.0 private var snoozeBG = 0.0
internal constructor(injector: HasAndroidInjector, result: NativeObject, j: JSONObject) : this(injector) { internal constructor(injector: HasAndroidInjector, result: NativeObject, j: JSONObject) : this(injector) {
date = DateUtil.now() date = dateUtil._now()
json = j json = j
if (result.containsKey("error")) { if (result.containsKey("error")) {
reason = result["error"].toString() reason = result["error"].toString()

View file

@ -13,7 +13,7 @@ class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector)
private var snoozeBG = 0.0 private var snoozeBG = 0.0
internal constructor(injector: HasAndroidInjector, result: JSONObject) : this(injector) { internal constructor(injector: HasAndroidInjector, result: JSONObject) : this(injector) {
date = DateUtil.now() date = dateUtil._now()
json = result json = result
try { try {
if (result.has("error")) { if (result.has("error")) {

View file

@ -8,7 +8,7 @@ import android.view.ViewGroup
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry.* import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.databinding.MaintenanceFragmentBinding import info.nightscout.androidaps.databinding.MaintenanceFragmentBinding
import info.nightscout.androidaps.events.EventNewBG import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
@ -17,7 +17,6 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -32,7 +31,6 @@ class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var maintenancePlugin: MaintenancePlugin @Inject lateinit var maintenancePlugin: MaintenancePlugin
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var importExportPrefs: ImportExportPrefsInterface @Inject lateinit var importExportPrefs: ImportExportPrefsInterface
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@ -66,9 +64,6 @@ class MaintenanceFragment : DaggerFragment() {
compositeDisposable.add( compositeDisposable.add(
fromAction { fromAction {
databaseHelper.resetDatabases() databaseHelper.resetDatabases()
// should be handled by Plugin-Interface and
// additional service interface and plugin registry
treatmentsPlugin.service.resetTreatments()
repository.clearDatabases() repository.clearDatabases()
} }
.subscribeOn(aapsSchedulers.io) .subscribeOn(aapsSchedulers.io)

View file

@ -40,7 +40,10 @@ class DataSyncSelectorImplementation @Inject constructor(
// Prepared for v3 (returns all modified after) // Prepared for v3 (returns all modified after)
override fun changedBoluses(): List<Bolus> { override fun changedBoluses(): List<Bolus> {
val startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0) val startId = sp.getLong(R.string.key_ns_bolus_last_synced_id, 0)
return appRepository.getModifiedBolusesDataFromId(startId).blockingGet().also { return appRepository.getModifiedBolusesDataFromId(startId)
.blockingGet()
.filter { it.type != Bolus.Type.PRIMING }
.also {
aapsLogger.debug(LTag.NSCLIENT, "Loading Bolus data for sync from $startId. Records ${it.size}") aapsLogger.debug(LTag.NSCLIENT, "Loading Bolus data for sync from $startId. Records ${it.size}")
} }
} }

View file

@ -9,9 +9,10 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.SyncNsBolusTransaction
import info.nightscout.androidaps.database.transactions.SyncNsCarbsTransaction
import info.nightscout.androidaps.database.transactions.SyncNsTemporaryTargetTransaction import info.nightscout.androidaps.database.transactions.SyncNsTemporaryTargetTransaction
import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction
import info.nightscout.androidaps.events.EventNsTreatment
import info.nightscout.androidaps.interfaces.ConfigInterface import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
@ -25,6 +26,8 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.bolusFromJson
import info.nightscout.androidaps.utils.extensions.carbsFromJson
import info.nightscout.androidaps.utils.extensions.temporaryTargetFromJson import info.nightscout.androidaps.utils.extensions.temporaryTargetFromJson
import info.nightscout.androidaps.utils.extensions.therapyEventFromJson import info.nightscout.androidaps.utils.extensions.therapyEventFromJson
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -73,9 +76,56 @@ class NSClientAddUpdateWorker(
if (mills != 0L && mills < dateutil._now()) if (mills != 0L && mills < dateutil._now())
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
if (insulin > 0) {
bolusFromJson(json)?.let { bolus ->
repository.runTransactionForResult(SyncNsBolusTransaction(bolus))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.inserted.forEach {
uel.log(UserEntry.Action.CAREPORTAL_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.U)
)
}
result.invalidated.forEach {
uel.log(UserEntry.Action.CAREPORTAL_DELETED_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.U)
)
}
}
} ?: aapsLogger.error("Error parsing bolus json $json")
}
if (carbs > 0) {
carbsFromJson(json)?.let { carb ->
repository.runTransactionForResult(SyncNsCarbsTransaction(carb))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.inserted.forEach {
uel.log(UserEntry.Action.CAREPORTAL_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.G)
)
}
result.invalidated.forEach {
uel.log(UserEntry.Action.CAREPORTAL_DELETED_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.G)
)
}
}
} ?: aapsLogger.error("Error parsing bolus json $json")
}
when { when {
insulin > 0 || carbs > 0 -> insulin > 0 || carbs > 0 -> Any()
rxBus.send(EventNsTreatment(EventNsTreatment.ADD, json))
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text -> eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
temporaryTargetFromJson(json)?.let { temporaryTarget -> temporaryTargetFromJson(json)?.let { temporaryTarget ->
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget)) repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget))
@ -115,7 +165,6 @@ class NSClientAddUpdateWorker(
eventType == TherapyEvent.Type.INSULIN_CHANGE.text || eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text || eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
eventType == TherapyEvent.Type.FINGER_STICK_BG_VALUE.text || eventType == TherapyEvent.Type.FINGER_STICK_BG_VALUE.text ||
eventType == TherapyEvent.Type.NOTE.text ||
eventType == TherapyEvent.Type.NONE.text || eventType == TherapyEvent.Type.NONE.text ||
eventType == TherapyEvent.Type.ANNOUNCEMENT.text || eventType == TherapyEvent.Type.ANNOUNCEMENT.text ||
eventType == TherapyEvent.Type.QUESTION.text || eventType == TherapyEvent.Type.QUESTION.text ||

View file

@ -8,10 +8,10 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.SyncNsBolusTransaction
import info.nightscout.androidaps.database.transactions.SyncNsCarbsTransaction
import info.nightscout.androidaps.database.transactions.SyncNsTemporaryTargetTransaction import info.nightscout.androidaps.database.transactions.SyncNsTemporaryTargetTransaction
import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction
import info.nightscout.androidaps.events.EventNsTreatment
import info.nightscout.androidaps.events.EventNsTreatment.Companion.REMOVE
import info.nightscout.androidaps.interfaces.ConfigInterface import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
@ -21,6 +21,8 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.bolusFromNsIdForInvalidating
import info.nightscout.androidaps.utils.extensions.carbsFromNsIdForInvalidating
import info.nightscout.androidaps.utils.extensions.temporaryTargetFromNsIdForInvalidating import info.nightscout.androidaps.utils.extensions.temporaryTargetFromNsIdForInvalidating
import info.nightscout.androidaps.utils.extensions.therapyEventFromNsIdForInvalidating import info.nightscout.androidaps.utils.extensions.therapyEventFromNsIdForInvalidating
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -61,7 +63,7 @@ class NSClientRemoveWorker(
val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId) val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget)) repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing temporary target", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it)
ret = Result.failure() ret = Result.failure()
} }
.blockingGet() .blockingGet()
@ -81,7 +83,7 @@ class NSClientRemoveWorker(
val therapyEvent = therapyEventFromNsIdForInvalidating(nsId) val therapyEvent = therapyEventFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent)) repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing therapy event", it) aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it)
ret = Result.failure() ret = Result.failure()
} }
.blockingGet() .blockingGet()
@ -94,8 +96,40 @@ class NSClientRemoveWorker(
} }
} }
// Insulin, carbs // room Bolus
rxBus.send(EventNsTreatment(REMOVE, json)) val bolus = bolusFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsBolusTransaction(bolus))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.invalidated.forEach {
uel.log(
UserEntry.Action.CAREPORTAL_DELETED_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.U))
}
}
// room Bolus
val carbs = carbsFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsCarbsTransaction(carbs))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.invalidated.forEach {
uel.log(
UserEntry.Action.CAREPORTAL_DELETED_FROM_NS,
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.G))
}
}
// old DB model // old DB model
databaseHelper.deleteTempBasalById(nsId) databaseHelper.deleteTempBasalById(nsId)
databaseHelper.deleteExtendedBolusById(nsId) databaseHelper.deleteExtendedBolusById(nsId)

View file

@ -28,7 +28,6 @@ import info.nightscout.androidaps.interfaces.PluginType
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.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.extensions.toConstant import info.nightscout.androidaps.utils.extensions.toConstant
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -61,7 +60,6 @@ class OpenHumansUploader @Inject constructor(
private val sp: SP, private val sp: SP,
private val rxBus: RxBusWrapper, private val rxBus: RxBusWrapper,
private val context: Context, private val context: Context,
private val treatmentsPlugin: TreatmentsPlugin,
private val databaseHelper: DatabaseHelperInterface, private val databaseHelper: DatabaseHelperInterface,
val repository: AppRepository val repository: AppRepository
) : PluginBase( ) : PluginBase(
@ -356,11 +354,11 @@ class OpenHumansUploader @Inject constructor(
if (currentProgress % 1000L == 0L) showOngoingNotification(maxProgress, currentProgress) if (currentProgress % 1000L == 0L) showOngoingNotification(maxProgress, currentProgress)
} }
copyDisposable = Completable.fromCallable { databaseHelper.clearOpenHumansQueue() } copyDisposable = Completable.fromCallable { databaseHelper.clearOpenHumansQueue() }
.andThen(Single.defer { Single.just(databaseHelper.getCountOfAllRows() + treatmentsPlugin.service.count()) }) // .andThen(Single.defer { Single.just(databaseHelper.getCountOfAllRows() + treatmentsPlugin.service.count()) })
.doOnSuccess { maxProgress = it } // .doOnSuccess { maxProgress = it }
.flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.getTreatmentData()) } } // .flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.getTreatmentData()) } }
.map { enqueueTreatment(it); increaseCounter() } // .map { enqueueTreatment(it); increaseCounter() }
.ignoreElements() // .ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) }) .andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) })
.map { enqueueBGReading(it); increaseCounter() } .map { enqueueBGReading(it); increaseCounter() }
.ignoreElements() .ignoreElements()

View file

@ -778,7 +778,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (config.APS && lastRun?.constraintsProcessed != null) { if (config.APS && lastRun?.constraintsProcessed != null) {
if (lastRun.constraintsProcessed!!.carbsReq > 0) { if (lastRun.constraintsProcessed!!.carbsReq > 0) {
//only display carbsreq when carbs have not been entered recently //only display carbsreq when carbs have not been entered recently
if (treatmentsPlugin.lastCarbTime < lastRun.lastAPSRun) { val lastCarbsTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastCarbsTime < lastRun.lastAPSRun) {
cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required) cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
} }
binding.infoLayout.cob.text = cobText binding.infoLayout.cob.text = cobText

View file

@ -98,7 +98,6 @@ class SmsCommunicatorPlugin @Inject constructor(
val commands = mapOf( val commands = mapOf(
"BG" to "BG", "BG" to "BG",
"LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20", "LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20",
"TREATMENTS" to "TREATMENTS REFRESH",
"NSCLIENT" to "NSCLIENT RESTART", "NSCLIENT" to "NSCLIENT RESTART",
"PUMP" to "PUMP\nPUMP CONNECT\nPUMP DISCONNECT 30\n", "PUMP" to "PUMP\nPUMP CONNECT\nPUMP DISCONNECT 30\n",
"BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n", "BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n",
@ -252,9 +251,6 @@ class SmsCommunicatorPlugin @Inject constructor(
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed))) if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processLOOP(divided, receivedSms) else if (divided.size == 2 || divided.size == 3) processLOOP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"TREATMENTS" ->
if (divided.size == 2) processTREATMENTS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"NSCLIENT" -> "NSCLIENT" ->
if (divided.size == 2) processNSCLIENT(divided, receivedSms) if (divided.size == 2) processNSCLIENT(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
@ -453,16 +449,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
private fun processTREATMENTS(divided: Array<String>, receivedSms: Sms) {
if (divided[1].toUpperCase(Locale.getDefault()) == "REFRESH") {
activePlugin.activeTreatments.service.resetTreatments()
rxBus.send(EventNSClientRestart())
sendSMS(Sms(receivedSms.phoneNumber, "TREATMENTS REFRESH SENT"))
receivedSms.processed = true
} else
sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
}
private fun processNSCLIENT(divided: Array<String>, receivedSms: Sms) { private fun processNSCLIENT(divided: Array<String>, receivedSms: Sms) {
if (divided[1].toUpperCase(Locale.getDefault()) == "RESTART") { if (divided[1].toUpperCase(Locale.getDefault()) == "RESTART") {
rxBus.send(EventNSClientRestart()) rxBus.send(EventNSClientRestart())
@ -870,7 +856,6 @@ class SmsCommunicatorPlugin @Inject constructor(
val detailedBolusInfo = DetailedBolusInfo() val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.carbs = anInteger().toDouble() detailedBolusInfo.carbs = anInteger().toDouble()
detailedBolusInfo.timestamp = secondLong() detailedBolusInfo.timestamp = secondLong()
if (activePlugin.activePump.pumpDescription.storesCarbInfo) {
commandQueue.bolus(detailedBolusInfo, object : Callback() { commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() { override fun run() {
if (result.success) { if (result.success) {
@ -888,14 +873,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
}) })
} else {
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, true)
var replyText = String.format(resourceHelper.gs(R.string.smscommunicator_carbsset), anInteger)
replyText += "\n" + activePlugin.activePump.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
uel.log(Action.SMS_CARBS, activePlugin.activePump.shortStatus(true), ValueWithUnit(R.string.smscommunicator_carbsset, 1), ValueWithUnit(anInteger
?: 0, Units.G))
}
} }
}) })
} }

View file

@ -115,13 +115,15 @@ class UploadChunk @Inject constructor(
private fun getTreatments(start: Long, end: Long): List<BaseElement> { private fun getTreatments(start: Long, end: Long): List<BaseElement> {
val result = LinkedList<BaseElement>() val result = LinkedList<BaseElement>()
val treatments = treatmentsPlugin.service.getTreatmentDataFromTime(start, end, true) repository.getBolusesDataFromTimeToTime(start, end, true)
for (treatment in treatments) { .blockingGet()
if (treatment.carbs > 0) { .forEach { bolus ->
result.add(WizardElement(treatment)) result.add(BolusElement(bolus))
} else if (treatment.insulin > 0) {
result.add(BolusElement(treatment))
} }
repository.getCarbsDataFromTimeToTime(start, end, true)
.blockingGet()
.forEach { carb ->
result.add(WizardElement(carb))
} }
return result return result
} }

View file

@ -1,22 +1,19 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.database.entities.Bolus
import java.util.* import java.util.*
class BolusElement(treatment: Treatment) class BolusElement(bolus: Bolus)
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-bolus" + treatment.date).toByteArray()).toString()) { : BaseElement(bolus.timestamp, UUID.nameUUIDFromBytes(("AAPS-bolus" + bolus.timestamp).toByteArray()).toString()) {
@Expose @Expose var subType = "normal"
var subType = "normal" @Expose var normal: Double = 0.0
@Expose @Expose var expectedNormal: Double = 0.0
var normal: Double = 0.0
@Expose
var expectedNormal: Double = 0.0
init { init {
type = "bolus" type = "bolus"
normal = treatment.insulin normal = bolus.amount
expectedNormal = treatment.insulin expectedNormal = bolus.amount
} }
} }

View file

@ -1,34 +1,29 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements package info.nightscout.androidaps.plugins.general.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.Carbs
import java.util.* import java.util.*
class WizardElement(treatment: Treatment) class WizardElement(carbs: Carbs)
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-wizard" + treatment.date).toByteArray()).toString()) { : BaseElement(carbs.timestamp, UUID.nameUUIDFromBytes(("AAPS-wizard" + carbs.timestamp).toByteArray()).toString()) {
@Expose @Expose var units = "mg/dL"
var units = "mg/dL" @Expose var carbInput: Double = 0.toDouble()
@Expose @Expose var insulinCarbRatio: Double = 0.toDouble()
var carbInput: Double = 0.toDouble() @Expose var bolus: BolusElement? = null
@Expose
var insulinCarbRatio: Double = 0.toDouble()
@Expose
var bolus: BolusElement? = null
init { init {
type = "wizard" type = "wizard"
carbInput = treatment.carbs carbInput = carbs.amount
insulinCarbRatio = treatment.ic val fake = Bolus(
if (treatment.insulin > 0) { amount = 0.0001,
bolus = BolusElement(treatment) timestamp = carbs.timestamp,
} else { type = Bolus.Type.NORMAL,
val fake = Treatment() isBasalInsulin = false
fake.insulin = 0.0001 )
fake.date = treatment.date
bolus = BolusElement(fake) // fake insulin record bolus = BolusElement(fake) // fake insulin record
} }
}
} }
/* TODO fill the rest /* TODO fill the rest

View file

@ -10,7 +10,8 @@ import javax.inject.Singleton
@Singleton @Singleton
class RateLimit @Inject constructor( class RateLimit @Inject constructor(
val aapsLogger: AAPSLogger private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil
) { ) {
private val rateLimits = HashMap<String, Long>() private val rateLimits = HashMap<String, Long>()
@ -20,13 +21,13 @@ class RateLimit @Inject constructor(
fun rateLimit(name: String, seconds: Int): Boolean { fun rateLimit(name: String, seconds: Int): Boolean {
// check if over limit // check if over limit
rateLimits[name]?.let { rateLimits[name]?.let {
if (DateUtil.now() - it < T.secs(seconds.toLong()).msecs()) { if (dateUtil._now() - it < T.secs(seconds.toLong()).msecs()) {
aapsLogger.debug(LTag.TIDEPOOL, "$name rate limited: $seconds seconds") aapsLogger.debug(LTag.TIDEPOOL, "$name rate limited: $seconds seconds")
return false return false
} }
} }
// not over limit // not over limit
rateLimits[name] = DateUtil.now() rateLimits[name] = dateUtil._now()
return true return true
} }
} }

View file

@ -26,7 +26,6 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
@ -78,8 +77,7 @@ class ActionStringHandler @Inject constructor(
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val config: Config, private val config: Config,
private val databaseHelper: DatabaseHelperInterface, private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository, private val repository: AppRepository
private val nsUpload: NSUpload
) { ) {
private val timeout = 65 * 1000 private val timeout = 65 * 1000
@ -613,9 +611,8 @@ class ActionStringHandler @Inject constructor(
detailedBolusInfo.carbs = carbs.toDouble() detailedBolusInfo.carbs = carbs.toDouble()
detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.NORMAL detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.NORMAL
detailedBolusInfo.carbsTimestamp = carbsTime detailedBolusInfo.carbsTimestamp = carbsTime
detailedBolusInfo.carbsDuration = carbsDuration.toLong() detailedBolusInfo.carbsDuration = T.hours(carbsDuration.toLong()).msecs()
val storesCarbs = activePlugin.activePump.pumpDescription.storesCarbInfo if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
if (detailedBolusInfo.insulin > 0 || (storesCarbs && carbsDuration == 0)) {
commandQueue.bolus(detailedBolusInfo, object : Callback() { commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() { override fun run() {
if (!result.success) { if (!result.success) {
@ -625,8 +622,6 @@ class ActionStringHandler @Inject constructor(
} }
} }
}) })
} else {
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
} }
} }

View file

@ -527,6 +527,8 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
} }
repository.getBolusesIncludingInvalidFromTime(startTimeWindow, true).blockingGet() repository.getBolusesIncludingInvalidFromTime(startTimeWindow, true).blockingGet()
.stream()
.filter(bolus -> bolus.getType() != Bolus.Type.PRIMING)
.forEach(bolus -> boluses.add(treatmentMap(bolus.getTimestamp(), bolus.getAmount(), 0, bolus.getType() == Bolus.Type.SMB, bolus.isValid()))); .forEach(bolus -> boluses.add(treatmentMap(bolus.getTimestamp(), bolus.getAmount(), 0, bolus.getType() == Bolus.Type.SMB, bolus.isValid())));
repository.getCarbsIncludingInvalidFromTime(startTimeWindow, true).blockingGet() repository.getCarbsIncludingInvalidFromTime(startTimeWindow, true).blockingGet()
.forEach(carb -> boluses.add(treatmentMap(carb.getTimestamp(), 0, carb.getAmount(), false, carb.isValid()))); .forEach(carb -> boluses.add(treatmentMap(carb.getTimestamp(), 0, carb.getAmount(), false, carb.isValid())));

View file

@ -6,7 +6,7 @@ import android.util.AttributeSet
import com.jjoe64.graphview.GraphView import com.jjoe64.graphview.GraphView
import com.jjoe64.graphview.series.DataPoint import com.jjoe64.graphview.series.DataPoint
import com.jjoe64.graphview.series.LineGraphSeries import com.jjoe64.graphview.series.LineGraphSeries
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.InsulinInterface import info.nightscout.androidaps.interfaces.InsulinInterface
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import java.util.* import java.util.*
@ -22,15 +22,17 @@ class ActivityGraph : GraphView {
removeAllSeries() removeAllSeries()
mSecondScale = null mSecondScale = null
val hours = floor(insulin.dia + 1).toLong() val hours = floor(insulin.dia + 1).toLong()
val t = Treatment().also { val bolus = Bolus(
it.date = 0 timestamp = 0,
it.insulin = 1.0 amount = 1.0,
} type = Bolus.Type.NORMAL,
isBasalInsulin = false
)
val activityArray: MutableList<DataPoint> = ArrayList() val activityArray: MutableList<DataPoint> = ArrayList()
val iobArray: MutableList<DataPoint> = ArrayList() val iobArray: MutableList<DataPoint> = ArrayList()
var time: Long = 0 var time: Long = 0
while (time <= T.hours(hours).msecs()) { while (time <= T.hours(hours).msecs()) {
val iob = t.iobCalc(time, insulin.dia) val iob = insulin.iobCalcForTreatment(bolus, time, insulin.dia)
activityArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.activityContrib)) activityArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.activityContrib))
iobArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.iobContrib)) iobArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.iobContrib))
time += T.mins(5).msecs() time += T.mins(5).msecs()

View file

@ -28,6 +28,7 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.extensions.expandCarbs
import info.nightscout.androidaps.utils.extensions.iobCalc import info.nightscout.androidaps.utils.extensions.iobCalc
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -531,7 +532,8 @@ open class IobCobCalculatorPlugin @Inject constructor(
var displayCob: Double? = null var displayCob: Double? = null
var futureCarbs = 0.0 var futureCarbs = 0.0
val now = DateUtil.now() val now = DateUtil.now()
val carbs = repository.getCarbsDataFromTime(now, true).blockingGet() val carbs = repository.getCarbsDataFromTime(now, true)
.blockingGet()
if (autosensData != null) { if (autosensData != null) {
displayCob = autosensData.cob displayCob = autosensData.cob
carbs.forEach { carb -> carbs.forEach { carb ->
@ -601,7 +603,10 @@ open class IobCobCalculatorPlugin @Inject constructor(
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME) sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
} }
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong() val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
repository.getCarbsDataFromTimeToTime(absorptionTimeAgo + 1, now, true).blockingGet().forEach { repository.getCarbsDataFromTimeToTime(absorptionTimeAgo + 1, now, true)
.map { it.map { c -> c.expandCarbs() }.flatten() }
.blockingGet()
.forEach {
if (it.amount > 0) { if (it.amount > 0) {
result.carbs += it.amount result.carbs += it.amount
if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp
@ -614,7 +619,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact
} }
result.lastBolusTime = treatmentsPlugin.lastBolusTime result.lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
return result return result
} }
@ -778,6 +783,15 @@ open class IobCobCalculatorPlugin @Inject constructor(
} }
} }
/**
* Time range to the past for IOB calculation
* @return milliseconds
*/
fun range(): Long {
val dia = profileFunction.getProfile()?.dia ?: Constants.defaultDIA
return (60 * 60 * 1000L * (24 + dia)).toLong()
}
override fun calculateIobFromBolus(): IobTotal = calculateIobFromBolusToTime(dateUtil._now()) override fun calculateIobFromBolus(): IobTotal = calculateIobFromBolusToTime(dateUtil._now())
override fun calculateIobFromBolusToTime(timestamp: Long): IobTotal { override fun calculateIobFromBolusToTime(timestamp: Long): IobTotal {
@ -786,7 +800,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
val dia = profile.dia val dia = profile.dia
val divisor = sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0) val divisor = sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0)
val boluses = repository.getBolusesDataFromTime(timestamp, true).blockingGet() val boluses = repository.getBolusesDataFromTime(timestamp - range(), true).blockingGet()
boluses.forEach { t -> boluses.forEach { t ->
if (t.isValid && t.timestamp < timestamp) { if (t.isValid && t.timestamp < timestamp) {

View file

@ -10,9 +10,9 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.InstanceId.instanceId import info.nightscout.androidaps.utils.InstanceId.instanceId
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
@ -25,7 +25,8 @@ class MDIPlugin @Inject constructor(
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
commandQueue: CommandQueueProvider, commandQueue: CommandQueueProvider,
private val treatmentsPlugin: TreatmentsPlugin private val dateUtil: DateUtil,
private val pumpSync: PumpSync
) : PumpPluginBase(PluginDescription() ) : PumpPluginBase(PluginDescription()
.mainType(PluginType.PUMP) .mainType(PluginType.PUMP)
.pluginIcon(R.drawable.ic_ict) .pluginIcon(R.drawable.ic_ict)
@ -73,7 +74,21 @@ class MDIPlugin @Inject constructor(
result.bolusDelivered = detailedBolusInfo.insulin result.bolusDelivered = detailedBolusInfo.insulin
result.carbsDelivered = detailedBolusInfo.carbs result.carbsDelivered = detailedBolusInfo.carbs
result.comment = resourceHelper.gs(R.string.virtualpump_resultok) result.comment = resourceHelper.gs(R.string.virtualpump_resultok)
treatmentsPlugin.addToHistoryTreatment(detailedBolusInfo, false) if (detailedBolusInfo.insulin > 0)
pumpSync.syncBolusWithPumpId(
timestamp = detailedBolusInfo.timestamp,
amount = detailedBolusInfo.insulin,
type = detailedBolusInfo.bolusType,
pumpId = dateUtil._now(),
pumpType = PumpType.MDI,
pumpSerial = serialNumber())
if (detailedBolusInfo.carbs > 0)
pumpSync.syncCarbsWithTimestamp(
timestamp = detailedBolusInfo.timestamp + T.mins(detailedBolusInfo.carbTime.toLong()).msecs(),
amount = detailedBolusInfo.carbs,
pumpId = null,
pumpType = PumpType.MDI,
pumpSerial = serialNumber())
return result return result
} }

View file

@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.InstanceId.instanceId import info.nightscout.androidaps.utils.InstanceId.instanceId
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -205,11 +206,20 @@ open class VirtualPumpPlugin @Inject constructor(
rxBus.send(EventVirtualPumpUpdateGui()) rxBus.send(EventVirtualPumpUpdateGui())
lastDataTime = System.currentTimeMillis() lastDataTime = System.currentTimeMillis()
if (detailedBolusInfo.insulin > 0) if (detailedBolusInfo.insulin > 0)
pumpSync.syncBolusWithPumpId(dateUtil._now(), detailedBolusInfo.insulin, detailedBolusInfo.bolusType, dateUtil._now(), pumpType pumpSync.syncBolusWithPumpId(
?: PumpType.GENERIC_AAPS, serialNumber()) timestamp = detailedBolusInfo.timestamp,
amount = detailedBolusInfo.insulin,
type = detailedBolusInfo.bolusType,
pumpId = dateUtil._now(),
pumpType = pumpType ?: PumpType.GENERIC_AAPS,
pumpSerial = serialNumber())
if (detailedBolusInfo.carbs > 0) if (detailedBolusInfo.carbs > 0)
pumpSync.syncCarbsWithTimestamp(dateUtil._now(), detailedBolusInfo.carbs, dateUtil._now(), pumpType pumpSync.syncCarbsWithTimestamp(
?: PumpType.GENERIC_AAPS, serialNumber()) timestamp = detailedBolusInfo.timestamp + T.mins(detailedBolusInfo.carbTime.toLong()).msecs(),
amount = detailedBolusInfo.carbs,
pumpId = null,
pumpType = pumpType ?: PumpType.GENERIC_AAPS,
pumpSerial = serialNumber())
return result return result
} }

View file

@ -106,6 +106,7 @@ open class SensitivityOref1Plugin @Inject constructor(
if (isEvent5minBack(siteChanges, autosensData.time)) { if (isEvent5minBack(siteChanges, autosensData.time)) {
deviationsArray.clear() deviationsArray.clear()
pastSensitivity += "(SITECHANGE)" pastSensitivity += "(SITECHANGE)"
pastSensitivity += "(SITECHANGE)"
} }
// reset deviations after profile switch // reset deviations after profile switch

View file

@ -87,7 +87,8 @@ class RandomBgPlugin @Inject constructor(
} }
override fun specialEnableCondition(): Boolean { override fun specialEnableCondition(): Boolean {
return isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode() // return isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode()
return true
} }
private fun handleNewData() { private fun handleNewData() {

View file

@ -17,8 +17,6 @@ import com.j256.ormlite.table.TableUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,7 +34,6 @@ import info.nightscout.androidaps.db.ICallback;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
@ -49,11 +46,8 @@ import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData; import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers; import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import io.reactivex.disposables.CompositeDisposable;
/** /**
@ -70,8 +64,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
@Inject OpenHumansUploader openHumansUploader; @Inject OpenHumansUploader openHumansUploader;
@Inject AapsSchedulers aapsSchedulers; @Inject AapsSchedulers aapsSchedulers;
private final CompositeDisposable disposable = new CompositeDisposable();
private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTreatmentEventPost = null; private static ScheduledFuture<?> scheduledTreatmentEventPost = null;
@ -79,20 +71,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
injector.androidInjector().inject(this); injector.androidInjector().inject(this);
onCreate(); onCreate();
dbInitialize(); dbInitialize();
disposable.add(rxBus
.toObservable(EventNsTreatment.class)
.observeOn(aapsSchedulers.getIo())
.subscribe(event -> {
int mode = event.getMode();
JSONObject payload = event.getPayload();
if (mode == EventNsTreatment.Companion.getADD() || mode == EventNsTreatment.Companion.getUPDATE()) {
this.createTreatmentFromJsonIfNotExists(payload);
} else { // EventNsTreatment.REMOVE
this.deleteNS(payload);
}
}, fabricPrivacy::logException)
);
} }
/** /**
@ -215,18 +193,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} }
} }
public void resetTreatments() {
try {
TableUtils.dropTable(this.getConnectionSource(), Treatment.class, true);
TableUtils.createTableIfNotExists(this.getConnectionSource(), Treatment.class);
DatabaseHelper.updateEarliestDataChange(0);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleTreatmentChange(null, true);
}
/** /**
* A place to centrally register events to be posted, if any data changed. * A place to centrally register events to be posted, if any data changed.
* This should be implemented in an abstract service-class. * This should be implemented in an abstract service-class.
@ -272,14 +238,14 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
public void scheduleTreatmentChange(@Nullable final Treatment treatment, boolean runImmediately) { public void scheduleTreatmentChange(@Nullable final Treatment treatment, boolean runImmediately) {
if (runImmediately) { if (runImmediately) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventReloadTreatmentData"); aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventReloadTreatmentData");
rxBus.send(new EventReloadTreatmentData(new EventTreatmentChange(treatment))); rxBus.send(new EventReloadTreatmentData(new EventTreatmentChange()));
if (DatabaseHelper.earliestDataChange != null) { if (DatabaseHelper.earliestDataChange != null) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventNewHistoryData"); aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventNewHistoryData");
rxBus.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange)); rxBus.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
} }
DatabaseHelper.earliestDataChange = null; DatabaseHelper.earliestDataChange = null;
} else { } else {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() { this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange()), treatmentEventWorker, new ICallback() {
@Override @Override
public void setPost(ScheduledFuture<?> post) { public void setPost(ScheduledFuture<?> post) {
scheduledTreatmentEventPost = post; scheduledTreatmentEventPost = post;
@ -293,16 +259,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} }
} }
public List<Treatment> getTreatmentData() {
try {
return this.getDao().queryForAll();
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public long count() { public long count() {
try { try {
return this.getDao().countOf(); return this.getDao().countOf();
@ -326,26 +282,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
"unit": "ml" "unit": "ml"
} }
*/ */
public void createTreatmentFromJsonIfNotExists(JSONObject json) {
try {
Treatment treatment = Treatment.createFromJson(json);
if (treatment != null) {
if (MedtronicHistoryData.doubleBolusDebug)
aapsLogger.debug(LTag.DATATREATMENTS, "DoubleBolusDebug: createTreatmentFromJsonIfNotExists:: medtronicPump={}", medtronicPumpPlugin.isEnabled());
if (!medtronicPumpPlugin.isEnabled())
createOrUpdate(treatment);
else
createOrUpdateMedtronic(treatment, true);
} else
aapsLogger.error("Date is null: " + treatment.toString());
} catch (JSONException e) {
aapsLogger.error("Unhandled exception", e);
}
}
// return true if new record is created // return true if new record is created
public UpdateReturn createOrUpdate(Treatment treatment) { public UpdateReturn createOrUpdate(Treatment treatment) {
if (treatment != null && treatment.source == Source.NONE) { if (treatment != null && treatment.source == Source.NONE) {
@ -654,107 +590,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
} }
} }
/**
* Returns the newest record with insulin > 0
*/
@Nullable
public Treatment getLastBolus(boolean excludeSMB) {
try {
QueryBuilder<Treatment, Long> queryBuilder = getDao().queryBuilder();
Where where = queryBuilder.where();
where.gt("insulin", 0);
where.and().le("date", DateUtil.now());
where.and().eq("isValid", true);
if (excludeSMB) where.and().eq("isSMB", false);
queryBuilder.orderBy("date", false);
queryBuilder.limit(1L);
List<Treatment> result = getDao().query(queryBuilder.prepare());
if (result.isEmpty())
return null;
return result.get(0);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* Returns the newest record with carbs > 0
*/
@Nullable
public Treatment getLastCarb() {
try {
QueryBuilder<Treatment, Long> queryBuilder = getDao().queryBuilder();
Where where = queryBuilder.where();
where.gt("carbs", 0);
where.and().le("date", DateUtil.now());
where.and().eq("isValid", true);
queryBuilder.orderBy("date", false);
queryBuilder.limit(1L);
List<Treatment> result = getDao().query(queryBuilder.prepare());
if (result.isEmpty())
return null;
return result.get(0);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void deleteNS(JSONObject json) {
String _id = JsonHelper.safeGetString(json, "_id");
if (_id != null && !_id.isEmpty())
this.deleteByNSId(_id);
}
/**
* deletes an entry by its NS Id.
* <p>
* Basically a convenience method for findByNSId and delete.
*
* @param _id
*/
private void deleteByNSId(String _id) {
Treatment stored = findByNSId(_id);
if (stored != null) {
aapsLogger.debug(LTag.DATATREATMENTS, "Removing Treatment record from database: " + stored.toString());
try {
getDao().delete(stored);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
DatabaseHelper.updateEarliestDataChange(stored.date);
this.scheduleTreatmentChange(stored, false);
}
}
/**
* deletes the treatment and sends the treatmentChange Event
* <p>
* should be moved ot a Service
*
* @param treatment
*/
public void delete(Treatment treatment) {
try {
getDao().delete(treatment);
DatabaseHelper.updateEarliestDataChange(treatment.date);
this.scheduleTreatmentChange(treatment, true);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
}
public void update(Treatment treatment) {
try {
getDao().update(treatment);
DatabaseHelper.updateEarliestDataChange(treatment.date);
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
scheduleTreatmentChange(treatment, true);
}
/** /**
* finds treatment by its NS Id. * finds treatment by its NS Id.
* *
@ -784,40 +619,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
return null; return null;
} }
public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) {
try {
TreatmentDaoWrapper daoTreatments = getDao();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
treatments = daoTreatments.query(preparedQuery);
return treatments;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public List<Treatment> getTreatmentDataFromTime(long from, long to, boolean ascending) {
try {
TreatmentDaoWrapper daoTreatments = getDao();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", from, to);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
treatments = daoTreatments.query(preparedQuery);
return treatments;
} catch (SQLException e) {
aapsLogger.error("Unhandled exception", e);
}
return new ArrayList<>();
}
@Nullable @Nullable
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {

View file

@ -8,7 +8,6 @@ import androidx.annotation.Nullable;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -62,6 +61,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryDa
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.extensions.BolusExtensionKt;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers; import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -240,7 +240,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
/** /**
* Returns all Treatments after specified timestamp. Also returns invalid entries (required to * Returns all Treatments after specified timestamp. Also returns invalid entries (required to
* map "Fill Canula" entries to history (and not to add double bolus for it) * map "Fill Cannula" entries to history (and not to add double bolus for it)
* *
* @param fromTimestamp * @param fromTimestamp
* @return * @return
@ -269,7 +269,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
} }
*/ */
} }
/*
@Override @Override
public long getLastBolusTime() { public long getLastBolusTime() {
Treatment last = getService().getLastBolus(false); Treatment last = getService().getLastBolus(false);
@ -305,6 +305,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
} }
*/
@Override @Override
public boolean isInHistoryRealTempBasalInProgress() { public boolean isInHistoryRealTempBasalInProgress() {
return getRealTempBasalFromHistory(System.currentTimeMillis()) != null; return getRealTempBasalFromHistory(System.currentTimeMillis()) != null;
@ -413,10 +415,21 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (runningTBR != null) { if (runningTBR != null) {
running = runningTBR.tempBasalConvertedToAbsolute(i, profile); running = runningTBR.tempBasalConvertedToAbsolute(i, profile);
} }
Treatment treatment = new Treatment(getInjector()); Bolus bolus = new Bolus(
treatment.date = i; 0, // id
treatment.insulin = running * 5.0 / 60.0; // 5 min chunk 0, // version
Iob iob = treatment.iobCalc(time, profile.getDia()); 0, //dateCreated
true, // isValid
null,
null,
i,
0,
running * 5.0 / 60.0,
Bolus.Type.NORMAL,
true,
null
);
Iob iob = BolusExtensionKt.iobCalc(bolus, activePlugin, time, profile.getDia());
total.basaliob += iob.getIobContrib(); total.basaliob += iob.getIobContrib();
total.activity += iob.getActivityContrib(); total.activity += iob.getActivityContrib();
} }

View file

@ -101,7 +101,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribeBy( .subscribeBy(
onError = { aapsLogger.error("Error removing entries", it) }, onError = { aapsLogger.error("Error removing entries", it) },
onComplete = { rxBus.send(EventTreatmentChange(null)) } onComplete = { rxBus.send(EventTreatmentChange()) }
) )
rxBus.send(EventNSClientRestart()) rxBus.send(EventNSClientRestart())
} }
@ -190,7 +190,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
.zipWith(bolusMealLinksWithInvalid(now)) { first, second -> first + second } .zipWith(bolusMealLinksWithInvalid(now)) { first, second -> first + second }
.zipWith(calcResultMealLinksWithInvalid(now)) { first, second -> first + second } .zipWith(calcResultMealLinksWithInvalid(now)) { first, second -> first + second }
.map { ml -> .map { ml ->
ml.sortedBy { ml.sortedByDescending {
it.carbs?.timestamp ?: it.bolus?.timestamp it.carbs?.timestamp ?: it.bolus?.timestamp
?: it.bolusCalculatorResult?.timestamp ?: it.bolusCalculatorResult?.timestamp
} }
@ -205,7 +205,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
.zipWith(bolusMealLinks(now)) { first, second -> first + second } .zipWith(bolusMealLinks(now)) { first, second -> first + second }
.zipWith(calcResultMealLinks(now)) { first, second -> first + second } .zipWith(calcResultMealLinks(now)) { first, second -> first + second }
.map { ml -> .map { ml ->
ml.sortedBy { ml.sortedByDescending {
it.carbs?.timestamp ?: it.bolus?.timestamp it.carbs?.timestamp ?: it.bolus?.timestamp
?: it.bolusCalculatorResult?.timestamp ?: it.bolusCalculatorResult?.timestamp
} }
@ -285,7 +285,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
when (ml.bolus.type) { when (ml.bolus.type) {
Bolus.Type.SMB -> "SMB" Bolus.Type.SMB -> "SMB"
Bolus.Type.NORMAL -> resourceHelper.gs(R.string.mealbolus) Bolus.Type.NORMAL -> resourceHelper.gs(R.string.mealbolus)
else -> "" Bolus.Type.PRIMING -> resourceHelper.gs(R.string.prime)
} }
} }
// Carbs // Carbs
@ -293,6 +293,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
ml.carbs?.let { carbs -> ml.carbs?.let { carbs ->
holder.binding.carbsDate.text = dateUtil.timeString(carbs.timestamp) holder.binding.carbsDate.text = dateUtil.timeString(carbs.timestamp)
holder.binding.carbs.text = resourceHelper.gs(R.string.format_carbs, carbs.amount.toInt()) holder.binding.carbs.text = resourceHelper.gs(R.string.format_carbs, carbs.amount.toInt())
holder.binding.carbsDuration.text = resourceHelper.gs(R.string.format_mins, T.msecs(carbs.duration).mins().toInt())
holder.binding.carbsNs.visibility = (NSUpload.isIdValid(carbs.interfaceIDs.nightscoutId)).toVisibility() holder.binding.carbsNs.visibility = (NSUpload.isIdValid(carbs.interfaceIDs.nightscoutId)).toVisibility()
holder.binding.carbsPump.visibility = (carbs.interfaceIDs.pumpId != null).toVisibility() holder.binding.carbsPump.visibility = (carbs.interfaceIDs.pumpId != null).toVisibility()
holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility() holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility()

View file

@ -217,7 +217,8 @@ open class CommandQueue @Inject constructor(
aapsLogger.debug(LTag.PUMPQUEUE, "Rejecting SMB since a bolus is queue/running") aapsLogger.debug(LTag.PUMPQUEUE, "Rejecting SMB since a bolus is queue/running")
return false return false
} }
if (detailedBolusInfo.lastKnownBolusTime < activePlugin.get().activeTreatments.lastBolusTime) { val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (detailedBolusInfo.lastKnownBolusTime < lastBolusTime) {
aapsLogger.debug(LTag.PUMPQUEUE, "Rejecting bolus, another bolus was issued since request time") aapsLogger.debug(LTag.PUMPQUEUE, "Rejecting bolus, another bolus was issued since request time")
return false return false
} }

View file

@ -22,7 +22,7 @@ class CommandSMBBolus(
override fun execute() { override fun execute() {
val r: PumpEnactResult val r: PumpEnactResult
val lastBolusTime = activePlugin.activeTreatments.lastBolusTime val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastBolusTime != 0L && lastBolusTime + T.mins(3).msecs() > dateUtil._now()) { if (lastBolusTime != 0L && lastBolusTime + T.mins(3).msecs() > dateUtil._now()) {
aapsLogger.debug(LTag.PUMPQUEUE, "SMB requested but still in 3 min interval") aapsLogger.debug(LTag.PUMPQUEUE, "SMB requested but still in 3 min interval")
r = PumpEnactResult(injector).enacted(false).success(false).comment("SMB requested but still in 3 min interval") r = PumpEnactResult(injector).enacted(false).success(false).comment("SMB requested but still in 3 min interval")

View file

@ -6,6 +6,7 @@ import android.util.LongSparseArray
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.db.TDD import info.nightscout.androidaps.db.TDD
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
@ -56,7 +57,9 @@ class TddCalculator @Inject constructor(
initializeData(range) initializeData(range)
val result = LongSparseArray<TDD>() val result = LongSparseArray<TDD>()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet().forEach { t-> repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING }
.forEach { t->
val midnight = MidnightTime.calc(t.timestamp) val midnight = MidnightTime.calc(t.timestamp)
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0) val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
tdd.bolus += t.amount tdd.bolus += t.amount

View file

@ -78,28 +78,22 @@
android:text="1.1.2000" android:text="1.1.2000"
tools:ignore="HardcodedText,RtlSymmetry" /> tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/treatments_insulin_label_string" />
<TextView <TextView
android:id="@+id/insulin" android:id="@+id/insulin"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp" android:layout_marginStart="10dp"
android:textStyle="bold" /> android:text="1.00 U"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top" android:layout_gravity="top"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="5dp"
android:text="@string/treatments_iob_label_string" /> android:text="@string/treatments_iob_label_string" />
<TextView <TextView
@ -107,13 +101,14 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp" android:text="0.45U"
android:textStyle="bold" /> android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginEnd="5dp"
android:layout_weight="1" android:layout_weight="1"
android:text="" /> android:text="" />
@ -121,7 +116,6 @@
android:id="@+id/meal_or_correction" android:id="@+id/meal_or_correction"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="Meal" android:text="Meal"
android:textAlignment="textEnd" android:textAlignment="textEnd"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
@ -130,7 +124,7 @@
android:id="@+id/bolus_ns" android:id="@+id/bolus_ns"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="NS" android:text="NS"
android:textColor="@color/colorSetTempButton" android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
@ -139,7 +133,7 @@
android:id="@+id/bolus_pump" android:id="@+id/bolus_pump"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="PH" android:text="PH"
android:textColor="@color/colorSetTempButton" android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
@ -148,7 +142,7 @@
android:id="@+id/bolus_invalid" android:id="@+id/bolus_invalid"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="@string/invalid" android:text="@string/invalid"
android:textColor="@android:color/holo_red_light" /> android:textColor="@android:color/holo_red_light" />
@ -156,11 +150,16 @@
android:id="@+id/bolus_remove" android:id="@+id/bolus_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="@string/remove_button" android:text="@string/remove_button"
android:textAlignment="viewEnd" android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" /> android:textColor="@android:color/holo_orange_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -201,10 +200,16 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView
android:id="@+id/carbs_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textStyle="bold" />
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1" android:layout_weight="1"
android:text="" /> android:text="" />
@ -212,7 +217,7 @@
android:id="@+id/carbs_ns" android:id="@+id/carbs_ns"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="NS" android:text="NS"
android:textColor="@color/colorSetTempButton" android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
@ -221,7 +226,7 @@
android:id="@+id/carbs_pump" android:id="@+id/carbs_pump"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="PH" android:text="PH"
android:textColor="@color/colorSetTempButton" android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" /> tools:ignore="HardcodedText" />
@ -230,7 +235,7 @@
android:id="@+id/carbs_invalid" android:id="@+id/carbs_invalid"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="@string/invalid" android:text="@string/invalid"
android:textColor="@android:color/holo_red_light" /> android:textColor="@android:color/holo_red_light" />
@ -238,20 +243,25 @@
android:id="@+id/carbs_remove" android:id="@+id/carbs_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginStart="5dp"
android:text="@string/remove_button" android:text="@string/remove_button"
android:textAlignment="viewEnd" android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" /> android:textColor="@android:color/holo_orange_light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp" />
</LinearLayout> </LinearLayout>
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:background="@color/list_delimiter" /> android:background="@color/list_delimiter" />
</LinearLayout> </LinearLayout>

View file

@ -1134,5 +1134,6 @@
<string name="current_basal_value">Current basal value</string> <string name="current_basal_value">Current basal value</string>
<string name="profile_carbs_ratio_value">Profile carbs ratio value</string> <string name="profile_carbs_ratio_value">Profile carbs ratio value</string>
<string name="full_sync">Full sync</string> <string name="full_sync">Full sync</string>
<string name="prime">Prime</string>
</resources> </resources>

View file

@ -468,36 +468,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("LOOP BLABLA", smsCommunicatorPlugin.messages[0].text) Assert.assertEquals("LOOP BLABLA", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text) Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
//TREATMENTS REFRESH
PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true)
PowerMockito.`when`(loopPlugin.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "TREATMENTS REFRESH")
smsCommunicatorPlugin.processSms(sms)
Assert.assertFalse(sms.ignored)
Assert.assertEquals("TREATMENTS REFRESH", smsCommunicatorPlugin.messages[0].text)
Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("TREATMENTS REFRESH"))
//TREATMENTS BLA BLA
PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true)
PowerMockito.`when`(loopPlugin.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "TREATMENTS BLA BLA")
smsCommunicatorPlugin.processSms(sms)
Assert.assertFalse(sms.ignored)
Assert.assertEquals("TREATMENTS BLA BLA", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
//TREATMENTS BLABLA
PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true)
PowerMockito.`when`(loopPlugin.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "TREATMENTS BLABLA")
smsCommunicatorPlugin.processSms(sms)
Assert.assertFalse(sms.ignored)
Assert.assertEquals("TREATMENTS BLABLA", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
//NSCLIENT RESTART //NSCLIENT RESTART
PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true) PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true)
PowerMockito.`when`(loopPlugin.isSuspended).thenReturn(false) PowerMockito.`when`(loopPlugin.isSuspended).thenReturn(false)

View file

@ -11,6 +11,7 @@ import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
@ -41,7 +42,8 @@ import java.util.*
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest( @PrepareForTest(
ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class, ConstraintChecker::class, VirtualPumpPlugin::class, ToastUtils::class, Context::class,
TreatmentsPlugin::class, FabricPrivacy::class, LoggerUtils::class, PowerManager::class) TreatmentsPlugin::class, FabricPrivacy::class, LoggerUtils::class, PowerManager::class,
AppRepository::class)
class CommandQueueTest : TestBaseWithProfile() { class CommandQueueTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var constraintChecker: ConstraintChecker
@ -113,7 +115,14 @@ class CommandQueueTest : TestBaseWithProfile() {
`when`(lazyActivePlugin.get()).thenReturn(activePlugin) `when`(lazyActivePlugin.get()).thenReturn(activePlugin)
`when`(activePlugin.activePump).thenReturn(testPumpPlugin) `when`(activePlugin.activePump).thenReturn(testPumpPlugin)
`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface) `when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface)
`when`(treatmentsInterface.lastBolusTime).thenReturn(Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis) `when`(repository.getLastBolusRecord()).thenReturn(
Bolus(
timestamp = Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis,
type = Bolus.Type.NORMAL,
amount = 0.0,
isBasalInsulin = false
)
)
`when`(profileFunction.getProfile()).thenReturn(validProfile) `when`(profileFunction.getProfile()).thenReturn(validProfile)
val bolusConstraint = Constraint(0.0) val bolusConstraint = Constraint(0.0)

View file

@ -75,7 +75,7 @@ class QueueThreadTest : TestBaseWithProfile() {
Mockito.`when`(lazyActivePlugin.get()).thenReturn(activePlugin) Mockito.`when`(lazyActivePlugin.get()).thenReturn(activePlugin)
Mockito.`when`(activePlugin.activePump).thenReturn(pumpPlugin) Mockito.`when`(activePlugin.activePump).thenReturn(pumpPlugin)
Mockito.`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface) Mockito.`when`(activePlugin.activeTreatments).thenReturn(treatmentsInterface)
Mockito.`when`(treatmentsInterface.lastBolusTime).thenReturn(Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis) // Mockito.`when`(treatmentsInterface.lastBolusTime).thenReturn(Calendar.getInstance().also { it.set(2000, 0, 1) }.timeInMillis)
Mockito.`when`(profileFunction.getProfile()).thenReturn(validProfile) Mockito.`when`(profileFunction.getProfile()).thenReturn(validProfile)
val bolusConstraint = Constraint(0.0) val bolusConstraint = Constraint(0.0)

View file

@ -10,6 +10,7 @@ import androidx.appcompat.app.AppCompatActivity
import com.google.common.base.Optional import com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
@ -22,6 +23,7 @@ import info.nightscout.androidaps.plugins.general.automation.events.EventTrigger
import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.services.LastLocationDataContainer import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException import org.json.JSONException
@ -37,10 +39,11 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var locationDataContainer: LastLocationDataContainer @Inject lateinit var locationDataContainer: LastLocationDataContainer
@Inject lateinit var treatmentsInterface: TreatmentsInterface @Inject lateinit var repository: AppRepository
@Inject lateinit var activePlugin: ActivePluginProvider @Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculator @Inject lateinit var iobCobCalculatorPlugin: IobCobCalculator
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Inject lateinit var dateUtil: DateUtil
init { init {
injector.androidInjector().inject(this) injector.androidInjector().inject(this)

View file

@ -4,19 +4,20 @@ import android.widget.LinearLayout
import com.google.common.base.Optional import com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetString import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import org.json.JSONObject import org.json.JSONObject
class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) { class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
var minutesAgo: InputDuration = InputDuration( 30, InputDuration.TimeUnit.MINUTES)
var minutesAgo: InputDuration = InputDuration(30, InputDuration.TimeUnit.MINUTES)
var comparator: Comparator = Comparator(resourceHelper) var comparator: Comparator = Comparator(resourceHelper)
private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) { private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) {
@ -35,7 +36,7 @@ class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
} }
override fun shouldRun(): Boolean { override fun shouldRun(): Boolean {
val lastBolusTime = treatmentsInterface.getLastBolusTime(true) val lastBolusTime = repository.getLastBolusRecordOfType(Bolus.Type.NORMAL)?.timestamp ?: 0L
if (lastBolusTime == 0L) if (lastBolusTime == 0L)
return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) { return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
@ -44,7 +45,7 @@ class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
false false
} }
val last = (DateUtil.now() - lastBolusTime).toDouble() / (60 * 1000) val last = (dateUtil._now() - lastBolusTime).toDouble() / (60 * 1000)
aapsLogger.debug(LTag.AUTOMATION, "LastBolus min ago: $minutesAgo") aapsLogger.debug(LTag.AUTOMATION, "LastBolus min ago: $minutesAgo")
val doRun = comparator.value.check(last.toInt(), minutesAgo.getMinutes()) val doRun = comparator.value.check(last.toInt(), minutesAgo.getMinutes())
if (doRun) { if (doRun) {

View file

@ -10,15 +10,12 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputTime
import info.nightscout.androidaps.plugins.general.automation.elements.InputWeekDay import info.nightscout.androidaps.plugins.general.automation.elements.InputWeekDay
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import org.json.JSONObject import org.json.JSONObject
import java.util.* import java.util.*
import javax.inject.Inject
class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) { class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var dateUtil: DateUtil
val days = InputWeekDay() val days = InputWeekDay()
val time = InputTime(resourceHelper, dateUtil) val time = InputTime(resourceHelper, dateUtil)
@ -34,7 +31,7 @@ class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
return this return this
} }
override fun shouldRun() : Boolean { override fun shouldRun(): Boolean {
val currentMinSinceMidnight = getMinSinceMidnight(dateUtil._now()) val currentMinSinceMidnight = getMinSinceMidnight(dateUtil._now())
val scheduledDayOfWeek = Calendar.getInstance()[Calendar.DAY_OF_WEEK] val scheduledDayOfWeek = Calendar.getInstance()[Calendar.DAY_OF_WEEK]
if (days.isSet(Objects.requireNonNull(InputWeekDay.DayOfWeek.fromCalendarInt(scheduledDayOfWeek)))) { if (days.isSet(Objects.requireNonNull(InputWeekDay.DayOfWeek.fromCalendarInt(scheduledDayOfWeek)))) {

View file

@ -4,22 +4,16 @@ import android.widget.LinearLayout
import com.google.common.base.Optional import com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject
class TriggerTempTarget(injector: HasAndroidInjector) : Trigger(injector) { class TriggerTempTarget(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
var comparator = ComparatorExists(resourceHelper) var comparator = ComparatorExists(resourceHelper)
constructor(injector: HasAndroidInjector, compare: ComparatorExists.Compare) : this(injector) { constructor(injector: HasAndroidInjector, compare: ComparatorExists.Compare) : this(injector) {

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.automation.triggers package info.nightscout.androidaps.plugins.general.automation.triggers
import android.content.Context
import android.widget.LinearLayout import android.widget.LinearLayout
import com.google.common.base.Optional import com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
@ -13,10 +12,8 @@ import info.nightscout.androidaps.utils.DateUtil
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 javax.inject.Inject
class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) { class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var dateUtil: DateUtil
var time = InputDateTime(resourceHelper, dateUtil) var time = InputDateTime(resourceHelper, dateUtil)
@ -24,7 +21,8 @@ class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) {
this.time.value = runAt this.time.value = runAt
} }
@Suppress("unused") constructor(injector: HasAndroidInjector, triggerTime: TriggerTime) : this(injector) { @Suppress("unused")
constructor(injector: HasAndroidInjector, triggerTime: TriggerTime) : this(injector) {
this.time.value = triggerTime.time.value this.time.value = triggerTime.time.value
} }

View file

@ -13,13 +13,10 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject
// Trigger for time range ( from 10:00AM till 13:00PM ) // Trigger for time range ( from 10:00AM till 13:00PM )
class TriggerTimeRange(injector: HasAndroidInjector) : Trigger(injector) { class TriggerTimeRange(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var dateUtil: DateUtil
// in minutes since midnight 60 means 1AM // in minutes since midnight 60 means 1AM
var range = InputTimeRange(resourceHelper, dateUtil) var range = InputTimeRange(resourceHelper, dateUtil)
@ -28,7 +25,8 @@ class TriggerTimeRange(injector: HasAndroidInjector) : Trigger(injector) {
range.end = end range.end = end
} }
@Suppress("unused") constructor(injector: HasAndroidInjector, triggerTimeRange: TriggerTimeRange) : this(injector) { @Suppress("unused")
constructor(injector: HasAndroidInjector, triggerTimeRange: TriggerTimeRange) : this(injector) {
range.start = triggerTimeRange.range.start range.start = triggerTimeRange.range.start
range.end = triggerTimeRange.range.end range.end = triggerTimeRange.range.end
} }

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.db.ProfileSwitch import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
@ -21,7 +22,7 @@ import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
@PrepareForTest(FabricPrivacy::class) @PrepareForTest(FabricPrivacy::class, AppRepository::class)
open class TestBaseWithProfile : TestBase() { open class TestBaseWithProfile : TestBase() {
@Mock lateinit var activePluginProvider: ActivePluginProvider @Mock lateinit var activePluginProvider: ActivePluginProvider
@ -32,6 +33,7 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var defaultValueHelper: DefaultValueHelper @Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var dateUtil: DateUtil @Mock lateinit var dateUtil: DateUtil
@Mock lateinit var configInterface: ConfigInterface @Mock lateinit var configInterface: ConfigInterface
@Mock lateinit var repository: AppRepository
val rxBus = RxBusWrapper(aapsSchedulers) val rxBus = RxBusWrapper(aapsSchedulers)

View file

@ -6,7 +6,6 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -18,7 +17,7 @@ import org.mockito.Mock
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
@PrepareForTest(RxBusWrapper::class, ActionsTestBase.TestLoopPlugin::class, AppRepository::class) @PrepareForTest(RxBusWrapper::class, ActionsTestBase.TestLoopPlugin::class)
open class ActionsTestBase : TestBaseWithProfile() { open class ActionsTestBase : TestBaseWithProfile() {
open class TestLoopPlugin( open class TestLoopPlugin(
@ -45,7 +44,6 @@ open class ActionsTestBase : TestBaseWithProfile() {
@Mock lateinit var profilePlugin: ProfileInterface @Mock lateinit var profilePlugin: ProfileInterface
@Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorInterface @Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorInterface
@Mock lateinit var loopPlugin: TestLoopPlugin @Mock lateinit var loopPlugin: TestLoopPlugin
@Mock lateinit var repository: AppRepository
private val pluginDescription = PluginDescription() private val pluginDescription = PluginDescription()
lateinit var testPumpPlugin: TestPumpPlugin lateinit var testPumpPlugin: TestPumpPlugin

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.automation.triggers
import com.google.common.base.Optional import com.google.common.base.Optional
import info.nightscout.androidaps.automation.R import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import org.json.JSONException import org.json.JSONException
@ -29,8 +30,15 @@ class TriggerBolusAgoTest : TriggerTestBase() {
@Test @Test
fun shouldRunTest() { fun shouldRunTest() {
`when`(treatmentsInterface.getLastBolusTime(true)).thenReturn(now) // Set last bolus time to now `when`(repository.getLastBolusRecordOfType(Bolus.Type.NORMAL)).thenReturn(
`when`(DateUtil.now()).thenReturn(now + 10 * 60 * 1000) // set current time to now + 10 min Bolus(
timestamp = now,
amount = 0.0,
type = Bolus.Type.NORMAL,
isBasalInsulin = false
)
) // Set last bolus time to now
`when`(dateUtil._now()).thenReturn(now + 10 * 60 * 1000) // set current time to now + 10 min
var t = TriggerBolusAgo(injector).setValue(110).comparator(Comparator.Compare.IS_EQUAL) var t = TriggerBolusAgo(injector).setValue(110).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(110, t.minutesAgo.value) Assert.assertEquals(110, t.minutesAgo.value)
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t.comparator.value) Assert.assertEquals(Comparator.Compare.IS_EQUAL, t.comparator.value)
@ -52,7 +60,14 @@ class TriggerBolusAgoTest : TriggerTestBase() {
Assert.assertTrue(t.shouldRun()) Assert.assertTrue(t.shouldRun())
t = TriggerBolusAgo(injector).setValue(390).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER) t = TriggerBolusAgo(injector).setValue(390).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
Assert.assertTrue(t.shouldRun()) Assert.assertTrue(t.shouldRun())
PowerMockito.`when`(treatmentsInterface.getLastBolusTime(true)).thenReturn(0L) // Set last bolus time to 0 `when`(repository.getLastBolusRecordOfType(Bolus.Type.NORMAL)).thenReturn(
Bolus(
timestamp = 0L,
amount = 0.0,
type = Bolus.Type.NORMAL,
isBasalInsulin = false
)
) // Set last bolus time to 0
t = TriggerBolusAgo(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE) t = TriggerBolusAgo(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
Assert.assertTrue(t.shouldRun()) Assert.assertTrue(t.shouldRun())
} }

View file

@ -14,13 +14,14 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.receivers.ReceiverStatusStore import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.LastLocationDataContainer import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Before import org.junit.Before
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
@PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class, AppRepository::class) @PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class)
open class TriggerTestBase : TestBaseWithProfile() { open class TriggerTestBase : TestBaseWithProfile() {
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
@ -29,11 +30,10 @@ open class TriggerTestBase : TestBaseWithProfile() {
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator @Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
@Mock lateinit var context: Context @Mock lateinit var context: Context
@Mock lateinit var automationPlugin: AutomationPlugin @Mock lateinit var automationPlugin: AutomationPlugin
@Mock lateinit var repository: AppRepository
lateinit var receiverStatusStore: ReceiverStatusStore lateinit var receiverStatusStore: ReceiverStatusStore
private val pluginDescription = PluginDescription() private val pluginDescription = PluginDescription()
lateinit var testPumpPlugin : TestPumpPlugin lateinit var testPumpPlugin: TestPumpPlugin
@Before @Before
fun prepareMock1() { fun prepareMock1() {
@ -51,10 +51,11 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.profileFunction = profileFunction it.profileFunction = profileFunction
it.sp = sp it.sp = sp
it.locationDataContainer = locationDataContainer it.locationDataContainer = locationDataContainer
it.treatmentsInterface = treatmentsInterface it.repository = repository
it.activePlugin = activePlugin it.activePlugin = activePlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin) it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin)
it.dateUtil = dateUtil
} }
if (it is TriggerBg) { if (it is TriggerBg) {
it.profileFunction = profileFunction it.profileFunction = profileFunction

View file

@ -28,7 +28,6 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider;
@ -488,8 +487,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
treatmentsPlugin.addToHistoryTreatment(detailedBolusInfo, false); treatmentsPlugin.addToHistoryTreatment(detailedBolusInfo, false);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE;
bolusingEvent.setT(new Treatment()); bolusingEvent.setT(new EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB));
bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
bolusingEvent.setPercent(100); bolusingEvent.setPercent(100);
rxBus.send(bolusingEvent); rxBus.send(bolusingEvent);
@ -566,8 +564,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
return new PumpEnactResult(getInjector()).success(true).enacted(false); return new PumpEnactResult(getInjector()).success(true).enacted(false);
} }
Treatment treatment = new Treatment(); EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
treatment.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
EventOverviewBolusProgress.INSTANCE.setT(treatment); EventOverviewBolusProgress.INSTANCE.setT(treatment);
// start bolus delivery // start bolus delivery

View file

@ -31,11 +31,8 @@ class PumpEnactResult(injector: HasAndroidInjector) {
var bolusDelivered = 0.0 // real value of delivered insulin var bolusDelivered = 0.0 // real value of delivered insulin
var carbsDelivered = 0.0 // real value of delivered carbs var carbsDelivered = 0.0 // real value of delivered carbs
var queued = false var queued = false
fun success(success: Boolean): PumpEnactResult {
this.success = success
return this
}
fun success(success: Boolean): PumpEnactResult = this.also { this.success = success }
fun enacted(enacted: Boolean): PumpEnactResult = this.also { it.enacted = enacted } fun enacted(enacted: Boolean): PumpEnactResult = this.also { it.enacted = enacted }
fun comment(comment: String): PumpEnactResult = this.also { it.comment = comment } fun comment(comment: String): PumpEnactResult = this.also { it.comment = comment }
fun comment(comment: Int): PumpEnactResult = this.also { it.comment = resourceHelper.gs(comment) } fun comment(comment: Int): PumpEnactResult = this.also { it.comment = resourceHelper.gs(comment) }

View file

@ -297,14 +297,6 @@ public class Treatment implements DataPointWithLabelInterface, DbObjectBase {
// ----------------- DataPointInterface end -------------------- // ----------------- DataPointInterface end --------------------
public Iob iobCalc(long time, double dia) {
if (!isValid)
return new Iob();
InsulinInterface insulinInterface = activePlugin.getActiveInsulin();
return insulinInterface.iobCalcForTreatment(this, time, dia);
}
@Override @Override
public long getDate() { public long getDate() {
return this.date; return this.date;

View file

@ -4,8 +4,53 @@ import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
interface PumpSync { interface PumpSync {
fun addBolusWithTempId(timestamp: Long, amount: Double, driverId: Long, pumpType: PumpType, pumpSerial: String) /**
fun syncBolusWithTempId(timestamp: Long, amount: Double, driverId: Long, pumpId: Long?, pumpType: PumpType, pumpSerial: String) * Create bolus with temporary id
*
* Search for combination of temporaryId, PumpType, pumpSerial
*
* If db record doesn't exist, new record is created.
* If exists false is returned and data is ignored
*
* USAGE:
* Generate unique temporaryId
* Call before bolus when no pumpId is known (provide timestamp, amount, temporaryId, type, pumpType, pumpSerial)
* After reading record from history or completed bolus call syncBolusWithTempId with the same temporaryId provided
* If syncBolusWithTempId is not called afterwards record remains valid and is calculated towards iob
*
* @param timestamp timestamp of event from pump history
* @param amount amount of insulin
* @param temporaryId temporary id generated when pump id in not know yet
* @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number
* @return true if new record is created
**/
fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String) : Boolean
/**
* Synchronization of boluses with temporary id
*
* Search for combination of temporaryId, PumpType, pumpSerial
*
* If db record doesn't exist data is ignored and false returned.
* If exists, amount and timestamp is updated, type and pumpId only if provided
* isValid field is preserved
*
* USAGE:
* After reading record from history or completed bolus call syncBolusWithTempId and
* provide updated timestamp, amount, pumpId (if known), type (if change needed) with the same temporaryId, pumpType, pumpSerial
*
* @param timestamp timestamp of event from pump history
* @param amount amount of insulin
* @param temporaryId temporary id generated when pump id in not know yet
* @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number
* @return true if record is successfully updated
**/
fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String) : Boolean
/** /**
* Synchronization of boluses * Synchronization of boluses
@ -13,17 +58,18 @@ interface PumpSync {
* Search for combination of pumpId, PumpType, pumpSerial * Search for combination of pumpId, PumpType, pumpSerial
* *
* If db record doesn't exist, new record is created. * If db record doesn't exist, new record is created.
* If exists, data is updated * If exists, amount, type (if provided) and timestamp is updated
* isValid field is preserved * isValid field is preserved
* *
* @param timestamp timestamp of event from pump history * @param timestamp timestamp of event from pump history
* @param amount amount of insulin * @param amount amount of insulin
* @param type type of bolus (NORMAL, SMB, PRIME). Default is NORMAL * @param type type of bolus (NORMAL, SMB, PRIME)
* @param pumpId pump id from history * @param pumpId pump id from history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO * @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number * @param pumpSerial pump serial number
* @return true if new record is created
**/ **/
fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType = DetailedBolusInfo.BolusType.NORMAL, pumpId: Long, pumpType: PumpType, pumpSerial: String) fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String) : Boolean
/** /**
* Synchronization of carbs * Synchronization of carbs
@ -39,8 +85,9 @@ interface PumpSync {
* @param pumpId pump id from history if coming form pump history * @param pumpId pump id from history if coming form pump history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO * @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @param pumpSerial pump serial number * @param pumpSerial pump serial number
* @return true if new record is created
**/ **/
fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String) fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String) : Boolean
/** /**
* Synchronization of events like CANNULA_CHANGE * Synchronization of events like CANNULA_CHANGE

View file

@ -4,15 +4,6 @@ import info.nightscout.androidaps.db.Treatment
interface TreatmentServiceInterface { interface TreatmentServiceInterface {
fun getTreatmentDataFromTime(mills: Long, ascending: Boolean): List<Treatment>
fun getTreatmentDataFromTime(from: Long, to: Long, ascending: Boolean): List<Treatment>
fun getTreatmentData(): List<Treatment>
fun getLastBolus(excludeSMB: Boolean): Treatment?
fun getLastCarb(): Treatment?
fun createOrUpdateMedtronic(treatment: Treatment, fromNightScout: Boolean): UpdateReturn fun createOrUpdateMedtronic(treatment: Treatment, fromNightScout: Boolean): UpdateReturn
fun createOrUpdate(treatment: Treatment): UpdateReturn fun createOrUpdate(treatment: Treatment): UpdateReturn
fun resetTreatments()
fun delete(data: Treatment)
fun update(data: Treatment)
fun count(): Long
} }

View file

@ -31,10 +31,6 @@ public interface TreatmentsInterface {
@Deprecated @Deprecated
List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp); List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp);
long getLastBolusTime();
long getLastBolusTime(boolean excludeSMB);
// real basals (not faked by extended bolus) // real basals (not faked by extended bolus)
boolean isInHistoryRealTempBasalInProgress(); boolean isInHistoryRealTempBasalInProgress();

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface
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.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -37,6 +38,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
@Inject lateinit var treatmentsPlugin: TreatmentsInterface @Inject lateinit var treatmentsPlugin: TreatmentsInterface
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var dateUtil: DateUtil
var date: Long = 0 var date: Long = 0
var reason: String? = null var reason: String? = null

View file

@ -43,18 +43,21 @@ public class NSUpload {
private final SP sp; private final SP sp;
private final UploadQueueInterface uploadQueue; private final UploadQueueInterface uploadQueue;
private final RunningConfiguration runningConfiguration; private final RunningConfiguration runningConfiguration;
private final DateUtil dateUtil;
@Inject @Inject
public NSUpload( public NSUpload(
AAPSLogger aapsLogger, AAPSLogger aapsLogger,
SP sp, SP sp,
UploadQueueInterface uploadQueue, UploadQueueInterface uploadQueue,
RunningConfiguration runningConfiguration RunningConfiguration runningConfiguration,
DateUtil dateUtil
) { ) {
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.sp = sp; this.sp = sp;
this.uploadQueue = uploadQueue; this.uploadQueue = uploadQueue;
this.runningConfiguration = runningConfiguration; this.runningConfiguration = runningConfiguration;
this.dateUtil = dateUtil;
} }
public void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) { public void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
@ -208,7 +211,7 @@ public class NSUpload {
IobTotal[] iob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile); IobTotal[] iob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile);
if (iob.length > 0) { if (iob.length > 0) {
deviceStatus.iob = iob[0].json(); deviceStatus.iob = iob[0].json();
deviceStatus.iob.put("time", DateUtil.toISOString(DateUtil.now())); deviceStatus.iob.put("time", DateUtil.toISOString(dateUtil._now()));
} }
} }
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.plugins.general.overview.events package info.nightscout.androidaps.plugins.general.overview.events
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
object EventOverviewBolusProgress : Event() { object EventOverviewBolusProgress : Event() {
data class Treatment constructor(@JvmField var insulin: Double = 0.0, @JvmField var carbs: Int = 0, @JvmField var isSMB: Boolean)
var status = "" var status = ""
var t: Treatment? = null var t: Treatment? = null
var percent = 0 var percent = 0

View file

@ -13,7 +13,6 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.core.R; import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.database.entities.Carbs; import info.nightscout.androidaps.database.entities.Carbs;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;

View file

@ -6,10 +6,7 @@ import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.Carbs import info.nightscout.androidaps.database.entities.Carbs
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampCarbsTransaction import info.nightscout.androidaps.database.transactions.*
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
import info.nightscout.androidaps.database.transactions.SyncPumpBolusTransaction
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -25,19 +22,54 @@ class PumpSyncImplementation @Inject constructor(
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
override fun addBolusWithTempId(timestamp: Long, amount: Double, driverId: Long, pumpType: PumpType, pumpSerial: String) { override fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String) : Boolean {
TODO("Not yet implemented")
}
override fun syncBolusWithTempId(timestamp: Long, amount: Double, driverId: Long, pumpId: Long?, pumpType: PumpType, pumpSerial: String) {
TODO("Not yet implemented")
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType, pumpId: Long, pumpType: PumpType, pumpSerial: String) {
val bolus = Bolus( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
amount = amount, amount = amount,
type = type.toDBbBolusType(), type = type.toDBbBolusType(),
interfaceIDs_backing = InterfaceIDs(
temporaryId = temporaryId,
pumpType = pumpType.toDbPumpType(),
pumpSerial = pumpSerial
),
isBasalInsulin = false
)
repository.runTransactionForResult(InsertPumpBolusWithTempIdTransaction(bolus))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
.blockingGet()
.also { result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") }
return result.inserted.size > 0
}
}
override fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
type = Bolus.Type.NORMAL, // not used for update
interfaceIDs_backing = InterfaceIDs(
temporaryId = temporaryId,
pumpId = pumpId,
pumpType = pumpType.toDbPumpType(),
pumpSerial = pumpSerial
),
isBasalInsulin = false
)
repository.runTransactionForResult(SyncPumpBolusWithTempIdTransaction(bolus, type?.toDBbBolusType()))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
.blockingGet()
.also { result ->
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") }
return result.updated.size > 0
}
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
type = type?.toDBbBolusType() ?: Bolus.Type.NORMAL,
interfaceIDs_backing = InterfaceIDs( interfaceIDs_backing = InterfaceIDs(
pumpId = pumpId, pumpId = pumpId,
pumpType = pumpType.toDbPumpType(), pumpType = pumpType.toDbPumpType(),
@ -45,17 +77,17 @@ class PumpSyncImplementation @Inject constructor(
), ),
isBasalInsulin = false isBasalInsulin = false
) )
disposable += repository.runTransactionForResult(SyncPumpBolusTransaction(bolus)) repository.runTransactionForResult(SyncPumpBolusTransaction(bolus, type?.toDBbBolusType()))
.subscribe( .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
{ result -> .blockingGet()
.also { result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") } result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") }
}, return result.inserted.size > 0
{ aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) } }
)
} }
override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String) { override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
val carbs = Carbs( val carbs = Carbs(
timestamp = timestamp, timestamp = timestamp,
amount = amount, amount = amount,
@ -65,11 +97,13 @@ class PumpSyncImplementation @Inject constructor(
pumpType = pumpType.toDbPumpType(), pumpType = pumpType.toDbPumpType(),
pumpSerial = pumpSerial) pumpSerial = pumpSerial)
) )
disposable += repository.runTransactionForResult(InsertIfNewByTimestampCarbsTransaction(carbs)) repository.runTransactionForResult(InsertIfNewByTimestampCarbsTransaction(carbs))
.subscribe( .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") } }, .blockingGet()
{ aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) } .also { result ->
) result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") }
return result.inserted.size > 0
}
} }
override fun insertTherapyEventIfNewWithTimestamp(timestamp: Long, type: DetailedBolusInfo.EventType, note: String?, pumpId: Long?, pumpType: PumpType, pumpSerial: String) { override fun insertTherapyEventIfNewWithTimestamp(timestamp: Long, type: DetailedBolusInfo.EventType, note: String?, pumpId: Long?, pumpType: PumpType, pumpSerial: String) {

View file

@ -1,7 +1,5 @@
package info.nightscout.androidaps.plugins.treatments; package info.nightscout.androidaps.plugins.treatments;
import info.nightscout.androidaps.db.Treatment;
public class TreatmentUpdateReturn { public class TreatmentUpdateReturn {
public TreatmentUpdateReturn(boolean success, boolean newRecord) { public TreatmentUpdateReturn(boolean success, boolean newRecord) {

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
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.queue.Callback import info.nightscout.androidaps.queue.Callback
@ -17,6 +18,7 @@ abstract class Command(
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var repository: AppRepository
enum class CommandType { enum class CommandType {
BOLUS, BOLUS,

View file

@ -1,19 +1,17 @@
package info.nightscout.androidaps.utils.extensions package info.nightscout.androidaps.utils.extensions
import com.google.gson.Gson
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Iob import info.nightscout.androidaps.data.Iob
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.InsulinInterface import info.nightscout.androidaps.interfaces.InsulinInterface
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import org.json.JSONException import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject import org.json.JSONObject
fun Bolus.iobCalc(activePlugin: ActivePluginProvider, time: Long, dia: Double): Iob { fun Bolus.iobCalc(activePlugin: ActivePluginProvider, time: Long, dia: Double): Iob {
if (!isValid) return Iob() if (!isValid || type == Bolus.Type.PRIMING ) return Iob()
val insulinInterface: InsulinInterface = activePlugin.activeInsulin val insulinInterface: InsulinInterface = activePlugin.activeInsulin
return insulinInterface.iobCalcForTreatment(this, time, dia) return insulinInterface.iobCalcForTreatment(this, time, dia)
} }
@ -24,8 +22,48 @@ fun Bolus.toJson(): JSONObject =
.put("insulin", amount) .put("insulin", amount)
.put("created_at", DateUtil.toISOString(timestamp)) .put("created_at", DateUtil.toISOString(timestamp))
.put("date", timestamp) .put("date", timestamp)
.put("type", type.name)
.put("isValid", isValid)
.put("isSMB", type == Bolus.Type.SMB).also { .put("isSMB", type == Bolus.Type.SMB).also {
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId) 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) if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
} }
/*
create fake object with nsID and isValid == false
*/
fun bolusFromNsIdForInvalidating(nsId: String): Bolus =
bolusFromJson(
JSONObject()
.put("mills", 1)
.put("insulin", -1.0)
.put("_id", nsId)
.put("isValid", false)
)!!
fun bolusFromJson(jsonObject: JSONObject): Bolus? {
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val amount = JsonHelper.safeGetDoubleAllowNull(jsonObject, "insulin") ?: return null
val type = Bolus.Type.fromString(JsonHelper.safeGetString(jsonObject, "type"))
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", 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)
return Bolus(
timestamp = timestamp,
amount = amount,
type = type,
isValid = isValid,
isBasalInsulin = false
).also {
it.interfaceIDs.nightscoutId = id
it.interfaceIDs.pumpId = pumpId
it.interfaceIDs.pumpType = pumpType
it.interfaceIDs.pumpSerial = pumpSerial
}
}

View file

@ -1,10 +1,13 @@
package info.nightscout.androidaps.utils.extensions package info.nightscout.androidaps.utils.extensions
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Carbs import info.nightscout.androidaps.database.entities.Carbs
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
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.util.concurrent.TimeUnit
import kotlin.math.roundToInt import kotlin.math.roundToInt
fun Carbs.expandCarbs(): List<Carbs> = fun Carbs.expandCarbs(): List<Carbs> =
@ -13,7 +16,7 @@ fun Carbs.expandCarbs(): List<Carbs> =
carbs.add(this) carbs.add(this)
} else { } else {
var remainingCarbs = this.amount var remainingCarbs = this.amount
val ticks = T.msecs(this.duration).mins() * 4 //duration guaranteed to be integer greater zero val ticks = T.msecs(this.duration).hours() * 4 //duration guaranteed to be integer greater zero
for (i in 0 until ticks) { for (i in 0 until ticks) {
val carbTime = this.timestamp + i * 15 * 60 * 1000 val carbTime = this.timestamp + i * 15 * 60 * 1000
val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
@ -36,5 +39,43 @@ fun Carbs.toJson(): JSONObject =
.put("date", timestamp).also { .put("date", timestamp).also {
if (duration != 0L) it.put("duration", duration) if (duration != 0L) it.put("duration", duration)
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId) 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) if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
} }
/*
create fake object with nsID and isValid == false
*/
fun carbsFromNsIdForInvalidating(nsId: String): Carbs =
carbsFromJson(
JSONObject()
.put("mills", 1)
.put("carbs", -1.0)
.put("_id", nsId)
.put("isValid", false)
)!!
fun carbsFromJson(jsonObject: JSONObject): Carbs? {
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val duration = JsonHelper.safeGetLong(jsonObject, "duration")
val amount = JsonHelper.safeGetDoubleAllowNull(jsonObject, "carbs") ?: return null
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", 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)
return Carbs(
timestamp = timestamp,
duration = duration,
amount = amount,
isValid = isValid
).also {
it.interfaceIDs.nightscoutId = id
it.interfaceIDs.pumpId = pumpId
it.interfaceIDs.pumpType = pumpType
it.interfaceIDs.pumpSerial = pumpSerial
}
}

View file

@ -3,10 +3,10 @@ package info.nightscout.androidaps.dana
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ProfileStore import info.nightscout.androidaps.interfaces.ProfileStore
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.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -180,7 +180,7 @@ class DanaPump @Inject constructor(
var bolusStartErrorCode: Int = 0 // last start bolus erroCode var bolusStartErrorCode: Int = 0 // last start bolus erroCode
var historyDoneReceived: Boolean = false // true when last history message is received var historyDoneReceived: Boolean = false // true when last history message is received
var bolusingTreatment: Treatment? = null // actually delivered treatment var bolusingTreatment: EventOverviewBolusProgress.Treatment? = null // actually delivered treatment
var bolusAmountToBeDelivered = 0.0 // amount to be delivered var bolusAmountToBeDelivered = 0.0 // amount to be delivered
var bolusProgressLastTimeStamp: Long = 0 // timestamp of last bolus progress message var bolusProgressLastTimeStamp: Long = 0 // timestamp of last bolus progress message
var bolusStopped = false // bolus finished var bolusStopped = false // bolus finished

View file

@ -21,21 +21,23 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpSync;
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.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers; import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -50,6 +52,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
private final ResourceHelper resourceHelper; private final ResourceHelper resourceHelper;
private final ConstraintChecker constraintChecker; private final ConstraintChecker constraintChecker;
private final FabricPrivacy fabricPrivacy; private final FabricPrivacy fabricPrivacy;
private final PumpSync pumpSync;
@Inject @Inject
public DanaRKoreanPlugin( public DanaRKoreanPlugin(
@ -65,6 +68,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
SP sp, SP sp,
CommandQueueProvider commandQueue, CommandQueueProvider commandQueue,
DateUtil dateUtil, DateUtil dateUtil,
PumpSync pumpSync,
FabricPrivacy fabricPrivacy FabricPrivacy fabricPrivacy
) { ) {
super(injector, danaPump, resourceHelper, constraintChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil); super(injector, danaPump, resourceHelper, constraintChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil);
@ -72,6 +76,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
this.context = context; this.context = context;
this.resourceHelper = resourceHelper; this.resourceHelper = resourceHelper;
this.constraintChecker = constraintChecker; this.constraintChecker = constraintChecker;
this.pumpSync = pumpSync;
this.fabricPrivacy = fabricPrivacy; this.fabricPrivacy = fabricPrivacy;
getPluginDescription().description(R.string.description_pump_dana_r_korean); getPluginDescription().description(R.string.description_pump_dana_r_korean);
@ -163,23 +168,40 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment(); EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
boolean connectionOK = false; boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, treatment);
PumpEnactResult result = new PumpEnactResult(getInjector()); PumpEnactResult result = new PumpEnactResult(getInjector());
result.success(connectionOK && Math.abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.getBolusStep()) result.success(connectionOK && Math.abs(detailedBolusInfo.insulin - treatment.insulin) < pumpDescription.getBolusStep())
.bolusDelivered(t.insulin) .bolusDelivered(treatment.insulin)
.carbsDelivered(detailedBolusInfo.carbs); .carbsDelivered(detailedBolusInfo.carbs);
if (!result.getSuccess()) if (!result.getSuccess())
result.comment(resourceHelper.gs(R.string.boluserrorcode, detailedBolusInfo.insulin, t.insulin, danaPump.getBolusStartErrorCode())); result.comment(resourceHelper.gs(R.string.boluserrorcode, detailedBolusInfo.insulin, treatment.insulin, danaPump.getBolusStartErrorCode()));
else else
result.comment(R.string.ok); result.comment(R.string.ok);
aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.getBolusDelivered()); aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.getBolusDelivered());
detailedBolusInfo.insulin = t.insulin; detailedBolusInfo.insulin = treatment.insulin;
detailedBolusInfo.timestamp = System.currentTimeMillis(); detailedBolusInfo.timestamp = System.currentTimeMillis();
activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false);
if (detailedBolusInfo.insulin > 0)
pumpSync.syncBolusWithPumpId(
detailedBolusInfo.timestamp,
detailedBolusInfo.insulin,
detailedBolusInfo.getBolusType(),
dateUtil._now(),
PumpType.DANA_R_KOREAN,
serialNumber()
);
if (detailedBolusInfo.carbs > 0)
pumpSync.syncCarbsWithTimestamp(
detailedBolusInfo.timestamp + T.mins(detailedBolusInfo.carbTime).msecs(),
detailedBolusInfo.carbs,
null,
PumpType.DANA_R_KOREAN,
serialNumber()
);
return result; return result;
} else { } else {
PumpEnactResult result = new PumpEnactResult(getInjector()); PumpEnactResult result = new PumpEnactResult(getInjector());

View file

@ -38,7 +38,6 @@ import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal;
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog; import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate; import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
@ -52,6 +51,7 @@ import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.androidaps.queue.commands.Command;
@ -254,7 +254,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
return null; return null;
} }
public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) { public boolean bolus(double amount, int carbs, long carbtime, final EventOverviewBolusProgress.Treatment t) {
if (!isConnected()) return false; if (!isConnected()) return false;
if (BolusProgressDialog.stopPressed) return false; if (BolusProgressDialog.stopPressed) return false;

View file

@ -20,7 +20,6 @@ import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider;
@ -29,6 +28,7 @@ import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
@ -182,8 +182,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
detailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history detailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history
Treatment t = new Treatment(); EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
boolean connectionOK = false; boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || carbs > 0) if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + T.mins(carbTime).msecs(), t); connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + T.mins(carbTime).msecs(), t);

View file

@ -52,7 +52,6 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBasic;
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog; import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate; import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
@ -338,7 +337,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
return true; return true;
} }
public boolean bolus(final double amount, int carbs, long carbtime, final Treatment t) { public boolean bolus(final double amount, int carbs, long carbtime, final EventOverviewBolusProgress.Treatment t) {
if (!isConnected()) return false; if (!isConnected()) return false;
if (BolusProgressDialog.stopPressed) return false; if (BolusProgressDialog.stopPressed) return false;

View file

@ -19,7 +19,6 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
@ -30,6 +29,7 @@ import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
@ -161,8 +161,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment(); EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
boolean connectionOK = false; boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);

View file

@ -35,7 +35,6 @@ import info.nightscout.androidaps.danar.comm.MsgPCCommStart;
import info.nightscout.androidaps.danar.comm.MsgPCCommStop; import info.nightscout.androidaps.danar.comm.MsgPCCommStop;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventBTChange; import info.nightscout.androidaps.events.EventBTChange;
import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventPumpStatusChanged;
@ -43,6 +42,7 @@ 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.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
@ -95,7 +95,7 @@ public abstract class AbstractDanaRExecutionService extends DaggerService {
public abstract PumpEnactResult loadEvents(); public abstract PumpEnactResult loadEvents();
public abstract boolean bolus(double amount, int carbs, long carbtime, final Treatment t); public abstract boolean bolus(double amount, int carbs, long carbtime, final EventOverviewBolusProgress.Treatment t);
public abstract boolean highTempBasal(int percent, int durationInMinutes); // Rv2 only public abstract boolean highTempBasal(int percent, int durationInMinutes); // Rv2 only

View file

@ -45,7 +45,6 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended;
import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal; import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog; import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate; import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
@ -263,7 +262,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService {
return null; return null;
} }
public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) { public boolean bolus(double amount, int carbs, long carbtime, final EventOverviewBolusProgress.Treatment t) {
if (!isConnected()) return false; if (!isConnected()) return false;
if (BolusProgressDialog.stopPressed) return false; if (BolusProgressDialog.stopPressed) return false;

View file

@ -1,10 +1,8 @@
package info.nightscout.androidaps.plugins.pump.danaR.comm package info.nightscout.androidaps.plugins.pump.danaR.comm
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.danar.R import info.nightscout.androidaps.danar.R
import info.nightscout.androidaps.danar.comm.MsgBolusProgress import info.nightscout.androidaps.danar.comm.MsgBolusProgress
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -17,7 +15,7 @@ class MsgBolusProgressTest : DanaRTestBase() {
@Test fun runTest() { @Test fun runTest() {
`when`(resourceHelper.gs(ArgumentMatchers.eq(R.string.bolusdelivering), ArgumentMatchers.anyDouble())).thenReturn("Delivering %1\$.2fU") `when`(resourceHelper.gs(ArgumentMatchers.eq(R.string.bolusdelivering), ArgumentMatchers.anyDouble())).thenReturn("Delivering %1\$.2fU")
danaPump.bolusingTreatment = Treatment(HasAndroidInjector { AndroidInjector { } }) danaPump.bolusingTreatment = EventOverviewBolusProgress.Treatment(0.0, 0, true)
danaPump.bolusAmountToBeDelivered = 3.0 danaPump.bolusAmountToBeDelivered = 3.0
val packet = MsgBolusProgress(injector) val packet = MsgBolusProgress(injector)

View file

@ -1,10 +1,8 @@
package info.nightscout.androidaps.plugins.pump.danaR.comm package info.nightscout.androidaps.plugins.pump.danaR.comm
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.danar.R import info.nightscout.androidaps.danar.R
import info.nightscout.androidaps.danar.comm.MsgBolusStop import info.nightscout.androidaps.danar.comm.MsgBolusStop
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -16,7 +14,7 @@ class MsgBolusStopTest : DanaRTestBase() {
@Test fun runTest() { @Test fun runTest() {
`when`(resourceHelper.gs(R.string.overview_bolusprogress_delivered)).thenReturn("Delivered") `when`(resourceHelper.gs(R.string.overview_bolusprogress_delivered)).thenReturn("Delivered")
danaPump.bolusingTreatment = Treatment(HasAndroidInjector { AndroidInjector { } }) danaPump.bolusingTreatment = EventOverviewBolusProgress.Treatment(0.0, 0, true)
val packet = MsgBolusStop(injector) val packet = MsgBolusStop(injector)
// test message decoding // test message decoding

View file

@ -11,6 +11,7 @@ import info.nightscout.androidaps.danar.R
import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
@ -30,6 +31,7 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
@Mock lateinit var commandQueue: CommandQueueProvider @Mock lateinit var commandQueue: CommandQueueProvider
@Mock lateinit var pumpSync: PumpSync
lateinit var danaPump: DanaPump lateinit var danaPump: DanaPump
@ -46,7 +48,7 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
`when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s") `when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s") `when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
danaPump = DanaPump(aapsLogger, sp, injector) danaPump = DanaPump(aapsLogger, sp, injector)
danaRPlugin = DanaRKoreanPlugin(injector, aapsLogger, aapsSchedulers, rxBus, danaPump, context, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, dateUtil, fabricPrivacy) danaRPlugin = DanaRKoreanPlugin(injector, aapsLogger, aapsSchedulers, rxBus, danaPump, context, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, dateUtil, pumpSync, fabricPrivacy)
} }
@Test @Throws(Exception::class) @Test @Throws(Exception::class)

View file

@ -15,7 +15,6 @@ import info.nightscout.androidaps.danars.services.DanaRSService
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventConfigBuilderChange import info.nightscout.androidaps.events.EventConfigBuilderChange
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
@ -26,6 +25,7 @@ import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
@ -278,8 +278,7 @@ class DanaRSPlugin @Inject constructor(
if (carbTime == 0) carbTime-- // better set 1 min back to prevents clash with insulin if (carbTime == 0) carbTime-- // better set 1 min back to prevents clash with insulin
detailedBolusInfo.carbTime = 0 detailedBolusInfo.carbTime = 0
detailedBolusInfoStorage.add(detailedBolusInfo) // will be picked up on reading history detailedBolusInfoStorage.add(detailedBolusInfo) // will be picked up on reading history
val t = Treatment() val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB);
t.isSMB = detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB
var connectionOK = false var connectionOK = false
if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t) if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t)
?: false ?: false

View file

@ -124,26 +124,26 @@ open class DanaRS_Packet_APS_History_Events(
DanaPump.BOLUS -> { DanaPump.BOLUS -> {
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0)
?: DetailedBolusInfo() val newRecord = pumpSync.syncBolusWithPumpId(
detailedBolusInfo.bolusTimestamp = datetime timestamp = datetime,
detailedBolusInfo.pumpType = PumpType.DANA_RS amount = param1 / 100.0,
detailedBolusInfo.pumpSerial = danaPump.serialNumber type = detailedBolusInfo?.bolusType,
detailedBolusInfo.bolusPumpId = pumpId pumpId = pumpId,
detailedBolusInfo.insulin = param1 / 100.0 pumpType = PumpType.DANA_RS,
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) pumpSerial = danaPump.serialNumber)
aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT BOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min")
status = "BOLUS " + dateUtil.timeString(datetime) status = "BOLUS " + dateUtil.timeString(datetime)
} }
DanaPump.DUALBOLUS -> { DanaPump.DUALBOLUS -> {
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0)
?: DetailedBolusInfo() val newRecord = pumpSync.syncBolusWithPumpId(
detailedBolusInfo.bolusTimestamp = datetime timestamp = datetime,
detailedBolusInfo.pumpType = PumpType.DANA_RS amount = param1 / 100.0,
detailedBolusInfo.pumpSerial = danaPump.serialNumber type = detailedBolusInfo?.bolusType,
detailedBolusInfo.bolusPumpId = pumpId pumpId = pumpId,
detailedBolusInfo.insulin = param1 / 100.0 pumpType = PumpType.DANA_RS,
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) pumpSerial = danaPump.serialNumber)
aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min") aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT DUALBOLUS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Bolus: " + param1 / 100.0 + "U Duration: " + param2 + "min")
status = "DUALBOLUS " + dateUtil.timeString(datetime) status = "DUALBOLUS " + dateUtil.timeString(datetime)
} }
@ -196,13 +196,12 @@ open class DanaRS_Packet_APS_History_Events(
} }
DanaPump.CARBS -> { DanaPump.CARBS -> {
val emptyCarbsInfo = DetailedBolusInfo() val newRecord = pumpSync.syncCarbsWithTimestamp(
emptyCarbsInfo.carbs = param1.toDouble() timestamp = datetime,
emptyCarbsInfo.carbsTimestamp = datetime amount = param1.toDouble(),
emptyCarbsInfo.pumpType = PumpType.DANA_RS pumpId = pumpId,
emptyCarbsInfo.pumpSerial = danaPump.serialNumber pumpType = PumpType.DANA_RS,
emptyCarbsInfo.carbsPumpId = pumpId pumpSerial = danaPump.serialNumber)
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false)
aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g") aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g")
status = "CARBS " + dateUtil.timeString(datetime) status = "CARBS " + dateUtil.timeString(datetime)
} }

View file

@ -18,7 +18,6 @@ import info.nightscout.androidaps.danars.R
import info.nightscout.androidaps.danars.comm.* import info.nightscout.androidaps.danars.comm.*
import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.dialogs.BolusProgressDialog
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.events.EventInitializationChanged
@ -247,7 +246,7 @@ class DanaRSService : DaggerService() {
return PumpEnactResult(injector).success(message.success()) return PumpEnactResult(injector).success(message.success())
} }
fun bolus(insulin: Double, carbs: Int, carbTime: Long, t: Treatment): Boolean { fun bolus(insulin: Double, carbs: Int, carbTime: Long, t: EventOverviewBolusProgress.Treatment): Boolean {
if (!isConnected) return false if (!isConnected) return false
if (BolusProgressDialog.stopPressed) return false if (BolusProgressDialog.stopPressed) return false
rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.startingbolus))) rxBus.send(EventPumpStatusChanged(resourceHelper.gs(R.string.startingbolus)))

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.danars.DanaRSTestBase
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -43,7 +44,7 @@ class DanaRSPacketNotifyDeliveryCompleteTest : DanaRSTestBase() {
@Test fun runTest() { @Test fun runTest() {
`when`(resourceHelper.gs(anyInt(), anyDouble())).thenReturn("SomeString") `when`(resourceHelper.gs(anyInt(), anyDouble())).thenReturn("SomeString")
danaPump.bolusingTreatment = Treatment(packetInjector) danaPump.bolusingTreatment = EventOverviewBolusProgress.Treatment(0.0, 0, true)
val packet = DanaRS_Packet_Notify_Delivery_Complete(packetInjector) val packet = DanaRS_Packet_Notify_Delivery_Complete(packetInjector)
// test params // test params
Assert.assertEquals(null, packet.requestParams) Assert.assertEquals(null, packet.requestParams)

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.danars.DanaRSTestBase
import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -42,7 +43,7 @@ class DanaRsPacketBolusSetStepBolusStopTest : DanaRSTestBase() {
@Test fun runTest() { @Test fun runTest() {
`when`(resourceHelper.gs(Mockito.anyInt())).thenReturn("SomeString") `when`(resourceHelper.gs(Mockito.anyInt())).thenReturn("SomeString")
danaPump.bolusingTreatment = Treatment(packetInjector) danaPump.bolusingTreatment = EventOverviewBolusProgress.Treatment(0.0, 0, true)
val testPacket = DanaRS_Packet_Bolus_Set_Step_Bolus_Stop(packetInjector) val testPacket = DanaRS_Packet_Bolus_Set_Step_Bolus_Stop(packetInjector)
// test message decoding // test message decoding
testPacket.handleMessage(byteArrayOf(0.toByte(), 0.toByte(), 0.toByte())) testPacket.handleMessage(byteArrayOf(0.toByte(), 0.toByte(), 0.toByte()))

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
@ -69,6 +70,6 @@ class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() {
@Before @Before
fun mock() { fun mock() {
danaRSPlugin = DanaRSPlugin(packetInjector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, profileFunction, activePluginProvider, sp, commandQueue, danaPump, detailedBolusInfoStorage, fabricPrivacy, dateUtil) danaRSPlugin = DanaRSPlugin(packetInjector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, profileFunction, activePluginProvider, sp, commandQueue, danaPump, detailedBolusInfoStorage, fabricPrivacy, dateUtil)
danaPump.bolusingTreatment = Treatment(packetInjector) danaPump.bolusingTreatment = EventOverviewBolusProgress.Treatment(0.0, 0, true)
} }
} }

View file

@ -2,11 +2,11 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 8, "version": 8,
"identityHash": "2e4a472793f7dd21528ddcb540500f1b", "identityHash": "dab6024e846ee68708e8cfc047c39662",
"entities": [ "entities": [
{ {
"tableName": "apsResults", "tableName": "apsResults",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `algorithm` TEXT NOT NULL, `glucoseStatusJson` TEXT NOT NULL, `currentTempJson` TEXT NOT NULL, `iobDataJson` TEXT NOT NULL, `profileJson` TEXT NOT NULL, `autosensDataJson` TEXT, `mealDataJson` TEXT NOT NULL, `isMicroBolusAllowed` INTEGER, `resultJson` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `algorithm` TEXT NOT NULL, `glucoseStatusJson` TEXT NOT NULL, `currentTempJson` TEXT NOT NULL, `iobDataJson` TEXT NOT NULL, `profileJson` TEXT NOT NULL, `autosensDataJson` TEXT, `mealDataJson` TEXT NOT NULL, `isMicroBolusAllowed` INTEGER, `resultJson` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -128,6 +128,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -187,7 +193,7 @@
}, },
{ {
"tableName": "boluses", "tableName": "boluses",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `amount` REAL NOT NULL, `type` TEXT NOT NULL, `isBasalInsulin` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT, `insulinEndTime` INTEGER, `peak` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `amount` REAL NOT NULL, `type` TEXT NOT NULL, `isBasalInsulin` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT, `insulinEndTime` INTEGER, `peak` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -273,6 +279,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -350,7 +362,7 @@
}, },
{ {
"tableName": "bolusCalculatorResults", "tableName": "bolusCalculatorResults",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `note` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `note` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -592,6 +604,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -651,7 +669,7 @@
}, },
{ {
"tableName": "carbs", "tableName": "carbs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -731,6 +749,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -790,7 +814,7 @@
}, },
{ {
"tableName": "effectiveProfileSwitches", "tableName": "effectiveProfileSwitches",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `basalBlocks` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `effectiveProfileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `basalBlocks` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `effectiveProfileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -870,6 +894,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -929,7 +959,7 @@
}, },
{ {
"tableName": "extendedBoluses", "tableName": "extendedBoluses",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `isEmulatingTempBasal` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `amount` REAL NOT NULL, `isEmulatingTempBasal` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1015,6 +1045,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1074,7 +1110,7 @@
}, },
{ {
"tableName": "glucoseValues", "tableName": "glucoseValues",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `raw` REAL, `value` REAL NOT NULL, `trendArrow` TEXT NOT NULL, `noise` REAL, `sourceSensor` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `glucoseValues`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `raw` REAL, `value` REAL NOT NULL, `trendArrow` TEXT NOT NULL, `noise` REAL, `sourceSensor` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `glucoseValues`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1172,6 +1208,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1231,7 +1273,7 @@
}, },
{ {
"tableName": "profileSwitches", "tableName": "profileSwitches",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `glucoseUnit` TEXT NOT NULL, `basalBlocks` TEXT NOT NULL, `isfBlocks` TEXT NOT NULL, `icBlocks` TEXT NOT NULL, `targetBlocks` TEXT NOT NULL, `timeshift` INTEGER NOT NULL, `percentage` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT NOT NULL, `insulinEndTime` INTEGER NOT NULL, `peak` INTEGER NOT NULL, FOREIGN KEY(`referenceId`) REFERENCES `profileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `glucoseUnit` TEXT NOT NULL, `basalBlocks` TEXT NOT NULL, `isfBlocks` TEXT NOT NULL, `icBlocks` TEXT NOT NULL, `targetBlocks` TEXT NOT NULL, `timeshift` INTEGER NOT NULL, `percentage` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, `insulinLabel` TEXT NOT NULL, `insulinEndTime` INTEGER NOT NULL, `peak` INTEGER NOT NULL, FOREIGN KEY(`referenceId`) REFERENCES `profileSwitches`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1353,6 +1395,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1430,7 +1478,7 @@
}, },
{ {
"tableName": "temporaryBasals", "tableName": "temporaryBasals",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `type` TEXT NOT NULL, `isAbsolute` INTEGER NOT NULL, `rate` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `type` TEXT NOT NULL, `isAbsolute` INTEGER NOT NULL, `rate` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1522,6 +1570,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1581,7 +1635,7 @@
}, },
{ {
"tableName": "temporaryTargets", "tableName": "temporaryTargets",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `reason` TEXT NOT NULL, `highTarget` REAL NOT NULL, `lowTarget` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryTargets`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `reason` TEXT NOT NULL, `highTarget` REAL NOT NULL, `lowTarget` REAL NOT NULL, `duration` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `temporaryTargets`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1673,6 +1727,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1732,7 +1792,7 @@
}, },
{ {
"tableName": "therapyEvents", "tableName": "therapyEvents",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `type` TEXT NOT NULL, `note` TEXT, `enteredBy` TEXT, `glucose` REAL, `glucoseType` TEXT, `glucoseUnit` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `type` TEXT NOT NULL, `note` TEXT, `enteredBy` TEXT, `glucose` REAL, `glucoseType` TEXT, `glucoseUnit` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1842,6 +1902,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -1901,7 +1967,7 @@
}, },
{ {
"tableName": "totalDailyDoses", "tableName": "totalDailyDoses",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `basalAmount` REAL, `bolusAmount` REAL, `totalAmount` REAL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `totalDailyDoses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `basalAmount` REAL, `bolusAmount` REAL, `totalAmount` REAL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `totalDailyDoses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -1987,6 +2053,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -2046,7 +2118,7 @@
}, },
{ {
"tableName": "apsResultLinks", "tableName": "apsResultLinks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `apsResultId` INTEGER NOT NULL, `smbId` INTEGER, `tbrId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`apsResultId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`smbId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`tbrId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `apsResultLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `apsResultId` INTEGER NOT NULL, `smbId` INTEGER, `tbrId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`apsResultId`) REFERENCES `apsResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`smbId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`tbrId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `apsResultLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -2120,6 +2192,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -2228,7 +2306,7 @@
}, },
{ {
"tableName": "multiwaveBolusLinks", "tableName": "multiwaveBolusLinks",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `bolusId` INTEGER NOT NULL, `extendedBolusId` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`extendedBolusId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `multiwaveBolusLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `bolusId` INTEGER NOT NULL, `extendedBolusId` INTEGER NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`extendedBolusId`) REFERENCES `extendedBoluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `multiwaveBolusLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -2296,6 +2374,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -2535,7 +2619,7 @@
}, },
{ {
"tableName": "foods", "tableName": "foods",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `name` TEXT NOT NULL, `category` TEXT, `subCategory` TEXT, `portion` REAL NOT NULL, `carbs` INTEGER NOT NULL, `fat` INTEGER, `protein` INTEGER, `energy` INTEGER, `unit` TEXT NOT NULL, `gi` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `foods`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `name` TEXT NOT NULL, `category` TEXT, `subCategory` TEXT, `portion` REAL NOT NULL, `carbs` INTEGER NOT NULL, `fat` INTEGER, `protein` INTEGER, `energy` INTEGER, `unit` TEXT NOT NULL, `gi` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `temporaryId` INTEGER, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `foods`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -2651,6 +2735,12 @@
"affinity": "TEXT", "affinity": "TEXT",
"notNull": false "notNull": false
}, },
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{ {
"fieldPath": "interfaceIDs_backing.pumpId", "fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId", "columnName": "pumpId",
@ -2704,7 +2794,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2e4a472793f7dd21528ddcb540500f1b')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'dab6024e846ee68708e8cfc047c39662')"
] ]
} }
} }

View file

@ -6,7 +6,7 @@ import androidx.room.TypeConverters
import info.nightscout.androidaps.database.daos.* import info.nightscout.androidaps.database.daos.*
import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.entities.*
const val DATABASE_VERSION = 8 const val DATABASE_VERSION = 9
@Database(version = DATABASE_VERSION, @Database(version = DATABASE_VERSION,
entities = [APSResult::class, Bolus::class, BolusCalculatorResult::class, Carbs::class, entities = [APSResult::class, Bolus::class, BolusCalculatorResult::class, Carbs::class,

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.database package info.nightscout.androidaps.database
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.entities.*
import info.nightscout.androidaps.database.interfaces.DBEntry import info.nightscout.androidaps.database.interfaces.DBEntry
import info.nightscout.androidaps.database.transactions.Transaction import info.nightscout.androidaps.database.transactions.Transaction
@ -263,7 +262,7 @@ open class AppRepository @Inject internal constructor(
* It is a Maybe as there might be no next element. * It is a Maybe as there might be no next element.
* */ * */
fun getNextSyncElementBolus(id: Long): Maybe<Pair<Bolus, Long>> = fun getNextSyncElementBolus(id: Long): Maybe<Pair<Bolus, Long>> =
database.bolusDao.getNextModifiedOrNewAfter(id) database.bolusDao.getNextModifiedOrNewAfterExclude(id, Bolus.Type.PRIMING)
.flatMap { nextIdElement -> .flatMap { nextIdElement ->
val nextIdElemReferenceId = nextIdElement.referenceId val nextIdElemReferenceId = nextIdElement.referenceId
if (nextIdElemReferenceId == null) { if (nextIdElemReferenceId == null) {
@ -278,8 +277,11 @@ open class AppRepository @Inject internal constructor(
database.bolusDao.getModifiedFrom(lastId) database.bolusDao.getModifiedFrom(lastId)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
fun findBolusByPumpIds(pumpId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): Bolus? = fun getLastBolusRecord(): Bolus? =
database.bolusDao.findByPumpIds(pumpId, pumpType, pumpSerial) database.bolusDao.getLastBolusRecord()
fun getLastBolusRecordOfType(type: Bolus.Type): Bolus? =
database.bolusDao.getLastBolusRecordOfType(type)
fun getOldestBolusRecord(): Bolus? = fun getOldestBolusRecord(): Bolus? =
database.bolusDao.getOldestBolusRecord() database.bolusDao.getOldestBolusRecord()
@ -334,6 +336,9 @@ open class AppRepository @Inject internal constructor(
fun getCarbsByTimestamp(timestamp: Long): Carbs? = fun getCarbsByTimestamp(timestamp: Long): Carbs? =
database.carbsDao.findByTimestamp(timestamp) database.carbsDao.findByTimestamp(timestamp)
fun getLastCarbsRecord(): Carbs? =
database.carbsDao.getLastCarbsRecord()
fun getOldestCarbsRecord(): Carbs? = fun getOldestCarbsRecord(): Carbs? =
database.carbsDao.getOldestCarbsRecord() database.carbsDao.getOldestCarbsRecord()

View file

@ -18,11 +18,26 @@ internal interface BolusDao : TraceableDao<Bolus> {
@Query("DELETE FROM $TABLE_BOLUSES") @Query("DELETE FROM $TABLE_BOLUSES")
override fun deleteAllEntries() override fun deleteAllEntries()
@Query("SELECT * FROM $TABLE_BOLUSES WHERE timestamp = :timestamp AND referenceId IS NULL")
fun findByTimestamp(timestamp: Long): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE nightscoutId = :nsId AND referenceId IS NULL")
fun findByNSId(nsId: String): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE pumpId = :pumpId AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL") @Query("SELECT * FROM $TABLE_BOLUSES WHERE pumpId = :pumpId AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL")
fun findByPumpIds(pumpId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): Bolus? fun findByPumpIds(pumpId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1") @Query("SELECT * FROM $TABLE_BOLUSES WHERE temporaryId = :temporaryId AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL")
fun getOldestBolusRecord(): Bolus? fun findByPumpTempIds(temporaryId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND type <> :exclude AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
fun getLastBolusRecord(exclude: Bolus.Type = Bolus.Type.PRIMING): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND type == :only AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
fun getLastBolusRecordOfType(only: Bolus.Type): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND type <> :exclude AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
fun getOldestBolusRecord(exclude: Bolus.Type = Bolus.Type.PRIMING): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC") @Query("SELECT * FROM $TABLE_BOLUSES WHERE isValid = 1 AND timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC")
fun getBolusesFromTime(timestamp: Long): Single<List<Bolus>> fun getBolusesFromTime(timestamp: Long): Single<List<Bolus>>
@ -37,12 +52,12 @@ internal interface BolusDao : TraceableDao<Bolus> {
fun getBolusesIncludingInvalidFromTimeToTime(from: Long, to: Long): Single<List<Bolus>> fun getBolusesIncludingInvalidFromTimeToTime(from: Long, to: Long): Single<List<Bolus>>
// This query will be used with v3 to get all changed records // This query will be used with v3 to get all changed records
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id AND referenceId IS NULL OR id IN (SELECT DISTINCT referenceId FROM $TABLE_BOLUSES WHERE id > :id) ORDER BY id ASC") @Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id AND type <> :exclude AND referenceId IS NULL OR id IN (SELECT DISTINCT referenceId FROM $TABLE_BOLUSES WHERE id > :id) ORDER BY id ASC")
fun getModifiedFrom(id: Long): Single<List<Bolus>> fun getModifiedFrom(id: Long, exclude: Bolus.Type = Bolus.Type.PRIMING): Single<List<Bolus>>
// for WS we need 1 record only // for WS we need 1 record only
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id ORDER BY id ASC limit 1") @Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id AND type <> :exclude ORDER BY id ASC limit 1")
fun getNextModifiedOrNewAfter(id: Long): Maybe<Bolus> fun getNextModifiedOrNewAfterExclude(id: Long, exclude: Bolus.Type = Bolus.Type.PRIMING): Maybe<Bolus>
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id = :referenceId") @Query("SELECT * FROM $TABLE_BOLUSES WHERE id = :referenceId")
fun getCurrentFromHistoric(referenceId: Long): Maybe<Bolus> fun getCurrentFromHistoric(referenceId: Long): Maybe<Bolus>

View file

@ -3,10 +3,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_CARBS
import info.nightscout.androidaps.database.TABLE_THERAPY_EVENTS
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Carbs import info.nightscout.androidaps.database.entities.Carbs
import info.nightscout.androidaps.database.entities.TherapyEvent
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.Single import io.reactivex.Single
@ -20,9 +17,15 @@ internal interface CarbsDao : TraceableDao<Carbs> {
@Query("DELETE FROM $TABLE_CARBS") @Query("DELETE FROM $TABLE_CARBS")
override fun deleteAllEntries() override fun deleteAllEntries()
@Query("SELECT * FROM $TABLE_CARBS WHERE nightscoutId = :nsId AND referenceId IS NULL")
fun findByNSId(nsId: String): Carbs?
@Query("SELECT * FROM $TABLE_CARBS WHERE timestamp = :timestamp AND referenceId IS NULL") @Query("SELECT * FROM $TABLE_CARBS WHERE timestamp = :timestamp AND referenceId IS NULL")
fun findByTimestamp(timestamp: Long): Carbs? fun findByTimestamp(timestamp: Long): Carbs?
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id DESC LIMIT 1")
fun getLastCarbsRecord(): Carbs?
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1") @Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
fun getOldestCarbsRecord(): Carbs? fun getOldestCarbsRecord(): Carbs?

View file

@ -1,10 +1,13 @@
package info.nightscout.androidaps.database.embedments package info.nightscout.androidaps.database.embedments
import info.nightscout.androidaps.database.entities.TherapyEvent
data class InterfaceIDs( data class InterfaceIDs(
var nightscoutSystemId: String? = null, var nightscoutSystemId: String? = null,
var nightscoutId: String? = null, var nightscoutId: String? = null,
var pumpType: PumpType? = null, // if == USER pumpSerial & pumpId can be null var pumpType: PumpType? = null, // if == USER pumpSerial & pumpId can be null
var pumpSerial: String? = null, var pumpSerial: String? = null,
var temporaryId: Long? = null, // temporary id for pump synchronization, when pump id is not available
var pumpId: Long? = null, var pumpId: Long? = null,
var startId: Long? = null, var startId: Long? = null,
var endId: Long? = null var endId: Long? = null
@ -40,6 +43,11 @@ data class InterfaceIDs(
TANDEM_T_SLIM_X2, TANDEM_T_SLIM_X2,
YPSOPUMP, YPSOPUMP,
MDI, MDI,
USER USER;
companion object {
fun fromString(name: String?) = values().firstOrNull { it.name == name }
}
} }
} }

View file

@ -40,6 +40,11 @@ data class Bolus(
enum class Type { enum class Type {
NORMAL, NORMAL,
SMB, SMB,
PRIMING PRIMING;
companion object {
fun fromString(name: String?) = values().firstOrNull { it.name == name } ?: NORMAL
}
} }
} }

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.database.transactions
import info.nightscout.androidaps.database.entities.Bolus
/**
* Creates or updates the Bolus from pump synchronization
*/
class InsertPumpBolusWithTempIdTransaction(
private val bolus: Bolus
) : Transaction<InsertPumpBolusWithTempIdTransaction.TransactionResult>() {
override fun run(): TransactionResult {
bolus.interfaceIDs.temporaryId ?: bolus.interfaceIDs.pumpType ?: bolus.interfaceIDs.pumpSerial ?:
throw IllegalStateException("Some pump ID is null")
val result = TransactionResult()
val current = database.bolusDao.findByPumpTempIds(bolus.interfaceIDs.temporaryId!!, bolus.interfaceIDs.pumpType!!, bolus.interfaceIDs.pumpSerial!!)
if (current == null) {
database.bolusDao.insert(bolus)
result.inserted.add(bolus)
}
return result
}
class TransactionResult {
val inserted = mutableListOf<Bolus>()
}
}

View file

@ -8,7 +8,7 @@ class InvalidateAAPSStartedTherapyEventTransaction(private val note: String) : T
val result = TransactionResult() val result = TransactionResult()
val therapyEvents = database.therapyEventDao.getValidByType(TherapyEvent.Type.NOTE) val therapyEvents = database.therapyEventDao.getValidByType(TherapyEvent.Type.NOTE)
for (event in therapyEvents) { for (event in therapyEvents) {
if (event.note == note) { if (event.note?.contains(note) == true) {
event.isValid = false event.isValid = false
database.therapyEventDao.updateExistingEntry(event) database.therapyEventDao.updateExistingEntry(event)
result.invalidated.add(event) result.invalidated.add(event)

View file

@ -0,0 +1,50 @@
package info.nightscout.androidaps.database.transactions
import info.nightscout.androidaps.database.entities.Bolus
/**
* Sync the Bolus from NS
*/
class SyncNsBolusTransaction(private val bolus: Bolus) : Transaction<SyncNsBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult {
val result = TransactionResult()
val current: Bolus? =
bolus.interfaceIDs.nightscoutId?.let {
database.bolusDao.findByNSId(it)
}
if (current != null) {
// nsId exists, allow only invalidation
if (current.isValid && !bolus.isValid) {
current.isValid = false
database.bolusDao.updateExistingEntry(current)
result.invalidated.add(current)
}
return result
}
// not known nsId
val existing = database.bolusDao.findByTimestamp(bolus.timestamp)
if (existing != null && existing.interfaceIDs.nightscoutId == null) {
// the same record, update nsId only
existing.interfaceIDs.nightscoutId = bolus.interfaceIDs.nightscoutId
existing.isValid = bolus.isValid
database.bolusDao.updateExistingEntry(existing)
result.updatedNsId.add(existing)
} else {
database.bolusDao.insertNewEntry(bolus)
result.inserted.add(bolus)
}
return result
}
class TransactionResult {
val updatedNsId = mutableListOf<Bolus>()
val inserted = mutableListOf<Bolus>()
val invalidated = mutableListOf<Bolus>()
}
}

View file

@ -0,0 +1,50 @@
package info.nightscout.androidaps.database.transactions
import info.nightscout.androidaps.database.entities.Carbs
/**
* Sync the carbs from NS
*/
class SyncNsCarbsTransaction(private val carbs: Carbs) : Transaction<SyncNsCarbsTransaction.TransactionResult>() {
override fun run(): TransactionResult {
val result = TransactionResult()
val current: Carbs? =
carbs.interfaceIDs.nightscoutId?.let {
database.carbsDao.findByNSId(it)
}
if (current != null) {
// nsId exists, allow only invalidation
if (current.isValid && !carbs.isValid) {
current.isValid = false
database.carbsDao.updateExistingEntry(current)
result.invalidated.add(current)
}
return result
}
// not known nsId
val existing = database.carbsDao.findByTimestamp(carbs.timestamp)
if (existing != null && existing.interfaceIDs.nightscoutId == null) {
// the same record, update nsId only
existing.interfaceIDs.nightscoutId = carbs.interfaceIDs.nightscoutId
existing.isValid = carbs.isValid
database.carbsDao.updateExistingEntry(existing)
result.updatedNsId.add(existing)
} else {
database.carbsDao.insertNewEntry(carbs)
result.inserted.add(carbs)
}
return result
}
class TransactionResult {
val updatedNsId = mutableListOf<Carbs>()
val inserted = mutableListOf<Carbs>()
val invalidated = mutableListOf<Carbs>()
}
}

View file

@ -1,15 +1,13 @@
package info.nightscout.androidaps.database.transactions package info.nightscout.androidaps.database.transactions
import info.nightscout.androidaps.database.embedments.InsulinConfiguration
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import java.lang.IllegalStateException
/** /**
* Creates or updates the Bolus from pump synchronization * Creates or updates the Bolus from pump synchronization
*/ */
class SyncPumpBolusTransaction( class SyncPumpBolusTransaction(
private val bolus: Bolus, private val bolus: Bolus,
private val bolusType: Bolus.Type? // extra parameter because field is not nullable in Bolus.class
) : Transaction<SyncPumpBolusTransaction.TransactionResult>() { ) : Transaction<SyncPumpBolusTransaction.TransactionResult>() {
override fun run(): TransactionResult { override fun run(): TransactionResult {
@ -21,9 +19,11 @@ class SyncPumpBolusTransaction(
database.bolusDao.insertNewEntry(bolus) database.bolusDao.insertNewEntry(bolus)
result.inserted.add(bolus) result.inserted.add(bolus)
} else { } else {
bolus.isValid = current.isValid current.timestamp = bolus.timestamp
database.bolusDao.updateExistingEntry(bolus) current.amount = bolus.amount
result.updated.add(bolus) current.type = bolusType ?: current.type
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)
} }
return result return result
} }

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.database.transactions
import info.nightscout.androidaps.database.entities.Bolus
/**
* Creates or updates the Bolus from pump synchronization
*/
class SyncPumpBolusWithTempIdTransaction(
private val bolus: Bolus,
private val newType: Bolus.Type?
) : Transaction<SyncPumpBolusWithTempIdTransaction.TransactionResult>() {
override fun run(): TransactionResult {
bolus.interfaceIDs.temporaryId ?: bolus.interfaceIDs.pumpType ?: bolus.interfaceIDs.pumpSerial ?:
throw IllegalStateException("Some pump ID is null")
val result = TransactionResult()
val current = database.bolusDao.findByPumpTempIds(bolus.interfaceIDs.temporaryId!!, bolus.interfaceIDs.pumpType!!, bolus.interfaceIDs.pumpSerial!!)
if (current != null) {
current.timestamp = bolus.timestamp
current.amount = bolus.amount
current.type = newType ?: current.type
current.interfaceIDs.pumpId = bolus.interfaceIDs.pumpId
database.bolusDao.updateExistingEntry(current)
result.updated.add(current)
}
return result
}
class TransactionResult {
val updated = mutableListOf<Bolus>()
}
}

View file

@ -37,7 +37,6 @@ import info.nightscout.androidaps.db.InsightPumpID;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.insight.R; import info.nightscout.androidaps.insight.R;
@ -591,8 +590,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface,
bolusCancelled = false; bolusCancelled = false;
} }
result.success(true).enacted(true); result.success(true).enacted(true);
Treatment t = new Treatment(); EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE;
bolusingEvent.setT(t); bolusingEvent.setT(t);
bolusingEvent.setStatus(resourceHelper.gs(R.string.insight_delivered, 0d, insulin)); bolusingEvent.setStatus(resourceHelper.gs(R.string.insight_delivered, 0d, insulin));

View file

@ -18,7 +18,6 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventCustomActionsChanged; import info.nightscout.androidaps.events.EventCustomActionsChanged;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
@ -418,8 +417,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true); activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE;
bolusingEvent.setT(new Treatment()); bolusingEvent.setT(new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB));
bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
bolusingEvent.setPercent(100); bolusingEvent.setPercent(100);
rxBus.send(bolusingEvent); rxBus.send(bolusingEvent);