Merge branch '0pen-dash-dash-history' into dev
This commit is contained in:
commit
7365986286
27 changed files with 545 additions and 86 deletions
|
@ -1,36 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.definition;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public enum OmnipodCommandType {
|
||||
INITIALIZE_POD(R.string.omnipod_common_cmd_initialize_pod), // First step of Pod activation
|
||||
INSERT_CANNULA(R.string.omnipod_common_cmd_insert_cannula), // Second step of Pod activation
|
||||
DEACTIVATE_POD(R.string.omnipod_common_cmd_deactivate_pod), //
|
||||
SET_BASAL_PROFILE(R.string.omnipod_common_cmd_set_basal_schedule), //
|
||||
SET_BOLUS(R.string.omnipod_common_cmd_set_bolus), //
|
||||
CANCEL_BOLUS(R.string.omnipod_common_cmd_cancel_bolus), //
|
||||
SET_TEMPORARY_BASAL(R.string.omnipod_common_cmd_set_tbr), //
|
||||
CANCEL_TEMPORARY_BASAL(R.string.omnipod_common_cmd_cancel_tbr_by_driver), //
|
||||
DISCARD_POD(R.string.omnipod_common_cmd_discard_pod), //
|
||||
GET_POD_STATUS(R.string.omnipod_common_cmd_get_pod_status), //
|
||||
SET_TIME(R.string.omnipod_common_cmd_set_time), //
|
||||
CONFIGURE_ALERTS(R.string.omnipod_common_cmd_configure_alerts), //
|
||||
ACKNOWLEDGE_ALERTS(R.string.omnipod_common_cmd_silence_alerts), //
|
||||
READ_POD_PULSE_LOG(R.string.omnipod_common_cmd_read_pulse_log), //
|
||||
SUSPEND_DELIVERY(R.string.omnipod_common_cmd_suspend_delivery),
|
||||
RESUME_DELIVERY(R.string.omnipod_common_cmd_resume_delivery),
|
||||
PLAY_TEST_BEEP(R.string.omnipod_common_cmd_play_test_beep);
|
||||
|
||||
private final int resourceId;
|
||||
|
||||
OmnipodCommandType(int resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public int getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.common.definition
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.R
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
enum class OmnipodCommandType(val resourceId: Int) {
|
||||
|
||||
INITIALIZE_POD(R.string.omnipod_common_cmd_initialize_pod), // First step of Pod activation
|
||||
INSERT_CANNULA(R.string.omnipod_common_cmd_insert_cannula), // Second step of Pod activation
|
||||
DEACTIVATE_POD(R.string.omnipod_common_cmd_deactivate_pod), //
|
||||
SET_BASAL_PROFILE(R.string.omnipod_common_cmd_set_basal_schedule), //
|
||||
SET_BOLUS(R.string.omnipod_common_cmd_set_bolus), //
|
||||
CANCEL_BOLUS(R.string.omnipod_common_cmd_cancel_bolus), //
|
||||
SET_TEMPORARY_BASAL(R.string.omnipod_common_cmd_set_tbr), //
|
||||
CANCEL_TEMPORARY_BASAL(R.string.omnipod_common_cmd_cancel_tbr_by_driver), //
|
||||
DISCARD_POD(R.string.omnipod_common_cmd_discard_pod), //
|
||||
GET_POD_STATUS(R.string.omnipod_common_cmd_get_pod_status), //
|
||||
SET_TIME(R.string.omnipod_common_cmd_set_time), //
|
||||
CONFIGURE_ALERTS(R.string.omnipod_common_cmd_configure_alerts), //
|
||||
ACKNOWLEDGE_ALERTS(R.string.omnipod_common_cmd_silence_alerts), //
|
||||
READ_POD_PULSE_LOG(R.string.omnipod_common_cmd_read_pulse_log), //
|
||||
SUSPEND_DELIVERY(R.string.omnipod_common_cmd_suspend_delivery), RESUME_DELIVERY(R.string.omnipod_common_cmd_resume_delivery), PLAY_TEST_BEEP(R.string.omnipod_common_cmd_play_test_beep);
|
||||
|
||||
}
|
|
@ -22,10 +22,12 @@ detekt { // TODO move to `subprojects` section in global build.gradle
|
|||
|
||||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':pump-common')
|
||||
implementation project(':omnipod-common')
|
||||
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
implementation "androidx.room:room-rxjava2:$room_version"
|
||||
implementation project(path: ':pump-common')
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation 'com.github.guepardoapps:kulid:2.0.0.0'
|
||||
}
|
||||
|
|
|
@ -11,5 +11,6 @@
|
|||
<activity android:name=".ui.wizard.activation.DashPodActivationWizardActivity" />
|
||||
<activity android:name=".ui.wizard.deactivation.DashPodDeactivationWizardActivity" />
|
||||
<activity android:name=".ui.DashPodManagementActivity" />
|
||||
<activity android:name=".ui.DashPodHistoryActivity" />
|
||||
</application>
|
||||
</manifest>
|
|
@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmed
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BasalValuesRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
|
||||
|
@ -363,8 +364,12 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
return PumpEnactResult(injector).success(true).enacted(true)
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMP, "setNewBasalProfile profile=$profile")
|
||||
val basalProgram = mapProfileToBasalProgram(profile)
|
||||
return setNewBasalProfile(profile, OmnipodCommandType.SET_BASAL_PROFILE)
|
||||
}
|
||||
|
||||
private fun setNewBasalProfile(profile: Profile, historyType: OmnipodCommandType): PumpEnactResult {
|
||||
var deliverySuspended = false
|
||||
val basalProgram = mapProfileToBasalProgram(profile)
|
||||
return executeProgrammingCommand(
|
||||
pre = suspendDeliveryIfActive().doOnComplete {
|
||||
if (podStateManager.activeCommand == null) {
|
||||
|
@ -372,7 +377,10 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
deliverySuspended = true
|
||||
}
|
||||
},
|
||||
historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE),
|
||||
historyEntry = history.createRecord(
|
||||
commandType = historyType,
|
||||
basalProfileRecord = BasalValuesRecord(profile.getBasalValues().toList())
|
||||
),
|
||||
activeCommandEntry = { historyId ->
|
||||
podStateManager.createActiveCommand(historyId, basalProgram = basalProgram)
|
||||
},
|
||||
|
@ -1139,7 +1147,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
return profileFunction.getProfile()?.let {
|
||||
executeProgrammingCommand(
|
||||
pre = observeDeliverySuspended(),
|
||||
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY),
|
||||
historyEntry = history.createRecord(OmnipodCommandType.RESUME_DELIVERY, basalProfileRecord = BasalValuesRecord(it.getBasalValues().toList())),
|
||||
command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(it), hasBasalBeepEnabled())
|
||||
.ignoreElements()
|
||||
).doFinally {
|
||||
|
@ -1153,16 +1161,20 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
private fun deactivatePod(): PumpEnactResult {
|
||||
var success = true
|
||||
val ret = executeProgrammingCommand(
|
||||
historyEntry = history.createRecord(OmnipodCommandType.DEACTIVATE_POD),
|
||||
command = omnipodManager.deactivatePod().ignoreElements(),
|
||||
checkNoActiveCommand = false,
|
||||
post = createFakeTBRWhenNoActivePod(),
|
||||
).doOnComplete {
|
||||
if (podStateManager.activeCommand != null) {
|
||||
success = false
|
||||
}
|
||||
podStateManager.reset()
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_FAULT))
|
||||
}.toPumpEnactResult()
|
||||
|
||||
if (podStateManager.activeCommand != null) {
|
||||
if (!success) {
|
||||
ret.success(false)
|
||||
}
|
||||
return ret
|
||||
|
@ -1170,7 +1182,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
|
||||
private fun handleTimeChange(): PumpEnactResult {
|
||||
return profileFunction.getProfile()?.let {
|
||||
setNewBasalProfile(it)
|
||||
setNewBasalProfile(it, OmnipodCommandType.SET_TIME)
|
||||
} ?: PumpEnactResult(injector).success(true).enacted(false).comment("No profile active")
|
||||
}
|
||||
|
||||
|
@ -1181,7 +1193,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
|
|||
val lowReservoirAlertEnabled = sp.getBoolean(R.string.key_omnipod_common_low_reservoir_alert_enabled, true)
|
||||
val lowReservoirAlertUnits = sp.getInt(R.string.key_omnipod_common_low_reservoir_alert_units, 10)
|
||||
|
||||
if (!podStateManager.differentAlertSettings(
|
||||
if (podStateManager.sameAlertSettings(
|
||||
expirationReminderEnabled,
|
||||
expirationHours,
|
||||
lowReservoirAlertEnabled,
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodD
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManagerImpl
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManagerImpl
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.DashPodHistoryActivity
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.DashPodManagementActivity
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activation.DashPodActivationWizardActivity
|
||||
|
@ -21,6 +22,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.deactivati
|
|||
abstract class OmnipodDashModule {
|
||||
// ACTIVITIES
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesDashPodHistoryActivity(): DashPodHistoryActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesDashPodManagementActivity(): DashPodManagementActivity
|
||||
|
||||
|
|
|
@ -641,7 +641,6 @@ class OmnipodDashManagerImpl @Inject constructor(
|
|||
observeConnectToPod,
|
||||
observeSendDeactivateCommand
|
||||
).interceptPodEvents()
|
||||
.doOnComplete(podStateManager::reset)
|
||||
}
|
||||
|
||||
inner class PodEventInterceptor : Consumer<PodEvent> {
|
||||
|
|
|
@ -105,7 +105,7 @@ interface OmnipodDashPodStateManager {
|
|||
- after getPodStatus was successful(we have an up-to-date podStatus)
|
||||
*/
|
||||
fun recoverActivationFromPodStatus(): String?
|
||||
fun differentAlertSettings(expirationReminderEnabled: Boolean, expirationHours: Int, lowReservoirAlertEnabled: Boolean, lowReservoirAlertUnits: Int): Boolean
|
||||
fun sameAlertSettings(expirationReminderEnabled: Boolean, expirationHours: Int, lowReservoirAlertEnabled: Boolean, lowReservoirAlertUnits: Int): Boolean
|
||||
fun updateExpirationAlertSettings(expirationReminderEnabled: Boolean, expirationHours: Int): Completable
|
||||
fun updateLowReservoirAlertSettings(lowReservoirAlertEnabled: Boolean, lowReservoirAlertUnits: Int): Completable
|
||||
|
||||
|
|
|
@ -435,7 +435,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun differentAlertSettings(
|
||||
override fun sameAlertSettings(
|
||||
expirationReminderEnabled: Boolean,
|
||||
expirationHours: Int,
|
||||
lowReservoirAlertEnabled: Boolean,
|
||||
|
|
|
@ -7,11 +7,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.Omnipod
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType.SET_BOLUS
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType.SET_TEMPORARY_BASAL
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.*
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.HistoryRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.*
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordDao
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordEntity
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper.HistoryMapper
|
||||
|
@ -40,19 +36,18 @@ class DashHistory @Inject constructor(
|
|||
|
||||
fun getById(id: String): HistoryRecord {
|
||||
val entry = dao.byIdBlocking(id)
|
||||
if (entry == null) {
|
||||
throw java.lang.IllegalArgumentException("history entry [$id] not found")
|
||||
}
|
||||
?: throw java.lang.IllegalArgumentException("history entry [$id] not found")
|
||||
return historyMapper.entityToDomain(entry)
|
||||
}
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
fun createRecord(
|
||||
commandType: OmnipodCommandType,
|
||||
date: Long = System.currentTimeMillis(),
|
||||
date: Long = currentTimeMillis(),
|
||||
initialResult: InitialResult = InitialResult.NOT_SENT,
|
||||
tempBasalRecord: TempBasalRecord? = null,
|
||||
bolusRecord: BolusRecord? = null,
|
||||
basalProfileRecord: BasalValuesRecord? = null,
|
||||
resolveResult: ResolvedResult? = null,
|
||||
resolvedAt: Long? = null
|
||||
): Single<String> = Single.defer {
|
||||
|
@ -72,6 +67,7 @@ class DashHistory @Inject constructor(
|
|||
commandType = commandType,
|
||||
tempBasalRecord = tempBasalRecord,
|
||||
bolusRecord = bolusRecord,
|
||||
basalProfileRecord = basalProfileRecord,
|
||||
initialResult = initialResult,
|
||||
resolvedResult = resolveResult,
|
||||
resolvedAt = resolvedAt
|
||||
|
@ -83,7 +79,8 @@ class DashHistory @Inject constructor(
|
|||
fun getRecords(): Single<List<HistoryRecord>> =
|
||||
dao.all().map { list -> list.map(historyMapper::entityToDomain) }
|
||||
|
||||
fun getRecordsAfter(time: Long): Single<List<HistoryRecordEntity>> = dao.allSince(time)
|
||||
fun getRecordsAfter(time: Long): Single<List<HistoryRecord>> =
|
||||
dao.allSince(time).map { list -> list.map(historyMapper::entityToDomain) }
|
||||
|
||||
fun updateFromState(podState: OmnipodDashPodStateManager) = Completable.defer {
|
||||
val historyId = podState.activeCommand?.historyId
|
||||
|
|
|
@ -18,4 +18,12 @@ data class HistoryRecord(
|
|||
val entropy = ULID.getEntropy(id)
|
||||
return ByteBuffer.wrap(entropy).long
|
||||
}
|
||||
|
||||
fun displayTimestamp(): Long {
|
||||
return date
|
||||
}
|
||||
|
||||
fun isSuccess(): Boolean {
|
||||
return initialResult == InitialResult.SENT && resolvedResult == ResolvedResult.SUCCESS
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
|
||||
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
|
||||
sealed class Record
|
||||
|
||||
|
@ -8,6 +9,8 @@ data class BolusRecord(val amout: Double, val bolusType: BolusType) : Record()
|
|||
|
||||
data class TempBasalRecord(val duration: Int, val rate: Double) : Record()
|
||||
|
||||
data class BasalValuesRecord(val segments: List<Profile.ProfileValue>) : Record()
|
||||
|
||||
enum class BolusType {
|
||||
DEFAULT, SMB;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
|
||||
|
||||
enum class InitialResult {
|
||||
NOT_SENT, FAILURE_SENDING, UNCONFIRMED, SENT
|
||||
NOT_SENT, FAILURE_SENDING, SENT
|
||||
}
|
||||
|
||||
enum class ResolvedResult {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import com.google.gson.GsonBuilder
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
|
||||
|
@ -31,4 +33,17 @@ class Converters {
|
|||
|
||||
@TypeConverter
|
||||
fun fromOmnipodCommandType(omnipodCommandType: OmnipodCommandType) = omnipodCommandType.name
|
||||
|
||||
@TypeConverter
|
||||
fun toSegments(s: String?): List<Profile.ProfileValue> {
|
||||
s ?: return emptyList()
|
||||
val gson = GsonBuilder().create()
|
||||
return gson.fromJson(s, Array<Profile.ProfileValue>::class.java).toList()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromBasalValues(segments: List<Profile.ProfileValue>): String {
|
||||
val gson = GsonBuilder().create()
|
||||
return gson.toJson(segments)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@ abstract class DashHistoryDatabase : RoomDatabase() {
|
|||
|
||||
companion object {
|
||||
|
||||
const val VERSION = 1
|
||||
const val VERSION = 2
|
||||
|
||||
fun build(context: Context) =
|
||||
Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
DashHistoryDatabase::class.java,
|
||||
"omnipod_dash_history_database.db"
|
||||
"omnipod_dash_history_database.db",
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
|
|
|
@ -19,7 +19,7 @@ abstract class HistoryRecordDao {
|
|||
@Query("SELECT * from historyrecords")
|
||||
abstract fun allBlocking(): List<HistoryRecordEntity>
|
||||
|
||||
@Query("SELECT * from historyrecords WHERE createdAt >= :since")
|
||||
@Query("SELECT * from historyrecords WHERE createdAt >= :since ORDER BY createdAt DESC")
|
||||
abstract fun allSince(since: Long): Single<List<HistoryRecordEntity>>
|
||||
|
||||
@Query("SELECT * FROM historyrecords WHERE id = :id LIMIT 1")
|
||||
|
|
|
@ -4,6 +4,7 @@ import androidx.room.Embedded
|
|||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BasalValuesRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
|
||||
|
@ -18,6 +19,7 @@ data class HistoryRecordEntity(
|
|||
val initialResult: InitialResult,
|
||||
@Embedded(prefix = "tempBasalRecord_") val tempBasalRecord: TempBasalRecord?,
|
||||
@Embedded(prefix = "bolusRecord_") val bolusRecord: BolusRecord?,
|
||||
@Embedded(prefix = "basalprofile_") val basalProfileRecord: BasalValuesRecord?,
|
||||
val resolvedResult: ResolvedResult?,
|
||||
val resolvedAt: Long?
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BasalValuesRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.HistoryRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
|
||||
|
@ -17,7 +18,8 @@ class HistoryMapper {
|
|||
tempBasalRecord = historyRecord.record as? TempBasalRecord,
|
||||
bolusRecord = historyRecord.record as? BolusRecord,
|
||||
resolvedResult = historyRecord.resolvedResult,
|
||||
resolvedAt = historyRecord.resolvedAt
|
||||
resolvedAt = historyRecord.resolvedAt,
|
||||
basalProfileRecord = historyRecord.record as? BasalValuesRecord
|
||||
)
|
||||
|
||||
fun entityToDomain(entity: HistoryRecordEntity): HistoryRecord =
|
||||
|
@ -27,7 +29,7 @@ class HistoryMapper {
|
|||
date = entity.date,
|
||||
initialResult = entity.initialResult,
|
||||
commandType = entity.commandType,
|
||||
record = entity.bolusRecord ?: entity.tempBasalRecord,
|
||||
record = entity.bolusRecord ?: entity.tempBasalRecord ?: entity.basalProfileRecord,
|
||||
resolvedResult = entity.resolvedResult,
|
||||
resolvedAt = entity.resolvedAt
|
||||
)
|
||||
|
|
|
@ -0,0 +1,279 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui
|
||||
// import info.nightscout.androidaps.plugins.pump.omnipod.dash.definition.PodHistoryEntryType;
|
||||
// import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.AapsOmnipodUtil;
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.*
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class DashPodHistoryActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var dashHistory: DashHistory
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
|
||||
private var historyTypeSpinner: Spinner? = null
|
||||
private var statusView: TextView? = null
|
||||
private var recyclerView: RecyclerView? = null
|
||||
private var linearLayoutManager: LinearLayoutManager? = null
|
||||
private val fullHistoryList: MutableList<HistoryRecord> = ArrayList<HistoryRecord>()
|
||||
private val filteredHistoryList: MutableList<HistoryRecord> = ArrayList<HistoryRecord>()
|
||||
private var recyclerViewAdapter: RecyclerViewAdapter? = null
|
||||
private var manualChange = false
|
||||
private var typeListFull: List<TypeList>? = null
|
||||
|
||||
private fun prepareData() {
|
||||
val gc = GregorianCalendar()
|
||||
gc.add(Calendar.DAY_OF_MONTH, -DAYS_TO_DISPLAY)
|
||||
|
||||
val since = gc.timeInMillis
|
||||
val records = dashHistory.getRecordsAfter(since)
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.blockingGet()
|
||||
fullHistoryList.addAll(records)
|
||||
}
|
||||
|
||||
private fun groupForCommandType(type: OmnipodCommandType): PumpHistoryEntryGroup {
|
||||
return when (type) {
|
||||
OmnipodCommandType.INITIALIZE_POD ->
|
||||
PumpHistoryEntryGroup.Prime
|
||||
OmnipodCommandType.INSERT_CANNULA ->
|
||||
PumpHistoryEntryGroup.Prime
|
||||
OmnipodCommandType.DEACTIVATE_POD ->
|
||||
PumpHistoryEntryGroup.Prime
|
||||
OmnipodCommandType.DISCARD_POD ->
|
||||
PumpHistoryEntryGroup.Prime
|
||||
|
||||
OmnipodCommandType.CANCEL_TEMPORARY_BASAL ->
|
||||
PumpHistoryEntryGroup.Basal
|
||||
OmnipodCommandType.SET_BASAL_PROFILE ->
|
||||
PumpHistoryEntryGroup.Basal
|
||||
OmnipodCommandType.SET_TEMPORARY_BASAL ->
|
||||
PumpHistoryEntryGroup.Basal
|
||||
OmnipodCommandType.RESUME_DELIVERY ->
|
||||
PumpHistoryEntryGroup.Basal
|
||||
OmnipodCommandType.SUSPEND_DELIVERY ->
|
||||
PumpHistoryEntryGroup.Basal
|
||||
|
||||
OmnipodCommandType.SET_BOLUS ->
|
||||
PumpHistoryEntryGroup.Bolus
|
||||
OmnipodCommandType.CANCEL_BOLUS ->
|
||||
PumpHistoryEntryGroup.Bolus
|
||||
|
||||
OmnipodCommandType.ACKNOWLEDGE_ALERTS ->
|
||||
PumpHistoryEntryGroup.Alarm
|
||||
OmnipodCommandType.CONFIGURE_ALERTS ->
|
||||
PumpHistoryEntryGroup.Alarm
|
||||
OmnipodCommandType.PLAY_TEST_BEEP ->
|
||||
PumpHistoryEntryGroup.Alarm
|
||||
|
||||
OmnipodCommandType.GET_POD_STATUS ->
|
||||
PumpHistoryEntryGroup.Configuration
|
||||
OmnipodCommandType.SET_TIME ->
|
||||
PumpHistoryEntryGroup.Configuration
|
||||
|
||||
OmnipodCommandType.READ_POD_PULSE_LOG ->
|
||||
PumpHistoryEntryGroup.Unknown
|
||||
}
|
||||
}
|
||||
private fun filterHistory(group: PumpHistoryEntryGroup) {
|
||||
filteredHistoryList.clear()
|
||||
aapsLogger.debug(LTag.PUMP, "Items on full list: {}", fullHistoryList.size)
|
||||
if (group === PumpHistoryEntryGroup.All) {
|
||||
filteredHistoryList.addAll(fullHistoryList)
|
||||
} else {
|
||||
filteredHistoryList.addAll(fullHistoryList.filter { groupForCommandType(it.commandType) == group })
|
||||
}
|
||||
recyclerViewAdapter?.let {
|
||||
it.historyList = filteredHistoryList
|
||||
it.notifyDataSetChanged()
|
||||
}
|
||||
aapsLogger.debug(LTag.PUMP, "Items on filtered list: {}", filteredHistoryList.size)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
filterHistory(selectedGroup)
|
||||
setHistoryTypeSpinner()
|
||||
}
|
||||
|
||||
private fun setHistoryTypeSpinner() {
|
||||
manualChange = true
|
||||
val typeList = typeListFull
|
||||
typeList?.let {
|
||||
for (i in it.indices) {
|
||||
if (it[i].entryGroup === selectedGroup) {
|
||||
historyTypeSpinner!!.setSelection(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
SystemClock.sleep(200)
|
||||
manualChange = false
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.omnipod_dash_pod_history_activity)
|
||||
prepareData()
|
||||
|
||||
recyclerView = findViewById(R.id.omnipod_history_recyclerview)
|
||||
recyclerViewAdapter = RecyclerViewAdapter(filteredHistoryList)
|
||||
linearLayoutManager = LinearLayoutManager(this)
|
||||
recyclerView?.run {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = linearLayoutManager
|
||||
adapter = recyclerViewAdapter
|
||||
}
|
||||
|
||||
statusView = findViewById(R.id.omnipod_historystatus)
|
||||
statusView?.run { visibility = View.GONE }
|
||||
|
||||
historyTypeSpinner = findViewById(R.id.omnipod_historytype)
|
||||
typeListFull = getTypeList(PumpHistoryEntryGroup.Companion.getTranslatedList(resourceHelper))
|
||||
val spinnerAdapter: ArrayAdapter<TypeList> = ArrayAdapter<TypeList>(this, R.layout.spinner_centered, typeListFull!!)
|
||||
historyTypeSpinner?.run {
|
||||
adapter = spinnerAdapter
|
||||
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
if (manualChange) return
|
||||
val selected = selectedItem as TypeList
|
||||
selectedGroup = selected.entryGroup
|
||||
filterHistory(selectedGroup)
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
if (manualChange) return
|
||||
filterHistory(PumpHistoryEntryGroup.All)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTypeList(list: List<PumpHistoryEntryGroup>): List<TypeList> {
|
||||
val typeList = ArrayList<TypeList>()
|
||||
for (pumpHistoryEntryGroup in list) {
|
||||
typeList.add(TypeList(pumpHistoryEntryGroup))
|
||||
}
|
||||
return typeList
|
||||
}
|
||||
|
||||
internal class TypeList(entryGroup: PumpHistoryEntryGroup) {
|
||||
|
||||
val entryGroup: PumpHistoryEntryGroup = entryGroup
|
||||
val name: String = entryGroup.translated ?: "XXX TODO"
|
||||
|
||||
override fun toString(): String {
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(historyList: List<HistoryRecord>) : RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder>() {
|
||||
|
||||
var historyList: List<HistoryRecord> = historyList
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): HistoryViewHolder {
|
||||
val v: View = LayoutInflater.from(viewGroup.context).inflate(
|
||||
R.layout.omnipod_dash_pod_history_item,
|
||||
viewGroup, false
|
||||
)
|
||||
return HistoryViewHolder(v)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) {
|
||||
val record: HistoryRecord = historyList[position]
|
||||
record?.let {
|
||||
holder.timeView.text = DateTimeUtil.toStringFromTimeInMillis(it.displayTimestamp())
|
||||
setValue(it, holder.valueView)
|
||||
setType(it, holder.typeView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setType(record: HistoryRecord, typeView: TextView) {
|
||||
typeView.text = resourceHelper.gs(record.commandType.resourceId)
|
||||
}
|
||||
|
||||
private fun setValue(historyEntry: HistoryRecord, valueView: TextView) {
|
||||
valueView.text = historyEntry.toString()
|
||||
// val entryType = historyEntry.commandType
|
||||
if (!historyEntry.isSuccess()) {
|
||||
valueView.text = resourceHelper.gs(translatedFailure(historyEntry))
|
||||
return
|
||||
}
|
||||
valueView.text = when (historyEntry.commandType) {
|
||||
OmnipodCommandType.SET_TEMPORARY_BASAL -> {
|
||||
val tbr = historyEntry.record as TempBasalRecord
|
||||
tbr?.let {
|
||||
resourceHelper.gs(R.string.omnipod_common_history_tbr_value, it.rate, it.duration)
|
||||
} ?: "n/a"
|
||||
}
|
||||
OmnipodCommandType.SET_BOLUS -> {
|
||||
val bolus = historyEntry.record as BolusRecord
|
||||
bolus?.let {
|
||||
resourceHelper.gs(R.string.omnipod_common_history_bolus_value, it.amout)
|
||||
} ?: "n/a"
|
||||
}
|
||||
OmnipodCommandType.SET_BASAL_PROFILE,
|
||||
OmnipodCommandType.SET_TIME,
|
||||
OmnipodCommandType.INSERT_CANNULA,
|
||||
OmnipodCommandType.RESUME_DELIVERY -> {
|
||||
val basal = historyEntry.record as BasalValuesRecord
|
||||
ProfileUtil.getBasalProfilesDisplayable(basal.segments.toTypedArray(), PumpType.OMNIPOD_DASH)
|
||||
}
|
||||
else ->
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return historyList.size
|
||||
}
|
||||
|
||||
inner class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val timeView: TextView = itemView.findViewById(R.id.omnipod_history_time)
|
||||
val typeView: TextView = itemView.findViewById(R.id.omnipod_history_source)
|
||||
val valueView: TextView = itemView.findViewById(R.id.omnipod_history_description)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translatedFailure(historyEntry: HistoryRecord): Int {
|
||||
return when {
|
||||
historyEntry.initialResult == InitialResult.FAILURE_SENDING ->
|
||||
R.string.omnipod_dash_failed_to_send
|
||||
historyEntry.initialResult == InitialResult.NOT_SENT ->
|
||||
R.string.omnipod_dash_command_not_sent
|
||||
historyEntry.initialResult == InitialResult.SENT &&
|
||||
historyEntry.resolvedResult == ResolvedResult.FAILURE ->
|
||||
R.string.omnipod_dash_command_not_received_by_the_pod
|
||||
else ->
|
||||
R.string.omnipod_dash_unknown
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var selectedGroup: PumpHistoryEntryGroup = PumpHistoryEntryGroup.All
|
||||
const val DAYS_TO_DISPLAY = 5
|
||||
}
|
||||
}
|
|
@ -96,6 +96,10 @@ class DashPodManagementActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
binding.buttonPodHistory.setOnClickListener {
|
||||
startActivity(Intent(this, DashPodHistoryActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -5,11 +5,15 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InitializePodViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.AlertTrigger
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.I8n
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -24,7 +28,9 @@ class DashInitializePodViewModel @Inject constructor(
|
|||
logger: AAPSLogger,
|
||||
private val sp: SP,
|
||||
private val podStateManager: OmnipodDashPodStateManager,
|
||||
private val resourceHelper: ResourceHelper
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val history: DashHistory,
|
||||
|
||||
) : InitializePodViewModel(injector, logger) {
|
||||
override fun isPodInAlarm(): Boolean = false // TODO
|
||||
|
||||
|
@ -41,13 +47,18 @@ class DashInitializePodViewModel @Inject constructor(
|
|||
} else
|
||||
null
|
||||
|
||||
super.disposable += omnipodManager.activatePodPart1(lowReservoirAlertTrigger).subscribeBy(
|
||||
onNext = { podEvent ->
|
||||
logger.debug(
|
||||
LTag.PUMP,
|
||||
"Received PodEvent in Pod activation part 1: $podEvent"
|
||||
super.disposable += omnipodManager.activatePodPart1(lowReservoirAlertTrigger)
|
||||
.ignoreElements()
|
||||
.andThen(podStateManager.updateLowReservoirAlertSettings(lowReservoirAlertEnabled, lowReservoirAlertUnits))
|
||||
.andThen(
|
||||
history.createRecord(
|
||||
OmnipodCommandType.INITIALIZE_POD,
|
||||
initialResult = InitialResult.SENT,
|
||||
resolveResult = ResolvedResult.SUCCESS,
|
||||
resolvedAt = System.currentTimeMillis(),
|
||||
).ignoreElement()
|
||||
)
|
||||
},
|
||||
.subscribeBy(
|
||||
onError = { throwable ->
|
||||
logger.error(LTag.PUMP, "Error in Pod activation part 1", throwable)
|
||||
source.onSuccess(
|
||||
|
@ -58,7 +69,6 @@ class DashInitializePodViewModel @Inject constructor(
|
|||
},
|
||||
onComplete = {
|
||||
logger.debug("Pod activation part 1 completed")
|
||||
podStateManager.updateLowReservoirAlertSettings(lowReservoirAlertEnabled, lowReservoirAlertUnits)
|
||||
source.onSuccess(PumpEnactResult(injector).success(true))
|
||||
}
|
||||
)
|
||||
|
|
|
@ -12,10 +12,15 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
|||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InsertCannulaViewModel
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BasalValuesRecord
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.Constants
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.I8n
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram
|
||||
|
@ -36,6 +41,7 @@ class DashInsertCannulaViewModel @Inject constructor(
|
|||
private val sp: SP,
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val history: DashHistory,
|
||||
|
||||
injector: HasAndroidInjector,
|
||||
logger: AAPSLogger
|
||||
|
@ -69,6 +75,15 @@ class DashInsertCannulaViewModel @Inject constructor(
|
|||
super.disposable += omnipodManager.activatePodPart2(basalProgram, expirationHoursBeforeShutdown)
|
||||
.ignoreElements()
|
||||
.andThen(podStateManager.updateExpirationAlertSettings(expirationReminderEnabled, expirationHours))
|
||||
.andThen(
|
||||
history.createRecord(
|
||||
OmnipodCommandType.INSERT_CANNULA,
|
||||
basalProfileRecord = BasalValuesRecord(profile.getBasalValues().toList()),
|
||||
initialResult = InitialResult.SENT,
|
||||
resolveResult = ResolvedResult.SUCCESS,
|
||||
resolvedAt = System.currentTimeMillis(),
|
||||
).ignoreElement()
|
||||
)
|
||||
.subscribeBy(
|
||||
onError = { throwable ->
|
||||
logger.error(LTag.PUMP, "Error in Pod activation part 2", throwable)
|
||||
|
@ -100,7 +115,6 @@ class DashInsertCannulaViewModel @Inject constructor(
|
|||
pumpType = PumpType.OMNIPOD_DASH,
|
||||
pumpSerial = podStateManager.uniqueId?.toString() ?: "n/a"
|
||||
)
|
||||
|
||||
rxBus.send(EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED))
|
||||
fabricPrivacy.logCustom("OmnipodDashPodActivated")
|
||||
source.onSuccess(PumpEnactResult(injector).success(true))
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/omnipod_historytop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/omnipod_dash_history_type"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/omnipod_historytype"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/pillborder"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/omnipod_dash_history_title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_historystatus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/omnipod_historytop"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/omnipod_history_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_below="@+id/omnipod_historystatus" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_time"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/omnipod_dash_history_item_date"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_source"
|
||||
android:layout_width="132dp"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/omnipod_dash_history_item_source"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_description"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/omnipod_dash_history_item_description"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
|
@ -111,6 +111,20 @@
|
|||
app:layout_constraintRight_toLeftOf="@+id/Actions_Col_1_Row_2_vertical_guideline"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/button_pod_history"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_pod_management_pod_history"
|
||||
android:text="@string/omnipod_common_pod_management_button_pod_history"
|
||||
android:textAllCaps="false"
|
||||
android:visibility="visible"
|
||||
app:layout_constrainedHeight="@+id/Actions_Row_2_horizontal_guideline"
|
||||
app:layout_constraintLeft_toRightOf="@+id/Actions_Col_1_Row_2_vertical_guideline"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/Actions_Col_1_Row_2_vertical_guideline"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
<!-- Omnipod Dash - Keys -->
|
||||
<string name="key_omnipod_dash_pod_state" translatable="false">AAPS.OmnipodDash.pod_state</string>
|
||||
|
||||
<!-- Omnipod Dash - History -->
|
||||
<string name="omnipod_dash_history_title">Pod History</string>
|
||||
<string name="omnipod_dash_history_item_description">Description</string>
|
||||
<string name="omnipod_dash_history_item_source">Source</string>
|
||||
<string name="omnipod_dash_history_item_date">Date</string>
|
||||
<string name="omnipod_dash_history_type">Type:</string>
|
||||
<string name="omnipod_dash_history_bolus_value">%1$.2f U</string>
|
||||
<string name="omnipod_dash_history_bolus_value_with_carbs">%1$.2f U, CH=%2$.1f g</string>
|
||||
<string name="omnipod_dash_history_tbr_value">Rate: %1$.2f U, duration: %2$d minutes</string>
|
||||
|
||||
<!-- Omnipod Dash - Overview -->
|
||||
<string name="omnipod_dash_overview_bluetooth_status">Bluetooth Status</string>
|
||||
<string name="omnipod_dash_overview_bluetooth_address">Bluetooth Address</string>
|
||||
|
@ -30,4 +40,10 @@
|
|||
<string name="omnipod_dash_found_too_many_pods">Found too many pods for activation</string>
|
||||
<string name="omnipod_dash_scan_failed">Could not find an available pod for activation</string>
|
||||
<string name="omnipod_dash_generic_error">Generic error: %1$s</string>
|
||||
<string name="omnipod_dash_failed_to_send">Failed to send the command</string>
|
||||
<string name="omnipod_dash_command_not_sent">Command not sent</string>
|
||||
<string name="omnipod_dash_command_not_received_by_the_pod">Command not received by the pod</string>
|
||||
<string name="omnipod_dash_unknown">Unknown state for the command</string>
|
||||
<string name="omnipod_common_history_tbr_value">Rate: %1$.2f U, duration: %2$d minutes</string>
|
||||
<string name="omnipod_common_history_bolus_value">%1$.2f U</string>
|
||||
</resources>
|
||||
|
|
|
@ -25,8 +25,9 @@ object ProfileUtil {
|
|||
val basalValueValue = pumpType.determineCorrectBasalSize(basalValue.value)
|
||||
val hour = basalValue.timeAsSeconds / (60 * 60)
|
||||
stringBuilder.append((if (hour < 10) "0" else "") + hour + ":00")
|
||||
stringBuilder.append(" ")
|
||||
stringBuilder.append(String.format(Locale.ENGLISH, "%.3f", basalValueValue))
|
||||
stringBuilder.append(", ")
|
||||
stringBuilder.append(",\n")
|
||||
}
|
||||
return if (stringBuilder.length > 3) stringBuilder.substring(0, stringBuilder.length - 2) else stringBuilder.toString()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue