Merge remote-tracking branch 'Nightscout/meallink' into meallink_ValueWithUnit

# Conflicts:
#	app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt
#	app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientAddUpdateWorker.kt
#	app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSClientRemoveWorker.kt
#	app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt
#	app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.kt
This commit is contained in:
Philoul 2021-03-30 23:05:19 +02:00
commit bf218e9ff4
112 changed files with 4122 additions and 956 deletions

View file

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

View file

@ -3,6 +3,8 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.TherapyEventDataPoint
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
@Module

View file

@ -16,7 +16,10 @@ import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.XXXValueWithUnit
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.UserEntry.Units
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.databinding.DialogCarbsBinding
import info.nightscout.androidaps.interfaces.Constraint
@ -224,7 +227,11 @@ class CarbsDialog : DialogFragmentWithDate() {
when {
activitySelected -> {
//uel.log(Action.TT, XXXValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY), XXXValueWithUnit.fromGlucoseUnit(activityTT, units) , XXXValueWithUnit.Minute(activityTTDuration))
uel.log(Action.TT, ValueWithUnit(Sources.CarbDialog), ValueWithUnit(TemporaryTarget.Reason.ACTIVITY.text, Units.TherapyEvent), ValueWithUnit(activityTT, units) , ValueWithUnit(activityTTDuration, Units.M))
uel.log(Action.TT,
ValueWithUnit(Sources.CarbDialog),
ValueWithUnit(TemporaryTarget.Reason.ACTIVITY.text, Units.TherapyEvent),
ValueWithUnit(activityTT, units) ,
ValueWithUnit(activityTTDuration, Units.M))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),
duration = TimeUnit.MINUTES.toMillis(activityTTDuration.toLong()),
@ -241,7 +248,11 @@ class CarbsDialog : DialogFragmentWithDate() {
eatingSoonSelected -> {
//uel.log(Action.TT, XXXValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON), XXXValueWithUnit.fromGlucoseUnit(eatingSoonTT, units) , XXXValueWithUnit.Minute(eatingSoonTTDuration))
uel.log(Action.TT, ValueWithUnit(Sources.CarbDialog), ValueWithUnit(TemporaryTarget.Reason.EATING_SOON.text, Units.TherapyEvent), ValueWithUnit(eatingSoonTT, units) , ValueWithUnit(eatingSoonTTDuration, Units.M))
uel.log(Action.TT,
ValueWithUnit(Sources.CarbDialog),
ValueWithUnit(TemporaryTarget.Reason.EATING_SOON.text, Units.TherapyEvent),
ValueWithUnit(eatingSoonTT, units) ,
ValueWithUnit(eatingSoonTTDuration, Units.M))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),
duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()),
@ -258,7 +269,11 @@ class CarbsDialog : DialogFragmentWithDate() {
hypoSelected -> {
//uel.log(Action.TT, XXXValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA), XXXValueWithUnit.fromGlucoseUnit(hypoTT, units) , XXXValueWithUnit.Minute(hypoTTDuration))
uel.log(Action.TT, ValueWithUnit(Sources.CarbDialog), ValueWithUnit(TemporaryTarget.Reason.HYPOGLYCEMIA.text, Units.TherapyEvent), ValueWithUnit(hypoTT, units) , ValueWithUnit(hypoTTDuration, Units.M))
uel.log(Action.TT,
ValueWithUnit(Sources.CarbDialog),
ValueWithUnit(TemporaryTarget.Reason.HYPOGLYCEMIA.text, Units.TherapyEvent),
ValueWithUnit(hypoTT, units) ,
ValueWithUnit(hypoTTDuration, Units.M))
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
timestamp = System.currentTimeMillis(),
duration = TimeUnit.MINUTES.toMillis(hypoTTDuration.toLong()),
@ -279,7 +294,7 @@ class CarbsDialog : DialogFragmentWithDate() {
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
detailedBolusInfo.context = context
detailedBolusInfo.notes = notes
detailedBolusInfo.carbsDuration = T.mins(duration.toLong()).msecs()
detailedBolusInfo.carbsDuration = T.hours(duration.toLong()).msecs()
detailedBolusInfo.carbsTimestamp = time
uel.log(if (duration == 0) Action.CARBS else Action.EXTENDED_CARBS,
detailedBolusInfo.notes,

View file

@ -176,7 +176,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))
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)
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
import info.nightscout.androidaps.db.Treatment
class EventTreatmentChange(val treatment: Treatment?) : EventLoop()
class EventTreatmentChange : EventLoop()

View file

@ -236,7 +236,9 @@ open class LoopPlugin @Inject constructor(
private fun treatmentTimeThreshold(durationMinutes: Int): Boolean {
val threshold = System.currentTimeMillis() + durationMinutes * 60 * 1000
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
}
@ -298,7 +300,7 @@ open class LoopPlugin @Inject constructor(
resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint!!).value()
// 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()) {
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
resultAfterConstraints.smb = 0.0
@ -580,7 +582,7 @@ open class LoopPlugin @Inject constructor(
return
}
val pump = activePlugin.activePump
val lastBolusTime = treatmentsPlugin.lastBolusTime
val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastBolusTime != 0L && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval")
callback?.result(PumpEnactResult(injector)
@ -602,7 +604,7 @@ open class LoopPlugin @Inject constructor(
// deliver SMB
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.lastBolusTime
detailedBolusInfo.lastKnownBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS
detailedBolusInfo.insulin = request.smb
detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.SMB

View file

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

View file

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

View file

@ -8,7 +8,7 @@ import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
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.events.EventNewBG
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.plugins.bus.RxBusWrapper
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.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -32,7 +31,6 @@ class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var maintenancePlugin: MaintenancePlugin
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var importExportPrefs: ImportExportPrefsInterface
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var repository: AppRepository
@ -65,9 +63,6 @@ class MaintenanceFragment : DaggerFragment() {
compositeDisposable.add(
fromAction {
databaseHelper.resetDatabases()
// should be handled by Plugin-Interface and
// additional service interface and plugin registry
treatmentsPlugin.service.resetTreatments()
repository.clearDatabases()
}
.subscribeOn(aapsSchedulers.io)

View file

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

View file

@ -9,10 +9,14 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.XXXValueWithUnit
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.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.UserEntry.Units
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.SyncNsTherapyEventTransaction
import info.nightscout.androidaps.events.EventNsTreatment
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
@ -26,6 +30,8 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
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.therapyEventFromJson
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -75,9 +81,60 @@ class NSClientAddUpdateWorker(
if (mills != 0L && mills < dateutil._now())
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(Action.CAREPORTAL,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.amount, UserEntry.Units.U)
)
}
result.invalidated.forEach {
uel.log(Action.CAREPORTAL_REMOVED,
ValueWithUnit(Sources.NSClient),
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(Action.CAREPORTAL,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.timestamp, Units.Timestamp, true),
ValueWithUnit(it.amount, Units.G)
)
}
result.invalidated.forEach {
uel.log(Action.CAREPORTAL,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.timestamp, Units.Timestamp, true),
ValueWithUnit(it.amount, Units.G)
)
}
}
} ?: aapsLogger.error("Error parsing bolus json $json")
}
when {
insulin > 0 || carbs > 0 ->
rxBus.send(EventNsTreatment(EventNsTreatment.ADD, json))
insulin > 0 || carbs > 0 -> Any()
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
temporaryTargetFromJson(json)?.let { temporaryTarget ->
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget))
@ -94,7 +151,8 @@ class NSClientAddUpdateWorker(
XXXValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
XXXValueWithUnit.Minute(tt.duration.toInt() / 60000)*/
result.inserted.forEach {
uel.log(Action.TT, ValueWithUnit(Sources.NSClient),
uel.log(Action.TT,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.reason.text, Units.TherapyEvent),
ValueWithUnit(it.lowTarget, Units.Mg_Dl, true),
ValueWithUnit(it.highTarget, Units.Mg_Dl, it.lowTarget != it.highTarget),
@ -136,7 +194,6 @@ class NSClientAddUpdateWorker(
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
eventType == TherapyEvent.Type.FINGER_STICK_BG_VALUE.text ||
eventType == TherapyEvent.Type.NOTE.text ||
eventType == TherapyEvent.Type.NONE.text ||
eventType == TherapyEvent.Type.ANNOUNCEMENT.text ||
eventType == TherapyEvent.Type.QUESTION.text ||

View file

@ -7,12 +7,14 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.XXXValueWithUnit
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.UserEntry.Units
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.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.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
@ -22,6 +24,8 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.JsonHelper
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.therapyEventFromNsIdForInvalidating
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -63,7 +67,7 @@ class NSClientRemoveWorker(
val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing temporary target", it)
aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it)
ret = Result.failure()
}
.blockingGet()
@ -93,7 +97,7 @@ class NSClientRemoveWorker(
val therapyEvent = therapyEventFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing therapy event", it)
aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it)
ret = Result.failure()
}
.blockingGet()
@ -113,8 +117,42 @@ class NSClientRemoveWorker(
}
}
// Insulin, carbs
rxBus.send(EventNsTreatment(REMOVE, json))
// room Bolus
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(
Action.CAREPORTAL_REMOVED,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.timestamp, Units.Timestamp, true),
ValueWithUnit(it.amount, 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(
Action.CAREPORTAL_REMOVED,
ValueWithUnit(Sources.NSClient),
ValueWithUnit(it.timestamp, Units.Timestamp, true),
ValueWithUnit(it.amount, Units.G))
}
}
// old DB model
databaseHelper.deleteTempBasalById(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.LTag
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.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -61,7 +60,6 @@ class OpenHumansUploader @Inject constructor(
private val sp: SP,
private val rxBus: RxBusWrapper,
private val context: Context,
private val treatmentsPlugin: TreatmentsPlugin,
private val databaseHelper: DatabaseHelperInterface,
val repository: AppRepository
) : PluginBase(
@ -356,11 +354,11 @@ class OpenHumansUploader @Inject constructor(
if (currentProgress % 1000L == 0L) showOngoingNotification(maxProgress, currentProgress)
}
copyDisposable = Completable.fromCallable { databaseHelper.clearOpenHumansQueue() }
.andThen(Single.defer { Single.just(databaseHelper.getCountOfAllRows() + treatmentsPlugin.service.count()) })
.doOnSuccess { maxProgress = it }
.flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.getTreatmentData()) } }
.map { enqueueTreatment(it); increaseCounter() }
.ignoreElements()
// .andThen(Single.defer { Single.just(databaseHelper.getCountOfAllRows() + treatmentsPlugin.service.count()) })
// .doOnSuccess { maxProgress = it }
// .flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.getTreatmentData()) } }
// .map { enqueueTreatment(it); increaseCounter() }
// .ignoreElements()
.andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) })
.map { enqueueBGReading(it); increaseCounter() }
.ignoreElements()

View file

@ -47,10 +47,10 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.source.DexcomPlugin
@ -778,7 +778,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (config.APS && lastRun?.constraintsProcessed != null) {
if (lastRun.constraintsProcessed!!.carbsReq > 0) {
//only display carbsreq when carbs have not been entered recently
if (treatmentsPlugin.lastCarbTime < lastRun.lastAPSRun) {
val lastCarb = repository.getLastCarbsRecordWrapped().blockingGet()
val lastCarbsTime = if (lastCarb is ValueWrapper.Existing) lastCarb.value.timestamp else 0L
if (lastCarbsTime < lastRun.lastAPSRun) {
cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
}
binding.infoLayout.cob.text = cobText
@ -861,7 +863,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// **** BG ****
if (predictionsAvailable && menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions)
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions?.map { bg-> GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper) }?.toMutableList())
else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null)
// Treatments

View file

@ -11,7 +11,8 @@ import com.jjoe64.graphview.series.Series
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.*
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.Bolus
@ -22,11 +23,7 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.*
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.target
import info.nightscout.androidaps.utils.resources.ResourceHelper
import java.util.*
@ -51,6 +48,7 @@ class GraphData(
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var translator: Translator
var maxY = Double.MIN_VALUE
private var minY = Double.MAX_VALUE
@ -77,7 +75,7 @@ class GraphData(
for (bg in bgReadingsArray!!) {
if (bg.timestamp < fromTime || bg.timestamp > toTime) continue
if (bg.value > maxBgValue) maxBgValue = bg.value
bgListArray.add(GlucoseValueDataPoint(injector, bg))
bgListArray.add(GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper))
}
if (predictions != null) {
predictions.sortWith(Comparator { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) })
@ -247,7 +245,7 @@ class GraphData(
it.y = getNearestBg(it.x.toLong())
filteredTreatments.add(it)
}
repository.getCarbsIncludingInvalidFromTimeToTime(fromTime, endTime, true).blockingGet()
repository.getCarbsIncludingInvalidFromTimeToTimeExpanded(fromTime, endTime, true).blockingGet()
.map { CarbsDataPoint(it, resourceHelper) }
.forEach {
it.y = getNearestBg(it.x.toLong())
@ -273,7 +271,7 @@ class GraphData(
// Careportal
// databaseHelper.getCareportalEventsFromTime(fromTime - 6 * 60 * 60 * 1000, true)
repository.compatGetTherapyEventDataFromToTime(fromTime - T.hours(6).msecs(), endTime).blockingGet()
.map { TherapyEventDataPoint(injector, it) }
.map { TherapyEventDataPoint(it, resourceHelper, profileFunction, translator) }
.filterTimeframe(fromTime, endTime)
.forEach {
if (it.y == 0.0) it.y = getNearestBg(it.x.toLong())

View file

@ -1,12 +1,10 @@
package info.nightscout.androidaps.data
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import android.graphics.Color
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DecimalFormatter.toPumpSupportedBolus
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -22,7 +20,7 @@ class BolusDataPoint @Inject constructor(
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue
override fun getLabel(): String = toPumpSupportedBolus(data.amount, activePlugin.activePump, resourceHelper)
override fun getLabel(): String = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, resourceHelper)
override fun getDuration(): Long = 0
override fun getSize(): Float = 2f

View file

@ -1,9 +1,7 @@
package info.nightscout.androidaps.data
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.Carbs
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -20,7 +18,7 @@ class CarbsDataPoint @Inject constructor(
override fun getDuration(): Long = 0
override fun getSize(): Float = 2f
override fun getShape(): PointsWithLabelGraphSeries.Shape = PointsWithLabelGraphSeries.Shape.BOLUS
override fun getShape(): PointsWithLabelGraphSeries.Shape = PointsWithLabelGraphSeries.Shape.CARBS
override fun getColor(): Int =
if (data.isValid) resourceHelper.gc(R.color.carbs)

View file

@ -1,29 +1,20 @@
package info.nightscout.androidaps.data
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class GlucoseValueDataPoint @Inject constructor(
val injector: HasAndroidInjector,
val data: GlucoseValue
val data: GlucoseValue,
private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction,
private val resourceHelper: ResourceHelper
) : DataPointWithLabelInterface {
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
init {
injector.androidInjector().inject(this)
}
fun valueToUnits(units: String): Double =
if (units == Constants.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
@ -59,11 +50,11 @@ class GlucoseValueDataPoint @Inject constructor(
val predictionColor: Int
get() {
return when (data.sourceSensor) {
GlucoseValue.SourceSensor.IOB_PREDICTION -> resourceHelper.gc(R.color.iob)
GlucoseValue.SourceSensor.COB_PREDICTION -> resourceHelper.gc(R.color.cob)
GlucoseValue.SourceSensor.IOB_PREDICTION -> resourceHelper.gc(R.color.iob)
GlucoseValue.SourceSensor.COB_PREDICTION -> resourceHelper.gc(R.color.cob)
GlucoseValue.SourceSensor.aCOB_PREDICTION -> -0x7f000001 and resourceHelper.gc(R.color.cob)
GlucoseValue.SourceSensor.UAM_PREDICTION -> resourceHelper.gc(R.color.uam)
GlucoseValue.SourceSensor.ZT_PREDICTION -> resourceHelper.gc(R.color.zt)
GlucoseValue.SourceSensor.UAM_PREDICTION -> resourceHelper.gc(R.color.uam)
GlucoseValue.SourceSensor.ZT_PREDICTION -> resourceHelper.gc(R.color.zt)
else -> R.color.white
}
}

View file

@ -1,35 +1,25 @@
package info.nightscout.androidaps.data
package info.nightscout.androidaps.plugins.general.overview.graphExtensions
import android.graphics.Color
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.Interval
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class TherapyEventDataPoint @Inject constructor(
val injector: HasAndroidInjector,
val data: TherapyEvent
val data: TherapyEvent,
private val resourceHelper: ResourceHelper,
private val profileFunction: ProfileFunction,
private val translator: Translator
) : DataPointWithLabelInterface, Interval {
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var translator: Translator
private var yValue = 0.0
init {
injector.androidInjector().inject(this)
}
override fun getX(): Double {
return data.timestamp.toDouble()
}

View file

@ -18,7 +18,10 @@ import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.XXXValueWithUnit
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.UserEntry.Units
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
import info.nightscout.androidaps.events.EventPreferenceChange
@ -97,7 +100,6 @@ class SmsCommunicatorPlugin @Inject constructor(
val commands = mapOf(
"BG" to "BG",
"LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20",
"TREATMENTS" to "TREATMENTS REFRESH",
"NSCLIENT" to "NSCLIENT RESTART",
"PUMP" to "PUMP\nPUMP CONNECT\nPUMP DISCONNECT 30\n",
"BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n",
@ -244,61 +246,58 @@ class SmsCommunicatorPlugin @Inject constructor(
if (divided.isNotEmpty() && isCommand(divided[0].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) {
when (divided[0].toUpperCase(Locale.getDefault())) {
"BG" ->
"BG" ->
if (divided.size == 1) processBG(receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"LOOP" ->
"LOOP" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processLOOP(divided, receivedSms)
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)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"PUMP" ->
"PUMP" ->
if (!remoteCommandsAllowed && divided.size > 1) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size <= 3) processPUMP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"PROFILE" ->
"PROFILE" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processPROFILE(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"BASAL" ->
"BASAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processBASAL(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"EXTENDED" ->
"EXTENDED" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processEXTENDED(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"BOLUS" ->
"BOLUS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 && DateUtil.now() - lastRemoteBolusTime < minDistance) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotebolusnotallowed)))
else if (divided.size == 2 && pump.isSuspended()) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.pumpsuspended)))
else if (divided.size == 2 || divided.size == 3) processBOLUS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"CARBS" ->
"CARBS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processCARBS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"CAL" ->
"CAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processCAL(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"TARGET" ->
"TARGET" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processTARGET(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"SMS" ->
"SMS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processSMS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"HELP" ->
"HELP" ->
if (divided.size == 1 || divided.size == 2) processHELP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
else ->
else ->
if (messageToConfirm?.requester?.phoneNumber == receivedSms.phoneNumber) {
messageToConfirm?.action(divided[0])
messageToConfirm = null
@ -452,16 +451,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) {
if (divided[1].toUpperCase(Locale.getDefault()) == "RESTART") {
rxBus.send(EventNSClientRestart())
@ -885,37 +874,32 @@ class SmsCommunicatorPlugin @Inject constructor(
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.carbs = anInteger().toDouble()
detailedBolusInfo.timestamp = secondLong()
if (activePlugin.activePump.pumpDescription.storesCarbInfo) {
commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (result.success) {
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), XXXValueWithUnit.StringResource(R.string.smscommunicator_carbsset, listOf(XXXValueWithUnit.Gram(anInteger ?: 0))))
uel.log(Action.CARBS, activePlugin.activePump.shortStatus(true), ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_carbsset, 1), ValueWithUnit(anInteger
?: 0, Units.G))
} else {
var replyText = resourceHelper.gs(R.string.smscommunicator_carbsfailed, anInteger)
replyText += "\n" + activePlugin.activePump.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
//uel.log(Action.SMS_CARBS, activePlugin.activePump.shortStatus(true), XXXValueWithUnit.StringResource(R.string.smscommunicator_carbsfailed, listOf(XXXValueWithUnit.Gram(anInteger
// ?: 0))))
uel.log(Action.CARBS, activePlugin.activePump.shortStatus(true), ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_carbsfailed, 1), ValueWithUnit(anInteger
?: 0, Units.G))
}
commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (result.success) {
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), XXXValueWithUnit.StringResource(R.string.smscommunicator_carbsset, listOf(XXXValueWithUnit.Gram(anInteger ?: 0))))
uel.log(Action.CARBS,
activePlugin.activePump.shortStatus(true),
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_carbsset, 1),
ValueWithUnit(anInteger ?: 0, Units.G))
} else {
var replyText = resourceHelper.gs(R.string.smscommunicator_carbsfailed, anInteger)
replyText += "\n" + activePlugin.activePump.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
//uel.log(Action.SMS_CARBS, activePlugin.activePump.shortStatus(true), XXXValueWithUnit.StringResource(R.string.smscommunicator_carbsfailed, listOf(XXXValueWithUnit.Gram(anInteger
// ?: 0))))
uel.log(Action.CARBS,
activePlugin.activePump.shortStatus(true),
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_carbsfailed, 1),
ValueWithUnit(anInteger ?: 0, Units.G))
}
})
} 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), XXXValueWithUnit.StringResource(R.string.smscommunicator_carbsset, listOf(XXXValueWithUnit.Gram(anInteger
// ?: 0))))
uel.log(Action.CARBS, activePlugin.activePump.shortStatus(true), ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_carbsset, 1), ValueWithUnit(anInteger
?: 0, Units.G))
}
}
})
}
})
}
@ -985,7 +969,10 @@ class SmsCommunicatorPlugin @Inject constructor(
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
//uel.log(Action.SMS_TT, ValueWithUnit(R.string.smscommunicator_tt_set, 2), ValueWithUnit(tt, units), ValueWithUnit(ttDuration, Units.M))
//uel.log(Action.SMS_TT, XXXValueWithUnit.fromGlucoseUnit(tt, units), XXXValueWithUnit.Minute(ttDuration))
uel.log(Action.TT, ValueWithUnit(Sources.SMS), ValueWithUnit(tt, units), ValueWithUnit(ttDuration, Units.M))
uel.log(Action.TT,
ValueWithUnit(Sources.SMS),
ValueWithUnit(tt, units),
ValueWithUnit(ttDuration, Units.M))
}
})
} else if (isStop) {
@ -1003,7 +990,9 @@ class SmsCommunicatorPlugin @Inject constructor(
val replyText = String.format(resourceHelper.gs(R.string.smscommunicator_tt_canceled))
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
//uel.log(Action.SMS_TT, XXXValueWithUnit.StringResource(R.string.smscommunicator_tt_canceled))
uel.log(Action.CANCEL_TT, ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_tt_canceled, Units.R_String))
uel.log(Action.CANCEL_TT,
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_tt_canceled, Units.R_String))
}
})
} else
@ -1023,7 +1012,9 @@ class SmsCommunicatorPlugin @Inject constructor(
val replyText = String.format(resourceHelper.gs(R.string.smscommunicator_stoppedsms))
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
//uel.log(Action.SMS_SMS, XXXValueWithUnit.StringResource(R.string.smscommunicator_stoppedsms))
uel.log(Action.STOP_SMS, ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_stoppedsms, Units.R_String))
uel.log(Action.STOP_SMS,
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_stoppedsms, Units.R_String))
}
})
} else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
@ -1043,10 +1034,14 @@ class SmsCommunicatorPlugin @Inject constructor(
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
if (result)
//uel.log(Action.SMS_CAL, XXXValueWithUnit.StringResource(R.string.smscommunicator_calibrationsent))
uel.log(Action.CALIBRATION, ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_calibrationsent, Units.R_String))
uel.log(Action.CALIBRATION,
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_calibrationsent, Units.R_String))
else
//uel.log(Action.SMS_CAL, XXXValueWithUnit.StringResource(R.string.smscommunicator_calibrationfailed))
uel.log(Action.CALIBRATION, ValueWithUnit(Sources.SMS), ValueWithUnit(R.string.smscommunicator_calibrationfailed, Units.R_String))
uel.log(Action.CALIBRATION,
ValueWithUnit(Sources.SMS),
ValueWithUnit(R.string.smscommunicator_calibrationfailed, Units.R_String))
}
})
} else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))

View file

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

View file

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

View file

@ -1,33 +1,28 @@
package info.nightscout.androidaps.plugins.general.tidepool.elements
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.*
class WizardElement(treatment: Treatment)
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-wizard" + treatment.date).toByteArray()).toString()) {
class WizardElement(carbs: Carbs)
: BaseElement(carbs.timestamp, UUID.nameUUIDFromBytes(("AAPS-wizard" + carbs.timestamp).toByteArray()).toString()) {
@Expose
var units = "mg/dL"
@Expose
var carbInput: Double = 0.toDouble()
@Expose
var insulinCarbRatio: Double = 0.toDouble()
@Expose
var bolus: BolusElement? = null
@Expose var units = "mg/dL"
@Expose var carbInput: Double = 0.toDouble()
@Expose var insulinCarbRatio: Double = 0.toDouble()
@Expose var bolus: BolusElement? = null
init {
type = "wizard"
carbInput = treatment.carbs
insulinCarbRatio = treatment.ic
if (treatment.insulin > 0) {
bolus = BolusElement(treatment)
} else {
val fake = Treatment()
fake.insulin = 0.0001
fake.date = treatment.date
bolus = BolusElement(fake) // fake insulin record
}
carbInput = carbs.amount
val fake = Bolus(
amount = 0.0001,
timestamp = carbs.timestamp,
type = Bolus.Type.NORMAL,
isBasalInsulin = false
)
bolus = BolusElement(fake) // fake insulin record
}
}

View file

@ -10,7 +10,8 @@ import javax.inject.Singleton
@Singleton
class RateLimit @Inject constructor(
val aapsLogger: AAPSLogger
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil
) {
private val rateLimits = HashMap<String, Long>()
@ -20,13 +21,13 @@ class RateLimit @Inject constructor(
fun rateLimit(name: String, seconds: Int): Boolean {
// check if over limit
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")
return false
}
}
// not over limit
rateLimits[name] = DateUtil.now()
rateLimits[name] = dateUtil._now()
return true
}
}

View file

@ -16,7 +16,10 @@ import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.UserEntry.*
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.UserEntry.Units
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.interfaces.end
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
@ -28,7 +31,6 @@ import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
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.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
@ -81,8 +83,7 @@ class ActionStringHandler @Inject constructor(
private val config: Config,
private val databaseHelper: DatabaseHelperInterface,
private val repository: AppRepository,
private val uel: UserEntryLogger,
private val nsUpload: NSUpload
private val uel: UserEntryLogger
) {
private val timeout = 65 * 1000
@ -569,7 +570,10 @@ class ActionStringHandler @Inject constructor(
return
}
//send profile to pump
uel.log(Action.PROFILE_SWITCH, ValueWithUnit(Sources.Wear), ValueWithUnit(percentage, Units.Percent), ValueWithUnit(timeshift, Units.H, timeshift != 0))
uel.log(Action.PROFILE_SWITCH,
ValueWithUnit(Sources.Wear),
ValueWithUnit(percentage, Units.Percent),
ValueWithUnit(timeshift, Units.H, timeshift != 0))
activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift)
}
@ -587,7 +591,9 @@ class ActionStringHandler @Inject constructor(
}, {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
})
uel.log(Action.TT, ValueWithUnit(Sources.Wear), ValueWithUnit(TemporaryTarget.Reason.WEAR.text, Units.TherapyEvent), ValueWithUnit(low, profileFunction.getUnits()), ValueWithUnit(high, profileFunction.getUnits(), low!=high), ValueWithUnit(duration, Units.M))
uel.log(Action.TT,
ValueWithUnit(Sources.Wear),
ValueWithUnit(TemporaryTarget.Reason.WEAR.text, Units.TherapyEvent), ValueWithUnit(low, profileFunction.getUnits()), ValueWithUnit(high, profileFunction.getUnits(), low!=high), ValueWithUnit(duration, Units.M))
} else {
disposable += repository.runTransactionForResult(CancelCurrentTemporaryTargetIfAnyTransaction(System.currentTimeMillis()))
.subscribe({ result ->
@ -595,7 +601,9 @@ class ActionStringHandler @Inject constructor(
}, {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
})
uel.log(Action.CANCEL_TT, ValueWithUnit(Sources.Wear), ValueWithUnit(TemporaryTarget.Reason.WEAR.text, Units.TherapyEvent))
uel.log(Action.CANCEL_TT,
ValueWithUnit(Sources.Wear),
ValueWithUnit(TemporaryTarget.Reason.WEAR.text, Units.TherapyEvent))
}
}
@ -626,15 +634,19 @@ class ActionStringHandler @Inject constructor(
detailedBolusInfo.carbs = carbs.toDouble()
detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.NORMAL
detailedBolusInfo.carbsTimestamp = carbsTime
detailedBolusInfo.carbsDuration = carbsDuration.toLong()
val storesCarbs = activePlugin.activePump.pumpDescription.storesCarbInfo
if (detailedBolusInfo.insulin > 0 || (storesCarbs && carbsDuration == 0)) {
detailedBolusInfo.carbsDuration = T.hours(carbsDuration.toLong()).msecs()
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
val action = when {
amount.equals(0.0) -> Action.CARBS
carbs.equals(0) -> Action.BOLUS
else -> Action.TREATMENT
amount.equals(0.0) -> Action.CARBS
carbs.equals(0) -> Action.BOLUS
carbsDuration>0 -> Action.EXTENDED_CARBS
else -> Action.TREATMENT
}
uel.log(action, ValueWithUnit(Sources.Wear), ValueWithUnit(amount, Units.U, amount != 0.0), ValueWithUnit(carbs, Units.G, carbs != 0))
uel.log(action,
ValueWithUnit(Sources.Wear),
ValueWithUnit(amount, Units.U, amount != 0.0),
ValueWithUnit(carbs, Units.G, carbs != 0),
ValueWithUnit(carbsDuration, Units.H, carbsDuration != 0))
commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
if (!result.success) {
@ -644,8 +656,6 @@ class ActionStringHandler @Inject constructor(
}
}
})
} else {
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
}
}

View file

@ -24,6 +24,7 @@ import com.google.android.gms.wearable.WearableListenerService;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -31,7 +32,7 @@ import dagger.android.AndroidInjection;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseValueDataPoint;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.GlucoseValueDataPoint;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.database.AppRepository;
@ -527,13 +528,18 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
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())));
repository.getCarbsIncludingInvalidFromTime(startTimeWindow, true).blockingGet()
repository.getCarbsDataFromTimeExpanded(startTimeWindow, true).blockingGet()
.forEach(carb -> boluses.add(treatmentMap(carb.getTimestamp(), 0, carb.getAmount(), false, carb.isValid())));
final LoopPlugin.LastRun finalLastRun = loopPlugin.getLastRun();
if (sp.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.getRequest().getHasPredictions() && finalLastRun.getConstraintsProcessed() != null) {
List<GlucoseValueDataPoint> predArray = finalLastRun.getConstraintsProcessed().getPredictions();
List<GlucoseValueDataPoint> predArray =
finalLastRun.getConstraintsProcessed().getPredictions()
.stream().map( bg -> new GlucoseValueDataPoint(bg, defaultValueHelper, profileFunction, resourceHelper))
.collect(Collectors.toList());
if (!predArray.isEmpty()) {
final String units = profileFunction.getUnits();

View file

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

View file

@ -531,7 +531,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
var displayCob: Double? = null
var futureCarbs = 0.0
val now = DateUtil.now()
val carbs = repository.getCarbsDataFromTime(now, true).blockingGet()
val carbs = repository.getCarbsDataFromTimeExpanded(now, true).blockingGet()
if (autosensData != null) {
displayCob = autosensData.cob
carbs.forEach { carb ->
@ -601,12 +601,14 @@ open class IobCobCalculatorPlugin @Inject constructor(
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
}
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
repository.getCarbsDataFromTimeToTime(absorptionTimeAgo + 1, now, true).blockingGet().forEach {
if (it.amount > 0) {
result.carbs += it.amount
if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
.blockingGet()
.forEach {
if (it.amount > 0) {
result.carbs += it.amount
if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp
}
}
}
val autosensData = getLastAutosensDataSynchronized("getMealData()")
if (autosensData != null) {
result.mealCOB = autosensData.cob
@ -614,7 +616,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact
}
result.lastBolusTime = treatmentsPlugin.lastBolusTime
result.lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
return result
}
@ -778,6 +780,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 calculateIobFromBolusToTime(timestamp: Long): IobTotal {
@ -786,7 +797,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
val dia = profile.dia
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 ->
if (t.isValid && t.timestamp < timestamp) {

View file

@ -189,7 +189,7 @@ class IobCobOref1Thread internal constructor(
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
}
}
val recentCarbTreatments = repository.getCarbsDataFromTimeToTime(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
for (recentCarbTreatment in recentCarbTreatments) {
autosensData.carbsFromBolus += recentCarbTreatment.amount
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()

View file

@ -188,7 +188,7 @@ class IobCobThread @Inject internal constructor(
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
}
}
val recentCarbTreatments = repository.getCarbsDataFromTimeToTime(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
for (recentCarbTreatment in recentCarbTreatments) {
autosensData.carbsFromBolus += recentCarbTreatment.amount
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()

View file

@ -10,9 +10,9 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.common.ManufacturerType
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.InstanceId.instanceId
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONException
import org.json.JSONObject
@ -25,7 +25,8 @@ class MDIPlugin @Inject constructor(
aapsLogger: AAPSLogger,
resourceHelper: ResourceHelper,
commandQueue: CommandQueueProvider,
private val treatmentsPlugin: TreatmentsPlugin
private val dateUtil: DateUtil,
private val pumpSync: PumpSync
) : PumpPluginBase(PluginDescription()
.mainType(PluginType.PUMP)
.pluginIcon(R.drawable.ic_ict)
@ -73,7 +74,21 @@ class MDIPlugin @Inject constructor(
result.bolusDelivered = detailedBolusInfo.insulin
result.carbsDelivered = detailedBolusInfo.carbs
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
}

View file

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

View file

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

View file

@ -87,7 +87,8 @@ class RandomBgPlugin @Inject constructor(
}
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() {

View file

@ -17,8 +17,6 @@ import com.j256.ormlite.table.TableUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.sql.SQLException;
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.Treatment;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTreatmentChange;
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.pump.medtronic.MedtronicPumpPlugin;
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.JsonHelper;
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 AapsSchedulers aapsSchedulers;
private final CompositeDisposable disposable = new CompositeDisposable();
private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledTreatmentEventPost = null;
@ -79,20 +71,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
injector.androidInjector().inject(this);
onCreate();
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.
* 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) {
if (runImmediately) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventReloadTreatmentData");
rxBus.send(new EventReloadTreatmentData(new EventTreatmentChange(treatment)));
rxBus.send(new EventReloadTreatmentData(new EventTreatmentChange()));
if (DatabaseHelper.earliestDataChange != null) {
aapsLogger.debug(LTag.DATATREATMENTS, "Firing EventNewHistoryData");
rxBus.send(new EventNewHistoryData(DatabaseHelper.earliestDataChange));
}
DatabaseHelper.earliestDataChange = null;
} else {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange(treatment)), treatmentEventWorker, new ICallback() {
this.scheduleEvent(new EventReloadTreatmentData(new EventTreatmentChange()), treatmentEventWorker, new ICallback() {
@Override
public void setPost(ScheduledFuture<?> 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() {
try {
return this.getDao().countOf();
@ -326,26 +282,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
"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
public UpdateReturn createOrUpdate(Treatment treatment) {
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.
*
@ -784,40 +619,6 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> impleme
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
@Override
public IBinder onBind(Intent intent) {

View file

@ -8,7 +8,6 @@ import androidx.annotation.Nullable;
import com.google.firebase.analytics.FirebaseAnalytics;
import java.util.ArrayList;
import java.util.List;
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.FabricPrivacy;
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.rx.AapsSchedulers;
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
* 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
* @return
@ -269,7 +269,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
*/
}
/*
@Override
public long getLastBolusTime() {
Treatment last = getService().getLastBolus(false);
@ -305,6 +305,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
}
*/
@Override
public boolean isInHistoryRealTempBasalInProgress() {
return getRealTempBasalFromHistory(System.currentTimeMillis()) != null;
@ -413,10 +415,21 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (runningTBR != null) {
running = runningTBR.tempBasalConvertedToAbsolute(i, profile);
}
Treatment treatment = new Treatment(getInjector());
treatment.date = i;
treatment.insulin = running * 5.0 / 60.0; // 5 min chunk
Iob iob = treatment.iobCalc(time, profile.getDia());
Bolus bolus = new Bolus(
0, // id
0, // version
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.activity += iob.getActivityContrib();
}

View file

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

View file

@ -22,7 +22,7 @@ class CommandSMBBolus(
override fun execute() {
val r: PumpEnactResult
val lastBolusTime = activePlugin.activeTreatments.lastBolusTime
val lastBolusTime = repository.getLastBolusRecord()?.timestamp ?: 0L
if (lastBolusTime != 0L && lastBolusTime + T.mins(3).msecs() > dateUtil._now()) {
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")

View file

@ -6,6 +6,7 @@ import android.util.LongSparseArray
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.db.TDD
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
@ -56,13 +57,15 @@ class TddCalculator @Inject constructor(
initializeData(range)
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 tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
tdd.bolus += t.amount
result.put(midnight, tdd)
}
repository.getCarbsDataFromTimeToTime(startTime, endTime, true).blockingGet().forEach { t->
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t->
val midnight = MidnightTime.calc(t.timestamp)
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
tdd.carbs += t.amount

View file

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

View file

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

View file

@ -468,36 +468,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("LOOP BLABLA", smsCommunicatorPlugin.messages[0].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
PowerMockito.`when`(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true)
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.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction
@ -41,7 +42,8 @@ import java.util.*
@RunWith(PowerMockRunner::class)
@PrepareForTest(
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() {
@Mock lateinit var constraintChecker: ConstraintChecker
@ -113,7 +115,14 @@ class CommandQueueTest : TestBaseWithProfile() {
`when`(lazyActivePlugin.get()).thenReturn(activePlugin)
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
`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)
val bolusConstraint = Constraint(0.0)

View file

@ -75,7 +75,7 @@ class QueueThreadTest : TestBaseWithProfile() {
Mockito.`when`(lazyActivePlugin.get()).thenReturn(activePlugin)
Mockito.`when`(activePlugin.activePump).thenReturn(pumpPlugin)
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)
val bolusConstraint = Constraint(0.0)

View file

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

View file

@ -4,19 +4,20 @@ import android.widget.LinearLayout
import com.google.common.base.Optional
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.logging.LTag
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.LabelWithElement
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
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.safeGetString
import org.json.JSONObject
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)
private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) {
@ -35,7 +36,7 @@ class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
}
override fun shouldRun(): Boolean {
val lastBolusTime = treatmentsInterface.getLastBolusTime(true)
val lastBolusTime = repository.getLastBolusRecordOfType(Bolus.Type.NORMAL)?.timestamp ?: 0L
if (lastBolusTime == 0L)
return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
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())
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")
val doRun = comparator.value.check(last.toInt(), minutesAgo.getMinutes())
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.LayoutBuilder
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.MidnightTime
import org.json.JSONObject
import java.util.*
import javax.inject.Inject
class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var dateUtil: DateUtil
val days = InputWeekDay()
val time = InputTime(resourceHelper, dateUtil)
@ -34,7 +31,7 @@ class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
return this
}
override fun shouldRun() : Boolean {
override fun shouldRun(): Boolean {
val currentMinSinceMidnight = getMinSinceMidnight(dateUtil._now())
val scheduledDayOfWeek = Calendar.getInstance()[Calendar.DAY_OF_WEEK]
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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.logging.LTag
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.StaticLabel
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
import javax.inject.Inject
class TriggerTempTarget(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var repository: AppRepository
@Inject lateinit var dateUtil: DateUtil
var comparator = ComparatorExists(resourceHelper)
constructor(injector: HasAndroidInjector, compare: ComparatorExists.Compare) : this(injector) {

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.automation.triggers
import android.content.Context
import android.widget.LinearLayout
import com.google.common.base.Optional
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.T
import org.json.JSONObject
import javax.inject.Inject
class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var dateUtil: DateUtil
var time = InputDateTime(resourceHelper, dateUtil)
@ -24,7 +21,8 @@ class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) {
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
}

View file

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

View file

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

View file

@ -6,7 +6,6 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -18,7 +17,7 @@ import org.mockito.Mock
import org.mockito.Mockito.`when`
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 TestLoopPlugin(
@ -45,7 +44,6 @@ open class ActionsTestBase : TestBaseWithProfile() {
@Mock lateinit var profilePlugin: ProfileInterface
@Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorInterface
@Mock lateinit var loopPlugin: TestLoopPlugin
@Mock lateinit var repository: AppRepository
private val pluginDescription = PluginDescription()
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 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.utils.DateUtil
import org.json.JSONException
@ -29,8 +30,15 @@ class TriggerBolusAgoTest : TriggerTestBase() {
@Test
fun shouldRunTest() {
`when`(treatmentsInterface.getLastBolusTime(true)).thenReturn(now) // Set last bolus time to now
`when`(DateUtil.now()).thenReturn(now + 10 * 60 * 1000) // set current time to now + 10 min
`when`(repository.getLastBolusRecordOfType(Bolus.Type.NORMAL)).thenReturn(
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)
Assert.assertEquals(110, t.minutesAgo.value)
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t.comparator.value)
@ -52,7 +60,14 @@ class TriggerBolusAgoTest : TriggerTestBase() {
Assert.assertTrue(t.shouldRun())
t = TriggerBolusAgo(injector).setValue(390).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
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)
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.receivers.ReceiverStatusStore
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Before
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest
@PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class, AppRepository::class)
@PrepareForTest(LastLocationDataContainer::class, AutomationPlugin::class)
open class TriggerTestBase : TestBaseWithProfile() {
@Mock lateinit var sp: SP
@ -29,11 +30,10 @@ open class TriggerTestBase : TestBaseWithProfile() {
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
@Mock lateinit var context: Context
@Mock lateinit var automationPlugin: AutomationPlugin
@Mock lateinit var repository: AppRepository
lateinit var receiverStatusStore: ReceiverStatusStore
private val pluginDescription = PluginDescription()
lateinit var testPumpPlugin : TestPumpPlugin
lateinit var testPumpPlugin: TestPumpPlugin
@Before
fun prepareMock1() {
@ -51,10 +51,11 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.profileFunction = profileFunction
it.sp = sp
it.locationDataContainer = locationDataContainer
it.treatmentsInterface = treatmentsInterface
it.repository = repository
it.activePlugin = activePlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin)
it.dateUtil = dateUtil
}
if (it is TriggerBg) {
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.TDD;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
@ -488,8 +487,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
treatmentsPlugin.addToHistoryTreatment(detailedBolusInfo, false);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE;
bolusingEvent.setT(new Treatment());
bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
bolusingEvent.setT(new EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB));
bolusingEvent.setPercent(100);
rxBus.send(bolusingEvent);
@ -566,8 +564,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
return new PumpEnactResult(getInjector()).success(true).enacted(false);
}
Treatment treatment = new Treatment();
treatment.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
EventOverviewBolusProgress.INSTANCE.setT(treatment);
// start bolus delivery

View file

@ -2,10 +2,8 @@ package info.nightscout.androidaps.core.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.data.GlucoseValueDataPoint
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.data.TherapyEventDataPoint
import info.nightscout.androidaps.db.ExtendedBolus
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.TemporaryBasal
@ -31,6 +29,4 @@ abstract class CoreDataClassesModule {
@ContributesAndroidInjector abstract fun profileSwitchInjector(): ProfileSwitch
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
@ContributesAndroidInjector abstract fun extendedBolusInjector(): ExtendedBolus
@ContributesAndroidInjector abstract fun glucoseValueDataPointInjector(): GlucoseValueDataPoint
@ContributesAndroidInjector abstract fun therapyEventDataPointInjector(): TherapyEventDataPoint
}

View file

@ -31,11 +31,8 @@ class PumpEnactResult(injector: HasAndroidInjector) {
var bolusDelivered = 0.0 // real value of delivered insulin
var carbsDelivered = 0.0 // real value of delivered carbs
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 comment(comment: String): PumpEnactResult = this.also { it.comment = 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 --------------------
public Iob iobCalc(long time, double dia) {
if (!isValid)
return new Iob();
InsulinInterface insulinInterface = activePlugin.getActiveInsulin();
return insulinInterface.iobCalcForTreatment(this, time, dia);
}
@Override
public long getDate() {
return this.date;

View file

@ -4,8 +4,53 @@ import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
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
@ -13,17 +58,18 @@ interface PumpSync {
* Search for combination of pumpId, PumpType, pumpSerial
*
* 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
*
* @param timestamp timestamp of event from pump history
* @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 pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @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
@ -39,8 +85,9 @@ interface PumpSync {
* @param pumpId pump id from history if coming form pump history
* @param pumpType pump type like PumpType.ACCU_CHEK_COMBO
* @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

View file

@ -4,15 +4,6 @@ import info.nightscout.androidaps.db.Treatment
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 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
List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp);
long getLastBolusTime();
long getLastBolusTime(boolean excludeSMB);
// real basals (not faked by extended bolus)
boolean isInHistoryRealTempBasalInProgress();

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.aps.loop
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.GlucoseValueDataPoint
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.ActivePluginProvider
@ -14,6 +13,7 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -37,6 +37,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
@Inject lateinit var treatmentsPlugin: TreatmentsInterface
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var dateUtil: DateUtil
var date: Long = 0
var reason: String? = null
@ -183,9 +184,9 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
return json
}
val predictions: MutableList<GlucoseValueDataPoint>
val predictions: MutableList<GlucoseValue>
get() {
val array: MutableList<GlucoseValueDataPoint> = ArrayList()
val array: MutableList<GlucoseValue> = ArrayList()
val startTime = date
json?.let { json ->
if (json.has("predBGs")) {
@ -201,7 +202,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
sourceSensor = GlucoseValue.SourceSensor.IOB_PREDICTION,
trendArrow = GlucoseValue.TrendArrow.NONE
)
array.add(GlucoseValueDataPoint(injector, gv))
array.add(gv)
}
}
if (predBGs.has("aCOB")) {
@ -215,7 +216,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
sourceSensor = GlucoseValue.SourceSensor.aCOB_PREDICTION,
trendArrow = GlucoseValue.TrendArrow.NONE
)
array.add(GlucoseValueDataPoint(injector, gv))
array.add(gv)
}
}
if (predBGs.has("COB")) {
@ -229,7 +230,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
sourceSensor = GlucoseValue.SourceSensor.COB_PREDICTION,
trendArrow = GlucoseValue.TrendArrow.NONE
)
array.add(GlucoseValueDataPoint(injector, gv))
array.add(gv)
}
}
if (predBGs.has("UAM")) {
@ -243,7 +244,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
sourceSensor = GlucoseValue.SourceSensor.UAM_PREDICTION,
trendArrow = GlucoseValue.TrendArrow.NONE
)
array.add(GlucoseValueDataPoint(injector, gv))
array.add(gv)
}
}
if (predBGs.has("ZT")) {
@ -257,7 +258,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
sourceSensor = GlucoseValue.SourceSensor.ZT_PREDICTION,
trendArrow = GlucoseValue.TrendArrow.NONE
)
array.add(GlucoseValueDataPoint(injector, gv))
array.add(gv)
}
}
}

View file

@ -43,18 +43,21 @@ public class NSUpload {
private final SP sp;
private final UploadQueueInterface uploadQueue;
private final RunningConfiguration runningConfiguration;
private final DateUtil dateUtil;
@Inject
public NSUpload(
AAPSLogger aapsLogger,
SP sp,
UploadQueueInterface uploadQueue,
RunningConfiguration runningConfiguration
RunningConfiguration runningConfiguration,
DateUtil dateUtil
) {
this.aapsLogger = aapsLogger;
this.sp = sp;
this.uploadQueue = uploadQueue;
this.runningConfiguration = runningConfiguration;
this.dateUtil = dateUtil;
}
public void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
@ -208,7 +211,7 @@ public class NSUpload {
IobTotal[] iob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile);
if (iob.length > 0) {
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;

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.plugins.general.overview.events
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.events.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 t: Treatment? = null
var percent = 0

View file

@ -18,15 +18,12 @@ package info.nightscout.androidaps.plugins.general.overview.graphExtensions;
* You should have received a copy of the GNU General Public License
* with the "Linking Exception" along with this program; if not,
* write to the author Jonas Gehring <g.jjoe64@gmail.com>.
* <p>
*/
/*
* Added by mike
*/
/**
* Added by mike
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
@ -61,6 +58,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
TRIANGLE,
RECTANGLE,
BOLUS,
CARBS,
SMB,
EXTENDEDBOLUS,
PROFILE,
@ -233,7 +231,18 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint);
if (value.getLabel() != null) {
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
}
} else if (value.getShape() == Shape.CARBS) {
mPaint.setStrokeWidth(0);
Point[] points = new Point[3];
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint);
if (value.getLabel() != null) {
drawLabel45Left(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
}
} else if (value.getShape() == Shape.SMB) {
mPaint.setStrokeWidth(2);
@ -282,21 +291,21 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
if (value.getLabel() != null) {
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
}
} else if (value.getShape() == Shape.ANNOUNCEMENT) {
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
if (value.getLabel() != null) {
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
}
} else if (value.getShape() == Shape.GENERAL) {
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
if (value.getLabel() != null) {
drawLabel45(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
drawLabel45Right(endX, endY, value, canvas, scaledPxSize, scaledTextSize);
}
} else if (value.getShape() == Shape.EXERCISE) {
mPaint.setStrokeWidth(0);
@ -380,29 +389,29 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
canvas.restore();
}
void drawLabel45(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
if (value.getLabel().startsWith("~")) {
float px = endX;
float py = endY + scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
mPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(value.getLabel().substring(1), px - scaledPxSize, py, mPaint);
mPaint.setTextAlign(Paint.Align.LEFT);
canvas.restore();
} else {
float px = endX;
float py = endY - scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
canvas.restore();
}
void drawLabel45Right(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
float px = endX;
float py = endY - scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
canvas.restore();
}
}
void drawLabel45Left(float endX, float endY, E value, Canvas canvas, Float scaledPxSize, Float scaledTextSize) {
float px = endX;
float py = endY + scaledPxSize;
canvas.save();
canvas.rotate(-45, px, py);
mPaint.setTextSize((float) (scaledTextSize * 0.8));
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
mPaint.setFakeBoldText(true);
mPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(value.getLabel(), px - scaledPxSize, py, mPaint);
mPaint.setTextAlign(Paint.Align.LEFT);
canvas.restore();
}
}

View file

@ -13,7 +13,6 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.core.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.database.entities.Carbs;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.logging.AAPSLogger;
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.Carbs
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampCarbsTransaction
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.database.transactions.*
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
@ -25,19 +22,54 @@ class PumpSyncImplementation @Inject constructor(
private val disposable = CompositeDisposable()
override fun addBolusWithTempId(timestamp: Long, amount: Double, driverId: Long, pumpType: PumpType, pumpSerial: String) {
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) {
override fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String) : Boolean {
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
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(
pumpId = pumpId,
pumpType = pumpType.toDbPumpType(),
@ -45,17 +77,17 @@ class PumpSyncImplementation @Inject constructor(
),
isBasalInsulin = false
)
disposable += repository.runTransactionForResult(SyncPumpBolusTransaction(bolus))
.subscribe(
{ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") }
},
{ aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
)
repository.runTransactionForResult(SyncPumpBolusTransaction(bolus, type?.toDBbBolusType()))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
.blockingGet()
.also { result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") }
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated carbs $it") }
return result.inserted.size > 0
}
}
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(
timestamp = timestamp,
amount = amount,
@ -65,11 +97,13 @@ class PumpSyncImplementation @Inject constructor(
pumpType = pumpType.toDbPumpType(),
pumpSerial = pumpSerial)
)
disposable += repository.runTransactionForResult(InsertIfNewByTimestampCarbsTransaction(carbs))
.subscribe(
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") } },
{ aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
)
repository.runTransactionForResult(InsertIfNewByTimestampCarbsTransaction(carbs))
.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 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;
import info.nightscout.androidaps.db.Treatment;
public class TreatmentUpdateReturn {
public TreatmentUpdateReturn(boolean success, boolean newRecord) {

View file

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

View file

@ -1,19 +1,17 @@
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.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.InsulinInterface
import info.nightscout.androidaps.utils.DateUtil
import org.json.JSONException
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
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
return insulinInterface.iobCalcForTreatment(this, time, dia)
}
@ -24,8 +22,48 @@ fun Bolus.toJson(): JSONObject =
.put("insulin", amount)
.put("created_at", DateUtil.toISOString(timestamp))
.put("date", timestamp)
.put("type", type.name)
.put("isValid", isValid)
.put("isSMB", type == Bolus.Type.SMB).also {
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId)
if (interfaceIDs.pumpType != null) it.put("pumpType", interfaceIDs.pumpType!!.name)
if (interfaceIDs.pumpSerial != null) it.put("pumpSerial", interfaceIDs.pumpSerial)
if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
}
/*
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,32 +1,11 @@
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.TherapyEvent
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
import kotlin.math.roundToInt
fun Carbs.expandCarbs(): List<Carbs> =
mutableListOf<Carbs>().also { carbs ->
if (this.duration == 0L) {
carbs.add(this)
} else {
var remainingCarbs = this.amount
val ticks = T.msecs(this.duration).mins() * 4 //duration guaranteed to be integer greater zero
for (i in 0 until ticks) {
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
remainingCarbs -= smallCarbAmount.toLong()
if (smallCarbAmount > 0)
carbs.add(Carbs(
timestamp = carbTime,
amount = smallCarbAmount.toDouble(),
duration = 0
))
}
}
}
fun Carbs.toJson(): JSONObject =
JSONObject()
@ -36,5 +15,43 @@ fun Carbs.toJson(): JSONObject =
.put("date", timestamp).also {
if (duration != 0L) it.put("duration", duration)
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)
}
/*
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 info.nightscout.androidaps.Constants
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.logging.AAPSLogger
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.utils.T
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -180,7 +180,7 @@ class DanaPump @Inject constructor(
var bolusStartErrorCode: Int = 0 // last start bolus erroCode
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 bolusProgressLastTimeStamp: Long = 0 // timestamp of last bolus progress message
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.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpSync;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
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.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.rx.AapsSchedulers;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -50,6 +52,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
private final ResourceHelper resourceHelper;
private final ConstraintChecker constraintChecker;
private final FabricPrivacy fabricPrivacy;
private final PumpSync pumpSync;
@Inject
public DanaRKoreanPlugin(
@ -65,6 +68,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
SP sp,
CommandQueueProvider commandQueue,
DateUtil dateUtil,
PumpSync pumpSync,
FabricPrivacy fabricPrivacy
) {
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.resourceHelper = resourceHelper;
this.constraintChecker = constraintChecker;
this.pumpSync = pumpSync;
this.fabricPrivacy = fabricPrivacy;
getPluginDescription().description(R.string.description_pump_dana_r_korean);
@ -163,23 +168,40 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment();
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
EventOverviewBolusProgress.Treatment treatment = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
boolean connectionOK = false;
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());
result.success(connectionOK && Math.abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.getBolusStep())
.bolusDelivered(t.insulin)
result.success(connectionOK && Math.abs(detailedBolusInfo.insulin - treatment.insulin) < pumpDescription.getBolusStep())
.bolusDelivered(treatment.insulin)
.carbsDelivered(detailedBolusInfo.carbs);
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
result.comment(R.string.ok);
aapsLogger.debug(LTag.PUMP, "deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.getBolusDelivered());
detailedBolusInfo.insulin = t.insulin;
detailedBolusInfo.insulin = treatment.insulin;
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;
} else {
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.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged;
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.configBuilder.ConstraintChecker;
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.pump.common.defs.PumpType;
import info.nightscout.androidaps.queue.commands.Command;
@ -254,7 +254,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
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 (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.PumpEnactResult;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
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.plugins.bus.RxBusWrapper;
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.defs.PumpType;
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
Treatment t = new Treatment();
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || carbs > 0)
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.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
@ -338,7 +337,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService {
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 (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.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
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.plugins.bus.RxBusWrapper;
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.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
@ -161,8 +161,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment();
t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB;
EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB);
boolean connectionOK = false;
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0)
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.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventBTChange;
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.LTag;
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.FabricPrivacy;
import info.nightscout.androidaps.utils.ToastUtils;
@ -95,7 +95,7 @@ public abstract class AbstractDanaRExecutionService extends DaggerService {
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

View file

@ -45,7 +45,6 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended;
import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.dialogs.BolusProgressDialog;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
@ -263,7 +262,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService {
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 (BolusProgressDialog.stopPressed) return false;

View file

@ -1,10 +1,8 @@
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.comm.MsgBolusProgress
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -17,7 +15,7 @@ class MsgBolusProgressTest : DanaRTestBase() {
@Test fun runTest() {
`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
val packet = MsgBolusProgress(injector)

View file

@ -1,10 +1,8 @@
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.comm.MsgBolusStop
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -16,7 +14,7 @@ class MsgBolusStopTest : DanaRTestBase() {
@Test fun runTest() {
`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)
// 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.Constraint
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert
@ -30,6 +31,7 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var sp: SP
@Mock lateinit var commandQueue: CommandQueueProvider
@Mock lateinit var pumpSync: PumpSync
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.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
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)

View file

@ -15,7 +15,6 @@ import info.nightscout.androidaps.danars.services.DanaRSService
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventConfigBuilderChange
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.general.overview.events.EventDismissNotification
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.pump.common.bolusInfo.DetailedBolusInfoStorage
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
detailedBolusInfo.carbTime = 0
detailedBolusInfoStorage.add(detailedBolusInfo) // will be picked up on reading history
val t = Treatment()
t.isSMB = detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB
val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB);
var connectionOK = false
if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t)
?: false

View file

@ -124,26 +124,26 @@ open class DanaRS_Packet_APS_History_Events(
DanaPump.BOLUS -> {
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0)
?: DetailedBolusInfo()
detailedBolusInfo.bolusTimestamp = datetime
detailedBolusInfo.pumpType = PumpType.DANA_RS
detailedBolusInfo.pumpSerial = danaPump.serialNumber
detailedBolusInfo.bolusPumpId = pumpId
detailedBolusInfo.insulin = param1 / 100.0
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = datetime,
amount = param1 / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = pumpId,
pumpType = PumpType.DANA_RS,
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")
status = "BOLUS " + dateUtil.timeString(datetime)
}
DanaPump.DUALBOLUS -> {
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0)
?: DetailedBolusInfo()
detailedBolusInfo.bolusTimestamp = datetime
detailedBolusInfo.pumpType = PumpType.DANA_RS
detailedBolusInfo.pumpSerial = danaPump.serialNumber
detailedBolusInfo.bolusPumpId = pumpId
detailedBolusInfo.insulin = param1 / 100.0
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
val newRecord = pumpSync.syncBolusWithPumpId(
timestamp = datetime,
amount = param1 / 100.0,
type = detailedBolusInfo?.bolusType,
pumpId = pumpId,
pumpType = PumpType.DANA_RS,
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")
status = "DUALBOLUS " + dateUtil.timeString(datetime)
}
@ -196,13 +196,12 @@ open class DanaRS_Packet_APS_History_Events(
}
DanaPump.CARBS -> {
val emptyCarbsInfo = DetailedBolusInfo()
emptyCarbsInfo.carbs = param1.toDouble()
emptyCarbsInfo.carbsTimestamp = datetime
emptyCarbsInfo.pumpType = PumpType.DANA_RS
emptyCarbsInfo.pumpSerial = danaPump.serialNumber
emptyCarbsInfo.carbsPumpId = pumpId
val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false)
val newRecord = pumpSync.syncCarbsWithTimestamp(
timestamp = datetime,
amount = param1.toDouble(),
pumpId = pumpId,
pumpType = PumpType.DANA_RS,
pumpSerial = danaPump.serialNumber)
aapsLogger.debug(LTag.PUMPCOMM, "[" + id + "] " + (if (newRecord) "**NEW** " else "") + "EVENT CARBS (" + recordCode + ") " + dateUtil.dateAndTimeString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g")
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.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.dialogs.BolusProgressDialog
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventInitializationChanged
@ -247,7 +246,7 @@ class DanaRSService : DaggerService() {
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 (BolusProgressDialog.stopPressed) return false
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.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -43,7 +44,7 @@ class DanaRSPacketNotifyDeliveryCompleteTest : DanaRSTestBase() {
@Test fun runTest() {
`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)
// test params
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.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
@ -42,7 +43,7 @@ class DanaRsPacketBolusSetStepBolusStopTest : DanaRSTestBase() {
@Test fun runTest() {
`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)
// test message decoding
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.plugins.bus.RxBusWrapper
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 org.junit.Assert
import org.junit.Before
@ -69,6 +70,6 @@ class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() {
@Before
fun mock() {
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,
"database": {
"version": 8,
"identityHash": "2e4a472793f7dd21528ddcb540500f1b",
"identityHash": "dab6024e846ee68708e8cfc047c39662",
"entities": [
{
"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": [
{
"fieldPath": "id",
@ -128,6 +128,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -187,7 +193,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -273,6 +279,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -350,7 +362,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -592,6 +604,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -651,7 +669,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -731,6 +749,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -790,7 +814,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -870,6 +894,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -929,7 +959,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1015,6 +1045,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1074,7 +1110,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1172,6 +1208,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1231,7 +1273,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1353,6 +1395,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1430,7 +1478,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1522,6 +1570,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1581,7 +1635,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1673,6 +1727,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1732,7 +1792,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1842,6 +1902,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -1901,7 +1967,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -1987,6 +2053,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -2046,7 +2118,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -2120,6 +2192,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -2228,7 +2306,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -2296,6 +2374,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -2535,7 +2619,7 @@
},
{
"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": [
{
"fieldPath": "id",
@ -2651,6 +2735,12 @@
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.temporaryId",
"columnName": "temporaryId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "interfaceIDs_backing.pumpId",
"columnName": "pumpId",
@ -2704,7 +2794,7 @@
"views": [],
"setupQueries": [
"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')"
]
}
}

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.database
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.*
import info.nightscout.androidaps.database.interfaces.DBEntry
import info.nightscout.androidaps.database.transactions.Transaction
@ -13,6 +12,7 @@ import io.reactivex.subjects.PublishSubject
import java.util.concurrent.Callable
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.roundToInt
@Singleton
open class AppRepository @Inject internal constructor(
@ -263,7 +263,7 @@ open class AppRepository @Inject internal constructor(
* It is a Maybe as there might be no next element.
* */
fun getNextSyncElementBolus(id: Long): Maybe<Pair<Bolus, Long>> =
database.bolusDao.getNextModifiedOrNewAfter(id)
database.bolusDao.getNextModifiedOrNewAfterExclude(id, Bolus.Type.PRIMING)
.flatMap { nextIdElement ->
val nextIdElemReferenceId = nextIdElement.referenceId
if (nextIdElemReferenceId == null) {
@ -278,8 +278,11 @@ open class AppRepository @Inject internal constructor(
database.bolusDao.getModifiedFrom(lastId)
.subscribeOn(Schedulers.io())
fun findBolusByPumpIds(pumpId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): Bolus? =
database.bolusDao.findByPumpIds(pumpId, pumpType, pumpSerial)
fun getLastBolusRecord(): Bolus? =
database.bolusDao.getLastBolusRecord()
fun getLastBolusRecordOfType(type: Bolus.Type): Bolus? =
database.bolusDao.getLastBolusRecordOfType(type)
fun getOldestBolusRecord(): Bolus? =
database.bolusDao.getOldestBolusRecord()
@ -308,6 +311,27 @@ open class AppRepository @Inject internal constructor(
database.bolusDao.deleteAllEntries()
// CARBS
val timeBackForExpand = 8 * 60 * 60 * 1000
private fun expandCarbs(carbs: Carbs): List<Carbs> =
if (carbs.duration == 0L) {
listOf(carbs)
} else {
var remainingCarbs = carbs.amount
val ticks = (carbs.duration / 1000 / 60 / 15).coerceAtLeast(1L)
(0 until ticks).map {
val carbTime = carbs.timestamp + it * 15 * 60 * 1000
val smallCarbAmount = (1.0 * remainingCarbs / (ticks - it)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs
remainingCarbs -= smallCarbAmount.toLong()
Carbs(timestamp = carbTime, amount = smallCarbAmount.toDouble(), duration = 0)
}.filter { it.amount != 0.0 }
}
private fun Single<List<Carbs>>.expand() = this.map { it.map(::expandCarbs).flatten() }
private fun Single<List<Carbs>>.filterOutExtended() = this.map { it.filter { c -> c.duration == 0L } }
private fun Single<List<Carbs>>.fromTo(from: Long, to: Long) = this.map { it.filter { c -> c.timestamp in from..to } }
private fun Single<List<Carbs>>.sort() = this.map { it.sortedBy { c -> c.timestamp } }
/*
* returns a Pair of the next entity to sync and the ID of the "update".
* The update id might either be the entry id itself if it is a new entry - or the id
@ -334,6 +358,14 @@ open class AppRepository @Inject internal constructor(
fun getCarbsByTimestamp(timestamp: Long): Carbs? =
database.carbsDao.findByTimestamp(timestamp)
fun getLastCarbsRecord(): Carbs? =
database.carbsDao.getLastCarbsRecord()
fun getLastCarbsRecordWrapped(): Single<ValueWrapper<Carbs>> =
database.carbsDao.getLastCarbsRecordMaybe()
.subscribeOn(Schedulers.io())
.toWrappedSingle()
fun getOldestCarbsRecord(): Carbs? =
database.carbsDao.getOldestCarbsRecord()
@ -342,18 +374,35 @@ open class AppRepository @Inject internal constructor(
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getCarbsDataFromTimeExpanded(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsFromTime(timestamp - timeBackForExpand)
.expand()
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getCarbsDataFromTimeToTime(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsFromTimeToTime(from, to)
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getCarbsIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsIncludingInvalidFromTime(timestamp)
fun getCarbsDataFromTimeToTimeExpanded(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsFromTimeToTime(from - timeBackForExpand, to)
.expand()
.fromTo(from, to)
.sort()
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getCarbsIncludingInvalidFromTimeToTime(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsIncludingInvalidFromTimeToTime(from, to)
fun getCarbsIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsIncludingInvalidFromTime(timestamp - timeBackForExpand)
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getCarbsIncludingInvalidFromTimeToTimeExpanded(from: Long, to: Long, ascending: Boolean): Single<List<Carbs>> =
database.carbsDao.getCarbsIncludingInvalidFromTimeToTime(from - timeBackForExpand, to)
.expand()
.fromTo(from, to)
.sort()
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())

View file

@ -18,11 +18,26 @@ internal interface BolusDao : TraceableDao<Bolus> {
@Query("DELETE FROM $TABLE_BOLUSES")
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")
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")
fun getOldestBolusRecord(): Bolus?
@Query("SELECT * FROM $TABLE_BOLUSES WHERE temporaryId = :temporaryId AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL")
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")
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>>
// 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")
fun getModifiedFrom(id: Long): Single<List<Bolus>>
@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, exclude: Bolus.Type = Bolus.Type.PRIMING): Single<List<Bolus>>
// for WS we need 1 record only
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id ORDER BY id ASC limit 1")
fun getNextModifiedOrNewAfter(id: Long): Maybe<Bolus>
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id > :id AND type <> :exclude ORDER BY id ASC limit 1")
fun getNextModifiedOrNewAfterExclude(id: Long, exclude: Bolus.Type = Bolus.Type.PRIMING): Maybe<Bolus>
@Query("SELECT * FROM $TABLE_BOLUSES WHERE id = :referenceId")
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.Query
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.TherapyEvent
import io.reactivex.Maybe
import io.reactivex.Single
@ -20,9 +17,18 @@ internal interface CarbsDao : TraceableDao<Carbs> {
@Query("DELETE FROM $TABLE_CARBS")
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")
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 DESC LIMIT 1")
fun getLastCarbsRecordMaybe(): Maybe<Carbs>
@Query("SELECT * FROM $TABLE_CARBS WHERE isValid = 1 AND referenceId IS NULL ORDER BY id ASC LIMIT 1")
fun getOldestCarbsRecord(): Carbs?

View file

@ -1,10 +1,13 @@
package info.nightscout.androidaps.database.embedments
import info.nightscout.androidaps.database.entities.TherapyEvent
data class InterfaceIDs(
var nightscoutSystemId: String? = null,
var nightscoutId: String? = null,
var pumpType: PumpType? = null, // if == USER pumpSerial & pumpId can be 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 startId: Long? = null,
var endId: Long? = null
@ -40,6 +43,11 @@ data class InterfaceIDs(
TANDEM_T_SLIM_X2,
YPSOPUMP,
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 {
NORMAL,
SMB,
PRIMING
PRIMING;
companion object {
fun fromString(name: String?) = values().firstOrNull { it.name == name } ?: NORMAL
}
}
}

Some files were not shown because too many files have changed in this diff Show more