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

This commit is contained in:
jbr7rr 2023-07-16 11:08:21 +02:00
commit 3f88e05898
31 changed files with 477 additions and 86 deletions

View file

@ -136,7 +136,7 @@ class MainApp : DaggerApplication() {
)
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
KeepAliveWorker.KA_0,
ExistingPeriodicWorkPolicy.REPLACE,
ExistingPeriodicWorkPolicy.UPDATE,
PeriodicWorkRequest.Builder(KeepAliveWorker::class.java, 15, TimeUnit.MINUTES)
.setInputData(Data.Builder().putString("schedule", KeepAliveWorker.KA_0).build())
.setInitialDelay(5, TimeUnit.SECONDS)

View file

@ -7,10 +7,10 @@ buildscript {
rxjava_version = '3.1.6'
rxandroid_version = '3.0.2'
rxkotlin_version = '3.0.1'
room_version = '2.5.1'
room_version = '2.5.2'
lifecycle_version = '2.6.1'
dagger_version = '2.46.1'
coroutines_version = '1.7.1'
dagger_version = '2.47'
coroutines_version = '1.7.2'
activity_version = '1.7.2'
fragmentktx_version = '1.6.0'
ormLite_version = '4.46'
@ -22,7 +22,8 @@ buildscript {
constraintlayout_version = '2.1.4'
preferencektx_version = '1.2.0'
commonslang3_version = '3.12.0'
commonscodec_version = '1.15'
commonscodec_version = '1.16.0'
guava_version = '32.0.1-jre'
jodatime_version = '2.10.14'
work_version = '2.8.1'
tink_version = '1.9.0'
@ -59,7 +60,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.6'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.7'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@ -75,7 +76,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.4.0"
id "org.jlleitschuh.gradle.ktlint" version "11.5.0"
id 'org.barfuin.gradle.jacocolog' version '3.1.0'
id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
}

View file

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

View file

@ -0,0 +1,6 @@
<vector android:height="40dp"
android:viewportHeight="108"
android:viewportWidth="123"
android:width="46dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ed1b24" android:fillType="evenOdd" android:pathData="M60.83,17.18c8,-8.35 13.62,-15.57 26,-17C110,-2.46 131.27,21.26 119.57,44.61c-3.33,6.65 -10.11,14.56 -17.61,22.32 -8.23,8.52 -17.34,16.87 -23.72,23.2l-17.4,17.26L46.46,93.55C29.16,76.89 1,55.92 0,29.94 -0.63,11.74 13.73,0.08 30.25,0.29c14.76,0.2 21,7.54 30.58,16.89Z"/>
</vector>

View file

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

View file

@ -31,6 +31,7 @@ import info.nightscout.automation.triggers.TriggerBolusAgo
import info.nightscout.automation.triggers.TriggerCOB
import info.nightscout.automation.triggers.TriggerConnector
import info.nightscout.automation.triggers.TriggerDelta
import info.nightscout.automation.triggers.TriggerHeartRate
import info.nightscout.automation.triggers.TriggerIob
import info.nightscout.automation.triggers.TriggerLocation
import info.nightscout.automation.triggers.TriggerProfilePercent
@ -41,6 +42,7 @@ import info.nightscout.automation.triggers.TriggerTempTargetValue
import info.nightscout.automation.triggers.TriggerTime
import info.nightscout.automation.triggers.TriggerTimeRange
import info.nightscout.automation.triggers.TriggerWifiSsid
import info.nightscout.automation.ui.TimerUtil
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
@ -53,7 +55,6 @@ import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.queue.Callback
import info.nightscout.automation.ui.TimerUtil
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventBTChange
@ -406,6 +407,7 @@ class AutomationPlugin @Inject constructor(
TriggerBolusAgo(injector),
TriggerPumpLastConnection(injector),
TriggerBTDevice(injector),
TriggerHeartRate(injector),
)
}

View file

@ -38,6 +38,7 @@ import info.nightscout.automation.triggers.TriggerCOB
import info.nightscout.automation.triggers.TriggerConnector
import info.nightscout.automation.triggers.TriggerDelta
import info.nightscout.automation.triggers.TriggerDummy
import info.nightscout.automation.triggers.TriggerHeartRate
import info.nightscout.automation.triggers.TriggerIob
import info.nightscout.automation.triggers.TriggerLocation
import info.nightscout.automation.triggers.TriggerProfilePercent
@ -75,6 +76,7 @@ abstract class AutomationModule {
@ContributesAndroidInjector abstract fun triggerConnectorInjector(): TriggerConnector
@ContributesAndroidInjector abstract fun triggerDeltaInjector(): TriggerDelta
@ContributesAndroidInjector abstract fun triggerDummyInjector(): TriggerDummy
@ContributesAndroidInjector abstract fun triggerHeartRateInjector(): TriggerHeartRate
@ContributesAndroidInjector abstract fun triggerIobInjector(): TriggerIob
@ContributesAndroidInjector abstract fun triggerLocationInjector(): TriggerLocation
@ContributesAndroidInjector abstract fun triggerProfilePercentInjector(): TriggerProfilePercent

View file

@ -95,6 +95,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
TriggerConnector::class.java.simpleName -> TriggerConnector(injector).fromJSON(data.toString())
TriggerDelta::class.java.simpleName -> TriggerDelta(injector).fromJSON(data.toString())
TriggerDummy::class.java.simpleName -> TriggerDummy(injector).fromJSON(data.toString())
TriggerHeartRate::class.java.simpleName -> TriggerHeartRate(injector).fromJSON(data.toString())
TriggerLocation::class.java.simpleName -> TriggerLocation(injector).fromJSON(data.toString())
TriggerProfilePercent::class.java.simpleName -> TriggerProfilePercent(injector).fromJSON(data.toString())
TriggerPumpLastConnection::class.java.simpleName -> TriggerPumpLastConnection(injector).fromJSON(data.toString())

View file

@ -0,0 +1,79 @@
package info.nightscout.automation.triggers
import android.widget.LinearLayout
import androidx.annotation.VisibleForTesting
import com.google.common.base.Optional
import dagger.android.HasAndroidInjector
import info.nightscout.automation.R
import info.nightscout.automation.elements.Comparator
import info.nightscout.automation.elements.InputDouble
import info.nightscout.automation.elements.LabelWithElement
import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
import java.text.DecimalFormat
class TriggerHeartRate(injector: HasAndroidInjector) : Trigger(injector) {
@VisibleForTesting val averageHeartRateDurationMillis = 330 * 1000L
private val minValue = 30
private val maxValue = 250
var heartRate: InputDouble = InputDouble(80.0, minValue.toDouble(), maxValue.toDouble(), 10.0, DecimalFormat("1"))
var comparator: Comparator = Comparator(rh).apply {
value = Comparator.Compare.IS_EQUAL_OR_GREATER
}
override fun shouldRun(): Boolean {
if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.info(LTag.AUTOMATION, "HR ready, no limit set ${friendlyDescription()}")
return true
}
val start = dateUtil.now() - averageHeartRateDurationMillis
val hrs = repository.getHeartRatesFromTime(start)
val duration = hrs.takeUnless { it.isEmpty() }?.sumOf { hr -> hr.duration } ?: 0L
if (duration == 0L) {
aapsLogger.info(LTag.AUTOMATION, "HR not ready, no heart rate measured for ${friendlyDescription()}")
return false
}
val hr = hrs.sumOf { hr -> hr.beatsPerMinute * hr.duration } / duration.toDouble()
return comparator.value.check(hr, heartRate.value).also {
aapsLogger.info(LTag.AUTOMATION, "HR ${if (it) "" else "not "}ready for $hr for ${friendlyDescription()}")
}
}
override fun dataJSON(): JSONObject =
JSONObject()
.put("heartRate", heartRate.value)
.put("comparator", comparator.value.toString())
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)
heartRate.setValue(JsonHelper.safeGetDouble(d, "heartRate"))
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
return this
}
override fun friendlyName(): Int = R.string.triggerHeartRate
override fun friendlyDescription(): String =
rh.gs(R.string.triggerHeartRateDesc, rh.gs(comparator.value.stringRes), heartRate.value)
override fun icon(): Optional<Int> = Optional.of(info.nightscout.core.main.R.drawable.ic_cp_heart_rate)
override fun duplicate(): Trigger {
return TriggerHeartRate(injector).also { o ->
o.heartRate.setValue(heartRate.value)
o.comparator.setValue(comparator.value)
}
}
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(StaticLabel(rh, R.string.triggerHeartRate, this))
.add(comparator)
.add(LabelWithElement(rh, rh.gs(R.string.triggerHeartRate) + ": ", "", heartRate))
.build(root)
}
}

View file

@ -94,6 +94,8 @@
<string name="lastboluscompared">Last bolus time %1$s %2$s min ago</string>
<string name="triggercoblabel">COB</string>
<string name="cobcompared">COB %1$s %2$.0f</string>
<string name="triggerHeartRate">Heart Rate</string>
<string name="triggerHeartRateDesc">HR %1$s %2$.0f</string>
<string name="iob_u">IOB [U]:</string>
<string name="distance_short">Dist [m]:</string>
<string name="recurringTime">Recurring time</string>

View file

@ -0,0 +1,126 @@
package info.nightscout.automation.triggers
import info.nightscout.automation.R
import info.nightscout.automation.elements.Comparator
import info.nightscout.database.entities.HeartRate
import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotSame
import org.junit.Assert.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when`
class TriggerHeartRateTest : TriggerTestBase() {
private var now = 1000L
@BeforeEach
fun mock() {
`when`(dateUtil.now()).thenReturn(now)
}
@Test
fun friendlyName() {
assertEquals(R.string.triggerHeartRate, TriggerHeartRate(injector).friendlyName())
}
@Test
fun friendlyDescription() {
val t = TriggerHeartRate(injector)
`when`(rh.gs(Comparator.Compare.IS_EQUAL_OR_GREATER.stringRes)).thenReturn(">")
`when`(rh.gs(R.string.triggerHeartRateDesc, ">", 80.0)).thenReturn("test")
assertEquals("test", t.friendlyDescription())
}
@Test
fun duplicate() {
val t = TriggerHeartRate(injector).apply {
heartRate.value = 100.0
comparator.value = Comparator.Compare.IS_GREATER
}
val dup = t.duplicate() as TriggerHeartRate
assertNotSame(t, dup)
assertEquals(100.0, dup.heartRate.value, 0.01)
assertEquals(Comparator.Compare.IS_GREATER, dup.comparator.value)
}
@Test
fun shouldRunNotAvailable() {
val t = TriggerHeartRate(injector).apply { comparator.value = Comparator.Compare.IS_NOT_AVAILABLE }
assertTrue(t.shouldRun())
verifyNoMoreInteractions(repository)
}
@Test
fun shouldRunNoHeartRate() {
val t = TriggerHeartRate(injector).apply {
heartRate.value = 100.0
comparator.value = Comparator.Compare.IS_GREATER
}
`when`(repository.getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)).thenReturn(emptyList())
assertFalse(t.shouldRun())
verify(repository).getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)
verifyNoMoreInteractions(repository)
}
@Test
fun shouldRunBelowThreshold() {
val t = TriggerHeartRate(injector).apply {
heartRate.value = 100.0
comparator.value = Comparator.Compare.IS_GREATER
}
val hrs = listOf(
HeartRate(duration = 300_000, timestamp = now - 300_000, beatsPerMinute = 80.0, device = "test"),
HeartRate(duration = 300_000, timestamp = now, beatsPerMinute = 60.0, device = "test"),
)
`when`(repository.getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)).thenReturn(hrs)
assertFalse(t.shouldRun())
verify(repository).getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)
verifyNoMoreInteractions(repository)
}
@Test
fun shouldRunTrigger() {
val t = TriggerHeartRate(injector).apply {
heartRate.value = 100.0
comparator.value = Comparator.Compare.IS_GREATER
}
val hrs = listOf(
HeartRate(duration = 300_000, timestamp = now, beatsPerMinute = 120.0, device = "test"),
)
`when`(repository.getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)).thenReturn(hrs)
assertTrue(t.shouldRun())
verify(repository).getHeartRatesFromTime(now - t.averageHeartRateDurationMillis)
verifyNoMoreInteractions(repository)
}
@Test
fun toJSON() {
val t = TriggerHeartRate(injector).apply {
heartRate.value = 100.0
comparator.value = Comparator.Compare.IS_GREATER
}
assertEquals(Comparator.Compare.IS_GREATER, t.comparator.value)
assertEquals(
"""{"data":{"comparator":"IS_GREATER","heartRate":100},"type":"TriggerHeartRate"}""".trimMargin(),
t.toJSON()
)
}
@Test
fun fromJSON() {
val t = TriggerDummy(injector).instantiate(
JSONObject(
"""{"data":{"comparator":"IS_GREATER","heartRate":100},"type":"TriggerHeartRate"}"""
)
) as TriggerHeartRate
assertEquals(Comparator.Compare.IS_GREATER, t.comparator.value)
assertEquals(100.0, t.heartRate.value, 0.01)
}
}

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">НАЗНАЧ</string>
<string name="heartRate_shortname">ЧСС</string>
<string name="sensitivity_shortname">ЧУВСТВ</string>
<string name="graph_scale">Масштаб графика</string>
<string name="graph_menu_divider_header">График</string>
@ -323,6 +325,7 @@
<string name="grams_short">г</string>
<string name="hour_short">ч</string>
<string name="no_active_profile">Активный профиль не установлен!</string>
<string name="profile_message">Профиль:\n\nСдвиг по времени: %1$d$\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

@ -563,7 +563,7 @@ class OpenHumansUploaderPlugin @Inject internal constructor(
.setBackoffCriteria(BackoffPolicy.LINEAR, 20, TimeUnit.MINUTES)
.setInitialDelay(if (delay) 1 else 0, TimeUnit.DAYS)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORK_NAME_PERIODIC, if (replace) ExistingPeriodicWorkPolicy.REPLACE else ExistingPeriodicWorkPolicy.KEEP, workRequest)
WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORK_NAME_PERIODIC, if (replace) ExistingPeriodicWorkPolicy.UPDATE else ExistingPeriodicWorkPolicy.KEEP, workRequest)
}
internal fun uploadNow() {

View file

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

View file

@ -110,7 +110,7 @@ buttons at the same time to cancel pairing)\n
<string name="combov2_set_emulated_100_tbr">Set emulated 100% TBR</string>
<string name="combov2_letting_emulated_100_tbr_finish">Letting ongoing emulated 100% TBR finish</string>
<string name="combov2_ignoring_redundant_100_tbr">Ignoring redundant 100% TBR request</string>
<string name="combov2_hit_unexpected_tbr_limit">Unexpected limit encountered while adjusting TBR: target percentage was %1$d%%, hit a limit at %1$d%%</string>
<string name="combov2_hit_unexpected_tbr_limit">Unexpected limit encountered while adjusting TBR: target percentage was %1$d%%, hit a limit at %2$d%%</string>
<string name="combov2_cannot_set_absolute_tbr_if_basal_zero">Cannot set absolute TBR if base basal rate is zero</string>
<string name="combov2_pair_with_pump_summary">Pair AndroidAPS and Android with a currently unpaired Accu-Chek Combo pump</string>
<string name="combov2_unpair_pump_summary">Unpair AndroidAPS and Android from the currently paired Accu-Chek Combo pump</string>

View file

@ -21,13 +21,14 @@ class DiaconnG8Pump @Inject constructor(
) {
var isPumpLogUploadFailed: Boolean = false
//var bleResultInfo: Pair<Int?, Boolean> = Pair(null, false)
var bolusConfirmMessage: Byte = 0
var isReadyToBolus: Boolean = false
var maxBolusePerDay: Double = 0.0
var pumpIncarnationNum: Int = 65536
var isPumpVersionGe2_63: Boolean = false // is pumpVersion higher then 2.63
var isPumpVersionGe3_53: Boolean = false // is pumpVersion higher then 3.42
var insulinWarningGrade: Int =0
var insulinWarningProcess: Int =0
var insulinWarningRemain: Int =0
@ -363,6 +364,11 @@ class DiaconnG8Pump @Inject constructor(
var otpNumber = 0
var bolusingSetAmount = 0.0
var bolusingInjAmount = 0.0
var bolusingSpeed = 0
var bolusingInjProgress = 0
companion object {
// User settings
const val ALARM = 0

View file

@ -43,6 +43,7 @@ import info.nightscout.pump.diaconn.packet.InjectionCancelSettingResponsePacket
import info.nightscout.pump.diaconn.packet.InjectionExtendedBolusResultReportPacket
import info.nightscout.pump.diaconn.packet.InjectionExtendedBolusSettingPacket
import info.nightscout.pump.diaconn.packet.InjectionExtendedBolusSettingResponsePacket
import info.nightscout.pump.diaconn.packet.InjectionProgressReportPacket
import info.nightscout.pump.diaconn.packet.InjectionSnackInquirePacket
import info.nightscout.pump.diaconn.packet.InjectionSnackInquireResponsePacket
import info.nightscout.pump.diaconn.packet.InjectionSnackResultReportPacket
@ -150,6 +151,7 @@ abstract class DiaconnG8PacketModule {
@ContributesAndroidInjector abstract fun contributesBigAPSMainInfoInquireResponsePacket(): BigAPSMainInfoInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesSerialNumInquirePacket(): SerialNumInquirePacket
@ContributesAndroidInjector abstract fun contributesSerialNumInquireResponsePacket(): SerialNumInquireResponsePacket
@ContributesAndroidInjector abstract fun contributesInjectionProgressReportPacket(): InjectionProgressReportPacket
}

View file

@ -215,6 +215,7 @@ class BigAPSMainInfoInquireResponsePacket(
//incarnation no 처리
diaconnG8Pump.isPumpVersionGe2_63 = PumpLogUtil.isPumpVersionGe(sp.getString(rh.gs(R.string.pumpversion), ""), 2, 63)
diaconnG8Pump.isPumpVersionGe3_53 = PumpLogUtil.isPumpVersionGe(sp.getString(rh.gs(R.string.pumpversion), ""), 3, 53)
aapsLogger.debug(LTag.PUMPCOMM, "result > " + diaconnG8Pump.result)
aapsLogger.debug(LTag.PUMPCOMM, "systemRemainInsulin > " + diaconnG8Pump.systemRemainInsulin)

View file

@ -214,6 +214,7 @@ class BigMainInfoInquireResponsePacket(
//incarnation no 처리
diaconnG8Pump.isPumpVersionGe2_63 = PumpLogUtil.isPumpVersionGe(sp.getString(rh.gs(R.string.pumpversion), ""), 2, 63)
diaconnG8Pump.isPumpVersionGe3_53 = PumpLogUtil.isPumpVersionGe(sp.getString(rh.gs(R.string.pumpversion), ""), 3, 53)
aapsLogger.debug(LTag.PUMPCOMM, "result > " + diaconnG8Pump.result)
aapsLogger.debug(LTag.PUMPCOMM, "systemRemainInsulin > " + diaconnG8Pump.systemRemainInsulin)

View file

@ -48,5 +48,6 @@ class DiaconnG8ResponseMessageHashTable @Inject constructor(val injector: HasAnd
put(BatteryWarningReportPacket(injector))
put(InjectionBlockReportPacket(injector))
put(BolusSpeedSettingReportPacket(injector))
put(InjectionProgressReportPacket(injector))
}
}

View file

@ -0,0 +1,53 @@
package info.nightscout.pump.diaconn.packet
import dagger.android.HasAndroidInjector
import info.nightscout.pump.diaconn.DiaconnG8Pump
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject
/**
* InjectionProgressReportPacket
*/
class InjectionProgressReportPacket(injector: HasAndroidInjector) : DiaconnG8Packet(injector ) {
@Inject lateinit var diaconnG8Pump: DiaconnG8Pump
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
init {
msgType = 0xEA.toByte()
aapsLogger.debug(LTag.PUMPCOMM, "InjectionProgressReportPacket init ")
}
override fun handleMessage(data: ByteArray?) {
val defectCheck = defect(data)
if (defectCheck != 0) {
aapsLogger.debug(LTag.PUMPCOMM, "InjectionProgressReportPacket Got some Error")
failed = true
return
} else failed = false
val bufferData = prefixDecode(data)
val setAmount = getShortToInt(bufferData) /100.0
val injAmount = getShortToInt(bufferData)/100.0
val speed = getByteToInt(bufferData);
val injProgress = getByteToInt(bufferData)
diaconnG8Pump.bolusingSetAmount = setAmount
diaconnG8Pump.bolusingInjAmount = injAmount
diaconnG8Pump.bolusingSpeed = speed
diaconnG8Pump.bolusingInjProgress = injProgress
aapsLogger.debug(LTag.PUMPCOMM, "bolusingSetAmount --> ${diaconnG8Pump.bolusingSetAmount}")
aapsLogger.debug(LTag.PUMPCOMM, "bolusingInjAmount --> ${diaconnG8Pump.bolusingInjAmount}")
aapsLogger.debug(LTag.PUMPCOMM, "bolusingSpeed --> ${diaconnG8Pump.bolusingSpeed}")
aapsLogger.debug(LTag.PUMPCOMM, "bolusingInjProgress --> ${diaconnG8Pump.bolusingInjProgress}")
}
override fun getFriendlyName(): String {
return "PUMP_INJECTION_PROGRESS_REPORT"
}
}

View file

@ -322,6 +322,7 @@ class DiaconnG8Service : DaggerService() {
for (i in 0 until loopSize) {
val startLogNo: Int = start + i * pumpLogPageSize
val endLogNo: Int = startLogNo + min(end - startLogNo, pumpLogPageSize)
aapsLogger.debug(LTag.PUMPCOMM, "pumplog request : $startLogNo ~ $endLogNo")
val msg = BigLogInquirePacket(injector, startLogNo, endLogNo, 100)
sendMessage(msg, 500)
}
@ -500,15 +501,27 @@ class DiaconnG8Service : DaggerService() {
val bolusDurationInMSec = (insulin * speed * 1000).toLong()
val expectedEnd = bolusStart + bolusDurationInMSec + 3500L
val totalwaitTime = (expectedEnd - System.currentTimeMillis()) / 1000
// reset bolus progress history
diaconnG8Pump.bolusingInjProgress = 0
diaconnG8Pump.bolusingSetAmount = 0.0
diaconnG8Pump.bolusingInjAmount = 0.0
if (diaconnG8Pump.isReadyToBolus) {
var progressPecent = 0
while (!diaconnG8Pump.bolusDone) {
val waitTime = (expectedEnd - System.currentTimeMillis()) / 1000
bolusingEvent.status = String.format(rh.gs(R.string.waitingforestimatedbolusend), if (waitTime < 0) 0 else waitTime)
var progressPecent = 0
if (totalwaitTime > waitTime && totalwaitTime > 0) {
progressPecent = ((totalwaitTime - waitTime) * 100 / totalwaitTime).toInt()
if(diaconnG8Pump.isPumpVersionGe3_53) {
progressPecent = diaconnG8Pump.bolusingInjProgress
//bolusingEvent.status = String.format(rh.gs(R.string.waitingforestimatedbolusend), progressPecent)
bolusingEvent.status = "볼러스 주입중 ${diaconnG8Pump.bolusingInjAmount}U / ${diaconnG8Pump.bolusingSetAmount}U (${progressPecent}%)"
bolusingEvent.percent = min(progressPecent, 100)
} else {
val waitTime = (expectedEnd - System.currentTimeMillis()) / 1000
bolusingEvent.status = String.format(rh.gs(R.string.waitingforestimatedbolusend), if (waitTime < 0) 0 else waitTime)
if (totalwaitTime > waitTime && totalwaitTime > 0) {
progressPecent = ((totalwaitTime - waitTime) * 100 / totalwaitTime).toInt()
}
bolusingEvent.percent = min(progressPecent, 100)
}
bolusingEvent.percent = min(progressPecent, 100)
rxBus.send(bolusingEvent)
SystemClock.sleep(200)
}
@ -522,7 +535,9 @@ class DiaconnG8Service : DaggerService() {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.gettingbolusstatus)))
sendMessage(InjectionSnackInquirePacket(injector), 2000) // last bolus
// 볼러스 결과 보고패킷에서 처리함.
bolusingEvent.percent = 100
if(!diaconnG8Pump.isPumpVersionGe3_53) {
bolusingEvent.percent = 100
}
rxBus.send(EventPumpStatusChanged(rh.gs(info.nightscout.shared.R.string.disconnecting)))
}
})
@ -549,29 +564,39 @@ class DiaconnG8Service : DaggerService() {
// temp state check
sendMessage(TempBasalInquirePacket(injector))
val result : DiaconnG8Packet
if(diaconnG8Pump.isPumpVersionGe3_53) {
val tbrPacket = TempBasalSettingPacket(injector, 3, ((durationInHours * 60) / 15).toInt(), ((absoluteRate * 100) + 1000).toInt())
sendMessage(tbrPacket, 100)
result = tbrPacket
if (!processConfirm(tbrPacket.msgType)) return false
} else {
if (diaconnG8Pump.tbStatus == 1) {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.stoppingtempbasal)))
val msgPacket = TempBasalSettingPacket(injector, 2, diaconnG8Pump.tbTime, diaconnG8Pump.tbInjectRateRatio)
// tempbasal stop
sendMessage(msgPacket, 100)
if (diaconnG8Pump.tbStatus == 1) {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.stoppingtempbasal)))
val tbrPacket = TempBasalSettingPacket(injector, 2, diaconnG8Pump.tbTime, diaconnG8Pump.tbInjectRateRatio)
// tempbasal stop
sendMessage(tbrPacket, 100)
// otp process
if (!processConfirm(tbrPacket.msgType)) return false
diaconnG8Pump.tempBasalStart = dateUtil.now()
}
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.settingtempbasal)))
val tbInjectRate = ((absoluteRate * 100) + 1000).toInt()
val tbrPacket = TempBasalSettingPacket(injector, 1, ((durationInHours * 60) / 15).toInt(), tbInjectRate)
sendMessage(tbrPacket, 100)
result = tbrPacket
// otp process
if (!processConfirm(msgPacket.msgType)) return false
diaconnG8Pump.tempBasalStart = dateUtil.now()
if (!processConfirm(tbrPacket.msgType)) return false
// pump tempbasal status inquire
}
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.settingtempbasal)))
val tbInjectRate = ((absoluteRate * 100) + 1000).toInt()
val msgTBR = TempBasalSettingPacket(injector, 1, ((durationInHours * 60) / 15).toInt(), tbInjectRate)
sendMessage(msgTBR, 100)
// otp process
if (!processConfirm(msgTBR.msgType)) return false
// pump tempbasal status inquire
sendMessage(TempBasalInquirePacket(injector))
loadHistory()
val tbr = pumpSync.expectedPumpState().temporaryBasal
diaconnG8Pump.fromTemporaryBasal(tbr)
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTING))
return msgTBR.success()
return result.success()
}
fun tempBasalShortDuration(absoluteRate: Double, durationInMinutes: Int): Boolean {
@ -581,28 +606,40 @@ class DiaconnG8Service : DaggerService() {
}
// temp state check
val result:DiaconnG8Packet
sendMessage(TempBasalInquirePacket(injector))
if (diaconnG8Pump.tbStatus == 1) {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.stoppingtempbasal)))
val msgPacket = TempBasalSettingPacket(injector, 2, diaconnG8Pump.tbTime, diaconnG8Pump.tbInjectRateRatio)
// tempbasal stop
sendMessage(msgPacket, 100)
if(diaconnG8Pump.isPumpVersionGe3_53) {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.settingtempbasal)))
val tbrSettingPacket = TempBasalSettingPacket(injector, 3, 2, ((absoluteRate * 100) + 1000).toInt())
sendMessage(tbrSettingPacket, 100)
result=tbrSettingPacket
// otp process
if (!processConfirm(msgPacket.msgType)) return false
SystemClock.sleep(500)
if (!processConfirm(tbrSettingPacket.msgType)) return false
sendMessage(TempBasalInquirePacket(injector))
} else {
if (diaconnG8Pump.tbStatus == 1) {
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.stoppingtempbasal)))
val tbrPacket = TempBasalSettingPacket(injector, 2, diaconnG8Pump.tbTime, diaconnG8Pump.tbInjectRateRatio)
// tempbasal stop
sendMessage(tbrPacket, 100)
// otp process
if (!processConfirm(tbrPacket.msgType)) return false
SystemClock.sleep(500)
}
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.settingtempbasal)))
val tbInjectRate = absoluteRate * 100 + 1000
val msgTBR = TempBasalSettingPacket(injector, 1, 2, tbInjectRate.toInt())
sendMessage(msgTBR, 100)
result=msgTBR
// otp process
if (!processConfirm(msgTBR.msgType)) return false
}
rxBus.send(EventPumpStatusChanged(rh.gs(R.string.settingtempbasal)))
val tbInjectRate = absoluteRate * 100 + 1000
val msgTBR = TempBasalSettingPacket(injector, 1, 2, tbInjectRate.toInt())
sendMessage(msgTBR, 100)
// otp process
if (!processConfirm(msgTBR.msgType)) return false
sendMessage(TempBasalInquirePacket(injector))
loadHistory()
val tbr = pumpSync.expectedPumpState().temporaryBasal
diaconnG8Pump.fromTemporaryBasal(tbr)
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTING))
return msgTBR.success()
return result.success()
}
fun tempBasalStop(): Boolean {

View file

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

View file

@ -22,7 +22,6 @@ import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.pump.PumpSync
import info.nightscout.interfaces.pump.defs.PumpType
import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -51,7 +50,6 @@ interface IAlarmManager {
class AlarmManager @Inject constructor() : IAlarmManager {
@Inject lateinit var patchManager: IPatchManager
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var commandQueue: CommandQueue
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var rxBus: RxBus
@ -71,6 +69,7 @@ class AlarmManager @Inject constructor() : IAlarmManager {
private var compositeDisposable: CompositeDisposable = CompositeDisposable()
private var alarmDisposable: Disposable? = null
@Suppress("unused")
@Inject
fun onInit() {
mAlarmProcess = AlarmProcess(patchManager, rxBus)
@ -150,7 +149,7 @@ class AlarmManager @Inject constructor() : IAlarmManager {
context.startActivity(i)
}
private fun showNotification(alarmCode: AlarmCode, timeOffset: Long = 0L) {
private fun showNotification(alarmCode: AlarmCode) {
var alarmMsg = resourceHelper.gs(alarmCode.resId)
if (alarmCode == B000) {
val expireTimeValue = pm.getPatchWakeupTimestamp() + TimeUnit.HOURS.toMillis(84)
@ -171,21 +170,25 @@ class AlarmManager @Inject constructor() : IAlarmManager {
else Single.just(IAlarmProcess.ALARM_HANDLED)
}
.subscribe { ret ->
if (ret == IAlarmProcess.ALARM_HANDLED) {
if (alarmCode == B001) {
pumpSync.syncStopTemporaryBasalWithPumpId(
timestamp = dateUtil.now(),
endPumpId = dateUtil.now(),
pumpType = PumpType.EOFLOW_EOPATCH2,
pumpSerial = patchManager.patchConfig.patchSerialNumber
)
when (ret) {
IAlarmProcess.ALARM_HANDLED -> {
if (alarmCode == B001) {
pumpSync.syncStopTemporaryBasalWithPumpId(
timestamp = dateUtil.now(),
endPumpId = dateUtil.now(),
pumpType = PumpType.EOFLOW_EOPATCH2,
pumpSerial = patchManager.patchConfig.patchSerialNumber
)
}
updateState(alarmCode, AlarmState.HANDLE)
}
updateState(alarmCode, AlarmState.HANDLE)
}else if(ret == IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP){
pm.getAlarms().needToStopBeep.add(alarmCode)
updateState(alarmCode, AlarmState.HANDLE)
} else {
showNotification(alarmCode)
IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP -> {
pm.getAlarms().needToStopBeep.add(alarmCode)
updateState(alarmCode, AlarmState.HANDLE)
}
else -> showNotification(alarmCode)
}
}
)

View file

@ -63,16 +63,16 @@ interface IAlarmProcess {
class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmProcess {
override fun doAction(context: Context, code: AlarmCode): Single<Int> {
return when (code) {
B001 -> resumeBasalAction(context)
B001 -> resumeBasalAction(context)
A002, A003, A004, A005, A018, A019,
A020, A022, A023, A034, A041, A042,
A043, A044, A106, A107, A108, A116,
A117, A118 -> patchDeactivationAction(context)
A007 -> inappropriateTemperatureAction(context)
A016 -> needleInsertionErrorAction(context)
B000 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B003, B005, B006, B018 -> stopAeBeepAction(context, code)
B012 -> Single.just(IAlarmProcess.ALARM_HANDLED)
A117, A118 -> patchDeactivationAction(context)
A007 -> inappropriateTemperatureAction(context)
A016 -> needleInsertionErrorAction(context)
B000 -> Single.just(IAlarmProcess.ALARM_HANDLED)
B003, B005, B006, B018 -> stopAeBeepAction(code)
B012 -> Single.just(IAlarmProcess.ALARM_HANDLED)
}
}
@ -146,20 +146,20 @@ class AlarmProcess(val patchManager: IPatchManager, val rxBus: RxBus) : IAlarmPr
patchManager.temperature
.map(TemperatureResponse::getTemperature)
.map { temp -> (temp >= EopatchActivity.NORMAL_TEMPERATURE_MIN && temp <= EopatchActivity.NORMAL_TEMPERATURE_MAX) }
.filter{ok -> ok}
.filter { ok -> ok }
.flatMap { patchManager.resumeBasal().map { it.isSuccess.takeOne(IAlarmProcess.ALARM_HANDLED, IAlarmProcess.ALARM_UNHANDLED) }.toMaybe() }
.defaultIfEmpty(IAlarmProcess.ALARM_UNHANDLED)
}
}
private fun stopAeBeepAction(context: Context, alarm: AlarmCode): Single<Int> {
if (patchManager.patchConnectionState.isConnected) {
return patchManager.stopAeBeep(alarm.aeCode)
private fun stopAeBeepAction(alarm: AlarmCode): Single<Int> {
return if (patchManager.patchConnectionState.isConnected) {
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)
} else {
Single.just(IAlarmProcess.ALARM_HANDLED_BUT_NEED_STOP_BEEP)
}
}
}

View file

@ -22,7 +22,7 @@
<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_b000">La vida útil del parche expira el %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>

View file

@ -1,2 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>
<resources>
<string name="string_a002">Tomt reservoar\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a003">Patch utløpt\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a004">Blokkering oppdaget\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a005">Feil i oppstart selvtest\nPatch har blitt deaktivert. Bytt patch nå.</string>
<string name="string_a007">Upassende temperatur\nInsulintilførsel eller \'Aktiver patch\' prosess har stoppet. Unngå ekstrem temperatur nå.</string>
<string name="string_a016">Feil ved innsetting av kanyle\nSjekk knott-posisjon og trykk på \"Prøv på nytt\".</string>
<string name="string_a018">Patch batteri feil\nPatch er deaktivert og tilførselen\nav insulin stoppet. Skift patch nå.</string>
<string name="string_a019">Patch batteri feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a020">Patch aktiveringsfeil\n\'Aktiver patch prosess har utløpt. Trykk på \'Bekreft\' for å deaktivere gjeldende patch. Skift patch.</string>
<string name="string_a022">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a023">Patch feil\nPatch er deaktivert og tilførselen\nav insulin stoppet. Skift patch nå.</string>
<string name="string_a034">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a041">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a042">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a043">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a044">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a106">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a107">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a108">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a116">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a117">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_a118">Patch feil\nPatch er deaktivert og tilførselen av insulin stoppet. Skift patch nå.</string>
<string name="string_b000">Patch levetid utløper %s. Gjør deg klar til å bytte pach.</string>
<string name="string_b001">Slutten på insulin suspendering\nTrykk \'gjenopptatt\' for å starte insulintilførselen på nytt.</string>
<string name="string_b003">Lavt reservoarnivå\nBytt patch snart.</string>
<string name="string_b005">Patch levetid er utløpt\nBytt patch nå.</string>
<string name="string_b006">Patch levetid utløper snart\nBytt patch nå.</string>
<string name="string_b012">Ufullstendig aktivering av Patch\nFullfør \'Aktiver patch\' prosessen.</string>
<string name="string_b018">Patch lavt batterinivå\nVær klar til å bytte patch.</string>
</resources>

View file

@ -27,9 +27,9 @@
<string name="time_1hr_30min">1 час 30 мин</string>
<string name="time_2hr">2 часа</string>
<string name="all_blank">\u0020</string>
<string name="patch_safe_deactivation_desc">Для перехода на новый Patch, Завершите пользование Patch\'ем. Подача инсулина этим Patch\'ем будет отменена.</string>
<string name="patch_safe_deactivation_desc">Для перехода на новый Patch, авершите пользование Патч-помпой. Подача инсулина этой Патч-помпой будет отменена.</string>
<string name="patch_discard_complete_title">Пользование Patch\'ем завершено.</string>
<string name="patch_discard_complete_desc">Patch был отключен.\nЗавершить пользование Patch\'ем\nУдалите Patch с тела.</string>
<string name="patch_discard_complete_desc">Patch деактивирован.\nЗавершите пользование Patch\'ем\nУдалите Patch с тела.</string>
<string name="patch_change_confirm_bolus_is_active_desc">Подается болюс. Отменить подачу инсулина и завершить пользование Patch\'ем?</string>
<string name="patch_change_confirm_temp_basal_is_active_desc">Подается временный базал. Отменить подачу инсулина и завершить пользование Patch\'ем?</string>
<string name="patch_change_confirm_bolus_and_temp_basal_are_active_desc">Подается болюс и временный базал. Отменить подачу инсулина и завершить пользование Patch\'ем?</string>

View file

@ -1,2 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources></resources>
<resources>
<string name="string_a002">Резервуар пуст\n POD деактивирован, подача инсулина прекращена. Замените POD.</string>
<string name="string_a003">Истек срок POD\n POD деактивирован, подача инсулина прекращена. Замените POD.</string>
<string name="string_a004">Закупорка\n POD деактивирован, подача инсулина прекращена. Замените POD.</string>
<string name="string_a005">Ошибка самотестирования при включении\n POD деактивирован. Замените POD.</string>
<string name="string_a007">Неверная температура\nПодача инсулина или процесс активации POD остановлен. Приведите темрературу к норме.</string>
<string name="string_a016">Ошибка ввода иглы\n Проверьте положение активатора и нажмите \"Повтор\".</string>
<string name="string_a018">Ошибка батареи POD\n POD деактивирован, \nподача инсулина прекращена. Замените POD.</string>
<string name="string_a019">Ошибка батареи POD\n POD деактивирован, подача инсулина прекращена. Замените POD.</string>
<string name="string_a020">Ошибка активации POD\n\'Время активации истекло. Нажмите \'Подтвердить\', чтобы деактивировать POD. Замените POD.</string>
<string name="string_a022">Ошибка батареи Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a023">Ошибка Патч-помпы\nПатч-помпа деактивирована и\nподача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a034">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a041">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a042">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a043">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a044">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a106">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a107">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a108">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a116">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a117">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_a118">Ошибка Патч-помпы\nПатч-помпа деактивирована, подача инсулина прекращена. Замените Патч-помпу.</string>
<string name="string_b000">Срок действия патч-помпы истекает %s. Будьте готовы заменить патч-помпу.</string>
<string name="string_b001">Приостановка подачи инсулина завершена\nНажмите \'Возобновить\' для перезапуска подачи инсулина.</string>
<string name="string_b003">Резервуар почти пуст\nБудьте готовы вскоре замените патч-помпу.</string>
<string name="string_b005">Срок службы Патч-помпы истёк\nЗамените Патч-помпу.</string>
<string name="string_b006">Срок работы Патч-помпы вскоре истечет\nЗамените Патч-помпу.</string>
<string name="string_b012">Неполная активация Патч-помпы\nЗавершите процесс активации Патч-помпы.</string>
<string name="string_b018">Низкий уровень заряда батареи\nБудьте готовы заменить Патч-помпу.</string>
</resources>

View file

@ -6,6 +6,7 @@
<!-- Omnipod Dash - History -->
<string name="omnipod_dash_history_title">Журнал помпы</string>
<string name="omnipod_dash_history_item_description">Описание</string>
<string name="omnipod_dash_history_item_amount">Количество</string>
<string name="omnipod_dash_history_item_source">Источник</string>
<string name="omnipod_dash_history_item_date">Дата</string>
<string name="omnipod_dash_history_type">Тип:</string>
@ -30,8 +31,10 @@
<string name="omnipod_dash_command_not_sent">Команда не отправлена</string>
<string name="omnipod_dash_command_not_received_by_the_pod">Команда не получена помпой</string>
<string name="omnipod_dash_unknown">Состояние команды неясно</string>
<string name="omnipod_common_history_tbr_value">%1$.2f ед/ч, %2$d минут</string>
<string name="omnipod_common_history_bolus_value">%1$.2f ед</string>
<string name="omnipod_common_alert_delivery_suspended">Введение инсулина приостановлено</string>
<string name="omnipod_common_history_total_delivered">Всего подано: %1$.2f ед</string>
<string name="omnipod_dash_connection_lost">Потеряно соединение с подом</string>
<string name="omnipod_dash_bolus_already_in_progress">Вводится еще один болюс</string>
<string name="omnipod_dash_not_enough_insulin">В резервуаре недостаточно инсулина</string>
@ -44,6 +47,7 @@
<string name="failed_to_set_the_new_basal_profile">Не удалось установить новый базовый профиль. Подача инсулина приостановлена</string>
<string name="setting_basal_profile_might_have_failed">Возможно не удалось задать базальный профиль. Подача инсулина может быть приостановлена! Обновите вручную состояние Pod на вкладке Omnipod и при необходимости возобновите процесс подачи.</string>
<string name="bolus_delivery_status_uncertain">Статус подачи болюса неясен. Обновите статус pod, чтобы подтвердить или отклонить.</string>
<string name="temp_basal_out_of_sync">Неожиданное состояние врем базала! Если перед этим подавался врем базал, то он отменен. Проверьте кол-во поданного инсулина и журнал событий POD</string>
<string name="checking_delivery_status">Выполняется проверка статуса подачи</string>
<string name="setting_temp_basal_might_have_basal_failed">Установка врем базала могла иметь сбой. Если временный базал запущен ранее, он был отменен. Вручную обновите статус Pod на вкладке Omnipod.</string>
<string name="cancel_temp_basal_result_is_uncertain">Результат отмены временного базала неясен</string>

View file

@ -193,4 +193,5 @@
<string name="old">старые</string>
<string name="old_warning">!старое!</string>
<string name="error">!ошибка!</string>
<string name="pref_heartRateSampling">Частота сердечных сокращений</string>
</resources>