This commit is contained in:
Milos Kozak 2023-11-01 13:38:58 +01:00
commit 4bcfec6300
75 changed files with 519 additions and 236 deletions

View file

@ -139,6 +139,7 @@ open class Notification {
const val PUMP_TIMEZONE_UPDATE_FAILED = 85
const val BLUETOOTH_NOT_SUPPORTED = 86
const val PUMP_WARNING = 87
const val PUMP_SYNC_ERROR = 88
const val USER_MESSAGE = 1000

View file

@ -2,7 +2,6 @@ package app.aaps.core.interfaces.nsclient
import android.text.Spanned
import app.aaps.core.interfaces.aps.APSResult
import dagger.android.HasAndroidInjector
import org.json.JSONObject
interface ProcessedDeviceStatusData {
@ -61,7 +60,7 @@ interface ProcessedDeviceStatusData {
val extendedOpenApsStatus: Spanned
val openApsStatus: Spanned
val openApsTimestamp: Long
fun getAPSResult(injector: HasAndroidInjector): APSResult
fun getAPSResult(): APSResult
val uploaderStatus: String
val uploaderStatusSpanned: Spanned
val extendedUploaderStatus: Spanned

View file

@ -9,7 +9,7 @@ class PumpDescription() {
var pumpType = PumpType.GENERIC_AAPS
var isBolusCapable = false
var bolusStep = 0.0
var isExtendedBolusCapable = false
var isExtendedBolusCapable = true
var extendedBolusStep = 0.0
var extendedBolusDurationStep = 0.0
var extendedBolusMaxDuration = 0.0

View file

@ -7,4 +7,7 @@ class EventNetworkChange(
var ssid: String = "",
var roaming: Boolean = false,
var metered: Boolean = false
) : Event()
) : Event() {
val isAnyConnection : Boolean
get() = mobileConnected || wifiConnected
}

View file

@ -268,6 +268,9 @@ enum class JsonKeys(val key: String) {
DYNPREF("dynPref"),
DYNPREFCOLOR("dynPrefColor"),
PREFKEY("prefKey"),
INVALIDTOPOFFSET("invalidTopOffset"),
INVALIDLEFTOFFSET("invalidLeftOffset"),
INVALIDROTATIONOFFSET("invalidRotationOffset"),
DEFAULT("default")
}

View file

@ -1,7 +1,6 @@
package app.aaps.core.interfaces.utils
import app.aaps.core.interfaces.aps.AutosensDataStore
import app.aaps.core.interfaces.iob.InMemoryGlucoseValue
import app.aaps.database.entities.GlucoseValue
/**
@ -10,22 +9,6 @@ import app.aaps.database.entities.GlucoseValue
*/
interface TrendCalculator {
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return TrendArrow
*/
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return TrendArrow
*/
fun getTrendArrow(glucoseValue: InMemoryGlucoseValue?): GlucoseValue.TrendArrow
/**
* Provide or calculate trend from newest bucketed data
*
@ -34,14 +17,6 @@ interface TrendCalculator {
*/
fun getTrendArrow(autosensDataStore: AutosensDataStore): GlucoseValue.TrendArrow?
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return string description of TrendArrow
*/
fun getTrendDescription(glucoseValue: GlucoseValue?): String
/**
* Provide or calculate trend from newest bucketed data
*

View file

@ -58,6 +58,7 @@
<string name="pref_show_direction_arrow">Отображать стрелку тренда</string>
<string name="pref_show_ago">Отображать историю</string>
<string name="pref_show_week_number">Показывать номер недели</string>
<string name="pref_show_date">Показать дату</string>
<string name="default_custom_watchface_comment">Циферблат по умолчанию, вы можете нажать на EXPORT WATCHFACE чтобы создать шаблон</string>
<string name="wear_default_watchface">Циферблат по умолчанию</string>
<string name="cwf_comment_background">Фоновое изображение</string>

View file

@ -58,6 +58,7 @@
<string name="pref_show_direction_arrow">Zobraziť trendovú šípku</string>
<string name="pref_show_ago">Zobraziť aktualizované pred</string>
<string name="pref_show_week_number">Zobraziť číslo týždňa</string>
<string name="pref_show_date">Zobraziť dátum</string>
<string name="default_custom_watchface_comment">Predvolený ciferník. Môžete kliknúť na tlačítko EXPORTOVAŤ CIFERNÍK pre vygenerovanie šablóny</string>
<string name="wear_default_watchface">Predvolený ciferník</string>
<string name="cwf_comment_background">Obrázok pozadia</string>

View file

@ -58,6 +58,7 @@
<string name="pref_show_direction_arrow">Ok yönünü Göster</string>
<string name="pref_show_ago">Önce Göster</string>
<string name="pref_show_week_number">Hafta sayısını göster</string>
<string name="pref_show_date">Tarihi Göster</string>
<string name="default_custom_watchface_comment">Varsayılan saat arayüzü; bir şablon oluşturmak için SAAT ARAYÜZÜNÜ DIŞA AKTAR butonuna tıklayabilirsiniz</string>
<string name="wear_default_watchface">Varsayılan saat arayüzü</string>
<string name="cwf_comment_background">Arka plan görüntüsü</string>

View file

@ -56,7 +56,7 @@ internal interface NightscoutRemoteService {
@DELETE("v3/entries/{identifier}")
suspend fun deleteEntry(@Path("identifier") identifier: String): Response<NSResponse<RemoteCreateUpdateResponse>>
@GET("v3/treatments?sort=date")
@GET("v3/treatments?sort=created_at")
suspend fun getTreatmentsNewerThan(@Query(value = "created_at\$gt", encoded = true) createdAt: String, @Query("limit") limit: Int): Response<NSResponse<List<RemoteTreatment>>>
@GET("v3/treatments/history/{from}")

View file

@ -120,7 +120,7 @@
<string name="notconfigured">Non configurato</string>
<string name="loopsuspended">Loop sospeso</string>
<string name="trend_arrow">Freccia trend</string>
<string name="a11y_autosens_label">Asuto sens</string>
<string name="a11y_autosens_label">Auto sens</string>
<string name="required">ric</string>
<string name="a11y_arrow_double_down">discesa rapida</string>
<string name="a11y_arrow_single_down">discesa</string>
@ -155,7 +155,7 @@
<string name="login">Login</string>
<string name="prime_fill">Carica/Riempi</string>
<string name="overview_insulin_label">Insulina</string>
<string name="stoptemptarget">Stoppa temp-target</string>
<string name="stoptemptarget">Stoppa target temporaneo</string>
<string name="closedloop">Loop chiuso</string>
<string name="openloop">Loop aperto</string>
<string name="lowglucosesuspend">Sospensione a glicemia bassa (LGS)</string>
@ -222,7 +222,7 @@
<string name="pump_battery_change">Cambio batteria micro</string>
<string name="temporary_target">Target temporaneo</string>
<string name="careportal_temporarytargetvalue">Valore target temporaneo</string>
<string name="careportal_temporarytargetcancel">Cancellazione temp-target</string>
<string name="careportal_temporarytargetcancel">Cancellazione target temporaneo</string>
<string name="boluswizard">Calcolatore</string>
<string name="glucosetype_finger">Dito</string>
<string name="glucosetype_sensor">Sensore</string>
@ -404,9 +404,9 @@
<string name="autotune_shortname">AT</string>
<string name="autotune_settings">Impostazioni Autotune</string>
<string name="autotune_auto_title">Automazione cambio profilo</string>
<string name="autotune_auto_summary">Se abilitato, Autotune si aggiornerà automaticamente e passerà al profilo di input dopo il calcolo da una regola di automazione.</string>
<string name="autotune_auto_summary">Se abilitato, dopo il calcolo di una regola di automazione Autotune verrà eseguito e il profilo generato verrà automaticamente attivato.</string>
<string name="autotune_categorize_uam_as_basal_title">Classifica UAM come basale</string>
<string name="autotune_categorize_uam_as_basal_summary">Abilita solo se hai inserito in modo affidabile tutti i carboidrati assunti, con questa opzione aumenti improvvisi individuati da Autotune verranno usati per consigliare modifiche alla velocità basale.</string>
<string name="autotune_categorize_uam_as_basal_summary">Abilita solo se hai inserito in modo affidabile tutti i carboidrati assunti, con questa opzione gli aumenti improvvisi individuati da Autotune verranno usati per consigliare modifiche alla velocità basale.</string>
<string name="autotune_tune_insulin_curve_title">Regola la curva dell\'insulina</string>
<string name="autotune_tune_insulin_curve_summary">Abilita solo se usi free-peak. Questa opzione regolerà la durata di picco e DIA</string>
<string name="autotune_default_tune_days_title">Numero di giorni di dati</string>
@ -453,9 +453,9 @@
<string name="info">INFO</string>
<!-- BolusWizard -->
<string name="bolus_advisor">Consiglio bolo</string>
<string name="bolus_advisor_message">Hai una glicemia alta. Invece di mangiare ora, si consiglia di attendere una glicemia migliore. Vuoi fare adesso un bolo di correzione ed essere ricordato quando è il momento di mangiare? In questo caso non verranno registrati carboidrati e dovrai usare di nuovo il calcolatore quando ti verrà mostrato il promemoria.</string>
<string name="bolus_advisor_message">Hai una glicemia alta. Invece di mangiare ora, si consiglia di attendere una glicemia migliore. Vuoi fare adesso un bolo di correzione ed ricevere un promemoria quando è il momento di mangiare? In questo caso non verranno registrati carboidrati e dovrai usare di nuovo il calcolatore quando ti verrà mostrato il promemoria.</string>
<string name="cobvsiob">COB vs IOB</string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! Rilevato assorbimento lento dei carboidrati: %2$d%% del tempo. Ricontrolla il tuo calcolo. COB potrebbero essere sovrastimati e potrebbe essere somministrata più insulina !!!!!</font>]]></string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! Rilevato assorbimento lento dei carboidrati: %2$d%% del tempo. Ricontrolla il tuo calcolo. I COB potrebbero essere sovrastimati e potrebbe essere somministrata più insulina !!!!!</font>]]></string>
<string name="partialboluswizard">Eroga parte del risultato del calcolatore [%]</string>
<string name="partialboluswizard_reset_time">Soglia tempo glicemia \"vecchia\" [min]</string>
<string name="bolus_constraint_applied_warn">Vincolo bolo applicato: %1$.2f U a %2$.2f U</string>
@ -555,7 +555,7 @@
<string name="ble_not_supported_or_not_paired">Bluetooth Low Energy non supportato o dispositivo non associato.</string>
<string name="ble_not_enabled">Bluetooth non abilitato.</string>
<string name="location_not_found_title">La localizzazione non è abilitata</string>
<string name="location_not_found_message">Affinché la ricerca bluetooth funzioni sui dispositivi più recenti, la localizzazione deve essere abilitata, ma può essere disabilitata dopo l\'associazione. AAPS non tiene traccia della tua posizione.</string>
<string name="location_not_found_message">Affinché la ricerca bluetooth funzioni sui dispositivi più recenti la localizzazione deve essere abilitata, ma può essere disabilitata dopo l\'associazione. AAPS non tiene traccia della tua posizione.</string>
<!-- Preferences -->
<string name="nav_plugin_preferences">Preferenze plugin</string>
<!-- SmsCommunicator -->
@ -589,8 +589,8 @@
<string name="weekday_monday_short">Lun</string>
<!-- WeekdayPicker -->
<string name="monday_short">L</string>
<string name="tuesday_short">M</string>
<string name="wednesday_short">M</string>
<string name="tuesday_short">Ma</string>
<string name="wednesday_short">Me</string>
<string name="thursday_short">G</string>
<string name="friday_short">V</string>
<string name="saturday_short">S</string>

View file

@ -51,6 +51,7 @@
<string name="extended_bolus">Bolus extins</string>
<string name="paused">Suspendat</string>
<string name="tdd_total">Total TDD</string>
<string name="tdd_old_data">Date vechi</string>
<string name="goingtodeliver">Se vor livra %1$.2fU</string>
<string name="waitingforpump">Se așteaptă pompa</string>
<string name="androidaps_start">AAPS pornit</string>
@ -167,6 +168,8 @@
<string name="virtualpump_uploadstatus_title">Trimitere status către NS sau Tidepool</string>
<string name="suspendloop_label">Buclă dezactivată/suspendată</string>
<string name="iob_label">Insulină activă (IOB)</string>
<string name="loopstatus_targets">ȚINTE:</string>
<string name="loopstatus_OAPS_result">REZULTATUL OAPS:</string>
<!-- Protection-->
<string name="wrongpassword">Parola greșită</string>
<string name="wrongpin">PIN greșit</string>
@ -462,6 +465,8 @@
<string name="bolus_recorded_only">Bolusul va fi doar consemnat (nu va fi livrat de pompă)</string>
<string name="advisoralarm">Rulează alarma când este timpul să mănânci</string>
<string name="no_action_selected">Nicio acțiune selectată, nu se va întâmpla nimic</string>
<string name="carb_equal_zero_no_action">Carbohidrați = 0. Nicio acțiune efectuată!</string>
<string name="wizard_no_insulin_required">Nu este necesară insulină!</string>
<string name="wizard_no_actual_bg">Nicio glicemie recentă pe care să se bazeze calculul!</string>
<string name="wizard_no_active_profile">Niciun profil activ stabilit!</string>
<string name="wizard_no_cob">COB necunoscut! Lipsesc datele de glicemie sau aplicația a fost repornită de curând?</string>

View file

@ -51,6 +51,7 @@
<string name="extended_bolus">Пролонгированный болюс</string>
<string name="paused">На паузе</string>
<string name="tdd_total">Суммарный суточный инсулин TDD</string>
<string name="tdd_old_data">Старые данные</string>
<string name="goingtodeliver">Будет подано %1$.2f ед инс</string>
<string name="waitingforpump">Ожидание помпы</string>
<string name="androidaps_start">AAPS запущен</string>
@ -167,6 +168,8 @@
<string name="virtualpump_uploadstatus_title">Передавать статус помпы в NS или Tidepool</string>
<string name="suspendloop_label">Отключенный/приостановленный цикл</string>
<string name="iob_label">Активный инсулин (IOB)</string>
<string name="loopstatus_targets">ЦЕЛИ:</string>
<string name="loopstatus_OAPS_result">РЕЗУЛЬТАТ: OAPS:</string>
<!-- Protection-->
<string name="wrongpassword">Неверный пароль</string>
<string name="wrongpin">Неверный PIN-код</string>
@ -462,6 +465,8 @@
<string name="bolus_recorded_only">Болюс будет только записан (без подачи помпой)</string>
<string name="advisoralarm">Напомнить о еде</string>
<string name="no_action_selected">Действие не выбрано, ничего не произойдет</string>
<string name="carb_equal_zero_no_action">Carbs = 0. Никаких мер не принято!</string>
<string name="wizard_no_insulin_required">Инсулин не требуется!</string>
<string name="wizard_no_actual_bg">Нет данных ГК для основы расчета!</string>
<string name="wizard_no_active_profile">Активный профиль не установлен!</string>
<string name="wizard_no_cob">Неизвестный COB! Отсутствуют данные ГК или приложения недавно перезапущено?</string>

View file

@ -51,6 +51,7 @@
<string name="extended_bolus">Predĺžený bolus</string>
<string name="paused">Pozastavené</string>
<string name="tdd_total">CDD celkom</string>
<string name="tdd_old_data">Staré dáta</string>
<string name="goingtodeliver">Podávanie %1$.2f J inzulínu</string>
<string name="waitingforpump">Čakám na pumpu</string>
<string name="androidaps_start">AAPS spustený</string>
@ -167,6 +168,8 @@
<string name="virtualpump_uploadstatus_title">Nahrávať stav pumpy do NS, alebo Tidepoolu</string>
<string name="suspendloop_label">Deaktivovaný/pozastavený uzavretý okruh</string>
<string name="iob_label">Aktívny inzulín (IOB)</string>
<string name="loopstatus_targets">CIELE:</string>
<string name="loopstatus_OAPS_result">VÝSLEDOK OAPS:</string>
<!-- Protection-->
<string name="wrongpassword">Nesprávne heslo</string>
<string name="wrongpin">Nesprávny PIN</string>
@ -462,6 +465,8 @@
<string name="bolus_recorded_only">Bolus bude iba zaznamenaný (nie pumpou vydaný)</string>
<string name="advisoralarm">Spustiť výstrahu, keď je čas na jedlo</string>
<string name="no_action_selected">Žiadna akcia nevybraná, nič sa neudeje</string>
<string name="carb_equal_zero_no_action">Sacharidy = 0. Žiadna akcia!</string>
<string name="wizard_no_insulin_required">Nie je požadovaný žiadny inzulín!</string>
<string name="wizard_no_actual_bg">Žiadna aktuálna glykémia k základnému výpočtu!</string>
<string name="wizard_no_active_profile">Nie je nastavený žiadny aktívny profil!</string>
<string name="wizard_no_cob">Neznáme COB! Chýbajú glykémie, alebo bola práve reštartovaná aplikácia?</string>

View file

@ -51,6 +51,7 @@
<string name="extended_bolus">Yayma Bolus</string>
<string name="paused">Duraklatıldı</string>
<string name="tdd_total">GTD Toplam</string>
<string name="tdd_old_data">Eski veri</string>
<string name="goingtodeliver">%1$.2f Ü gönderilecek</string>
<string name="waitingforpump">Pompa bekleniyor</string>
<string name="androidaps_start">AAPS başladı</string>
@ -167,6 +168,8 @@
<string name="virtualpump_uploadstatus_title">Pompa durumunu NS veya Tidepool\'a yükleyin</string>
<string name="suspendloop_label">Döngüyü Devre Dışı bırakma/Askıya alma</string>
<string name="iob_label">Aktif İnsülin (AİNS)</string>
<string name="loopstatus_targets">HEDEFLER:</string>
<string name="loopstatus_OAPS_result">OAPS SONUCU:</string>
<!-- Protection-->
<string name="wrongpassword">Hatalı parola</string>
<string name="wrongpin">Yanlış PIN</string>
@ -462,6 +465,8 @@
<string name="bolus_recorded_only">Bolus yalnızca kaydedilecektir (pompa ile iletilmez)</string>
<string name="advisoralarm">Yemek zamanı alarmı çalıştır</string>
<string name="no_action_selected">Seçili eylem yok, hiçbir şey olmayacak</string>
<string name="carb_equal_zero_no_action">Karb = 0. Hiçbir şey yapılmadı!</string>
<string name="wizard_no_insulin_required">İnsülin gerekmiyor!</string>
<string name="wizard_no_actual_bg">Hesaplamayı temel alacak yeni bir KŞ yok!</string>
<string name="wizard_no_active_profile">Etkin profil ayarlanmadı!</string>
<string name="wizard_no_cob">Aktif karbonhidrat (AKRB) bilinmiyor! KŞ okuması eksik veya son uygulama yeniden başlatılsın mı?</string>

View file

@ -155,5 +155,6 @@
<string name="key_virtual_pump_upload_status" translatable="false">virtualpump_uploadstatus</string>
<string name="key_use_autosens" translatable="false">openapsama_useautosens</string>
<string name="key_used_autosens_on_main_phone" translatable="false">used_autosens_on_main_phone</string>
<string name="key_openapsma_max_basal" translatable="false">openapsma_max_basal</string>
</resources>

View file

@ -3,75 +3,16 @@ package app.aaps.implementation.utils
import app.aaps.core.interfaces.aps.AutosensDataStore
import app.aaps.core.interfaces.iob.InMemoryGlucoseValue
import app.aaps.core.interfaces.resources.ResourceHelper
import app.aaps.core.interfaces.utils.T
import app.aaps.core.interfaces.utils.TrendCalculator
import app.aaps.database.entities.GlucoseValue
import app.aaps.database.impl.AppRepository
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TrendCalculatorImpl @Inject constructor(
private val repository: AppRepository,
private val rh: ResourceHelper
) : TrendCalculator {
override fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow =
when {
glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE
glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow
else -> calculateDirection(InMemoryGlucoseValue(glucoseValue))
}
override fun getTrendArrow(glucoseValue: InMemoryGlucoseValue?): GlucoseValue.TrendArrow =
when {
glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE
glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow
else -> calculateDirection(glucoseValue)
}
override fun getTrendDescription(glucoseValue: GlucoseValue?): String =
when (getTrendArrow(glucoseValue)) {
GlucoseValue.TrendArrow.DOUBLE_DOWN -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_double_down)
GlucoseValue.TrendArrow.SINGLE_DOWN -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_single_down)
GlucoseValue.TrendArrow.FORTY_FIVE_DOWN -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_forty_five_down)
GlucoseValue.TrendArrow.FLAT -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_flat)
GlucoseValue.TrendArrow.FORTY_FIVE_UP -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_forty_five_up)
GlucoseValue.TrendArrow.SINGLE_UP -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_single_up)
GlucoseValue.TrendArrow.DOUBLE_UP -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_double_up)
GlucoseValue.TrendArrow.NONE -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_none)
else -> rh.gs(app.aaps.core.ui.R.string.a11y_arrow_unknown)
}
private fun calculateDirection(glucoseValue: InMemoryGlucoseValue): GlucoseValue.TrendArrow {
val toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()
if (readings.size < 2)
return GlucoseValue.TrendArrow.NONE
val current = readings[0]
val previous = readings[1]
// Avoid division by 0
val slope =
if (current.timestamp == previous.timestamp) 0.0
else (previous.value - current.value) / (previous.timestamp - current.timestamp)
val slopeByMinute = slope * 60000
return when {
slopeByMinute <= -3.5 -> GlucoseValue.TrendArrow.DOUBLE_DOWN
slopeByMinute <= -2 -> GlucoseValue.TrendArrow.SINGLE_DOWN
slopeByMinute <= -1 -> GlucoseValue.TrendArrow.FORTY_FIVE_DOWN
slopeByMinute <= 1 -> GlucoseValue.TrendArrow.FLAT
slopeByMinute <= 2 -> GlucoseValue.TrendArrow.FORTY_FIVE_UP
slopeByMinute <= 3.5 -> GlucoseValue.TrendArrow.SINGLE_UP
slopeByMinute <= 40 -> GlucoseValue.TrendArrow.DOUBLE_UP
else -> GlucoseValue.TrendArrow.NONE
}
}
override fun getTrendArrow(autosensDataStore: AutosensDataStore): GlucoseValue.TrendArrow? {
val data = autosensDataStore.getBucketedDataTableCopy() ?: return null
if (data.size == 0) return null

View file

@ -247,7 +247,7 @@ class OpenAPSAMAPlugin @Inject constructor(
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
if (isEnabled()) {
var maxBasal = sp.getDouble(R.string.key_openapsma_max_basal, 1.0)
var maxBasal = sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)
if (maxBasal < profile.getMaxDailyBasal()) {
maxBasal = profile.getMaxDailyBasal()
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)

View file

@ -313,7 +313,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
if (isEnabled()) {
var maxBasal = sp.getDouble(R.string.key_openapsma_max_basal, 1.0)
var maxBasal = sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)
if (maxBasal < profile.getMaxDailyBasal()) {
maxBasal = profile.getMaxDailyBasal()
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)

View file

@ -3,17 +3,17 @@
<string name="dynisf_adjust_sensitivity">Regola sensibilità e BG</string>
<string name="DynISFAdjust_title" formatted="false">Fattore di regolazione per ISF Dinamico (%)</string>
<string name="DynISFAdjust_summary" formatted="false">Fattore di regolazione per ISF Dinamico. Imposta più del 100% per dosi di correzione più aggressive e meno del 100% per correzioni meno aggressive.</string>
<string name="high_temptarget_raises_sensitivity_title">Temp-Target \"alto\" aumenta la sensibilità</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Aumenta la sensibilità per temp-target >= 100]]></string>
<string name="low_temptarget_lowers_sensitivity_title">Temp-Target \"basso\" riduce la sensibilità</string>
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Riduci la sensibilità per temp-target < 100]]></string>
<string name="high_temptarget_raises_sensitivity_title">Target temporaneo \"alto\" aumenta la sensibilità</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Aumenta la sensibilità per Target temporaneo >= 100]]></string>
<string name="low_temptarget_lowers_sensitivity_title">Target temporaneo \"basso\" riduce la sensibilità</string>
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Riduci la sensibilità per Target temporaneo < 100]]></string>
<string name="openapssmb">OpenAPS SMB</string>
<string name="openaps_smb_dynamic_isf">ISF Dinamico</string>
<string name="smb_interval_summary">Frequenza erogazione SMB (min)</string>
<string name="resistance_lowers_target_title">La resistenza abbassa il target</string>
<string name="resistance_lowers_target_summary">Quando viene rilevata resistenza, ridurre la glicemia target</string>
<string name="sensitivity_raises_target_title">La sensibilità aumenta il target</string>
<string name="sensitivity_raises_target_summary">Quando viene rilevata sensibilità, aumentare la glicemia target</string>
<string name="sensitivity_raises_target_summary">Quando viene rilevata sensibilità, aumenta la glicemia target</string>
<string name="openapsma_disabled">Il plugin è disabilitato</string>
<string name="openapsma_no_glucose_data">Dati glicemia non disponibili</string>
<string name="openaps_no_as_data">Nessun dato autosens disponibile</string>
@ -46,7 +46,7 @@
<string name="openapsama_autosens_adjust_targets_summary">[Valore predefinito: vero]\nViene usato per consentire ad autosens di regolare i target glicemici, in aggiunta a ISF e basali.</string>
<string name="openapsama_autosens_adjust_targets">Autosens regola anche i target</string>
<string name="openapsama_min_5m_carb_impact_summary">[Valore predefinito: 3.0 (AMA) o 8.0 (SMB)]. Questa è un\'impostazione per l\'impatto di assorbimento predefinito dei carboidrati in 5 minuti. L\'impostazione predefinita è una previsione di 3mg/dl/5min. Ha effetto sulla velocità di decadimento dei COB (carboidrati attivi) e su quanto il loro assorbimento incide nella previsione dellandamento glicemico, quando la glicemia sta scendendo più del previsto o non sta salendo quanto previsto.</string>
<string name="openapsama_max_daily_safety_multiplier_summary">[Valore predefinito: 3] Questo è un parametro di sicurezza chiave in OpenAPS. Ciò che fa è limitare le tue basali a essere 3 volte, al più, la tua velocità basale massima. Probabilmente non avrai bisogno di cambiare questo valore, ma dovresti essere consapevole di cosa significa il gruppo di parametri \"3x max giornaliera; 4x corrente\" e per quali motivi di sicurezza siano stati impostati tali valori.</string>
<string name="openapsama_max_daily_safety_multiplier_summary">[Valore predefinito: 3] Questo è un parametro di sicurezza chiave in OpenAPS. Ciò che fa è limitare la tua basale ad un valore pari alla tua velocità basale massima moltiplicata per 3. Probabilmente non avrai bisogno di cambiare questo valore ma dovresti essere consapevole di cosa significa il gruppo di parametri \"3x max giornaliera; 4x corrente\" e per quali motivi di sicurezza siano stati impostati tali valori.</string>
<string name="openapsama_current_basal_safety_multiplier_summary">[Valore predefinito: 4] Questo è un ulteriore parametro di sicurezza chiave in OpenAPS. La tua basale temporanea, indipendentemente dalla basale massima impostata sul micro, non può mai essere più alta di questo valore moltiplicato per la tua basale corrente in ogni specifico momento. Questo serve a impedire alle persone di addentrarsi in \"territori pericolosi\" impostando basali massime eccessivamente alte prima di aver capito come funziona l\'algoritmo. Ancora una volta, il valore predefinito è 4x; la maggior parte delle persone non avrà bisogno di modificare questo valore e avrà, invece, maggiori probabilità di dover regolare altre impostazioni se ha la sensazione di \"scontrarsi\" con questo limite di sicurezza.</string>
<string name="openapsama_bolus_snooze_dia_divisor_summary">[Valore predefinito: 2]\nBolus snooze è attivato dopo un bolo pasto per fare in modo che il loop non imposti basali temporanee basse quando hai appena mangiato. AndroidAPS non imposterà velocità basali troppo basse nel periodo corrispondente a DIA diviso il parametro bolus snooze - divisore DIA. Con DIA di 3 ore \"bolus snooze\" durerà 1.5 ore (3/2).</string>
<string name="openapsama_link_to_preference_json_doc_txt">Attenzione!\nNormalmente non dovresti modificare questi valori. FAI CLICK QUI e leggi il testo e assicurati di AVERLO CAPITO prima di cambiare uno di questi valori.</string>
@ -55,10 +55,10 @@
<string name="openapsama_max_daily_safety_multiplier">Moltiplicatore di sicurezza max basale giornaliera</string>
<string name="openapsama_current_basal_safety_multiplier">Moltiplicatore di sicurezza basale corrente</string>
<string name="openapssmb_max_iob_title">Max IOB totale a cui limitare OpenAPS [U]</string>
<string name="openapssmb_max_iob_summary">Questo valore è chiamato Max IOB nel contesto OpenAPS\nOpenAPS non aggiungerà ulteriore insulina se IOB corrente è maggiore di questo valore</string>
<string name="openapssmb_max_iob_summary">Questo valore è chiamato Max IOB nel contesto OpenAPS\nOpenAPS non aggiungerà ulteriore insulina se l\'IOB corrente è maggiore di questo valore</string>
<string name="enable_uam">Abilita UAM</string>
<string name="enable_smb">Abilita SMB</string>
<string name="enable_smb_summary">Usa super-micro-boli al posto della basale temporanea per un\'azione più veloce</string>
<string name="enable_smb_summary">Usa super-micro-boli (SMB) al posto della basale temporanea per un\'azione più veloce</string>
<string name="enable_uam_summary">Rilevamento dei pasti non annunciati</string>
<string name="enable_smb_always">Abilita SMB sempre</string>
<string name="enable_smb_always_summary">Abilita SMB sempre, indipendentemente dai boli. Possibile solo con sorgente glicemia con un buon filtraggio dei dati, come G5</string>
@ -75,7 +75,7 @@
<string name="uam_smb_max_minutes_summary">Max minuti di basale a cui limitare SMB per UAM</string>
<string name="carbs_req_threshold">CHO minimi richiesti per il suggerimento</string>
<string name="carbs_req_threshold_summary">Quantità minima di carboidrati (in grammi) necessaria per visualizzare un avviso di suggerimento CHO. Al di sotto di questo numero non verrà attivata alcuna notifica.</string>
<string name="lgs_threshold_summary">Glicemia sotto la quale l\'erogazione d\'insulina è sospesa. Il valore predefinito utilizza il modello target standard. L\'utente può impostare un valore compreso tra 60 mg/dl (3.3mmol/l) e 100mg/dl (5.5mmol/l). Con valori inferiori a 65/3.6 viene usato il modello predefinito</string>
<string name="lgs_threshold_summary">Glicemia sotto la quale l\'erogazione d\'insulina è sospesa. Il valore predefinito utilizza il modello target standard. L\'utente può impostare un valore compreso tra 60 mg/dl (3.3mmol/l) e 100mg/dl (5.5mmol/l). Con valori inferiori a 65 mg/dl (3.6mmol/l) viene usato il modello predefinito</string>
<string name="lgs_threshold_title">Glicemia sotto la quale si attiva la sospensione per glicemia bassa</string>
<string name="increasing_max_basal">Aumento del valore max basale perché l\'impostazione è inferiore alla tua basale massima nel profilo</string>
<string name="max_basal_multiplier">moltiplicatore max basale</string>

View file

@ -22,9 +22,9 @@
<string name="key_lgs_threshold" translatable="false">lgsThreshold</string>
<string name="key_DynISFAdjust" translatable="false">DynISFAdjust</string>
<string name="key_adjust_sensitivity" translatable="false">dynisf_adjust_sensitivity</string>
<string name="key_openapsma_max_basal" translatable="false">openapsma_max_basal</string>
<string name="dynisf_adjust_sensitivity">Adjust sensitivity and BG</string>
<string name="dynisf_adjust_sensitivity">Adjust sensitivity and basal</string>
<string name="dynisf_adjust_sensitivity_summary">If activated DynISF uses the last 24h TDD/7D TDD as the basis for adjusting calculated ISF and also for increasing and decreasing basal rate, in the same way that standard Autosens does</string>
<string name="DynISFAdjust_title" formatted="false">DynamicISF Adjustment Factor %</string>
<string name="DynISFAdjust_summary" formatted="false">Adjustment factor for DynamicISF. Set more than 100% for more aggressive correction doses, and less than 100% for less aggressive corrections.</string>
<string name="high_temptarget_raises_sensitivity_title">High temptarget raises sensitivity</string>
@ -151,4 +151,5 @@
<string name="fallback_smb_no_tdd">Fallback to SMB. Not enough TDD data.</string>
</resources>

View file

@ -52,6 +52,7 @@
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_adjust_sensitivity"
android:summary="@string/dynisf_adjust_sensitivity_summary"
android:title="@string/dynisf_adjust_sensitivity" />
<SwitchPreference

View file

@ -37,7 +37,7 @@
<string name="glucoseisnotavailable">Glicemia non disponibile</string>
<string name="glucosecomparedmgdl">Glicemia %1$s %2$.0f %3$s</string>
<string name="glucosecomparedmmol">Glicemia %1$s %2$.1f %3$s</string>
<string name="notemptarget">Il target temporaneo non esiste</string>
<string name="notemptarget">Il target temporaneo non è impostato</string>
<string name="temptargetcomparedmgdl">Temp-Target %1$s %2$.0f %3$s</string>
<string name="temptargetcomparedmmol">Temp-Target %1$s %2$.1f %3$s</string>
<string name="percentagecompared">PCT profilo %1$s %2$d</string>

View file

@ -11,7 +11,6 @@ import app.aaps.core.interfaces.maintenance.PrefsImportDir
import app.aaps.core.interfaces.maintenance.PrefsMetadataKey
import app.aaps.core.interfaces.resources.ResourceHelper
import app.aaps.core.interfaces.rx.bus.RxBus
import app.aaps.core.interfaces.rx.weardata.CwfData
import app.aaps.core.interfaces.rx.weardata.CwfFile
import app.aaps.core.interfaces.rx.weardata.EventData
import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat
@ -30,7 +29,6 @@ import org.joda.time.Hours
import org.joda.time.LocalDateTime
import org.joda.time.format.DateTimeFormat
import java.io.File
import java.util.zip.ZipInputStream
import javax.inject.Inject
import kotlin.math.abs
@ -89,7 +87,10 @@ class PrefFileListProviderImpl @Inject constructor(
// we sort only if we have metadata to be used for that
if (loadMetadata) {
prefFiles.sortWith(
prefFiles
.filter { it.metadata[PrefsMetadataKeyImpl.AAPS_FLAVOUR]?.status != null }
.toMutableList()
.sortWith(
compareByDescending<PrefsFile> { it.metadata[PrefsMetadataKeyImpl.AAPS_FLAVOUR]?.status as PrefsStatusImpl }
.thenByDescending { it.metadata[PrefsMetadataKeyImpl.CREATED_AT]?.value }
)

View file

@ -9,7 +9,7 @@ class SWButton(injector: HasAndroidInjector) : SWItem(injector, Type.BUTTON) {
private var buttonRunnable: Runnable? = null
private var buttonText = 0
private var buttonValidator: (() -> Boolean)? = { false }
private var buttonValidator: (() -> Boolean)? = null
private var button: Button? = null
fun text(buttonText: Int): SWButton {

View file

@ -88,7 +88,7 @@
<string name="preferences_export_canceled">Esportazione annullata! Le preferenze NON sono state esportate!</string>
<string name="preferences_import_canceled">Importazione annullata! Le preferenze NON sono state importate!</string>
<string name="preferences_import_impossible">Impossibile importare le preferenze!</string>
<string name="check_preferences_details_btn">Descrivi i problemi importazione…</string>
<string name="check_preferences_details_btn">Descrivi i problemi di importazione…</string>
<string name="check_preferences_details_title">Dettagli dei problemi di importazione</string>
<string name="check_preferences_import_btn">Importa</string>
<string name="check_preferences_import_anyway_btn">Importa comunque (PERICOLOSO!)</string>

View file

@ -21,9 +21,9 @@ class Objective4(injector: HasAndroidInjector) : Objective(injector, "maxbasal",
object : Task(this, R.string.objectives_maxbasal_gate) {
override fun isCompleted(): Boolean {
val profile = profileFunction.getProfile() ?: return false
val maxBasalSet = (activePlugin.activeAPS as PluginConstraints).applyBasalConstraints(ConstraintObject(Double.MAX_VALUE, aapsLogger), profile)
val maxBasalSet = sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 0.0)
val maxDailyBasal = profile.getMaxDailyBasal()
return maxBasalSet.value() > 2.8 * maxDailyBasal
return maxBasalSet > 2.8 * maxDailyBasal
}
}.learned(Learned(R.string.objectives_maxbasal_learned))
)

View file

@ -316,7 +316,7 @@ class ConstraintsCheckerImplTest : TestBaseWithProfile() {
// insightPlugin.setStatusResult(result);
// No limit by default
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
`when`(sp.getString(app.aaps.core.utils.R.string.key_age, "")).thenReturn("child")
@ -343,7 +343,7 @@ class ConstraintsCheckerImplTest : TestBaseWithProfile() {
// insightPlugin.setStatusResult(result);
// No limit by default
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
`when`(sp.getString(app.aaps.core.utils.R.string.key_age, "")).thenReturn("child")

View file

@ -138,7 +138,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
@Test
fun basalRateShouldBeLimited() {
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
`when`(sp.getString(app.aaps.core.utils.R.string.key_age, "")).thenReturn("child")
@ -167,7 +167,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
@Test
fun percentBasalRateShouldBeLimited() {
// No limit by default
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
`when`(sp.getString(app.aaps.core.utils.R.string.key_age, "")).thenReturn("child")
@ -190,7 +190,7 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
@Test
fun percentBasalShouldBeLimitedBySMB() {
// No limit by default
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.core.utils.R.string.key_openapsma_max_basal, 1.0)).thenReturn(1.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
`when`(sp.getDouble(app.aaps.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
`when`(sp.getString(app.aaps.core.utils.R.string.key_age, "")).thenReturn("child")

View file

@ -56,6 +56,7 @@ import app.aaps.core.interfaces.rx.events.EventAcceptOpenLoopChange
import app.aaps.core.interfaces.rx.events.EventBucketedDataCreated
import app.aaps.core.interfaces.rx.events.EventEffectiveProfileSwitchChanged
import app.aaps.core.interfaces.rx.events.EventExtendedBolusChange
import app.aaps.core.interfaces.rx.events.EventInitializationChanged
import app.aaps.core.interfaces.rx.events.EventMobileToWear
import app.aaps.core.interfaces.rx.events.EventNewOpenLoopNotification
import app.aaps.core.interfaces.rx.events.EventPreferenceChange
@ -307,6 +308,10 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overviewData.pumpStatus = it.getStatus(requireContext())
updatePumpStatus()
}, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ processButtonsVisibility() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.io)
@ -787,7 +792,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val lastBgDescription = overviewData.lastBgDescription(iobCobCalculator.ads)
runOnUiThread {
_binding ?: return@runOnUiThread
binding.infoLayout.bg.text = profileUtil.fromMgdlToStringInUnits(lastBg?.value)
binding.infoLayout.bg.text = profileUtil.fromMgdlToStringInUnits(lastBg?.recalculated)
binding.infoLayout.bg.setTextColor(lastBgColor)
trendArrow?.let { binding.infoLayout.arrow.setImageResource(it.directionToIcon()) }
binding.infoLayout.arrow.visibility = (trendArrow != null).toVisibilityKeepSpace()
@ -957,9 +962,12 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
profileUtil.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh)
)
} else {
// If the target is not the same as set in the profile then oref has overridden it
profileFunction.getProfile()?.let { profile ->
val targetUsed = loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0
// If the target is not the same as set in the profile then oref has overridden it
val targetUsed =
if (config.APS) loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0
else if (config.NSCLIENT) JsonHelper.safeGetDouble(processedDeviceStatusData.getAPSResult().json, "targetBg")
else 0.0
if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) {
aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed")
@ -1105,7 +1113,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val isfMgdl = profile?.getIsfMgdl()
val variableSens =
if (config.APS && request is VariableSensitivityResult) request.variableSens ?: 0.0
else if (config.NSCLIENT) JsonHelper.safeGetDouble(processedDeviceStatusData.getAPSResult(injector).json, "variable_sens")
else if (config.NSCLIENT) JsonHelper.safeGetDouble(processedDeviceStatusData.getAPSResult().json, "variable_sens")
else 0.0
if (variableSens != isfMgdl && variableSens != 0.0 && isfMgdl != null) {

View file

@ -14,7 +14,7 @@
<string name="smscommunicator_otp_reset_btn">Resetta autenticatori</string>
<string name="smscommunicator_otp_reset_title">Resetta chiave autenticatore</string>
<string name="smscommunicator_otp_reset_prompt">Sei sicuro di resettare la chiave autenticatore? Renderà non validi tutti gli autenticatori attualmente configurati e sarà necessario configurarli nuovamente.</string>
<string name="smscommunicator_otp_reset_successful">La nuova chiave autenticatore è stata generata! Usa il QRCode aggiornato per fornire gli autenticatori.</string>
<string name="smscommunicator_otp_reset_successful">La nuova chiave autenticatore è stata generata! Fornisci il QRCode aggiornato agli autenticatori.</string>
<string name="smscommunicator_otp_export_title">Esportazione OTP secret</string>
<string name="smscommunicator_otp_export_prompt">Sei sicuro di voler copiare l\'OTP secret negli appunti?\n\nPotresti averne bisogno solo se la tua app autenticatore ha problemi con la scansione del QRCode, vuoi inserirlo manualmente o vuoi configurare un token OTP hardware usando un\'app dedicata.</string>
<string name="smscommunicator_otp_export_successful">OTP secret (in formato Base32) esportato e copiato negli appunti. Incollalo nell\'autenticatore o nel configuratore hardware di OTP!</string>
@ -225,7 +225,7 @@
<string name="secondcarbsincrement">Secondo incremento di CHO</string>
<string name="thirdcarbsincrement">Terzo incremento di CHO</string>
<string name="cgm">CGM</string>
<string name="default_temptargets">Temp-Target predefiniti</string>
<string name="default_temptargets">Target temporanei predefiniti</string>
<string name="eatingsoon_duration">target \"pasto a breve\" - durata</string>
<string name="eatingsoon_target">target \"pasto a breve\"</string>
<string name="activity_duration">target \"attività fisica\" - durata</string>

View file

@ -5,14 +5,14 @@
<string name="sensitivity_aaps">Sensibilità AAPS</string>
<string name="sensitivity_weighted_average">Sensibilità WeightedAverage</string>
<string name="description_sensitivity_aaps">La sensibilità è calcolata allo stesso modo di Oref0, ma puoi specificare l\'intervallo di tempo al passato. L\'assorbimento minimo dei carboidrati è calcolato da \'max tempo assorbimento pasto\' nelle preferenze.</string>
<string name="description_sensitivity_oref1">La sensibilità è calcolata dai dati delle ultime 8h o 24h (usando tra i due periodi il più sensibile) e i carboidrati (se non assorbiti) vengono tagliati fuori dopo il tempo specificato nelle preferenze. Il plugin calcola anche UAM.</string>
<string name="description_sensitivity_oref1">La sensibilità è calcolata dai dati delle ultime 8h o 24h (usando tra i due periodi quello più sensibile) e i carboidrati (se non assorbiti) vengono tagliati fuori dopo il tempo specificato nelle preferenze. Il plugin calcola anche UAM.</string>
<string name="description_sensitivity_weighted_average">La sensibilità è calcolata come media ponderata dalle deviazioni. Le deviazioni più recenti hanno peso maggiore. L\'assorbimento minimo dei carboidrati è calcolato da \'max tempo assorbimento pasto\' nelle preferenze. Questo algoritmo è il più veloce nel seguire i cambiamenti di sensibilità.</string>
<string name="uam_disabled_oref1_not_selected">UAM disabilitato perché il plugin di sensibilità Oref1, dal quale UAM dipende, non è abilitato</string>
<string name="absorption_settings_title">Impostazioni assorbimento</string>
<string name="absorption_max_time_title">Max tempo assorbimento pasto [h]</string>
<string name="absorption_max_time_summary">Tempo in ore in cui è previsto che tutti i carboidrati del pasto vengano assorbiti</string>
<string name="openapsama_autosens_period">Intervallo per autosens [h]</string>
<string name="openapsama_autosens_period_summary">Quantità di ore al passato per il rilevamento della sensibilità (il tempo di assorbimento dei carboidrati è escluso)</string>
<string name="openapsama_autosens_period_summary">Quantità di ore del passato per il rilevamento della sensibilità (il tempo di assorbimento dei carboidrati è escluso)</string>
<string name="openapsama_autosens_max_summary">[Valore predefinito: 1.2]\nQuesto è un moltiplicatore di sicurezza per autosens (e presto autotune) per impostare un limite massimo del 20%% (col valore predefinito) su quanto alto può essere il rapporto di autosens, che a sua volta determina quanto in alto autosens può regolare le basali, quanto in basso può regolare ISF e quanto in basso può impostare il target glicemico.</string>
<string name="openapsama_autosens_min_summary">[Valore predefinito: 0.7]\nUn altro limite di sicurezza di autosens, imposta un blocco a quanto in basso autosens può regolare le basali e a quanto in alto può regolare ISF e target glicemici.</string>
<string name="openapsama_autosens_max">Max rapporto autosens</string>

View file

@ -94,6 +94,8 @@ class GarminPlugin @Inject constructor(
server?.close()
server = HttpServer(aapsLogger, port).apply {
registerEndpoint("/get", ::onGetBloodGlucose)
registerEndpoint("/carbs", ::onPostCarbs)
registerEndpoint("/connect", ::onConnectPump)
}
} else if (server != null) {
aapsLogger.info(LTag.GARMIN, "stopping HTTP server")
@ -243,4 +245,36 @@ class GarminPlugin @Inject constructor(
aapsLogger.warn(LTag.GARMIN, "Skip saving invalid HR $avg $samplingStart..$samplingEnd")
}
}
/** Handles carb notification from the device. */
@VisibleForTesting
@Suppress("UNUSED_PARAMETER")
fun onPostCarbs(caller: SocketAddress, uri: URI, requestBody: String?): CharSequence {
aapsLogger.info(LTag.GARMIN, "carbs from $caller, req: $uri")
postCarbs(getQueryParameter(uri, "carbs", 0L).toInt())
return ""
}
private fun postCarbs(carbs: Int) {
if (carbs > 0) {
loopHub.postCarbs(carbs)
}
}
/** Handles pump connected notification that the user entered on the Garmin device. */
@VisibleForTesting
@Suppress("UNUSED_PARAMETER")
fun onConnectPump(caller: SocketAddress, uri: URI, requestBody: String?): CharSequence {
aapsLogger.info(LTag.GARMIN, "connect from $caller, req: $uri")
val minutes = getQueryParameter(uri, "disconnectMinutes", 0L).toInt()
if (minutes > 0) {
loopHub.disconnectPump(minutes)
} else {
loopHub.connectPump()
}
val jo = JsonObject()
jo.addProperty("connected", loopHub.isConnected)
return jo.toString()
}
}

View file

@ -29,9 +29,19 @@ interface LoopHub {
/** Returns the factor by which the basal rate is currently raised (> 1) or lowered (< 1). */
val temporaryBasal: Double
/** Tells the loop algorithm that the pump is physically connected. */
fun connectPump()
/** Tells the loop algorithm that the pump will be physically disconnected
* for the given number of minutes. */
fun disconnectPump(minutes: Int)
/** Retrieves the glucose values starting at from. */
fun getGlucoseValues(from: Instant, ascending: Boolean): List<GlucoseValue>
/** Notifies the system that carbs were eaten and stores the value. */
fun postCarbs(carbohydrates: Int)
/** Stores hear rate readings that a taken and averaged of the given interval. */
fun storeHeartRate(
samplingStart: Instant, samplingEnd: Instant,

View file

@ -2,15 +2,26 @@ package app.aaps.plugins.sync.garmin
import androidx.annotation.VisibleForTesting
import app.aaps.core.interfaces.aps.Loop
import app.aaps.core.interfaces.constraints.ConstraintsChecker
import app.aaps.core.interfaces.db.GlucoseUnit
import app.aaps.core.interfaces.iob.IobCobCalculator
import app.aaps.core.interfaces.logging.AAPSLogger
import app.aaps.core.interfaces.logging.LTag
import app.aaps.core.interfaces.logging.UserEntryLogger
import app.aaps.core.interfaces.profile.Profile
import app.aaps.core.interfaces.profile.ProfileFunction
import app.aaps.core.interfaces.pump.DetailedBolusInfo
import app.aaps.core.interfaces.queue.CommandQueue
import app.aaps.core.interfaces.sharedPreferences.SP
import app.aaps.database.ValueWrapper
import app.aaps.database.entities.EffectiveProfileSwitch
import app.aaps.database.entities.GlucoseValue
import app.aaps.database.entities.HeartRate
import app.aaps.database.entities.OfflineEvent
import app.aaps.database.entities.UserEntry
import app.aaps.database.entities.ValueWithUnit
import app.aaps.database.impl.AppRepository
import app.aaps.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction
import app.aaps.database.impl.transactions.InsertOrUpdateHeartRateTransaction
import java.time.Clock
import java.time.Instant
@ -22,10 +33,15 @@ import javax.inject.Singleton
* Interface to the functionality of the looping algorithm and storage systems.
*/
class LoopHubImpl @Inject constructor(
private val aapsLogger: AAPSLogger,
private val commandQueue: CommandQueue,
private val constraintChecker: ConstraintsChecker,
private val iobCobCalculator: IobCobCalculator,
private val loop: Loop,
private val profileFunction: ProfileFunction,
private val repo: AppRepository,
private val userEntryLogger: UserEntryLogger,
private val sp: SP,
) : LoopHub {
@VisibleForTesting
@ -40,7 +56,9 @@ class LoopHubImpl @Inject constructor(
/** Returns the glucose unit (mg/dl or mmol/l) as selected by the user. */
override val glucoseUnit: GlucoseUnit
get() = profileFunction.getProfile()?.units ?: GlucoseUnit.MGDL
get() = GlucoseUnit.fromText(sp.getString(
app.aaps.core.utils.R.string.key_units,
GlucoseUnit.MGDL.asText))
/** Returns the remaining bolus insulin on board. */
override val insulinOnboard: Double
@ -65,12 +83,51 @@ class LoopHubImpl @Inject constructor(
return if (apsResult == null) Double.NaN else apsResult.percent / 100.0
}
/** Tells the loop algorithm that the pump is physicallly connected. */
override fun connectPump() {
repo.runTransaction(
CancelCurrentOfflineEventIfAnyTransaction(clock.millis())
).subscribe()
commandQueue.cancelTempBasal(true, null)
userEntryLogger.log(UserEntry.Action.RECONNECT, UserEntry.Sources.GarminDevice)
}
/** Tells the loop algorithm that the pump will be physically disconnected
* for the given number of minutes. */
override fun disconnectPump(minutes: Int) {
currentProfile?.let { p ->
loop.goToZeroTemp(minutes, p, OfflineEvent.Reason.DISCONNECT_PUMP)
userEntryLogger.log(
UserEntry.Action.DISCONNECT,
UserEntry.Sources.GarminDevice,
ValueWithUnit.Minute(minutes)
)
}
}
/** Retrieves the glucose values starting at from. */
override fun getGlucoseValues(from: Instant, ascending: Boolean): List<GlucoseValue> {
return repo.compatGetBgReadingsDataFromTime(from.toEpochMilli(), ascending)
.blockingGet()
}
/** Notifies the system that carbs were eaten and stores the value. */
override fun postCarbs(carbohydrates: Int) {
aapsLogger.info(LTag.GARMIN, "post $carbohydrates g carbohydrates")
val carbsAfterConstraints =
carbohydrates.coerceAtMost(constraintChecker.getMaxCarbsAllowed().value())
userEntryLogger.log(
UserEntry.Action.CARBS,
UserEntry.Sources.GarminDevice,
ValueWithUnit.Gram(carbsAfterConstraints)
)
val detailedBolusInfo = DetailedBolusInfo().apply {
eventType = DetailedBolusInfo.EventType.CARBS_CORRECTION
carbs = carbsAfterConstraints.toDouble()
}
commandQueue.bolus(detailedBolusInfo, null)
}
/** Stores hear rate readings that a taken and averaged of the given interval. */
override fun storeHeartRate(
samplingStart: Instant, samplingEnd: Instant,

View file

@ -81,10 +81,15 @@ class NsIncomingDataProcessor @Inject constructor(
)
}
/**
* Preprocess list of SGVs
*
* @return true if there was an accepted SGV
*/
@Suppress("SpellCheckingInspection")
fun processSgvs(sgvs: Any) {
fun processSgvs(sgvs: Any): Boolean {
if (!nsClientSource.isEnabled() && !sp.getBoolean(app.aaps.core.utils.R.string.key_ns_receive_cgm, false)) return
if (!nsClientSource.isEnabled() && !sp.getBoolean(app.aaps.core.utils.R.string.key_ns_receive_cgm, false)) return false
var latestDateInReceivedData: Long = 0
aapsLogger.debug(LTag.NSCLIENT, "Received NS Data: $sgvs")
@ -104,6 +109,7 @@ class NsIncomingDataProcessor @Inject constructor(
glucoseValues += sgv
}
}
if (latestDateInReceivedData > 0) {
activePlugin.activeNsClient?.updateLatestBgReceivedIfNewer(latestDateInReceivedData)
// Was that sgv more less 5 mins ago ?
if (T.msecs(dateUtil.now() - latestDateInReceivedData).mins() < 5L) {
@ -112,8 +118,15 @@ class NsIncomingDataProcessor @Inject constructor(
}
storeDataForDb.glucoseValues.addAll(glucoseValues)
}
return latestDateInReceivedData > 0
}
fun processTreatments(treatments: List<NSTreatment>) {
/**
* Preprocess list of treatments
*
* @return true if there was an accepted treatment
*/
fun processTreatments(treatments: List<NSTreatment>): Boolean {
try {
var latestDateInReceivedData: Long = 0
for (treatment in treatments) {
@ -189,11 +202,14 @@ class NsIncomingDataProcessor @Inject constructor(
}
}
}
if (latestDateInReceivedData > 0)
activePlugin.activeNsClient?.updateLatestTreatmentReceivedIfNewer(latestDateInReceivedData)
return latestDateInReceivedData > 0
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
rxBus.send(EventNSClientNewLog("◄ ERROR", error.localizedMessage))
}
return false
}
fun processFood(data: Any) {

View file

@ -130,8 +130,10 @@ class StoreDataForDbImpl @Inject constructor(
private val pause = 1000L // to slow down db operations
fun <T> HashMap<T, Long>.inc(key: T) =
synchronized(this) {
if (containsKey(key)) merge(key, 1, Long::plus)
else put(key, 1)
}
override fun storeGlucoseValuesToDb() {
if (glucoseValues.isNotEmpty())

View file

@ -84,7 +84,11 @@ class ReceiverDelegate @Inject constructor(
val newNetworkState = calculateStatus(ev)
if (newNetworkState != allowedNetworkState) {
allowedNetworkState = newNetworkState
if (!newNetworkState) blockingReason = rh.gs(R.string.blocked_by_connectivity)
if (!newNetworkState) {
blockingReason =
if (!ev.isAnyConnection) rh.gs(R.string.no_connectivity)
else rh.gs(R.string.blocked_by_connectivity)
}
processStateChange()
}
}

View file

@ -116,7 +116,7 @@ class ProcessedDeviceStatusDataImpl @Inject constructor(
override val openApsTimestamp: Long
get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1
override fun getAPSResult(injector: HasAndroidInjector): APSResult =
override fun getAPSResult(): APSResult =
instantiator.provideAPSResultObject().also {
it.json = openAPSData.suggested
it.date = openAPSData.clockSuggested

View file

@ -524,7 +524,11 @@ class NSClientService : DaggerService() {
}
}
val devicestatuses = gson.fromJson(data.getString("devicestatus"), Array<NSDeviceStatus>::class.java)
val devicestatuses = try {
gson.fromJson(data.getString("devicestatus"), Array<NSDeviceStatus>::class.java)
} catch (unused: Exception) {
emptyArray<NSDeviceStatus>()
}
if (devicestatuses.isNotEmpty()) {
rxBus.send(EventNSClientNewLog("◄ DATA", "received " + devicestatuses.size + " device statuses"))
nsDeviceStatusHandler.handleNewData(devicestatuses)

View file

@ -194,7 +194,7 @@ class NSClientV3Plugin @Inject constructor(
disposable += rxBus
.toObservable(EventAppExit::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ if (nsClientV3Service != null) context.unbindService(serviceConnection) }, fabricPrivacy::logException)
.subscribe({ stopService() }, fabricPrivacy::logException)
disposable += rxBus
.toObservable(EventConnectivityOptionChanged::class.java)
.observeOn(aapsSchedulers.io)
@ -222,6 +222,7 @@ class NSClientV3Plugin @Inject constructor(
ev.isChanged(rh.gs(app.aaps.core.utils.R.string.key_ns_announcements))
) {
stopService()
nsAndroidClient = null
setClient()
}
if (ev.isChanged(rh.gs(app.aaps.core.utils.R.string.key_local_profile_last_change)))
@ -359,7 +360,11 @@ class NSClientV3Plugin @Inject constructor(
}
private fun stopService() {
try {
if (nsClientV3Service != null) context.unbindService(serviceConnection)
} catch (e: Exception) {
nsClientV3Service = null
}
}
override fun resend(reason: String) {

View file

@ -65,7 +65,7 @@ class LoadBgWorker(
sp.putBoolean(app.aaps.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
// Schedule processing of fetched data and continue of loading
continueLoading = response.code != 304
nsIncomingDataProcessor.processSgvs(sgvs)
continueLoading = nsIncomingDataProcessor.processSgvs(sgvs)
} else {
// End first load
if (isFirstLoad) {

View file

@ -58,8 +58,8 @@ class LoadTreatmentsWorker(
val action = if (isFirstLoad) "RCV-F" else "RCV"
rxBus.send(EventNSClientNewLog("$action", "${treatments.size} TRs from ${dateUtil.dateAndTimeAndSecondsString(lastLoaded)}"))
// Schedule processing of fetched data and continue of loading
continueLoading = response.code != 304
nsIncomingDataProcessor.processTreatments(response.values)
continueLoading =
response.code != 304 && nsIncomingDataProcessor.processTreatments(response.values)
} else {
// End first load
if (isFirstLoad) {

View file

@ -2,6 +2,7 @@ package app.aaps.plugins.sync.wear.wearintegration
import android.app.NotificationManager
import android.content.Context
import app.aaps.core.interfaces.aps.AutosensDataStore
import app.aaps.core.interfaces.aps.Loop
import app.aaps.core.interfaces.configuration.Config
import app.aaps.core.interfaces.configuration.Constants
@ -741,7 +742,7 @@ class DataHandlerMobile @Inject constructor(
fun resendData(from: String) {
aapsLogger.debug(LTag.WEAR, "Sending data to wear from $from")
// SingleBg
iobCobCalculator.ads.lastBg()?.let { rxBus.send(EventMobileToWear(getSingleBG(it))) }
iobCobCalculator.ads.lastBg()?.let { rxBus.send(EventMobileToWear(getSingleBG(it, iobCobCalculator.ads))) }
// Preferences
rxBus.send(
EventMobileToWear(
@ -769,7 +770,7 @@ class DataHandlerMobile @Inject constructor(
)
// GraphData
iobCobCalculator.ads.getBucketedDataTableCopy()?.let { bucketedData ->
rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(bucketedData.map { getSingleBG(it) }))))
rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(bucketedData.map { getSingleBG(it, null) }))))
}
// Treatments
sendTreatments()
@ -969,7 +970,7 @@ class DataHandlerMobile @Inject constructor(
return deltaStringDetailed
}
private fun getSingleBG(glucoseValue: InMemoryGlucoseValue): EventData.SingleBg {
private fun getSingleBG(glucoseValue: InMemoryGlucoseValue, autosensDataStore: AutosensDataStore?): EventData.SingleBg {
val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true)
val units = profileFunction.getUnits()
val lowLine = profileUtil.convertToMgdl(defaultValueHelper.determineLowLine(), units)
@ -979,7 +980,7 @@ class DataHandlerMobile @Inject constructor(
timeStamp = glucoseValue.timestamp,
sgvString = profileUtil.stringInCurrentUnitsDetect(glucoseValue.value),
glucoseUnits = units.asText,
slopeArrow = trendCalculator.getTrendArrow(glucoseValue).symbol,
slopeArrow = (autosensDataStore?.let { ads -> trendCalculator.getTrendArrow(ads) } ?: GlucoseValue.TrendArrow.NONE).symbol,
delta = glucoseStatus?.let { deltaString(it.delta, it.delta * Constants.MGDL_TO_MMOLL, units) } ?: "--",
deltaDetailed = glucoseStatus?.let { deltaStringDetailed(it.delta, it.delta * Constants.MGDL_TO_MMOLL, units) } ?: "--",
avgDelta = glucoseStatus?.let { deltaString(it.shortAvgDelta, it.shortAvgDelta * Constants.MGDL_TO_MMOLL, units) } ?: "--",

View file

@ -143,7 +143,7 @@ class DataLayerListenerServiceMobile : WearableListenerService() {
}
rxDataPath -> {
aapsLogger.debug(LTag.WEAR, "onMessageReceived rxDataPath: ${String(messageEvent.data)}")
aapsLogger.debug(LTag.WEAR, "onMessageReceived rxDataPath: ${messageEvent.data.size}")
val command = EventData.deserializeByte(messageEvent.data)
rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId })
}
@ -213,13 +213,13 @@ class DataLayerListenerServiceMobile : WearableListenerService() {
}
private fun sendMessage(path: String, data: ByteArray) {
aapsLogger.debug(LTag.WEAR, "sendMessage: $path")
aapsLogger.debug(LTag.WEAR, "sendMessage: $path ${data.size}")
transcriptionNodeId?.also { nodeId ->
messageClient
.sendMessage(nodeId, path, data).apply {
addOnSuccessListener { }
addOnFailureListener {
aapsLogger.debug(LTag.WEAR, "sendMessage: $path failure")
aapsLogger.debug(LTag.WEAR, "sendMessage: $path failure ${data.size}")
}
}
}

View file

@ -116,7 +116,7 @@
<string name="xdrip_local_broadcasts_summary">Envoyer les glycémies et les traitements à xDrip+. La source de données \"xDrip+ Sync Follower\" doit être sélectionnée et l\'acceptation des données doit être activée dans Paramètres - Paramètres Inter-app - Accepter Glycémies/Traitements</string>
<string name="xdrip_local_broadcasts_title">Activer les diffusions vers xDrip+.</string>
<!-- DataBroadcast-->
<string name="data_broadcaster">Diffusue de données</string>
<string name="data_broadcaster">Diffuseur de données</string>
<string name="data_broadcaster_short">DD</string>
<string name="data_broadcaster_description">Diffuser des données sur l\'application G-Watch Wear de Garmin</string>
<!-- GarminPlugin -->

View file

@ -98,7 +98,7 @@
<string name="upload_now">Carica adesso</string>
<string name="not_connected">Non connesso</string>
<string name="read_only">Sola lettura</string>
<string name="working">Lavorazione</string>
<string name="working">In esecuzione</string>
<!-- xDrip status line -->
<!-- Xdrip StatusLine -->
<string name="xdrip">xDrip+</string>
@ -138,7 +138,7 @@
<string name="no_success">non riuscito - controlla il telefono</string>
<string name="wear_settings">Impostazioni smartwatch</string>
<string name="wearcontrol_title">Controlli da smartwatch</string>
<string name="wearcontrol_summary">Imposta Temp-Target e inserisci trattamenti dallo smartwatch.</string>
<string name="wearcontrol_summary">Imposta Target temporanei e inserisci trattamenti dallo smartwatch.</string>
<string name="wear_wizard_settings_summary">Calcoli inclusi nel risultato del Calcolatore:</string>
<string name="wear_general_settings">Impostazioni generali</string>
<string name="wear_notifysmb_title">Notifica SMB</string>

View file

@ -116,7 +116,12 @@
<string name="xdrip_local_broadcasts_summary">Отправлять данные о глюкозе и терапии на xDrip+. Источником данных должен быть выбран \"xDrip+ Sync Follower\" а в настройках между приложениями надо включить - Принимать глюкозу/терапию</string>
<string name="xdrip_local_broadcasts_title">Включить трансляции для xDrip+.</string>
<!-- DataBroadcast-->
<string name="data_broadcaster_short">DBRO</string>
<string name="data_broadcaster_description">Передавать данные приложению Garmin\'s G-Watch Wear</string>
<!-- GarminPlugin -->
<string name="garmin">Garmin</string>
<string name="garmin_description">Подключение к устройству Garmin (Fenix, Edge, …)</string>
<string name="key_garmin_settings">Настройки Garmin</string>
<!-- Wear-->
<string name="wear_shortname">WEAR</string>
<string name="description_wear">Мониторить и контролировать AAPS при помощи часов WearOS.</string>

View file

@ -116,11 +116,14 @@
<string name="xdrip_local_broadcasts_summary">Poslať dáta o glykémii a ošetrení do xDrip+. Musí byť vybraný zdroj dát \"xDrip+ Sync Follower\" a prijímanie dát musí byť povolené v Nastavenia - Nastavenie komunikácie medzi aplikáciami - Prijímať Glykémie/Ošetrenia</string>
<string name="xdrip_local_broadcasts_title">Povoliť odosielanie do xDrip+.</string>
<!-- DataBroadcast-->
<string name="data_broadcaster_short">DBRO</string>
<string name="data_broadcaster_description">Odosielanie dát do Garmin aplikácie G-Watch Wear</string>
<!-- GarminPlugin -->
<string name="garmin">Garmin</string>
<string name="garmin_description">Pripájanie k zariadeniu Garmin (Fénix, Edge, ...)</string>
<string name="key_garmin_settings">Garmin nastavenia</string>
<!-- Wear-->
<string name="wear_shortname">WEAR</string>
<string name="description_wear">Zobrazovanie stavu a riadenie AndroidAPS z hodiniek s WearOS.</string>
<string name="no_watch_connected">(Žiadne hodinky nie sú pripojené)</string>
<string name="pump_status">Stav pumpy</string>

View file

@ -41,6 +41,7 @@
<string name="description_ns_client_v3">Synchronizes your data with Nightscout using v3 API</string>
<string name="blocked_by_charging">Blocked by charging options</string>
<string name="blocked_by_connectivity">Blocked by connectivity options</string>
<string name="no_connectivity">No connectivity</string>
<string name="unsupported_ns_version">Unsupported version of Nightscout</string>
<string name="openaps_short">OAPS</string>
<string name="uploader_short">UPLD</string>

View file

@ -1,5 +1,6 @@
package app.aaps.plugins.sync.garmin
import app.aaps.core.interfaces.db.GlucoseUnit
import app.aaps.core.interfaces.resources.ResourceHelper
import app.aaps.core.interfaces.rx.events.EventNewBG
import app.aaps.core.interfaces.sharedPreferences.SP
@ -9,14 +10,18 @@ import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
import org.mockito.Mockito.atMost
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when`
import java.net.SocketAddress
import java.net.URI
import java.time.Clock
import java.time.Instant
@ -113,4 +118,91 @@ class GarminPluginTest: TestBase() {
verify(gp.newValue).signalAll()
verify(loopHub).getGlucoseValues(from, true)
}
@Test
fun testOnGetBloodGlucose() {
`when`(loopHub.isConnected).thenReturn(true)
`when`(loopHub.insulinOnboard).thenReturn(3.14)
`when`(loopHub.temporaryBasal).thenReturn(0.8)
val from = getGlucoseValuesFrom
`when`(loopHub.getGlucoseValues(from, true)).thenReturn(
listOf(createGlucoseValue(Instant.ofEpochSecond(1_000))))
val hr = createHeartRate(99)
val uri = createUri(hr)
val result = gp.onGetBloodGlucose(mock(SocketAddress::class.java), uri, null)
assertEquals(
"{\"encodedGlucose\":\"0A+6AQ==\"," +
"\"remainingInsulin\":3.14," +
"\"glucoseUnit\":\"mmoll\",\"temporaryBasalRate\":0.8," +
"\"profile\":\"D\",\"connected\":true}",
result.toString())
verify(loopHub).getGlucoseValues(from, true)
verify(loopHub).insulinOnboard
verify(loopHub).temporaryBasal
verify(loopHub).isConnected
verify(loopHub).glucoseUnit
verify(loopHub).storeHeartRate(
Instant.ofEpochSecond(hr["hrStart"] as Long),
Instant.ofEpochSecond(hr["hrEnd"] as Long),
99,
hr["device"] as String)
}
@Test
fun testOnGetBloodGlucose_Wait() {
`when`(loopHub.isConnected).thenReturn(true)
`when`(loopHub.insulinOnboard).thenReturn(3.14)
`when`(loopHub.temporaryBasal).thenReturn(0.8)
`when`(loopHub.glucoseUnit).thenReturn(GlucoseUnit.MMOL)
val from = getGlucoseValuesFrom
`when`(loopHub.getGlucoseValues(from, true)).thenReturn(
listOf(createGlucoseValue(clock.instant().minusSeconds(330))))
val params = createHeartRate(99).toMutableMap()
params["wait"] = 10
val uri = createUri(params)
gp.newValue = mock(Condition::class.java)
val result = gp.onGetBloodGlucose(mock(SocketAddress::class.java), uri, null)
assertEquals(
"{\"encodedGlucose\":\"/wS6AQ==\"," +
"\"remainingInsulin\":3.14," +
"\"glucoseUnit\":\"mmoll\",\"temporaryBasalRate\":0.8," +
"\"profile\":\"D\",\"connected\":true}",
result.toString())
verify(gp.newValue).awaitNanos(anyLong())
verify(loopHub, times(2)).getGlucoseValues(from, true)
verify(loopHub).insulinOnboard
verify(loopHub).temporaryBasal
verify(loopHub).isConnected
verify(loopHub).glucoseUnit
verify(loopHub).storeHeartRate(
Instant.ofEpochSecond(params["hrStart"] as Long),
Instant.ofEpochSecond(params["hrEnd"] as Long),
99,
params["device"] as String)
}
@Test
fun testOnPostCarbs() {
val uri = createUri(mapOf("carbs" to "12"))
assertEquals("", gp.onPostCarbs(mock(SocketAddress::class.java), uri, null))
verify(loopHub).postCarbs(12)
}
@Test
fun testOnConnectPump_Disconnect() {
val uri = createUri(mapOf("disconnectMinutes" to "20"))
`when`(loopHub.isConnected).thenReturn(false)
assertEquals("{\"connected\":false}", gp.onConnectPump(mock(SocketAddress::class.java), uri, null))
verify(loopHub).disconnectPump(20)
verify(loopHub).isConnected
}
@Test
fun testOnConnectPump_Connect() {
val uri = createUri(mapOf("disconnectMinutes" to "0"))
`when`(loopHub.isConnected).thenReturn(true)
assertEquals("{\"connected\":true}", gp.onConnectPump(mock(SocketAddress::class.java), uri, null))
verify(loopHub).connectPump()
verify(loopHub).isConnected
}
}

View file

@ -1,8 +1,8 @@
package app.aaps.plugins.sync.garmin
import app.aaps.core.interfaces.aps.APSResult
import app.aaps.core.interfaces.aps.Loop
import app.aaps.core.interfaces.constraints.Constraint
import app.aaps.core.interfaces.constraints.ConstraintsChecker
import app.aaps.core.interfaces.db.GlucoseUnit
import app.aaps.core.interfaces.iob.IobCobCalculator
@ -10,13 +10,19 @@ import app.aaps.core.interfaces.iob.IobTotal
import app.aaps.core.interfaces.logging.UserEntryLogger
import app.aaps.core.interfaces.profile.Profile
import app.aaps.core.interfaces.profile.ProfileFunction
import app.aaps.core.interfaces.pump.DetailedBolusInfo
import app.aaps.core.interfaces.queue.CommandQueue
import app.aaps.core.interfaces.sharedPreferences.SP
import app.aaps.database.ValueWrapper
import app.aaps.database.entities.EffectiveProfileSwitch
import app.aaps.database.entities.GlucoseValue
import app.aaps.database.entities.HeartRate
import app.aaps.database.entities.OfflineEvent
import app.aaps.database.entities.UserEntry
import app.aaps.database.entities.ValueWithUnit
import app.aaps.database.entities.embedments.InsulinConfiguration
import app.aaps.database.impl.AppRepository
import app.aaps.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction
import app.aaps.database.impl.transactions.InsertOrUpdateHeartRateTransaction
import app.aaps.shared.tests.TestBase
import io.reactivex.rxjava3.core.Completable
@ -27,6 +33,8 @@ import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.argThat
import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
@ -45,13 +53,17 @@ class LoopHubTest: TestBase() {
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var repo: AppRepository
@Mock lateinit var userEntryLogger: UserEntryLogger
@Mock lateinit var sp: SP
private lateinit var loopHub: LoopHubImpl
private val clock = Clock.fixed(Instant.ofEpochMilli(10_000), ZoneId.of("UTC"))
@BeforeEach
fun setup() {
loopHub = LoopHubImpl(iobCobCalculator, loop, profileFunction, repo)
loopHub = LoopHubImpl(
aapsLogger, commandQueue, constraints, iobCobCalculator, loop,
profileFunction, repo, userEntryLogger, sp
)
loopHub.clock = clock
}
@ -83,18 +95,10 @@ class LoopHubTest: TestBase() {
@Test
fun testGlucoseUnit() {
val profile = mock(Profile::class.java)
`when`(profile.units).thenReturn(GlucoseUnit.MMOL)
`when`(profileFunction.getProfile()).thenReturn(profile)
assertEquals(GlucoseUnit.MMOL, loopHub.glucoseUnit)
verify(profileFunction, times(1)).getProfile()
}
@Test
fun testGlucoseUnitNullProfile() {
`when`(profileFunction.getProfile()).thenReturn(null)
`when`(sp.getString(app.aaps.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText)).thenReturn("mg/dl")
assertEquals(GlucoseUnit.MGDL, loopHub.glucoseUnit)
verify(profileFunction, times(1)).getProfile()
`when`(sp.getString(app.aaps.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText)).thenReturn("mmol")
assertEquals(GlucoseUnit.MMOL, loopHub.glucoseUnit)
}
@Test
@ -165,6 +169,32 @@ class LoopHubTest: TestBase() {
verify(loop, times(1)).lastRun
}
@Test
fun testConnectPump() {
val c = mock(Completable::class.java)
val dummy = CancelCurrentOfflineEventIfAnyTransaction(0)
val matcher = {
argThat<CancelCurrentOfflineEventIfAnyTransaction> { t -> t.timestamp == clock.millis() }}
`when`(repo.runTransaction(matcher() ?: dummy)).thenReturn(c)
loopHub.connectPump()
verify(repo).runTransaction(matcher() ?: dummy)
verify(commandQueue).cancelTempBasal(true, null)
verify(userEntryLogger).log(UserEntry.Action.RECONNECT, UserEntry.Sources.GarminDevice)
}
@Test
fun testDisconnectPump() {
val profile = mock(Profile::class.java)
`when`(profileFunction.getProfile()).thenReturn(profile)
loopHub.disconnectPump(23)
verify(profileFunction).getProfile()
verify(loop).goToZeroTemp(23, profile, OfflineEvent.Reason.DISCONNECT_PUMP)
verify(userEntryLogger).log(
UserEntry.Action.DISCONNECT,
UserEntry.Sources.GarminDevice,
ValueWithUnit.Minute(23))
}
@Test
fun testGetGlucoseValues() {
val glucoseValues = listOf(
@ -180,6 +210,25 @@ class LoopHubTest: TestBase() {
verify(repo).compatGetBgReadingsDataFromTime(1001_000, false)
}
@Test
fun testPostCarbs() {
@Suppress("unchecked_cast")
val constraint = mock(Constraint::class.java) as Constraint<Int>
`when`(constraint.value()).thenReturn(99)
`when`(constraints.getMaxCarbsAllowed()).thenReturn(constraint)
loopHub.postCarbs(100)
verify(constraints).getMaxCarbsAllowed()
verify(userEntryLogger).log(
UserEntry.Action.CARBS,
UserEntry.Sources.GarminDevice,
ValueWithUnit.Gram(99))
verify(commandQueue).bolus(
argThat { b ->
b!!.eventType == DetailedBolusInfo.EventType.CARBS_CORRECTION &&
b.carbs == 99.0 }?: DetailedBolusInfo() ,
isNull())
}
@Test
fun testStoreHeartRate() {
val samplingStart = Instant.ofEpochMilli(1_001_000)

View file

@ -29,14 +29,14 @@
<string name="combo_notification_check_time_date">Necessario aggiornare orologio micro</string>
<string name="combo_pump_tbr_cancelled_warrning">Avviso TBR CANCELLATO: confermato</string>
<string name="combo_error_no_connection_no_bolus_delivered">Il micro potrebbe non essere raggiungibile. Nessun bolo erogato</string>
<string name="combo_error_no_bolus_delivered">Erogazione bolo fallita. Sembra che nessun bolo sia stato erogato. Per sicurezza, controlla il micro per evitare un doppio bolo e se è tutto ok, erogalo di nuovo. Come protezione da eventuali \"bug\", i boli non vengono ripetuti automaticamente.</string>
<string name="combo_error_no_bolus_delivered">Erogazione bolo fallita. Sembra che nessun bolo sia stato erogato. Per sicurezza controlla il micro per evitare un doppio bolo e se è tutto ok, erogalo di nuovo. Come protezione da eventuali \"bug\", i boli non vengono ripetuti automaticamente.</string>
<string name="combo_error_partial_bolus_delivered">Solo la quantità di %1$.2f U del bolo richiesto di %2$.2f U è stata erogata a causa di un errore. Controlla il micro per verificare quanto accaduto e intraprendi le azioni necessarie.</string>
<string name="combo_error_bolus_verification_failed">Erogazione del bolo e verifica dello storico del micro fallite. Controlla il micro. Se è stato erogato un bolo, sarà aggiunto ai trattamenti durante la successiva connessione al micro.</string>
<string name="combo_reservoir_level_insufficient_for_bolus">Insulina nel serbatoio insufficiente per erogare il bolo</string>
<string name="combo_invalid_setup">Configurazione micro non valida, controlla la documentazione e verifica che il menu Quick Info sia denominato QUICK INFO usando \"360 configuration software\".</string>
<string name="combo_actvity_reading_basal_profile">Lettura profilo basale</string>
<string name="combo_bolus_rejected_due_to_pump_history_change">Lo storico del micro è cambiato dopo il calcolo del bolo. Il bolo non è stato erogato. Ricalcolare se un bolo è ancora necessario.</string>
<string name="combo_error_updating_treatment_record">Bolo erogato con successo, ma non è possibile aggiungere la voce ai trattamenti. Questo può accadere se due piccoli boli della stessa quantità sono stati somministrati negli ultimi due minuti. Controlla lo storico del micro e le voci della sezione Trattamenti e usa la sezione Portale per aggiungere eventuali voci mancanti. Assicurati di non aggiungere voci che si riferiscano al medesimo minuto e alla stessa quantità.</string>
<string name="combo_error_updating_treatment_record">Bolo erogato con successo ma non è stato possibile aggiungere la voce ai trattamenti. Questo può accadere se due piccoli boli della stessa quantità sono stati somministrati negli ultimi due minuti. Controlla lo storico del micro e le voci della sezione Trattamenti e usa la sezione Portale per aggiungere eventuali voci mancanti. Assicurati di non aggiungere voci che si riferiscano al medesimo minuto e alla stessa quantità.</string>
<string name="combo_high_temp_rejected_due_to_pump_history_changes">Rifiuto basale temporanea \"alta\" in quanto il calcolo non ha considerato i cambiamenti recenti allo storico del micro</string>
<string name="combo_activity_checking_pump_state">Aggiornamento stato micro</string>
<string name="combo_warning_pump_basal_rate_changed">La velocità basale sul micro è cambiata e verrà aggiornata a breve</string>
@ -44,14 +44,14 @@
<string name="combo_activity_checking_for_history_changes">Controllo modifiche allo storico</string>
<string name="combo_error_multiple_boluses_with_identical_timestamp">Sono appena stati importati più boli con la stessa quantità nello stesso minuto. Solo un record può essere aggiunto ai trattamenti. Controlla il micro e aggiungi manualmente un record di bolo usando la sezione Portale. Assicurati di creare un bolo con un\'ora non usata da nessun altro bolo.</string>
<string name="combo_check_date">L\'ultimo bolo è più vecchio di 24 ore o ha una data nel futuro. Controlla che la data sul micro sia impostata correttamente.</string>
<string name="combo_suspious_bolus_time">L\'ora/la data del bolo erogato sul micro sembra errata, IOB probabilmente non è corretto. Controlla l\'ora e/o la data del micro.</string>
<string name="combo_suspious_bolus_time">L\'ora e/o la data del bolo erogato sul micro sembra errata, IOB probabilmente non è corretto. Controlla l\'ora e/o la data del micro.</string>
<string name="combo_bolus_count">Conteggio bolo</string>
<string name="combo_tbr_count">Conteggio TBR</string>
<string name="bolusstopped">Bolo stoppato</string>
<string name="bolusstopping">Stop del bolo in corso</string>
<string name="pump_commerror_label">Conta degli errori comunicazione</string>
<string name="show_comm_error_count_title">Mostra conta degli errori di comunicazione</string>
<string name="show_comm_error_count_summary">Mostra la conta degli errori quando si comunica con Ruffy. Nella maggior parte dei casi, un numero più alto di 0 denota problemi di comunicazione con Ruffy (potrebbe essere necessario riavviare).</string>
<string name="pump_commerror_label">Conteggio degli errori comunicazione</string>
<string name="show_comm_error_count_title">Mostra conteggio degli errori di comunicazione</string>
<string name="show_comm_error_count_summary">Mostra il conteggio degli errori quando si comunica con Ruffy. Nella maggior parte dei casi un numero più alto di 0 denota problemi di comunicazione con esso (potrebbe essere necessario riavviare).</string>
<string name="combo_error_display_never">Mai</string>
<string name="combo_error_display_error">In caso di errore</string>
<string name="combo_error_display_always">Sempre</string>

View file

@ -3,7 +3,7 @@
<string name="combov2_plugin_name">Accu-Check Combo</string>
<string name="combov2_plugin_description">Integrazione nativa del microinfusore Accu-Chek Combo</string>
<string name="combov2_could_not_connect">Impossibile connettersi al micro</string>
<string name="combov2_not_paired">Non associato a un micro</string>
<string name="combov2_not_paired">Non associato ad un micro</string>
<string name="combov2_pump_terminated_connection">Il micro ha terminato la connessione</string>
<string name="combov2_warning">Avviso Combo</string>
<string name="combov2_error">Errore Combo</string>
@ -21,7 +21,7 @@
<string name="combov2_error_11">Set di infusione non caricato</string>
<string name="combov2_extended_bolus_not_supported">Il bolo esteso non è supportato</string>
<string name="combov2_title">Accu-Check Combo v2</string>
<string name="combov2_pair_with_pump_title">Associa con micro</string>
<string name="combov2_pair_with_pump_title">Associa micro</string>
<string name="combov2_unpair_pump_title">Disassocia micro</string>
<string name="combov2_driver_state_label">Stato driver</string>
<string name="combov2_current_activity_label">Attività corrente</string>
@ -29,11 +29,11 @@
<string name="combov2_start_pairing">Avvia associazione</string>
<string name="combov2_pairing_in_progress">Associazione Combo in corso</string>
<string name="combov2_pairing_start_steps">Passi per eseguire l\'associazione con il tuo Combo:\n\n
1. Sul tuo microinfusore, vai alle Impostazioni Bluetooth\n
1. Sul tuo microinfusore vai alle Impostazioni Bluetooth\n
2. Controlla se un dispositivo è già mostrato come associato; in tal caso, vai alla schermata del microinfusore \"Elimina dispositivo\" per eliminare/disassociare quel dispositivo\n
3. Vai alla schermata del microinfusore \"Aggiungi dispositivo\" e avvia l\'associazione sul microinfusore\n
4. Clicca sul tasto \"Avvia associazione\" qui sotto per avviare l\'associazione in AndroidAPS\n</string>
<string name="combov2_steps_if_no_connection_during_pairing">Dopo un po \', il nome del telefono viene mostrato sullo schermo del micro; premi il tasto di CONFERMA per confermare.\n\n
<string name="combov2_steps_if_no_connection_during_pairing">Dopo un po\', il nome del telefono viene mostrato sullo schermo del micro; premi il tasto di CONFERMA per confermare.\n\n
Quando l\'associazione è stata completata con successo, conferma la fine dell\'associazione sul microinfusore e torna alla schermata principale del microinfusore premendo il tasto di CONFERMA due volte.\n\n
Se non viene stabilita alcuna connessione dopo più di ~5 minuti:\n\n
1. Premi Indietro o il tasto \"Annulla associazione\"\n

View file

@ -130,8 +130,8 @@
<string name="diaconn_g8_logsuccess">OK</string>
<string name="diaconn_g8_logmealsuccess">Pasto: OK</string>
<string name="diaconn_g8_errorcode_1">Ricerca non possibile a causa di un errore CRC del pacchetto.</string>
<string name="diaconn_g8_errorcode_2">Impostazione non possibile - errore di un parametro di input.</string>
<string name="diaconn_g8_errorcode_3">Impostazione non possibile - errore di specifica del protocollo.</string>
<string name="diaconn_g8_errorcode_2">Impostazione non possibile per errore di un parametro di input.</string>
<string name="diaconn_g8_errorcode_3">Impostazione non possibile per errore di specifica del protocollo.</string>
<string name="diaconn_g8_errorcode_4">Pasti programmati, erogazione non possibile ora.</string>
<string name="diaconn_g8_errorcode_6">Cancellato dal micro</string>
<string name="diaconn_g8_errorcode_7">Altre azioni in corso, limitazione impostazioni app.</string>
@ -148,7 +148,7 @@
<string name="diaconn_g8_logtubechange_summary">Aggiungi evento \"cambio catetere\" alle note quando rilevato nello storico</string>
<string name="diaconn_g8_logtempstart">Avvio basale temporanea</string>
<string name="diaconn_g8_errorcode_32">Durante l\'esecuzione di LGS, lerogazione è limitata</string>
<string name="diaconn_g8_errorcode_33">Stato LGS già su ON. Comando di attivazione rifiutato.</string>
<string name="diaconn_g8_errorcode_33">Stato LGS già su ON, comando di attivazione rifiutato.</string>
<string name="diaconn_g8_errorcode_34">Stato LGS già su OFF. Comando di disattivazione rifiutato.</string>
<string name="diaconn_g8_errorcode_35">L\'avvio della basale temporanea viene rifiutato quando è già in esecuzione una basale temporanea</string>
<string name="diaconn_g8_errorcode_36">Lo stop della basale temporanea viene rifiutato quando non è in esecuzione alcuna basale temporanea</string>

View file

@ -44,7 +44,7 @@
<string name="patch_comm_error_during_discard_desc_2">Per la disattivazione unilaterale, tocca \'Scarta\'.</string>
<string name="patch_manually_turning_off_alarm_title">Disattivazione manuale allarme patch</string>
<string name="patch_manually_turning_off_alarm_desc_1">Se disattivato unilateralmente durante un errore di comunicazione, il BIP di allarme dalla patch potrebbe non arrestarsi.</string>
<string name="patch_manually_turning_off_alarm_desc_2">In questo caso, puoi fermarlo completamente colpendo la porta di rilascio manuale dell\'allarme sulla patch come di seguito:</string>
<string name="patch_manually_turning_off_alarm_desc_2">In questo caso, puoi fermarlo completamente tramite lo switch manuale dell\'allarme sulla patch come di seguito:</string>
<string name="patch_manually_turning_off_alarm_step_1">1. Rimuovi la patch dal corpo e stacca il nastro adesivo.</string>
<string name="patch_manually_turning_off_alarm_step_2">2. Usa una clip, colpisci con forza il foro accanto alla porta di riempimento dell\'insulina.</string>
<string name="patch_wake_up">Riempimento insulina</string>
@ -87,7 +87,7 @@
<string name="patch_communication_check_helper_1">Avvicinare il dispositivo alla patch.</string>
<string name="patch_communication_check_helper_2">Spostati in un altro posto e riprova.</string>
<string name="patch_communication_failed">Errore comunicazione</string>
<string name="patch_communication_succeed">Riuscita comunicazione</string>
<string name="patch_communication_succeed">Comunicazione riuscita</string>
<string name="patch_communication_succeed_message">Connesso con la patch</string>
<string name="patch_cancel_pairing">Annulla associazione</string>
<string name="symbol_days">giorni</string>
@ -113,8 +113,8 @@
<string name="string_in_progress">Elaborazione</string>
<string name="retry">Riprova</string>
<string name="string_caution_not_remove_needle_cap">[Caution] NON rimuovere la protezione dell\'ago e il supporto adesivo sino a ulteriori istruzioni.</string>
<string name="string_are_you_sure_to_discard_current_patch">Sei sicuro di scartare la patch corrent?</string>
<string name="string_unconfirmed_bolus_info_discard_confirm_message">A causa di informazioni non confermate riguardo il bolo, il calcolo del bolo non può essere usato fino a %s.\n\nSei sicuro di voler scartare la patch corrente?</string>
<string name="string_are_you_sure_to_discard_current_patch">Sei sicuro di voler scartare la patch corrente?</string>
<string name="string_unconfirmed_bolus_info_discard_confirm_message">A causa di informazioni non confermate riguardo il bolo, il calcolatore del bolo non può essere usato fino a %s.\n\nSei sicuro di voler scartare la patch corrente?</string>
<string name="needle_insertion_error_1">Errore inserimento ago.</string>
<string name="needle_insertion_error_2">Controlla che la direzione del foro rimanente dopo aver girato la leva sia dritta, quindi tocca \'Riprova\'.</string>
<string name="needle_insertion_error_3">Tocca \'Scarta\' per disattivare la patch.</string>

View file

@ -52,7 +52,7 @@
<!-- <string name="medtronic_history_group_all">All</string>-->
<string name="medtronic_pump_history">Storico micro Medtronic</string>
<!-- <string name="medtronic_cmd_profile_not_set">Remote Basal profile setting is not supported. Please modify Basal profile on your pump manually.</string> -->
<string name="medtronic_cmd_cancel_bolus_not_supported">Hai cancellato il bolo, dopo che era già stato impostato sul micro. Dal momento che il micro Medtronic non supporta la cancellazione, avrai bisogno di cancellare il bolo manualmente. Metti il micro in modalità sospensione e poi fallo ripartire (se vuoi ancora cancellare il bolo). L\'applicazione rileverà le modifiche al prossimo aggiornamento (in meno di 5 minuti).</string>
<string name="medtronic_cmd_cancel_bolus_not_supported">Hai cancellato il bolo dopo che era già stato impostato sul micro. Dal momento che il micro Medtronic non supporta la cancellazione, avrai bisogno di cancellare il bolo manualmente. Metti il micro in modalità sospensione e poi fallo ripartire (se vuoi ancora cancellare il bolo). L\'applicazione rileverà le modifiche al prossimo aggiornamento (in meno di 5 minuti).</string>
<string name="medtronic_cmd_cant_read_tbr">Impossibile leggere il TBR corrente.</string>
<string name="medtronic_cmd_cant_cancel_tbr_stop_op">Impossibile cancellare il TBR corrente. Arresto dell\'operazione.</string>
<string name="medtronic_cmd_set_profile_pattern_overflow">Impostazione del profilo fallita. A causa dei seguenti modelli, hai una velocità basale troppo grande: %1$s</string>

View file

@ -559,10 +559,30 @@ class MedtrumService : DaggerService(), BLECommCallback {
private fun syncRecords(): Boolean {
aapsLogger.debug(LTag.PUMP, "syncRecords: called!, syncedSequenceNumber: ${medtrumPump.syncedSequenceNumber}, currentSequenceNumber: ${medtrumPump.currentSequenceNumber}")
var result = true
var failureCount = 0
if (medtrumPump.syncedSequenceNumber < medtrumPump.currentSequenceNumber) {
for (sequence in (medtrumPump.syncedSequenceNumber + 1)..medtrumPump.currentSequenceNumber) {
result = sendPacketAndGetResponse(GetRecordPacket(injector, sequence), COMMAND_SYNC_TIMEOUT_SEC)
if (!result) break
val packet = GetRecordPacket(injector, sequence)
result = sendPacketAndGetResponse(packet, COMMAND_SYNC_TIMEOUT_SEC)
if (!result && packet.failed) {
// Record may be broken for unkown reasons, try the next packet if that fails abort
failureCount++
aapsLogger.error(LTag.PUMPCOMM, "Failed to sync record $sequence, failureCount: $failureCount")
if (failureCount == 1) {
// Show notification to alert user of failure
uiInteraction.addNotificationWithSound(
Notification.PUMP_SYNC_ERROR,
rh.gs(R.string.pump_sync_error),
Notification.URGENT,
app.aaps.core.ui.R.raw.alarm
)
} else if (failureCount >= 2) {
break
}
} else if (!result) {
// Communication timeout, try again
break
}
}
}
return result

View file

@ -112,6 +112,8 @@
<string name="alarm_setting_summary">Selectează setările preferate pentru alarma pompei.</string>
<string name="pump_warning_notification_title">Notificare la avertizarea pompei</string>
<string name="pump_warning_notification_summary">Arată notificare cu privire la avertismentele non-critice ale pompei: baterie scăzută, rezervor redus (20 de unități) și expiră în curând. Se recomandă să lăsaţi activat când alarmele pompei sunt setate la silențios.</string>
<string name="pump_warning_expiry_hour_title">Atenționare expirare pompă [hours]</string>
<string name="pump_warning_expiry_hour_summary">Arată notificarea la ora specificată după activare.</string>
<string name="patch_expiration_title">Patch Expirare</string>
<string name="patch_expiration_summary">Când este activat, patchul va expira după 3 zile, cu o perioadă de graţie de 8 ore după expirare.</string>
<string name="hourly_max_insulin_title">Insulină maximă pe oră</string>

View file

@ -112,6 +112,8 @@
<string name="alarm_setting_summary">Выберите предпочитаемые параметры оповещений помпы.</string>
<string name="pump_warning_notification_title">Уведомление об оповещениях помпы</string>
<string name="pump_warning_notification_summary">Показывать уведомления о некритических оповещениях помпы: низком заряде батареи, низком запасе инсулина (20 единиц) и приближающемся истечении срока работы. Рекомендуется оставить включенным, когда звук оповещений выключен.</string>
<string name="pump_warning_expiry_hour_title">Предупреждение об окончании срока годности помпы [hours]</string>
<string name="pump_warning_expiry_hour_summary">Показывать уведомление в указанный час после активации.</string>
<string name="patch_expiration_title">Окончание срока действия патча</string>
<string name="patch_expiration_summary">Если включено, то патч закончит свое действие через 3 дня, с дополнительными 8 часами после этого.</string>
<string name="hourly_max_insulin_title">Максимальное количество инсулина в час</string>

View file

@ -112,6 +112,8 @@
<string name="alarm_setting_summary">Vyberte preferované nastavenie výstrah.</string>
<string name="pump_warning_notification_title">Oznámenie o výstrahe pumpy</string>
<string name="pump_warning_notification_summary">Zobraziť upozornenie na nie kritické varovanie pumpy: vybitá batéria, takmer prázdny zásobník (20 jednotiek) a čoskoro dojde inzulín. Doporučené ponechať zapnuté, keď sú výstrahy pumpy nastavené na ticho.</string>
<string name="pump_warning_expiry_hour_title">Výstraha expirácie pumpy (hodiny)</string>
<string name="pump_warning_expiry_hour_summary">Zobraziť notifikáciu v určenej hodine po aktivácii.</string>
<string name="patch_expiration_title">Expirácia Patch</string>
<string name="patch_expiration_summary">Pokiaľ je povolené, Patch expiruje po 3 dňoch s maximálnou dobou odkladu 8 hodín.</string>
<string name="hourly_max_insulin_title">Hodinové maximum inzulínu</string>

View file

@ -112,6 +112,8 @@
<string name="alarm_setting_summary">Tercih ettiğiniz pompa alarm ayarlarını seçin.</string>
<string name="pump_warning_notification_title">Pompa uyarısı hakkında bildirim</string>
<string name="pump_warning_notification_summary">Kritik olmayan pompa uyarılarıyla ilgili bildirimi göster: düşük pil, düşük rezervuar (20 birim) ve yakında süresi doluyor. Pompa alarmları sessize ayarlandığında etkin bırakılması önerilir.</string>
<string name="pump_warning_expiry_hour_title">Pompa sona erme süresi uyarısı [hours]</string>
<string name="pump_warning_expiry_hour_summary">Etkinleştirmeden sonra belirtilen saatte bildirimi göster.</string>
<string name="patch_expiration_title">Patch süre sonu</string>
<string name="patch_expiration_summary">Etkinleştirildiğinde, patch 3 gün sonra sona erecek ve bunun ardından 8 saatlik bir ek süre tanınacaktır.</string>
<string name="hourly_max_insulin_title">Saatlik Maksimum insülin</string>

View file

@ -38,6 +38,7 @@
<string name="pump_is_suspended_day_max">Pump is suspended due to daily max insulin exceeded</string>
<string name="patch_not_active">Patch not activated</string>
<string name="pump_setting_failed">Setting user settings to pump failed!</string>
<string name="pump_sync_error">Error while syncing history from pump, a record has been skipped. Check treatment tab to check if bolus is synced correctly. Snooze and if error keep coming back change patch or pumpbase.</string>
<!-- overview fragment -->
<string name="ble_status_label">BLE Status</string>

View file

@ -40,7 +40,7 @@
<string name="omnipod_common_confirmation_time_on_pod_updated">L\'ora nel pod è stata aggiornata.</string>
<string name="omnipod_common_confirmation_suspended_delivery">Tutta l\'erogazione di insulina è stata sospesa.</string>
<string name="omnipod_common_confirmation_silenced_alerts">Gli avvisi attivi sono stati silenziati.</string>
<string name="omnipod_common_confirmation_delivery_resumed">L\'erogazione di insulina è ripresa.</string>
<string name="omnipod_common_confirmation_delivery_resumed">L\'erogazione di insulina è stata ripristinata.</string>
<!-- Omnipod - Overview -->
<string name="omnipod_common_overview_button_set_time">Imposta ora</string>
<string name="omnipod_common_overview_button_suspend_delivery">Sospensione</string>
@ -80,16 +80,16 @@
<string name="omnipod_common_pod_activation_wizard_initialize_pod_title">Inizializza pod</string>
<string name="omnipod_common_pod_activation_wizard_attach_pod_title">Collega pod</string>
<string name="omnipod_common_pod_activation_wizard_attach_pod_text">Prepara il sito di infusione. Rimuovi la protezione dell\'ago del pod e il supporto adesivo e collega il pod al sito di infusione.\n\nSe la cannula fuoriesce premi <b>Annulla</b> e scarta il pod.\n\nPremi <b>Avanti</b> per inserire la cannula e iniziare l\'erogazione della basale.</string>
<string name="omnipod_common_pod_activation_wizard_attach_pod_confirm_insert_cannula_text">Quando premi <b>OK</b>, la cannula verrà inserita. Assicurati di aver collegato il pod al sito di infusione.</string>
<string name="omnipod_common_pod_activation_wizard_attach_pod_confirm_insert_cannula_text">Quando premi <b>OK</b> la cannula verrà inserita. Assicurati di aver collegato il pod al sito di infusione.</string>
<string name="omnipod_common_pod_activation_wizard_insert_cannula_title">Inserisci cannula</string>
<string name="omnipod_common_pod_activation_wizard_insert_cannula_text">Tentativo di impostare il piano basale iniziale e inserire la cannula.\n\nQuando la cannula è stata inserita con successo, puoi premere <b>Avanti</b>.</string>
<string name="omnipod_common_pod_activation_wizard_insert_cannula_text">Tentativo di impostare il piano basale iniziale e inserire la cannula.\n\nQuando la cannula è stata inserita con successo puoi premere <b>Avanti</b>.</string>
<string name="omnipod_common_pod_activation_wizard_pod_activated_title">Pod attivato</string>
<string name="omnipod_common_pod_activation_wizard_pod_activated_text">Il nuovo pod è ora attivo.\n\nIl tuo piano basale è stato programmato e la cannula è stata inserita.\n\nVerifica che la cannula sia stata inserita correttamente e sostituisci il tuo pod se avverti il contrario.</string>
<string name="omnipod_common_pod_activation_wizard_pod_activated_text">Il nuovo pod è ora attivo.\n\nIl tuo piano basale è stato programmato e la cannula è stata inserita.\n\nVerifica che la cannula sia stata inserita correttamente e sostituisci il tuo pod qualora non lo fosse.</string>
<!-- Omnipod - Pod Deactivation Wizard -->
<string name="omnipod_common_pod_deactivation_wizard_start_pod_deactivation_title">Disattiva pod</string>
<string name="omnipod_common_pod_deactivation_wizard_start_pod_deactivation_text">Premi <b>Avanti</b> per disattivare il pod.\n\n<b>Nota:</b> Questo sospenderà tutta l\'erogazione di insulina e disattiverà il pod.</string>
<string name="omnipod_common_pod_deactivation_wizard_deactivating_pod_title">Disattivazione pod</string>
<string name="omnipod_common_pod_deactivation_wizard_deactivating_pod_text">Disattivazione del pod.\n\nQuando la disattivazione è correttamente completata, puoi premere <b>Avanti</b>.</string>
<string name="omnipod_common_pod_deactivation_wizard_deactivating_pod_text">Disattivazione del pod.\n\nQuando la disattivazione sarà correttamente completata, puoi premere <b>Avanti</b>.</string>
<string name="omnipod_common_pod_deactivation_wizard_pod_deactivated_title">Pod disattivato</string>
<string name="omnipod_common_pod_deactivation_wizard_pod_deactivated_text">Il tuo pod è stato disattivato.\n\nRimuovi il pod dal tuo corpo e gettalo.</string>
<string name="omnipod_common_pod_deactivation_wizard_pod_discarded_title">Pod scartato</string>
@ -153,7 +153,7 @@
<string name="omnipod_common_alert_finish_pairing_reminder">Fine promemoria associazione</string>
<string name="omnipod_common_alert_finish_setup_reminder_reminder">Fine promemoria configurazione</string>
<string name="omnipod_common_alert_expiration">Il pod scadrà presto</string>
<string name="omnipod_common_alert_expiration_advisory">Il pod scadrà presto</string>
<string name="omnipod_common_alert_expiration_advisory">Il pod scadrà a breve</string>
<string name="omnipod_common_alert_shutdown_imminent">L\'arresto è imminente</string>
<string name="omnipod_common_alert_low_reservoir">Livello serbatoio basso</string>
<string name="omnipod_common_alert_unknown_alert">Avviso sconosciuto</string>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Omnipod Dash - Description -->
<string name="omnipod_dash_pump_description">Integrazione del microinfusore Omnipod Dash (il nuovo modello, abilitato al Bluetooth e con la protezione ago di colore blu).</string>
<string name="omnipod_dash_pump_description">Integrazione del microinfusore Omnipod Dash (il nuovo modello, con il Bluetooth e con la protezione ago di colore blu).</string>
<!-- Omnipod Dash - Keys -->
<!-- Omnipod Dash - History -->
<string name="omnipod_dash_history_title">Storico pod</string>
@ -25,9 +25,9 @@
<!-- Exceptions -->
<string name="omnipod_dash_failed_to_connect">Impossibile connettersi al pod</string>
<string name="omnipod_dash_found_too_many_pods">Trovati troppi pod per l\'attivazione</string>
<string name="omnipod_dash_scan_failed">Nessun pod disponibile per l\'attivazione</string>
<string name="omnipod_dash_scan_failed">Nessun pod disponibile per l\'attivazione trovato</string>
<string name="omnipod_dash_generic_error">Errore generico: %1$s</string>
<string name="omnipod_dash_failed_to_send">Impossibile inviare il comando</string>
<string name="omnipod_dash_failed_to_send">L\'invio del comando è fallito</string>
<string name="omnipod_dash_command_not_sent">Comando non inviato</string>
<string name="omnipod_dash_command_not_received_by_the_pod">Comando non ricevuto dal pod</string>
<string name="omnipod_dash_unknown">Stato sconosciuto per il comando</string>
@ -35,9 +35,9 @@
<string name="omnipod_common_history_bolus_value">%1$.2f U</string>
<string name="omnipod_common_alert_delivery_suspended">L\'erogazione di insulina è sospesa</string>
<string name="omnipod_common_history_total_delivered">Totale erogato: %1$.2f U</string>
<string name="omnipod_dash_connection_lost">Persa connessione al pod</string>
<string name="omnipod_dash_connection_lost">Connessione col pod persa</string>
<string name="omnipod_dash_bolus_already_in_progress">Altro bolo in erogazione</string>
<string name="omnipod_dash_not_enough_insulin">Non è rimasta abbastanza insulina nel serbatoio</string>
<string name="omnipod_dash_not_enough_insulin">Insulina nel serbatoio insufficiente</string>
<string name="unconfirmed_command" comment="26 characters max for translation">Comando non confermato</string>
<string name="requested_by_user" comment="26 characters max for translation">Richiesto da utente</string>
<string name="profile_set_ok">Impostazione profilo OK</string>

View file

@ -42,14 +42,14 @@
<string name="omnipod_eros_error_communication_failed_riley_link_interrupted">RileyLink interrotto</string>
<string name="omnipod_eros_error_communication_failed_no_response_from_pod">Nessuna risposta dal pod</string>
<string name="omnipod_eros_error_set_basal_failed_delivery_might_be_suspended">Impostazione profilo basale fallita. L\'erogazione potrebbe essere sospesa! Aggiorna manualmente lo stato del pod dalla scheda Omnipod e riprendi l\'erogazione se necessario.</string>
<string name="omnipod_eros_error_set_basal_might_have_failed_delivery_might_be_suspended">L\'Impostazione del profilo basale potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Aggiorna manualmente lo stato del pod dalla scheda Omnipod e riprendi l\'erogazione se necessario.</string>
<string name="omnipod_eros_error_set_basal_failed_delivery_suspended">Impostazione profilo basale fallita. L\'erogazione è sospesa! Riprendi manualmente l\'erogazione dalla scheda Omnipod.</string>
<string name="omnipod_eros_error_cancel_temp_basal_failed_uncertain">La cancellazione della basale temporanea potrebbe essere fallita. Aggiorna manualmente lo stato del pod dalla scheda Omnipod.</string>
<string name="omnipod_eros_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Impostazione basale temporanea fallita. Se una basale temporanea era precedentemente in esecuzione, potrebbe essere stata cancellata. Aggiorna manualmente lo stato del pod dalla scheda Omnipod.</string>
<string name="omnipod_eros_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed">L\'impostazione della basale temporanea potrebbe essere fallita. Se una basale temporanea era precedentemente in esecuzione, è stata cancellata. Aggiorna manualmente lo stato del pod dalla scheda Omnipod.</string>
<string name="omnipod_eros_error_set_basal_might_have_failed_delivery_might_be_suspended">L\'impostazione del profilo basale potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Aggiorna manualmente lo stato del pod nella scheda Omnipod e riprendi l\'erogazione se necessario.</string>
<string name="omnipod_eros_error_set_basal_failed_delivery_suspended">Impostazione profilo basale fallita. L\'erogazione è sospesa! Riprendi manualmente l\'erogazione nella scheda Omnipod.</string>
<string name="omnipod_eros_error_cancel_temp_basal_failed_uncertain">La cancellazione della basale temporanea potrebbe essere fallita. Aggiorna manualmente lo stato del pod nella scheda Omnipod.</string>
<string name="omnipod_eros_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Impostazione basale temporanea fallita. Se una basale temporanea era precedentemente in esecuzione, potrebbe essere stata cancellata. Aggiorna manualmente lo stato del pod nella scheda Omnipod.</string>
<string name="omnipod_eros_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed">L\'impostazione della basale temporanea potrebbe essere fallita. Se una basale temporanea era precedentemente in esecuzione, è stata cancellata. Aggiorna manualmente lo stato del pod nella scheda Omnipod.</string>
<string name="omnipod_eros_error_set_temp_basal_failed_validation">La durata del TBR deve essere maggiore di zero e un multiplo di %1$s minuti.</string>
<string name="omnipod_eros_error_set_time_failed_delivery_might_be_suspended">L\'Impostazione dell\'ora potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Aggiorna manualmente lo stato del pod dalla scheda Omnipod e riprendi l\'erogazione se necessario.</string>
<string name="omnipod_eros_error_set_time_failed_delivery_suspended">Impostazione ora fallita. L\'erogazione è sospesa! Riprendi manualmente l\'erogazione dalla scheda Omnipod.</string>
<string name="omnipod_eros_error_set_time_failed_delivery_might_be_suspended">L\'impostazione dell\'ora potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Aggiorna manualmente lo stato del pod nella scheda Omnipod e riprendi l\'erogazione se necessario.</string>
<string name="omnipod_eros_error_set_time_failed_delivery_suspended">Impostazione ora fallita. L\'erogazione è sospesa! Riprendi manualmente l\'erogazione nella scheda Omnipod.</string>
<string name="omnipod_eros_error_failed_to_read_pulse_log">Impossibile leggere il log impulsi</string>
<string name="omnipod_eros_error_automatic_time_or_timezone_change_failed">Impossibile cambiare automaticamente l\'ora nel pod. Dovresti sincronizzare manualmente l\'ora nella scheda Omnipod.</string>
<string name="omnipod_eros_error_operation_not_possible_no_configuration">Operazione non possibile.\n\nDevi prima configurare Omnipod.</string>
@ -66,7 +66,7 @@
<string name="omnipod_eros_pod_management_pulse_log_value">Log impulsi (copiato negli appunti)</string>
<!-- Omnipod Eros - Pod Activation Wizard -->
<string name="omnipod_eros_pod_activation_wizard_start_pod_activation_text">Riempi un nuovo pod con abbastanza insulina per 3 giorni.\n\nResta in ascolto di due bip dal pod durante il processo di riempimento. Questi indicano che è stata inserita la quantità minima di 80U. Assicurati di svuotare completamente la siringa di riempimento, anche dopo aver sentito i due segnali acustici.\n\nDopo il riempimento del pod, premi <b>Avanti</b>.\n\n<b>Nota:</b> non rimuovere la protezione dell\'ago del pod in questo momento.\n<b>Nota:</b> colloca il RileyLink in posizione verticale e il pod a pochi centimetri di distanza.</string>
<string name="omnipod_eros_pod_activation_wizard_initialize_pod_text">Tentativo di associazione nuovo pod e caricamento.\n\nQuando il processo di inizializzazione è stato completato con successo, puoi premere <b>Avanti</b>.\n\n<b>Nota:</b> colloca il RileyLink in posizione verticale e il pod a pochi centimetri di distanza.</string>
<string name="omnipod_eros_pod_activation_wizard_initialize_pod_text">Tentativo di associazione nuovo pod e caricamento.\n\nQuando il processo di inizializzazione è stato completato con successo puoi premere <b>Avanti</b>.\n\n<b>Nota:</b> colloca il RileyLink in posizione verticale e il pod a pochi centimetri di distanza.</string>
<!-- Omnipod Eros - Other -->
<string name="omnipod_eros_uncertain">indeterminato</string>
</resources>

View file

@ -9,7 +9,7 @@
<!-- PumpCommon - Pump Status -->
<string name="pump_status_not_initialized">Non inizializzato</string>
<string name="pump_status_initialized">Inizializzato</string>
<string name="pump_status_encrypt">Comunicazione crittata</string>
<string name="pump_status_encrypt">Comunicazione criptata</string>
<string name="pump_status_ready">Pronto</string>
<string name="pump_status_busy">Occupato</string>
<string name="pump_status_suspended">Sospeso</string>

View file

@ -219,11 +219,13 @@ class RileyLinkBLEConfigActivity : TranslatedDaggerAppCompatActivity() {
}
scanning = true
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED) {
if (bluetoothAdapter?.isEnabled == true && bluetoothAdapter?.state == BluetoothAdapter.STATE_ON) {
bleScanner?.startScan(filters, settings, bleScanCallback)
aapsLogger.debug(LTag.PUMPBTCOMM, "startLeDeviceScan: Scanning Start")
Toast.makeText(this@RileyLinkBLEConfigActivity, R.string.riley_link_ble_config_scan_scanning, Toast.LENGTH_SHORT).show()
}
}
}
private fun stopLeDeviceScan() {
if (scanning) {

View file

@ -34,8 +34,8 @@ class TreatmentsActivity : TranslatedDaggerAppCompatActivity() {
setContentView(binding.root)
// Use index, TabItems crashes with an id
val useFakeTempBasal = activePlugin.activePump.isFakingTempsByExtendedBoluses
binding.treatmentsTabs.getTabAt(1)?.view?.visibility = useFakeTempBasal.not().toVisibility()
val showEbTab = !activePlugin.activePump.isFakingTempsByExtendedBoluses && activePlugin.activePump.pumpDescription.isExtendedBolusCapable
binding.treatmentsTabs.getTabAt(1)?.view?.visibility = showEbTab.toVisibility()
setFragment(TreatmentsBolusCarbsFragment())
setSupportActionBar(binding.toolbar)

View file

@ -132,7 +132,7 @@ class Widget : AppWidgetProvider() {
private fun updateBg(views: RemoteViews) {
views.setTextViewText(
R.id.bg,
overviewData.lastBg(iobCobCalculator.ads)?.let { profileUtil.fromMgdlToStringInUnits(it.value) } ?: rh.gs(app.aaps.core.ui.R.string.value_unavailable_short))
overviewData.lastBg(iobCobCalculator.ads)?.let { profileUtil.fromMgdlToStringInUnits(it.recalculated) } ?: rh.gs(app.aaps.core.ui.R.string.value_unavailable_short))
views.setTextColor(
R.id.bg, when {
overviewData.isLow(iobCobCalculator.ads) -> rh.gc(app.aaps.core.ui.R.color.widget_low)

View file

@ -27,7 +27,7 @@
<string name="age">Età</string>
<string name="weight_label">Peso</string>
<string name="most_common_profile">Profilo più comune:</string>
<string name="survey_comment">Nota: solo i dati visibili su questa schermata verranno caricati (in modo anonimo). Un ID è assegnato a questa installazione di AAPS. Puoi inviare nuovamente i dati se il tuo profilo principale viene modificato, ma lascialo in esecuzione almeno per una settimana per rendere il risultato visibile nel time in range (TIR). Il tuo aiuto è apprezzato.</string>
<string name="survey_comment">Nota: solo i dati visibili su questa schermata verranno caricati in modo anonimo. A questa installazione di AAPS verrà assegnato un ID. Puoi inviare nuovamente i dati se il tuo profilo principale viene modificato, ma lascialo in esecuzione almeno per una settimana per rendere il risultato visibile nel time in range (TIR). Il tuo aiuto è apprezzato.</string>
<string name="glucose_type">Tipo glicemia</string>
<string name="bg_other">Altro</string>
<string name="bg_meter">Glucometro</string>

View file

@ -50,6 +50,18 @@ android {
buildConfigField("String", "BUILDVERSION", "\"${generateGitBuild()}-${generateDate()}\"")
}
android {
buildTypes {
debug {
enableUnitTestCoverage = true
// Disable androidTest coverage, since it performs offline coverage
// instrumentation and that causes online (JavaAgent) instrumentation
// to fail in this project.
enableAndroidTestCoverage = false
}
}
}
flavorDimensions.add("standard")
productFlavors {
create("full") {

View file

@ -206,15 +206,15 @@ class DataLayerListenerServiceWear : WearableListenerService() {
} ?: aapsLogger.debug(LTag.WEAR, "sendMessage: Ignoring message. No node selected.")
}
@Suppress("unused")
private fun sendMessage(path: String, data: ByteArray) {
aapsLogger.debug(LTag.WEAR, "sendMessage: $path")
aapsLogger.debug(LTag.WEAR, "sendMessage: $path ${data.size}")
transcriptionNodeId?.also { nodeId ->
messageClient
.sendMessage(nodeId, path, data).apply {
addOnSuccessListener { }
addOnFailureListener {
aapsLogger.debug(LTag.WEAR, "sendMessage: $path failure")
aapsLogger.debug(LTag.WEAR, "sendMessage: $path failure ${data.size}")
}
}
}

View file

@ -819,9 +819,9 @@ class CustomWatchface : BaseWatchFace() {
getColorSteps(dynColor, COLOR.key, INVALIDCOLOR.key)
getColorSteps(dynFontColor, FONTCOLOR.key, INVALIDFONTCOLOR.key)
getIntSteps(dynTextSize, TEXTSIZE.key, INVALIDTEXTSIZE.key)
getIntSteps(dynLeftOffset, LEFTOFFSET.key, INVALIDTEXTSIZE.key)
getIntSteps(dynTopOffset, TOPOFFSET.key, INVALIDTEXTSIZE.key)
getIntSteps(dynRotationOffset, ROTATIONOFFSET.key, INVALIDTEXTSIZE.key)
getIntSteps(dynLeftOffset, LEFTOFFSET.key, INVALIDLEFTOFFSET.key)
getIntSteps(dynTopOffset, TOPOFFSET.key, INVALIDTOPOFFSET.key)
getIntSteps(dynRotationOffset, ROTATIONOFFSET.key, INVALIDROTATIONOFFSET.key)
}
private fun getDrawableSteps(dynMap: MutableMap<Int, Drawable?>, key: String, invalidKey: String) {

View file

@ -51,7 +51,7 @@ class PreparePredictionsWorker(
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PreparePredictionsData?
?: return Result.failure(workDataOf("Error" to "missing input data"))
val apsResult = if (config.APS) loop.lastRun?.constraintsProcessed else processedDeviceStatusData.getAPSResult(injector)
val apsResult = if (config.APS) loop.lastRun?.constraintsProcessed else processedDeviceStatusData.getAPSResult()
val predictionsAvailable = if (config.APS) loop.lastRun?.request?.hasPredictions == true else config.NSCLIENT
val menuChartSettings = overviewMenus.setting
// align to hours