Merge remote-tracking branch 'nightscout/dev' into medtrum-test1

This commit is contained in:
jbr7rr 2023-06-16 21:02:26 +02:00
commit cbc5a51f2c
142 changed files with 1150 additions and 329 deletions

View file

@ -3,6 +3,7 @@ package info.nightscout.rx.weardata
import info.nightscout.rx.events.Event
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import org.joda.time.DateTime
import java.util.Objects
@Serializable
@ -90,6 +91,16 @@ sealed class EventData : Event() {
@Serializable
data class ActionQuickWizardPreCheck(val guid: String) : EventData()
@Serializable
data class ActionHeartRate(
val duration: Long,
val timestamp: Long,
val beatsPerMinute: Double,
val device: String): EventData() {
override fun toString() =
"HR ${beatsPerMinute.toInt()} at ${DateTime(timestamp)} for ${duration / 1000.0}sec $device"
}
@Serializable
data class ActionTempTargetPreCheck(
val command: TempTargetCommand,

View file

@ -327,6 +327,7 @@ class HistoryBrowseActivity : TranslatedDaggerAppCompatActivity() {
var useRatioForScale = false
var useDSForScale = false
var useBGIForScale = false
var useHRForScale = false
when {
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
@ -335,6 +336,7 @@ class HistoryBrowseActivity : TranslatedDaggerAppCompatActivity() {
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.HR.ordinal] -> useHRForScale = true
}
val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
@ -345,6 +347,7 @@ class HistoryBrowseActivity : TranslatedDaggerAppCompatActivity() {
if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(useBGIForScale, if (alignDevBgiScale) 1.0 else 0.8)
if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(useRatioForScale, if (useRatioForScale) 1.0 else 0.8)
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && config.isDev()) secondGraphData.addDeviationSlope(useDSForScale, 1.0)
if (menuChartSettings[g + 1][OverviewMenus.CharType.HR.ordinal] && config.isDev()) secondGraphData.addHeartRate(useHRForScale, 1.0)
// set manual x bounds to have nice steps
secondGraphData.formatAxis(historyBrowserData.overviewData.fromTime, historyBrowserData.overviewData.endTime)

View file

@ -2,7 +2,7 @@
buildscript {
ext {
kotlin_version = '1.8.21'
kotlin_version = '1.8.22'
core_version = '1.10.1'
rxjava_version = '3.1.6'
rxandroid_version = '3.0.2'
@ -11,11 +11,11 @@ buildscript {
lifecycle_version = '2.6.1'
dagger_version = '2.46.1'
coroutines_version = '1.7.1'
activity_version = '1.7.1'
fragmentktx_version = '1.5.7'
activity_version = '1.7.2'
fragmentktx_version = '1.6.0'
ormLite_version = '4.46'
gson_version = '2.10.1'
nav_version = '2.5.3'
nav_version = '2.6.0'
appcompat_version = '1.6.1'
material_version = '1.9.0'
gridlayout_version = '1.0.0'
@ -59,7 +59,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.6'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@ -75,7 +75,7 @@ buildscript {
plugins {
// Test Gradle build, keep disabled under normal circumstances
// id "com.osacky.doctor" version "0.8.1"
id "org.jlleitschuh.gradle.ktlint" version "11.3.2"
id "org.jlleitschuh.gradle.ktlint" version "11.4.0"
id 'org.barfuin.gradle.jacocolog' version '3.1.0'
id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
}

View file

@ -150,4 +150,7 @@ interface OverviewData {
val dsMinScale: Scale
var dsMaxSeries: LineGraphSeries<ScaledDataPoint>
var dsMinSeries: LineGraphSeries<ScaledDataPoint>
}
var heartRateScale: Scale
var heartRateGraphSeries: LineGraphSeries<DataPointWithLabelInterface>
}

View file

@ -0,0 +1,24 @@
package info.nightscout.core.graph.data
import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.HeartRate
import info.nightscout.shared.interfaces.ResourceHelper
class HeartRateDataPoint(
private val data: HeartRate,
private val rh: ResourceHelper,
) : DataPointWithLabelInterface {
override fun getX(): Double = (data.timestamp - data.duration).toDouble()
override fun getY(): Double = data.beatsPerMinute
override fun setY(y: Double) {}
override val label: String = ""
override val duration = data.duration
override val shape = PointsWithLabelGraphSeries.Shape.HEARTRATE
override val size = 1f
override val paintStyle: Paint.Style = Paint.Style.FILL
override fun color(context: Context?): Int = rh.gac(context, info.nightscout.core.ui.R.attr.heartRateColor)
}

View file

@ -54,7 +54,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
GENERAL_WITH_DURATION,
COB_FAIL_OVER,
IOB_PREDICTION,
BUCKETED_BG
BUCKETED_BG,
HEARTRATE,
}
/**
@ -324,6 +325,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
mPaint.setStrokeWidth(5);
canvas.drawRect(endX - 3, bounds.top + py - 3, xPlusLength + 3, bounds.bottom + py + 3, mPaint);
}
} else if (value.getShape() == Shape.HEARTRATE) {
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, 1F, mPaint);
}
// set values above point
}

View file

@ -7,5 +7,6 @@ interface APS {
var lastDetermineBasalAdapter: DetermineBasalAdapter?
var lastAutosensResult: AutosensResult
operator fun invoke(initiator: String, tempBasalFallback: Boolean)
fun isEnabled(): Boolean
fun invoke(initiator: String, tempBasalFallback: Boolean)
}

View file

@ -15,7 +15,8 @@ interface OverviewMenus {
BGI,
SEN,
ACT,
DEVSLOPE
DEVSLOPE,
HR,
}
val setting: List<Array<Boolean>>
@ -23,4 +24,4 @@ interface OverviewMenus {
fun setupChartMenu(context: Context, chartButton: ImageButton)
fun enabledTypes(graph: Int): String
fun isEnabledIn(type: CharType): Int
}
}

View file

@ -23,7 +23,7 @@ dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
api 'com.google.guava:guava:31.1-jre'
api 'com.google.guava:guava:32.0.1-jre'
api "androidx.activity:activity-ktx:$activity_version"
api "androidx.appcompat:appcompat:$appcompat_version"

View file

@ -216,6 +216,7 @@
<item name="inRangeBackground">@color/inRangeBackground</item>
<item name="devSlopePosColor">@color/devSlopePos</item>
<item name="devSlopeNegColor">@color/devSlopeNeg</item>
<item name="heartRateColor">@color/heartRate</item>
<item name="deviationGreyColor">@color/deviationGrey</item>
<item name="deviationBlackColor">@color/deviationBlack</item>
<item name="deviationGreenColor">@color/deviationGreen</item>

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="biometric_title">Требуется авторизация</string>
<string name="biometric_description">Поместите палец на устройство считывания отпечатков, чтобы подтвердить свою идентичность</string>
<string name="biometric_description">Поместите палец на устройство считывания отпечатков, чтобы подтвердить свою личность</string>
<string name="settings_protection">Защита настроек</string>
<string name="application_protection">Защита приложения</string>
<string name="bolus_protection">Защита болюсов</string>
<string name="settings_password">Пароль параметров</string>
<string name="settings_pin">ПИН-код настроек</string>
<string name="application_password">Пароль приложения</string>
<string name="application_pin">PIN-код приложения</string>
<string name="bolus_password">Пароль болюсов</string>
<string name="bolus_pin">Пин-код болюса</string>
<string name="protection_timeout_title">Тайм-аут удержания пароля и пин-кода [s]</string>
<string name="settings_password">Пароль для настроек</string>
<string name="settings_pin">ПИН для настроек</string>
<string name="application_password">Пароль для приложения</string>
<string name="application_pin">ПИН для приложения</string>
<string name="bolus_password">Пароль для болюсов</string>
<string name="bolus_pin">ПИН для болюсов</string>
<string name="protection_timeout_title">Тайм-аут удержания пароля и ПИН-кода [s]</string>
<string name="protection_timeout_summary">Время до ввода пароля или PIN-кода</string>
<string name="biometric">Биометрия</string>
<string name="custom_password">Настраиваемый пароль</string>
@ -20,12 +20,12 @@
<string name="unsecure_fallback_biometric">Небезопасный резервный вход</string>
<string name="unsecure_fallback_descriotion_biometric">Биометрической защите требуется главный пароль для безопасности.\n\n Установите главный пароль!</string>
<string name="password_set">Пароль задан!</string>
<string name="pin_set">PIN-код установлен!</string>
<string name="pin_set">ПИН установлен!</string>
<string name="password_not_set">Пароль не задан</string>
<string name="pin_not_set">PIN-код не задан</string>
<string name="pin_not_set">ПИН не задан</string>
<string name="password_not_changed">Пароль не был изменён</string>
<string name="pin_not_changed">PIN-код не изменён</string>
<string name="pin_cleared">PIN-код очищен!</string>
<string name="pin_not_changed">ПИН не изменён</string>
<string name="pin_cleared">ПИН очищен!</string>
<string name="password_hint">Введите пароль здесь</string>
<string name="pin_hint">Введите PIN-код здесь</string>
<string name="pin_hint">Введите ПИН здесь</string>
</resources>

View file

@ -6,9 +6,9 @@
<string name="profile_set_ok">базальный профиль помпы обновлен</string>
<string name="invalid_input">введенные данные неверны</string>
<string name="bolus_delivering">Подается болюс %1$.2f ед</string>
<string name="constraint_applied">применено ограничение!</string>
<string name="constraint_applied">Применено ограничение!</string>
<string name="tempbasals_iobtotal_label_string">Общий IOB:</string>
<string name="tt_label">Врем цель (TT)</string>
<string name="tt_label">ВЦ</string>
<string name="pump_unreachable">Помпа недоступна</string>
<string name="insulin_unit_shortname">Ед</string>
<string name="pump_base_basal_rate">%1$.2f ед/ч</string>
@ -25,12 +25,12 @@
<string name="save">Сохранить</string>
<string name="snooze">Отложить</string>
<string name="virtual_pump">Виртуальная помпа</string>
<string name="constraints">ограничения</string>
<string name="constraints">Ограничения</string>
<string name="superbolus">Суперболюс</string>
<string name="pump_paused">Помпа приостановлена</string>
<string name="and">И</string>
<string name="patient_name_default" comment="This is default patient display name, when user does not provide real one">Пользователь</string>
<string name="result">результат</string>
<string name="result">Результат</string>
<string name="settings">Настройки</string>
<string name="statuslights">Индикаторы состояния</string>
<string name="do_ns_upload_title">Выгружать (передавать данные) ГК в Nightscout</string>
@ -40,7 +40,7 @@
<string name="ue_export_to_csv">Экспорт пользовательских записей в Excel (csv)</string>
<string name="confirm">Подтверждаю</string>
<string name="pump">Помпа</string>
<string name="missed_bg_readings">Пропущенные данные СК</string>
<string name="missed_bg_readings">Пропущенные данные ГК</string>
<string name="treatments_iob_label_string">IOB акт инс:</string>
<string name="mute5min">Отключить уведомления на 5 минут</string>
<string name="mute">Отключить звук</string>
@ -49,10 +49,10 @@
<string name="extendedbolusdeliveryerror">Ошибка подачи пролонгированного болюса</string>
<string name="aps_mode_title">Режим APS</string>
<string name="extended_bolus">Пролонгированный болюс</string>
<string name="paused">на паузе</string>
<string name="paused">На паузе</string>
<string name="tdd_total">Суммарный суточный инсулин TDD</string>
<string name="goingtodeliver">Будет подано %1$.2f ед инс</string>
<string name="waitingforpump">ожидание помпы</string>
<string name="waitingforpump">Ожидание помпы</string>
<string name="androidaps_start">AAPS запущен</string>
<string name="formatsignedinsulinunits">%1$+.2f ед</string>
<string name="format_carbs">%1$d гр</string>
@ -60,18 +60,18 @@
<string name="format_mins">%1$d мин</string>
<string name="objectives">Цели</string>
<string name="please_wait">Подождите…</string>
<string name="stop">стоп</string>
<string name="stop">Стоп</string>
<string name="carbs">Углеводы</string>
<string name="invalid_profile">Недопустимый профиль!</string>
<string name="no_profile_set">ПРОФИЛЬ НЕ ЗАДАН</string>
<string name="active"><![CDATA[Активен]]></string>
<string name="date">дата</string>
<string name="date">Дата</string>
<string name="units_label">единицы</string>
<string name="dia_label">DIA (время действия инсулина)</string>
<string name="ic_label">Углеводный коэффициент IC (ГУ/ед. инс)</string>
<string name="isf_label">ISF (чувствительность к инсулину)</string>
<string name="basal_label">базал</string>
<string name="target_label">Целевое значение СК:</string>
<string name="target_label">Целевое значение ГК:</string>
<string name="dia_long_label">Продолжительность действия инсулина</string>
<string name="ic_long_label">Углеводный коэффициент IC (ГУ/ед. инс.)</string>
<string name="isf_long_label">Фактор Чувствительности к Инсулину (ISF)</string>
@ -86,10 +86,10 @@
<string name="pump_time_updated">Время на помпе обновлено</string>
<string name="exit">Выйти</string>
<string name="removerecord">Удалить запись</string>
<string name="loopisdisabled">Зцикл не работает</string>
<string name="loopisdisabled">Цикл не работает</string>
<string name="alarm">Оповещения об опасности</string>
<string name="disableloop">Деактивировать цикличность</string>
<string name="enableloop">Активировать цикличность</string>
<string name="disableloop">Деактивировать цикл</string>
<string name="enableloop">Активировать цикл</string>
<string name="resumeloop">Возобновить цикл</string>
<string name="suspendloop">Приостановить цикл</string>
<string name="duration_min_label">Длительность (мин)</string>
@ -98,8 +98,8 @@
<string name="exists">существует</string>
<string name="notexists">не существует</string>
<string name="glucose">Гликемия</string>
<string name="iob">IOB акт инс</string>
<string name="cob">АктУгл COB</string>
<string name="iob">IOB (актИнс)</string>
<string name="cob">COB (актУгл)</string>
<string name="name_short">Имя:</string>
<string name="time">Время</string>
<string name="ns_wifi_ssids">SSID для Wi-Fi</string>
@ -117,7 +117,7 @@
<string name="duration_label">Длительность действия</string>
<string name="shortgramm">грамм</string>
<string name="pumpsuspended">Работа помпы остановлена</string>
<string name="notconfigured">Не сконфигурировано</string>
<string name="notconfigured">Не настроено</string>
<string name="loopsuspended">ЗЦ остановлен</string>
<string name="trend_arrow">Стрелка тренда</string>
<string name="a11y_autosens_label">Auto sens</string>
@ -157,7 +157,7 @@
<string name="overview_insulin_label">Инсулин</string>
<string name="stoptemptarget">Остановить врем цель</string>
<string name="closedloop">Замкнутый цикл</string>
<string name="openloop">открытый цикл</string>
<string name="openloop">Открытый цикл</string>
<string name="lowglucosesuspend">Приостановка помпы на низкой ГК</string>
<string name="dia">Время действия инсулина DIA</string>
<string name="ic_short">IC углкоэф ГУ/инс</string>

View file

@ -181,6 +181,7 @@
<attr name="bolusDataPointColor" format="reference|color" />
<attr name="profileSwitchColor" format="reference|color" />
<attr name="originalBgValueColor" format="reference|color" />
<attr name="heartRateColor" format="reference|color" />
<attr name="therapyEvent_NS_MBG" format="reference|color" />
<attr name="therapyEvent_FINGER_STICK_BG_VALUE" format="reference|color" />
<attr name="therapyEvent_EXERCISE" format="reference|color" />
@ -221,4 +222,4 @@
<attr name="crossTargetColor" format="reference|color" />
<!---Custom button -->
<attr name="customBtnStyle" format="reference"/>
</resources>
</resources>

View file

@ -153,6 +153,7 @@
<color name="bgi">#00EEEE</color>
<color name="devSlopePos">#FFFFFF00</color>
<color name="devSlopeNeg">#FFFF00FF</color>
<color name="heartRate">#FFFFFF66</color>
<color name="actionsConfirm">#F6CE22</color>
<color name="deviations">#FF0000</color>
<color name="cobAlert">#7484E2</color>

View file

@ -219,6 +219,7 @@
<item name="inRangeBackground">@color/inRangeBackground</item>
<item name="devSlopePosColor">@color/devSlopePos</item>
<item name="devSlopeNegColor">@color/devSlopeNeg</item>
<item name="heartRateColor">@color/heartRate</item>
<item name="deviationGreyColor">@color/deviationGrey</item>
<item name="deviationBlackColor">@color/deviationBlack</item>
<item name="deviationGreenColor">@color/deviationGreen</item>

View file

@ -22,7 +22,7 @@ dependencies {
implementation project(':app-wear-shared:shared')
//Firebase
api platform('com.google.firebase:firebase-bom:32.0.0')
api platform('com.google.firebase:firebase-bom:32.1.1')
api "com.google.firebase:firebase-analytics-ktx"
api "com.google.firebase:firebase-crashlytics-ktx"
// StatsActivity not in use now

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="count_selected">%1$d выбрано</string>
<string name="count_selected">Выбрано: %1$d</string>
<string name="remove_items">Удалить элементы</string>
<string name="sort_items">Сортировать элементы</string>
<string name="remove_selected_items">Удалить выбранные элементы</string>

View file

@ -53,6 +53,8 @@ files:
translation: /pump/pump-core/src/main/res/values-%android_code%/strings.xml
- source: /pump/eopatch/src/main/res/values/strings.xml
translation: /pump/eopatch/src/main/res/values-%android_code%/strings.xml
- source: /pump/eopatch/src/main/res/values/strings_alarm.xml
translation: /pump/eopatch/src/main/res/values-%android_code%/strings_alarm.xml
- source: /pump/diaconn/src/main/res/values/strings.xml
translation: /pump/diaconn/src/main/res/values-%android_code%/strings.xml
- source: /pump/pump-common/src/main/res/values/strings.xml

View file

@ -92,8 +92,26 @@ internal class HeartRateDaoTest {
}
}
companion object {
@Test
fun getFromTimeToTime() {
createDatabase().use { db ->
val dao = db.heartRateDao
val timestamp = System.currentTimeMillis()
val hr1 = createHeartRate(timestamp = timestamp, beatsPerMinute = 80.0)
val hr2 = createHeartRate(timestamp = timestamp + 1, beatsPerMinute = 150.0)
val hr3 = createHeartRate(timestamp = timestamp + 2, beatsPerMinute = 160.0)
dao.insertNewEntry(hr1)
dao.insertNewEntry(hr2)
dao.insertNewEntry(hr3)
assertEquals(listOf(hr1, hr2, hr3), dao.getFromTimeToTime(timestamp, timestamp + 2))
assertEquals(listOf(hr1, hr2), dao.getFromTimeToTime(timestamp, timestamp + 1))
assertEquals(listOf(hr2), dao.getFromTimeToTime(timestamp + 1, timestamp + 1))
assertTrue(dao.getFromTimeToTime(timestamp + 3, timestamp + 10).isEmpty())
}
}
companion object {
private const val TEST_DB_NAME = "testDatabase"
fun createHeartRate(timestamp: Long? = null, beatsPerMinute: Double = 80.0) =

View file

@ -934,6 +934,9 @@ import kotlin.math.roundToInt
fun getHeartRatesFromTime(timeMillis: Long) = database.heartRateDao.getFromTime(timeMillis)
fun getHeartRatesFromTimeToTime(startMillis: Long, endMillis: Long) =
database.heartRateDao.getFromTimeToTime(startMillis, endMillis)
suspend fun collectNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int) = NewEntries(
apsResults = database.apsResultDao.getNewEntriesSince(since, until, limit, offset),
apsResultLinks = database.apsResultLinkDao.getNewEntriesSince(since, until, limit, offset),

View file

@ -23,6 +23,9 @@ internal interface HeartRateDao : TraceableDao<HeartRate> {
@Query("SELECT * FROM $TABLE_HEART_RATE WHERE timestamp >= :timestamp ORDER BY timestamp")
fun getFromTime(timestamp: Long): List<HeartRate>
@Query("SELECT * FROM $TABLE_HEART_RATE WHERE timestamp BETWEEN :startMillis AND :endMillis ORDER BY timestamp")
fun getFromTimeToTime(startMillis: Long, endMillis: Long): List<HeartRate>
@Query("SELECT * FROM $TABLE_HEART_RATE WHERE timestamp > :since AND timestamp <= :until LIMIT :limit OFFSET :offset")
fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<HeartRate>
}

View file

@ -87,6 +87,7 @@ class OverviewDataImpl @Inject constructor(
dsMinSeries = LineGraphSeries()
treatmentsSeries = PointsWithLabelGraphSeries()
epsSeries = PointsWithLabelGraphSeries()
heartRateGraphSeries = LineGraphSeries()
}
override fun initRange() {
@ -322,4 +323,6 @@ class OverviewDataImpl @Inject constructor(
override val dsMinScale = Scale()
override var dsMaxSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
override var dsMinSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
override var heartRateScale = Scale()
override var heartRateGraphSeries: LineGraphSeries<DataPointWithLabelInterface> = LineGraphSeries()
}

View file

@ -218,7 +218,7 @@ class LoopPlugin @Inject constructor(
val start = dateUtil.now()
while (start + T.mins(maxMinutes).msecs() > dateUtil.now()) {
if (commandQueue.size() == 0 && commandQueue.performing() == null) return true
SystemClock.sleep(100)
SystemClock.sleep(1000)
}
return false
}
@ -247,10 +247,16 @@ class LoopPlugin @Inject constructor(
return
}
if (!isEmptyQueue()) {
aapsLogger.debug(LTag.APS, rh.gs(info.nightscout.core.ui.R.string.pump_busy))
rxBus.send(EventLoopSetLastRunGui(rh.gs(info.nightscout.core.ui.R.string.pump_busy)))
return
}
// Check if pump info is loaded
if (pump.baseBasalRate < 0.01) return
val usedAPS = activePlugin.activeAPS
if ((usedAPS as PluginBase).isEnabled()) {
if (usedAPS.isEnabled()) {
usedAPS.invoke(initiator, tempBasalFallback)
apsResult = usedAPS.lastAPSResult
}
@ -261,12 +267,6 @@ class LoopPlugin @Inject constructor(
return
}
if (!isEmptyQueue()) {
aapsLogger.debug(LTag.APS, rh.gs(info.nightscout.core.ui.R.string.pump_busy))
rxBus.send(EventLoopSetLastRunGui(rh.gs(info.nightscout.core.ui.R.string.pump_busy)))
return
}
// Prepare for pumps using % basals
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT && allowPercentage()) {
apsResult.usePercent = true

View file

@ -24,6 +24,7 @@
<string name="objectives_autosens_gate">1 semaine de Boucle Fermée en journée en saisissant régulièrement les glucides</string>
<string name="objectives_autosens_learned">Si le résultat de votre autosens n\'est pas autour de 100%, votre profil est probablement erroné.</string>
<string name="objectives_smb_objective">Activation de fonctionnalités supplémentaires pour l\'utilisation en journée, telles que la fonction SMB</string>
<string name="objectives_smb_gate">Vous devez lire le wiki et augmenter le maxIA pour faire fonctionner les SMB ! Un bon début est maxIA = moyenne des bolus repas + 3 fois le basal le plus élevé</string>
<string name="objectives_smb_learned">L\'utilisation de SMB est votre objectif. L\'algorithme Oref1 a été conçu pour vous aider également avec vos bolus. Vous ne devriez pas donner un bolus complet pour votre nourriture, mais seulement une partie de celui-ci et laisser AAPS vous donner le reste si nécessaire. De cette façon, vous avez plus de latitude pour les glucides mal calculés. Saviez-vous que vous pouvez définir un pourcentage à appliquer au résultat de la calculatrice de bolus pour réduire la taille du bolus ?</string>
<string name="objectives_auto_objective">Activation de l\'automatisation</string>
<string name="objectives_auto_gate">Lisez la documentation sur le fonctionnement de l\'automatisation fonctionne. Configurez vos premières règles simples. Au lieu de mettre une action, configurez une notification. Quand vous êtes sûr que l\'automatisation est déclenchée au bon moment, remplacez la notification par une action réelle. (https://wiki.aaps.app/fr/latest/Usage/Automation.html)</string>

View file

@ -1030,6 +1030,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
var useRatioForScale = false
var useDSForScale = false
var useBGIForScale = false
var useHRForScale = false
when {
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
@ -1038,6 +1039,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
menuChartSettings[g + 1][OverviewMenus.CharType.HR.ordinal] -> useHRForScale = true
}
val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
@ -1052,6 +1054,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (useDSForScale) 1.0 else 0.8,
useRatioForScale
)
if (menuChartSettings[g + 1][OverviewMenus.CharType.HR.ordinal]) secondGraphData.addHeartRate(useHRForScale, if (useHRForScale) 1.0 else 0.8)
// set manual x bounds to have nice steps
secondGraphData.formatAxis(overviewData.fromTime, overviewData.endTime)
@ -1067,7 +1070,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] ||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] ||
menuChartSettings[g + 1][OverviewMenus.CharType.HR.ordinal]
).toVisibility()
secondaryGraphsData[g].performUpdate()
}

View file

@ -47,7 +47,8 @@ class OverviewMenusImpl @Inject constructor(
BGI(R.string.overview_show_bgi, info.nightscout.core.ui.R.attr.bgiColor, info.nightscout.core.ui.R.attr.menuTextColor, primary = false, secondary = true, shortnameId = R.string.bgi_shortname),
SEN(R.string.overview_show_sensitivity, info.nightscout.core.ui.R.attr.ratioColor, info.nightscout.core.ui.R.attr.menuTextColorInverse, primary = false, secondary = true, shortnameId = R.string.sensitivity_shortname),
ACT(R.string.overview_show_activity, info.nightscout.core.ui.R.attr.activityColor, info.nightscout.core.ui.R.attr.menuTextColor, primary = true, secondary = false, shortnameId = R.string.activity_shortname),
DEVSLOPE(R.string.overview_show_deviation_slope, info.nightscout.core.ui.R.attr.devSlopePosColor, info.nightscout.core.ui.R.attr.menuTextColor, primary = false, secondary = true, shortnameId = R.string.devslope_shortname)
DEVSLOPE(R.string.overview_show_deviation_slope, info.nightscout.core.ui.R.attr.devSlopePosColor, info.nightscout.core.ui.R.attr.menuTextColor, primary = false, secondary = true, shortnameId = R.string.devslope_shortname),
HR(R.string.overview_show_heartRate, info.nightscout.core.ui.R.attr.heartRateColor, info.nightscout.core.ui.R.attr.menuTextColor, primary = false, secondary = true, shortnameId = R.string.heartRate_shortname),
}
companion object {
@ -202,4 +203,4 @@ class OverviewMenusImpl @Inject constructor(
return -1
}
}
}

View file

@ -258,5 +258,14 @@ class GraphData(
// draw it
graph.onDataChanged(false, false)
}
}
fun addHeartRate(useForScale: Boolean, scale: Double) {
val maxHR = overviewData.heartRateGraphSeries.highestValueY
if (useForScale) {
minY = 0.0
maxY = maxHR
}
addSeries(overviewData.heartRateGraphSeries)
overviewData.heartRateScale.multiplier = maxY * scale / maxHR
}
}

View file

@ -19,6 +19,7 @@ import info.nightscout.database.ValueWrapper
import info.nightscout.database.entities.Bolus
import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.database.entities.HeartRate
import info.nightscout.database.entities.TemporaryBasal
import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.database.entities.TotalDailyDose
@ -28,6 +29,7 @@ import info.nightscout.database.entities.interfaces.end
import info.nightscout.database.impl.AppRepository
import info.nightscout.database.impl.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.database.impl.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
import info.nightscout.database.impl.transactions.InsertOrUpdateHeartRateTransaction
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
@ -308,6 +310,10 @@ class DataHandlerMobile @Inject constructor(
aapsLogger.debug(LTag.WEAR, "WearException received $it from ${it.sourceNodeId}")
fabricPrivacy.logWearException(it)
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventData.ActionHeartRate::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ handleHeartRate(it) }, fabricPrivacy::logException)
}
private fun handleTddStatus() {
@ -1230,4 +1236,15 @@ class DataHandlerMobile @Inject constructor(
@Synchronized private fun sendError(errorMessage: String) {
rxBus.send(EventMobileToWear(EventData.ConfirmAction(rh.gs(info.nightscout.core.ui.R.string.error), errorMessage, returnCommand = EventData.Error(dateUtil.now())))) // ignore return path
}
/** Stores heart rate events coming from the Wear device. */
private fun handleHeartRate(actionHeartRate: EventData.ActionHeartRate) {
aapsLogger.debug(LTag.WEAR, "Heart rate received $actionHeartRate from ${actionHeartRate.sourceNodeId}")
val hr = HeartRate(
duration = actionHeartRate.duration,
timestamp = actionHeartRate.timestamp,
beatsPerMinute = actionHeartRate.beatsPerMinute,
device = actionHeartRate.device)
repository.runTransaction(InsertOrUpdateHeartRateTransaction(hr)).blockingAwait()
}
}

View file

@ -322,7 +322,6 @@
<string name="grams_short">гр.</string>
<string name="hour_short">ч</string>
<string name="no_active_profile">Не е настроен активен профил!</string>
<string name="profile_message">Профил:\n\nСмяна на времето: %1$\nПроценти: %2$d%%\"</string>
<string name="tdd_line">%1$.2fЕ %1$.0f%%</string>
<string name="no_profile">Не е зареден профил</string>
<string name="aps_only">Прилагане само в режим АПС!</string>

View file

@ -253,6 +253,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Predikce</string>
<string name="overview_show_treatments">Ošetření</string>
<string name="overview_show_heartRate">Tepová frekvence</string>
<string name="overview_show_deviation_slope">Odchylka sklonu</string>
<string name="overview_show_activity">Aktivita</string>
<string name="overview_show_bgi">Vliv na hladinu glukózy</string>
@ -270,6 +271,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string>
<string name="treatments_shortname">OŠET</string>
<string name="heartRate_shortname">TF</string>
<string name="sensitivity_shortname">SENZ</string>
<string name="graph_scale">Měřítko grafu</string>
<string name="graph_menu_divider_header">Graf</string>
@ -323,7 +325,7 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Není nastaven žádný aktivní profil!</string>
<string name="profile_message">Profil:\n\nPosunutí: %1$\nProcento: %2$d%%\"</string>
<string name="profile_message">Profil:\n\nPosunutí: %1$d\nProcento: %2$d%%\"</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">Není vybrán žádný profil</string>
<string name="aps_only">Použít pouze v APS módu!</string>

View file

@ -324,7 +324,6 @@ Unerwartetes Verhalten.</string>
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Kein aktiver Profilwechsel!</string>
<string name="profile_message">Profil:\n\nZeitverschiebung: %1$\nProzent: %2$d%%\"</string>
<string name="tdd_line">%1$.2fE %1$.0f%%</string>
<string name="no_profile">Kein Profil geladen</string>
<string name="aps_only">Nur im APS-Modus anwendbar!</string>

View file

@ -254,6 +254,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Predicciones</string>
<string name="overview_show_treatments">Tratamientos</string>
<string name="overview_show_heartRate">Ritmo cardíaco</string>
<string name="overview_show_deviation_slope">Pendiente de desviación</string>
<string name="overview_show_activity">Actividad</string>
<string name="overview_show_bgi">Impacto de glucosa en sangre</string>
@ -271,6 +272,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string>
<string name="treatments_shortname">TRAT</string>
<string name="heartRate_shortname">RC</string>
<string name="sensitivity_shortname">Sens</string>
<string name="graph_scale">Escala gráfica</string>
<string name="graph_menu_divider_header">Gráfico</string>
@ -324,7 +326,7 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Sin cambio de perfil activo</string>
<string name="profile_message">Perfil:\n\nHorario: %1$\nPorcentaje: %2$d%%\"</string>
<string name="profile_message">Perfil:\n\nAjuste de tiempo: %1$d\nPorcentaje: %2$d%%\"</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">Ningún perfil cargado</string>
<string name="aps_only">Sólo se aplica en modo APS</string>

View file

@ -253,6 +253,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Prédictions</string>
<string name="overview_show_treatments">Traitements</string>
<string name="overview_show_heartRate">Fréquence Cardiaque</string>
<string name="overview_show_deviation_slope">Pente de déviations</string>
<string name="overview_show_activity">Activité</string>
<string name="overview_show_bgi">Impact glycémique</string>
@ -270,6 +271,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">PENTEDEV</string>
<string name="treatments_shortname">TRAIT</string>
<string name="heartRate_shortname">BPM</string>
<string name="sensitivity_shortname">SENS</string>
<string name="graph_scale">Échelle du graph.</string>
<string name="graph_menu_divider_header">Graph</string>
@ -323,7 +325,6 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Aucun profil actif!</string>
<string name="profile_message">Profil :\n\nDécalage: %1$\nPourcentage: %2$d%%\"</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">Aucun profil séléctionné</string>
<string name="aps_only">S\'applique uniquement en mode APS!</string>

View file

@ -253,6 +253,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Predizioni</string>
<string name="overview_show_treatments">Trattamenti</string>
<string name="overview_show_heartRate">Frequenza cardiaca</string>
<string name="overview_show_deviation_slope">Pendenza deviazione</string>
<string name="overview_show_activity">Attività</string>
<string name="overview_show_bgi">Impatto glicemia (BGI)</string>
@ -270,6 +271,7 @@
<string name="abs_insulin_shortname">ASS</string>
<string name="devslope_shortname">PENDEV</string>
<string name="treatments_shortname">TRATT</string>
<string name="heartRate_shortname">FC</string>
<string name="sensitivity_shortname">SENS</string>
<string name="graph_scale">Scala del grafico</string>
<string name="graph_menu_divider_header">Grafico</string>
@ -323,7 +325,7 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Nessun cambio profilo attivo!</string>
<string name="profile_message">Profilo:\n\nTimeshift: %1$\nPercentuale: %2$d%%\"</string>
<string name="profile_message">Profilo:\n\nTimeshift: %1$d\nPercentuale: %2$d%%\"</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">Nessun profilo caricato</string>
<string name="aps_only">Si applica solo in modalità APS!</string>

View file

@ -253,6 +253,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">חיזוי</string>
<string name="overview_show_treatments">טיפולים</string>
<string name="overview_show_heartRate">דופק</string>
<string name="overview_show_deviation_slope">שיפוע הסטייה</string>
<string name="overview_show_activity">פעילות</string>
<string name="overview_show_bgi">השפעת הסוכר בדם</string>
@ -270,6 +271,7 @@
<string name="abs_insulin_shortname">אבס\'</string>
<string name="devslope_shortname">שיפוע</string>
<string name="treatments_shortname">TREAT</string>
<string name="heartRate_shortname">דופק</string>
<string name="sensitivity_shortname">רגישות</string>
<string name="graph_scale">קנה מידה של הגרף</string>
<string name="graph_menu_divider_header">גרף</string>
@ -323,7 +325,6 @@
<string name="grams_short">גר\'</string>
<string name="hour_short">ש\'</string>
<string name="no_active_profile">לא הופעלה החלפת פרופיל!</string>
<string name="profile_message">פרופיל:\n\nהיסט זמן: %1$\nאחוז: %2$d%\"</string>
<string name="tdd_line">%1$.2fיח\' %1$.0f%</string>
<string name="no_profile">לא נטען פרופיל</string>
<string name="aps_only">חל רק במצב APS!</string>

View file

@ -323,7 +323,6 @@
<string name="grams_short">g</string>
<string name="hour_short">val</string>
<string name="no_active_profile">Neparinktas aktyvus profilis!</string>
<string name="profile_message">Profilis:\n\nLaiko perstūmimas: %1$\nProcentai: %2$d%%\"</string>
<string name="tdd_line">%1$.2fv %1$.0f%%</string>
<string name="no_profile">Profilis neįkeltas</string>
<string name="aps_only">Tik APS režime!</string>

View file

@ -322,7 +322,6 @@
<string name="grams_short">g</string>
<string name="hour_short">u</string>
<string name="no_active_profile">Geen actieve profielwissel!</string>
<string name="profile_message">Profiel: \n\nTijdverschuiving: %1$\nPercentage: %2$d%%\"</string>
<string name="tdd_line">%1$.2fE %1$.0f%%</string>
<string name="no_profile">Geen profiel geladen</string>
<string name="aps_only">Alleen gebruiken in de APS modus!</string>

View file

@ -253,6 +253,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Prognoser</string>
<string name="overview_show_treatments">Behandlinger</string>
<string name="overview_show_heartRate">Puls</string>
<string name="overview_show_deviation_slope">Avvikskurve</string>
<string name="overview_show_activity">Aktivitet</string>
<string name="overview_show_bgi">Blodsukkerpåvirkning</string>
@ -270,6 +271,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string>
<string name="treatments_shortname">BEH</string>
<string name="heartRate_shortname">HR</string>
<string name="sensitivity_shortname">SENS</string>
<string name="graph_scale">Graf skala</string>
<string name="graph_menu_divider_header">Graf</string>
@ -323,7 +325,7 @@
<string name="grams_short">g</string>
<string name="hour_short">t</string>
<string name="no_active_profile">Det er ikke angitt noen aktiv profil!</string>
<string name="profile_message">Profil:\n\nTidsforskyving: %1$\nProsent: %2$d%%\"</string>
<string name="profile_message">Profil:\n\nTidsforskyving: %1$d$\nProsent: %2$d%%\"</string>
<string name="tdd_line">%1$.2fE %1$.0f%%</string>
<string name="no_profile">Ingen profil valgt</string>
<string name="aps_only">Bare bruk i APS-modus!</string>

View file

@ -323,7 +323,6 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Nie ustawiono aktywnego profilu!</string>
<string name="profile_message">Profil:\n\nZmiana czasu: %1$\nProcent: %2$d%%\"</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">Nie załadowano profilu</string>
<string name="aps_only">Stosuje się tylko w trybie APS!</string>

View file

@ -323,7 +323,6 @@
<string name="grams_short">г</string>
<string name="hour_short">ч</string>
<string name="no_active_profile">Активный профиль не установлен!</string>
<string name="profile_message">Профиль:\n\nСдвиг по времени: %1$\nПроцент: %2$d%%\"</string>
<string name="tdd_line">%1$.2fед%1$.0f%%</string>
<string name="no_profile">Профиль не загружен</string>
<string name="aps_only">Применять только в режиме APS!</string>

View file

@ -254,6 +254,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Predikcie</string>
<string name="overview_show_treatments">Ošetrenia</string>
<string name="overview_show_heartRate">Tepová frekvencia</string>
<string name="overview_show_deviation_slope">Odchýlka sklonu</string>
<string name="overview_show_activity">Aktivita</string>
<string name="overview_show_bgi">Vplyv na glykémiu (BGI)</string>
@ -271,6 +272,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string>
<string name="treatments_shortname">OŠET</string>
<string name="heartRate_shortname">TF</string>
<string name="sensitivity_shortname">SENZ</string>
<string name="graph_scale">Mierka grafu</string>
<string name="graph_menu_divider_header">Graf</string>
@ -324,7 +326,7 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">Nie je nastavený žiadny aktívny profil!</string>
<string name="profile_message">Profil:\n\nPosun času: %1$\nPercento: %2$d%%\"</string>
<string name="profile_message">Profil:\n\nPosunutie: %1$d\nPercento: %2$d%%\"</string>
<string name="tdd_line">%1$.2fJI %1$.0f%%</string>
<string name="no_profile">Nie je vybraný žiadny profil</string>
<string name="aps_only">Použiť iba v APS móde!</string>

View file

@ -254,6 +254,7 @@
<!-- OverviewMenu-->
<string name="overview_show_predictions">Tahminler</string>
<string name="overview_show_treatments">Tedaviler</string>
<string name="overview_show_heartRate">Nabız</string>
<string name="overview_show_deviation_slope">Sapma eğimi</string>
<string name="overview_show_activity">Aktivite</string>
<string name="overview_show_bgi">Kan Şekeri Etkisi</string>
@ -271,6 +272,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">EĞİMSAPMA</string>
<string name="treatments_shortname">TEDAVİ</string>
<string name="heartRate_shortname">Nabız</string>
<string name="sensitivity_shortname">SENS</string>
<string name="graph_scale">Grafik ölçeği</string>
<string name="graph_menu_divider_header">Grafik</string>
@ -324,7 +326,7 @@
<string name="grams_short">gr</string>
<string name="hour_short">sa</string>
<string name="no_active_profile">Etkin profil ayarlanmadı!</string>
<string name="profile_message">Profil:\n\nZaman Kayması: %1$\nYüzde: %2$d%%\"</string>
<string name="profile_message">Profil:\n\nZaman Kayması: %1$d\nYüzde: %2$d%%\"</string>
<string name="tdd_line">%1$.2fÜ %1$.0f%%</string>
<string name="no_profile">Profil yüklenmedi</string>
<string name="aps_only">Sadece APS modunda uygulayın!</string>

View file

@ -291,6 +291,7 @@
<string name="overview_show_predictions">Predictions</string>
<string name="overview_show_treatments">Treatments</string>
<string name="overview_show_heartRate">Heart Rate</string>
<string name="overview_show_deviation_slope">Deviation slope</string>
<string name="overview_show_activity">Activity</string>
<string name="overview_show_bgi">Blood Glucose Impact</string>
@ -308,6 +309,7 @@
<string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string>
<string name="treatments_shortname">TREAT</string>
<string name="heartRate_shortname">HR</string>
<string name="sensitivity_shortname">SENS</string>
<string name="graph_scale">Graph scale</string>
<string name="graph_menu_divider_header">Graph</string>
@ -370,7 +372,7 @@
<string name="grams_short">g</string>
<string name="hour_short">h</string>
<string name="no_active_profile">No active profile switch!</string>
<string name="profile_message">Profile:\n\nTimeshift: %1$\nPercentage: %2$d%%\"</string>
<string name="profile_message">Profile:\n\nTimeshift: %1$d\nPercentage: %2$d%%\"</string>
<string name="key_wear_predictions" translatable="false">wear_predictions</string>
<string name="tdd_line">%1$.2fU %1$.0f%%</string>
<string name="no_profile">No profile loaded</string>

View file

@ -23,6 +23,6 @@ dependencies {
implementation project(':app-wear-shared:shared')
// RuffyScripter
api 'com.google.guava:guava:31.1-jre'
api 'com.google.guava:guava:32.0.1-jre'
}

View file

@ -29,7 +29,7 @@ dependencies {
implementation project(':core:utils')
implementation project(':core:ui')
api 'com.google.guava:guava:31.1-jre'
api 'com.google.guava:guava:32.0.1-jre'
//RxAndroidBle
implementation "com.polidea.rxandroidble3:rxandroidble:1.17.2"

View file

@ -2,9 +2,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".ui.EopatchActivity" />
<activity android:name=".ui.AlarmHelperActivity" />
<activity android:name=".ui.DialogHelperActivity" />
<activity
android:name=".ui.EopatchActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<activity
android:name=".ui.AlarmHelperActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<activity
android:name=".ui.DialogHelperActivity"
android:configChanges="orientation|layoutDirection|screenLayout|density|screenSize|smallestScreenSize"/>
<receiver android:name=".OsAlarmReceiver"/>
</application>

View file

@ -42,6 +42,7 @@ import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.subjects.BehaviorSubject
import org.json.JSONException
import org.json.JSONObject
@ -86,30 +87,30 @@ class EopatchPumpPlugin @Inject constructor(
override fun onStart() {
super.onStart()
mDisposables.add(rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ event: EventPreferenceChange ->
if (event.isChanged(rh.gs(SettingKeys.LOW_RESERVOIR_REMINDERS)) || event.isChanged(rh.gs(SettingKeys.EXPIRATION_REMINDERS))) {
patchManager.changeReminderSetting()
} else if (event.isChanged(rh.gs(SettingKeys.BUZZER_REMINDERS))) {
patchManager.changeBuzzerSetting()
}
}) { throwable: Throwable -> fabricPrivacy.logException(throwable) }
)
mDisposables += rxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ event: EventPreferenceChange ->
if (event.isChanged(rh.gs(SettingKeys.LOW_RESERVOIR_REMINDERS)) || event.isChanged(rh.gs(SettingKeys.EXPIRATION_REMINDERS))) {
patchManager.changeReminderSetting()
} else if (event.isChanged(rh.gs(SettingKeys.BUZZER_REMINDERS))) {
patchManager.changeBuzzerSetting()
}
}, fabricPrivacy::logException)
mDisposables += rxBus
.toObservable(EventAppInitialized::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
preferenceManager.init()
patchManager.init()
alarmManager.init()
}, fabricPrivacy::logException)
mDisposables.add(rxBus
.toObservable(EventAppInitialized::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({
preferenceManager.init()
patchManager.init()
alarmManager.init()
}) { throwable: Throwable -> fabricPrivacy.logException(throwable) }
)
// following was moved from specialEnableCondition()
// specialEnableCondition() is called too often to add there executive code
// This is a required code for maintaining the patch activation phase and maintaining the alarm. It should not be deleted.
//BG -> FG, restart patch activation and trigger unhandled alarm
if (preferenceManager.isInitDone()) {
patchManager.checkActivationProcess()
@ -199,12 +200,12 @@ class EopatchPumpPlugin @Inject constructor(
val nb = preferenceManager.getNormalBasalManager().convertProfileToNormalBasal(profile)
mDisposables.add(
patchManager.startBasal(nb)
.observeOn(aapsSchedulers.main)
.subscribe({ response ->
result.onNext(response.isSuccess)
}, {
result.onNext(false)
})
.observeOn(aapsSchedulers.main)
.subscribe({ response ->
result.onNext(response.isSuccess)
}, {
result.onNext(false)
})
)
do {

View file

@ -1,77 +0,0 @@
package info.nightscout.androidaps.plugins.pump.eopatch;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import java.util.Objects;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
public class OsAlarmService extends Service {
public static final int FOREGROUND_NOTIFICATION_ID = 34534554;
private CompositeDisposable compositeDisposable;
private boolean foreground = false;
@Override
public void onCreate() {
super.onCreate();
compositeDisposable = new CompositeDisposable();
startForeground();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground();
String action = null;
if (action == null) {
return Service.START_NOT_STICKY;
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
((NotificationManager) Objects.requireNonNull(getSystemService(Context.NOTIFICATION_SERVICE))).cancel(FOREGROUND_NOTIFICATION_ID);
compositeDisposable.dispose();
}
public synchronized void startForeground() {
if (!foreground) {
foreground = true;
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void start(Context context) {
Intent intent = new Intent(context, OsAlarmService.class);
// context.startForegroundService(intent);
}
public static void notifyNotification(Context context, boolean isNetworkAvailable) {
notifyNotification(context);
}
public static void notifyNotification(Context context) {
// Notification builder = getNotification(context);
// ((NotificationManager) Objects.requireNonNull(context.getSystemService(Context.NOTIFICATION_SERVICE))).notify(FOREGROUND_NOTIFICATION_ID, builder);
}
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPreferenceManager
import info.nightscout.androidaps.plugins.pump.eopatch.code.AlarmCategory
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventEoPatchAlarm
import info.nightscout.androidaps.plugins.pump.eopatch.extension.takeOne
import info.nightscout.androidaps.plugins.pump.eopatch.ui.AlarmHelperActivity
import info.nightscout.androidaps.plugins.pump.eopatch.vo.Alarms
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -160,10 +161,11 @@ class AlarmManager @Inject constructor() : IAlarmManager {
id = Notification.EOELOW_PATCH_ALERTS + (alarmCode.aeCode + 10000),
text = alarmMsg,
level = Notification.URGENT,
buttonText = R.string.confirm,
buttonText = (alarmCode == B001).takeOne(R.string.string_resume, R.string.confirm),
action = {
compositeDisposable.add(
Single.just(isValid(alarmCode))
.observeOn(aapsSchedulers.main) //don't remove
.flatMap { isValid ->
return@flatMap if (isValid) mAlarmProcess.doAction(context, alarmCode)
else Single.just(IAlarmProcess.ALARM_HANDLED)
@ -179,18 +181,17 @@ class AlarmManager @Inject constructor() : IAlarmManager {
)
}
updateState(alarmCode, AlarmState.HANDLE)
}else if(ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP){
pm.getAlarms().needToStopBeep.add(alarmCode)
updateState(alarmCode, AlarmState.HANDLE)
} else {
uiInteraction.addNotification(
id = Notification.EOELOW_PATCH_ALERTS + (alarmCode.aeCode + 10000),
text = alarmMsg,
level = Notification.URGENT
)
showNotification(alarmCode)
}
}
)
},
soundId = info.nightscout.core.ui.R.raw.error,
date = pm.getPatchConfig().patchWakeupTimestamp + TimeUnit.SECONDS.toMillis(timeOffset)
date = pm.getAlarms().getOccuredAlarmTimestamp(alarmCode)
)
}

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmCode.B012
import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmCode.B018
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.BaseResponse
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.PatchBooleanResponse
import info.nightscout.androidaps.plugins.pump.eopatch.core.response.TemperatureResponse
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventDialog
import info.nightscout.androidaps.plugins.pump.eopatch.event.EventProgressDialog
@ -55,6 +56,7 @@ interface IAlarmProcess {
const val ALARM_UNHANDLED = 0
const val ALARM_PAUSE = 1
const val ALARM_HANDLED = 2
const val ALARM_HANDLED_BUT_NEED_STOP_BEEP = 3
}
}
@ -68,14 +70,14 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
A117, A118 -> patchDeactivationAction(context)
A007 -> inappropriateTemperatureAction(context)
A016 -> needleInsertionErrorAction(context)
B000, B003, B018 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B005, B006 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B000 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B003, B005, B006, B018 -> stopAeBeepAction(context, code)
B012 -> Single.just(IAlarmProcess.ALARM_HANDLED)
}
}
private fun startActivityWithSingleTop(context: Context, intent: Intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
context.startActivity(intent)
}
@ -104,7 +106,7 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
Single.fromCallable {
showCommunicationFailedDialog {
startActivityWithSingleTop(context,
createIntentForCheckConnection(context, goHomeAfterDiscard = true, forceDiscard = true))
createIntentForCheckConnection(context, goHomeAfterDiscard = true, forceDiscard = true, isAlarmHandling = true))
}
IAlarmProcess.ALARM_PAUSE
}
@ -115,6 +117,7 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
return actionWithPatchCheckConnection(context) {
patchManager.resumeBasal()
.map { obj: BaseResponse -> obj.isSuccess }
.onErrorReturn { false }
.flatMap { Single.just(it.takeOne(IAlarmProcess.ALARM_HANDLED, IAlarmProcess.ALARM_UNHANDLED)) }
}
}
@ -148,4 +151,15 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
.defaultIfEmpty(IAlarmProcess.ALARM_UNHANDLED)
}
}
private fun stopAeBeepAction(context: Context, alarm: AlarmCode): Single<Int> {
if (patchManager.patchConnectionState.isConnected) {
return patchManager.stopAeBeep(alarm.aeCode)
.map { obj: PatchBooleanResponse -> obj.isSuccess }
.onErrorReturn { false }
.flatMap { Single.just(it.takeOne(IAlarmProcess.ALARM_HANDLED, IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP)) }
}else{
return Single.just(IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP)
}
}
}

View file

@ -17,6 +17,7 @@ import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -120,6 +121,7 @@ class AlarmRegistry @Inject constructor() : IAlarmRegistry {
return Maybe.fromCallable {
cancelOsAlarmInternal(alarmCode)
val pendingIntent = createPendingIntent(alarmCode, 0)
aapsLogger.debug("[${alarmCode}] OS Alarm added. ${DateUtil(mContext).toISOString(triggerTime)}")
mOsAlarmManager.setAlarmClock(AlarmClockInfo(triggerTime, pendingIntent), pendingIntent)
alarmCode
}

View file

@ -192,7 +192,6 @@ public class PatchManagerImpl {
.filter(it -> patch.getConnectionState().isConnected())
.concatMapIterable(EventEoPatchAlarm::getAlarmCodes)
.filter(AlarmCode::isPatchOccurrenceAlert)
.flatMap(it -> stopAeBeep(it.getAeCode()).toObservable())
.subscribe()
);
@ -250,6 +249,16 @@ public class PatchManagerImpl {
}
return Single.just(true);
})
.flatMap(ret -> {
if(!pm.getAlarms().getNeedToStopBeep().isEmpty()) {
return Observable.fromStream(pm.getAlarms().getNeedToStopBeep().stream())
.flatMapSingle(alarmCode -> stopAeBeep(alarmCode.getAeCode()).doOnSuccess(patchBooleanResponse -> {
pm.getAlarms().getNeedToStopBeep().remove(alarmCode);
}))
.lastOrError();
}
return Single.just(true);
})
.subscribe());
}

View file

@ -36,11 +36,10 @@ public class StartBondTask extends TaskBase {
})
.filter(result -> result == BluetoothDevice.BOND_BONDED)
.map(result -> true)
.timeout(60, TimeUnit.SECONDS)
.timeout(35, TimeUnit.SECONDS)
.doOnNext(v -> prefSetMacAddress(mac))
.doOnError(e -> {
prefSetMacAddress("");
aapsLogger.error(LTag.PUMPCOMM, (e.getMessage() != null) ? e.getMessage() : "StartBondTask error");
})
.firstOrError();
}

View file

@ -30,6 +30,8 @@ public class StopBasalTask extends TaskBase {
@Inject PumpSync pumpSync;
@Inject UserEntryLogger uel;
@Inject UpdateConnectionTask updateConnectionTask;
private final BasalStop BASAL_STOP;
private final BehaviorSubject<Boolean> bolusCheckSubject = BehaviorSubject.create();
private final BehaviorSubject<Boolean> exbolusCheckSubject = BehaviorSubject.create();
@ -93,15 +95,11 @@ public class StopBasalTask extends TaskBase {
.flatMap(v -> isReady())
.concatMapSingle(v -> BASAL_STOP.stop())
.doOnNext(this::checkResponse)
.doOnNext(v -> updateConnectionTask.enqueue())
.firstOrError()
.doOnSuccess(this::onBasalStopped)
.doOnError(e -> aapsLogger.error(LTag.PUMPCOMM, (e.getMessage() != null) ? e.getMessage() : "StopBasalTask error"));
}
private void onBasalStopped(BasalStopResponse response) {
enqueue(TaskFunc.UPDATE_CONNECTION);
}
public synchronized void enqueue() {
boolean ready = (disposable == null || disposable.isDisposed());

View file

@ -4,8 +4,6 @@ import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.media.MediaPlayer
import android.media.RingtoneManager
import android.os.Bundle
import android.view.MotionEvent
import androidx.appcompat.app.AlertDialog
@ -22,8 +20,6 @@ import info.nightscout.androidaps.plugins.pump.eopatch.ui.viewmodel.EopatchViewM
import info.nightscout.core.utils.extensions.safeGetSerializableExtra
class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
private var mediaPlayer: MediaPlayer? = null
private var mPatchCommCheckDialog: Dialog? = null
private var mProgressDialog: AlertDialog? = null
@ -81,26 +77,26 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
setResult(RESULT_DISCARDED)
if (intent.getBooleanExtra(EXTRA_GO_HOME, true)) {
backToHome(false)
backToHome()
} else {
this@EopatchActivity.finish()
}
})
}
PatchStep.COMPLETE -> backToHome(true)
PatchStep.COMPLETE -> backToHome()
PatchStep.FINISH -> {
if (!intent.getBooleanExtra(EXTRA_START_FROM_MENU, false)
|| intent.getBooleanExtra(EXTRA_GO_HOME, true)
) {
backToHome(false)
backToHome()
} else {
this@EopatchActivity.finish()
}
}
PatchStep.BACK_TO_HOME -> backToHome(false)
PatchStep.BACK_TO_HOME -> backToHome()
PatchStep.CANCEL -> this@EopatchActivity.finish()
else -> Unit
}
@ -122,6 +118,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java)
forceDiscard = intent.getBooleanExtra(EXTRA_FORCE_DISCARD, false)
isInAlarmHandling = intent.getBooleanExtra(EXTRA_IS_ALARM_HANDLING, false)
if (intent.getBooleanExtra(EXTRA_START_WITH_COMM_CHECK, false)) {
checkCommunication({
initializePatchStep(step)
@ -220,6 +217,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
// EventType.SHOW_BONDED_DIALOG -> this@EopatchActivity.finish()
EventType.SHOW_DISCARD_DIALOG -> {
val cancelLabel = isInAlarmHandling.takeOne(null, getString(R.string.cancel))
info.nightscout.core.ui.dialogs.AlertDialogHelper.Builder(this@EopatchActivity).apply {
setTitle(R.string.string_discard_patch)
if (isBolusActive) {
@ -238,7 +236,7 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
}
}
setNegativeButton(R.string.cancel) { _, _ ->
setNegativeButton(cancelLabel) { _, _ ->
dismissProgressDialog()
updateIncompletePatchActivationReminder()
}
@ -272,29 +270,10 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
}
}
private fun backToHome(isActivated: Boolean) {
if (isActivated) {
mediaPlayer = MediaPlayer.create(this, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))?.apply {
setOnCompletionListener {
this@EopatchActivity.finish()
}
start()
}
}
private fun backToHome() {
this@EopatchActivity.finish()
}
override fun onDestroy() {
super.onDestroy()
mediaPlayer?.let {
it.stop()
it.release()
mediaPlayer = null
}
}
override fun onBackPressed() {
binding.viewModel?.apply{
when(patchStep.value){
@ -311,16 +290,18 @@ class EopatchActivity : EoBaseActivity<ActivityEopatchBinding>() {
const val EXTRA_START_WITH_COMM_CHECK = "EXTRA_START_WITH_COMM_CHECK"
const val EXTRA_GO_HOME = "EXTRA_GO_HOME"
const val EXTRA_FORCE_DISCARD = "EXTRA_FORCE_DISCARD"
const val EXTRA_IS_ALARM_HANDLING = "EXTRA_IS_ALARM_HANDLING"
const val NORMAL_TEMPERATURE_MIN = 4
const val NORMAL_TEMPERATURE_MAX = 45
@JvmStatic
@JvmOverloads
fun createIntentForCheckConnection(context: Context, goHomeAfterDiscard: Boolean = true, forceDiscard: Boolean = false): Intent {
fun createIntentForCheckConnection(context: Context, goHomeAfterDiscard: Boolean = true, forceDiscard: Boolean = false, isAlarmHandling: Boolean = false): Intent {
return Intent(context, EopatchActivity::class.java).apply {
putExtra(EXTRA_START_PATCH_STEP, PatchStep.CHECK_CONNECTION)
putExtra(EXTRA_GO_HOME, goHomeAfterDiscard)
putExtra(EXTRA_FORCE_DISCARD, forceDiscard)
putExtra(EXTRA_IS_ALARM_HANDLING, isAlarmHandling)
}
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.eopatch.alarm.AlarmProcess
import info.nightscout.androidaps.plugins.pump.eopatch.alarm.IAlarmProcess
import info.nightscout.androidaps.plugins.pump.eopatch.bindingadapters.setOnSafeClickListener
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPatchManager
import info.nightscout.androidaps.plugins.pump.eopatch.ble.IPreferenceManager
import info.nightscout.androidaps.plugins.pump.eopatch.databinding.DialogAlarmBinding
import info.nightscout.androidaps.plugins.pump.eopatch.ui.AlarmHelperActivity
import info.nightscout.core.ui.R
@ -32,6 +33,7 @@ class AlarmDialog : DaggerDialogFragment() {
@Inject lateinit var patchManager: IPatchManager
@Inject lateinit var rxBus: RxBus
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var pm: IPreferenceManager
var helperActivity: AlarmHelperActivity? = null
var alarmCode: AlarmCode? = null
@ -84,7 +86,10 @@ class AlarmDialog : DaggerDialogFragment() {
.subscribeOn(aapsSchedulers.io)
.subscribe ({ ret ->
aapsLogger.debug("Alarm processing result :${ret}")
if (ret == IAlarmProcess.ALARM_HANDLED) {
if (ret == IAlarmProcess.ALARM_HANDLED || ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP) {
if(ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP){
pm.getAlarms().needToStopBeep.add(ac)
}
alarmCode?.let{
patchManager.preferenceManager.getAlarms().handle(it)
patchManager.preferenceManager.flushAlarms()

View file

@ -74,6 +74,7 @@ class EopatchViewModel @Inject constructor(
private const val MAX_ELAPSED_MILLIS_AFTER_EXPIRATION = -12L * 60 * 60 * 1000
}
var forceDiscard = false
var isInAlarmHandling = false
var connectionTryCnt = 0
val patchConfig: PatchConfig = patchManager.patchConfig
@ -312,6 +313,7 @@ class EopatchViewModel @Inject constructor(
CommonUtils.dispose(mCommCheckDisposable)
updateIncompletePatchActivationReminder()
dismissPatchCommCheckDialogInternal(false)
connectionTryCnt = 0
}
@Synchronized

View file

@ -7,6 +7,7 @@ import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.subjects.BehaviorSubject
import java.util.*
import kotlin.collections.HashSet
class Alarms: IPreference<Alarms> {
@Transient
@ -26,6 +27,8 @@ class Alarms: IPreference<Alarms> {
var occurred = HashMap<AlarmCode, AlarmItem>()
var needToStopBeep = HashSet<AlarmCode>()
init {
initObject()
}
@ -36,6 +39,7 @@ class Alarms: IPreference<Alarms> {
fun clear(){
registered.clear()
occurred.clear()
needToStopBeep.clear()
}
fun update(other: Alarms) {
@ -75,6 +79,13 @@ class Alarms: IPreference<Alarms> {
occurred.remove(alarmCode)
}
fun getOccuredAlarmTimestamp(alarmCode: AlarmCode): Long{
return if(occurred.containsKey(alarmCode))
occurred.getValue(alarmCode).triggerTimeMilli
else
System.currentTimeMillis()
}
private fun isRegistered(alarmCode: AlarmCode): Boolean{
return registered.containsKey(alarmCode)
}

View file

@ -144,8 +144,6 @@ class PatchConfig: IPreference<PatchConfig> {
this.standardBolusInjectCount = 0
this.extendedBolusInjectCount = 0
this.basalInjectCount = 0
this.lowReservoirAlertAmount = 10
this.patchExpireAlertTime = 4
this.remainedInsulin = 0f
}

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Prázdný zásobník\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a003">Pumpě vypršela platnost\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a004">Okluze\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a005">Selhání automatického testu\nPumpa byla deaktivována. Vyměňte pumpu.</string>
<string name="string_a007">Nevhodná teplota\nVýdej inzulínu nebo proces \"Aktivování pumpy\" byl zastaven. Vyhněte se extrémní teplotě.</string>
<string name="string_a016">Chyba vložení kanyly\nZkontrolujte pozici páčky a klepněte na \'Opakovat\'.</string>
<string name="string_a018">Chyba baterie\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a019">Chyba baterie\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a020">Chyba aktivace pumpy\nČas na akivaci pumpy vypršel. Klepnutím na \'Potvrdit\' deaktivujete aktuální pumpu. Vyměňte pumpu.</string>
<string name="string_a022">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a023">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a034">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a041">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a042">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a043">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a044">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a106">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a107">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a108">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a116">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a117">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_a118">Chyba pumpy\nPumpa byla deaktivována a byl vypnut výdej inzulínu. Vyměňte pumpu.</string>
<string name="string_b000">Provozní životnost pumpy vyprší %s. Buďte připraveni vyměnit pumpu.</string>
<string name="string_b001">Konec pozastavení pumpy\nKlepnutím na tlačítko \"Pokračovat\" obnovíte výdej inzulínu.</string>
<string name="string_b003">Nízký stav zásobníku\nBrzy vyměňte pumpu.</string>
<string name="string_b005">Provozní životnost vypršela\nVyměňte pumpu.</string>
<string name="string_b006">Pumpa brzy vyprší\nVyměňte pumpu.</string>
<string name="string_b012">Neúplná aktivace pumpy\nDokončete proces \'Aktivace pumpy\'.</string>
<string name="string_b018">Nízký stav baterie\nBuďte připraveni vyměnit pumpu.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Reservorio vacío\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a003">Parche expirado\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a004">Oclusión\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a005">Error en la prueba de encendido\nEl parche ha sido desactivado. Cambia el parche ahora.</string>
<string name="string_a007">Temperatura inadecuada\nEntrega de insulina o proceso de \'Activar parche\' detenido. Evita la temperatura extrema ahora.</string>
<string name="string_a016">Error en la insercción de la aguja\nComprueba la posición de la palanca y pulsa en \'Reintentar\'.</string>
<string name="string_a018">Error de batería del parche\nEl parche ha sido desactivado y\se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a019">Error de batería del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a020">Error en la activación del parche\n\'El proceso de \'Activar parche\' ha expirdado. Pulsa\'Confirmar\'para desactivar el parche actual. Cambia el parche ahora.</string>
<string name="string_a022">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a023">Error del parche\nEl parche ha sido desactivado y\se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a034">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a041">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a042">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a043">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a044">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a106">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a107">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a108">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a116">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a117">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_a118">Error del parche\nEl parche ha sido desactivado y se ha detenido la entrega de insulina. Cambia el parche ahora.</string>
<string name="string_b000">La vida útil del parche expira %s. Prepárate para cambiar el parche.</string>
<string name="string_b001">Fin de la suspensión de insulina\nPulsa en \'Reanudar\' para reanudar la entrega de insulina.</string>
<string name="string_b003">Reservorio bajo\nReemplaza el parche pronto.</string>
<string name="string_b005">La vida útil del parche ha expirado\nCambia el parche ahora.</string>
<string name="string_b006">El parche expira pronto\nCambia el parche ahora.</string>
<string name="string_b012">Activación incompleta del parche\nCompleta el proceso de \'Activar parche\'.</string>
<string name="string_b018">Batería baja del parche\nPrepárate para cambiar el parche.</string>
</resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Réservoir vide\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a003">Le Patch a expiré\nLe Patch a été désactivé et la distribution d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a004">Occlusion\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a005">Échec de l\'auto-test au démarrage\nLe Patch a été désactivé. Changez le Patch.</string>
<string name="string_a007">Température inadaptée\nL\'injection d\'insuline ou \"L\'activation du Patch\" ont été arrêtées. Corrigez la température extrême maintenant.</string>
<string name="string_a016">Erreur d\'insertion d\'aiguille\nVérifiez la position du bouton et appuyez sur \'Réessayer\'.</string>
<string name="string_a018">Erreur batterie du Patch\nLe Patch a été désactivé et\nl\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a019">Erreur batterie du Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a020">Erreur d\'activation du Patch\nle processus \'Activer le Patch\' a expiré. Appuyez sur \'Confirmer\' pour désactiver le Patch actuel. Changez le Patch.</string>
<string name="string_a022">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a023">Erreur Patch\nLe Patch a été désactivé et\n l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a034">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a041">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a042">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a043">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a044">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a106">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a107">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a108">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a116">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a117">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_a118">Erreur Patch\nLe Patch a été désactivé et l\'injection d\'insuline a été arrêtée. Changez le Patch maintenant.</string>
<string name="string_b000">La durée de vie du Patch expirera %s. Soyez prêt à changer le Patch.</string>
<string name="string_b001">Fin de la suspension d\'insuline\nAppuyez sur « Reprendre » pour redémarrer l\'injection d\'insuline.</string>
<string name="string_b003">Réservoir bas\nRemplacer le patch bientôt.</string>
<string name="string_b005">Le Patch a expiré\nChanger le Patch maintenant.</string>
<string name="string_b006">Le Patch va bientôt expirer\nChanger le Patch maintenant.</string>
<string name="string_b012">Activation du Patch incomplète\nTerminez le processus \'Activer le Patch\'.</string>
<string name="string_b018">Batterie du Patch faible\nSoyez prêt à changer le Patch.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Serbatoio vuoto\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a003">Patch scaduta\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a004">Occlusione\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a005">Autotest di accensione non riuscito\nLa patch è stata disattivata. Cambia patch ora.</string>
<string name="string_a007">Temperatura inappropriata\nL\'erogazione di insulina o il processo \'Attiva patch\" sono stati fermati. Agisci ora per evitare temperature estreme.</string>
<string name="string_a016">Errore inserimento ago\nControlla la posizione della manopola e tocca \'Riprova\'.</string>
<string name="string_a018">Errore batteria patch\nLa patch è stata disattivata e\nl\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a019">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a020">Errore attivazione patch\nIl processo \'Attiva patch\' è scaduto. Tocca \'Conferma\' per disattivare la patch corrente. Cambia patch ora.</string>
<string name="string_a022">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a023">Errore batteria patch\nLa patch è stata disattivata e\nl\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a034">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a041">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a042">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a043">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a044">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a106">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a107">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a108">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a116">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a117">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_a118">Errore batteria patch\nLa patch è stata disattivata e l\'erogazione di insulina fermata. Cambia patch ora.</string>
<string name="string_b000">La durata operativa della patch scadrà %s. Sii pronto a cambiare patch.</string>
<string name="string_b001">Fine della sospensione dell\'insulina\nTocca \'Riprendi\' per riavviare l\'erogazione di insulina.</string>
<string name="string_b003">Livello serbatoio basso\nSostituisci la patch presto.</string>
<string name="string_b005">Durata operativa della patch scaduta\nCambia patch ora.</string>
<string name="string_b006">La patch scadrà presto\nCambia patch ora.</string>
<string name="string_b012">Attivazione patch incompleta\nCompleta il processo \'Attiva patch\'.</string>
<string name="string_b018">Batteria patch quasi scarica\nSii pronto a cambiare patch.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Prázdny zásobník\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a003">Pumpe vypršala platnosť\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a004">Oklúzia\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a005">Zlyhanie automatického testu\nPumpa bola deaktivovaná. Vymeňte pumpu.</string>
<string name="string_a007">Nevhodná teplota\nPodávanie inzulínu, alebo proces \"Aktivovania pumpy\" bol zastavený. Vyhnite se extrémnej teplote.</string>
<string name="string_a016">Chyba vloženia kanyly\nSkontrolujte pozíciu páčky a stlačte \'Opakovať\'.</string>
<string name="string_a018">Chyba batérie\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a019">Chyba batérie\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a020">Chyba aktivácie pumpy\nČas na aktiváciu pumpy vypršal. Stlačením \'Potvrdiť\' deaktivujete aktuálnu pumpu. Vymeňte pumpu.</string>
<string name="string_a022">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a023">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a034">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a041">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a042">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a043">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a044">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a106">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a107">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a108">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a116">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a117">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_a118">Chyba pumpy\nPumpa bola deaktivovaná a podávanie inzulínu bolo zastavené. Vymeňte pumpu.</string>
<string name="string_b000">Životnosť pumpy vyprší %s. Buďte pripravený vymeniť pumpu.</string>
<string name="string_b001">Koniec pozastavenia pumpy\nStlačením tlačítka \"Pokračovať\" obnovíte podávanie inzulínu.</string>
<string name="string_b003">Nízký stav zásobníka\nVymeňte pumpu čo možno najskôr..</string>
<string name="string_b005">Životnosť pumpy vypršala\nVymeňte pumpu.</string>
<string name="string_b006">Pumpa čoskoro vyprší\nVymeňte pumpu.</string>
<string name="string_b012">Neúplná aktivácia pumpy\nDokončite proces \'Aktivácia pumpy\'.</string>
<string name="string_b018">Nízký stav batérie\nBuďte pripravený vymeniť pumpu.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="string_a002">Boş rezervuar\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a003">Patch süresi doldu\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a004">Tıkanma\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Patch\'i değiştirin.</string>
<string name="string_a005">ılışta otomatik test hatası\nPatch devre dışı bırakıldı. Şimdi Patch\'i değiştirin.</string>
<string name="string_a007">Uygun olmayan sıcaklık\nİnsülin iletimi veya \"Patch Etkinleştir\" işlemi durduruldu. Şimdi aşırı sıcaklıktan kaçının.</string>
<string name="string_a016">İğne yerleştirme Hatası\nDüğme konumunu kontrol edin ve \'Yeniden Dene\'ye dokunun.</string>
<string name="string_a018">Patch pil hatası\nPatch devre dışı bırakıldı ve\ninsülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a019">Patch pil hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a020">Patch etkinleştirme Hatası\n\'Patch Etkinleştir\' işleminin süresi doldu. Geçerli Patch\'i devre dışı bırakmak için \'Onayla\'ya dokunun. Şimdi Patch\'i değiştirin.</string>
<string name="string_a022">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a023">Patch Hatası\nPatch devre dışı bırakıldı ve\ninsülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a034">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a041">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a042">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a043">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a044">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a106">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a107">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a108">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a116">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a117">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_a118">Patch Hatası\nPatch devre dışı bırakıldı ve insülin iletimi durduruldu. Şimdi Patch\'i değiştirin.</string>
<string name="string_b000">Patch ömrü %s sona erecek. Patch\'i değiştirmeye hazır olun.</string>
<string name="string_b001">İnsülin askıya alma işleminin sonu\nİnsülin iletimini yeniden başlatmak için \'Devam Et\'e dokunun.</string>
<string name="string_b003">Düşük rezervuar\nPatch\'i yakında değiştirin.</string>
<string name="string_b005">Patch çalışma ömrü doldu\nPatch\'i şimdi değiştirin.</string>
<string name="string_b006">Patch yakında sona erecek\nPatch\'i şimdi değiştirin.</string>
<string name="string_b012">Eksik Patch Etkinleştirme\n\'Patch Etkinleştir\' işlemini tamamlayın.</string>
<string name="string_b018">Patch pili zayıf\nPatch değiştirmeye hazır olun.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>

View file

@ -59,7 +59,7 @@
<string name="omnipod_common_overview_temp_basal_rate">Débit de Basal Temp.</string>
<string name="omnipod_common_overview_base_basal_rate">Débit de Basal</string>
<string name="omnipod_common_overview_reservoir">Réservoir</string>
<string name="omnipod_common_overview_pod_active_alerts">Activer Alertes Pod</string>
<string name="omnipod_common_overview_pod_active_alerts">Dernières alertes Pod</string>
<string name="omnipod_common_overview_firmware_version">Version du firmware</string>
<string name="omnipod_common_overview_time_on_pod">Heure du Pod</string>
<string name="omnipod_common_overview_temp_basal_value">%1$.2fU/h @%2$s (%3$d/%4$d minutes)</string>

View file

@ -328,6 +328,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
podStateManager.updateActiveCommand()
.map { handleCommandConfirmation(it) }
.ignoreElement(),
verifyPumpState(),
checkPodKaput(),
)
)
@ -572,9 +573,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
.bolusDelivered(0.0)
.comment(rh.gs(R.string.omnipod_dash_not_enough_insulin))
}
if (podStateManager.deliveryStatus == DeliveryStatus.BOLUS_AND_BASAL_ACTIVE ||
podStateManager.deliveryStatus == DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE
) {
if (podStateManager.deliveryStatus?.bolusDeliveringActive() == true) {
return PumpEnactResult(injector)
.success(false)
.enacted(false)
@ -632,14 +631,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
)
} else {
if (podStateManager.activeCommand != null) {
val sound =
if (sp.getBoolean(
info.nightscout.androidaps.plugins.pump.omnipod.common.R.string
.key_omnipod_common_notification_uncertain_bolus_sound_enabled, true
)
) info.nightscout.core.ui.R.raw.boluserror
else 0
val sound = if (hasBolusErrorBeepEnabled()) info.nightscout.core.ui.R.raw.boluserror else 0
showErrorDialog(rh.gs(R.string.bolus_delivery_status_uncertain), sound)
}
}
@ -714,7 +706,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
val percent = (waited.toFloat() / estimatedDeliveryTimeSeconds) * 100
updateBolusProgressDialog(
rh.gs(info.nightscout.pump.common.R.string.bolus_delivered_so_far, Round.roundTo(percent*requestedBolusAmount/100, PodConstants.POD_PULSE_BOLUS_UNITS), requestedBolusAmount),
rh.gs(info.nightscout.pump.common.R.string.bolus_delivered_so_far, Round.roundTo(percent * requestedBolusAmount / 100, PodConstants.POD_PULSE_BOLUS_UNITS), requestedBolusAmount),
percent.toInt()
)
}
@ -897,9 +889,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
private fun observeNoActiveTempBasal(): Completable {
return Completable.defer {
if (podStateManager.deliveryStatus !in
arrayOf(DeliveryStatus.TEMP_BASAL_ACTIVE, DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE)
) {
if (podStateManager.deliveryStatus?.tempBasalActive() == false) {
// TODO: what happens if we try to cancel nonexistent temp basal?
aapsLogger.info(LTag.PUMP, "No temporary basal to cancel")
Completable.complete()
@ -946,6 +936,13 @@ class OmnipodDashPumpPlugin @Inject constructor(
return sp.getBoolean(info.nightscout.androidaps.plugins.pump.omnipod.common.R.string.key_omnipod_common_basal_beeps_enabled, false)
}
private fun hasBolusErrorBeepEnabled(): Boolean {
return sp.getBoolean(
info.nightscout.androidaps.plugins.pump.omnipod.common.R.string
.key_omnipod_common_notification_uncertain_bolus_sound_enabled, true
)
}
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
if (!podStateManager.tempBasalActive &&
pumpSync.expectedPumpState().temporaryBasal == null
@ -1323,6 +1320,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
podStateManager.updateActiveCommand()
.map { handleCommandConfirmation(it) }
.ignoreElement(),
verifyPumpState(),
checkPodKaput(),
refreshOverview(),
post,
@ -1488,6 +1486,40 @@ class OmnipodDashPumpPlugin @Inject constructor(
}
}
private fun verifyPumpState(): Completable = Completable.defer {
aapsLogger.debug(LTag.PUMP, "verifyPumpState, AAPS: ${pumpSync.expectedPumpState().temporaryBasal} Pump: ${podStateManager.deliveryStatus}")
val tbr = pumpSync.expectedPumpState().temporaryBasal
if (tbr != null && podStateManager.deliveryStatus?.basalActive() == true) {
aapsLogger.error(LTag.PUMP, "AAPS expected a TBR running but pump has no TBR running! AAPS: ${pumpSync.expectedPumpState().temporaryBasal} Pump: ${podStateManager.deliveryStatus}")
// Alert user
val sound = if (hasBolusErrorBeepEnabled()) info.nightscout.core.ui.R.raw.boluserror else 0
showErrorDialog(rh.gs(R.string.temp_basal_out_of_sync), sound)
// Sync stopped basal with AAPS
val ret = pumpSync.syncStopTemporaryBasalWithPumpId(
System.currentTimeMillis(), // Note: It would be nice if TBR end could be estimated, but this will add a lot of complexity
tbr.id,
PumpType.OMNIPOD_DASH,
serialNumber()
)
aapsLogger.info(LTag.PUMP, "syncStopTemporaryBasalWithPumpId ret=$ret pumpId=${tbr.id}")
podStateManager.tempBasal = null
} else if (tbr == null && podStateManager.deliveryStatus?.tempBasalActive() == true) {
aapsLogger.error(LTag.PUMP, "AAPS expected no TBR running but pump has a TBR running! AAPS: ${pumpSync.expectedPumpState().temporaryBasal} Pump: ${podStateManager.deliveryStatus}")
// Alert user
val sound = if (hasBolusErrorBeepEnabled()) info.nightscout.core.ui.R.raw.boluserror else 0
showErrorDialog(rh.gs(R.string.temp_basal_out_of_sync), sound)
// If this is reached is reached there is probably a something wrong with the time (maybe it has changed?).
// No way to calculate the TBR end time and update pumpSync properly.
// Cancel TBR running on Pump
return@defer observeNoActiveTempBasal()
.concatWith(podStateManager.updateActiveCommand()
.map { handleCommandConfirmation(it) }
.ignoreElement())
}
return@defer Completable.complete()
}
private fun showErrorDialog(message: String, sound: Int) {
uiInteraction.runAlarm(message, rh.gs(info.nightscout.core.ui.R.string.error), sound)
}

View file

@ -96,7 +96,6 @@ class Connection(
connectionWaitCond.timeoutMs = newTimeout
}
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
_connectionWaitCond = null
val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks, this)
val discovered = discoverer.discoverServices(connectionWaitCond)
@ -122,21 +121,24 @@ class Connection(
cmdBleIO.hello()
cmdBleIO.readyToRead()
dataBleIO.readyToRead()
_connectionWaitCond = null
}
@Synchronized
fun disconnect(closeGatt: Boolean) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting closeGatt=$closeGatt")
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
if (closeGatt) {
gattConnection?.close()
gattConnection = null
} else {
if (closeGatt == false && gattConnection != null) {
// Disconnect first, then close gatt
gattConnection?.disconnect()
} else {
// Call with closeGatt=true only when ble is already disconnected or there is no connection
gattConnection?.close()
bleCommCallbacks.resetConnection()
gattConnection = null
session = null
msgIO = null
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
}
bleCommCallbacks.resetConnection()
session = null
msgIO = null
}
private fun waitForConnection(connectionWaitCond: ConnectionWaitCondition): ConnectionState {

View file

@ -16,6 +16,10 @@ enum class DeliveryStatus(override val value: Byte) : HasValue {
return value in arrayOf(BOLUS_AND_BASAL_ACTIVE.value, BOLUS_AND_TEMP_BASAL_ACTIVE.value)
}
fun basalActive(): Boolean {
return value in arrayOf(BOLUS_AND_BASAL_ACTIVE.value, BASAL_ACTIVE.value)
}
fun tempBasalActive(): Boolean {
return value in arrayOf(BOLUS_AND_TEMP_BASAL_ACTIVE.value, TEMP_BASAL_ACTIVE.value)
}

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.history
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
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.definition.PodConstants.Companion.POD_PULSE_BOLUS_UNITS
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmationDenied
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmationSuccess
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandSendingFailure
@ -57,6 +58,7 @@ class DashHistory @Inject constructor(
tempBasalRecord: TempBasalRecord? = null,
bolusRecord: BolusRecord? = null,
basalProfileRecord: BasalValuesRecord? = null,
totalAmountDeliveredRecord: Double? = null,
resolveResult: ResolvedResult? = null,
resolvedAt: Long? = null
): Single<Long> = Single.defer {
@ -79,6 +81,7 @@ class DashHistory @Inject constructor(
tempBasalRecord = tempBasalRecord,
bolusRecord = bolusRecord,
basalProfileRecord = basalProfileRecord,
totalAmountDelivered = totalAmountDeliveredRecord,
initialResult = initialResult,
resolvedResult = resolveResult,
resolvedAt = resolvedAt
@ -99,18 +102,23 @@ class DashHistory @Inject constructor(
logger.error(LTag.PUMP, "HistoryId not found to for updating from state")
return@defer Completable.complete()
}
when (podState.getCommandConfirmationFromState()) {
CommandSendingFailure ->
val setTotalAmountDelivered = dao.setTotalAmountDelivered(historyId, podState.pulsesDelivered?.times(POD_PULSE_BOLUS_UNITS))
val commandConfirmation = when (podState.getCommandConfirmationFromState()) {
CommandSendingFailure ->
dao.setInitialResult(historyId, InitialResult.FAILURE_SENDING)
CommandSendingNotConfirmed ->
dao.setInitialResult(historyId, InitialResult.SENT)
CommandConfirmationDenied ->
CommandConfirmationDenied ->
markFailure(historyId)
CommandConfirmationSuccess ->
dao.setInitialResult(historyId, InitialResult.SENT)
.andThen(markSuccess(historyId))
NoActiveCommand ->
NoActiveCommand ->
Completable.complete()
}
Completable.concat(listOf(setTotalAmountDelivered, commandConfirmation))
}
}

View file

@ -9,6 +9,7 @@ data class HistoryRecord(
val commandType: OmnipodCommandType,
val initialResult: InitialResult,
val record: Record?,
val totalAmountDelivered: Double?,
val resolvedResult: ResolvedResult?,
val resolvedAt: Long?
) {

View file

@ -18,7 +18,7 @@ abstract class DashHistoryDatabase : RoomDatabase() {
companion object {
const val VERSION = 3
const val VERSION = 4
fun build(context: Context) =
Room.databaseBuilder(

View file

@ -36,4 +36,7 @@ abstract class HistoryRecordDao {
@Query("UPDATE historyrecords SET initialResult = :initialResult WHERE id = :id ")
abstract fun setInitialResult(id: Long, initialResult: InitialResult): Completable
@Query("UPDATE historyrecords SET totalAmountDelivered = :totalAmountDelivered WHERE id = :id ")
abstract fun setTotalAmountDelivered(id: Long, totalAmountDelivered: Double?): Completable
}

View file

@ -27,6 +27,7 @@ data class HistoryRecordEntity(
@Embedded(prefix = "tempBasalRecord_") val tempBasalRecord: TempBasalRecord?,
@Embedded(prefix = "bolusRecord_") val bolusRecord: BolusRecord?,
@Embedded(prefix = "basalprofile_") val basalProfileRecord: BasalValuesRecord?,
val totalAmountDelivered: Double?,
val resolvedResult: ResolvedResult?,
val resolvedAt: Long?
)

View file

@ -13,6 +13,7 @@ class HistoryMapper {
initialResult = entity.initialResult,
commandType = entity.commandType,
record = entity.bolusRecord ?: entity.tempBasalRecord ?: entity.basalProfileRecord,
totalAmountDelivered = entity.totalAmountDelivered,
resolvedResult = entity.resolvedResult,
resolvedAt = entity.resolvedAt
)

View file

@ -213,6 +213,7 @@ class DashPodHistoryActivity : TranslatedDaggerAppCompatActivity() {
holder.timeView.text = DateTimeUtil.toStringFromTimeInMillis(it.displayTimestamp())
setValue(it, holder.valueView)
setType(it, holder.typeView)
setAmount(it, holder.amountView)
}
}
@ -297,6 +298,12 @@ class DashPodHistoryActivity : TranslatedDaggerAppCompatActivity() {
setTextViewColor(check_result = false, valueView, historyEntry)
}
private fun setAmount(historyEntry: HistoryRecord, amountView: TextView) {
amountView.text = historyEntry.totalAmountDelivered?.let { rh.gs(R.string.omnipod_common_history_total_delivered, it) }
// Set some color
setTextViewColor(check_result = false, amountView, historyEntry)
}
override fun getItemCount(): Int {
return historyList.size
}
@ -306,6 +313,7 @@ class DashPodHistoryActivity : TranslatedDaggerAppCompatActivity() {
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)
val amountView: TextView = itemView.findViewById(R.id.omnipod_history_amount)
}
}

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